• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "osal_time.h"
36 #include "securec.h"
37 
38 #define HDF_LOG_TAG HDF_AUDIO_HOST
39 
40 #define UEVENT_ACTION           "ACTION="
41 #define UEVENT_NAME             "NAME="
42 #define UEVENT_STATE            "STATE="
43 #define UEVENT_DEV_NAME         "DEVNAME="
44 #define UEVENT_DEVTYPE          "DEVTYPE="
45 #define UEVENT_SUBSYSTEM        "SUBSYSTEM="
46 #define UEVENT_SWITCH_NAME      "SWITCH_NAME="
47 #define UEVENT_SWITCH_STATE     "SWITCH_STATE="
48 #define UEVENT_ID_MODEL         "ID_MODEL="
49 #define UEVENT_HDI_NAME         "HID_NAME="
50 #define UEVENT_ACTION_ADD       "add"
51 #define UEVENT_ACTION_REMOVE    "remove"
52 #define UEVENT_ACTION_CHANGE    "change"
53 #define UEVENT_TYPE_EXTCON      "extcon3"
54 #define UEVENT_NAME_HEADSET     "headset"
55 #define UEVENT_STATE_ANALOG_HS0 "MICROPHONE=0"
56 #define UEVENT_STATE_ANALOG_HS1 "MICROPHONE=1"
57 #define UEVENT_SUBSYSTEM_SWITCH "switch"
58 #define UEVENT_SWITCH_NAME_H2W  "h2w"
59 #define UEVENT_USB_AUDIO        "USB Audio"
60 #define UEVENT_USB_HEADSET      "HEADSET"
61 #define UEVENT_SUBSYSTEM_USB        "usb"
62 #define UEVENT_SUBSYSTEM_USB_DEVICE "usb_device"
63 
64 #define UEVENT_SOCKET_BUFF_SIZE (64 * 1024)
65 #define UEVENT_SOCKET_GROUPS    0xffffffff
66 #define UEVENT_MSG_LEN          2048
67 
68 #define UEVENT_POLL_WAIT_TIME 100
69 #define AUDIO_UEVENT_USB_DEVICE_COUNT 10
70 
71 #define USB_DEV_NAME_LEN_MAX    64
72 #define USB_DES_LEN_MAX         4096
73 #define DEV_BUS_USB_DIR         "/dev/bus/usb"
74 #define BUS_USB_DIR             "bus/usb"
75 #define USB_IF_DESC_LEN         9
76 #define USB_IF_CLASS_OFFSET     5
77 #define USB_IF_SUBCLASS_OFFSET  6
78 #define USB_AUDIO_DESC_TYPE     0x4
79 #define USB_AUDIO_CLASS         1
80 #define USB_AUDIO_SUBCLASS_CTRL 1
81 #define AUDIO_DEVICE_ONLINE     1
82 #define AUDIO_DEVICE_WAIT_ONLINE 10
83 
84 struct UsbDevice {
85     int8_t devName[USB_DEV_NAME_LEN_MAX];
86     uint8_t desc[USB_DES_LEN_MAX];
87     size_t descLen;
88 };
89 
90 struct AudioPnpUevent {
91     const char *action;
92     const char *name;
93     const char *state;
94     const char *devType;
95     const char *subSystem;
96     const char *switchName;
97     const char *switchState;
98     const char *hidName;
99     const char *devName;
100 };
101 
CheckUsbDesc(struct UsbDevice * usbDevice)102 static int32_t CheckUsbDesc(struct UsbDevice *usbDevice)
103 {
104     if (usbDevice->descLen > USB_DES_LEN_MAX) {
105         AUDIO_FUNC_LOGE("usbDevice->descLen is more than USB_DES_LEN_MAX");
106         return HDF_ERR_INVALID_PARAM;
107     }
108     for (size_t len = 0; len < usbDevice->descLen;) {
109         size_t descLen = usbDevice->desc[len];
110         if (descLen == 0) {
111             AUDIO_FUNC_LOGE("descLen is 0");
112             return HDF_ERR_INVALID_PARAM;
113         }
114 
115         if (descLen < USB_IF_DESC_LEN) {
116             len += descLen;
117             continue;
118         }
119 
120         int32_t descType = usbDevice->desc[len + 1];
121         if (descType != USB_AUDIO_DESC_TYPE) {
122             len += descLen;
123             continue;
124         }
125 
126         /* According to the 1.0 and 2.0 usb standard protocols, the audio field corresponding to the interface
127          * description type is: offset=1 interface descriptor type is 4; offset=5 interface class,audio is 1; offset=6
128          * interface subclass,audio control is 1 */
129         int32_t usbClass = usbDevice->desc[len + USB_IF_CLASS_OFFSET];
130         int32_t subClass = usbDevice->desc[len + USB_IF_SUBCLASS_OFFSET];
131         if (usbClass == USB_AUDIO_CLASS && subClass == USB_AUDIO_SUBCLASS_CTRL) {
132             AUDIO_FUNC_LOGI(
133                 "descType %{public}d, usbClass %{public}d, subClass %{public}d", descType, usbClass, subClass);
134             return AUDIO_DEVICE_ONLINE;
135         }
136         len += descLen;
137     }
138     return HDF_SUCCESS;
139 }
140 
ReadAndScanUsbDev(const char * devPath)141 static int32_t ReadAndScanUsbDev(const char *devPath)
142 {
143     FILE *fp = NULL;
144     struct UsbDevice usbDevice;
145     size_t len;
146     errno_t error;
147     char realpathRes[PATH_MAX + 1] = {'\0'};
148 
149     if (devPath == NULL) {
150         AUDIO_FUNC_LOGE("audio devPath null");
151         return HDF_FAILURE;
152     }
153 
154     OsalMSleep(AUDIO_DEVICE_WAIT_ONLINE);
155     if (realpath(devPath, realpathRes) == NULL) {
156         AUDIO_FUNC_LOGE("audio realpath fail[%{public}d]", errno);
157         return HDF_FAILURE;
158     }
159 
160     fp = fopen(realpathRes, "r");
161     if (fp == NULL) {
162         AUDIO_FUNC_LOGE("audio realpath open fail");
163         return HDF_FAILURE;
164     }
165 
166     len = fread(usbDevice.desc, 1, sizeof(usbDevice.desc) - 1, fp);
167     if (len == 0) {
168         AUDIO_FUNC_LOGE("audio realpath read fail");
169         (void)fclose(fp);
170         return HDF_FAILURE;
171     }
172     (void)fclose(fp);
173 
174     error = strncpy_s((char *)usbDevice.devName, sizeof(usbDevice.devName), realpathRes, sizeof(usbDevice.devName) - 1);
175     if (error != EOK) {
176         AUDIO_FUNC_LOGE("audio realpath strncpy fail");
177         return HDF_FAILURE;
178     }
179 
180     usbDevice.descLen = len;
181     return CheckUsbDesc(&usbDevice);
182 }
183 
184 #define SWITCH_STATE_PATH    "/sys/class/switch/h2w/state"
185 #define STATE_PATH_ITEM_SIZE 1
186 
DetectAnalogHeadsetState(struct AudioEvent * audioEvent)187 static int32_t DetectAnalogHeadsetState(struct AudioEvent *audioEvent)
188 {
189     int8_t state = 0;
190     FILE *fp = fopen(SWITCH_STATE_PATH, "r");
191     if (fp == NULL) {
192         AUDIO_FUNC_LOGE("audio open switch state node fail");
193         return HDF_ERR_INVALID_PARAM;
194     }
195 
196     size_t ret = fread(&state, STATE_PATH_ITEM_SIZE, STATE_PATH_ITEM_SIZE, fp);
197     if (ret == 0) {
198         (void)fclose(fp);
199         AUDIO_FUNC_LOGE("audio read switch state node fail");
200         return HDF_FAILURE;
201     }
202 
203     AUDIO_FUNC_LOGI("audio switch state = %{public}c", state);
204     if (state == '0') {
205         audioEvent->eventType = HDF_AUDIO_DEVICE_REMOVE;
206         audioEvent->deviceType = HDF_AUDIO_HEADSET;
207     } else {
208         audioEvent->eventType = HDF_AUDIO_DEVICE_ADD;
209         audioEvent->deviceType = HDF_AUDIO_HEADSET;
210     }
211 
212     (void)fclose(fp);
213     return HDF_SUCCESS;
214 }
215 
216 struct AudioDevBusUsbDevice {
217     bool isUsed;
218     int8_t devName[USB_DEV_NAME_LEN_MAX];
219 };
220 
221 struct AudioDevBusUsbDevice g_audioUsbDeviceList[AUDIO_UEVENT_USB_DEVICE_COUNT] = {0};
222 
FindAudioUsbDevice(const char * devName)223 static bool FindAudioUsbDevice(const char *devName)
224 {
225     if (strlen(devName) > USB_DEV_NAME_LEN_MAX - 1) {
226         AUDIO_FUNC_LOGE("find usb audio device name exceed max len");
227         return false;
228     }
229 
230     for (uint32_t i = 0; i < AUDIO_UEVENT_USB_DEVICE_COUNT; i++) {
231         if (g_audioUsbDeviceList[i].isUsed &&
232             (strncmp((char *)g_audioUsbDeviceList[i].devName, devName, strlen(devName)) == EOK)) {
233             return true;
234         }
235     }
236     return false;
237 }
AddAudioUsbDevice(const char * devName)238 static bool AddAudioUsbDevice(const char *devName)
239 {
240     if (strlen(devName) > USB_DEV_NAME_LEN_MAX - 1) {
241         AUDIO_FUNC_LOGE("add usb audio device name exceed max len");
242         return false;
243     }
244 
245     if (FindAudioUsbDevice(devName)) {
246         AUDIO_FUNC_LOGI("find usb audio device name[%{public}s]", devName);
247         return true;
248     }
249 
250     for (uint32_t i = 0; i < AUDIO_UEVENT_USB_DEVICE_COUNT; i++) {
251         if (g_audioUsbDeviceList[i].isUsed) {
252             continue;
253         }
254         if (strncpy_s((char *)g_audioUsbDeviceList[i].devName, USB_DEV_NAME_LEN_MAX, devName, strlen(devName)) != EOK) {
255             AUDIO_FUNC_LOGE("add usb audio device name fail");
256             return false;
257         }
258         g_audioUsbDeviceList[i].isUsed = true;
259         return true;
260     }
261     AUDIO_FUNC_LOGE("add usb audio device name fail");
262     return false;
263 }
264 
DeleteAudioUsbDevice(const char * devName)265 static bool DeleteAudioUsbDevice(const char *devName)
266 {
267     if (strlen(devName) > USB_DEV_NAME_LEN_MAX - 1) {
268         AUDIO_FUNC_LOGE("delete usb audio device name exceed max len");
269         return false;
270     }
271 
272     for (uint32_t i = 0; i < AUDIO_UEVENT_USB_DEVICE_COUNT; i++) {
273         if (g_audioUsbDeviceList[i].isUsed &&
274             strncmp((char *)g_audioUsbDeviceList[i].devName, devName, strlen(devName)) == EOK) {
275             g_audioUsbDeviceList[i].isUsed = false;
276             AUDIO_FUNC_LOGI("delete usb audio device name[%{public}s]", devName);
277             return true;
278         }
279     }
280 
281     return false;
282 }
283 
CheckAudioUsbDevice(const char * devName)284 static bool CheckAudioUsbDevice(const char *devName)
285 {
286     int32_t state = 0;
287     int32_t len;
288     char subDir[USB_DEV_NAME_LEN_MAX] = {0};
289 
290     if (*devName == '\0') {
291         return false;
292     }
293     len = snprintf_s(subDir, USB_DEV_NAME_LEN_MAX, USB_DEV_NAME_LEN_MAX - 1, "/dev/" "%s", devName);
294     if (len < 0) {
295         AUDIO_FUNC_LOGE("audio snprintf dev dir fail");
296         return false;
297     }
298 
299     AUDIO_FUNC_LOGE("usb device name[%{public}s]", devName);
300     state = ReadAndScanUsbDev(subDir);
301     if ((state == AUDIO_DEVICE_ONLINE) && AddAudioUsbDevice(devName)) {
302         return true;
303     }
304     return false;
305 }
306 
AudioUsbHeadsetDetectDevice(struct AudioPnpUevent * audioPnpUevent)307 static int32_t AudioUsbHeadsetDetectDevice(struct AudioPnpUevent *audioPnpUevent)
308 {
309     struct AudioEvent audioEvent = {0};
310 
311     if (audioPnpUevent == NULL) {
312         AUDIO_FUNC_LOGE("audioPnpUevent is null");
313         return HDF_ERR_INVALID_PARAM;
314     }
315 
316     if (audioPnpUevent->action == NULL || audioPnpUevent->devName == NULL || audioPnpUevent->subSystem == NULL ||
317         audioPnpUevent->devType == NULL) {
318         AUDIO_FUNC_LOGE("audioPnpUevent element is null");
319         return HDF_ERR_INVALID_PARAM;
320     }
321 
322     if ((strcmp(audioPnpUevent->subSystem, UEVENT_SUBSYSTEM_USB) != 0) ||
323         (strcmp(audioPnpUevent->devType, UEVENT_SUBSYSTEM_USB_DEVICE) != 0) ||
324         (strstr(audioPnpUevent->devName, BUS_USB_DIR) == NULL)) {
325         return HDF_ERR_INVALID_PARAM;
326     }
327 
328     if (strcmp(audioPnpUevent->action, UEVENT_ACTION_ADD) == 0) {
329         if (!CheckAudioUsbDevice(audioPnpUevent->devName)) {
330             AUDIO_FUNC_LOGW("check audio usb device not exist, not add");
331             return HDF_ERR_INVALID_PARAM;
332         }
333         audioEvent.eventType = HDF_AUDIO_DEVICE_ADD;
334     } else if (strcmp(audioPnpUevent->action, UEVENT_ACTION_REMOVE) == 0) {
335         if (!DeleteAudioUsbDevice(audioPnpUevent->devName)) {
336             AUDIO_FUNC_LOGW("check audio usb device not exist, not delete");
337             return HDF_ERR_INVALID_PARAM;
338         }
339         audioEvent.eventType = HDF_AUDIO_DEVICE_REMOVE;
340     } else {
341         return HDF_FAILURE;
342     }
343 
344     audioEvent.deviceType = HDF_AUDIO_USB_HEADSET;
345     AUDIO_FUNC_LOGI("audio usb headset [%{public}s]", audioEvent.eventType == HDF_AUDIO_DEVICE_ADD ? "add" : "removed");
346     return AudioPnpUpdateInfoOnly(audioEvent);
347 }
348 
AudioAnalogHeadsetDetectDevice(struct AudioPnpUevent * audioPnpUevent)349 static int32_t AudioAnalogHeadsetDetectDevice(struct AudioPnpUevent *audioPnpUevent)
350 {
351     struct AudioEvent audioEvent;
352     if (audioPnpUevent == NULL) {
353         AUDIO_FUNC_LOGE("audioPnpUevent is null!");
354         return HDF_ERR_INVALID_PARAM;
355     }
356 
357     if (strncmp(audioPnpUevent->subSystem, UEVENT_SUBSYSTEM_SWITCH, strlen(UEVENT_SUBSYSTEM_SWITCH)) == 0) {
358         static uint32_t h2wTypeLast = HDF_AUDIO_HEADSET;
359         if (strncmp(audioPnpUevent->switchName, UEVENT_SWITCH_NAME_H2W, strlen(UEVENT_SWITCH_NAME_H2W)) != 0) {
360             AUDIO_FUNC_LOGE("the switch name of 'h2w' not found!");
361             return HDF_FAILURE;
362         }
363         if (audioPnpUevent->switchState[0] == '0') {
364             audioEvent.eventType = HDF_AUDIO_DEVICE_REMOVE;
365             audioEvent.deviceType = h2wTypeLast;
366         } else if ((audioPnpUevent->switchState[0] == '1') || (audioPnpUevent->switchState[0] == '2')) {
367             audioEvent.eventType = HDF_AUDIO_DEVICE_ADD;
368             audioEvent.deviceType = HDF_AUDIO_HEADSET;
369         } else {
370             audioEvent.eventType = HDF_AUDIO_DEVICE_ADD;
371             audioEvent.deviceType = HDF_AUDIO_DEVICE_UNKOWN;
372         }
373         h2wTypeLast = audioEvent.deviceType;
374     } else {
375         if (strncmp(audioPnpUevent->action, UEVENT_ACTION_CHANGE, strlen(UEVENT_ACTION_CHANGE)) != 0) {
376             return HDF_FAILURE;
377         }
378         if (strstr(audioPnpUevent->name, UEVENT_NAME_HEADSET) == NULL) {
379             return HDF_FAILURE;
380         }
381         if (strncmp(audioPnpUevent->devType, UEVENT_TYPE_EXTCON, strlen(UEVENT_TYPE_EXTCON)) != 0) {
382             return HDF_FAILURE;
383         }
384         if (strstr(audioPnpUevent->state, UEVENT_STATE_ANALOG_HS0) != NULL) {
385             audioEvent.eventType = HDF_AUDIO_DEVICE_REMOVE;
386         } else if (strstr(audioPnpUevent->state, UEVENT_STATE_ANALOG_HS1) != NULL) {
387             audioEvent.eventType = HDF_AUDIO_DEVICE_ADD;
388         } else {
389             return HDF_FAILURE;
390         }
391         audioEvent.deviceType = HDF_AUDIO_HEADSET;
392     }
393 
394     AUDIO_FUNC_LOGI("audio analog [%{public}s][%{public}s]",
395         audioEvent.deviceType == HDF_AUDIO_HEADSET ? "headset" : "headphone",
396         audioEvent.eventType == HDF_AUDIO_DEVICE_ADD ? "add" : "removed");
397 
398     return AudioPnpUpdateInfoOnly(audioEvent);
399 }
400 
AudioPnpUeventParse(const char * msg,const ssize_t strLength)401 static bool AudioPnpUeventParse(const char *msg, const ssize_t strLength)
402 {
403     struct AudioPnpUevent audioPnpUevent = {"", "", "", "", "", "", "", "", ""};
404 
405     if (strncmp(msg, "libudev", strlen("libudev")) == 0) {
406         return false;
407     }
408 
409     if (strLength > UEVENT_MSG_LEN + 1) {
410         AUDIO_FUNC_LOGE("strLength > UEVENT_MSG_LEN + 1");
411         return false;
412     }
413     for (const char *msgTmp = msg; msgTmp < (msg + strLength);) {
414         if (*msgTmp == '\0') {
415             msgTmp++;
416             continue;
417         }
418 
419         if (strncmp(msgTmp, UEVENT_ACTION, strlen(UEVENT_ACTION)) == 0) {
420             msgTmp += strlen(UEVENT_ACTION);
421             audioPnpUevent.action = msgTmp;
422         } else if (strncmp(msgTmp, UEVENT_DEV_NAME, strlen(UEVENT_DEV_NAME)) == 0) {
423             msgTmp += strlen(UEVENT_DEV_NAME);
424             audioPnpUevent.devName = msgTmp;
425         } else if (strncmp(msgTmp, UEVENT_NAME, strlen(UEVENT_NAME)) == 0) {
426             msgTmp += strlen(UEVENT_NAME);
427             audioPnpUevent.name = msgTmp;
428         } else if (strncmp(msgTmp, UEVENT_STATE, strlen(UEVENT_STATE)) == 0) {
429             msgTmp += strlen(UEVENT_STATE);
430             audioPnpUevent.state = msgTmp;
431         } else if (strncmp(msgTmp, UEVENT_DEVTYPE, strlen(UEVENT_DEVTYPE)) == 0) {
432             msgTmp += strlen(UEVENT_DEVTYPE);
433             audioPnpUevent.devType = msgTmp;
434         } else if (strncmp(msgTmp, UEVENT_SUBSYSTEM, strlen(UEVENT_SUBSYSTEM)) == 0) {
435             msgTmp += strlen(UEVENT_SUBSYSTEM);
436             audioPnpUevent.subSystem = msgTmp;
437         } else if (strncmp(msgTmp, UEVENT_SWITCH_NAME, strlen(UEVENT_SWITCH_NAME)) == 0) {
438             msgTmp += strlen(UEVENT_SWITCH_NAME);
439             audioPnpUevent.switchName = msgTmp;
440         } else if (strncmp(msgTmp, UEVENT_SWITCH_STATE, strlen(UEVENT_SWITCH_STATE)) == 0) {
441             msgTmp += strlen(UEVENT_SWITCH_STATE);
442             audioPnpUevent.switchState = msgTmp;
443         } else if (strncmp(msgTmp, UEVENT_HDI_NAME, strlen(UEVENT_HDI_NAME)) == 0) {
444             msgTmp += strlen(UEVENT_HDI_NAME);
445             audioPnpUevent.hidName = msgTmp;
446         }
447         msgTmp += strlen(msgTmp) + 1;
448     }
449 
450     if (AudioAnalogHeadsetDetectDevice(&audioPnpUevent) == HDF_SUCCESS) {
451         return true;
452     }
453     if (AudioUsbHeadsetDetectDevice(&audioPnpUevent) == HDF_SUCCESS) {
454         return true;
455     }
456 
457     return false;
458 }
459 
AudioPnpUeventOpen(int * fd)460 static int AudioPnpUeventOpen(int *fd)
461 {
462     int socketFd = -1;
463     int buffSize = UEVENT_SOCKET_BUFF_SIZE;
464     const int32_t on = 1; // turn on passcred
465     struct sockaddr_nl addr;
466 
467     if (memset_s(&addr, sizeof(addr), 0, sizeof(addr)) != EOK) {
468         AUDIO_FUNC_LOGE("addr memset_s failed!");
469         return HDF_FAILURE;
470     }
471     addr.nl_family = AF_NETLINK;
472     addr.nl_pid = (sa_family_t)getpid();
473     addr.nl_groups = UEVENT_SOCKET_GROUPS;
474 
475     socketFd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
476     if (socketFd < 0) {
477         AUDIO_FUNC_LOGE("socketFd failed! ret = %{public}d", socketFd);
478         return HDF_FAILURE;
479     }
480 
481     if (setsockopt(socketFd, SOL_SOCKET, SO_RCVBUF, &buffSize, sizeof(buffSize)) != 0) {
482         AUDIO_FUNC_LOGE("setsockopt failed!");
483         close(socketFd);
484         return HDF_FAILURE;
485     }
486 
487     if (setsockopt(socketFd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) != 0) {
488         AUDIO_FUNC_LOGE("setsockopt failed!");
489         close(socketFd);
490         return HDF_FAILURE;
491     }
492 
493     if (bind(socketFd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
494         AUDIO_FUNC_LOGE("bind socketFd failed!");
495         close(socketFd);
496         return HDF_FAILURE;
497     }
498 
499     *fd = socketFd;
500 
501     return HDF_SUCCESS;
502 }
503 
AudioPnpReadUeventMsg(int sockFd,char * buffer,size_t length)504 static ssize_t AudioPnpReadUeventMsg(int sockFd, char *buffer, size_t length)
505 {
506     char credMsg[CMSG_SPACE(sizeof(struct ucred))] = {0};
507     struct iovec iov;
508     struct sockaddr_nl addr;
509     struct msghdr msghdr = {0};
510 
511     (void)memset_s(&addr, sizeof(addr), 0, sizeof(addr));
512 
513     iov.iov_base = buffer;
514     iov.iov_len = length;
515 
516     msghdr.msg_name = &addr;
517     msghdr.msg_namelen = sizeof(addr);
518     msghdr.msg_iov = &iov;
519     msghdr.msg_iovlen = 1;
520     msghdr.msg_control = credMsg;
521     msghdr.msg_controllen = sizeof(credMsg);
522 
523     ssize_t len = recvmsg(sockFd, &msghdr, 0);
524     if (len <= 0) {
525         return HDF_FAILURE;
526     }
527 
528     struct cmsghdr *hdr = CMSG_FIRSTHDR(&msghdr);
529     if (hdr == NULL || hdr->cmsg_type != SCM_CREDENTIALS) {
530         AUDIO_FUNC_LOGW("Unexpected control message, ignored");
531         *buffer = '\0';
532         return HDF_FAILURE;
533     }
534 
535     return len;
536 }
537 
DetectAudioDevice(void)538 void DetectAudioDevice(void)
539 {
540     int32_t ret;
541     struct AudioEvent audioEvent = {0};
542 
543     ret = DetectAnalogHeadsetState(&audioEvent);
544     if ((ret == HDF_SUCCESS) && (audioEvent.eventType == HDF_AUDIO_DEVICE_ADD)) {
545         AUDIO_FUNC_LOGI("audio detect analog headset exist");
546         audioEvent.eventType = HDF_AUDIO_DEVICE_ADD;
547         audioEvent.deviceType = HDF_AUDIO_HEADSET;
548         AudioPnpUpdateInfoOnly(audioEvent);
549     }
550 }
551 
552 static bool g_pnpThreadRunning = false;
AudioPnpUeventStart(void * useless)553 static void *AudioPnpUeventStart(void *useless)
554 {
555     (void)useless;
556     ssize_t rcvLen;
557     int socketFd = -1;
558     struct pollfd fd;
559     char msg[UEVENT_MSG_LEN + 1] = {0};
560 
561     AUDIO_FUNC_LOGI("audio uevent start");
562     DetectAudioDevice();
563     if (AudioPnpUeventOpen(&socketFd) != HDF_SUCCESS) {
564         AUDIO_FUNC_LOGE("open audio pnp socket failed!");
565         return NULL;
566     }
567 
568     fd.fd = socketFd;
569     fd.events = POLLIN | POLLERR;
570     fd.revents = 0;
571 
572     while (g_pnpThreadRunning) {
573         if (poll(&fd, 1, -1) <= 0) {
574             AUDIO_FUNC_LOGE("audio event poll fail %{public}d", errno);
575             OsalMSleep(UEVENT_POLL_WAIT_TIME);
576             continue;
577         }
578 
579         if (((uint32_t)fd.revents & POLLIN) == POLLIN) {
580             (void)memset_s(&msg, sizeof(msg), 0, sizeof(msg));
581             rcvLen = AudioPnpReadUeventMsg(socketFd, msg, UEVENT_MSG_LEN);
582             if (rcvLen <= 0) {
583                 continue;
584             }
585 
586             if (!AudioPnpUeventParse(msg, rcvLen)) {
587                 continue;
588             }
589         } else if (((uint32_t)fd.revents & POLLERR) == POLLERR) {
590             AUDIO_FUNC_LOGE("audio event poll error");
591         }
592     }
593 
594     close(socketFd);
595     return NULL;
596 }
597 
AudioPnpUeventStartThread(void)598 int32_t AudioPnpUeventStartThread(void)
599 {
600     pthread_t thread;
601     pthread_attr_t tidsAttr;
602     const char *threadName = "pnp_uevent";
603     g_pnpThreadRunning = true;
604 
605     AUDIO_FUNC_LOGI("create audio uevent thread");
606     pthread_attr_init(&tidsAttr);
607     pthread_attr_setdetachstate(&tidsAttr, PTHREAD_CREATE_DETACHED);
608     if (pthread_create(&thread, &tidsAttr, AudioPnpUeventStart, NULL) != 0) {
609         AUDIO_FUNC_LOGE("create audio pnp uevent thread failed");
610         return HDF_FAILURE;
611     }
612 
613     if (pthread_setname_np(thread, threadName) != 0) {
614         AUDIO_FUNC_LOGE("AudioPnpUeventStartThread setname failed");
615         return HDF_FAILURE;
616     }
617 
618     return HDF_SUCCESS;
619 }
620 
AudioPnpUeventStopThread(void)621 void AudioPnpUeventStopThread(void)
622 {
623     AUDIO_FUNC_LOGI("audio pnp uevent thread exit");
624     g_pnpThreadRunning = false;
625 }
626