• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "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