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 "ddk_device_manager.h" 17094332d3Sopenharmony_ci 18094332d3Sopenharmony_ci#include <ctype.h> 19094332d3Sopenharmony_ci#include <dirent.h> 20094332d3Sopenharmony_ci#include <fcntl.h> 21094332d3Sopenharmony_ci#include <unistd.h> 22094332d3Sopenharmony_ci 23094332d3Sopenharmony_ci#include "ddk_sysfs_device.h" 24094332d3Sopenharmony_ci#include "hdf_base.h" 25094332d3Sopenharmony_ci#include "hdf_dlist.h" 26094332d3Sopenharmony_ci#include "hdf_io_service_if.h" 27094332d3Sopenharmony_ci#include "hdf_log.h" 28094332d3Sopenharmony_ci#include "hdf_sbuf.h" 29094332d3Sopenharmony_ci#include "osal_mem.h" 30094332d3Sopenharmony_ci#include "osal_mutex.h" 31094332d3Sopenharmony_ci#include "securec.h" 32094332d3Sopenharmony_ci#include "usbd_wrapper.h" 33094332d3Sopenharmony_ci 34094332d3Sopenharmony_ci#define HDF_LOG_TAG usb_ddk_dev_mgr 35094332d3Sopenharmony_ci#define USB_GADGET_STATE_PATH "/sys/devices/virtual/" 36094332d3Sopenharmony_cistruct UsbDdkDeviceInfo { 37094332d3Sopenharmony_ci struct OsalMutex deviceMutex; 38094332d3Sopenharmony_ci struct DListHead list; 39094332d3Sopenharmony_ci struct UsbPnpNotifyMatchInfoTable info; 40094332d3Sopenharmony_ci}; 41094332d3Sopenharmony_ci 42094332d3Sopenharmony_cistruct UsbDdkDeviceList { 43094332d3Sopenharmony_ci bool isInit; 44094332d3Sopenharmony_ci struct OsalMutex listMutex; 45094332d3Sopenharmony_ci struct DListHead devList; 46094332d3Sopenharmony_ci}; 47094332d3Sopenharmony_ci 48094332d3Sopenharmony_ci#ifdef USB_EVENT_NOTIFY_LINUX_NATIVE_MODE 49094332d3Sopenharmony_cistatic struct UsbDdkDeviceList g_ddkDevList = {.isInit = false}; 50094332d3Sopenharmony_ci#define STATE_STRING_LENGTH 20 51094332d3Sopenharmony_ci 52094332d3Sopenharmony_cichar *g_gadgetStatePath = "invalid_path"; 53094332d3Sopenharmony_ci 54094332d3Sopenharmony_cistatic struct UsbDdkDeviceInfo *DdkDevMgrIsDevExists(uint64_t devAddr) 55094332d3Sopenharmony_ci{ 56094332d3Sopenharmony_ci OsalMutexLock(&g_ddkDevList.listMutex); 57094332d3Sopenharmony_ci if (DListIsEmpty(&g_ddkDevList.devList)) { 58094332d3Sopenharmony_ci HDF_LOGI("%{public}s: the devList is empty.", __func__); 59094332d3Sopenharmony_ci OsalMutexUnlock(&g_ddkDevList.listMutex); 60094332d3Sopenharmony_ci return NULL; 61094332d3Sopenharmony_ci } 62094332d3Sopenharmony_ci 63094332d3Sopenharmony_ci struct UsbDdkDeviceInfo *res = NULL; 64094332d3Sopenharmony_ci struct UsbDdkDeviceInfo *infoPos = NULL; 65094332d3Sopenharmony_ci struct UsbDdkDeviceInfo *infoTemp = NULL; 66094332d3Sopenharmony_ci DLIST_FOR_EACH_ENTRY_SAFE(infoPos, infoTemp, &g_ddkDevList.devList, struct UsbDdkDeviceInfo, list) { 67094332d3Sopenharmony_ci if (infoPos->info.usbDevAddr == devAddr) { 68094332d3Sopenharmony_ci res = infoPos; 69094332d3Sopenharmony_ci break; 70094332d3Sopenharmony_ci } 71094332d3Sopenharmony_ci } 72094332d3Sopenharmony_ci OsalMutexUnlock(&g_ddkDevList.listMutex); 73094332d3Sopenharmony_ci return res; 74094332d3Sopenharmony_ci} 75094332d3Sopenharmony_ci 76094332d3Sopenharmony_cistatic int32_t DdkDevMgrAddDevice(struct UsbDdkDeviceInfo *device) 77094332d3Sopenharmony_ci{ 78094332d3Sopenharmony_ci if (device == NULL) { 79094332d3Sopenharmony_ci HDF_LOGE("%{public}s: invalid param", __func__); 80094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 81094332d3Sopenharmony_ci } 82094332d3Sopenharmony_ci 83094332d3Sopenharmony_ci HDF_LOGI("%{public}s: make device address and whether the device exists", __func__); 84094332d3Sopenharmony_ci if (DdkDevMgrIsDevExists(DdkSysfsMakeDevAddr(device->info.busNum, device->info.devNum)) != NULL) { 85094332d3Sopenharmony_ci HDF_LOGW("%{public}s: add device repeatedly busNum:%{public}d, devNum:%{public}d", __func__, 86094332d3Sopenharmony_ci device->info.busNum, device->info.devNum); 87094332d3Sopenharmony_ci return HDF_SUCCESS; 88094332d3Sopenharmony_ci } 89094332d3Sopenharmony_ci 90094332d3Sopenharmony_ci OsalMutexLock(&g_ddkDevList.listMutex); 91094332d3Sopenharmony_ci DListInsertTail(&device->list, &g_ddkDevList.devList); 92094332d3Sopenharmony_ci OsalMutexUnlock(&g_ddkDevList.listMutex); 93094332d3Sopenharmony_ci HDF_LOGI("%{public}s: add device successed", __func__); 94094332d3Sopenharmony_ci return HDF_SUCCESS; 95094332d3Sopenharmony_ci} 96094332d3Sopenharmony_ci 97094332d3Sopenharmony_ciint32_t DdkDevMgrRemoveDevice(int32_t busNum, int32_t devNum, struct UsbPnpNotifyMatchInfoTable *info) 98094332d3Sopenharmony_ci{ 99094332d3Sopenharmony_ci uint64_t devAddr = DdkSysfsMakeDevAddr(busNum, devNum); 100094332d3Sopenharmony_ci struct UsbDdkDeviceInfo *dev = DdkDevMgrIsDevExists(devAddr); 101094332d3Sopenharmony_ci if (dev == NULL) { 102094332d3Sopenharmony_ci HDF_LOGE("%{public}s: no device busNum:%{public}d, devNum:%{public}d", __func__, busNum, devNum); 103094332d3Sopenharmony_ci return HDF_DEV_ERR_NO_DEVICE; 104094332d3Sopenharmony_ci } 105094332d3Sopenharmony_ci 106094332d3Sopenharmony_ci int32_t ret = memcpy_s( 107094332d3Sopenharmony_ci info, sizeof(struct UsbPnpNotifyMatchInfoTable), &dev->info, sizeof(struct UsbPnpNotifyMatchInfoTable)); 108094332d3Sopenharmony_ci if (ret != EOK) { 109094332d3Sopenharmony_ci HDF_LOGE("%{public}s: memcpy_s failed", __func__); 110094332d3Sopenharmony_ci return HDF_FAILURE; 111094332d3Sopenharmony_ci } 112094332d3Sopenharmony_ci 113094332d3Sopenharmony_ci OsalMutexLock(&g_ddkDevList.listMutex); 114094332d3Sopenharmony_ci DListRemove(&dev->list); 115094332d3Sopenharmony_ci OsalMemFree(dev); 116094332d3Sopenharmony_ci dev = NULL; 117094332d3Sopenharmony_ci OsalMutexUnlock(&g_ddkDevList.listMutex); 118094332d3Sopenharmony_ci return HDF_SUCCESS; 119094332d3Sopenharmony_ci} 120094332d3Sopenharmony_ci 121094332d3Sopenharmony_cistatic int32_t DdkDevMgrInitDevice(struct UsbDdkDeviceInfo *deviceInfo) 122094332d3Sopenharmony_ci{ 123094332d3Sopenharmony_ci (void)memset_s(deviceInfo, sizeof(struct UsbDdkDeviceInfo), 0, sizeof(struct UsbDdkDeviceInfo)); 124094332d3Sopenharmony_ci int32_t ret = OsalMutexInit(&deviceInfo->deviceMutex); 125094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 126094332d3Sopenharmony_ci HDF_LOGE("%{public}s: init mutex failed", __func__); 127094332d3Sopenharmony_ci return HDF_FAILURE; 128094332d3Sopenharmony_ci } 129094332d3Sopenharmony_ci DListHeadInit(&deviceInfo->list); 130094332d3Sopenharmony_ci 131094332d3Sopenharmony_ci return HDF_SUCCESS; 132094332d3Sopenharmony_ci} 133094332d3Sopenharmony_ci 134094332d3Sopenharmony_ciconst struct UsbPnpNotifyMatchInfoTable *DdkDevMgrCreateDevice(const char *deviceDir) 135094332d3Sopenharmony_ci{ 136094332d3Sopenharmony_ci struct UsbDdkDeviceInfo *device = (struct UsbDdkDeviceInfo *)OsalMemCalloc(sizeof(struct UsbDdkDeviceInfo)); 137094332d3Sopenharmony_ci if (device == NULL) { 138094332d3Sopenharmony_ci HDF_LOGE("%{public}s: init device failed", __func__); 139094332d3Sopenharmony_ci return NULL; 140094332d3Sopenharmony_ci } 141094332d3Sopenharmony_ci 142094332d3Sopenharmony_ci int32_t status = HDF_SUCCESS; 143094332d3Sopenharmony_ci do { 144094332d3Sopenharmony_ci // init device 145094332d3Sopenharmony_ci status = DdkDevMgrInitDevice(device); 146094332d3Sopenharmony_ci if (status != HDF_SUCCESS) { 147094332d3Sopenharmony_ci HDF_LOGE("%{public}s: init device failed:%{public}d", __func__, status); 148094332d3Sopenharmony_ci break; 149094332d3Sopenharmony_ci } 150094332d3Sopenharmony_ci 151094332d3Sopenharmony_ci // get device from sysfs 152094332d3Sopenharmony_ci status = DdkSysfsGetDevice(deviceDir, &device->info); 153094332d3Sopenharmony_ci if (status != HDF_SUCCESS) { 154094332d3Sopenharmony_ci HDF_LOGE("%{public}s: sysfs get device failed:%{public}d", __func__, status); 155094332d3Sopenharmony_ci break; 156094332d3Sopenharmony_ci } 157094332d3Sopenharmony_ci 158094332d3Sopenharmony_ci // insert device to list 159094332d3Sopenharmony_ci status = DdkDevMgrAddDevice(device); 160094332d3Sopenharmony_ci if (status != HDF_SUCCESS) { 161094332d3Sopenharmony_ci HDF_LOGE("%{public}s: add device failed:%{public}d", __func__, status); 162094332d3Sopenharmony_ci break; 163094332d3Sopenharmony_ci } 164094332d3Sopenharmony_ci return &device->info; 165094332d3Sopenharmony_ci } while (0); 166094332d3Sopenharmony_ci 167094332d3Sopenharmony_ci OsalMemFree(device); 168094332d3Sopenharmony_ci return status == HDF_SUCCESS ? &device->info : NULL; 169094332d3Sopenharmony_ci} 170094332d3Sopenharmony_ci 171094332d3Sopenharmony_cistatic int32_t DdkDevMgrScanSysfs(const char *sysfsDevDir) 172094332d3Sopenharmony_ci{ 173094332d3Sopenharmony_ci if (sysfsDevDir == NULL) { 174094332d3Sopenharmony_ci HDF_LOGE("%{public}s: invalid param", __func__); 175094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 176094332d3Sopenharmony_ci } 177094332d3Sopenharmony_ci 178094332d3Sopenharmony_ci DIR *dir = opendir(sysfsDevDir); 179094332d3Sopenharmony_ci if (dir == NULL) { 180094332d3Sopenharmony_ci HDF_LOGE("%{public}s: opendir failed sysfsDevDir:%{public}s", __func__, sysfsDevDir); 181094332d3Sopenharmony_ci return HDF_ERR_BAD_FD; 182094332d3Sopenharmony_ci } 183094332d3Sopenharmony_ci 184094332d3Sopenharmony_ci struct dirent *devHandle; 185094332d3Sopenharmony_ci while ((devHandle = readdir(dir))) { 186094332d3Sopenharmony_ci // only read dir like 3-1 187094332d3Sopenharmony_ci if (devHandle->d_name[0] > '9' || devHandle->d_name[0] < '0' || strchr(devHandle->d_name, ':')) { 188094332d3Sopenharmony_ci continue; 189094332d3Sopenharmony_ci } 190094332d3Sopenharmony_ci 191094332d3Sopenharmony_ci if (DdkDevMgrCreateDevice(devHandle->d_name) == NULL) { 192094332d3Sopenharmony_ci HDF_LOGW("%{public}s: create device failed d_name:%{public}s", __func__, devHandle->d_name); 193094332d3Sopenharmony_ci } 194094332d3Sopenharmony_ci } 195094332d3Sopenharmony_ci closedir(dir); 196094332d3Sopenharmony_ci return HDF_SUCCESS; 197094332d3Sopenharmony_ci} 198094332d3Sopenharmony_ci 199094332d3Sopenharmony_ciint32_t DdkDevMgrInit(const char *gadgetStatePath) 200094332d3Sopenharmony_ci{ 201094332d3Sopenharmony_ci if (g_ddkDevList.isInit) { 202094332d3Sopenharmony_ci return HDF_SUCCESS; 203094332d3Sopenharmony_ci } 204094332d3Sopenharmony_ci 205094332d3Sopenharmony_ci if (gadgetStatePath == NULL) { 206094332d3Sopenharmony_ci HDF_LOGE("%{public}s: invalid gadgetStatePath", __func__); 207094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 208094332d3Sopenharmony_ci } 209094332d3Sopenharmony_ci 210094332d3Sopenharmony_ci g_gadgetStatePath = (char *)gadgetStatePath; 211094332d3Sopenharmony_ci int32_t ret = OsalMutexInit(&g_ddkDevList.listMutex); 212094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 213094332d3Sopenharmony_ci HDF_LOGE("%{public}s: init mutex failed", __func__); 214094332d3Sopenharmony_ci return HDF_FAILURE; 215094332d3Sopenharmony_ci } 216094332d3Sopenharmony_ci 217094332d3Sopenharmony_ci DListHeadInit(&g_ddkDevList.devList); 218094332d3Sopenharmony_ci ret = DdkDevMgrScanSysfs(SYSFS_DEVICES_DIR); 219094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 220094332d3Sopenharmony_ci HDF_LOGE("%{public}s: Scan sysfs failed ret=%{public}d", __func__, ret); 221094332d3Sopenharmony_ci return HDF_FAILURE; 222094332d3Sopenharmony_ci } 223094332d3Sopenharmony_ci g_ddkDevList.isInit = true; 224094332d3Sopenharmony_ci return HDF_SUCCESS; 225094332d3Sopenharmony_ci} 226094332d3Sopenharmony_ci 227094332d3Sopenharmony_ciint32_t DdkDevMgrForEachDeviceSafe(DdkDevMgrHandleDev handle, void *priv) 228094332d3Sopenharmony_ci{ 229094332d3Sopenharmony_ci OsalMutexLock(&g_ddkDevList.listMutex); 230094332d3Sopenharmony_ci if (DListIsEmpty(&g_ddkDevList.devList)) { 231094332d3Sopenharmony_ci HDF_LOGI("%{public}s:the devList is empty", __func__); 232094332d3Sopenharmony_ci OsalMutexUnlock(&g_ddkDevList.listMutex); 233094332d3Sopenharmony_ci return HDF_SUCCESS; 234094332d3Sopenharmony_ci } 235094332d3Sopenharmony_ci 236094332d3Sopenharmony_ci struct UsbDdkDeviceInfo *pos = NULL; 237094332d3Sopenharmony_ci struct UsbDdkDeviceInfo *tmp = NULL; 238094332d3Sopenharmony_ci DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &g_ddkDevList.devList, struct UsbDdkDeviceInfo, list) { 239094332d3Sopenharmony_ci if (handle(&pos->info, priv) != HDF_SUCCESS) { 240094332d3Sopenharmony_ci HDF_LOGW("%{public}s: handle failed", __func__); 241094332d3Sopenharmony_ci } 242094332d3Sopenharmony_ci } 243094332d3Sopenharmony_ci 244094332d3Sopenharmony_ci OsalMutexUnlock(&g_ddkDevList.listMutex); 245094332d3Sopenharmony_ci return HDF_SUCCESS; 246094332d3Sopenharmony_ci} 247094332d3Sopenharmony_ci 248094332d3Sopenharmony_ciint32_t DdkDevMgrGetGadgetLinkStatusSafe(DdkDevMgrHandleGadget handle, void *priv) 249094332d3Sopenharmony_ci{ 250094332d3Sopenharmony_ci if (priv == NULL || handle == NULL) { 251094332d3Sopenharmony_ci HDF_LOGE("%{public}s: invalid param.", __func__); 252094332d3Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 253094332d3Sopenharmony_ci } 254094332d3Sopenharmony_ci 255094332d3Sopenharmony_ci char pathBuf[PATH_MAX] = {'\0'}; 256094332d3Sopenharmony_ci if (realpath(g_gadgetStatePath, pathBuf) == NULL) { 257094332d3Sopenharmony_ci HDF_LOGE("%{public}s: path conversion failed", __func__); 258094332d3Sopenharmony_ci return HDF_FAILURE; 259094332d3Sopenharmony_ci } 260094332d3Sopenharmony_ci 261094332d3Sopenharmony_ci if (strncmp(USB_GADGET_STATE_PATH, pathBuf, strlen(USB_GADGET_STATE_PATH)) != 0) { 262094332d3Sopenharmony_ci HDF_LOGE("%{public}s: The file path is incorrect", __func__); 263094332d3Sopenharmony_ci return HDF_FAILURE; 264094332d3Sopenharmony_ci } 265094332d3Sopenharmony_ci 266094332d3Sopenharmony_ci int32_t fd = open(pathBuf, O_RDONLY | O_CLOEXEC); 267094332d3Sopenharmony_ci if (fd == -1) { 268094332d3Sopenharmony_ci HDF_LOGE("%{public}s: open %{public}s failed errno:%{public}d", __func__, g_gadgetStatePath, errno); 269094332d3Sopenharmony_ci return HDF_ERR_IO; 270094332d3Sopenharmony_ci } 271094332d3Sopenharmony_ci 272094332d3Sopenharmony_ci char buf[STATE_STRING_LENGTH] = {0}; 273094332d3Sopenharmony_ci ssize_t numRead = read(fd, buf, STATE_STRING_LENGTH); 274094332d3Sopenharmony_ci close(fd); 275094332d3Sopenharmony_ci if (numRead <= 0) { 276094332d3Sopenharmony_ci HDF_LOGE("%{public}s: read state failed errno:%{public}d", __func__, errno); 277094332d3Sopenharmony_ci return HDF_ERR_IO; 278094332d3Sopenharmony_ci } 279094332d3Sopenharmony_ci 280094332d3Sopenharmony_ci if ((strncmp(buf, "CONNECTED", strlen("CONNECTED")) == 0) || 281094332d3Sopenharmony_ci (strncmp(buf, "CONFIGURED", strlen("CONFIGURED")) == 0)) { 282094332d3Sopenharmony_ci // call back 283094332d3Sopenharmony_ci if (handle(priv) != HDF_SUCCESS) { 284094332d3Sopenharmony_ci HDF_LOGW("%{public}s: handle failed", __func__); 285094332d3Sopenharmony_ci } 286094332d3Sopenharmony_ci } 287094332d3Sopenharmony_ci 288094332d3Sopenharmony_ci return HDF_SUCCESS; 289094332d3Sopenharmony_ci} 290094332d3Sopenharmony_cibool DdkDevMgrGetGadgetLinkStatus() 291094332d3Sopenharmony_ci{ 292094332d3Sopenharmony_ci char pathBuf[PATH_MAX] = {'\0'}; 293094332d3Sopenharmony_ci if (realpath(g_gadgetStatePath, pathBuf) == NULL) { 294094332d3Sopenharmony_ci HDF_LOGE("%{public}s: path conversion failed", __func__); 295094332d3Sopenharmony_ci return false; 296094332d3Sopenharmony_ci } 297094332d3Sopenharmony_ci 298094332d3Sopenharmony_ci if (strncmp(USB_GADGET_STATE_PATH, pathBuf, strlen(USB_GADGET_STATE_PATH)) != 0) { 299094332d3Sopenharmony_ci HDF_LOGE("%{public}s: The file path is incorrect", __func__); 300094332d3Sopenharmony_ci return false; 301094332d3Sopenharmony_ci } 302094332d3Sopenharmony_ci 303094332d3Sopenharmony_ci int32_t fd = open(pathBuf, O_RDONLY | O_CLOEXEC); 304094332d3Sopenharmony_ci if (fd == -1) { 305094332d3Sopenharmony_ci HDF_LOGE("%{public}s: open %{public}s failed errno:%{public}d", __func__, g_gadgetStatePath, errno); 306094332d3Sopenharmony_ci return false; 307094332d3Sopenharmony_ci } 308094332d3Sopenharmony_ci 309094332d3Sopenharmony_ci char buf[STATE_STRING_LENGTH] = {0}; 310094332d3Sopenharmony_ci ssize_t numRead = read(fd, buf, STATE_STRING_LENGTH); 311094332d3Sopenharmony_ci close(fd); 312094332d3Sopenharmony_ci if (numRead <= 0) { 313094332d3Sopenharmony_ci HDF_LOGE("%{public}s: read state failed errno:%{public}d", __func__, errno); 314094332d3Sopenharmony_ci return false; 315094332d3Sopenharmony_ci } 316094332d3Sopenharmony_ci HDF_LOGE("%{public}s: read status:%{public}s", __func__, buf); 317094332d3Sopenharmony_ci if ((strncmp(buf, "CONNECTED", strlen("CONNECTED")) == 0) || 318094332d3Sopenharmony_ci (strncmp(buf, "CONFIGURED", strlen("CONFIGURED")) == 0)) { 319094332d3Sopenharmony_ci return true; 320094332d3Sopenharmony_ci } 321094332d3Sopenharmony_ci return false; 322094332d3Sopenharmony_ci} 323094332d3Sopenharmony_ci#else // USB_EVENT_NOTIFY_LINUX_NATIVE_MODE 324094332d3Sopenharmony_cistruct HdfIoService *g_usbPnpSrv = NULL; 325094332d3Sopenharmony_ci#define HDF_USB_INFO_MAX_SIZE (127 * sizeof(struct UsbPnpNotifyMatchInfoTable)) // 127 is max deivce num 326094332d3Sopenharmony_ciint32_t DdkDevMgrInit(const char *gadgetStatePath) 327094332d3Sopenharmony_ci{ 328094332d3Sopenharmony_ci (void)gadgetStatePath; 329094332d3Sopenharmony_ci g_usbPnpSrv = HdfIoServiceBind(USB_PNP_NOTIFY_SERVICE_NAME); 330094332d3Sopenharmony_ci if (g_usbPnpSrv == NULL) { 331094332d3Sopenharmony_ci HDF_LOGE("%{public}s: HdfIoServiceBind failed.", __func__); 332094332d3Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 333094332d3Sopenharmony_ci } 334094332d3Sopenharmony_ci return HDF_SUCCESS; 335094332d3Sopenharmony_ci} 336094332d3Sopenharmony_ci 337094332d3Sopenharmony_ciint32_t DdkDevMgrForEachDeviceSafe(DdkDevMgrHandleDev handle, void *priv) 338094332d3Sopenharmony_ci{ 339094332d3Sopenharmony_ci if (g_usbPnpSrv == NULL || handle == NULL) { 340094332d3Sopenharmony_ci HDF_LOGE("%{public}s: invalid param.", __func__); 341094332d3Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 342094332d3Sopenharmony_ci } 343094332d3Sopenharmony_ci 344094332d3Sopenharmony_ci struct HdfSBuf *reply = HdfSbufObtain(HDF_USB_INFO_MAX_SIZE); 345094332d3Sopenharmony_ci if (reply == NULL) { 346094332d3Sopenharmony_ci HDF_LOGE("%{public}s: HdfSbufObtain reply failed", __func__); 347094332d3Sopenharmony_ci return HDF_DEV_ERR_NO_MEMORY; 348094332d3Sopenharmony_ci } 349094332d3Sopenharmony_ci 350094332d3Sopenharmony_ci // request device list from pnp service 351094332d3Sopenharmony_ci int32_t ret = g_usbPnpSrv->dispatcher->Dispatch(&g_usbPnpSrv->object, USB_PNP_DRIVER_GETDEVICES, NULL, reply); 352094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 353094332d3Sopenharmony_ci HDF_LOGE("%{public}s:failed to send service call, ret:%{public}d", __func__, ret); 354094332d3Sopenharmony_ci HdfSbufRecycle(reply); 355094332d3Sopenharmony_ci return ret; 356094332d3Sopenharmony_ci } 357094332d3Sopenharmony_ci 358094332d3Sopenharmony_ci // read device list 359094332d3Sopenharmony_ci int32_t count = 0; 360094332d3Sopenharmony_ci if (!HdfSbufReadInt32(reply, &count)) { 361094332d3Sopenharmony_ci HDF_LOGE("%{public}s: failed to read count from reply", __func__); 362094332d3Sopenharmony_ci HdfSbufRecycle(reply); 363094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 364094332d3Sopenharmony_ci } 365094332d3Sopenharmony_ci 366094332d3Sopenharmony_ci HDF_LOGI("%{public}s: total obj num count:%{public}d ", __func__, count); 367094332d3Sopenharmony_ci struct UsbPnpNotifyMatchInfoTable *info = NULL; 368094332d3Sopenharmony_ci uint32_t infoSize = 0; 369094332d3Sopenharmony_ci for (int32_t i = 0; i < count; ++i) { 370094332d3Sopenharmony_ci if (!HdfSbufReadBuffer(reply, (const void **)(&info), &infoSize) || info == NULL) { 371094332d3Sopenharmony_ci HDF_LOGE("%{public}s: HdfSbufReadBuffer failed", __func__); 372094332d3Sopenharmony_ci HdfSbufRecycle(reply); 373094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 374094332d3Sopenharmony_ci } 375094332d3Sopenharmony_ci // call back 376094332d3Sopenharmony_ci if (handle(info, priv) != HDF_SUCCESS) { 377094332d3Sopenharmony_ci HDF_LOGW("%{public}s: handle failed", __func__); 378094332d3Sopenharmony_ci } 379094332d3Sopenharmony_ci } 380094332d3Sopenharmony_ci 381094332d3Sopenharmony_ci HdfSbufRecycle(reply); 382094332d3Sopenharmony_ci return HDF_SUCCESS; 383094332d3Sopenharmony_ci} 384094332d3Sopenharmony_ci 385094332d3Sopenharmony_cistatic int32_t DdkDevMgrGetGadgetStatus(int32_t *gadgetStatus) 386094332d3Sopenharmony_ci{ 387094332d3Sopenharmony_ci if (g_usbPnpSrv == NULL) { 388094332d3Sopenharmony_ci HDF_LOGE("%{public}s: invalid param.", __func__); 389094332d3Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 390094332d3Sopenharmony_ci } 391094332d3Sopenharmony_ci 392094332d3Sopenharmony_ci struct HdfSBuf *reply = HdfSbufObtain(HDF_USB_INFO_MAX_SIZE); 393094332d3Sopenharmony_ci if (reply == NULL) { 394094332d3Sopenharmony_ci HDF_LOGE("%{public}s: HdfSbufObtain reply failed", __func__); 395094332d3Sopenharmony_ci return HDF_DEV_ERR_NO_MEMORY; 396094332d3Sopenharmony_ci } 397094332d3Sopenharmony_ci 398094332d3Sopenharmony_ci int32_t ret = 399094332d3Sopenharmony_ci g_usbPnpSrv->dispatcher->Dispatch(&g_usbPnpSrv->object, USB_PNP_DRIVER_GET_GADGET_LINK_STATUS, NULL, reply); 400094332d3Sopenharmony_ci if (ret != HDF_SUCCESS) { 401094332d3Sopenharmony_ci HDF_LOGE("%{public}s:failed to send service call, ret:%{public}d", __func__, ret); 402094332d3Sopenharmony_ci HdfSbufRecycle(reply); 403094332d3Sopenharmony_ci return ret; 404094332d3Sopenharmony_ci } 405094332d3Sopenharmony_ci 406094332d3Sopenharmony_ci if (!HdfSbufReadInt32(reply, gadgetStatus)) { 407094332d3Sopenharmony_ci HDF_LOGE("%{public}s: failed to read count from reply", __func__); 408094332d3Sopenharmony_ci HdfSbufRecycle(reply); 409094332d3Sopenharmony_ci return HDF_ERR_INVALID_PARAM; 410094332d3Sopenharmony_ci } 411094332d3Sopenharmony_ci 412094332d3Sopenharmony_ci HdfSbufRecycle(reply); 413094332d3Sopenharmony_ci return HDF_SUCCESS; 414094332d3Sopenharmony_ci} 415094332d3Sopenharmony_ci 416094332d3Sopenharmony_ciint32_t DdkDevMgrGetGadgetLinkStatusSafe(DdkDevMgrHandleGadget handle, void *priv) 417094332d3Sopenharmony_ci{ 418094332d3Sopenharmony_ci if (priv == NULL || handle == NULL) { 419094332d3Sopenharmony_ci HDF_LOGE("%{public}s: invalid param.", __func__); 420094332d3Sopenharmony_ci return HDF_ERR_INVALID_OBJECT; 421094332d3Sopenharmony_ci } 422094332d3Sopenharmony_ci int32_t gadgetStatus = 0; 423094332d3Sopenharmony_ci if (DdkDevMgrGetGadgetStatus(&gadgetStatus) != HDF_SUCCESS) { 424094332d3Sopenharmony_ci HDF_LOGE("%{public}s: DdkDevMgrGetGadgetStatus failed", __func__); 425094332d3Sopenharmony_ci return HDF_FAILURE; 426094332d3Sopenharmony_ci } 427094332d3Sopenharmony_ci // gadget add 428094332d3Sopenharmony_ci if (gadgetStatus != 0) { 429094332d3Sopenharmony_ci // call back 430094332d3Sopenharmony_ci if (handle(priv) != HDF_SUCCESS) { 431094332d3Sopenharmony_ci HDF_LOGW("%{public}s: handle failed", __func__); 432094332d3Sopenharmony_ci } 433094332d3Sopenharmony_ci } 434094332d3Sopenharmony_ci return HDF_SUCCESS; 435094332d3Sopenharmony_ci} 436094332d3Sopenharmony_ci 437094332d3Sopenharmony_cibool DdkDevMgrGetGadgetLinkStatus() 438094332d3Sopenharmony_ci{ 439094332d3Sopenharmony_ci int32_t gadgetStatus = 0; 440094332d3Sopenharmony_ci if (DdkDevMgrGetGadgetStatus(&gadgetStatus) != HDF_SUCCESS) { 441094332d3Sopenharmony_ci HDF_LOGE("%{public}s: DdkDevMgrGetGadgetStatus failed", __func__); 442094332d3Sopenharmony_ci return false; 443094332d3Sopenharmony_ci } 444094332d3Sopenharmony_ci // gadget add 445094332d3Sopenharmony_ci if (gadgetStatus != 0) { 446094332d3Sopenharmony_ci return gadgetStatus == USB_PNP_DRIVER_GADGET_ADD ? true : false; 447094332d3Sopenharmony_ci } 448094332d3Sopenharmony_ci return false; 449094332d3Sopenharmony_ci} 450094332d3Sopenharmony_ci#endif // USB_EVENT_NOTIFY_LINUX_NATIVE_MODE 451