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