• 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_soundcard.h"
17 #include <ctype.h>
18 #include "cJSON.h"
19 
20 #define HDF_LOG_TAG HDF_AUDIO_HAL_SND
21 
22 #define ALSA_CARD_CONFIG_FILE HDF_CONFIG_DIR "/alsa_adapter.json"
23 #define ALSA_CONFIG_FILE_MAX  (2 * 1024) // 2KB
24 #define SUPPORT_CAPTURE_OR_RENDER  1
25 #define SUPPORT_CAPTURE_AND_RENDER 2
26 #define MALLOC_MAX 100
27 
28 /* Define structure description alsa_adapter.hson information  */
29 struct AlsaAdapterCfgInfo {
30     char adapterName[MAX_CARD_NAME_LEN];
31     int32_t cardId;
32     char cardName[MAX_CARD_NAME_LEN];
33 };
34 struct AlsaAdapterList {
35     int32_t num;
36     struct AlsaAdapterCfgInfo list[AUDIO_MAX_CARD_NUM];
37 };
38 static struct AlsaAdapterList g_alsaAdapterList[SND_CARD_MAX];
39 
40 struct AlsaDevInfo {
41     char cardId[MAX_CARD_NAME_LEN + 1];
42     char pcmInfoId[MAX_CARD_NAME_LEN + 1];
43     int32_t card;
44     int32_t device;
45 };
46 struct AlsaCardsList {
47     int32_t num;
48     struct AlsaDevInfo alsaDevIns[MAX_CARD_NUM];
49 };
50 static struct AlsaCardsList g_alsaCardsDevList;
51 
52 
CfgReadAdapterFile(const char * fpath)53 static char *CfgReadAdapterFile(const char *fpath)
54 {
55     FILE *fp = NULL;
56     char *pJsonStr = NULL;
57     char pathBuf[PATH_MAX] = {0};
58 
59     if (fpath == NULL) {
60         AUDIO_FUNC_LOGE("Parameter is null!!!");
61         return NULL;
62     }
63     if (realpath(fpath, pathBuf) == NULL) {
64         AUDIO_FUNC_LOGE("File path invalid!");
65         return NULL;
66     }
67 
68     fp = fopen(pathBuf, "r");
69     if (fp == NULL) {
70         AUDIO_FUNC_LOGE("Can not open config file [ %{public}s ].", fpath);
71         return NULL;
72     }
73     if (fseek(fp, 0, SEEK_END) != 0) {
74         AUDIO_FUNC_LOGE("fseek configuration file error!");
75         (void)fclose(fp);
76         return NULL;
77     }
78     int32_t jsonStrSize = ftell(fp);
79     if (jsonStrSize <= 0) {
80         AUDIO_FUNC_LOGE("The configuration file size <= 0!");
81         (void)fclose(fp);
82         return NULL;
83     }
84     rewind(fp);
85     if (jsonStrSize > ALSA_CONFIG_FILE_MAX) {
86         AUDIO_FUNC_LOGE("The configuration file is too large to load!");
87         (void)fclose(fp);
88         return NULL;
89     }
90     pJsonStr = (char *)OsalMemCalloc((uint32_t)jsonStrSize + 1);
91     if (pJsonStr == NULL) {
92         AUDIO_FUNC_LOGE("OsalMemCalloc pJsonStr failed!");
93         (void)fclose(fp);
94         return NULL;
95     }
96     if (fread(pJsonStr, jsonStrSize, 1, fp) != 1) {
97         AUDIO_FUNC_LOGE("Read to config file failed!!!");
98         (void)fclose(fp);
99         AudioMemFree((void **)&pJsonStr);
100         return NULL;
101     }
102     (void)fclose(fp);
103 
104     return pJsonStr;
105 }
106 
CfgGetAdapterCount()107 static int32_t CfgGetAdapterCount()
108 {
109     int32_t num = 0;
110     for (enum SndCardType type = SND_CARD_PRIMARY; type < SND_CARD_MAX; ++type) {
111         num += g_alsaAdapterList[type].num;
112     }
113     return num;
114 }
115 
CfgGetAdapterCardType(const char * adapterName)116 static enum SndCardType CfgGetAdapterCardType(const char* adapterName)
117 {
118     if (adapterName == NULL) {
119         return SND_CARD_UNKNOWN;
120     }
121 
122     struct AlsaAdapterCfgInfo *info;
123     for (enum SndCardType type = SND_CARD_PRIMARY; type < SND_CARD_MAX; ++type) {
124         for (int32_t i = 0; i < g_alsaAdapterList[type].num; ++i) {
125             info = &g_alsaAdapterList[type].list[i];
126             if (strncmp(adapterName, info->adapterName, strlen(info->adapterName)) == 0) {
127                 return type;
128             }
129         }
130     }
131     return SND_CARD_UNKNOWN;
132 }
133 
CfgGetAdapterInfo(const char * adapterName,struct AlsaAdapterCfgInfo infos[],int infoLen)134 static int CfgGetAdapterInfo(const char* adapterName, struct AlsaAdapterCfgInfo infos[], int infoLen)
135 {
136     if (adapterName == NULL) {
137         return 0;
138     }
139 
140     struct AlsaAdapterCfgInfo *info;
141     int index = 0;
142     for (enum SndCardType type = SND_CARD_PRIMARY; type < SND_CARD_MAX; ++type) {
143         for (int32_t i = 0; i < g_alsaAdapterList[type].num; ++i) {
144             info = &g_alsaAdapterList[type].list[i];
145             if (strncmp(adapterName, info->adapterName, strlen(info->adapterName)) == 0
146                 && index < infoLen) {
147                 infos[index++] = *info;
148             }
149         }
150     }
151     return index;
152 }
153 
CfgDumpAdapterInfo(struct AlsaAdapterCfgInfo * info)154 static int32_t CfgDumpAdapterInfo(struct AlsaAdapterCfgInfo *info)
155 {
156     enum SndCardType cardType = SND_CARD_UNKNOWN;
157     CHECK_NULL_PTR_RETURN_DEFAULT(info);
158 
159     if (strcmp(info->adapterName, PRIMARY) == 0) {
160         cardType = SND_CARD_PRIMARY;
161     } else if (strcmp(info->adapterName, HDMI) == 0) {
162         cardType = SND_CARD_HDMI;
163     } else if (strcmp(info->adapterName, USB) == 0) {
164         cardType = SND_CARD_USB;
165     } else if (strcmp(info->adapterName, A2DP) == 0) {
166         cardType = SND_CARD_BT;
167     }
168 
169     if (cardType == SND_CARD_UNKNOWN) {
170         AUDIO_FUNC_LOGE("Error: %{public}s is unspupported adapter name", info->adapterName);
171     }
172 
173     int32_t idx = g_alsaAdapterList[cardType].num;
174     int32_t ret = memcpy_s((void*)&g_alsaAdapterList[cardType].list[idx], sizeof(struct AlsaAdapterCfgInfo),
175         (void*)info, sizeof(struct AlsaAdapterCfgInfo));
176     if (ret != EOK) {
177         AUDIO_FUNC_LOGE("memcpy_s g_alsaAdapterList fail!");
178         return HDF_FAILURE;
179     }
180     g_alsaAdapterList[cardType].num++;
181 
182     AUDIO_FUNC_LOGI("cardId:%{public}d: adapterName:%{public}s, cardName:%{public}s",
183         g_alsaAdapterList[cardType].list[idx].cardId,
184         g_alsaAdapterList[cardType].list[idx].adapterName,
185         g_alsaAdapterList[cardType].list[idx].cardName);
186     return HDF_SUCCESS;
187 }
188 
CfgSaveAdapterStruct(cJSON * adapter,struct AlsaAdapterCfgInfo * info)189 static int32_t CfgSaveAdapterStruct(cJSON *adapter, struct AlsaAdapterCfgInfo *info)
190 {
191     CHECK_NULL_PTR_RETURN_DEFAULT(adapter);
192     CHECK_NULL_PTR_RETURN_DEFAULT(info);
193 
194     cJSON *item = cJSON_GetObjectItem(adapter, "name");
195     if (item == NULL || item->valuestring == NULL) {
196         AUDIO_FUNC_LOGE("adapter name is null!");
197         return HDF_FAILURE;
198     }
199     int32_t ret = memcpy_s(info->adapterName, MAX_CARD_NAME_LEN - 1, item->valuestring, MAX_CARD_NAME_LEN - 1);
200     if (ret != EOK) {
201         AUDIO_FUNC_LOGE("memcpy_s adapterName fail!");
202         return HDF_FAILURE;
203     }
204 
205     item = cJSON_GetObjectItem(adapter, "cardId");
206     if (item == NULL) {
207         AUDIO_FUNC_LOGE("cardId not set!");
208         return HDF_FAILURE;
209     }
210     info->cardId = item->valuedouble;
211 
212     item = cJSON_GetObjectItem(adapter, "cardName");
213     if (item == NULL || item->valuestring == NULL) {
214         AUDIO_FUNC_LOGE("cardName is null!");
215         return HDF_FAILURE;
216     }
217     ret = memcpy_s(info->cardName, MAX_CARD_NAME_LEN - 1, item->valuestring, MAX_CARD_NAME_LEN - 1);
218     if (ret != EOK) {
219         AUDIO_FUNC_LOGE("memcpy_s cardName fail!");
220         return HDF_FAILURE;
221     }
222 
223     return HDF_SUCCESS;
224 }
225 
CfgParseAdapterItems(cJSON * adapterObj)226 static int32_t CfgParseAdapterItems(cJSON *adapterObj)
227 {
228     cJSON *adapterItems = NULL;
229 
230     adapterItems = cJSON_GetObjectItem(adapterObj, "adapters");
231     if (adapterItems == NULL) {
232         AUDIO_FUNC_LOGE("Get adapterItems from json failed!\n");
233         return HDF_FAILURE;
234     }
235     int32_t adapterNum = cJSON_GetArraySize(adapterItems);
236     if (adapterNum <= 0) {
237         AUDIO_FUNC_LOGE("Get adapter number failed!");
238         return HDF_FAILURE;
239     } else if (adapterNum > MAX_CARD_NUM) {
240         AUDIO_FUNC_LOGE("Read adapters number is %{public}d over max num %{public}d!", adapterNum, MAX_CARD_NUM);
241         return HDF_FAILURE;
242     }
243 
244     for (int32_t i = 0; i < adapterNum; ++i) {
245         cJSON *adapter;
246         struct AlsaAdapterCfgInfo info;
247         adapter = cJSON_GetArrayItem(adapterItems, i);
248         if (adapter == NULL) {
249             AUDIO_FUNC_LOGE("Get adapter item from array failed!");
250         }
251 
252         int32_t ret = CfgSaveAdapterStruct(adapter, &info);
253         if (ret != HDF_SUCCESS) {
254             AUDIO_FUNC_LOGE("CfgSaveAdapterStruct failed!");
255             return HDF_FAILURE;
256         }
257 
258         ret = CfgDumpAdapterInfo(&info);
259         if (ret != HDF_SUCCESS) {
260             AUDIO_FUNC_LOGE("CfgDumpAdapterInfo failed!");
261             return HDF_FAILURE;
262         }
263     }
264 
265     return HDF_SUCCESS;
266 }
267 
CfgSaveAdapterFromFile(void)268 int32_t CfgSaveAdapterFromFile(void)
269 {
270     cJSON *adapterObj = NULL;
271     char *configBuf = NULL;
272 
273     configBuf = CfgReadAdapterFile(ALSA_CARD_CONFIG_FILE);
274     if (configBuf == NULL) {
275         AUDIO_FUNC_LOGE("CfgReadAdapterFile failed!");
276         return HDF_FAILURE;
277     }
278     adapterObj = cJSON_Parse(configBuf);
279     if (adapterObj == NULL) {
280         AUDIO_FUNC_LOGE("Parse json file failed!");
281         AudioMemFree((void **)&configBuf);
282         return HDF_FAILURE;
283     }
284     AudioMemFree((void **)&configBuf);
285 
286     int32_t ret = CfgParseAdapterItems(adapterObj);
287     if (ret != HDF_SUCCESS) {
288         cJSON_Delete(adapterObj);
289         AUDIO_FUNC_LOGE("Parse adapter items failed!");
290         return HDF_FAILURE;
291     }
292 
293     cJSON_Delete(adapterObj);
294     return HDF_SUCCESS;
295 }
296 
DevGetInfoByAdapter(struct AlsaAdapterCfgInfo infos[],int32_t size)297 static struct AlsaDevInfo *DevGetInfoByAdapter(struct AlsaAdapterCfgInfo infos[], int32_t size)
298 {
299     struct AlsaDevInfo *info = NULL;
300     int num = g_alsaCardsDevList.num;
301     for (int i = 0; i < num; ++i) {
302         info = &g_alsaCardsDevList.alsaDevIns[i];
303         for (int j = 0; j < size; ++j) {
304             if (info->card == infos[j].cardId) {
305                 return info;
306             }
307         }
308     }
309     return NULL;
310 }
311 
DevGetInfoByPcmInfoId(const char * name)312 static struct AlsaDevInfo *DevGetInfoByPcmInfoId(const char * name)
313 {
314     struct AlsaDevInfo *info = NULL;
315     int num = g_alsaCardsDevList.num;
316     for (int i = 0; i < num; ++i) {
317         info = &g_alsaCardsDevList.alsaDevIns[i];
318         if (strcmp(name, info->pcmInfoId) == 0) {
319             return info;
320         }
321     }
322 
323     return NULL;
324 }
325 
DevSaveCardPcmInfo(snd_ctl_t * handle,snd_pcm_stream_t stream,int card,const char * deviceName)326 static int32_t DevSaveCardPcmInfo(snd_ctl_t *handle, snd_pcm_stream_t stream, int card, const char *deviceName)
327 {
328     int pcmDev = -1;
329     snd_ctl_card_info_t *info = NULL;
330     snd_pcm_info_t *pcminfo = NULL;
331     snd_ctl_card_info_alloca(&info);
332     snd_pcm_info_alloca(&pcminfo);
333 
334     if (snd_ctl_card_info(handle, info) != 0) {
335         AUDIO_FUNC_LOGE("snd_ctl_card_info failed.");
336         return HDF_FAILURE;
337     }
338     if (snd_ctl_pcm_next_device(handle, &pcmDev) < 0 || pcmDev < 0) {
339         AUDIO_FUNC_LOGE("No pcm device found");
340         return HDF_FAILURE;
341     }
342     while (pcmDev >= 0) {
343         snd_pcm_info_set_device(pcminfo, pcmDev);
344         snd_pcm_info_set_subdevice(pcminfo, 0);
345         snd_pcm_info_set_stream(pcminfo, stream);
346         int32_t ret = snd_ctl_pcm_info(handle, pcminfo);
347         if (ret < 0) {
348             if (ret != -ENOENT) {
349                 AUDIO_FUNC_LOGE("control digital audio info (%{public}d)", pcmDev);
350             }
351         } else {
352             struct AlsaDevInfo *devInfo = &g_alsaCardsDevList.alsaDevIns[g_alsaCardsDevList.num];
353             const char *cardId = snd_ctl_card_info_get_id(info);
354             const char *pcmInfoId = snd_pcm_info_get_id(pcminfo);
355             AUDIO_FUNC_LOGD("alsa cardName: %{public}s, pcmInfoId %{public}s", cardId, pcmInfoId);
356             devInfo->card = card;
357             devInfo->device = pcmDev;
358             if (strncpy_s(devInfo->cardId, MAX_CARD_NAME_LEN + 1, cardId, strlen(cardId)) != 0) {
359                 AUDIO_FUNC_LOGE("strncpy_s failed!");
360                 return HDF_FAILURE;
361             }
362             if (strncpy_s(devInfo->pcmInfoId, MAX_CARD_NAME_LEN + 1, pcmInfoId, strlen(pcmInfoId)) != 0) {
363                 AUDIO_FUNC_LOGE("strncpy_s failed!");
364                 return HDF_FAILURE;
365             }
366             g_alsaCardsDevList.num++;
367         }
368 
369         if (snd_ctl_pcm_next_device(handle, &pcmDev) < 0) {
370             AUDIO_FUNC_LOGE("snd_ctl_pcm_next_device error!");
371             return HDF_FAILURE;
372         }
373         AUDIO_FUNC_LOGD("soundcard pcm device number: %{public}d.", pcmDev);
374     }
375     return HDF_SUCCESS;
376 }
377 
DevSaveDriverInfo(snd_pcm_stream_t stream)378 static int32_t DevSaveDriverInfo(snd_pcm_stream_t stream)
379 {
380     snd_ctl_t *handle = NULL;
381     int card = -1;
382     char deviceName[MAX_CARD_NAME_LEN] = {0};
383 
384     int32_t ret = snd_card_next(&card);
385     if (ret < 0 || card < 0) {
386         AUDIO_FUNC_LOGE("No soundcards found: %{public}s.", snd_strerror(ret));
387         return HDF_FAILURE;
388     }
389 
390     while (card >= 0) {
391         (void)memset_s(deviceName, MAX_CARD_NAME_LEN, 0, MAX_CARD_NAME_LEN);
392         ret = snprintf_s(deviceName, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1, "hw:%d", card);
393         if (ret < 0) {
394             AUDIO_FUNC_LOGE("snprintf_s failed");
395             snd_ctl_close(handle);
396             return HDF_FAILURE;
397         }
398 
399         ret = snd_ctl_open(&handle, deviceName, 0);
400         if (ret != 0) {
401             AUDIO_FUNC_LOGE("snd_ctl_open failed.");
402             return HDF_FAILURE;
403         }
404 
405         ret = DevSaveCardPcmInfo(handle, stream, card, deviceName);
406         if (ret != HDF_SUCCESS) {
407             AUDIO_FUNC_LOGE("save alsa sound cards %{public}s pcm info failed!", deviceName);
408         }
409 
410         ret = snd_ctl_close(handle);
411         if (ret < 0) {
412             AUDIO_FUNC_LOGE("snd_ctl_close error: %{public}s.", snd_strerror(ret));
413             return HDF_FAILURE;
414         }
415 
416         ret = snd_card_next(&card);
417         if (ret < 0) {
418             AUDIO_FUNC_LOGE("snd_card_next error: %{public}s", snd_strerror(ret));
419             return HDF_FAILURE;
420         }
421     }
422 
423     return HDF_SUCCESS;
424 }
425 
SndSaveCardListInfo(snd_pcm_stream_t stream)426 int32_t SndSaveCardListInfo(snd_pcm_stream_t stream)
427 {
428     (void)memset_s(&g_alsaAdapterList, sizeof(struct AlsaAdapterList) * SND_CARD_MAX,
429         0, sizeof(struct AlsaAdapterList) * SND_CARD_MAX);
430     (void)memset_s(&g_alsaCardsDevList, sizeof(struct AlsaCardsList),
431         0, sizeof(struct AlsaCardsList));
432 
433     /* Parse sound card from configuration file */
434     int32_t ret = CfgSaveAdapterFromFile();
435     if (ret != HDF_SUCCESS) {
436         AUDIO_FUNC_LOGE("parse config file failed! ret = %{public}d", ret);
437         return HDF_FAILURE;
438     }
439 
440     /* Read sound card list from alsa hardware */
441     ret = DevSaveDriverInfo(stream);
442     if (ret != HDF_SUCCESS) {
443         AUDIO_FUNC_LOGE("failed to save alsa sound cards driver info");
444         return HDF_FAILURE;
445     }
446 
447     /* if the alsa hardware include usb then add to adapter list */
448     struct AlsaDevInfo *devInfo = DevGetInfoByPcmInfoId(USB);
449     if (devInfo != NULL) {
450         g_alsaAdapterList[SND_CARD_USB].num = 1;
451         ret = memcpy_s((void*)&g_alsaAdapterList[SND_CARD_USB].list[0].adapterName, MAX_CARD_NAME_LEN,
452         USB, sizeof(USB));
453         if (ret != EOK) {
454             AUDIO_FUNC_LOGE("memcpy_s adapterName fail!");
455             return HDF_FAILURE;
456         }
457     }
458 
459     return HDF_SUCCESS;
460 }
461 
SndMatchSelAdapter(struct AlsaSoundCard * cardIns,const char * adapterName)462 int32_t SndMatchSelAdapter(struct AlsaSoundCard *cardIns, const char *adapterName)
463 {
464     struct AlsaDevInfo *devInfo = NULL;
465     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
466     CHECK_NULL_PTR_RETURN_DEFAULT(adapterName);
467 
468     enum SndCardType  cardType = CfgGetAdapterCardType(adapterName);
469     if (cardType == SND_CARD_UNKNOWN) {
470         AUDIO_FUNC_LOGE("unknow card type error.");
471         return HDF_FAILURE;
472     }
473     cardIns->cardType = cardType;
474 
475     struct AlsaAdapterCfgInfo adapterInfos[g_alsaAdapterList[cardType].num];
476     int32_t num = CfgGetAdapterInfo(adapterName, adapterInfos, g_alsaAdapterList[cardType].num);
477     if (num == 0) {
478         AUDIO_FUNC_LOGE("adapter %{public}s is not exits.", cardIns->adapterName);
479         return HDF_FAILURE;
480     }
481 
482     devInfo = DevGetInfoByAdapter(adapterInfos, num);
483     if (devInfo == NULL) {
484         AUDIO_FUNC_LOGE("adapter %{public}s cant not find sound card device.", cardIns->adapterName);
485         return HDF_FAILURE;
486     }
487 
488     int32_t ret = snprintf_s(cardIns->devName, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1,
489         "hw:%d,%d", devInfo->card, devInfo->device);
490     if (ret < 0) {
491         AUDIO_FUNC_LOGE("%{public}s snprintf_s devName failed", cardIns->adapterName);
492         return HDF_FAILURE;
493     }
494     ret = snprintf_s(cardIns->ctrlName, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1, "hw:%d", devInfo->card);
495     if (ret < 0) {
496         AUDIO_FUNC_LOGE("%{public}s snprintf_s ctrlName failed", cardIns->adapterName);
497         return HDF_FAILURE;
498     }
499     ret = snprintf_s(cardIns->alsaCardId, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1, "%s", devInfo->cardId);
500     if (ret < 0) {
501         AUDIO_FUNC_LOGE("%{public}s snprintf_s alsaCardId failed", cardIns->adapterName);
502         return HDF_FAILURE;
503     }
504 
505     return HDF_SUCCESS;
506 }
507 
SndConverAlsaPcmFormat(const struct AudioPcmHwParams * hwParams,snd_pcm_format_t * alsaPcmFormat)508 int32_t SndConverAlsaPcmFormat(const struct AudioPcmHwParams *hwParams, snd_pcm_format_t *alsaPcmFormat)
509 {
510     CHECK_NULL_PTR_RETURN_DEFAULT(hwParams);
511     CHECK_NULL_PTR_RETURN_DEFAULT(alsaPcmFormat);
512     enum AudioFormat audioFormat = hwParams->format;
513     bool isBigEndian = hwParams->isBigEndian;
514 
515     /** Little Endian */
516     if (!isBigEndian) {
517         switch (audioFormat) {
518             case AUDIO_FORMAT_TYPE_PCM_8_BIT:
519                 *alsaPcmFormat = SND_PCM_FORMAT_S8; /** Signed 8 bit */
520                 break;
521             case AUDIO_FORMAT_TYPE_PCM_16_BIT:
522                 *alsaPcmFormat = SND_PCM_FORMAT_S16_LE; /** Signed 16 bit Little Endian */
523                 break;
524             case AUDIO_FORMAT_TYPE_PCM_24_BIT:
525                 *alsaPcmFormat = SND_PCM_FORMAT_S24_LE; /** Signed 24 bit Little Endian */
526                 break;
527             case AUDIO_FORMAT_TYPE_PCM_32_BIT:
528                 *alsaPcmFormat = SND_PCM_FORMAT_S32_LE; /** Signed 32 bit Little Endian */
529                 break;
530             default:
531                 AUDIO_FUNC_LOGE("not support format %{public}d", audioFormat);
532                 return HDF_ERR_NOT_SUPPORT;
533         }
534     } else { /** Big Endian */
535         switch (audioFormat) {
536             case AUDIO_FORMAT_TYPE_PCM_8_BIT:
537                 *alsaPcmFormat = SND_PCM_FORMAT_S8; /** Signed 8 bit */
538                 break;
539             case AUDIO_FORMAT_TYPE_PCM_16_BIT:
540                 *alsaPcmFormat = SND_PCM_FORMAT_S16_BE; /** Signed 16 bit Big Endian */
541                 break;
542             case AUDIO_FORMAT_TYPE_PCM_24_BIT:
543                 *alsaPcmFormat = SND_PCM_FORMAT_S24_BE; /** Signed 24 bit Big Endian */
544                 break;
545             case AUDIO_FORMAT_TYPE_PCM_32_BIT:
546                 *alsaPcmFormat = SND_PCM_FORMAT_S32_BE; /** Signed 32 bit Big Endian */
547                 break;
548             default:
549                 AUDIO_FUNC_LOGE("not support format %{public}d", audioFormat);
550                 return HDF_ERR_NOT_SUPPORT;
551         }
552     }
553 
554     return HDF_SUCCESS;
555 }
556 
SndPcmPrepare(struct AlsaSoundCard * cardIns)557 int32_t SndPcmPrepare(struct AlsaSoundCard *cardIns)
558 {
559     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
560     int32_t ret = snd_pcm_prepare(cardIns->pcmHandle);
561     if (ret < 0) {
562         AUDIO_FUNC_LOGE("snd_pcm_prepare fail: %{public}s", snd_strerror(ret));
563         return HDF_FAILURE;
564     }
565     return HDF_SUCCESS;
566 }
567 
SndisBusy(struct AlsaSoundCard * cardIns)568 bool SndisBusy(struct AlsaSoundCard *cardIns)
569 {
570     if (cardIns == NULL) {
571         return false;
572     }
573     return (cardIns->pcmHandle == NULL) ? false : true;
574 }
575 
SndOpenMixer(struct AlsaSoundCard * cardIns)576 int32_t SndOpenMixer(struct AlsaSoundCard *cardIns)
577 {
578     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
579 
580     if (strlen(cardIns->ctrlName) == 0) {
581         AUDIO_FUNC_LOGE("The soundcard ctrname is null.");
582         return HDF_FAILURE;
583     }
584 
585     int32_t ret = snd_mixer_open(&cardIns->mixerHandle, 0);
586     if (ret < 0) {
587         AUDIO_FUNC_LOGE("Failed to open mixer: %{public}s.", snd_strerror(ret));
588         return HDF_FAILURE;
589     }
590 
591     ret = snd_mixer_attach(cardIns->mixerHandle, cardIns->ctrlName);
592     if (ret < 0) {
593         AUDIO_FUNC_LOGE("Failed to attach mixer: %{public}s.", snd_strerror(ret));
594         ret = snd_mixer_close(cardIns->mixerHandle);
595         if (ret < 0) {
596             AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret));
597         }
598         cardIns->mixerHandle = NULL;
599         return HDF_FAILURE;
600     }
601 
602     ret = snd_mixer_selem_register(cardIns->mixerHandle, NULL, NULL);
603     if (ret < 0) {
604         AUDIO_FUNC_LOGE("Failed to register mixer element: %{public}s.", snd_strerror(ret));
605         ret = snd_mixer_close(cardIns->mixerHandle);
606         if (ret < 0) {
607             AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret));
608         }
609         cardIns->mixerHandle = NULL;
610         return HDF_FAILURE;
611     }
612 
613     ret = snd_mixer_load(cardIns->mixerHandle);
614     if (ret < 0) {
615         AUDIO_FUNC_LOGE("Failed to load mixer element: %{public}s.", snd_strerror(ret));
616         ret = snd_mixer_close(cardIns->mixerHandle);
617         if (ret < 0) {
618             AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret));
619         }
620         cardIns->mixerHandle = NULL;
621         return HDF_FAILURE;
622     }
623     return HDF_SUCCESS;
624 }
625 
SndGetRunState(struct AlsaSoundCard * cardIns)626 snd_pcm_state_t SndGetRunState(struct AlsaSoundCard * cardIns)
627 {
628     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
629     return snd_pcm_state(cardIns->pcmHandle);
630 }
631 
SndCloseHandle(struct AlsaSoundCard * cardIns)632 void SndCloseHandle(struct AlsaSoundCard *cardIns)
633 {
634     if (cardIns == NULL) {
635         AUDIO_FUNC_LOGE("cardIns is NULL");
636         return;
637     }
638     if (cardIns->cardStatus > 0) {
639         cardIns->cardStatus -= 1;
640     }
641     if (cardIns->cardStatus == 0) {
642         int32_t ret;
643         if (cardIns->pcmHandle != NULL) {
644             ret = snd_pcm_close(cardIns->pcmHandle);
645             if (ret < 0) {
646                 AUDIO_FUNC_LOGE("snd_pcm_close fail: %{public}s", snd_strerror(ret));
647             }
648             cardIns->pcmHandle = NULL;
649         }
650         if (cardIns->mixerHandle != NULL) {
651             ret = snd_mixer_close(cardIns->mixerHandle);
652             if (ret < 0) {
653                 AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret));
654             }
655             cardIns->mixerHandle = NULL;
656         }
657         (void)memset_s(cardIns, sizeof(struct AlsaSoundCard), 0, sizeof(struct AlsaSoundCard));
658     }
659 }
660 
AudioInitPortOut(struct AudioPort * audioPort)661 static void AudioInitPortOut(struct AudioPort *audioPort)
662 {
663     audioPort->dir = PORT_OUT;
664     audioPort->portId = 0;
665     audioPort->portName = strdup("AOP");
666 }
667 
AudioInitPortIn(struct AudioPort * audioPort)668 static void AudioInitPortIn(struct AudioPort *audioPort)
669 {
670     audioPort->dir = PORT_IN;
671     audioPort->portId = 0;
672     audioPort->portName = strdup("AIP");
673 }
674 
AudioInitPortOutAndIn(struct AudioPort * audioPort)675 static void AudioInitPortOutAndIn(struct AudioPort *audioPort)
676 {
677     audioPort->dir = PORT_OUT_IN;
678     audioPort->portId = 0;
679     audioPort->portName = strdup("AIOP");
680 }
681 
AudioInitPorts(struct AudioAdapterDescriptor * desc,enum SndCardType type)682 static int32_t AudioInitPorts(struct AudioAdapterDescriptor *desc, enum SndCardType type)
683 {
684     uint8_t portNum = 0;
685     CHECK_NULL_PTR_RETURN_DEFAULT(desc);
686 
687     switch (type) {
688         case SND_CARD_PRIMARY:
689             portNum = PORT_OUT_IN;
690             break;
691         case SND_CARD_HDMI:
692             portNum = PORT_OUT;
693             break;
694         case SND_CARD_USB:
695             portNum = PORT_IN;
696             break;
697         default:
698             AUDIO_FUNC_LOGE("Unknown sound card type does not support this sound card temporarily!");
699             return HDF_FAILURE;
700     }
701 
702 #ifndef AUDIO_HDI_SERVICE_MODE
703         desc->portNum = portNum;
704 #else
705         desc->portsLen = portNum;
706 #endif
707     if (portNum == 0) {
708         AUDIO_FUNC_LOGE("portNum is zero");
709         return HDF_FAILURE;
710     }
711     desc->ports = (struct AudioPort *)OsalMemCalloc(sizeof(struct AudioPort) * portNum);
712     if (desc->ports == NULL) {
713         AUDIO_FUNC_LOGE("OsalMemCalloc failed!");
714         return HDF_ERR_MALLOC_FAIL;
715     }
716 
717     if (type == SND_CARD_PRIMARY) {
718         AudioInitPortOut(&desc->ports[0]);
719         AudioInitPortIn(&desc->ports[SUPPORT_CAPTURE_OR_RENDER]);
720         AudioInitPortOutAndIn(&desc->ports[SUPPORT_CAPTURE_AND_RENDER]);
721     } else if (type == SND_CARD_HDMI) {
722         AudioInitPortOut(&desc->ports[0]);
723     } else if (type == SND_CARD_USB) {
724         AudioInitPortOut(&desc->ports[0]);
725         AudioInitPortIn(&desc->ports[SUPPORT_CAPTURE_OR_RENDER]);
726     } else {
727         AUDIO_FUNC_LOGE("adapter list not support sound card type %{public}d", type);
728         return HDF_FAILURE;
729     }
730 
731     return HDF_SUCCESS;
732 }
733 
AudioGetAllCardInfo(struct AudioAdapterDescriptor ** descs,int32_t * sndCardNum)734 int32_t AudioGetAllCardInfo(struct AudioAdapterDescriptor **descs, int32_t *sndCardNum)
735 {
736     CHECK_NULL_PTR_RETURN_DEFAULT(descs);
737     CHECK_NULL_PTR_RETURN_DEFAULT(sndCardNum);
738 
739     int32_t ret = SndSaveCardListInfo(SND_PCM_STREAM_PLAYBACK);
740     if (ret != HDF_SUCCESS) {
741         return HDF_FAILURE;
742     }
743 
744     int32_t adapterNum = CfgGetAdapterCount();
745     if (*descs == NULL && adapterNum > 0 && adapterNum < MALLOC_MAX) {
746         AUDIO_FUNC_LOGW("*descs is null, need memcalloc.");
747         *descs = (struct AudioAdapterDescriptor *)OsalMemCalloc(sizeof(struct AudioAdapterDescriptor) * adapterNum);
748         if (*descs == NULL) {
749             AUDIO_FUNC_LOGE("OsalMemCalloc descs is NULL");
750             return HDF_ERR_MALLOC_FAIL;
751         }
752     }
753     *sndCardNum = adapterNum;
754 
755     int32_t idx = 0;
756     for (enum SndCardType type = SND_CARD_PRIMARY; type < SND_CARD_MAX; ++type) {
757         for (int32_t i = 0; i < g_alsaAdapterList[type].num; ++i) {
758             (*descs)[idx].adapterName = strdup(g_alsaAdapterList[type].list[i].adapterName);
759             AudioInitPorts(&(*descs)[idx], type);
760             AUDIO_FUNC_LOGI("adapter name : %{public}s", (*descs)[idx].adapterName);
761             idx++;
762         }
763     }
764 
765     return HDF_SUCCESS;
766 }
767 
HdfIoServiceBindName(const char * serviceName)768 struct HdfIoService *HdfIoServiceBindName(const char *serviceName)
769 {
770     (void)serviceName;
771     /* Nothing to do */
772     static struct HdfIoService hdfIoService;
773     return &hdfIoService;
774 }
775 
AudioBindService(const char * name)776 struct DevHandle *AudioBindService(const char *name)
777 {
778     struct DevHandle *handle = NULL;
779 
780     if (name == NULL) {
781         AUDIO_FUNC_LOGE("service name NULL!");
782         return NULL;
783     }
784 
785     handle = (struct DevHandle *)OsalMemCalloc(sizeof(struct DevHandle));
786     if (handle == NULL) {
787         AUDIO_FUNC_LOGE("OsalMemCalloc handle failed!!!");
788         return NULL;
789     }
790 
791     AUDIO_FUNC_LOGI("BIND SERVICE SUCCESS!");
792     return handle;
793 }
794 
AudioCloseService(const struct DevHandle * handle)795 void AudioCloseService(const struct DevHandle *handle)
796 {
797     if (handle != NULL) {
798         AudioMemFree((void **)&handle);
799     }
800 }
801 
SndElementItemInit(struct AlsaMixerCtlElement * m)802 void SndElementItemInit(struct AlsaMixerCtlElement *m)
803 {
804     m->iface = IFACE_MIXER;
805     m->index = 0;
806     m->device = 0;
807     m->subdevice = 0;
808 }
809 
ConvertIfaceType(enum SndIfaceType iface)810 static snd_ctl_elem_iface_t ConvertIfaceType(enum SndIfaceType iface)
811 {
812     snd_ctl_elem_iface_t snd_iface;
813     switch (iface) {
814         case IFACE_CARD:
815             snd_iface = SND_CTL_ELEM_IFACE_CARD;
816             break;
817         case IFACE_MIXER:
818             snd_iface = SND_CTL_ELEM_IFACE_MIXER;
819             break;
820         case IFACE_PCM:
821             snd_iface = SND_CTL_ELEM_IFACE_PCM;
822             break;
823         case IFACE_RAWMIDI:
824             snd_iface = SND_CTL_ELEM_IFACE_RAWMIDI;
825             break;
826         case IFACE_TIMER:
827             snd_iface = SND_CTL_ELEM_IFACE_TIMER;
828             break;
829         case IFACE_SEQUENCER:
830             snd_iface = SND_CTL_ELEM_IFACE_SEQUENCER;
831             break;
832         default:
833             snd_iface = SND_CTL_ELEM_IFACE_MIXER;
834             break;
835     }
836     return snd_iface;
837 }
838 
SetElementInfo(snd_ctl_t * alsaHandle,const struct AlsaMixerCtlElement * ctlElem,snd_ctl_elem_info_t * info,snd_ctl_elem_id_t * id)839 static int32_t SetElementInfo(snd_ctl_t *alsaHandle, const struct AlsaMixerCtlElement *ctlElem,
840     snd_ctl_elem_info_t *info, snd_ctl_elem_id_t *id)
841 {
842     CHECK_NULL_PTR_RETURN_DEFAULT(alsaHandle);
843     CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
844     CHECK_NULL_PTR_RETURN_DEFAULT(info);
845     CHECK_NULL_PTR_RETURN_DEFAULT(id);
846 
847     if (ctlElem->numid >= 0) {
848         snd_ctl_elem_id_set_numid(id, ctlElem->numid);
849     }
850     if (ctlElem->index >= 0) {
851         snd_ctl_elem_id_set_index(id, ctlElem->index);
852     }
853     if (ctlElem->device >= 0) {
854         snd_ctl_elem_id_set_device(id, ctlElem->device);
855     }
856     if (ctlElem->subdevice >= 0) {
857         snd_ctl_elem_id_set_subdevice(id, ctlElem->subdevice);
858     }
859 
860     snd_ctl_elem_iface_t ifaceType = ConvertIfaceType(ctlElem->iface);
861     snd_ctl_elem_id_set_interface(id, ifaceType);
862     if (ctlElem->name) {
863         snd_ctl_elem_id_set_name(id, ctlElem->name);
864     }
865     snd_ctl_elem_info_set_id(info, id);
866     int32_t ret = snd_ctl_elem_info(alsaHandle, info);
867     if (ret < 0) {
868         AUDIO_FUNC_LOGE("Cannot find the given element from elem_value\n");
869         return HDF_FAILURE;
870     }
871     snd_ctl_elem_info_get_id(info, id);
872 
873     return HDF_SUCCESS;
874 }
875 
SndElementReadInt(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,long * value)876 int32_t SndElementReadInt(struct AlsaSoundCard *cardIns,
877     const struct AlsaMixerCtlElement *ctlElem, long *value)
878 {
879     snd_ctl_t *alsaHandle = NULL;
880     snd_ctl_elem_id_t *elem_id = NULL;
881     snd_ctl_elem_info_t *elem_info = NULL;
882     snd_ctl_elem_value_t *elem_value = NULL;
883 
884     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
885     CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
886 
887     int ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
888     if (ret < 0) {
889         AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
890         return HDF_FAILURE;
891     }
892 
893     snd_ctl_elem_id_alloca(&elem_id);
894     snd_ctl_elem_info_alloca(&elem_info);
895     snd_ctl_elem_value_alloca(&elem_value);
896     ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
897     if (ret != HDF_SUCCESS) {
898         AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
899         return HDF_FAILURE;
900     }
901     snd_ctl_elem_value_set_id(elem_value, elem_id);
902 
903     if (!snd_ctl_elem_info_is_readable(elem_info)) {
904         AUDIO_FUNC_LOGE("Element read enable\n");
905         return HDF_FAILURE;
906     }
907     ret = snd_ctl_elem_read(alsaHandle, elem_value);
908     if (ret < 0) {
909         AUDIO_FUNC_LOGE("Cannot read the given element from elem_value \n");
910         return HDF_FAILURE;
911     }
912 
913     snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(elem_info);
914     if (type == SND_CTL_ELEM_TYPE_INTEGER) {
915         *value = snd_ctl_elem_value_get_integer(elem_value, 0);
916     } else if (type == SND_CTL_ELEM_TYPE_INTEGER64) {
917         *value = (long)snd_ctl_elem_value_get_integer64(elem_value, 0);
918     } else {
919         AUDIO_FUNC_LOGE("Element type is not interger\n");
920         return HDF_FAILURE;
921     }
922 
923     return HDF_SUCCESS;
924 }
925 
SndElementReadEnum(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,unsigned int * item)926 int32_t SndElementReadEnum(
927     struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, unsigned int *item)
928 {
929     snd_ctl_t *alsaHandle = NULL;
930     snd_ctl_elem_id_t *elem_id = NULL;
931     snd_ctl_elem_info_t *elem_info = NULL;
932     snd_ctl_elem_value_t *elem_value = NULL;
933 
934     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
935     CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
936 
937     int ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
938     if (ret < 0) {
939         AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
940         return HDF_FAILURE;
941     }
942 
943     snd_ctl_elem_id_alloca(&elem_id);
944     snd_ctl_elem_info_alloca(&elem_info);
945     snd_ctl_elem_value_alloca(&elem_value);
946     ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
947     if (ret != HDF_SUCCESS) {
948         AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
949         return HDF_FAILURE;
950     }
951     snd_ctl_elem_value_set_id(elem_value, elem_id);
952 
953     if (!snd_ctl_elem_info_is_readable(elem_info)) {
954         AUDIO_FUNC_LOGE("Element read enable\n");
955         return HDF_FAILURE;
956     }
957     ret = snd_ctl_elem_read(alsaHandle, elem_value);
958     if (ret < 0) {
959         AUDIO_FUNC_LOGE("Cannot read the given element from elem_value \n");
960         return HDF_FAILURE;
961     }
962 
963     snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(elem_info);
964     if (type == SND_CTL_ELEM_TYPE_ENUMERATED) {
965         *item = snd_ctl_elem_value_get_enumerated(elem_value, 0);
966     } else {
967         AUDIO_FUNC_LOGE("Element type is not enumerated\n");
968         return HDF_FAILURE;
969     }
970 
971     return HDF_SUCCESS;
972 }
973 
SndElementReadRange(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,long * mix,long * max)974 int32_t SndElementReadRange(
975     struct AlsaSoundCard * cardIns, const struct AlsaMixerCtlElement * ctlElem, long * mix, long * max)
976 {
977     snd_ctl_t *alsaHandle = NULL;
978     snd_ctl_elem_id_t *elem_id = NULL;
979     snd_ctl_elem_info_t *elem_info = NULL;
980     snd_ctl_elem_value_t *elem_value = NULL;
981 
982     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
983     CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
984 
985     int ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
986     if (ret < 0) {
987         AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
988         return HDF_FAILURE;
989     }
990 
991     snd_ctl_elem_id_alloca(&elem_id);
992     snd_ctl_elem_info_alloca(&elem_info);
993     snd_ctl_elem_value_alloca(&elem_value);
994     ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
995     if (ret != HDF_SUCCESS) {
996         AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
997         return HDF_FAILURE;
998     }
999     snd_ctl_elem_value_set_id(elem_value, elem_id);
1000 
1001     if (!snd_ctl_elem_info_is_readable(elem_info)) {
1002         AUDIO_FUNC_LOGE("Element read enable\n");
1003         return HDF_FAILURE;
1004     }
1005     ret = snd_ctl_elem_read(alsaHandle, elem_value);
1006     if (ret < 0) {
1007         AUDIO_FUNC_LOGE("Cannot read the given element from elem_value \n");
1008         return HDF_FAILURE;
1009     }
1010 
1011     snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(elem_info);
1012     if (type == SND_CTL_ELEM_TYPE_INTEGER) {
1013         *mix = snd_ctl_elem_info_get_min(elem_info);
1014         *max = snd_ctl_elem_info_get_max(elem_info);
1015     } else if (type == SND_CTL_ELEM_TYPE_INTEGER64) {
1016         *mix = (long)snd_ctl_elem_info_get_min64(elem_info);
1017         *max = (long)snd_ctl_elem_info_get_max64(elem_info);
1018     } else {
1019         AUDIO_FUNC_LOGE("Element value is not integer type!\n");
1020         return HDF_FAILURE;
1021     }
1022 
1023     return HDF_SUCCESS;
1024 }
1025 
SndElementReadSwitch(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,bool * on)1026 int32_t SndElementReadSwitch(
1027     struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, bool *on)
1028 {
1029     snd_ctl_t *alsaHandle = NULL;
1030     snd_ctl_elem_id_t *elem_id = NULL;
1031     snd_ctl_elem_info_t *elem_info = NULL;
1032     snd_ctl_elem_value_t *elem_value = NULL;
1033 
1034     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1035     CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
1036 
1037     int ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
1038     if (ret < 0) {
1039         AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
1040         return HDF_FAILURE;
1041     }
1042 
1043     snd_ctl_elem_id_alloca(&elem_id);
1044     snd_ctl_elem_info_alloca(&elem_info);
1045     snd_ctl_elem_value_alloca(&elem_value);
1046     ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
1047     if (ret != HDF_SUCCESS) {
1048         AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
1049         return HDF_FAILURE;
1050     }
1051     snd_ctl_elem_value_set_id(elem_value, elem_id);
1052 
1053     if (!snd_ctl_elem_info_is_readable(elem_info)) {
1054         AUDIO_FUNC_LOGE("Element read enable\n");
1055         return HDF_FAILURE;
1056     }
1057     ret = snd_ctl_elem_read(alsaHandle, elem_value);
1058     if (ret < 0) {
1059         AUDIO_FUNC_LOGE("Cannot read the given element from elem_value \n");
1060         return HDF_FAILURE;
1061     }
1062 
1063     snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(elem_info);
1064     if (type == SND_CTL_ELEM_TYPE_BOOLEAN) {
1065         ret = snd_ctl_elem_value_get_boolean(elem_value, 0);
1066         *on = (ret > 0) ? true : false;
1067     } else {
1068         AUDIO_FUNC_LOGE("Element type is not boolean\n");
1069         return HDF_FAILURE;
1070     }
1071 
1072     return HDF_SUCCESS;
1073 }
1074 
SndElementWriteInt(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,long value)1075 int32_t SndElementWriteInt(
1076     struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, long value)
1077 {
1078     snd_ctl_t *alsaHandle = NULL;
1079     snd_ctl_elem_id_t *elem_id = NULL;
1080     snd_ctl_elem_info_t *elem_info = NULL;
1081     snd_ctl_elem_value_t *elem_value = NULL;
1082 
1083     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1084     CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
1085 
1086     int ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
1087     if (ret < 0) {
1088         AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
1089         return HDF_FAILURE;
1090     }
1091 
1092     snd_ctl_elem_id_alloca(&elem_id);
1093     snd_ctl_elem_info_alloca(&elem_info);
1094     snd_ctl_elem_value_alloca(&elem_value);
1095     ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
1096     if (ret != HDF_SUCCESS) {
1097         AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
1098         return HDF_FAILURE;
1099     }
1100 
1101     if (!snd_ctl_elem_info_is_writable(elem_info)) {
1102         AUDIO_FUNC_LOGE("Element write enable\n");
1103         return HDF_FAILURE;
1104     }
1105 
1106     snd_ctl_elem_value_set_id(elem_value, elem_id);
1107     snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(elem_info);
1108     if (type == SND_CTL_ELEM_TYPE_INTEGER) {
1109         snd_ctl_elem_value_set_integer(elem_value, 0, value);
1110     } else if (type == SND_CTL_ELEM_TYPE_INTEGER64) {
1111         snd_ctl_elem_value_set_integer64(elem_value, 0, (long long)value);
1112     } else {
1113         AUDIO_FUNC_LOGE("Element value is not integer type!\n");
1114         return HDF_FAILURE;
1115     }
1116 
1117     ret = snd_ctl_elem_write(alsaHandle, elem_value);
1118     if (ret < 0) {
1119         AUDIO_FUNC_LOGE("snd_ctl_elem_write failed!\n");
1120         return HDF_FAILURE;
1121     }
1122 
1123     return HDF_SUCCESS;
1124 }
1125 
SndElementWriteEnum(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,unsigned int item)1126 int32_t SndElementWriteEnum(
1127     struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, unsigned int item)
1128 {
1129     snd_ctl_t *alsaHandle = NULL;
1130     snd_ctl_elem_id_t *elem_id = NULL;
1131     snd_ctl_elem_info_t *elem_info = NULL;
1132     snd_ctl_elem_value_t *elem_value = NULL;
1133 
1134     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1135     CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
1136 
1137     int ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
1138     if (ret < 0) {
1139         AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
1140         return HDF_FAILURE;
1141     }
1142 
1143     snd_ctl_elem_id_alloca(&elem_id);
1144     snd_ctl_elem_info_alloca(&elem_info);
1145     snd_ctl_elem_value_alloca(&elem_value);
1146     ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
1147     if (ret != HDF_SUCCESS) {
1148         AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
1149         return HDF_FAILURE;
1150     }
1151 
1152     if (!snd_ctl_elem_info_is_writable(elem_info)) {
1153         AUDIO_FUNC_LOGE("Element write enable\n");
1154         return HDF_FAILURE;
1155     }
1156 
1157     snd_ctl_elem_value_set_id(elem_value, elem_id);
1158     snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(elem_info);
1159     if (type == SND_CTL_ELEM_TYPE_ENUMERATED) {
1160         snd_ctl_elem_value_set_enumerated(elem_value, 0, item);
1161     } else {
1162         AUDIO_FUNC_LOGE("Element value is not enum type!\n");
1163         return HDF_FAILURE;
1164     }
1165 
1166     ret = snd_ctl_elem_write(alsaHandle, elem_value);
1167     if (ret < 0) {
1168         AUDIO_FUNC_LOGE("snd_ctl_elem_write failed!\n");
1169         return HDF_FAILURE;
1170     }
1171 
1172     return HDF_SUCCESS;
1173 }
1174 
SndElementWriteSwitch(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,bool on)1175 int32_t SndElementWriteSwitch(
1176     struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, bool on)
1177 {
1178     snd_ctl_t *alsaHandle = NULL;
1179     snd_ctl_elem_id_t *elem_id;
1180     snd_ctl_elem_info_t *elem_info;
1181     snd_ctl_elem_value_t *elem_value;
1182 
1183     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1184     CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
1185 
1186     int ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
1187     if (ret < 0) {
1188         AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
1189         return HDF_FAILURE;
1190     }
1191 
1192     snd_ctl_elem_id_alloca(&elem_id);
1193     snd_ctl_elem_info_alloca(&elem_info);
1194     snd_ctl_elem_value_alloca(&elem_value);
1195     ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
1196     if (ret != HDF_SUCCESS) {
1197         AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
1198         return HDF_FAILURE;
1199     }
1200 
1201     if (!snd_ctl_elem_info_is_writable(elem_info)) {
1202         AUDIO_FUNC_LOGE("Element write enable\n");
1203         return HDF_FAILURE;
1204     }
1205 
1206     snd_ctl_elem_value_set_id(elem_value, elem_id);
1207     snd_ctl_elem_type_t type = snd_ctl_elem_info_get_type(elem_info);
1208     if (type == SND_CTL_ELEM_TYPE_BOOLEAN) {
1209         int value = on ? 1 : 0;
1210         snd_ctl_elem_value_set_boolean(elem_value, 0, value);
1211     } else {
1212         AUDIO_FUNC_LOGE("Element value is not boolean type!\n");
1213         return HDF_FAILURE;
1214     }
1215 
1216     ret = snd_ctl_elem_write(alsaHandle, elem_value);
1217     if (ret < 0) {
1218         AUDIO_FUNC_LOGE("snd_ctl_elem_write failed!\n");
1219         return HDF_FAILURE;
1220     }
1221 
1222     return HDF_SUCCESS;
1223 }
1224 
SndElementWrite(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem)1225 int32_t SndElementWrite(
1226     struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem)
1227 {
1228     snd_ctl_t *alsaHandle = NULL;
1229     snd_ctl_elem_id_t *elem_id = NULL;
1230     snd_ctl_elem_info_t *elem_info = NULL;
1231     snd_ctl_elem_value_t *elem_value = NULL;
1232 
1233     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1234     CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
1235 
1236     int ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
1237     if (ret < 0) {
1238         AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
1239         return HDF_FAILURE;
1240     }
1241 
1242     snd_ctl_elem_id_alloca(&elem_id);
1243     snd_ctl_elem_info_alloca(&elem_info);
1244     snd_ctl_elem_value_alloca(&elem_value);
1245     ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
1246     if (ret != HDF_SUCCESS) {
1247         AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
1248         return HDF_FAILURE;
1249     }
1250 
1251     if (!snd_ctl_elem_info_is_writable(elem_info)) {
1252         AUDIO_FUNC_LOGE("Element write enable\n");
1253         return HDF_FAILURE;
1254     }
1255 
1256     snd_ctl_elem_value_set_id(elem_value, elem_id);
1257     ret = snd_ctl_ascii_value_parse(alsaHandle, elem_value, elem_info, ctlElem->value);
1258     if (ret < 0) {
1259         AUDIO_FUNC_LOGE("Control parse error: %s\n", snd_strerror(ret));
1260         return HDF_FAILURE;
1261     }
1262     ret = snd_ctl_elem_write(alsaHandle, elem_value);
1263     if (ret < 0) {
1264         AUDIO_FUNC_LOGE("Control element write error: %s\n", snd_strerror(ret));
1265         return HDF_FAILURE;
1266     }
1267 
1268     return HDF_SUCCESS;
1269 }
1270 
SndElementGroupWrite(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * elemGroup,int32_t groupSize)1271 int32_t SndElementGroupWrite(
1272     struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement* elemGroup, int32_t groupSize)
1273 {
1274     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1275 
1276     for (int i = 0; i < groupSize; ++i) {
1277         int err = SndElementWrite(cardIns, &elemGroup[i]);
1278         if (err < 0) {
1279             AUDIO_FUNC_LOGE("Cant't set element %{public}s", elemGroup[i].name);
1280         }
1281     }
1282 
1283     return HDF_SUCCESS;
1284 }
1285 
SndTraversalMixerElement(struct AlsaSoundCard * cardIns,bool (* callback)(void * data,snd_ctl_elem_id_t * elem_id),void * data)1286 int32_t SndTraversalMixerElement(struct AlsaSoundCard *cardIns,
1287     bool (*callback)(void *data, snd_ctl_elem_id_t *elem_id), void *data)
1288 {
1289     snd_hctl_t *handle = NULL;
1290     snd_hctl_elem_t *elem = NULL;
1291     snd_ctl_elem_id_t *elem_id = NULL;
1292     snd_ctl_elem_info_t *elem_info = NULL;
1293     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1294     CHECK_NULL_PTR_RETURN_DEFAULT(callback);
1295 
1296     int ret = snd_hctl_open(&handle, cardIns->ctrlName, 0);
1297     if (ret < 0) {
1298         AUDIO_FUNC_LOGE("Control %{public}s open error: %{public}s",
1299             cardIns->ctrlName, snd_strerror(ret));
1300         return HDF_FAILURE;
1301     }
1302     ret = snd_hctl_load(handle);
1303     if (ret < 0) {
1304         AUDIO_FUNC_LOGE("Control %{public}s local error: %{public}s\n",
1305             cardIns->ctrlName, snd_strerror(ret));
1306         return HDF_FAILURE;
1307     }
1308 
1309     snd_ctl_elem_id_alloca(&elem_id);
1310     snd_ctl_elem_info_alloca(&elem_info);
1311     for (elem = snd_hctl_first_elem(handle); elem; elem = snd_hctl_elem_next(elem)) {
1312         ret = snd_hctl_elem_info(elem, elem_info);
1313         if (ret < 0) {
1314             AUDIO_FUNC_LOGE("Control %{public}s snd_hctl_elem_info error: %{public}s\n",
1315                 cardIns->ctrlName, snd_strerror(ret));
1316             return HDF_FAILURE;
1317         }
1318         if (snd_ctl_elem_info_is_inactive(elem_info)) {
1319             continue;
1320         }
1321         snd_hctl_elem_get_id(elem, elem_id);
1322         if (callback(data, elem_id)) {
1323             (void)snd_hctl_close(handle);
1324             return HDF_SUCCESS;
1325         }
1326     }
1327     (void)snd_hctl_close(handle);
1328     return HDF_FAILURE;
1329 }
1330