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