1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
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_accessory_uevent_handle.h"
17 #include "hdf_base.h"
18 #include "hdf_log.h"
19 #include "usbd_wrapper.h"
20 #include "ddk_pnp_listener_mgr.h"
21
22 #define HDF_LOG_TAG usb_accessory_uevent
23
24 char *g_usbAccessoryUeventPath = "invalid_path";
25
26 struct UsbAccessoryUeventInfo {
27 const char *devPath;
28 const char *subSystem;
29 const char *accessory;
30 const char *devName;
31 };
32
UsbAccessoryDispatchUevent(const struct UsbAccessoryUeventInfo * info)33 static void UsbAccessoryDispatchUevent(const struct UsbAccessoryUeventInfo *info)
34 {
35 if (info == NULL) {
36 HDF_LOGE("%{public}s: info is NULL", __func__);
37 return;
38 }
39 HDF_LOGD("%{public}s: devPath: %{public}s, accessory: %{public}s", __func__, info->devPath, info->accessory);
40 if (strcmp(info->devPath, g_usbAccessoryUeventPath) != 0) {
41 return;
42 }
43 if (strcmp(info->accessory, "START") == 0) {
44 DdkListenerMgrNotifyAll(NULL, USB_ACCESSORY_START);
45 } else if (strcmp(info->accessory, "SEND") == 0) {
46 DdkListenerMgrNotifyAll(NULL, USB_ACCESSORY_SEND);
47 }
48 }
49
UsbAccessoryUeventHandle(const char msg[],ssize_t rcvLen)50 void UsbAccessoryUeventHandle(const char msg[], ssize_t rcvLen)
51 {
52 HDF_LOGD("%{public}s: msg: %{public}s, len: %{public}zd", __func__, msg, rcvLen);
53 if (rcvLen <= 0) {
54 HDF_LOGE("%{public}s: rcvLen is invalid: %{public}zd", __func__, rcvLen);
55 return;
56 }
57 char fullMsg[rcvLen + 1];
58 for (int i = 0; i < rcvLen; i++) {
59 if (msg[i] == '\0') {
60 fullMsg[i] = ' ';
61 } else {
62 fullMsg[i] = msg[i];
63 }
64 }
65 fullMsg[rcvLen] = '\0';
66
67 struct UsbAccessoryUeventInfo info = {
68 .devPath = "",
69 .subSystem = "",
70 .accessory = "",
71 .devName = ""
72 };
73 const char *msgTmp = msg;
74 while (*msgTmp && (msgTmp - msg < rcvLen)) {
75 if (strncmp(msgTmp, "DEVPATH=", strlen("DEVPATH=")) == 0) {
76 msgTmp += strlen("DEVPATH=");
77 info.devPath = msgTmp;
78 } else if (strncmp(msgTmp, "SUBSYSTEM=", strlen("SUBSYSTEM=")) == 0 &&
79 strlen(info.subSystem) == 0) { // some uevent has more than one SUBSYSTEM property
80 msgTmp += strlen("SUBSYSTEM=");
81 info.subSystem = msgTmp;
82 } else if (strncmp(msgTmp, "ACCESSORY=", strlen("ACCESSORY=")) == 0) {
83 msgTmp += strlen("ACCESSORY=");
84 info.accessory = msgTmp;
85 } else if (strncmp(msgTmp, "DEVNAME=", strlen("DEVNAME=")) == 0) {
86 msgTmp += strlen("DEVNAME=");
87 info.devName = msgTmp;
88 }
89 msgTmp += strlen(msgTmp) + 1; // 1 is a skip character '\0'
90 }
91
92 UsbAccessoryDispatchUevent(&info);
93 }
94
UsbAccessoryUeventInit(const char * ueventPath)95 int32_t UsbAccessoryUeventInit(const char *ueventPath)
96 {
97 if (ueventPath == NULL) {
98 HDF_LOGE("%{public}s invalid param", __func__);
99 return HDF_ERR_INVALID_PARAM;
100 }
101 HDF_LOGD("%{public}s: enter, ueventPath: %{public}s", __func__, ueventPath);
102
103 g_usbAccessoryUeventPath = (char *)ueventPath;
104 return HDF_SUCCESS;
105 }
106