1/* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "usb_pnp_manager.h" 17#include <pthread.h> 18#include <unistd.h> 19 20#include "ddk_device_manager.h" 21#include "ddk_pnp_listener_mgr.h" 22#include "ddk_uevent_handle.h" 23#include "device_resource_if.h" 24#include "hdf_base.h" 25#include "hdf_device_desc.h" 26#include "hdf_device_object.h" 27#include "hdf_io_service_if.h" 28#include "hdf_log.h" 29#include "osal_mem.h" 30#include "securec.h" 31#include "usb_ddk_pnp_loader.h" 32#include "usbd_wrapper.h" 33 34#define HDF_LOG_TAG usb_pnp_manager 35#define MODULENAMESIZE 128 36 37#ifdef USB_EMULATOR_MODE 38#define USB_GADGET_STATE_PATH "gadget_state_path" 39#define USB_GADGET_UEVENT_PATH "gadget_uevent_path" 40const char USB_EMULATOR_DEFAULT_STATE_PATH[] = "/sys/class/gadget_usb/gadget0/state"; 41const char USB_EMULATOR_DEFAULT_UEVENT_PATH[] = "/devices/virtual/gadget_usb/gadget0"; 42#endif 43 44bool UsbPnpManagerWriteModuleName(struct HdfSBuf *sbuf, const char *moduleName) 45{ 46 char modName[MODULENAMESIZE] = {0}; 47 if (sprintf_s(modName, MODULENAMESIZE, "lib%s.z.so", moduleName) < 0) { 48 HDF_LOGE("%{public}s: sprintf_s modName failed", __func__); 49 return false; 50 } 51 52 return HdfSbufWriteString(sbuf, modName); 53} 54 55static int32_t UsbPnpManagerDispatch( 56 struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply) 57{ 58 (void)client; 59 (void)cmd; 60 (void)data; 61 (void)reply; 62 63 HDF_LOGI("received cmd = %{public}d", cmd); 64 return HDF_SUCCESS; 65} 66 67static int32_t UsbPnpManagerBind(struct HdfDeviceObject *device) 68{ 69 static struct IDeviceIoService pnpLoaderService = { 70 .Dispatch = UsbPnpManagerDispatch, 71 }; 72 73 if (device == NULL) { 74 return HDF_ERR_INVALID_OBJECT; 75 } 76 77 device->service = &pnpLoaderService; 78 HDF_LOGI("usb pnp manager bind success"); 79 80 return HDF_SUCCESS; 81} 82 83#ifdef USB_EVENT_NOTIFY_LINUX_NATIVE_MODE 84int32_t UsbPnpManagerStartUeventThread(void) 85{ 86 pthread_t tid; 87 int32_t ret = pthread_create(&tid, NULL, DdkUeventMain, NULL); 88 if (ret != 0) { 89 HDF_LOGE("%{public}s: create thread failed:%{public}d", __func__, ret); 90 return ret; 91 } 92 93 ret = pthread_setname_np(tid, "usbpnpUeventThd"); 94 if (ret != 0) { 95 HDF_LOGE("%{public}s: set thread name failed:%{public}d", __func__, ret); 96 } 97 return ret; 98} 99#endif 100 101static const char *UsbPnpMgrGetGadgetPath(struct HdfDeviceObject *device, const char *attrName) 102{ 103 struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); 104 if (iface == NULL) { 105 HDF_LOGE("%{public}s: DeviceResourceGetIfaceInstance failed", __func__); 106 return NULL; 107 } 108 109 const char *path = NULL; 110 const char *pathDef = NULL; 111 if (device == NULL) { 112 HDF_LOGE("%{public}s: device is empty", __func__); 113 return NULL; 114 } 115#ifdef USB_EMULATOR_MODE 116 if (iface->GetString(device->property, attrName, &path, pathDef) != HDF_SUCCESS) { 117 HDF_LOGW("%{public}s: emulator read %{public}s failed", __func__, attrName); 118 119 if (strncmp(attrName, USB_GADGET_STATE_PATH, strlen(USB_GADGET_STATE_PATH)) == 0) { 120 path = USB_EMULATOR_DEFAULT_STATE_PATH; 121 } else { 122 path = USB_EMULATOR_DEFAULT_UEVENT_PATH; 123 } 124 } 125#else 126 if (iface->GetString(device->property, attrName, &path, pathDef) != HDF_SUCCESS) { 127 HDF_LOGE("%{public}s: read %{public}s failed", __func__, attrName); 128 return NULL; 129 } 130#endif 131 return path; 132} 133 134static int32_t UsbPnpManagerInit(struct HdfDeviceObject *device) 135{ 136 static struct HdfDevEventlistener usbPnpListener = { 137 .callBack = UsbDdkPnpLoaderEventReceived, 138 }; 139 usbPnpListener.priv = (void *)(device); 140 141 int32_t ret = DdkDevMgrInit(UsbPnpMgrGetGadgetPath(device, "gadget_state_path")); 142 if (ret != HDF_SUCCESS) { 143 HDF_LOGE("%{public}s: DdkDevMgrInit error", __func__); 144 return HDF_FAILURE; 145 } 146 147 ret = DdkListenerMgrInit(); 148 if (ret != HDF_SUCCESS) { 149 HDF_LOGE("%{public}s: DdkListenerMgrInit error", __func__); 150 return HDF_FAILURE; 151 } 152 153 ret = DdkUeventInit(UsbPnpMgrGetGadgetPath(device, "gadget_uevent_path")); 154 if (ret != HDF_SUCCESS) { 155 HDF_LOGE("%{public}s: DdkUeventInit error", __func__); 156 return ret; 157 } 158#ifdef USB_EVENT_NOTIFY_LINUX_NATIVE_MODE 159 if (UsbPnpManagerStartUeventThread() != HDF_SUCCESS) { 160 HDF_LOGE("%{public}s: start uevent thread failed", __func__); 161 return HDF_FAILURE; 162 } 163#endif 164 165#ifdef USB_EMULATOR_MODE 166 ret = UsbDdkPnpLoaderEventHandle(); 167 if (ret != HDF_SUCCESS) { 168 HDF_LOGW("%{public}s: emulator, UsbDdkPnpLoaderEventHandle failed", __func__); 169 } 170 if (DdkListenerMgrAdd(&usbPnpListener) != HDF_SUCCESS) { 171 HDF_LOGW("%{public}s: emulator, add listener failed", __func__); 172 } 173#else 174 ret = UsbDdkPnpLoaderEventHandle(); 175 if (ret != HDF_SUCCESS) { 176 HDF_LOGE("%{public}s: UsbDdkPnpLoaderEventHandle failed", __func__); 177 return ret; 178 } 179 if (DdkListenerMgrAdd(&usbPnpListener) != HDF_SUCCESS) { 180 HDF_LOGE("%{public}s: add listener failed", __func__); 181 return HDF_FAILURE; 182 } 183#endif 184 HDF_LOGI("UsbPnpManagerInit done"); 185 return HDF_SUCCESS; 186} 187 188static void UsbPnpManagerRelease(struct HdfDeviceObject *device) 189{ 190 (void)device; 191 return; 192} 193 194struct HdfDriverEntry g_usbPnpManagerEntry = { 195 .moduleVersion = 1, 196 .Bind = UsbPnpManagerBind, 197 .Init = UsbPnpManagerInit, 198 .Release = UsbPnpManagerRelease, 199 .moduleName = "HDF_USB_PNP_MANAGER", 200}; 201 202HDF_INIT(g_usbPnpManagerEntry); 203