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 #include "usb_accessory_uevent_handle.h"
34 
35 #define HDF_LOG_TAG    usb_pnp_manager
36 #define MODULENAMESIZE 128
37 const char USB_ACCESSORY_UEVENT_PATH[] = "usb_accessory_uevent_path";
38 const char USB_ACCESSORY_DEFAULT_PATH[] = "/devices/virtual/misc/usb_accessory";
39 #define USB_GADGET_UEVENT_PATH "gadget_uevent_path"
40 #define USB_GADGET_STATE_PATH "gadget_state_path"
41 
42 #ifdef USB_EMULATOR_MODE
43 const char USB_EMULATOR_DEFAULT_STATE_PATH[] =  "/sys/class/gadget_usb/gadget0/state";
44 const char USB_EMULATOR_DEFAULT_UEVENT_PATH[] = "/devices/virtual/gadget_usb/gadget0";
45 #endif
46 
UsbPnpManagerWriteModuleName(struct HdfSBuf * sbuf,const char * moduleName)47 bool UsbPnpManagerWriteModuleName(struct HdfSBuf *sbuf, const char *moduleName)
48 {
49     char modName[MODULENAMESIZE] = {0};
50     if (sprintf_s(modName, MODULENAMESIZE, "lib%s.z.so", moduleName) < 0) {
51         HDF_LOGE("%{public}s: sprintf_s modName failed", __func__);
52         return false;
53     }
54 
55     return HdfSbufWriteString(sbuf, modName);
56 }
57 
UsbPnpManagerDispatch(struct HdfDeviceIoClient * client,int32_t cmd,struct HdfSBuf * data,struct HdfSBuf * reply)58 static int32_t UsbPnpManagerDispatch(
59     struct HdfDeviceIoClient *client, int32_t cmd, struct HdfSBuf *data, struct HdfSBuf *reply)
60 {
61     (void)client;
62     (void)cmd;
63     (void)data;
64     (void)reply;
65 
66     HDF_LOGI("received cmd = %{public}d", cmd);
67     return HDF_SUCCESS;
68 }
69 
UsbPnpManagerBind(struct HdfDeviceObject * device)70 static int32_t UsbPnpManagerBind(struct HdfDeviceObject *device)
71 {
72     static struct IDeviceIoService pnpLoaderService = {
73         .Dispatch = UsbPnpManagerDispatch,
74     };
75 
76     if (device == NULL) {
77         return HDF_ERR_INVALID_OBJECT;
78     }
79 
80     device->service = &pnpLoaderService;
81     HDF_LOGI("usb pnp manager bind success");
82 
83     return HDF_SUCCESS;
84 }
85 
86 #ifdef USB_EVENT_NOTIFY_LINUX_NATIVE_MODE
UsbPnpManagerStartUeventThread(void)87 int32_t UsbPnpManagerStartUeventThread(void)
88 {
89     pthread_t tid;
90     int32_t ret = pthread_create(&tid, NULL, DdkUeventMain, NULL);
91     if (ret != 0) {
92         HDF_LOGE("%{public}s: create thread failed:%{public}d", __func__, ret);
93         return ret;
94     }
95 
96     ret = pthread_setname_np(tid, "usbpnpUeventThd");
97     if (ret != 0) {
98         HDF_LOGE("%{public}s: set thread name failed:%{public}d", __func__, ret);
99     }
100     return ret;
101 }
102 #endif
103 
UsbPnpMgrGetGadgetPath(struct HdfDeviceObject * device,const char * attrName)104 static const char *UsbPnpMgrGetGadgetPath(struct HdfDeviceObject *device, const char *attrName)
105 {
106     struct DeviceResourceIface *iface = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
107     if (iface == NULL) {
108         HDF_LOGE("%{public}s: DeviceResourceGetIfaceInstance failed", __func__);
109         return NULL;
110     }
111 
112     const char *path = NULL;
113     const char *pathDef = NULL;
114     if (device == NULL) {
115         HDF_LOGE("%{public}s: device is empty", __func__);
116         return NULL;
117     }
118 #ifdef USB_EMULATOR_MODE
119     if (iface->GetString(device->property, attrName, &path, pathDef) != HDF_SUCCESS) {
120         HDF_LOGW("%{public}s: emulator read %{public}s failed", __func__, attrName);
121 
122         if (strncmp(attrName, USB_GADGET_STATE_PATH, strlen(USB_GADGET_STATE_PATH)) == 0) {
123             path = USB_EMULATOR_DEFAULT_STATE_PATH;
124         } else if (strncmp(attrName, USB_ACCESSORY_UEVENT_PATH, strlen(USB_ACCESSORY_UEVENT_PATH)) == 0) {
125             path = USB_ACCESSORY_DEFAULT_PATH;
126         } else {
127             path = USB_EMULATOR_DEFAULT_UEVENT_PATH;
128         }
129     }
130 #else
131     if (iface->GetString(device->property, attrName, &path, pathDef) != HDF_SUCCESS) {
132         HDF_LOGW("%{public}s: emulator read %{public}s failed", __func__, attrName);
133         if (strncmp(attrName, USB_ACCESSORY_UEVENT_PATH, strlen(USB_ACCESSORY_UEVENT_PATH)) == 0) {
134             path = USB_ACCESSORY_DEFAULT_PATH;
135         }
136     }
137 #endif
138     return path;
139 }
140 
DdkUeventAndAccessoryInit(struct HdfDeviceObject * device)141 static int32_t DdkUeventAndAccessoryInit(struct HdfDeviceObject *device)
142 {
143     if (device == NULL) {
144         HDF_LOGE("%{public}s: device is NULL", __func__);
145         return HDF_FAILURE;
146     }
147     int32_t ret = DdkUeventInit(UsbPnpMgrGetGadgetPath(device, USB_GADGET_UEVENT_PATH));
148     if (ret != HDF_SUCCESS) {
149         HDF_LOGE("%{public}s: DdkUeventInit error", __func__);
150         return ret;
151     }
152 
153     ret = UsbAccessoryUeventInit(UsbPnpMgrGetGadgetPath(device, USB_ACCESSORY_UEVENT_PATH));
154     if (ret != HDF_SUCCESS) {
155         HDF_LOGD("%{public}s: UsbAccessoryUeventInit error, ret=%{public}d", __func__, ret);
156         return ret;
157     }
158 
159     return HDF_SUCCESS;
160 }
161 
UsbPnpManagerInit(struct HdfDeviceObject * device)162 static int32_t UsbPnpManagerInit(struct HdfDeviceObject *device)
163 {
164     HDF_LOGD("%{public}s: enter", __func__);
165     static struct HdfDevEventlistener usbPnpListener = {
166         .callBack = UsbDdkPnpLoaderEventReceived,
167     };
168     usbPnpListener.priv = (void *)(device);
169 
170     int32_t ret = DdkDevMgrInit(UsbPnpMgrGetGadgetPath(device, "gadget_state_path"));
171     if (ret != HDF_SUCCESS) {
172         HDF_LOGE("%{public}s: DdkDevMgrInit error", __func__);
173         return HDF_FAILURE;
174     }
175 
176     ret = DdkListenerMgrInit();
177     if (ret != HDF_SUCCESS) {
178         HDF_LOGE("%{public}s: DdkListenerMgrInit error", __func__);
179         return HDF_FAILURE;
180     }
181 
182     ret = DdkUeventAndAccessoryInit(device);
183     if (ret != HDF_SUCCESS) {
184         HDF_LOGE("%{public}s: DdkUeventAndAccessoryInit error, ret=%{public}d", __func__, ret);
185         return ret;
186     }
187 
188 #ifdef USB_EVENT_NOTIFY_LINUX_NATIVE_MODE
189     if (UsbPnpManagerStartUeventThread() != HDF_SUCCESS) {
190         HDF_LOGE("%{public}s: start uevent thread failed", __func__);
191         return HDF_FAILURE;
192     }
193 #endif
194 
195 #ifdef USB_EMULATOR_MODE
196     ret = UsbDdkPnpLoaderEventHandle();
197     if (ret != HDF_SUCCESS) {
198         HDF_LOGW("%{public}s: emulator, UsbDdkPnpLoaderEventHandle failed", __func__);
199     }
200     if (DdkListenerMgrAdd(&usbPnpListener) != HDF_SUCCESS) {
201         HDF_LOGW("%{public}s: emulator, add listener failed", __func__);
202     }
203 #else
204     ret = UsbDdkPnpLoaderEventHandle();
205     if (ret != HDF_SUCCESS) {
206         HDF_LOGE("%{public}s: UsbDdkPnpLoaderEventHandle failed", __func__);
207         return ret;
208     }
209     if (DdkListenerMgrAdd(&usbPnpListener) != HDF_SUCCESS) {
210         HDF_LOGE("%{public}s: add listener failed", __func__);
211         return HDF_FAILURE;
212     }
213 #endif
214     HDF_LOGI("UsbPnpManagerInit done");
215     return HDF_SUCCESS;
216 }
217 
UsbPnpManagerRelease(struct HdfDeviceObject * device)218 static void UsbPnpManagerRelease(struct HdfDeviceObject *device)
219 {
220     (void)device;
221     return;
222 }
223 
224 struct HdfDriverEntry g_usbPnpManagerEntry = {
225     .moduleVersion = 1,
226     .Bind = UsbPnpManagerBind,
227     .Init = UsbPnpManagerInit,
228     .Release = UsbPnpManagerRelease,
229     .moduleName = "HDF_USB_PNP_MANAGER",
230 };
231 
232 HDF_INIT(g_usbPnpManagerEntry);
233