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