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 "alsa_lib_common.h"
17 #include <ctype.h>
18 #include <limits.h>
19 #include "audio_common.h"
20 #include "audio_internal.h"
21 #include "cJSON.h"
22 #include "osal_mem.h"
23 #include "securec.h"
24
25 #define HDF_LOG_TAG HDF_AUDIO_HAL_LIB
26
27 #define USB_AUDIO "USB Audio"
28
29 #define MAX_ELEMENT 100
30 #define ALSA_CARD_CONFIG_FILE HDF_CONFIG_DIR "/alsa_adapter.json"
31 #define ALSA_CONFIG_FILE_MAX (2 * 1024) // 2KB
32
33 struct CardStream {
34 int card;
35 snd_pcm_stream_t stream; /** Playback stream or Capture stream */
36 };
37
38 static struct AudioCardInfo *g_audioCardIns = NULL;
39 struct AlsaDevInfo *g_alsadevInfo = NULL;
40 static bool g_parseFlag = false;
41
42 char *g_usbVolCtlNameTable[] = {
43 "Earpiece",
44 "Speaker",
45 "DACL",
46 "DACR",
47 "Headphone",
48 "PCM",
49 };
50
51 static struct DevProcInfo *g_sndCardList[SND_CARD_MAX][AUDIO_MAX_CARD_NUM] = {{NULL}};
52
AudioGetSoundCardsInfo(enum SndCardType cardType)53 static struct DevProcInfo **AudioGetSoundCardsInfo(enum SndCardType cardType)
54 {
55 return (struct DevProcInfo **)(g_sndCardList + cardType);
56 }
57
InitCardIns(void)58 int32_t InitCardIns(void)
59 {
60 if (g_audioCardIns == NULL) {
61 g_audioCardIns = (struct AudioCardInfo *)OsalMemCalloc(MAX_CARD_NUM * sizeof(struct AudioCardInfo));
62 if (g_audioCardIns == NULL) {
63 AUDIO_FUNC_LOGE("Failed to allocate memory!");
64 return HDF_FAILURE;
65 }
66 }
67
68 return HDF_SUCCESS;
69 }
70
AddCardIns(const char * cardName)71 static struct AudioCardInfo *AddCardIns(const char *cardName)
72 {
73 int32_t i;
74 int32_t ret;
75
76 if (cardName == NULL || strlen(cardName) == 0) {
77 AUDIO_FUNC_LOGE("Invalid cardName!");
78 return NULL;
79 }
80
81 if (g_audioCardIns == NULL) {
82 AUDIO_FUNC_LOGE("g_audioCardIns is NULL!");
83 return NULL;
84 }
85
86 for (i = 0; i < MAX_CARD_NUM; i++) {
87 if (g_audioCardIns[i].cardStatus == 0) {
88 (void)memset_s(&g_audioCardIns[i], sizeof(struct AudioCardInfo), 0, sizeof(struct AudioCardInfo));
89 ret = strncpy_s(g_audioCardIns[i].cardName, MAX_CARD_NAME_LEN + 1, cardName, strlen(cardName));
90 if (ret != 0) {
91 AUDIO_FUNC_LOGE("strncpy_s failed!");
92 return NULL;
93 }
94 g_audioCardIns[i].cardStatus++;
95 return &(g_audioCardIns[i]);
96 }
97 }
98 AUDIO_FUNC_LOGE("Failed to AddCardIns!");
99
100 return NULL;
101 }
102
FindCardIns(const char * cardName)103 static struct AudioCardInfo *FindCardIns(const char *cardName)
104 {
105 int32_t i;
106
107 if (cardName == NULL || strlen(cardName) == 0) {
108 AUDIO_FUNC_LOGE("Invalid cardName!");
109 return NULL;
110 }
111
112 if (g_audioCardIns == NULL) {
113 AUDIO_FUNC_LOGE("g_audioCardIns is NULL!");
114 return NULL;
115 }
116
117 for (i = 0; i < MAX_CARD_NUM; i++) {
118 if (strcmp(g_audioCardIns[i].cardName, cardName) == 0) {
119 return &(g_audioCardIns[i]);
120 }
121 }
122
123 return NULL;
124 }
125
AudioAddCardIns(const char * cardName)126 static int32_t AudioAddCardIns(const char *cardName)
127 {
128 struct AudioCardInfo *cardInfo = NULL;
129
130 if (cardName == NULL) {
131 AUDIO_FUNC_LOGE("Invalid cardName!");
132 return HDF_FAILURE;
133 }
134
135 cardInfo = FindCardIns(cardName);
136 if (cardInfo == NULL) {
137 cardInfo = AddCardIns(cardName);
138 if (cardInfo == NULL) {
139 AUDIO_FUNC_LOGE("AddCardIns failed!");
140 return HDF_FAILURE;
141 }
142 }
143
144 return HDF_SUCCESS;
145 }
146
GetCardIns(const char * cardName)147 struct AudioCardInfo *GetCardIns(const char *cardName)
148 {
149 if (cardName == NULL) {
150 AUDIO_FUNC_LOGE("Invalid cardName!");
151 return NULL;
152 }
153
154 return FindCardIns(cardName);
155 }
156
CheckCardStatus(struct AudioCardInfo * cardIns)157 void CheckCardStatus(struct AudioCardInfo *cardIns)
158 {
159 int32_t ret;
160 if (cardIns == NULL) {
161 AUDIO_FUNC_LOGE("The parameter is empty!");
162 return;
163 }
164 if (cardIns->cardStatus > 0) {
165 cardIns->cardStatus -= 1;
166 }
167 if (cardIns->cardStatus == 0) {
168 if (cardIns->renderPcmHandle != NULL) {
169 ret = snd_pcm_close(cardIns->renderPcmHandle);
170 if (ret < 0) {
171 AUDIO_FUNC_LOGE("snd_pcm_close fail: %{public}s", snd_strerror(ret));
172 }
173 cardIns->renderPcmHandle = NULL;
174 }
175 if (cardIns->capturePcmHandle != NULL) {
176 ret = snd_pcm_close(cardIns->capturePcmHandle);
177 if (ret < 0) {
178 AUDIO_FUNC_LOGE("snd_pcm_close fail: %{public}s", snd_strerror(ret));
179 }
180 cardIns->capturePcmHandle = NULL;
181 }
182 (void)memset_s(cardIns->cardName, MAX_CARD_NAME_LEN + 1, 0, MAX_CARD_NAME_LEN + 1);
183 }
184 }
185
CardInfoRelease(void)186 static void CardInfoRelease(void)
187 {
188 for (int i = 0; i < SND_CARD_MAX; i++) {
189 for (int j = 0; j < AUDIO_MAX_CARD_NUM; j++) {
190 if (g_sndCardList[i][j] != NULL) {
191 AudioMemFree((void **)&(g_sndCardList[i][j]));
192 g_sndCardList[i][j] = NULL;
193 }
194 }
195 }
196 g_parseFlag = false;
197 }
198
DestroyCardList(void)199 int32_t DestroyCardList(void)
200 {
201 int32_t i;
202
203 if (g_audioCardIns != NULL) {
204 for (i = 0; i < MAX_CARD_NUM; i++) {
205 if (g_audioCardIns[i].cardStatus != 0) {
206 AUDIO_FUNC_LOGE("refCount is not zero, Sound card in use!");
207 return HDF_ERR_DEVICE_BUSY;
208 }
209 }
210 AudioMemFree((void **)&g_audioCardIns);
211 g_audioCardIns = NULL;
212
213 /* Release the sound card configuration space */
214 CardInfoRelease();
215 }
216
217 return HDF_SUCCESS;
218 }
219
GetDevIns(struct AudioCardInfo * cardIns,int card,const char * cardId,int dev,const char * pcmInfoId)220 static int32_t GetDevIns(struct AudioCardInfo *cardIns, int card, const char *cardId, int dev, const char *pcmInfoId)
221 {
222 int32_t i;
223 int32_t ret;
224
225 if (cardIns == NULL || cardId == NULL || pcmInfoId == NULL || strlen(cardId) == 0) {
226 AUDIO_FUNC_LOGE("The parameter is empty!");
227 return HDF_FAILURE;
228 }
229
230 for (i = 0; i < MAX_CARD_NUM; i++) {
231 if (strlen(cardIns->alsaDevIns[i].cardId) == 0) {
232 cardIns->alsaDevIns[i].card = card;
233 cardIns->alsaDevIns[i].device = dev;
234 ret = strncpy_s(cardIns->alsaDevIns[i].cardId, MAX_CARD_NAME_LEN + 1, cardId, strlen(cardId));
235 if (ret != 0) {
236 AUDIO_FUNC_LOGE("strncpy_s failed!");
237 return HDF_FAILURE;
238 }
239 ret = strncpy_s(cardIns->alsaDevIns[i].pcmInfoId, MAX_CARD_NAME_LEN + 1, pcmInfoId, strlen(pcmInfoId));
240 if (ret != 0) {
241 AUDIO_FUNC_LOGE("strncpy_s failed!");
242 return HDF_FAILURE;
243 }
244 return HDF_SUCCESS;
245 }
246 }
247 AUDIO_FUNC_LOGE("A maximum of %{public}d sound cards are supported!", MAX_CARD_NUM);
248
249 return HDF_FAILURE;
250 }
251
CloseMixerHandle(snd_mixer_t * alsaMixHandle)252 int32_t CloseMixerHandle(snd_mixer_t *alsaMixHandle)
253 {
254 int32_t ret;
255
256 if (alsaMixHandle == NULL) {
257 return HDF_SUCCESS;
258 }
259
260 ret = snd_mixer_close(alsaMixHandle);
261 if (ret < 0) {
262 AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret));
263 return HDF_FAILURE;
264 }
265
266 return HDF_SUCCESS;
267 }
268
InitSound(snd_mixer_t ** mixer,char * hwCtlName)269 void InitSound(snd_mixer_t **mixer, char *hwCtlName)
270 {
271 int32_t ret;
272
273 if (mixer == NULL || hwCtlName == NULL) {
274 AUDIO_FUNC_LOGE("The parameter is null.");
275 return;
276 }
277
278 ret = snd_mixer_open(mixer, 0);
279 if (ret < 0) {
280 AUDIO_FUNC_LOGE("Failed to open mixer: %{public}s.", snd_strerror(ret));
281 return;
282 }
283
284 ret = snd_mixer_attach(*mixer, hwCtlName);
285 if (ret < 0) {
286 AUDIO_FUNC_LOGE("Failed to attach mixer: %{public}s.", snd_strerror(ret));
287 ret = snd_mixer_close(*mixer);
288 if (ret < 0) {
289 AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret));
290 }
291 return;
292 }
293
294 ret = snd_mixer_selem_register(*mixer, NULL, NULL);
295 if (ret < 0) {
296 AUDIO_FUNC_LOGE("Failed to register mixer element: %{public}s.", snd_strerror(ret));
297 ret = snd_mixer_close(*mixer);
298 if (ret < 0) {
299 AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret));
300 }
301 return;
302 }
303
304 ret = snd_mixer_load(*mixer);
305 if (ret < 0) {
306 AUDIO_FUNC_LOGE("Failed to load mixer element: %{public}s.", snd_strerror(ret));
307 ret = snd_mixer_close(*mixer);
308 if (ret < 0) {
309 AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret));
310 }
311 return;
312 }
313 }
314
HdfIoServiceBindName(const char * serviceName)315 struct HdfIoService *HdfIoServiceBindName(const char *serviceName)
316 {
317 (void)serviceName;
318 /* Nothing to do */
319 static struct HdfIoService hdfIoService;
320 return &hdfIoService;
321 }
322
GetDevCardsInfo(snd_ctl_t * handle,snd_ctl_card_info_t * info,snd_pcm_info_t * pcmInfo,struct AudioCardInfo * cardIns,struct CardStream cardStream)323 static void GetDevCardsInfo(snd_ctl_t *handle, snd_ctl_card_info_t *info, snd_pcm_info_t *pcmInfo,
324 struct AudioCardInfo *cardIns, struct CardStream cardStream)
325 {
326 int dev = -1;
327 int32_t ret;
328
329 if (handle == NULL || info == NULL || pcmInfo == NULL || cardIns == NULL) {
330 AUDIO_FUNC_LOGE("The parameter is empty.");
331 return;
332 }
333
334 while (1) {
335 ret = snd_ctl_pcm_next_device(handle, &dev);
336 if (ret < 0) {
337 AUDIO_FUNC_LOGE("snd_ctl_pcm_next_device error: %{public}s.", snd_strerror(ret));
338 }
339 if (dev < 0) {
340 break;
341 }
342
343 snd_pcm_info_set_device(pcmInfo, dev);
344 snd_pcm_info_set_subdevice(pcmInfo, 0);
345 snd_pcm_info_set_stream(pcmInfo, cardStream.stream);
346 if ((ret = snd_ctl_pcm_info(handle, pcmInfo)) < 0) {
347 if (ret != -ENOENT) {
348 AUDIO_FUNC_LOGE(
349 "control digital audio info (%{public}d): %{public}s", cardStream.card, snd_strerror(ret));
350 }
351 continue;
352 }
353
354 const char *cardId = snd_ctl_card_info_get_id(info);
355 const char *pcmInfoId = snd_pcm_info_get_id(pcmInfo);
356 ret = GetDevIns(cardIns, cardStream.card, cardId, dev, pcmInfoId);
357 if (ret < 0) {
358 AUDIO_FUNC_LOGE("GetDevIns error.");
359 return;
360 }
361 }
362 }
363
GetDeviceList(struct AudioCardInfo * cardIns,snd_pcm_stream_t stream)364 static void GetDeviceList(struct AudioCardInfo *cardIns, snd_pcm_stream_t stream)
365 {
366 int32_t ret;
367 snd_ctl_t *handle;
368 int card = -1;
369 snd_ctl_card_info_t *info = NULL;
370 snd_pcm_info_t *pcminfo = NULL;
371 char deviceName[MAX_CARD_NAME_LEN] = {0};
372 struct CardStream cardStream;
373
374 if (cardIns == NULL) {
375 AUDIO_FUNC_LOGE("The parameter is empty.");
376 return;
377 }
378 snd_ctl_card_info_alloca(&info);
379 snd_pcm_info_alloca(&pcminfo);
380
381 ret = snd_card_next(&card);
382 if (ret < 0 || card < 0) {
383 AUDIO_FUNC_LOGE("No soundcards found: %{public}s.", snd_strerror(ret));
384 return;
385 }
386 while (card >= 0) {
387 (void)memset_s(deviceName, MAX_CARD_NAME_LEN, 0, MAX_CARD_NAME_LEN);
388 ret = snprintf_s(deviceName, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1, "hw:%d", card);
389 if (ret < 0) {
390 AUDIO_FUNC_LOGE("snprintf_s failed");
391 return;
392 }
393
394 ret = snd_ctl_open(&handle, deviceName, 0);
395 if (ret == HDF_SUCCESS) {
396 ret = snd_ctl_card_info(handle, info);
397 if (ret == HDF_SUCCESS) {
398 cardStream.card = card;
399 cardStream.stream = stream;
400 GetDevCardsInfo(handle, info, pcminfo, cardIns, cardStream);
401 }
402 ret = snd_ctl_close(handle);
403 if (ret < 0) {
404 AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret));
405 return;
406 }
407 }
408
409 ret = snd_card_next(&card);
410 if (ret < 0) {
411 AUDIO_FUNC_LOGE("snd_card_next error: %{public}s", snd_strerror(ret));
412 return;
413 }
414 }
415 }
416
GetSelCardInfo(struct AudioCardInfo * cardIns,struct AlsaDevInfo * devInsHandle)417 int32_t GetSelCardInfo(struct AudioCardInfo *cardIns, struct AlsaDevInfo *devInsHandle)
418 {
419 int32_t ret;
420
421 if (cardIns == NULL || devInsHandle == NULL) {
422 AUDIO_FUNC_LOGE("The parameter is empty.");
423 return HDF_FAILURE;
424 }
425
426 ret = snprintf_s(cardIns->devName, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1, "hw:%d,%d", devInsHandle->card,
427 devInsHandle->device);
428 if (ret >= 0) {
429 ret = snprintf_s(cardIns->ctrlName, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1, "hw:%d", devInsHandle->card);
430 if (ret >= 0) {
431 ret = snprintf_s(cardIns->alsaCardId, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1, "%s", devInsHandle->cardId);
432 if (ret >= 0) {
433 return HDF_SUCCESS;
434 }
435 }
436 }
437 AUDIO_FUNC_LOGE("snprintf_s failed");
438
439 return HDF_FAILURE;
440 }
441
MatchProfileSoundCard(struct DevProcInfo * cardInfo[],char * adapterName)442 static const char *MatchProfileSoundCard(struct DevProcInfo *cardInfo[], char *adapterName)
443 {
444 if (cardInfo == NULL || adapterName == NULL) {
445 AUDIO_FUNC_LOGE("The parameter is empty.");
446 return NULL;
447 }
448
449 if (strncmp(adapterName, PRIMARY, strlen(PRIMARY)) != 0) {
450 AUDIO_FUNC_LOGE("The user sound card name %{public}s is incorrect!", adapterName);
451 return NULL;
452 }
453
454 for (int i = 0; i < AUDIO_MAX_CARD_NUM; i++) {
455 if (cardInfo[i] != NULL) {
456 if (strncmp(cardInfo[i]->cardName, PRIMARY, strlen(PRIMARY)) == 0) {
457 return cardInfo[i]->cid;
458 }
459 }
460 }
461 AUDIO_FUNC_LOGE("No sound card selected by the user is matched from the configuration file.");
462
463 return NULL;
464 }
465
GetPrimaryCardInfo(struct AudioCardInfo * cardIns)466 static int32_t GetPrimaryCardInfo(struct AudioCardInfo *cardIns)
467 {
468 int32_t i;
469 int32_t ret;
470 const char *cardId = NULL;
471 struct DevProcInfo **cardInfoPri = NULL;
472
473 if (cardIns == NULL) {
474 AUDIO_FUNC_LOGE("The parameter is empty.");
475 return HDF_FAILURE;
476 }
477
478 cardInfoPri = AudioGetSoundCardsInfo(SND_CARD_PRIMARY);
479 if (cardInfoPri == NULL) {
480 AUDIO_FUNC_LOGE("The parameter is empty.");
481 return HDF_FAILURE;
482 }
483
484 cardId = MatchProfileSoundCard(cardInfoPri, cardIns->cardName);
485 if (cardId == NULL) {
486 AUDIO_FUNC_LOGE("get cardId is null.");
487 return HDF_FAILURE;
488 }
489
490 for (i = 0; i < MAX_CARD_NUM; i++) {
491 /** Built in codec */
492 if (strcmp(cardId, cardIns->alsaDevIns[i].cardId) == 0) {
493 ret = GetSelCardInfo(cardIns, &cardIns->alsaDevIns[i]);
494 if (ret != HDF_SUCCESS) {
495 AUDIO_FUNC_LOGE("GetSelCardInfo error.");
496 }
497 return ret;
498 }
499 }
500
501 return HDF_FAILURE;
502 }
503
GetUsbCardInfo(struct AudioCardInfo * cardIns)504 static int32_t GetUsbCardInfo(struct AudioCardInfo *cardIns)
505 {
506 int32_t i;
507 int32_t ret;
508
509 if (cardIns == NULL) {
510 AUDIO_FUNC_LOGE("The parameter is empty.");
511 return HDF_FAILURE;
512 }
513
514 for (i = 0; i < MAX_CARD_NUM; i++) {
515 /** External codec */
516 if (strcmp(USB_AUDIO, cardIns->alsaDevIns[i].pcmInfoId) == 0) {
517 ret = GetSelCardInfo(cardIns, &cardIns->alsaDevIns[i]);
518 if (ret != HDF_SUCCESS) {
519 AUDIO_FUNC_LOGE("GetSelCardInfo error.");
520 }
521 return ret;
522 }
523 }
524
525 return HDF_FAILURE;
526 }
527
MatchSelAdapter(const char * adapterName,struct AudioCardInfo * cardIns)528 int32_t MatchSelAdapter(const char *adapterName, struct AudioCardInfo *cardIns)
529 {
530 int32_t ret;
531
532 if (adapterName == NULL || cardIns == NULL) {
533 AUDIO_FUNC_LOGE("The parameter is empty.");
534 return HDF_FAILURE;
535 }
536
537 if (strncmp(adapterName, PRIMARY, strlen(PRIMARY)) == 0) {
538 ret = GetPrimaryCardInfo(cardIns);
539 if (ret < 0) {
540 AUDIO_FUNC_LOGE("GetPrimaryCardInfo error.");
541 return HDF_FAILURE;
542 }
543 } else if (strncmp(adapterName, USB, strlen(USB)) == 0) {
544 ret = GetUsbCardInfo(cardIns);
545 if (ret < 0) {
546 AUDIO_FUNC_LOGE("GetUsbCardInfo error.");
547 return HDF_FAILURE;
548 }
549 } else if (strncmp(adapterName, A2DP, strlen(A2DP)) == 0) {
550 AUDIO_FUNC_LOGE("Currently not supported A2DP, please check!");
551 return HDF_ERR_NOT_SUPPORT;
552 } else {
553 AUDIO_FUNC_LOGE("The selected sound card not find, please check!");
554 return HDF_FAILURE;
555 }
556
557 return HDF_SUCCESS;
558 }
559
AudioUsbFindElement(snd_mixer_t * mixer)560 snd_mixer_elem_t *AudioUsbFindElement(snd_mixer_t *mixer)
561 {
562 int i;
563 int count;
564 int32_t maxLoop = MAX_ELEMENT;
565 snd_mixer_elem_t *element = NULL;
566 char *mixerCtlName = NULL;
567
568 if (mixer == NULL) {
569 AUDIO_FUNC_LOGE("The parameter is NULL!");
570 return NULL;
571 }
572
573 count = sizeof(g_usbVolCtlNameTable) / sizeof(char *);
574 for (element = snd_mixer_first_elem(mixer); element != NULL && maxLoop >= 0;
575 element = snd_mixer_elem_next(element)) {
576 for (i = 0; i < count; i++) {
577 mixerCtlName = g_usbVolCtlNameTable[i];
578 /* Compare whether the element name is the option we want to set */
579 if (strcmp(mixerCtlName, snd_mixer_selem_get_name(element)) == 0) {
580 return element;
581 }
582 }
583 maxLoop--;
584 }
585
586 return NULL;
587 }
588
AudioFindElement(const char * mixerCtlName,snd_mixer_elem_t * element)589 static snd_mixer_elem_t *AudioFindElement(const char *mixerCtlName, snd_mixer_elem_t *element)
590 {
591 int32_t maxLoop = MAX_ELEMENT;
592
593 if (mixerCtlName == NULL || element == NULL) {
594 AUDIO_FUNC_LOGE("The parameter is NULL!");
595 return NULL;
596 }
597
598 while (element && maxLoop >= 0) {
599 /* Compare whether the element name is the option we want to set */
600 if (strcmp(mixerCtlName, snd_mixer_selem_get_name(element)) == 0) {
601 break;
602 }
603 /* If not, keep looking for the next one */
604 element = snd_mixer_elem_next(element);
605 maxLoop--;
606 }
607
608 if (element == NULL || maxLoop < 0) {
609 AUDIO_FUNC_LOGE("snd_mixer_find_selem Err\n");
610 return NULL;
611 }
612
613 return element;
614 }
615
GetPriMixerCtlElement(struct AudioCardInfo * cardIns,snd_mixer_elem_t * pcmElement)616 int32_t GetPriMixerCtlElement(struct AudioCardInfo *cardIns, snd_mixer_elem_t *pcmElement)
617 {
618 const char *mixerCtrlLeftVolName = "DACL";
619 const char *mixerCtrlRightVolName = "DACR";
620
621 if (cardIns == NULL || pcmElement == NULL) {
622 AUDIO_FUNC_LOGE("The parameter is empty.");
623 return HDF_FAILURE;
624 }
625
626 cardIns->ctrlLeftVolume = AudioFindElement(mixerCtrlLeftVolName, pcmElement);
627 cardIns->ctrlRightVolume = AudioFindElement(mixerCtrlRightVolName, pcmElement);
628
629 return HDF_SUCCESS;
630 }
631
AudioMixerSetCtrlMode(struct AudioCardInfo * cardIns,const char * adapterName,const char * mixerCtrlName,int numId,int item)632 int32_t AudioMixerSetCtrlMode(
633 struct AudioCardInfo *cardIns, const char *adapterName, const char *mixerCtrlName, int numId, int item)
634 {
635 int32_t ret;
636 snd_ctl_t *alsaHandle = NULL;
637 snd_ctl_elem_value_t *ctlElemValue = NULL;
638
639 if (cardIns == NULL || adapterName == NULL || mixerCtrlName == NULL) {
640 AUDIO_FUNC_LOGE("AudioCtlRenderSetVolume parameter is NULL!");
641 return HDF_FAILURE;
642 }
643
644 if (strncmp(adapterName, PRIMARY, strlen(PRIMARY)) == 0) {
645 ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
646 if (ret < 0) {
647 AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
648 return HDF_FAILURE;
649 }
650
651 ret = snd_ctl_elem_value_malloc(&ctlElemValue);
652 if (ret < 0) {
653 AUDIO_FUNC_LOGE("snd_ctl_elem_value_malloc error: %{public}s", snd_strerror(ret));
654 ret = snd_ctl_close(alsaHandle);
655 if (ret < 0) {
656 AUDIO_FUNC_LOGE("snd_ctl_close error: %{public}s", snd_strerror(ret));
657 }
658 return HDF_FAILURE;
659 }
660
661 snd_ctl_elem_value_set_numid(ctlElemValue, numId);
662 snd_ctl_elem_value_set_interface(ctlElemValue, SND_CTL_ELEM_IFACE_MIXER);
663 snd_ctl_elem_value_set_name(ctlElemValue, mixerCtrlName);
664 snd_ctl_elem_value_set_integer(ctlElemValue, 0, item);
665 ret = snd_ctl_elem_write(alsaHandle, ctlElemValue);
666 if (ret < 0) {
667 AUDIO_FUNC_LOGE("snd_ctl_elem_write error: %{public}s", snd_strerror(ret));
668 snd_ctl_elem_value_free(ctlElemValue);
669 ret = snd_ctl_close(alsaHandle);
670 if (ret < 0) {
671 AUDIO_FUNC_LOGE("snd_ctl_close error: %{public}s", snd_strerror(ret));
672 }
673 return HDF_FAILURE;
674 }
675 snd_ctl_elem_value_free(ctlElemValue);
676 ret = snd_ctl_close(alsaHandle);
677 if (ret < 0) {
678 AUDIO_FUNC_LOGE("snd_ctl_close error: %{public}s", snd_strerror(ret));
679 return HDF_FAILURE;
680 }
681 }
682
683 return HDF_SUCCESS;
684 }
685
AudioGetCardInfo(const char * adapterName,snd_pcm_stream_t stream)686 struct AudioCardInfo *AudioGetCardInfo(const char *adapterName, snd_pcm_stream_t stream)
687 {
688 int32_t ret;
689 struct AudioCardInfo *cardIns = NULL;
690
691 if (adapterName == NULL) {
692 AUDIO_FUNC_LOGE("The parameter is empty.");
693 return NULL;
694 }
695
696 ret = InitCardIns();
697 if (ret != HDF_SUCCESS) {
698 AUDIO_FUNC_LOGE("Failed to initialize sound card information.");
699 return NULL;
700 }
701
702 ret = AudioAddCardIns(adapterName);
703 if (ret < 0) {
704 AUDIO_FUNC_LOGE("AudioAddCardIns failed.");
705 (void)DestroyCardList();
706 return NULL;
707 }
708
709 cardIns = GetCardIns(adapterName);
710 if (cardIns == NULL) {
711 AUDIO_FUNC_LOGE("The cardIns is empty.");
712 (void)DestroyCardList();
713 return NULL;
714 }
715
716 GetDeviceList(cardIns, stream);
717 if (MatchSelAdapter(adapterName, cardIns) < 0) {
718 AUDIO_FUNC_LOGE("MatchSelAdapter is error.");
719 CheckCardStatus(cardIns);
720 (void)DestroyCardList();
721 return NULL;
722 }
723
724 return cardIns;
725 }
726
CheckParaFormat(struct AudioPcmHwParams hwParams,snd_pcm_format_t * alsaPcmFormat)727 int32_t CheckParaFormat(struct AudioPcmHwParams hwParams, snd_pcm_format_t *alsaPcmFormat)
728 {
729 if (alsaPcmFormat == NULL) {
730 AUDIO_FUNC_LOGE("paras is NULL!");
731 return HDF_FAILURE;
732 }
733 enum AudioFormat audioFormat = hwParams.format;
734 bool isBigEndian = hwParams.isBigEndian;
735
736 /** Little Endian */
737 if (!isBigEndian) {
738 switch (audioFormat) {
739 case AUDIO_FORMAT_PCM_8_BIT:
740 *alsaPcmFormat = SND_PCM_FORMAT_S8; /** Signed 8 bit */
741 break;
742 case AUDIO_FORMAT_PCM_16_BIT:
743 *alsaPcmFormat = SND_PCM_FORMAT_S16_LE; /** Signed 16 bit Little Endian */
744 break;
745 case AUDIO_FORMAT_PCM_24_BIT:
746 *alsaPcmFormat = SND_PCM_FORMAT_S24_LE; /** Signed 24 bit Little Endian */
747 break;
748 case AUDIO_FORMAT_PCM_32_BIT:
749 *alsaPcmFormat = SND_PCM_FORMAT_S32_LE; /** Signed 32 bit Little Endian */
750 break;
751 default:
752 return HDF_ERR_NOT_SUPPORT;
753 }
754 } else { /** Big Endian */
755 switch (audioFormat) {
756 case AUDIO_FORMAT_PCM_8_BIT:
757 *alsaPcmFormat = SND_PCM_FORMAT_S8; /** Signed 8 bit */
758 break;
759 case AUDIO_FORMAT_PCM_16_BIT:
760 *alsaPcmFormat = SND_PCM_FORMAT_S16_BE; /** Signed 16 bit Big Endian */
761 break;
762 case AUDIO_FORMAT_PCM_24_BIT:
763 *alsaPcmFormat = SND_PCM_FORMAT_S24_BE; /** Signed 24 bit Big Endian */
764 break;
765 case AUDIO_FORMAT_PCM_32_BIT:
766 *alsaPcmFormat = SND_PCM_FORMAT_S32_BE; /** Signed 32 bit Big Endian */
767 break;
768 default:
769 return HDF_ERR_NOT_SUPPORT;
770 }
771 }
772
773 return HDF_SUCCESS;
774 }
775
AudioAdaptersGetConfig(const char * fpath)776 static char *AudioAdaptersGetConfig(const char *fpath)
777 {
778 int32_t jsonStrSize;
779 FILE *fp = NULL;
780 char *pJsonStr = NULL;
781 char pathBuf[PATH_MAX] = {0};
782
783 if (fpath == NULL) {
784 AUDIO_FUNC_LOGE("Parameter is null!!!");
785 return NULL;
786 }
787 if (realpath(fpath, pathBuf) == NULL) {
788 AUDIO_FUNC_LOGE("File path invalid!");
789 return NULL;
790 }
791
792 fp = fopen(pathBuf, "r");
793 if (fp == NULL) {
794 AUDIO_FUNC_LOGE("Can not open config file [ %{public}s ].", fpath);
795 return NULL;
796 }
797 if (fseek(fp, 0, SEEK_END) != 0) {
798 AUDIO_FUNC_LOGE("fseek configuration file error!");
799 (void)fclose(fp);
800 return NULL;
801 }
802 jsonStrSize = ftell(fp);
803 if (jsonStrSize <= 0) {
804 AUDIO_FUNC_LOGE("The configuration file size <= 0!");
805 (void)fclose(fp);
806 return NULL;
807 }
808 rewind(fp);
809 if (jsonStrSize > ALSA_CONFIG_FILE_MAX) {
810 AUDIO_FUNC_LOGE("The configuration file is too large to load!");
811 (void)fclose(fp);
812 return NULL;
813 }
814 pJsonStr = (char *)OsalMemCalloc((uint32_t)jsonStrSize + 1);
815 if (pJsonStr == NULL) {
816 AUDIO_FUNC_LOGE("OsalMemCalloc pJsonStr failed!");
817 (void)fclose(fp);
818 return NULL;
819 }
820 if (fread(pJsonStr, jsonStrSize, 1, fp) != 1) {
821 AUDIO_FUNC_LOGE("Read to config file failed!!!");
822 (void)fclose(fp);
823 AudioMemFree((void **)&pJsonStr);
824 return NULL;
825 }
826 (void)fclose(fp);
827
828 return pJsonStr;
829 }
830
AudioCardGetConfig(const char * fpath)831 static cJSON *AudioCardGetConfig(const char *fpath)
832 {
833 char *pJsonStr = NULL;
834 cJSON *cJsonObj = NULL;
835
836 if (fpath == NULL) {
837 AUDIO_FUNC_LOGE("Parameter error!");
838 return NULL;
839 }
840
841 pJsonStr = AudioAdaptersGetConfig(fpath);
842 if (pJsonStr == NULL) {
843 AUDIO_FUNC_LOGE("AudioAdaptersGetConfig failed!");
844 return NULL;
845 }
846
847 cJsonObj = cJSON_Parse(pJsonStr);
848 if (cJsonObj == NULL) {
849 AUDIO_FUNC_LOGE("AudioAdaptersGetConfig failed!");
850 AudioMemFree((void **)&pJsonStr);
851 return NULL;
852 }
853 AudioMemFree((void **)&pJsonStr);
854
855 return cJsonObj;
856 }
857
AudioAdapterCheckName(const char * name)858 static int32_t AudioAdapterCheckName(const char *name)
859 {
860 uint32_t len;
861 const char *strName = name;
862
863 if (strName == NULL) {
864 AUDIO_FUNC_LOGE("Invalid parameter!");
865 return HDF_FAILURE;
866 }
867
868 len = strlen(strName);
869 if (len == 0 || len >= CARD_ID_LEN_MAX) {
870 AUDIO_FUNC_LOGE("name len is zero or too long!");
871 return HDF_FAILURE;
872 }
873
874 if (!isalpha(*strName++)) { // Names must begin with a letter
875 AUDIO_FUNC_LOGE("The name of the illegal!");
876 return HDF_FAILURE;
877 }
878
879 while (*strName != '\0') {
880 if (*strName == '_' || *strName == '-') {
881 strName++;
882 continue;
883 }
884
885 if (!isalnum(*strName++)) {
886 AUDIO_FUNC_LOGE("The name of the illegal!");
887 return HDF_FAILURE;
888 }
889 }
890
891 return HDF_SUCCESS;
892 }
893
AudioAdapterNameToType(const char * name)894 static enum SndCardType AudioAdapterNameToType(const char *name)
895 {
896 enum SndCardType cardType = SND_CARD_UNKNOWN;
897
898 if (name == NULL) {
899 AUDIO_FUNC_LOGE("Invalid parameter!");
900 return SND_CARD_UNKNOWN;
901 }
902
903 if (strcmp(name, "primary") == 0) {
904 cardType = SND_CARD_PRIMARY;
905 } else if (strcmp(name, "hdmi") == 0) {
906 cardType = SND_CARD_HDMI;
907 } else if (strcmp(name, "usb") == 0) {
908 cardType = SND_CARD_USB;
909 } else if (strcmp(name, "bt") == 0) {
910 cardType = SND_CARD_BT;
911 }
912
913 return cardType;
914 }
915
AudioAdapterInfoSet(struct DevProcInfo * cardDev,enum SndCardType cardType)916 static int32_t AudioAdapterInfoSet(struct DevProcInfo *cardDev, enum SndCardType cardType)
917 {
918 int32_t ret;
919 struct DevProcInfo *adapter = NULL;
920
921 if (cardDev == NULL) {
922 AUDIO_FUNC_LOGE("Invalid parameter!");
923 return HDF_FAILURE;
924 }
925
926 adapter = (struct DevProcInfo *)OsalMemCalloc(sizeof(struct DevProcInfo));
927 if (adapter == NULL) {
928 AUDIO_FUNC_LOGE("calloc cardDev failed!");
929 return HDF_FAILURE;
930 }
931
932 ret = memcpy_s(adapter->cardName, CARD_ID_LEN_MAX - 1, cardDev->cardName, CARD_ID_LEN_MAX - 1);
933 if (ret != EOK) {
934 AUDIO_FUNC_LOGE("memcpy_s adapter card name fail!");
935 AudioMemFree((void **)&adapter);
936 return HDF_FAILURE;
937 }
938 ret = memcpy_s(adapter->cid, CARD_ID_LEN_MAX - 1, cardDev->cid, CARD_ID_LEN_MAX - 1);
939 if (ret != EOK) {
940 AUDIO_FUNC_LOGE("memcpy_s adapter card id fail!");
941 AudioMemFree((void **)&adapter);
942 return HDF_FAILURE;
943 }
944 ret = memcpy_s(adapter->did, CARD_ID_LEN_MAX - 1, cardDev->did, CARD_ID_LEN_MAX - 1);
945 if (ret != EOK) {
946 AUDIO_FUNC_LOGE("memcpy_s adapter dai id fail!");
947 /* Only log is printed and cannot be returned */
948 }
949
950 for (int cardNum = 0; cardNum < AUDIO_MAX_CARD_NUM; cardNum++) {
951 if (g_sndCardList[cardType][cardNum] == NULL) {
952 g_sndCardList[cardType][cardNum] = adapter;
953 break;
954 }
955
956 if (cardNum == AUDIO_MAX_CARD_NUM - 1) {
957 AUDIO_FUNC_LOGE("The maximum limit for a single type of sound card is %{public}d.", AUDIO_MAX_CARD_NUM);
958 AudioMemFree((void **)&adapter);
959 return HDF_FAILURE;
960 }
961 }
962
963 return HDF_SUCCESS;
964 }
965
AudioGetItemString(cJSON * adapter,char * name)966 static cJSON *AudioGetItemString(cJSON *adapter, char *name)
967 {
968 int32_t ret;
969 cJSON *item = NULL;
970
971 if (adapter == NULL || name == NULL) {
972 AUDIO_FUNC_LOGE("Invalid parameter!");
973 return NULL;
974 }
975
976 item = cJSON_GetObjectItem(adapter, name);
977 if (item == NULL) {
978 AUDIO_FUNC_LOGE("item is null!");
979 return NULL;
980 }
981 if (item->valuestring == NULL) {
982 AUDIO_FUNC_LOGE("item valuestring is null!");
983 return NULL;
984 }
985
986 ret = AudioAdapterCheckName(item->valuestring);
987 if (ret < 0) {
988 if (strncmp(name, "daiId", sizeof("daiId")) != 0) {
989 AUDIO_FUNC_LOGE("The %{public}s name incorrect!", name);
990 }
991 return NULL;
992 }
993
994 return item;
995 }
996
AudioGetAllItem(cJSON * adapter,struct DevProcInfo * cardDev)997 static int32_t AudioGetAllItem(cJSON *adapter, struct DevProcInfo *cardDev)
998 {
999 int32_t ret;
1000 cJSON *adapterName = NULL;
1001 cJSON *cid = NULL;
1002 cJSON *did = NULL;
1003
1004 if (adapter == NULL || cardDev == NULL) {
1005 AUDIO_FUNC_LOGE("Invalid parameter!");
1006 return HDF_FAILURE;
1007 }
1008
1009 adapterName = AudioGetItemString(adapter, "name");
1010 if (adapterName == NULL) {
1011 AUDIO_FUNC_LOGE("Get adapterName failed!");
1012 return HDF_FAILURE;
1013 }
1014 ret = memcpy_s(cardDev->cardName, CARD_ID_LEN_MAX - 1, adapterName->valuestring, CARD_ID_LEN_MAX - 1);
1015 if (ret != EOK) {
1016 AUDIO_FUNC_LOGE("memcpy_s adapter card name fail!");
1017 return HDF_FAILURE;
1018 }
1019
1020 cid = AudioGetItemString(adapter, "cardId");
1021 if (cid == NULL) {
1022 AUDIO_FUNC_LOGE("Get cid failed!");
1023 return HDF_FAILURE;
1024 }
1025 ret = memcpy_s(cardDev->cid, CARD_ID_LEN_MAX - 1, cid->valuestring, CARD_ID_LEN_MAX - 1);
1026 if (ret != EOK) {
1027 AUDIO_FUNC_LOGE("memcpy_s adapter card id fail!");
1028 return HDF_FAILURE;
1029 }
1030
1031 did = AudioGetItemString(adapter, "daiId");
1032 if (did == NULL) { // Not all sound cards have dai id.
1033 return HDF_SUCCESS;
1034 }
1035 ret = memcpy_s(cardDev->did, CARD_ID_LEN_MAX - 1, did->valuestring, CARD_ID_LEN_MAX - 1);
1036 if (ret != EOK) {
1037 AUDIO_FUNC_LOGE("memcpy_s adapter card id fail!");
1038 /* Only log is printed and cannot be returned */
1039 }
1040
1041 return HDF_SUCCESS;
1042 }
1043
AudioParseAdapter(cJSON * adapter)1044 static int32_t AudioParseAdapter(cJSON *adapter)
1045 {
1046 int ret;
1047 struct DevProcInfo cardDev;
1048 enum SndCardType cardType = SND_CARD_UNKNOWN;
1049
1050 if (adapter == NULL) {
1051 AUDIO_FUNC_LOGE("Parameter error!\n");
1052 return HDF_FAILURE;
1053 }
1054
1055 (void)memset_s(&cardDev, sizeof(struct DevProcInfo), 0, sizeof(struct DevProcInfo));
1056 ret = AudioGetAllItem(adapter, &cardDev);
1057 if (ret < 0) {
1058 AUDIO_FUNC_LOGE("AudioGetAllItem failed!\n");
1059 return ret;
1060 }
1061 cardType = AudioAdapterNameToType(cardDev.cardName);
1062 switch (cardType) {
1063 case SND_CARD_PRIMARY:
1064 case SND_CARD_HDMI:
1065 case SND_CARD_USB:
1066 case SND_CARD_BT:
1067 ret = AudioAdapterInfoSet(&cardDev, cardType);
1068 if (ret < 0) {
1069 AUDIO_FUNC_LOGE("AudioAdapterInfoSet failed!\n");
1070 return ret;
1071 }
1072 break;
1073 default:
1074 AUDIO_FUNC_LOGE("Sound card unknown!\n");
1075 return HDF_FAILURE;
1076 }
1077
1078 return HDF_SUCCESS;
1079 }
1080
AudioAdaptersSetAdapterVar(cJSON * cJsonObj)1081 static int32_t AudioAdaptersSetAdapterVar(cJSON *cJsonObj)
1082 {
1083 int32_t ret, adaptersArraySize;
1084 cJSON *adapterObj = NULL;
1085
1086 if (cJsonObj == NULL) {
1087 AUDIO_FUNC_LOGE("Parameter error!");
1088 return HDF_FAILURE;
1089 }
1090
1091 adaptersArraySize = cJSON_GetArraySize(cJsonObj);
1092 if (adaptersArraySize <= 0) {
1093 AUDIO_FUNC_LOGE("Failed to get JSON array size!");
1094 return HDF_FAILURE;
1095 }
1096 if (adaptersArraySize > MAX_CARD_NUM) {
1097 AUDIO_FUNC_LOGE("Read adapters number is %{public}d!", adaptersArraySize);
1098 AUDIO_FUNC_LOGE("The number of sound cards exceeds the upper limit %{public}d.", MAX_CARD_NUM);
1099 return HDF_FAILURE;
1100 }
1101
1102 for (int32_t i = 0; i < adaptersArraySize; i++) {
1103 adapterObj = cJSON_GetArrayItem(cJsonObj, i);
1104 if (adapterObj != NULL) {
1105 ret = AudioParseAdapter(adapterObj);
1106 if (ret < 0) {
1107 AUDIO_FUNC_LOGE("AudioParseAdapter (%{public}d) error!", i);
1108 return HDF_FAILURE;
1109 }
1110 adapterObj = NULL;
1111 }
1112 }
1113
1114 return HDF_SUCCESS;
1115 }
1116
CardInfoParseFromConfig(void)1117 int32_t CardInfoParseFromConfig(void)
1118 {
1119 int32_t ret;
1120 cJSON *cJsonObj = NULL;
1121 cJSON *adaptersObj = NULL;
1122
1123 if (g_parseFlag) {
1124 return HDF_SUCCESS;
1125 }
1126
1127 cJsonObj = AudioCardGetConfig(ALSA_CARD_CONFIG_FILE);
1128 if (cJsonObj == NULL) {
1129 AUDIO_FUNC_LOGE("AudioCardGetConfig failed!\n");
1130 return HDF_FAILURE;
1131 }
1132
1133 adaptersObj = cJSON_GetObjectItem(cJsonObj, "adapters");
1134 if (adaptersObj == NULL) {
1135 AUDIO_FUNC_LOGE("cJSON_GetObjectItem adapters failed!\n");
1136 cJSON_Delete(cJsonObj);
1137 return HDF_FAILURE;
1138 }
1139
1140 ret = AudioAdaptersSetAdapterVar(adaptersObj);
1141 if (ret < 0) {
1142 AUDIO_FUNC_LOGE("AudioAdaptersSetAdapterVar is failed!\n");
1143 cJSON_Delete(cJsonObj);
1144 return HDF_FAILURE;
1145 }
1146 cJSON_Delete(cJsonObj);
1147 g_parseFlag = true;
1148
1149 return HDF_SUCCESS;
1150 }
1151