1 /*
2  * Copyright (c) 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 #ifndef LOG_TAG
16 #define LOG_TAG "AudioSocketThread"
17 #endif
18 
19 #include "audio_socket_thread.h"
20 #include <cctype>
21 #include <cstdlib>
22 #include <dirent.h>
23 #include <linux/netlink.h>
24 #include <sys/socket.h>
25 #include <unistd.h>
26 #include <string>
27 #include "osal_time.h"
28 #include "audio_utils.h"
29 #include "audio_errors.h"
30 #include "securec.h"
31 #include "audio_policy_log.h"
32 #include "audio_pnp_server.h"
33 
34 namespace OHOS {
35 namespace AudioStandard {
36 using namespace std;
37 AudioEvent AudioSocketThread::audioSocketEvent_ = {
38     .eventType = AUDIO_EVENT_UNKNOWN,
39     .deviceType = AUDIO_DEVICE_UNKNOWN,
40 };
41 
42 AudioDevBusUsbDevice g_audioUsbDeviceList[AUDIO_UEVENT_USB_DEVICE_COUNT] = {};
43 
IsUpdatePnpDeviceState(AudioEvent * pnpDeviceEvent)44 bool AudioSocketThread::IsUpdatePnpDeviceState(AudioEvent *pnpDeviceEvent)
45 {
46     if (pnpDeviceEvent->eventType == audioSocketEvent_.eventType &&
47         pnpDeviceEvent->deviceType == audioSocketEvent_.deviceType &&
48         pnpDeviceEvent->name == audioSocketEvent_.name &&
49         pnpDeviceEvent->address == audioSocketEvent_.address) {
50         return false;
51     }
52     return true;
53 }
54 
UpdatePnpDeviceState(AudioEvent * pnpDeviceEvent)55 void AudioSocketThread::UpdatePnpDeviceState(AudioEvent *pnpDeviceEvent)
56 {
57     audioSocketEvent_.eventType = pnpDeviceEvent->eventType;
58     audioSocketEvent_.deviceType = pnpDeviceEvent->deviceType;
59     audioSocketEvent_.name = pnpDeviceEvent->name;
60     audioSocketEvent_.address = pnpDeviceEvent->address;
61 }
62 
AudioPnpUeventOpen(int * fd)63 int AudioSocketThread::AudioPnpUeventOpen(int *fd)
64 {
65     int socketFd = -1;
66     int buffSize = UEVENT_SOCKET_BUFF_SIZE;
67     const int32_t on = 1; // turn on passcred
68     sockaddr_nl addr;
69 
70     if (memset_s(&addr, sizeof(addr), 0, sizeof(addr)) != EOK) {
71         AUDIO_ERR_LOG("addr memset_s failed!");
72         return ERROR;
73     }
74     addr.nl_family = AF_NETLINK;
75     addr.nl_pid = ((uint32_t)gettid() << MOVE_NUM) | (uint32_t)getpid();
76     addr.nl_groups = UEVENT_SOCKET_GROUPS;
77 
78     socketFd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
79     if (socketFd < 0) {
80         AUDIO_ERR_LOG("socket failed, %{public}d", errno);
81         return ERROR;
82     }
83 
84     if (setsockopt(socketFd, SOL_SOCKET, SO_RCVBUF, &buffSize, sizeof(buffSize)) != 0) {
85         AUDIO_ERR_LOG("setsockopt SO_RCVBUF failed, %{public}d", errno);
86         CloseFd(socketFd);
87         return ERROR;
88     }
89 
90     if (setsockopt(socketFd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) != 0) {
91         AUDIO_ERR_LOG("setsockopt SO_PASSCRED failed, %{public}d", errno);
92         CloseFd(socketFd);
93         return ERROR;
94     }
95 
96     if (::bind(socketFd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
97         AUDIO_ERR_LOG("bind socket failed, %{public}d", errno);
98         CloseFd(socketFd);
99         return ERROR;
100     }
101 
102     *fd = socketFd;
103     return SUCCESS;
104 }
105 
AudioPnpReadUeventMsg(int sockFd,char * buffer,size_t length)106 ssize_t AudioSocketThread::AudioPnpReadUeventMsg(int sockFd, char *buffer, size_t length)
107 {
108     char credMsg[CMSG_SPACE(sizeof(struct ucred))] = {0};
109     iovec iov;
110     sockaddr_nl addr;
111     msghdr msghdr = {0};
112 
113     memset_s(&addr, sizeof(addr), 0, sizeof(addr));
114 
115     iov.iov_base = buffer;
116     iov.iov_len = length;
117 
118     msghdr.msg_name = &addr;
119     msghdr.msg_namelen = sizeof(addr);
120     msghdr.msg_iov = &iov;
121     msghdr.msg_iovlen = 1;
122     msghdr.msg_control = credMsg;
123     msghdr.msg_controllen = sizeof(credMsg);
124 
125     ssize_t len = recvmsg(sockFd, &msghdr, 0);
126     if (len <= 0) {
127         return ERROR;
128     }
129     cmsghdr *hdr = CMSG_FIRSTHDR(&msghdr);
130     if (hdr == NULL || hdr->cmsg_type != SCM_CREDENTIALS) {
131         AUDIO_ERR_LOG("Unexpected control message, ignored");
132         *buffer = '\0';
133         return ERROR;
134     }
135     return len;
136 }
137 
SetAudioPnpUevent(AudioEvent * audioEvent,struct AudioPnpUevent * audioPnpUevent,uint32_t h2wTypeLast)138 static void SetAudioPnpUevent(AudioEvent *audioEvent, struct AudioPnpUevent *audioPnpUevent, uint32_t h2wTypeLast)
139 {
140     switch (audioPnpUevent->switchState[0]) {
141         case REMOVE_AUDIO_DEVICE:
142             audioEvent->eventType = PNP_EVENT_DEVICE_REMOVE;
143             audioEvent->deviceType = h2wTypeLast;
144             break;
145         case ADD_DEVICE_HEADSET:
146         case ADD_DEVICE_HEADSET_WITHOUT_MIC:
147             audioEvent->eventType = PNP_EVENT_DEVICE_ADD;
148             audioEvent->deviceType = PNP_DEVICE_HEADSET;
149             break;
150         case ADD_DEVICE_ADAPTER:
151             audioEvent->eventType = PNP_EVENT_DEVICE_ADD;
152             audioEvent->deviceType = PNP_DEVICE_ADAPTER_DEVICE;
153             break;
154         default:
155             audioEvent->eventType = PNP_EVENT_DEVICE_ADD;
156             audioEvent->deviceType = PNP_DEVICE_UNKNOWN;
157             break;
158     }
159 }
160 
SetAudioPnpServerEventValue(AudioEvent * audioEvent,struct AudioPnpUevent * audioPnpUevent)161 int32_t AudioSocketThread::SetAudioPnpServerEventValue(AudioEvent *audioEvent, struct AudioPnpUevent *audioPnpUevent)
162 {
163     if (strncmp(audioPnpUevent->subSystem, UEVENT_SUBSYSTEM_SWITCH, strlen(UEVENT_SUBSYSTEM_SWITCH)) == 0) {
164         static uint32_t h2wTypeLast = PNP_DEVICE_HEADSET;
165         if (strncmp(audioPnpUevent->switchName, UEVENT_SWITCH_NAME_H2W, strlen(UEVENT_SWITCH_NAME_H2W)) != 0) {
166             AUDIO_ERR_LOG("the switch name of 'h2w' not found!");
167             return ERROR;
168         }
169         SetAudioPnpUevent(audioEvent, audioPnpUevent, h2wTypeLast);
170         h2wTypeLast = audioEvent->deviceType;
171         audioEvent->name = audioPnpUevent->name;
172         audioEvent->address = audioPnpUevent->devName;
173     } else {
174         if (strncmp(audioPnpUevent->action, UEVENT_ACTION_CHANGE, strlen(UEVENT_ACTION_CHANGE)) != 0) {
175             return ERROR;
176         }
177         if (strstr(audioPnpUevent->name, UEVENT_NAME_HEADSET) == NULL) {
178             return ERROR;
179         }
180         if (strncmp(audioPnpUevent->devType, UEVENT_TYPE_EXTCON, strlen(UEVENT_TYPE_EXTCON)) != 0) {
181             return ERROR;
182         }
183         if (strstr(audioPnpUevent->state, UEVENT_STATE_ANALOG_HS0) != NULL) {
184             audioEvent->eventType = PNP_EVENT_DEVICE_REMOVE;
185         } else if (strstr(audioPnpUevent->state, UEVENT_STATE_ANALOG_HS1) != NULL) {
186             audioEvent->eventType = PNP_EVENT_DEVICE_ADD;
187         } else {
188             return ERROR;
189         }
190         audioEvent->deviceType = PNP_DEVICE_HEADSET;
191     }
192     return SUCCESS;
193 }
194 
AudioAnalogHeadsetDetectDevice(struct AudioPnpUevent * audioPnpUevent)195 int32_t AudioSocketThread::AudioAnalogHeadsetDetectDevice(struct AudioPnpUevent *audioPnpUevent)
196 {
197     AudioEvent audioEvent;
198     if (audioPnpUevent == NULL) {
199         AUDIO_ERR_LOG("audioPnpUevent is null!");
200         return HDF_ERR_INVALID_PARAM;
201     }
202 
203     if (SetAudioPnpServerEventValue(&audioEvent, audioPnpUevent) != SUCCESS) {
204         return ERROR;
205     }
206     AUDIO_DEBUG_LOG("audio analog [%{public}s][%{public}s]",
207         audioEvent.deviceType == PNP_DEVICE_HEADSET ? "headset" : "headphone",
208         audioEvent.eventType == PNP_EVENT_DEVICE_ADD ? "add" : "removed");
209 
210     if (!IsUpdatePnpDeviceState(&audioEvent)) {
211         AUDIO_ERR_LOG("audio analog device[%{public}u] state[%{public}u] not need flush !", audioEvent.deviceType,
212             audioEvent.eventType);
213         return SUCCESS;
214     }
215     UpdatePnpDeviceState(&audioEvent);
216     return SUCCESS;
217 }
218 
CheckUsbDesc(struct UsbDevice * usbDevice)219 int32_t AudioSocketThread::CheckUsbDesc(struct UsbDevice *usbDevice)
220 {
221     if (usbDevice->descLen > USB_DES_LEN_MAX) {
222         AUDIO_ERR_LOG("usbDevice->descLen is more than USB_DES_LEN_MAX");
223         return HDF_ERR_INVALID_PARAM;
224     }
225     for (size_t len = 0; len < usbDevice->descLen;) {
226         size_t descLen = usbDevice->desc[len];
227         if (descLen == 0) {
228             AUDIO_ERR_LOG("descLen is 0");
229             return HDF_ERR_INVALID_PARAM;
230         }
231 
232         if (descLen < USB_IF_DESC_LEN) {
233             len += descLen;
234             continue;
235         }
236 
237         int32_t descType = usbDevice->desc[len + 1];
238         if (descType != USB_AUDIO_DESC_TYPE) {
239             len += descLen;
240             continue;
241         }
242 
243         /* According to the 1.0 and 2.0 usb standard protocols, the audio field corresponding to the interface
244          * description type is: offset=1 interface descriptor type is 4; offset=5 interface class,audio is 1; offset=6
245          * interface subclass,audio control is 1 */
246         int32_t usbClass = usbDevice->desc[len + USB_IF_CLASS_OFFSET];
247         int32_t subClass = usbDevice->desc[len + USB_IF_SUBCLASS_OFFSET];
248         if (usbClass == USB_AUDIO_CLASS && subClass == USB_AUDIO_SUBCLASS_CTRL) {
249             AUDIO_INFO_LOG(
250                 "descType %{public}d, usbClass %{public}d, subClass %{public}d", descType, usbClass, subClass);
251             return AUDIO_DEVICE_ONLINE;
252         }
253         len += descLen;
254     }
255     return SUCCESS;
256 }
257 
ReadAndScanUsbDev(const char * devPath)258 int32_t AudioSocketThread::ReadAndScanUsbDev(const char *devPath)
259 {
260     FILE *fp = NULL;
261     struct UsbDevice usbDevice;
262     size_t len;
263     errno_t error;
264     uint32_t tryTime = 0;
265     char realpathRes[PATH_MAX + 1] = {'\0'};
266 
267     if (devPath == NULL) {
268         AUDIO_ERR_LOG("audio devPath null");
269         return ERROR;
270     }
271 
272     while (tryTime < AUDIO_DEVICE_WAIT_TRY_TIME) {
273         if (realpath(devPath, realpathRes) != NULL || (strlen(devPath) > PATH_MAX)) {
274             AUDIO_INFO_LOG("audio try[%{public}d] realpath fail[%{public}d] realpathRes [%{public}s]",
275                 tryTime, errno, realpathRes);
276             break;
277         }
278         tryTime++;
279         OsalMSleep(AUDIO_DEVICE_WAIT_ONLINE);
280     }
281 
282     fp = fopen(realpathRes, "r");
283     if (fp == NULL) {
284         AUDIO_ERR_LOG("audio realpath open fail[%{public}d]", errno);
285         return ERROR;
286     }
287 
288     len = fread(usbDevice.desc, 1, sizeof(usbDevice.desc) - 1, fp);
289     if (len == 0) {
290         AUDIO_ERR_LOG("audio realpath read fail");
291         fclose(fp);
292         return ERROR;
293     }
294     fclose(fp);
295 
296     error = strncpy_s((char *)usbDevice.devName, sizeof(usbDevice.devName), realpathRes,
297         sizeof(usbDevice.devName) - 1);
298     if (error != EOK) {
299         AUDIO_ERR_LOG("audio realpath strncpy fail");
300         return ERROR;
301     }
302 
303     usbDevice.descLen = len;
304     return CheckUsbDesc(&usbDevice);
305 }
306 
FindAudioUsbDevice(const char * devName)307 bool AudioSocketThread::FindAudioUsbDevice(const char *devName)
308 {
309     if (strlen(devName) > USB_DEV_NAME_LEN_MAX - 1) {
310         AUDIO_ERR_LOG("find usb audio device name exceed max len");
311         return false;
312     }
313 
314     for (uint32_t count = 0; count < AUDIO_UEVENT_USB_DEVICE_COUNT; count++) {
315         if (g_audioUsbDeviceList[count].isUsed &&
316             (strncmp((char *)g_audioUsbDeviceList[count].devName, devName, strlen(devName)) == EOK)) {
317             return true;
318         }
319     }
320     return false;
321 }
322 
AddAudioUsbDevice(const char * devName)323 bool AudioSocketThread::AddAudioUsbDevice(const char *devName)
324 {
325     if (strlen(devName) > USB_DEV_NAME_LEN_MAX - 1) {
326         AUDIO_ERR_LOG("add usb audio device name exceed max len");
327         return false;
328     }
329 
330     if (FindAudioUsbDevice(devName)) {
331         AUDIO_ERR_LOG("find usb audio device name[%{public}s]", devName);
332         return true;
333     }
334 
335     for (uint32_t count = 0; count < AUDIO_UEVENT_USB_DEVICE_COUNT; count++) {
336         if (g_audioUsbDeviceList[count].isUsed) {
337             continue;
338         }
339         if (strncpy_s((char *)g_audioUsbDeviceList[count].devName, USB_DEV_NAME_LEN_MAX, devName, strlen(devName))
340             != EOK) {
341             AUDIO_ERR_LOG("add usb audio device name fail");
342             return false;
343         }
344         g_audioUsbDeviceList[count].isUsed = true;
345         return true;
346     }
347     AUDIO_ERR_LOG("add usb audio device name fail");
348     return false;
349 }
350 
CheckAudioUsbDevice(const char * devName)351 bool AudioSocketThread::CheckAudioUsbDevice(const char *devName)
352 {
353     int32_t state = 0;
354     int32_t len;
355     char subDir[USB_DEV_NAME_LEN_MAX] = {0};
356 
357     if (*devName == '\0') {
358         return false;
359     }
360     len = snprintf_s(subDir, USB_DEV_NAME_LEN_MAX, USB_DEV_NAME_LEN_MAX - 1, "/dev/" "%s", devName);
361     if (len < 0) {
362         AUDIO_ERR_LOG("audio snprintf dev dir fail");
363         return false;
364     }
365     AUDIO_INFO_LOG("CheckAudioUsbDevice: devName:%{public}s subDir:%{public}s len:%{public}d", devName, subDir, len);
366 
367     state = ReadAndScanUsbDev(subDir);
368     if ((state == AUDIO_DEVICE_ONLINE) && AddAudioUsbDevice(devName)) {
369         return true;
370     }
371     return false;
372 }
373 
DeleteAudioUsbDevice(const char * devName)374 bool AudioSocketThread::DeleteAudioUsbDevice(const char *devName)
375 {
376     if (strlen(devName) > USB_DEV_NAME_LEN_MAX - 1) {
377         AUDIO_ERR_LOG("delete usb audio device name exceed max len");
378         return false;
379     }
380 
381     for (uint32_t count = 0; count < AUDIO_UEVENT_USB_DEVICE_COUNT; count++) {
382         if (g_audioUsbDeviceList[count].isUsed &&
383             strncmp((char *)g_audioUsbDeviceList[count].devName, devName, strlen(devName)) == EOK) {
384             g_audioUsbDeviceList[count].isUsed = false;
385             AUDIO_INFO_LOG("delete usb audio device name[%{public}s]", devName);
386             return true;
387         }
388     }
389 
390     return false;
391 }
392 
AudioDpDetectDevice(struct AudioPnpUevent * audioPnpUevent)393 int32_t AudioSocketThread::AudioDpDetectDevice(struct AudioPnpUevent *audioPnpUevent)
394 {
395     AudioEvent audioEvent = {0};
396     if (audioPnpUevent == NULL) {
397         return HDF_ERR_INVALID_PARAM;
398     }
399     if ((strcmp(audioPnpUevent->subSystem, "switch") != 0) ||
400         (strstr(audioPnpUevent->switchName, "hdmi_audio") == NULL) ||
401         (strcmp(audioPnpUevent->action, "change") != 0)) {
402         return HDF_ERR_INVALID_PARAM;
403     }
404 
405     if (strcmp(audioPnpUevent->switchState, "1") == 0) {
406         audioEvent.eventType = PNP_EVENT_DEVICE_ADD;
407     } else if (strcmp(audioPnpUevent->switchState, "0") == 0) {
408         audioEvent.eventType = PNP_EVENT_DEVICE_REMOVE;
409     } else {
410         AUDIO_ERR_LOG("audio dp device [%{public}d]", audioEvent.eventType);
411         return ERROR;
412     }
413     audioEvent.deviceType = PNP_DEVICE_DP_DEVICE;
414 
415     std::string switchNameStr = audioPnpUevent->switchName;
416 
417     auto portBegin = switchNameStr.find("device_port=");
418     if (portBegin != switchNameStr.npos) {
419         audioEvent.name = switchNameStr.substr(portBegin + std::strlen("device_port="),
420             switchNameStr.length() - portBegin - std::strlen("device_port="));
421     }
422 
423     auto addressBegin = switchNameStr.find("hdmi_audio");
424     auto addressEnd = switchNameStr.find_first_of("device_port", portBegin);
425     if (addressEnd != switchNameStr.npos) {
426         std::string portId = switchNameStr.substr(addressBegin + std::strlen("hdmi_audio"),
427             addressEnd - addressBegin - std::strlen("hdmi_audio")-1);
428         audioEvent.address = portId;
429         AUDIO_INFO_LOG("audio dp device portId:[%{public}s]", portId.c_str());
430     }
431 
432     if (audioEvent.address.empty()) {
433         audioEvent.address = '0';
434     }
435     AUDIO_INFO_LOG("audio dp device [%{public}s]", audioEvent.eventType == PNP_EVENT_DEVICE_ADD ? "add" : "removed");
436 
437     if (!IsUpdatePnpDeviceState(&audioEvent)) {
438         AUDIO_ERR_LOG("audio usb device[%{public}u] state[%{public}u] not need flush !", audioEvent.deviceType,
439             audioEvent.eventType);
440         return SUCCESS;
441     }
442     UpdatePnpDeviceState(&audioEvent);
443     return SUCCESS;
444 }
445 
AudioUsbHeadsetDetectDevice(struct AudioPnpUevent * audioPnpUevent)446 int32_t AudioSocketThread::AudioUsbHeadsetDetectDevice(struct AudioPnpUevent *audioPnpUevent)
447 {
448     AudioEvent audioEvent = {0};
449 
450     if (audioPnpUevent == NULL) {
451         return HDF_ERR_INVALID_PARAM;
452     }
453 
454     if (audioPnpUevent->action == NULL || audioPnpUevent->devName == NULL || audioPnpUevent->subSystem == NULL ||
455         audioPnpUevent->devType == NULL) {
456         return HDF_ERR_INVALID_PARAM;
457     }
458 
459     if ((strcmp(audioPnpUevent->subSystem, UEVENT_SUBSYSTEM_USB) != 0) ||
460         (strcmp(audioPnpUevent->devType, UEVENT_SUBSYSTEM_USB_DEVICE) != 0) ||
461         (strstr(audioPnpUevent->devName, BUS_USB_DIR) == NULL)) {
462         return HDF_ERR_INVALID_PARAM;
463     }
464 
465     if (strcmp(audioPnpUevent->action, UEVENT_ACTION_ADD) == 0) {
466         if (!CheckAudioUsbDevice(audioPnpUevent->devName)) {
467             return HDF_ERR_INVALID_PARAM;
468         }
469         audioEvent.eventType = PNP_EVENT_DEVICE_ADD;
470     } else if (strcmp(audioPnpUevent->action, UEVENT_ACTION_REMOVE) == 0) {
471         if (!DeleteAudioUsbDevice(audioPnpUevent->devName)) {
472             return HDF_ERR_INVALID_PARAM;
473         }
474         audioEvent.eventType = PNP_EVENT_DEVICE_REMOVE;
475     } else {
476         return ERROR;
477     }
478 
479     audioEvent.deviceType = PNP_DEVICE_USB_HEADSET;
480     AUDIO_DEBUG_LOG("audio usb headset [%{public}s]", audioEvent.eventType == PNP_EVENT_DEVICE_ADD ? "add" : "removed");
481 
482     audioEvent.name = audioPnpUevent->name;
483     audioEvent.address = audioPnpUevent->devName;
484 
485     if (!IsUpdatePnpDeviceState(&audioEvent)) {
486         AUDIO_ERR_LOG("audio usb device[%{public}u] state[%{public}u] not need flush !", audioEvent.deviceType,
487             audioEvent.eventType);
488         return SUCCESS;
489     }
490     UpdatePnpDeviceState(&audioEvent);
491     return SUCCESS;
492 }
493 
AudioMicBlockDevice(struct AudioPnpUevent * audioPnpUevent)494 int32_t AudioSocketThread::AudioMicBlockDevice(struct AudioPnpUevent *audioPnpUevent)
495 {
496     if (audioPnpUevent == nullptr) {
497         AUDIO_ERR_LOG("mic blocked audioPnpUevent is null");
498         return HDF_ERR_INVALID_PARAM;
499     }
500     AudioEvent audioEvent = {0};
501     if (strncmp(audioPnpUevent->name, "mic_blocked", strlen("mic_blocked")) == 0) {
502         audioEvent.eventType = PNP_EVENT_MIC_BLOCKED;
503     } else if (strncmp(audioPnpUevent->name, "mic_un_blocked", strlen("mic_un_blocked")) == 0) {
504         audioEvent.eventType = PNP_EVENT_MIC_UNBLOCKED;
505     } else {
506         return HDF_ERR_INVALID_PARAM;
507     }
508     audioEvent.deviceType = PNP_DEVICE_MIC;
509 
510     AUDIO_INFO_LOG("mic blocked uevent info recv: %{public}s", audioPnpUevent->name);
511     UpdatePnpDeviceState(&audioEvent);
512     return SUCCESS;
513 }
514 
AudioPnpUeventParse(const char * msg,const ssize_t strLength)515 bool AudioSocketThread::AudioPnpUeventParse(const char *msg, const ssize_t strLength)
516 {
517     struct AudioPnpUevent audioPnpUevent = {"", "", "", "", "", "", "", "", ""};
518 
519     if (strncmp(msg, "libudev", strlen("libudev")) == 0) {
520         return false;
521     }
522 
523     if (strLength > UEVENT_MSG_LEN + 1) {
524         AUDIO_ERR_LOG("strLength > UEVENT_MSG_LEN + 1");
525         return false;
526     }
527     AUDIO_DEBUG_LOG("Param strLength: %{public}zu msg:[%{public}s] len:[%{public}zu]", strLength, msg, strlen(msg));
528     for (const char *msgTmp = msg; msgTmp < (msg + strLength);) {
529         if (*msgTmp == '\0') {
530             msgTmp++;
531             continue;
532         }
533         AUDIO_DEBUG_LOG("Param msgTmp:[%{public}s] len:[%{public}zu]", msgTmp, strlen(msgTmp));
534         const char *arrStrTmp[UEVENT_ARR_SIZE] = {
535             UEVENT_ACTION, UEVENT_DEV_NAME, UEVENT_NAME, UEVENT_STATE, UEVENT_DEVTYPE,
536             UEVENT_SUBSYSTEM, UEVENT_SWITCH_NAME, UEVENT_SWITCH_STATE, UEVENT_HDI_NAME
537         };
538         const char **arrVarTmp[UEVENT_ARR_SIZE] = {
539             &audioPnpUevent.action, &audioPnpUevent.devName, &audioPnpUevent.name,
540             &audioPnpUevent.state, &audioPnpUevent.devType, &audioPnpUevent.subSystem,
541             &audioPnpUevent.switchName, &audioPnpUevent.switchState, &audioPnpUevent.hidName
542         };
543         for (int count = 0; count < UEVENT_ARR_SIZE; count++) {
544             if (strncmp(msgTmp, arrStrTmp[count], strlen(arrStrTmp[count])) == 0) {
545                 msgTmp += strlen(arrStrTmp[count]);
546                 *arrVarTmp[count] = msgTmp;
547                 break;
548             }
549         }
550         msgTmp += strlen(msgTmp) + 1;
551     }
552 
553     if ((AudioAnalogHeadsetDetectDevice(&audioPnpUevent) == SUCCESS) ||
554         (AudioUsbHeadsetDetectDevice(&audioPnpUevent) == SUCCESS) ||
555         (AudioDpDetectDevice(&audioPnpUevent) == SUCCESS) ||
556         (AudioMicBlockDevice(&audioPnpUevent) == SUCCESS)) {
557         return true;
558     }
559 
560     return false;
561 }
562 
DetectAnalogHeadsetState(AudioEvent * audioEvent)563 int32_t AudioSocketThread::DetectAnalogHeadsetState(AudioEvent *audioEvent)
564 {
565     int8_t state = 0;
566     FILE *fp = fopen(SWITCH_STATE_PATH, "r");
567     if (fp == NULL) {
568         AUDIO_ERR_LOG("audio open switch state node fail, %{public}d", errno);
569         return HDF_ERR_INVALID_PARAM;
570     }
571 
572     size_t ret = fread(&state, STATE_PATH_ITEM_SIZE, STATE_PATH_ITEM_SIZE, fp);
573     if (ret == 0) {
574         fclose(fp);
575         AUDIO_ERR_LOG("audio read switch state node fail, %{public}d", errno);
576         return ERROR;
577     }
578 
579     if (state == '0') {
580         audioEvent->eventType = AUDIO_DEVICE_REMOVE;
581         audioEvent->deviceType = AUDIO_HEADSET;
582     } else {
583         audioEvent->eventType = AUDIO_DEVICE_ADD;
584         audioEvent->deviceType = AUDIO_HEADSET;
585     }
586 
587     fclose(fp);
588     return SUCCESS;
589 }
590 
UpdateDeviceState(AudioEvent audioEvent)591 void AudioSocketThread::UpdateDeviceState(AudioEvent audioEvent)
592 {
593     char pnpInfo[AUDIO_EVENT_INFO_LEN_MAX] = {0};
594     int32_t ret;
595     if (!IsUpdatePnpDeviceState(&audioEvent)) {
596         AUDIO_ERR_LOG("audio first pnp device[%{public}u] state[%{public}u] not need flush !", audioEvent.deviceType,
597             audioEvent.eventType);
598         return;
599     }
600     ret = snprintf_s(pnpInfo, AUDIO_EVENT_INFO_LEN_MAX, AUDIO_EVENT_INFO_LEN_MAX - 1, "EVENT_TYPE=%u;DEVICE_TYPE=%u",
601         audioEvent.eventType, audioEvent.deviceType);
602     if (ret < 0) {
603         AUDIO_ERR_LOG("snprintf_s fail!");
604         return;
605     }
606 
607     UpdatePnpDeviceState(&audioEvent);
608     return;
609 }
610 
IsBadName(const char * name)611 inline bool AudioSocketThread::IsBadName(const char *name)
612 {
613     if (*name == '\0') {
614         AUDIO_ERR_LOG("name is null");
615         return true;
616     }
617 
618     while (*name != '\0') {
619         if (isdigit(*name++) == 0) {
620             return true;
621         }
622     }
623 
624     return false;
625 }
626 
ScanUsbBusSubDir(const char * subDir)627 int32_t AudioSocketThread::ScanUsbBusSubDir(const char *subDir)
628 {
629     int32_t len;
630     DIR *devDir = NULL;
631     dirent *dirEnt = NULL;
632 
633     char devName[USB_DEV_NAME_LEN_MAX] = {0};
634 
635     devDir = opendir(subDir);
636     if (devDir == NULL) {
637         AUDIO_ERR_LOG("open usb sub dir failed");
638         return HDF_ERR_INVALID_PARAM;
639     }
640 
641     int32_t state = SUCCESS;
642     while (((dirEnt = readdir(devDir)) != NULL) && (state == SUCCESS)) {
643         if (IsBadName(dirEnt->d_name)) {
644             continue;
645         }
646 
647         len = snprintf_s(devName, USB_DEV_NAME_LEN_MAX, USB_DEV_NAME_LEN_MAX - 1, "%s/%s", subDir,
648             dirEnt->d_name);
649         if (len < 0) {
650             AUDIO_ERR_LOG("audio snprintf dev dir fail");
651             state = ERROR;
652             break;
653         }
654 
655         AUDIO_DEBUG_LOG("audio usb dir[%{public}s]", devName);
656         state = ReadAndScanUsbDev(devName);
657         if (state == AUDIO_DEVICE_ONLINE) {
658             char *subDevName = devName + strlen("/dev/");
659             AUDIO_ERR_LOG("audio sub dev dir=[%{public}s]", subDevName);
660             if (AddAudioUsbDevice(subDevName)) {
661                 AUDIO_ERR_LOG("audio add usb audio device success");
662                 break;
663             }
664         }
665     }
666 
667     closedir(devDir);
668     return state;
669 }
670 
DetectUsbHeadsetState(AudioEvent * audioEvent)671 int32_t AudioSocketThread::DetectUsbHeadsetState(AudioEvent *audioEvent)
672 {
673     int32_t len;
674     DIR *busDir = NULL;
675     dirent *dirEnt = NULL;
676 
677     char subDir[USB_DEV_NAME_LEN_MAX] = {0};
678 
679     busDir = opendir(DEV_BUS_USB_DIR);
680     if (busDir == NULL) {
681         AUDIO_ERR_LOG("open usb dir failed");
682         return HDF_ERR_INVALID_PARAM;
683     }
684 
685     int32_t state = SUCCESS;
686     while (((dirEnt = readdir(busDir)) != NULL) && (state == SUCCESS)) {
687         if (IsBadName(dirEnt->d_name)) {
688             continue;
689         }
690 
691         len = snprintf_s(subDir, USB_DEV_NAME_LEN_MAX, USB_DEV_NAME_LEN_MAX - 1, DEV_BUS_USB_DIR "/%s",
692             dirEnt->d_name);
693         if (len < 0) {
694             AUDIO_ERR_LOG("audio snprintf dev dir fail");
695             break;
696         }
697         state = ScanUsbBusSubDir(subDir);
698         if (state == AUDIO_DEVICE_ONLINE) {
699             audioEvent->eventType = AUDIO_DEVICE_ADD;
700             audioEvent->deviceType = AUDIO_USB_HEADSET;
701             closedir(busDir);
702             return SUCCESS;
703         }
704     }
705 
706     closedir(busDir);
707     return ERROR;
708 }
709 } // namespace AudioStandard
710 } // namespace OHOS