1 /*
2  * Copyright (c) 2022-2023 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 "hdf_audio_pnp_uevent.h"
17 #include <ctype.h>
18 #include <dirent.h>
19 #include <errno.h>
20 #include <fcntl.h>
21 
22 #include <linux/netlink.h>
23 
24 #include <poll.h>
25 #include <pthread.h>
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <sys/socket.h>
29 #include <sys/types.h>
30 #include <unistd.h>
31 
32 #include "audio_uhdf_log.h"
33 #include "hdf_audio_pnp_server.h"
34 #include "hdf_base.h"
35 #include "hdf_device_object.h"
36 #include "osal_time.h"
37 #include "securec.h"
38 
39 #define HDF_LOG_TAG HDF_AUDIO_HOST
40 
41 #define UEVENT_ACTION           "ACTION="
42 #define UEVENT_NAME             "NAME="
43 #define UEVENT_STATE            "STATE="
44 #define UEVENT_DEV_NAME         "DEVNAME="
45 #define UEVENT_DEVTYPE          "DEVTYPE="
46 #define UEVENT_SUBSYSTEM        "SUBSYSTEM="
47 #define UEVENT_SWITCH_NAME      "SWITCH_NAME="
48 #define UEVENT_SWITCH_STATE     "SWITCH_STATE="
49 #define UEVENT_ID_MODEL         "ID_MODEL="
50 #define UEVENT_HDI_NAME         "HID_NAME="
51 #define UEVENT_ACTION_ADD       "add"
52 #define UEVENT_ACTION_REMOVE    "remove"
53 #define UEVENT_ACTION_CHANGE    "change"
54 #define UEVENT_TYPE_EXTCON      "extcon3"
55 #define UEVENT_NAME_HEADSET     "headset"
56 #define UEVENT_STATE_ANALOG_HS0 "MICROPHONE=0"
57 #define UEVENT_STATE_ANALOG_HS1 "MICROPHONE=1"
58 #define UEVENT_SUBSYSTEM_SWITCH "switch"
59 #define UEVENT_SWITCH_NAME_H2W  "h2w"
60 #define UEVENT_USB_AUDIO        "USB Audio"
61 #define UEVENT_USB_HEADSET      "HEADSET"
62 #define UEVENT_SUBSYSTEM_USB        "usb"
63 #define UEVENT_SUBSYSTEM_USB_DEVICE "usb_device"
64 
65 #define UEVENT_SOCKET_BUFF_SIZE (64 * 1024)
66 #define UEVENT_SOCKET_GROUPS    0xffffffff
67 #define UEVENT_MSG_LEN          2048
68 #define AUDIO_EVENT_INFO_LEN_MAX 256
69 #define UEVENT_POLL_WAIT_TIME 100
70 #define AUDIO_UEVENT_USB_DEVICE_COUNT 10
71 
72 #define USB_DEV_NAME_LEN_MAX    64
73 #define USB_DES_LEN_MAX         4096
74 #define DEV_BUS_USB_DIR         "/dev/bus/usb"
75 #define BUS_USB_DIR             "bus/usb"
76 #define USB_IF_DESC_LEN         9
77 #define USB_IF_CLASS_OFFSET     5
78 #define USB_IF_SUBCLASS_OFFSET  6
79 #define USB_AUDIO_DESC_TYPE     0x4
80 #define USB_AUDIO_CLASS         1
81 #define USB_AUDIO_SUBCLASS_CTRL 1
82 #define AUDIO_DEVICE_ONLINE     1
83 #define AUDIO_DEVICE_WAIT_ONLINE 20
84 #define AUDIO_DEVICE_WAIT_TRY_TIME 10
85 #define AUDIO_DEVICE_WAIT_USB_ONLINE 1000
86 #define AUDIO_DEVICE_WAIT_USB_HEADSET_ONLINE 150
87 #define UEVENT_ARR_SIZE 9
88 #define MOVE_NUM 16
89 
90 #define REMOVE_AUDIO_DEVICE '0'
91 #define ADD_DEVICE_HEADSET '1'
92 #define ADD_DEVICE_HEADSET_WITHOUT_MIC '2'
93 #define ADD_DEVICE_ADAPTER '4'
94 
95 struct UsbDevice {
96     int8_t devName[USB_DEV_NAME_LEN_MAX];
97     uint8_t desc[USB_DES_LEN_MAX];
98     size_t descLen;
99 };
100 
101 struct AudioPnpUevent {
102     const char *action;
103     const char *name;
104     const char *state;
105     const char *devType;
106     const char *subSystem;
107     const char *switchName;
108     const char *switchState;
109     const char *hidName;
110     const char *devName;
111 };
112 
113 struct AudioEvent g_audioPnpDeviceState = {
114     .eventType = AUDIO_EVENT_UNKNOWN,
115     .deviceType = AUDIO_DEVICE_UNKNOWN,
116 };
117 
IsUpdatePnpDeviceState(struct AudioEvent * pnpDeviceEvent)118 static bool IsUpdatePnpDeviceState(struct AudioEvent *pnpDeviceEvent)
119 {
120     if (pnpDeviceEvent->eventType == g_audioPnpDeviceState.eventType &&
121         pnpDeviceEvent->deviceType == g_audioPnpDeviceState.deviceType) {
122         return false;
123     }
124     return true;
125 }
126 
UpdatePnpDeviceState(struct AudioEvent * pnpDeviceEvent)127 static void UpdatePnpDeviceState(struct AudioEvent *pnpDeviceEvent)
128 {
129     g_audioPnpDeviceState.eventType = pnpDeviceEvent->eventType;
130     g_audioPnpDeviceState.deviceType = pnpDeviceEvent->deviceType;
131 }
132 
CheckUsbDesc(struct UsbDevice * usbDevice)133 static int32_t CheckUsbDesc(struct UsbDevice *usbDevice)
134 {
135     if (usbDevice->descLen > USB_DES_LEN_MAX) {
136         AUDIO_FUNC_LOGE("usbDevice->descLen is more than USB_DES_LEN_MAX");
137         return HDF_ERR_INVALID_PARAM;
138     }
139     for (size_t len = 0; len < usbDevice->descLen;) {
140         size_t descLen = usbDevice->desc[len];
141         if (descLen == 0) {
142             AUDIO_FUNC_LOGE("descLen is 0");
143             return HDF_ERR_INVALID_PARAM;
144         }
145 
146         if (descLen < USB_IF_DESC_LEN) {
147             len += descLen;
148             continue;
149         }
150 
151         int32_t descType = usbDevice->desc[len + 1];
152         if (descType != USB_AUDIO_DESC_TYPE) {
153             len += descLen;
154             continue;
155         }
156 
157         /* According to the 1.0 and 2.0 usb standard protocols, the audio field corresponding to the interface
158          * description type is: offset=1 interface descriptor type is 4; offset=5 interface class,audio is 1; offset=6
159          * interface subclass,audio control is 1 */
160         int32_t usbClass = usbDevice->desc[len + USB_IF_CLASS_OFFSET];
161         int32_t subClass = usbDevice->desc[len + USB_IF_SUBCLASS_OFFSET];
162         if (usbClass == USB_AUDIO_CLASS && subClass == USB_AUDIO_SUBCLASS_CTRL) {
163             AUDIO_FUNC_LOGI(
164                 "descType %{public}d, usbClass %{public}d, subClass %{public}d", descType, usbClass, subClass);
165             return AUDIO_DEVICE_ONLINE;
166         }
167         len += descLen;
168     }
169     return HDF_SUCCESS;
170 }
171 
ReadAndScanUsbDev(const char * devPath)172 static int32_t ReadAndScanUsbDev(const char *devPath)
173 {
174     FILE *fp = NULL;
175     struct UsbDevice usbDevice;
176     size_t len;
177     errno_t error;
178     uint32_t tryTime = 0;
179     char realpathRes[PATH_MAX + 1] = {'\0'};
180 
181     if (devPath == NULL) {
182         AUDIO_FUNC_LOGE("audio devPath null");
183         return HDF_FAILURE;
184     }
185 
186     while (tryTime < AUDIO_DEVICE_WAIT_TRY_TIME) {
187         if (realpath(devPath, realpathRes) != NULL) {
188             break;
189         }
190 
191         tryTime++;
192         AUDIO_FUNC_LOGW("audio try[%{public}d] realpath fail[%{public}d]", tryTime, errno);
193         OsalMSleep(AUDIO_DEVICE_WAIT_ONLINE);
194     }
195 
196     fp = fopen(realpathRes, "r");
197     if (fp == NULL) {
198         AUDIO_FUNC_LOGE("audio realpath open fail[%{public}d]", errno);
199         return HDF_FAILURE;
200     }
201 
202     len = fread(usbDevice.desc, 1, sizeof(usbDevice.desc) - 1, fp);
203     if (len == 0) {
204         AUDIO_FUNC_LOGE("audio realpath read fail");
205         (void)fclose(fp);
206         return HDF_FAILURE;
207     }
208     (void)fclose(fp);
209 
210     error = strncpy_s((char *)usbDevice.devName, sizeof(usbDevice.devName), realpathRes, sizeof(usbDevice.devName) - 1);
211     if (error != EOK) {
212         AUDIO_FUNC_LOGE("audio realpath strncpy fail");
213         return HDF_FAILURE;
214     }
215 
216     usbDevice.descLen = len;
217     return CheckUsbDesc(&usbDevice);
218 }
219 
220 #define SWITCH_STATE_PATH    "/sys/class/switch/h2w/state"
221 #define STATE_PATH_ITEM_SIZE 1
222 
DetectAnalogHeadsetState(struct AudioEvent * audioEvent)223 static int32_t DetectAnalogHeadsetState(struct AudioEvent *audioEvent)
224 {
225     int8_t state = 0;
226     FILE *fp = fopen(SWITCH_STATE_PATH, "r");
227     if (fp == NULL) {
228         AUDIO_FUNC_LOGE("audio open switch state node fail, %{public}d", errno);
229         return HDF_ERR_INVALID_PARAM;
230     }
231 
232     size_t ret = fread(&state, STATE_PATH_ITEM_SIZE, STATE_PATH_ITEM_SIZE, fp);
233     if (ret == 0) {
234         (void)fclose(fp);
235         AUDIO_FUNC_LOGE("audio read switch state node fail, %{public}d", errno);
236         return HDF_FAILURE;
237     }
238 
239     AUDIO_FUNC_LOGI("audio switch state = %{public}c", state);
240     if (state == '0') {
241         audioEvent->eventType = AUDIO_DEVICE_REMOVE;
242         audioEvent->deviceType = AUDIO_HEADSET;
243     } else {
244         audioEvent->eventType = AUDIO_DEVICE_ADD;
245         audioEvent->deviceType = AUDIO_HEADSET;
246     }
247 
248     (void)fclose(fp);
249     return HDF_SUCCESS;
250 }
251 
252 struct AudioDevBusUsbDevice {
253     bool isUsed;
254     int8_t devName[USB_DEV_NAME_LEN_MAX];
255 };
256 
257 struct AudioDevBusUsbDevice g_audioUsbDeviceList[AUDIO_UEVENT_USB_DEVICE_COUNT] = {0};
258 
FindAudioUsbDevice(const char * devName)259 static bool FindAudioUsbDevice(const char *devName)
260 {
261     if (strlen(devName) > USB_DEV_NAME_LEN_MAX - 1) {
262         AUDIO_FUNC_LOGE("find usb audio device name exceed max len");
263         return false;
264     }
265 
266     for (uint32_t i = 0; i < AUDIO_UEVENT_USB_DEVICE_COUNT; i++) {
267         if (g_audioUsbDeviceList[i].isUsed &&
268             (strncmp((char *)g_audioUsbDeviceList[i].devName, devName, strlen(devName)) == EOK)) {
269             return true;
270         }
271     }
272     return false;
273 }
AddAudioUsbDevice(const char * devName)274 static bool AddAudioUsbDevice(const char *devName)
275 {
276     if (strlen(devName) > USB_DEV_NAME_LEN_MAX - 1) {
277         AUDIO_FUNC_LOGE("add usb audio device name exceed max len");
278         return false;
279     }
280 
281     if (FindAudioUsbDevice(devName)) {
282         AUDIO_FUNC_LOGI("find usb audio device name[%{public}s]", devName);
283         return true;
284     }
285 
286     for (uint32_t i = 0; i < AUDIO_UEVENT_USB_DEVICE_COUNT; i++) {
287         if (g_audioUsbDeviceList[i].isUsed) {
288             continue;
289         }
290         if (strncpy_s((char *)g_audioUsbDeviceList[i].devName, USB_DEV_NAME_LEN_MAX, devName, strlen(devName)) != EOK) {
291             AUDIO_FUNC_LOGE("add usb audio device name fail");
292             return false;
293         }
294         g_audioUsbDeviceList[i].isUsed = true;
295         return true;
296     }
297     AUDIO_FUNC_LOGE("add usb audio device name fail");
298     return false;
299 }
300 
DeleteAudioUsbDevice(const char * devName)301 static bool DeleteAudioUsbDevice(const char *devName)
302 {
303     if (strlen(devName) > USB_DEV_NAME_LEN_MAX - 1) {
304         AUDIO_FUNC_LOGE("delete usb audio device name exceed max len");
305         return false;
306     }
307 
308     for (uint32_t i = 0; i < AUDIO_UEVENT_USB_DEVICE_COUNT; i++) {
309         if (g_audioUsbDeviceList[i].isUsed &&
310             strncmp((char *)g_audioUsbDeviceList[i].devName, devName, strlen(devName)) == EOK) {
311             g_audioUsbDeviceList[i].isUsed = false;
312             AUDIO_FUNC_LOGI("delete usb audio device name[%{public}s]", devName);
313             return true;
314         }
315     }
316 
317     return false;
318 }
319 
CheckAudioUsbDevice(const char * devName)320 static bool CheckAudioUsbDevice(const char *devName)
321 {
322     int32_t state = 0;
323     int32_t len;
324     char subDir[USB_DEV_NAME_LEN_MAX] = {0};
325 
326     if (*devName == '\0') {
327         return false;
328     }
329     len = snprintf_s(subDir, USB_DEV_NAME_LEN_MAX, USB_DEV_NAME_LEN_MAX - 1, "/dev/" "%s", devName);
330     if (len < 0) {
331         AUDIO_FUNC_LOGE("audio snprintf dev dir fail");
332         return false;
333     }
334 
335     AUDIO_FUNC_LOGI("usb device name[%{public}s]", devName);
336     state = ReadAndScanUsbDev(subDir);
337     if ((state == AUDIO_DEVICE_ONLINE) && AddAudioUsbDevice(devName)) {
338         return true;
339     }
340     return false;
341 }
342 
IsBadName(const char * name)343 static inline bool IsBadName(const char *name)
344 {
345     if (*name == '\0') {
346         AUDIO_FUNC_LOGE("name is null");
347         return true;
348     }
349 
350     while (*name != '\0') {
351         if (isdigit(*name++) == 0) {
352             return true;
353         }
354     }
355 
356     return false;
357 }
358 
ScanUsbBusSubDir(const char * subDir)359 static int32_t ScanUsbBusSubDir(const char *subDir)
360 {
361     int32_t len;
362     DIR *devDir = NULL;
363     struct dirent *dirEnt = NULL;
364 
365     char devName[USB_DEV_NAME_LEN_MAX] = {0};
366 
367     devDir = opendir(subDir);
368     if (devDir == NULL) {
369         AUDIO_FUNC_LOGE("open usb sub dir failed");
370         return HDF_ERR_INVALID_PARAM;
371     }
372 
373     int32_t state = HDF_SUCCESS;
374     while (((dirEnt = readdir(devDir)) != NULL) && (state == HDF_SUCCESS)) {
375         if (IsBadName(dirEnt->d_name)) {
376             continue;
377         }
378 
379         len = snprintf_s(devName, USB_DEV_NAME_LEN_MAX, USB_DEV_NAME_LEN_MAX - 1, "%s/%s", subDir, dirEnt->d_name);
380         if (len < 0) {
381             AUDIO_FUNC_LOGE("audio snprintf dev dir fail");
382             state = HDF_FAILURE;
383             break;
384         }
385 
386         AUDIO_FUNC_LOGD("audio usb dir[%{public}s]", devName);
387         state = ReadAndScanUsbDev(devName);
388         if (state == AUDIO_DEVICE_ONLINE) {
389             char *subDevName = devName + strlen("/dev/");
390             AUDIO_FUNC_LOGI("audio sub dev dir=[%{public}s]", subDevName);
391             if (AddAudioUsbDevice(subDevName)) {
392                 AUDIO_FUNC_LOGI("audio add usb audio device success");
393                 break;
394             }
395         }
396     }
397 
398     closedir(devDir);
399     return state;
400 }
401 
DetectUsbHeadsetState(struct AudioEvent * audioEvent)402 static int32_t DetectUsbHeadsetState(struct AudioEvent *audioEvent)
403 {
404     int32_t len;
405     DIR *busDir = NULL;
406     struct dirent *dirEnt = NULL;
407 
408     char subDir[USB_DEV_NAME_LEN_MAX] = {0};
409 
410     busDir = opendir(DEV_BUS_USB_DIR);
411     if (busDir == NULL) {
412         AUDIO_FUNC_LOGE("open usb dir failed");
413         return HDF_ERR_INVALID_PARAM;
414     }
415 
416     int32_t state = HDF_SUCCESS;
417     while (((dirEnt = readdir(busDir)) != NULL) && (state == HDF_SUCCESS)) {
418         if (IsBadName(dirEnt->d_name)) {
419             continue;
420         }
421 
422         len = snprintf_s(subDir, USB_DEV_NAME_LEN_MAX, USB_DEV_NAME_LEN_MAX - 1, DEV_BUS_USB_DIR "/%s", dirEnt->d_name);
423         if (len < 0) {
424             AUDIO_FUNC_LOGE("audio snprintf dev dir fail");
425             break;
426         }
427 
428         state = ScanUsbBusSubDir(subDir);
429         if (state == AUDIO_DEVICE_ONLINE) {
430             audioEvent->eventType = AUDIO_DEVICE_ADD;
431             audioEvent->deviceType = AUDIO_USB_HEADSET;
432             closedir(busDir);
433             return HDF_SUCCESS;
434         }
435     }
436 
437     closedir(busDir);
438     return HDF_FAILURE;
439 }
440 
AudioUsbHeadsetDetectDevice(struct AudioPnpUevent * audioPnpUevent)441 static int32_t AudioUsbHeadsetDetectDevice(struct AudioPnpUevent *audioPnpUevent)
442 {
443     struct AudioEvent audioEvent = {0};
444 
445     if (audioPnpUevent == NULL) {
446         AUDIO_FUNC_LOGE("audioPnpUevent is null");
447         return HDF_ERR_INVALID_PARAM;
448     }
449 
450     if (audioPnpUevent->action == NULL || audioPnpUevent->devName == NULL || audioPnpUevent->subSystem == NULL ||
451         audioPnpUevent->devType == NULL) {
452         AUDIO_FUNC_LOGE("audioPnpUevent element is null");
453         return HDF_ERR_INVALID_PARAM;
454     }
455 
456     if ((strcmp(audioPnpUevent->subSystem, UEVENT_SUBSYSTEM_USB) != 0) ||
457         (strcmp(audioPnpUevent->devType, UEVENT_SUBSYSTEM_USB_DEVICE) != 0) ||
458         (strstr(audioPnpUevent->devName, BUS_USB_DIR) == NULL)) {
459         return HDF_ERR_INVALID_PARAM;
460     }
461 
462     if (strcmp(audioPnpUevent->action, UEVENT_ACTION_ADD) == 0) {
463         if (!CheckAudioUsbDevice(audioPnpUevent->devName)) {
464             AUDIO_FUNC_LOGW("check audio usb device not exist, not add");
465             return HDF_ERR_INVALID_PARAM;
466         }
467         audioEvent.eventType = AUDIO_DEVICE_ADD;
468     } else if (strcmp(audioPnpUevent->action, UEVENT_ACTION_REMOVE) == 0) {
469         if (!DeleteAudioUsbDevice(audioPnpUevent->devName)) {
470             AUDIO_FUNC_LOGW("check audio usb device[%{public}s] not exist, not delete", audioPnpUevent->devName);
471             return HDF_ERR_INVALID_PARAM;
472         }
473         audioEvent.eventType = AUDIO_DEVICE_REMOVE;
474     } else {
475         return HDF_FAILURE;
476     }
477 
478     audioEvent.deviceType = AUDIO_USB_HEADSET;
479     AUDIO_FUNC_LOGI("audio usb headset [%{public}s]", audioEvent.eventType == AUDIO_DEVICE_ADD ? "add" : "removed");
480 
481     if (!IsUpdatePnpDeviceState(&audioEvent)) {
482         AUDIO_FUNC_LOGI("audio usb device[%{public}u] state[%{public}u] not need flush !", audioEvent.deviceType,
483             audioEvent.eventType);
484         return HDF_SUCCESS;
485     }
486     UpdatePnpDeviceState(&audioEvent);
487 
488     return AudioPnpUpdateInfoOnly(audioEvent);
489 }
490 
SetAudioEventValue(struct AudioEvent * audioEvent,struct AudioPnpUevent * audioPnpUevent)491 static int32_t SetAudioEventValue(struct AudioEvent *audioEvent, struct AudioPnpUevent *audioPnpUevent)
492 {
493     if (strncmp(audioPnpUevent->subSystem, UEVENT_SUBSYSTEM_SWITCH, strlen(UEVENT_SUBSYSTEM_SWITCH)) == 0) {
494         static uint32_t h2wTypeLast = AUDIO_HEADSET;
495         if (strncmp(audioPnpUevent->switchName, UEVENT_SWITCH_NAME_H2W, strlen(UEVENT_SWITCH_NAME_H2W)) != 0) {
496             AUDIO_FUNC_LOGE("the switch name of 'h2w' not found!");
497             return HDF_FAILURE;
498         }
499         switch (audioPnpUevent->switchState[0]) {
500             case REMOVE_AUDIO_DEVICE:
501                 audioEvent->eventType = AUDIO_DEVICE_REMOVE;
502                 audioEvent->deviceType = h2wTypeLast;
503                 break;
504             case ADD_DEVICE_HEADSET:
505             case ADD_DEVICE_HEADSET_WITHOUT_MIC:
506                 audioEvent->eventType = AUDIO_DEVICE_ADD;
507                 audioEvent->deviceType = AUDIO_HEADSET;
508                 break;
509             case ADD_DEVICE_ADAPTER:
510                 audioEvent->eventType = AUDIO_DEVICE_ADD;
511                 audioEvent->deviceType = AUDIO_ADAPTER_DEVICE;
512                 break;
513             default:
514                 audioEvent->eventType = AUDIO_DEVICE_ADD;
515                 audioEvent->deviceType = AUDIO_DEVICE_UNKNOWN;
516                 break;
517         }
518         h2wTypeLast = audioEvent->deviceType;
519     } else {
520         if (strncmp(audioPnpUevent->action, UEVENT_ACTION_CHANGE, strlen(UEVENT_ACTION_CHANGE)) != 0) {
521             return HDF_FAILURE;
522         }
523         if (strstr(audioPnpUevent->name, UEVENT_NAME_HEADSET) == NULL) {
524             return HDF_FAILURE;
525         }
526         if (strncmp(audioPnpUevent->devType, UEVENT_TYPE_EXTCON, strlen(UEVENT_TYPE_EXTCON)) != 0) {
527             return HDF_FAILURE;
528         }
529         if (strstr(audioPnpUevent->state, UEVENT_STATE_ANALOG_HS0) != NULL) {
530             audioEvent->eventType = AUDIO_DEVICE_REMOVE;
531         } else if (strstr(audioPnpUevent->state, UEVENT_STATE_ANALOG_HS1) != NULL) {
532             audioEvent->eventType = AUDIO_DEVICE_ADD;
533         } else {
534             return HDF_FAILURE;
535         }
536         audioEvent->deviceType = AUDIO_HEADSET;
537     }
538     return HDF_SUCCESS;
539 }
540 
AudioAnalogHeadsetDetectDevice(struct AudioPnpUevent * audioPnpUevent)541 static int32_t AudioAnalogHeadsetDetectDevice(struct AudioPnpUevent *audioPnpUevent)
542 {
543     struct AudioEvent audioEvent;
544     if (audioPnpUevent == NULL) {
545         AUDIO_FUNC_LOGE("audioPnpUevent is null!");
546         return HDF_ERR_INVALID_PARAM;
547     }
548     if (SetAudioEventValue(&audioEvent, audioPnpUevent) != HDF_SUCCESS) {
549         return HDF_FAILURE;
550     }
551     AUDIO_FUNC_LOGI("audio analog [%{public}s][%{public}s]",
552         audioEvent.deviceType == AUDIO_HEADSET ? "headset" : "headphone",
553         audioEvent.eventType == AUDIO_DEVICE_ADD ? "add" : "removed");
554 
555     if (!IsUpdatePnpDeviceState(&audioEvent)) {
556         AUDIO_FUNC_LOGI("audio analog device[%{public}u] state[%{public}u] not need flush !", audioEvent.deviceType,
557             audioEvent.eventType);
558         return HDF_SUCCESS;
559     }
560     UpdatePnpDeviceState(&audioEvent);
561     return AudioPnpUpdateInfoOnly(audioEvent);
562 }
563 
AudioPnpUeventParse(const char * msg,const ssize_t strLength)564 static bool AudioPnpUeventParse(const char *msg, const ssize_t strLength)
565 {
566     struct AudioPnpUevent audioPnpUevent = {"", "", "", "", "", "", "", "", ""};
567 
568     if (strncmp(msg, "libudev", strlen("libudev")) == 0) {
569         return false;
570     }
571 
572     if (strLength > UEVENT_MSG_LEN + 1) {
573         AUDIO_FUNC_LOGE("strLength > UEVENT_MSG_LEN + 1");
574         return false;
575     }
576     for (const char *msgTmp = msg; msgTmp < (msg + strLength);) {
577         if (*msgTmp == '\0') {
578             msgTmp++;
579             continue;
580         }
581         const char *arrStrTmp[UEVENT_ARR_SIZE] = {
582             UEVENT_ACTION, UEVENT_DEV_NAME, UEVENT_NAME, UEVENT_STATE, UEVENT_DEVTYPE,
583             UEVENT_SUBSYSTEM, UEVENT_SWITCH_NAME, UEVENT_SWITCH_STATE, UEVENT_HDI_NAME
584         };
585         const char **arrVarTmp[UEVENT_ARR_SIZE] = {
586             &audioPnpUevent.action, &audioPnpUevent.devName, &audioPnpUevent.name,
587             &audioPnpUevent.state, &audioPnpUevent.devType, &audioPnpUevent.subSystem,
588             &audioPnpUevent.switchName, &audioPnpUevent.switchState, &audioPnpUevent.hidName
589         };
590         for (int i = 0; i < UEVENT_ARR_SIZE; i++) {
591             if (strncmp(msgTmp, arrStrTmp[i], strlen(arrStrTmp[i])) == 0) {
592                 msgTmp += strlen(arrStrTmp[i]);
593                 *arrVarTmp[i] = msgTmp;
594                 break;
595             }
596         }
597         msgTmp += strlen(msgTmp) + 1;
598     }
599 
600     if (AudioAnalogHeadsetDetectDevice(&audioPnpUevent) == HDF_SUCCESS) {
601         return true;
602     }
603     if (AudioUsbHeadsetDetectDevice(&audioPnpUevent) == HDF_SUCCESS) {
604         return true;
605     }
606 
607     return false;
608 }
609 
AudioPnpUeventOpen(int * fd)610 static int AudioPnpUeventOpen(int *fd)
611 {
612     int socketFd = -1;
613     int buffSize = UEVENT_SOCKET_BUFF_SIZE;
614     const int32_t on = 1; // turn on passcred
615     struct sockaddr_nl addr;
616 
617     if (memset_s(&addr, sizeof(addr), 0, sizeof(addr)) != EOK) {
618         AUDIO_FUNC_LOGE("addr memset_s failed!");
619         return HDF_FAILURE;
620     }
621     addr.nl_family = AF_NETLINK;
622     addr.nl_pid = ((uint32_t)gettid() << MOVE_NUM) | (uint32_t)getpid();
623     addr.nl_groups = UEVENT_SOCKET_GROUPS;
624 
625     socketFd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
626     if (socketFd < 0) {
627         AUDIO_FUNC_LOGE("socket failed, %{public}d", errno);
628         return HDF_FAILURE;
629     }
630 
631     if (setsockopt(socketFd, SOL_SOCKET, SO_RCVBUF, &buffSize, sizeof(buffSize)) != 0) {
632         AUDIO_FUNC_LOGE("setsockopt SO_RCVBUF failed, %{public}d", errno);
633         close(socketFd);
634         return HDF_FAILURE;
635     }
636 
637     if (setsockopt(socketFd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) != 0) {
638         AUDIO_FUNC_LOGE("setsockopt SO_PASSCRED failed, %{public}d", errno);
639         close(socketFd);
640         return HDF_FAILURE;
641     }
642 
643     if (bind(socketFd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
644         AUDIO_FUNC_LOGE("bind socket failed, %{public}d", errno);
645         close(socketFd);
646         return HDF_FAILURE;
647     }
648 
649     *fd = socketFd;
650 
651     return HDF_SUCCESS;
652 }
653 
AudioPnpReadUeventMsg(int sockFd,char * buffer,size_t length)654 static ssize_t AudioPnpReadUeventMsg(int sockFd, char *buffer, size_t length)
655 {
656     char credMsg[CMSG_SPACE(sizeof(struct ucred))] = {0};
657     struct iovec iov;
658     struct sockaddr_nl addr;
659     struct msghdr msghdr = {0};
660 
661     (void)memset_s(&addr, sizeof(addr), 0, sizeof(addr));
662 
663     iov.iov_base = buffer;
664     iov.iov_len = length;
665 
666     msghdr.msg_name = &addr;
667     msghdr.msg_namelen = sizeof(addr);
668     msghdr.msg_iov = &iov;
669     msghdr.msg_iovlen = 1;
670     msghdr.msg_control = credMsg;
671     msghdr.msg_controllen = sizeof(credMsg);
672 
673     ssize_t len = recvmsg(sockFd, &msghdr, 0);
674     if (len <= 0) {
675         return HDF_FAILURE;
676     }
677 
678     struct cmsghdr *hdr = CMSG_FIRSTHDR(&msghdr);
679     if (hdr == NULL || hdr->cmsg_type != SCM_CREDENTIALS) {
680         AUDIO_FUNC_LOGW("Unexpected control message, ignored");
681         *buffer = '\0';
682         return HDF_FAILURE;
683     }
684 
685     return len;
686 }
687 
UpdateDeviceState(struct AudioEvent audioEvent,struct HdfDeviceObject * device)688 static void UpdateDeviceState(struct AudioEvent audioEvent, struct HdfDeviceObject *device)
689 {
690     char pnpInfo[AUDIO_EVENT_INFO_LEN_MAX] = {0};
691     int32_t ret;
692     if (!IsUpdatePnpDeviceState(&audioEvent)) {
693         AUDIO_FUNC_LOGI("audio first pnp device[%{public}u] state[%{public}u] not need flush !", audioEvent.deviceType,
694             audioEvent.eventType);
695         return;
696     }
697     ret = snprintf_s(pnpInfo, AUDIO_EVENT_INFO_LEN_MAX, AUDIO_EVENT_INFO_LEN_MAX - 1, "EVENT_TYPE=%u;DEVICE_TYPE=%u",
698         audioEvent.eventType, audioEvent.deviceType);
699     if (ret < 0) {
700         AUDIO_FUNC_LOGE("snprintf_s fail!");
701         return;
702     }
703 
704     UpdatePnpDeviceState(&audioEvent);
705     if (HdfDeviceObjectSetServInfo(device, pnpInfo) != HDF_SUCCESS) {
706         AUDIO_FUNC_LOGE("set audio event status info failed!");
707     }
708     return;
709 }
710 
711 #ifdef AUDIO_DOUBLE_PNP_DETECT
712 static struct AudioEvent g_usbHeadset = {0};
UpdateUsbHeadset(void * arg)713 static void* UpdateUsbHeadset(void *arg)
714 {
715     OsalMSleep(AUDIO_DEVICE_WAIT_USB_HEADSET_ONLINE);
716     char pnpInfo[AUDIO_EVENT_INFO_LEN_MAX] = {0};
717     int32_t ret;
718     if (!IsUpdatePnpDeviceState(&g_usbHeadset)) {
719         AUDIO_FUNC_LOGI("audio first pnp device[%{public}u] state[%{public}u] not need flush !",
720             g_usbHeadset.deviceType, g_usbHeadset.eventType);
721         return NULL;
722     }
723     ret = snprintf_s(pnpInfo, AUDIO_EVENT_INFO_LEN_MAX, AUDIO_EVENT_INFO_LEN_MAX - 1, "EVENT_TYPE=%u;DEVICE_TYPE=%u",
724         g_usbHeadset.eventType, g_usbHeadset.deviceType);
725     if (ret < 0) {
726         AUDIO_FUNC_LOGE("snprintf_s fail!");
727         return NULL;
728     }
729 
730     UpdatePnpDeviceState(&g_usbHeadset);
731     struct HdfDeviceObject *device = (struct HdfDeviceObject *)arg;
732     if (HdfDeviceObjectSetServInfo(device, pnpInfo) != HDF_SUCCESS) {
733         AUDIO_FUNC_LOGE("set audio event status info failed!");
734     }
735     if (HdfDeviceObjectUpdate(device) != HDF_SUCCESS) {
736         AUDIO_FUNC_LOGE("update audio status info failed!");
737         return NULL;
738     }
739     return NULL;
740 }
741 #endif
742 
DetectAudioDevice(struct HdfDeviceObject * device)743 void DetectAudioDevice(struct HdfDeviceObject *device)
744 {
745     int32_t ret;
746     struct AudioEvent audioEvent = {0};
747 
748     OsalMSleep(AUDIO_DEVICE_WAIT_USB_ONLINE); // Wait until the usb node is successfully created
749     ret = DetectAnalogHeadsetState(&audioEvent);
750     if ((ret == HDF_SUCCESS) && (audioEvent.eventType == AUDIO_DEVICE_ADD)) {
751         AUDIO_FUNC_LOGI("audio detect analog headset");
752         UpdateDeviceState(audioEvent, device);
753 #ifndef AUDIO_DOUBLE_PNP_DETECT
754         return;
755 #endif
756     }
757 #ifdef AUDIO_DOUBLE_PNP_DETECT
758     ret = DetectUsbHeadsetState(&g_usbHeadset);
759     if ((ret == HDF_SUCCESS) && (g_usbHeadset.eventType == AUDIO_DEVICE_ADD)) {
760         AUDIO_FUNC_LOGI("audio detect usb headset");
761         pthread_t thread;
762         pthread_attr_t tidsAttr;
763         const char *threadName = "update_usb_headset";
764         pthread_attr_init(&tidsAttr);
765         pthread_attr_setdetachstate(&tidsAttr, PTHREAD_CREATE_DETACHED);
766         if (pthread_create(&thread, &tidsAttr, UpdateUsbHeadset, device) != 0) {
767             AUDIO_FUNC_LOGE("create audio update usb headset thread failed");
768             return;
769         }
770 
771         if (pthread_setname_np(thread, threadName) != 0) {
772             AUDIO_FUNC_LOGE("setname failed");
773             return;
774         }
775     }
776 #else
777     audioEvent.eventType = AUDIO_EVENT_UNKNOWN;
778     audioEvent.deviceType = AUDIO_DEVICE_UNKNOWN;
779     ret = DetectUsbHeadsetState(&audioEvent);
780     if ((ret == HDF_SUCCESS) && (audioEvent.eventType == AUDIO_DEVICE_ADD)) {
781         AUDIO_FUNC_LOGI("audio detect usb headset");
782         UpdateDeviceState(audioEvent, device);
783     }
784 #endif
785     return;
786 }
787 
788 static bool g_pnpThreadRunning = false;
AudioPnpUeventStart(void * useless)789 static void AudioPnpUeventStart(void *useless)
790 {
791     (void)useless;
792     ssize_t rcvLen;
793     int socketFd = -1;
794     struct pollfd fd;
795     char msg[UEVENT_MSG_LEN + 1] = {0};
796 
797     AUDIO_FUNC_LOGI("audio uevent start");
798     if (AudioPnpUeventOpen(&socketFd) != HDF_SUCCESS) {
799         AUDIO_FUNC_LOGE("open audio pnp socket failed!");
800         return;
801     }
802 
803     fd.fd = socketFd;
804     fd.events = POLLIN | POLLERR;
805     fd.revents = 0;
806 
807     while (g_pnpThreadRunning) {
808         if (poll(&fd, 1, -1) <= 0) {
809             AUDIO_FUNC_LOGE("audio event poll fail %{public}d", errno);
810             OsalMSleep(UEVENT_POLL_WAIT_TIME);
811             continue;
812         }
813 
814         if (((uint32_t)fd.revents & POLLIN) == POLLIN) {
815             (void)memset_s(&msg, sizeof(msg), 0, sizeof(msg));
816             rcvLen = AudioPnpReadUeventMsg(socketFd, msg, UEVENT_MSG_LEN);
817             if (rcvLen <= 0) {
818                 continue;
819             }
820 
821             if (!AudioPnpUeventParse(msg, rcvLen)) {
822                 continue;
823             }
824         } else if (((uint32_t)fd.revents & POLLERR) == POLLERR) {
825             AUDIO_FUNC_LOGE("audio event poll error");
826         }
827     }
828 
829     close(socketFd);
830     return;
831 }
832 
AudioUsbPnpUeventStartThread(void)833 int32_t AudioUsbPnpUeventStartThread(void)
834 {
835     const char *threadName = "pnp_usb";
836     g_pnpThreadRunning = true;
837 
838     AUDIO_FUNC_LOGI("create audio usb uevent thread");
839     FfrtTaskAttr attr;
840     FfrtAttrInitFunc()(&attr);
841     FfrtAttrSetQosFunc()(&attr, FFRT_QOS_DEFAULT);
842     FfrtAttrSetNameFunc()(&attr, threadName);
843     FfrtSubmitBaseFunc()(FfrtCreateFunctionWrapper(AudioPnpUeventStart, NULL, NULL), NULL, NULL, &attr);
844 
845     return HDF_SUCCESS;
846 }
847 
AudioUsbPnpUeventStopThread(void)848 void AudioUsbPnpUeventStopThread(void)
849 {
850     AUDIO_FUNC_LOGI("audio pnp uevent thread exit");
851     g_pnpThreadRunning = false;
852 }
853