1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include "usbd_function.h" 17094332d3Sopenharmony_ci 18094332d3Sopenharmony_ci#include <dlfcn.h> 19094332d3Sopenharmony_ci#include <unistd.h> 20094332d3Sopenharmony_ci#include <cerrno> 21094332d3Sopenharmony_ci 22094332d3Sopenharmony_ci#include "devmgr_hdi.h" 23094332d3Sopenharmony_ci#include "hdf_log.h" 24094332d3Sopenharmony_ci#include "hdf_remote_service.h" 25094332d3Sopenharmony_ci#include "hdf_sbuf.h" 26094332d3Sopenharmony_ci#include "idevmgr_hdi.h" 27094332d3Sopenharmony_ci#include "iservmgr_hdi.h" 28094332d3Sopenharmony_ci#include "message_option.h" 29094332d3Sopenharmony_ci#include "message_parcel.h" 30094332d3Sopenharmony_ci#include "osal_time.h" 31094332d3Sopenharmony_ci#include "parameter.h" 32094332d3Sopenharmony_ci#include "securec.h" 33094332d3Sopenharmony_ci#include "string_ex.h" 34094332d3Sopenharmony_ci#include "usbd_type.h" 35094332d3Sopenharmony_ci#include "usbfn_mtp_impl.h" 36094332d3Sopenharmony_ci#include "usbd_wrapper.h" 37094332d3Sopenharmony_ci 38094332d3Sopenharmony_cinamespace OHOS { 39094332d3Sopenharmony_cinamespace HDI { 40094332d3Sopenharmony_cinamespace Usb { 41094332d3Sopenharmony_cinamespace V1_1 { 42094332d3Sopenharmony_ciuint32_t UsbdFunction::currentFuncs_ = USB_FUNCTION_HDC; 43094332d3Sopenharmony_ci 44094332d3Sopenharmony_ciusing OHOS::HDI::DeviceManager::V1_0::IDeviceManager; 45094332d3Sopenharmony_ciusing OHOS::HDI::ServiceManager::V1_0::IServiceManager; 46094332d3Sopenharmony_ciusing OHOS::HDI::Usb::Gadget::Mtp::V1_0::IUsbfnMtpInterface; 47094332d3Sopenharmony_ciusing GetMtpImplFunc = void*(*)(); 48094332d3Sopenharmony_ci 49094332d3Sopenharmony_ciconstexpr uint32_t UDC_NAME_MAX_LEN = 32; 50094332d3Sopenharmony_ciconstexpr int32_t WAIT_UDC_MAX_LOOP = 30; 51094332d3Sopenharmony_ciconstexpr uint32_t WAIT_UDC_TIME = 100000; 52094332d3Sopenharmony_ciconstexpr int32_t WRITE_UDC_MAX_RETRY = 5; 53094332d3Sopenharmony_ci/* mtp and ptp use same driver and same service */ 54094332d3Sopenharmony_cistatic std::string MTP_PTP_SERVICE_NAME {"usbfn_mtp_interface_service"}; 55094332d3Sopenharmony_ci#define UDC_PATH "/config/usb_gadget/g1/UDC" 56094332d3Sopenharmony_ci 57094332d3Sopenharmony_cistatic void *g_libHandle = nullptr; 58094332d3Sopenharmony_cistatic GetMtpImplFunc g_getMtpImpl = nullptr; 59094332d3Sopenharmony_ci 60094332d3Sopenharmony_cistatic void InitGetMtpImpl() 61094332d3Sopenharmony_ci{ 62094332d3Sopenharmony_ci if (g_getMtpImpl != nullptr) { 63094332d3Sopenharmony_ci return; 64094332d3Sopenharmony_ci } 65094332d3Sopenharmony_ci 66094332d3Sopenharmony_ci g_libHandle = dlopen("libusbfn_mtp_interface_service_1.0.z.so", RTLD_LAZY); 67094332d3Sopenharmony_ci if (g_libHandle == nullptr) { 68094332d3Sopenharmony_ci HDF_LOGE("%{public}s dlopen failed: %{public}s", __func__, dlerror()); 69094332d3Sopenharmony_ci return; 70094332d3Sopenharmony_ci } 71094332d3Sopenharmony_ci 72094332d3Sopenharmony_ci void *funcPtr = dlsym(g_libHandle, "UsbfnMtpInterfaceImplGetInstance"); 73094332d3Sopenharmony_ci if (funcPtr == nullptr) { 74094332d3Sopenharmony_ci HDF_LOGE("%{public}s dlsym failed: %{public}s", __func__, dlerror()); 75094332d3Sopenharmony_ci dlclose(g_libHandle); 76094332d3Sopenharmony_ci g_libHandle = nullptr; 77094332d3Sopenharmony_ci return; 78094332d3Sopenharmony_ci } 79094332d3Sopenharmony_ci 80094332d3Sopenharmony_ci g_getMtpImpl = reinterpret_cast<GetMtpImplFunc>(funcPtr); 81094332d3Sopenharmony_ci} 82094332d3Sopenharmony_ci 83094332d3Sopenharmony_cistatic void ReleaseGetMtpImpl() 84094332d3Sopenharmony_ci{ 85094332d3Sopenharmony_ci g_getMtpImpl = nullptr; 86094332d3Sopenharmony_ci if (g_libHandle != nullptr) { 87094332d3Sopenharmony_ci dlclose(g_libHandle); 88094332d3Sopenharmony_ci g_libHandle = nullptr; 89094332d3Sopenharmony_ci } 90094332d3Sopenharmony_ci} 91094332d3Sopenharmony_ci 92094332d3Sopenharmony_cistatic IUsbfnMtpInterface *GetUsbfnMtpImpl() 93094332d3Sopenharmony_ci{ 94094332d3Sopenharmony_ci InitGetMtpImpl(); 95094332d3Sopenharmony_ci if (g_getMtpImpl == nullptr) { 96094332d3Sopenharmony_ci return nullptr; 97094332d3Sopenharmony_ci } 98094332d3Sopenharmony_ci 99094332d3Sopenharmony_ci void *instance = g_getMtpImpl(); 100094332d3Sopenharmony_ci if (instance != nullptr) { 101094332d3Sopenharmony_ci return reinterpret_cast<IUsbfnMtpInterface *>(instance); 102094332d3Sopenharmony_ci } 103094332d3Sopenharmony_ci return nullptr; 104094332d3Sopenharmony_ci} 105094332d3Sopenharmony_ci 106094332d3Sopenharmony_ciint32_t UsbdFunction::SendCmdToService(const char *name, int32_t cmd, unsigned char funcMask) 107094332d3Sopenharmony_ci{ 108094332d3Sopenharmony_ci auto servMgr = IServiceManager::Get(); 109094332d3Sopenharmony_ci if (servMgr == nullptr) { 110094332d3Sopenharmony_ci HDF_LOGE("%{public}s: get IServiceManager failed", __func__); 111094332d3Sopenharmony_ci return HDF_FAILURE; 112094332d3Sopenharmony_ci } 113094332d3Sopenharmony_ci 114094332d3Sopenharmony_ci sptr<IRemoteObject> remote = servMgr->GetService(name); 115094332d3Sopenharmony_ci if (remote == nullptr) { 116094332d3Sopenharmony_ci HDF_LOGE("%{public}s: get remote object failed: %{public}s", __func__, name); 117094332d3Sopenharmony_ci return HDF_FAILURE; 118094332d3Sopenharmony_ci } 119094332d3Sopenharmony_ci 120094332d3Sopenharmony_ci OHOS::MessageParcel data; 121094332d3Sopenharmony_ci OHOS::MessageParcel reply; 122094332d3Sopenharmony_ci OHOS::MessageOption option; 123094332d3Sopenharmony_ci 124094332d3Sopenharmony_ci if (!data.WriteInterfaceToken(Str8ToStr16(HDF_USB_USBFN_DESC))) { 125094332d3Sopenharmony_ci HDF_LOGE("%{public}s: WriteInterfaceToken failed", __func__); 126094332d3Sopenharmony_ci return HDF_FAILURE; 127094332d3Sopenharmony_ci } 128094332d3Sopenharmony_ci 129094332d3Sopenharmony_ci if (!data.WriteUint8(funcMask)) { 130094332d3Sopenharmony_ci HDF_LOGE("%{public}s: WriteInt8 failed: %{public}d", __func__, funcMask); 131094332d3Sopenharmony_ci return HDF_FAILURE; 132094332d3Sopenharmony_ci } 133094332d3Sopenharmony_ci 134094332d3Sopenharmony_ci int32_t ret = remote->SendRequest(cmd, data, reply, option); 135094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 136094332d3Sopenharmony_ci HDF_LOGE("%{public}s: send request to %{public}s failed, ret=%{public}d", __func__, name, ret); 137094332d3Sopenharmony_ci return ret; 138094332d3Sopenharmony_ci } 139094332d3Sopenharmony_ci return HDF_SUCCESS; 140094332d3Sopenharmony_ci} 141094332d3Sopenharmony_ci 142094332d3Sopenharmony_ciint32_t UsbdFunction::InitMtp() 143094332d3Sopenharmony_ci{ 144094332d3Sopenharmony_ci int32_t ret = UsbdRegisterDevice(MTP_PTP_SERVICE_NAME); 145094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 146094332d3Sopenharmony_ci HDF_LOGE("%{public}s: register mtp device failed: %{public}d", __func__, ret); 147094332d3Sopenharmony_ci return ret; 148094332d3Sopenharmony_ci } 149094332d3Sopenharmony_ci auto serviceImpl = GetUsbfnMtpImpl(); 150094332d3Sopenharmony_ci if (serviceImpl == nullptr) { 151094332d3Sopenharmony_ci HDF_LOGE("%{public}s: failed to get of implement service", __func__); 152094332d3Sopenharmony_ci return HDF_FAILURE; 153094332d3Sopenharmony_ci } 154094332d3Sopenharmony_ci ret = serviceImpl->Init(); 155094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 156094332d3Sopenharmony_ci UsbdUnregisterDevice(MTP_PTP_SERVICE_NAME); 157094332d3Sopenharmony_ci HDF_LOGE("%{public}s: init mtp device failed: %{public}d", __func__, ret); 158094332d3Sopenharmony_ci } 159094332d3Sopenharmony_ci HDF_LOGI("%{public}s: start Init done", __func__); 160094332d3Sopenharmony_ci return ret; 161094332d3Sopenharmony_ci} 162094332d3Sopenharmony_ci 163094332d3Sopenharmony_ciint32_t UsbdFunction::ReleaseMtp() 164094332d3Sopenharmony_ci{ 165094332d3Sopenharmony_ci auto serviceImpl = GetUsbfnMtpImpl(); 166094332d3Sopenharmony_ci if (serviceImpl == nullptr) { 167094332d3Sopenharmony_ci HDF_LOGE("%{public}s: failed to get of implement service", __func__); 168094332d3Sopenharmony_ci return HDF_FAILURE; 169094332d3Sopenharmony_ci } 170094332d3Sopenharmony_ci int32_t ret = serviceImpl->Release(); 171094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 172094332d3Sopenharmony_ci HDF_LOGE("%{public}s: release mtp device failed: %{public}d", __func__, ret); 173094332d3Sopenharmony_ci } 174094332d3Sopenharmony_ci ReleaseGetMtpImpl(); 175094332d3Sopenharmony_ci 176094332d3Sopenharmony_ci UsbdUnregisterDevice(MTP_PTP_SERVICE_NAME); 177094332d3Sopenharmony_ci HDF_LOGI("%{public}s: release Mtp done", __func__); 178094332d3Sopenharmony_ci return ret; 179094332d3Sopenharmony_ci} 180094332d3Sopenharmony_ci 181094332d3Sopenharmony_ciint32_t UsbdFunction::RemoveHdc() 182094332d3Sopenharmony_ci{ 183094332d3Sopenharmony_ci int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_OFF); 184094332d3Sopenharmony_ci if (status != 0) { 185094332d3Sopenharmony_ci HDF_LOGE("%{public}s:remove hdc config error = %{public}d", __func__, status); 186094332d3Sopenharmony_ci return HDF_FAILURE; 187094332d3Sopenharmony_ci } 188094332d3Sopenharmony_ci return HDF_SUCCESS; 189094332d3Sopenharmony_ci} 190094332d3Sopenharmony_ci 191094332d3Sopenharmony_ciint32_t UsbdFunction::AddHdc() 192094332d3Sopenharmony_ci{ 193094332d3Sopenharmony_ci int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_ON); 194094332d3Sopenharmony_ci if (status != 0) { 195094332d3Sopenharmony_ci HDF_LOGE("%{public}s:add hdc config error = %{public}d", __func__, status); 196094332d3Sopenharmony_ci return HDF_FAILURE; 197094332d3Sopenharmony_ci } 198094332d3Sopenharmony_ci 199094332d3Sopenharmony_ci status = SetParameter(PERSIST_SYS_USB_CONFIG, HDC_CONFIG_ON); 200094332d3Sopenharmony_ci if (status != 0) { 201094332d3Sopenharmony_ci HDF_LOGE("%{public}s:add hdc persist config error = %{public}d", __func__, status); 202094332d3Sopenharmony_ci return HDF_FAILURE; 203094332d3Sopenharmony_ci } 204094332d3Sopenharmony_ci return HDF_SUCCESS; 205094332d3Sopenharmony_ci} 206094332d3Sopenharmony_ci 207094332d3Sopenharmony_ciint32_t UsbdFunction::SetFunctionToRndis() 208094332d3Sopenharmony_ci{ 209094332d3Sopenharmony_ci int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_RNDIS); 210094332d3Sopenharmony_ci if (status != 0) { 211094332d3Sopenharmony_ci HDF_LOGE("%{public}s:add rndis config error = %{public}d", __func__, status); 212094332d3Sopenharmony_ci return HDF_FAILURE; 213094332d3Sopenharmony_ci } 214094332d3Sopenharmony_ci return HDF_SUCCESS; 215094332d3Sopenharmony_ci} 216094332d3Sopenharmony_ci 217094332d3Sopenharmony_ciint32_t UsbdFunction::SetFunctionToStorage() 218094332d3Sopenharmony_ci{ 219094332d3Sopenharmony_ci int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_STORAGE); 220094332d3Sopenharmony_ci if (status != 0) { 221094332d3Sopenharmony_ci HDF_LOGE("%{public}s:add storage config error = %{public}d", __func__, status); 222094332d3Sopenharmony_ci return HDF_FAILURE; 223094332d3Sopenharmony_ci } 224094332d3Sopenharmony_ci 225094332d3Sopenharmony_ci status = SetParameter(PERSIST_SYS_USB_CONFIG, HDC_CONFIG_STORAGE); 226094332d3Sopenharmony_ci if (status != 0) { 227094332d3Sopenharmony_ci HDF_LOGE("%{public}s:add storage persist config error = %{public}d", __func__, status); 228094332d3Sopenharmony_ci return HDF_FAILURE; 229094332d3Sopenharmony_ci } 230094332d3Sopenharmony_ci return HDF_SUCCESS; 231094332d3Sopenharmony_ci} 232094332d3Sopenharmony_ci 233094332d3Sopenharmony_ciint32_t UsbdFunction::SetFunctionToRndisHdc() 234094332d3Sopenharmony_ci{ 235094332d3Sopenharmony_ci int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_RNDIS_HDC); 236094332d3Sopenharmony_ci if (status != 0) { 237094332d3Sopenharmony_ci HDF_LOGE("%{public}s:add rndis hdc config error = %{public}d", __func__, status); 238094332d3Sopenharmony_ci return HDF_FAILURE; 239094332d3Sopenharmony_ci } 240094332d3Sopenharmony_ci return HDF_SUCCESS; 241094332d3Sopenharmony_ci} 242094332d3Sopenharmony_ci 243094332d3Sopenharmony_ciint32_t UsbdFunction::SetFunctionToManufactureHdc() 244094332d3Sopenharmony_ci{ 245094332d3Sopenharmony_ci int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_MANUFACTURE_HDC); 246094332d3Sopenharmony_ci if (status != 0) { 247094332d3Sopenharmony_ci HDF_LOGE("%{public}s:add manufacture hdc config error = %{public}d", __func__, status); 248094332d3Sopenharmony_ci return HDF_FAILURE; 249094332d3Sopenharmony_ci } 250094332d3Sopenharmony_ci return HDF_SUCCESS; 251094332d3Sopenharmony_ci} 252094332d3Sopenharmony_ci 253094332d3Sopenharmony_ciint32_t UsbdFunction::SetFunctionToStorageHdc() 254094332d3Sopenharmony_ci{ 255094332d3Sopenharmony_ci int32_t status = SetParameter(SYS_USB_CONFIG, HDC_CONFIG_STORAGE_HDC); 256094332d3Sopenharmony_ci if (status != 0) { 257094332d3Sopenharmony_ci HDF_LOGE("%{public}s:add storage hdc config error = %{public}d", __func__, status); 258094332d3Sopenharmony_ci return HDF_FAILURE; 259094332d3Sopenharmony_ci } 260094332d3Sopenharmony_ci return HDF_SUCCESS; 261094332d3Sopenharmony_ci} 262094332d3Sopenharmony_ci 263094332d3Sopenharmony_ciint32_t UsbdFunction::SetFunctionToNone() 264094332d3Sopenharmony_ci{ 265094332d3Sopenharmony_ci uint32_t ddkFuns = currentFuncs_ & USB_DDK_FUNCTION_SUPPORT; 266094332d3Sopenharmony_ci if (ddkFuns > 0) { 267094332d3Sopenharmony_ci if ((ddkFuns & USB_FUNCTION_ACM) != 0) { 268094332d3Sopenharmony_ci UsbdFunction::SendCmdToService(ACM_SERVICE_NAME, ACM_RELEASE, USB_FUNCTION_ACM); 269094332d3Sopenharmony_ci UsbdUnregisterDevice(std::string(ACM_SERVICE_NAME)); 270094332d3Sopenharmony_ci } 271094332d3Sopenharmony_ci if ((ddkFuns & USB_FUNCTION_ECM) != 0) { 272094332d3Sopenharmony_ci UsbdFunction::SendCmdToService(ECM_SERVICE_NAME, ECM_RELEASE, USB_FUNCTION_ECM); 273094332d3Sopenharmony_ci UsbdUnregisterDevice(std::string(ECM_SERVICE_NAME)); 274094332d3Sopenharmony_ci } 275094332d3Sopenharmony_ci if ((ddkFuns & USB_FUNCTION_MTP) != 0 || (ddkFuns & USB_FUNCTION_PTP) != 0) { 276094332d3Sopenharmony_ci if (ReleaseMtp() != HDF_SUCCESS) { 277094332d3Sopenharmony_ci HDF_LOGE("%{public}s: release mtp failed", __func__); 278094332d3Sopenharmony_ci } 279094332d3Sopenharmony_ci } 280094332d3Sopenharmony_ci } 281094332d3Sopenharmony_ci UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT); 282094332d3Sopenharmony_ci UsbdUnregisterDevice(std::string(DEV_SERVICE_NAME)); 283094332d3Sopenharmony_ci int32_t ret = RemoveHdc(); 284094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 285094332d3Sopenharmony_ci HDF_LOGE("%{public}s: RemoveHdc error, ret = %{public}d", __func__, ret); 286094332d3Sopenharmony_ci return ret; 287094332d3Sopenharmony_ci } 288094332d3Sopenharmony_ci 289094332d3Sopenharmony_ci ret = UsbdWaitToNone(); 290094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 291094332d3Sopenharmony_ci HDF_LOGE("%{public}s: UsbdWaitToNone error, ret = %{public}d", __func__, ret); 292094332d3Sopenharmony_ci return ret; 293094332d3Sopenharmony_ci } 294094332d3Sopenharmony_ci currentFuncs_ = USB_FUNCTION_NONE; 295094332d3Sopenharmony_ci return ret; 296094332d3Sopenharmony_ci} 297094332d3Sopenharmony_ci 298094332d3Sopenharmony_ciint32_t UsbdFunction::SetDDKFunction(uint32_t funcs) 299094332d3Sopenharmony_ci{ 300094332d3Sopenharmony_ci HDF_LOGD("%{public}s: SetDDKFunction funcs=%{public}d", __func__, funcs); 301094332d3Sopenharmony_ci uint32_t ddkFuns = static_cast<uint32_t>(funcs) & USB_DDK_FUNCTION_SUPPORT; 302094332d3Sopenharmony_ci if (ddkFuns == 0) { 303094332d3Sopenharmony_ci HDF_LOGE("%{public}s: not use ddkfunction", __func__); 304094332d3Sopenharmony_ci return HDF_SUCCESS; 305094332d3Sopenharmony_ci } 306094332d3Sopenharmony_ci int32_t ret = UsbdRegisterDevice(std::string(DEV_SERVICE_NAME)); 307094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 308094332d3Sopenharmony_ci HDF_LOGE("%{public}s: failed to register device", __func__); 309094332d3Sopenharmony_ci return ret; 310094332d3Sopenharmony_ci } 311094332d3Sopenharmony_ci if (UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_ADD, ddkFuns)) { 312094332d3Sopenharmony_ci HDF_LOGE("%{public}s: create dev error: %{public}d", __func__, ddkFuns); 313094332d3Sopenharmony_ci return HDF_FAILURE; 314094332d3Sopenharmony_ci } 315094332d3Sopenharmony_ci return HDF_SUCCESS; 316094332d3Sopenharmony_ci} 317094332d3Sopenharmony_ci 318094332d3Sopenharmony_ciint32_t UsbdFunction::UsbdWriteUdc(char* udcName, size_t len) 319094332d3Sopenharmony_ci{ 320094332d3Sopenharmony_ci FILE *fpWrite = fopen(UDC_PATH, "w"); 321094332d3Sopenharmony_ci if (fpWrite == NULL) { 322094332d3Sopenharmony_ci HDF_LOGE("%{public}s: fopen failed", __func__); 323094332d3Sopenharmony_ci return HDF_ERR_BAD_FD; 324094332d3Sopenharmony_ci } 325094332d3Sopenharmony_ci 326094332d3Sopenharmony_ci size_t count = fwrite(udcName, len, 1, fpWrite); 327094332d3Sopenharmony_ci if (count != 1) { 328094332d3Sopenharmony_ci HDF_LOGE("%{public}s: fwrite failed, errno: %{public}d", __func__, errno); 329094332d3Sopenharmony_ci (void)fclose(fpWrite); 330094332d3Sopenharmony_ci return HDF_FAILURE; 331094332d3Sopenharmony_ci } 332094332d3Sopenharmony_ci 333094332d3Sopenharmony_ci if (ferror(fpWrite)) { 334094332d3Sopenharmony_ci HDF_LOGW("%{public}s: fwrite failed, errno: %{public}d", __func__, errno); 335094332d3Sopenharmony_ci } 336094332d3Sopenharmony_ci if (fclose(fpWrite) == EOF) { 337094332d3Sopenharmony_ci HDF_LOGE("%{public}s: flcose failed, errno: %{public}d", __func__, errno); 338094332d3Sopenharmony_ci return HDF_FAILURE; 339094332d3Sopenharmony_ci } 340094332d3Sopenharmony_ci return HDF_SUCCESS; 341094332d3Sopenharmony_ci} 342094332d3Sopenharmony_ciint32_t UsbdFunction::UsbdReadUdc(char* udcName, size_t len) 343094332d3Sopenharmony_ci{ 344094332d3Sopenharmony_ci FILE *fpRead = fopen(UDC_PATH, "r"); 345094332d3Sopenharmony_ci if (fpRead == NULL) { 346094332d3Sopenharmony_ci HDF_LOGE("%{public}s: fopen failed", __func__); 347094332d3Sopenharmony_ci return HDF_ERR_BAD_FD; 348094332d3Sopenharmony_ci } 349094332d3Sopenharmony_ci 350094332d3Sopenharmony_ci size_t count = fread(udcName, len, 1, fpRead); 351094332d3Sopenharmony_ci if (count != 1) { 352094332d3Sopenharmony_ci if (feof(fpRead)) { 353094332d3Sopenharmony_ci HDF_LOGI("%{public}s: fread end of file reached.", __func__); 354094332d3Sopenharmony_ci } else if (ferror(fpRead)) { 355094332d3Sopenharmony_ci HDF_LOGE("%{public}s: fread failed, errno: %{public}d", __func__, errno); 356094332d3Sopenharmony_ci } else { 357094332d3Sopenharmony_ci HDF_LOGW("%{public}s: fread len than expected", __func__); 358094332d3Sopenharmony_ci } 359094332d3Sopenharmony_ci (void)fclose(fpRead); 360094332d3Sopenharmony_ci return HDF_FAILURE; 361094332d3Sopenharmony_ci } 362094332d3Sopenharmony_ci 363094332d3Sopenharmony_ci if (fclose(fpRead) == EOF) { 364094332d3Sopenharmony_ci HDF_LOGW("%{public}s: flcose failed, errno: %{public}d", __func__, errno); 365094332d3Sopenharmony_ci } 366094332d3Sopenharmony_ci return HDF_SUCCESS; 367094332d3Sopenharmony_ci} 368094332d3Sopenharmony_ci 369094332d3Sopenharmony_ciint32_t UsbdFunction::UsbdEnableDevice(int32_t funcs) 370094332d3Sopenharmony_ci{ 371094332d3Sopenharmony_ci // get udc name 372094332d3Sopenharmony_ci char udcName[UDC_NAME_MAX_LEN] = {0}; 373094332d3Sopenharmony_ci int32_t ret = GetParameter("sys.usb.controller", "invalid", udcName, UDC_NAME_MAX_LEN); 374094332d3Sopenharmony_ci if (ret <= 0) { 375094332d3Sopenharmony_ci HDF_LOGE("%{public}s: GetParameter failed", __func__); 376094332d3Sopenharmony_ci return HDF_FAILURE; 377094332d3Sopenharmony_ci } 378094332d3Sopenharmony_ci 379094332d3Sopenharmony_ci char tmpName[UDC_NAME_MAX_LEN] = {0}; 380094332d3Sopenharmony_ci for (int32_t i = 0; i < WRITE_UDC_MAX_RETRY; i++) { 381094332d3Sopenharmony_ci if (i != 0 && ret != HDF_SUCCESS) { 382094332d3Sopenharmony_ci ret = SetDDKFunction(funcs); 383094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 384094332d3Sopenharmony_ci UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT); 385094332d3Sopenharmony_ci UsbdUnregisterDevice(std::string(DEV_SERVICE_NAME)); 386094332d3Sopenharmony_ci usleep(WAIT_UDC_TIME); 387094332d3Sopenharmony_ci continue; 388094332d3Sopenharmony_ci } 389094332d3Sopenharmony_ci } 390094332d3Sopenharmony_ci ret = UsbdWriteUdc(udcName, strlen(udcName)); 391094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 392094332d3Sopenharmony_ci UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT); 393094332d3Sopenharmony_ci UsbdUnregisterDevice(std::string(DEV_SERVICE_NAME)); 394094332d3Sopenharmony_ci usleep(WAIT_UDC_TIME); 395094332d3Sopenharmony_ci continue; 396094332d3Sopenharmony_ci } 397094332d3Sopenharmony_ci 398094332d3Sopenharmony_ci (void)memset_s(tmpName, UDC_NAME_MAX_LEN, 0, UDC_NAME_MAX_LEN); 399094332d3Sopenharmony_ci ret = UsbdReadUdc(tmpName, strlen(udcName)); 400094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 401094332d3Sopenharmony_ci UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT); 402094332d3Sopenharmony_ci UsbdUnregisterDevice(std::string(DEV_SERVICE_NAME)); 403094332d3Sopenharmony_ci usleep(WAIT_UDC_TIME); 404094332d3Sopenharmony_ci continue; 405094332d3Sopenharmony_ci } 406094332d3Sopenharmony_ci 407094332d3Sopenharmony_ci if (strcmp(udcName, tmpName) == 0) { 408094332d3Sopenharmony_ci return HDF_SUCCESS; 409094332d3Sopenharmony_ci } 410094332d3Sopenharmony_ci HDF_LOGI("%{public}s: tmpName: %{public}s", __func__, tmpName); 411094332d3Sopenharmony_ci usleep(WAIT_UDC_TIME); 412094332d3Sopenharmony_ci } 413094332d3Sopenharmony_ci 414094332d3Sopenharmony_ci if (strcmp(udcName, tmpName) != 0) { 415094332d3Sopenharmony_ci HDF_LOGE("%{public}s: strcmp failed", __func__); 416094332d3Sopenharmony_ci return HDF_FAILURE; 417094332d3Sopenharmony_ci } 418094332d3Sopenharmony_ci return HDF_SUCCESS; 419094332d3Sopenharmony_ci} 420094332d3Sopenharmony_ci 421094332d3Sopenharmony_ciint32_t UsbdFunction::UsbdWaitUdc() 422094332d3Sopenharmony_ci{ 423094332d3Sopenharmony_ci // get udc name 424094332d3Sopenharmony_ci char udcName[UDC_NAME_MAX_LEN] = {0}; 425094332d3Sopenharmony_ci int32_t ret = GetParameter("sys.usb.controller", "invalid", udcName, UDC_NAME_MAX_LEN - 1); 426094332d3Sopenharmony_ci if (ret <= 0) { 427094332d3Sopenharmony_ci HDF_LOGE("%{public}s: GetParameter failed", __func__); 428094332d3Sopenharmony_ci return HDF_FAILURE; 429094332d3Sopenharmony_ci } 430094332d3Sopenharmony_ci 431094332d3Sopenharmony_ci char tmpName[UDC_NAME_MAX_LEN] = {0}; 432094332d3Sopenharmony_ci for (int32_t i = 0; i < WAIT_UDC_MAX_LOOP; i++) { 433094332d3Sopenharmony_ci (void)memset_s(tmpName, UDC_NAME_MAX_LEN, 0, UDC_NAME_MAX_LEN); 434094332d3Sopenharmony_ci ret = UsbdReadUdc(tmpName, strlen(udcName)); 435094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 436094332d3Sopenharmony_ci usleep(WAIT_UDC_TIME); 437094332d3Sopenharmony_ci continue; 438094332d3Sopenharmony_ci } 439094332d3Sopenharmony_ci 440094332d3Sopenharmony_ci if (strcmp(udcName, tmpName) == 0) { 441094332d3Sopenharmony_ci return HDF_SUCCESS; 442094332d3Sopenharmony_ci } 443094332d3Sopenharmony_ci HDF_LOGE("%{public}s: read UDC_PATH: %{public}s", __func__, tmpName); 444094332d3Sopenharmony_ci usleep(WAIT_UDC_TIME); 445094332d3Sopenharmony_ci } 446094332d3Sopenharmony_ci 447094332d3Sopenharmony_ci if (strcmp(udcName, tmpName) != 0) { 448094332d3Sopenharmony_ci HDF_LOGE("%{public}s: strcmp failed", __func__); 449094332d3Sopenharmony_ci return HDF_FAILURE; 450094332d3Sopenharmony_ci } 451094332d3Sopenharmony_ci 452094332d3Sopenharmony_ci return HDF_SUCCESS; 453094332d3Sopenharmony_ci} 454094332d3Sopenharmony_ci 455094332d3Sopenharmony_ciint32_t UsbdFunction::UsbdWaitToNone() 456094332d3Sopenharmony_ci{ 457094332d3Sopenharmony_ci char stateName[UDC_NAME_MAX_LEN] = {0}; 458094332d3Sopenharmony_ci for (int32_t i = 0; i < WAIT_UDC_MAX_LOOP; i++) { 459094332d3Sopenharmony_ci (void)memset_s(stateName, UDC_NAME_MAX_LEN, 0, UDC_NAME_MAX_LEN); 460094332d3Sopenharmony_ci int32_t ret = GetParameter(SYS_USB_STATE, "invalid", stateName, UDC_NAME_MAX_LEN - 1); 461094332d3Sopenharmony_ci if (ret <= 0) { 462094332d3Sopenharmony_ci HDF_LOGE("%{public}s: GetParameter failed", __func__); 463094332d3Sopenharmony_ci return HDF_FAILURE; 464094332d3Sopenharmony_ci } 465094332d3Sopenharmony_ci if (strcmp(stateName, HDC_CONFIG_OFF) == 0) { 466094332d3Sopenharmony_ci return HDF_SUCCESS; 467094332d3Sopenharmony_ci } 468094332d3Sopenharmony_ci usleep(WAIT_UDC_TIME); 469094332d3Sopenharmony_ci } 470094332d3Sopenharmony_ci 471094332d3Sopenharmony_ci if (strcmp(stateName, HDC_CONFIG_OFF) != 0) { 472094332d3Sopenharmony_ci HDF_LOGE("%{public}s: strcmp failed", __func__); 473094332d3Sopenharmony_ci return HDF_FAILURE; 474094332d3Sopenharmony_ci } 475094332d3Sopenharmony_ci 476094332d3Sopenharmony_ci return HDF_SUCCESS; 477094332d3Sopenharmony_ci} 478094332d3Sopenharmony_ci 479094332d3Sopenharmony_ciint32_t UsbdFunction::UsbdInitDDKFunction(uint32_t funcs) 480094332d3Sopenharmony_ci{ 481094332d3Sopenharmony_ci int32_t ret; 482094332d3Sopenharmony_ci if ((funcs & USB_FUNCTION_ACM) != 0) { 483094332d3Sopenharmony_ci ret = UsbdRegisterDevice(std::string(ACM_SERVICE_NAME)); 484094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 485094332d3Sopenharmony_ci HDF_LOGE("%{public}s: failed to register device", __func__); 486094332d3Sopenharmony_ci return HDF_FAILURE; 487094332d3Sopenharmony_ci } 488094332d3Sopenharmony_ci if (SendCmdToService(ACM_SERVICE_NAME, ACM_INIT, USB_FUNCTION_ACM) != 0) { 489094332d3Sopenharmony_ci UsbdUnregisterDevice(std::string(ACM_SERVICE_NAME)); 490094332d3Sopenharmony_ci HDF_LOGE("%{public}s: acm init error", __func__); 491094332d3Sopenharmony_ci return HDF_FAILURE; 492094332d3Sopenharmony_ci } 493094332d3Sopenharmony_ci currentFuncs_ |= USB_FUNCTION_ACM; 494094332d3Sopenharmony_ci } 495094332d3Sopenharmony_ci if ((funcs & USB_FUNCTION_ECM) != 0) { 496094332d3Sopenharmony_ci ret = UsbdRegisterDevice(std::string(ECM_SERVICE_NAME)); 497094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 498094332d3Sopenharmony_ci HDF_LOGE("%{public}s: failed to register device", __func__); 499094332d3Sopenharmony_ci return HDF_FAILURE; 500094332d3Sopenharmony_ci } 501094332d3Sopenharmony_ci if (SendCmdToService(ECM_SERVICE_NAME, ECM_INIT, USB_FUNCTION_ECM) != 0) { 502094332d3Sopenharmony_ci UsbdUnregisterDevice(std::string(ECM_SERVICE_NAME)); 503094332d3Sopenharmony_ci HDF_LOGE("%{public}s: ecm init error", __func__); 504094332d3Sopenharmony_ci return HDF_FAILURE; 505094332d3Sopenharmony_ci } 506094332d3Sopenharmony_ci currentFuncs_ |= USB_FUNCTION_ACM; 507094332d3Sopenharmony_ci } 508094332d3Sopenharmony_ci if ((funcs & USB_FUNCTION_MTP) != 0 || (funcs & USB_FUNCTION_PTP) != 0) { 509094332d3Sopenharmony_ci ret = InitMtp(); 510094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 511094332d3Sopenharmony_ci HDF_LOGE("%{public}s: failed to init mtp", __func__); 512094332d3Sopenharmony_ci return HDF_FAILURE; 513094332d3Sopenharmony_ci } 514094332d3Sopenharmony_ci } 515094332d3Sopenharmony_ci return HDF_SUCCESS; 516094332d3Sopenharmony_ci} 517094332d3Sopenharmony_ci 518094332d3Sopenharmony_ciint32_t UsbdFunction::UsbdSetKernelFunction(int32_t kfuns, int32_t funcs) 519094332d3Sopenharmony_ci{ 520094332d3Sopenharmony_ci switch (kfuns) { 521094332d3Sopenharmony_ci case USB_FUNCTION_HDC: 522094332d3Sopenharmony_ci HDF_LOGI("%{public}s: set hdc", __func__); 523094332d3Sopenharmony_ci return UsbdFunction::AddHdc(); 524094332d3Sopenharmony_ci case USB_FUNCTION_RNDIS: 525094332d3Sopenharmony_ci HDF_LOGI("%{public}s: set rndis", __func__); 526094332d3Sopenharmony_ci return UsbdFunction::SetFunctionToRndis(); 527094332d3Sopenharmony_ci case USB_FUNCTION_STORAGE: 528094332d3Sopenharmony_ci HDF_LOGI("%{public}s: set mass_storage", __func__); 529094332d3Sopenharmony_ci return UsbdFunction::SetFunctionToStorage(); 530094332d3Sopenharmony_ci case USB_FUNCTION_RNDIS | USB_FUNCTION_HDC: 531094332d3Sopenharmony_ci HDF_LOGI("%{public}s: set rndis hdc", __func__); 532094332d3Sopenharmony_ci return UsbdFunction::SetFunctionToRndisHdc(); 533094332d3Sopenharmony_ci case USB_FUNCTION_STORAGE | USB_FUNCTION_HDC: 534094332d3Sopenharmony_ci HDF_LOGI("%{public}s: set storage hdc", __func__); 535094332d3Sopenharmony_ci return UsbdFunction::SetFunctionToStorageHdc(); 536094332d3Sopenharmony_ci case USB_FUNCTION_MANUFACTURE | USB_FUNCTION_HDC: 537094332d3Sopenharmony_ci HDF_LOGI("%{public}s: set manufacture hdc", __func__); 538094332d3Sopenharmony_ci return UsbdFunction::SetFunctionToManufactureHdc(); 539094332d3Sopenharmony_ci default: 540094332d3Sopenharmony_ci HDF_LOGI("%{public}s: enable device", __func__); 541094332d3Sopenharmony_ci return UsbdEnableDevice(funcs); 542094332d3Sopenharmony_ci } 543094332d3Sopenharmony_ci} 544094332d3Sopenharmony_ci 545094332d3Sopenharmony_ciint32_t UsbdFunction::UsbdSetFunction(uint32_t funcs) 546094332d3Sopenharmony_ci{ 547094332d3Sopenharmony_ci HDF_LOGI("%{public}s: UsbdSetFunction funcs=%{public}d", __func__, funcs); 548094332d3Sopenharmony_ci if ((funcs | USB_FUNCTION_SUPPORT) != USB_FUNCTION_SUPPORT) { 549094332d3Sopenharmony_ci HDF_LOGE("%{public}s: funcs invalid", __func__); 550094332d3Sopenharmony_ci return HDF_FAILURE; 551094332d3Sopenharmony_ci } 552094332d3Sopenharmony_ci 553094332d3Sopenharmony_ci uint32_t kfuns = static_cast<uint32_t>(funcs) & (~USB_DDK_FUNCTION_SUPPORT); 554094332d3Sopenharmony_ci if (UsbdFunction::SetFunctionToNone()) { 555094332d3Sopenharmony_ci HDF_LOGW("%{public}s: setFunctionToNone error", __func__); 556094332d3Sopenharmony_ci } 557094332d3Sopenharmony_ci 558094332d3Sopenharmony_ci if (funcs == USB_FUNCTION_NONE) { 559094332d3Sopenharmony_ci HDF_LOGW("%{public}s: setFunctionToNone", __func__); 560094332d3Sopenharmony_ci return HDF_SUCCESS; 561094332d3Sopenharmony_ci } 562094332d3Sopenharmony_ci 563094332d3Sopenharmony_ci if (UsbdFunction::SetDDKFunction(funcs)) { 564094332d3Sopenharmony_ci HDF_LOGE("%{public}s:SetDDKFunction error", __func__); 565094332d3Sopenharmony_ci return HDF_FAILURE; 566094332d3Sopenharmony_ci } 567094332d3Sopenharmony_ci 568094332d3Sopenharmony_ci int32_t ret = UsbdSetKernelFunction(kfuns, funcs); 569094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 570094332d3Sopenharmony_ci HDF_LOGE("%{public}s, set kernel func failed", __func__); 571094332d3Sopenharmony_ci return HDF_FAILURE; 572094332d3Sopenharmony_ci } 573094332d3Sopenharmony_ci currentFuncs_ |= kfuns; 574094332d3Sopenharmony_ci if (funcs == USB_FUNCTION_NONE) { 575094332d3Sopenharmony_ci HDF_LOGI("%{public}s, none function", __func__); 576094332d3Sopenharmony_ci return HDF_SUCCESS; 577094332d3Sopenharmony_ci } 578094332d3Sopenharmony_ci 579094332d3Sopenharmony_ci if (UsbdWaitUdc() != HDF_SUCCESS) { 580094332d3Sopenharmony_ci HDF_LOGE("%{public}s, wait udc failed", __func__); 581094332d3Sopenharmony_ci return HDF_FAILURE; 582094332d3Sopenharmony_ci } 583094332d3Sopenharmony_ci if (UsbdInitDDKFunction(funcs) != HDF_SUCCESS) { 584094332d3Sopenharmony_ci HDF_LOGE("%{public}s, init ddk func failed", __func__); 585094332d3Sopenharmony_ci UsbdFunction::SendCmdToService(DEV_SERVICE_NAME, FUNCTION_DEL, USB_DDK_FUNCTION_SUPPORT); 586094332d3Sopenharmony_ci UsbdUnregisterDevice(std::string(DEV_SERVICE_NAME)); 587094332d3Sopenharmony_ci return HDF_FAILURE; 588094332d3Sopenharmony_ci } 589094332d3Sopenharmony_ci currentFuncs_ = funcs; 590094332d3Sopenharmony_ci return HDF_SUCCESS; 591094332d3Sopenharmony_ci} 592094332d3Sopenharmony_ci 593094332d3Sopenharmony_ciint32_t UsbdFunction::UsbdGetFunction(void) 594094332d3Sopenharmony_ci{ 595094332d3Sopenharmony_ci return currentFuncs_; 596094332d3Sopenharmony_ci} 597094332d3Sopenharmony_ci 598094332d3Sopenharmony_ciint32_t UsbdFunction::UsbdUpdateFunction(uint32_t funcs) 599094332d3Sopenharmony_ci{ 600094332d3Sopenharmony_ci if ((funcs | USB_FUNCTION_SUPPORT) != USB_FUNCTION_SUPPORT && funcs != (USB_FUNCTION_HDC + USB_FUNCTION_RNDIS) && 601094332d3Sopenharmony_ci funcs != (USB_FUNCTION_HDC + USB_FUNCTION_STORAGE)) { 602094332d3Sopenharmony_ci HDF_LOGE("%{public}s: funcs invalid funcs is: %{public}d", __func__, funcs); 603094332d3Sopenharmony_ci return HDF_FAILURE; 604094332d3Sopenharmony_ci } 605094332d3Sopenharmony_ci currentFuncs_ = funcs; 606094332d3Sopenharmony_ci return HDF_SUCCESS; 607094332d3Sopenharmony_ci} 608094332d3Sopenharmony_ci 609094332d3Sopenharmony_ciint32_t UsbdFunction::UsbdRegisterDevice(const std::string &serviceName) 610094332d3Sopenharmony_ci{ 611094332d3Sopenharmony_ci int32_t ret; 612094332d3Sopenharmony_ci OHOS::sptr<IDeviceManager> devMgr = IDeviceManager::Get(); 613094332d3Sopenharmony_ci if (devMgr == nullptr) { 614094332d3Sopenharmony_ci HDF_LOGE("%{public}s: get IDeviceManager failed", __func__); 615094332d3Sopenharmony_ci return HDF_FAILURE; 616094332d3Sopenharmony_ci } 617094332d3Sopenharmony_ci ret = devMgr->LoadDevice(serviceName); 618094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 619094332d3Sopenharmony_ci HDF_LOGE("%{public}s, load %{public}s failed", __func__, serviceName.c_str()); 620094332d3Sopenharmony_ci return ret; 621094332d3Sopenharmony_ci } 622094332d3Sopenharmony_ci return ret; 623094332d3Sopenharmony_ci} 624094332d3Sopenharmony_ci 625094332d3Sopenharmony_civoid UsbdFunction::UsbdUnregisterDevice(const std::string &serviceName) 626094332d3Sopenharmony_ci{ 627094332d3Sopenharmony_ci int32_t ret; 628094332d3Sopenharmony_ci OHOS::sptr<IDeviceManager> devMgr = IDeviceManager::Get(); 629094332d3Sopenharmony_ci if (devMgr == nullptr) { 630094332d3Sopenharmony_ci HDF_LOGE("%{public}s: get devMgr object failed", __func__); 631094332d3Sopenharmony_ci return; 632094332d3Sopenharmony_ci } 633094332d3Sopenharmony_ci ret = devMgr->UnloadDevice(serviceName); 634094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 635094332d3Sopenharmony_ci HDF_LOGW("%{public}s, %{public}s unload failed", __func__, serviceName.c_str()); 636094332d3Sopenharmony_ci } 637094332d3Sopenharmony_ci} 638094332d3Sopenharmony_ci} // namespace V1_0 639094332d3Sopenharmony_ci} // namespace Usb 640094332d3Sopenharmony_ci} // namespace HDI 641094332d3Sopenharmony_ci} // namespace OHOS 642