• 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 
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     int32_t jsonStrSize;
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     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)134 static struct AlsaAdapterCfgInfo *CfgGetAdapterInfo(const char* adapterName)
135 {
136     if (adapterName == NULL) {
137         return NULL;
138     }
139 
140     struct AlsaAdapterCfgInfo *info;
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                 return info;
146             }
147         }
148     }
149     return NULL;
150 }
151 
CfgDumpAdapterInfo(struct AlsaAdapterCfgInfo * info)152 static int32_t CfgDumpAdapterInfo(struct AlsaAdapterCfgInfo *info)
153 {
154     int32_t ret, idx;
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     idx = g_alsaAdapterList[cardType].num;
173     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     int32_t ret;
191     cJSON *item;
192     CHECK_NULL_PTR_RETURN_DEFAULT(adapter);
193     CHECK_NULL_PTR_RETURN_DEFAULT(info);
194 
195     item = cJSON_GetObjectItem(adapter, "name");
196     if (item == NULL || item->valuestring == NULL) {
197         AUDIO_FUNC_LOGE("adapter name is null!");
198         return HDF_FAILURE;
199     }
200     ret = memcpy_s(info->adapterName, MAX_CARD_NAME_LEN - 1, item->valuestring, MAX_CARD_NAME_LEN - 1);
201     if (ret != EOK) {
202         AUDIO_FUNC_LOGE("memcpy_s adapterName fail!");
203         return HDF_FAILURE;
204     }
205 
206     item = cJSON_GetObjectItem(adapter, "cardId");
207     if (item == NULL) {
208         AUDIO_FUNC_LOGE("cardId not set!");
209         return HDF_FAILURE;
210     }
211     info->cardId = item->valuedouble;
212 
213     item = cJSON_GetObjectItem(adapter, "cardName");
214     if (item == NULL || item->valuestring == NULL) {
215         AUDIO_FUNC_LOGE("cardName is null!");
216         return HDF_FAILURE;
217     }
218     ret = memcpy_s(info->cardName, MAX_CARD_NAME_LEN - 1, item->valuestring, MAX_CARD_NAME_LEN - 1);
219     if (ret != EOK) {
220         AUDIO_FUNC_LOGE("memcpy_s cardName fail!");
221         return HDF_FAILURE;
222     }
223 
224     return HDF_SUCCESS;
225 }
226 
CfgParseAdapterItems(cJSON * adapterObj)227 static int32_t CfgParseAdapterItems(cJSON *adapterObj)
228 {
229     int32_t ret, adapterNum;
230     cJSON *adapterItems = NULL;
231 
232     adapterItems = cJSON_GetObjectItem(adapterObj, "adapters");
233     if (adapterItems == NULL) {
234         AUDIO_FUNC_LOGE("Get adapterItems from json failed!\n");
235         return HDF_FAILURE;
236     }
237     adapterNum = cJSON_GetArraySize(adapterItems);
238     if (adapterNum <= 0) {
239         AUDIO_FUNC_LOGE("Get adapter number failed!");
240         return HDF_FAILURE;
241     } else if (adapterNum > MAX_CARD_NUM) {
242         AUDIO_FUNC_LOGE("Read adapters number is %{public}d over max num %{public}d!", adapterNum, MAX_CARD_NUM);
243         return HDF_FAILURE;
244     }
245 
246     for (int32_t i = 0; i < adapterNum; ++i) {
247         cJSON *adapter;
248         struct AlsaAdapterCfgInfo info;
249         adapter = cJSON_GetArrayItem(adapterItems, i);
250         if (adapter == NULL) {
251             AUDIO_FUNC_LOGE("Get adapter item from array failed!");
252         }
253 
254         ret = CfgSaveAdapterStruct(adapter, &info);
255         if (ret != HDF_SUCCESS) {
256             AUDIO_FUNC_LOGE("CfgSaveAdapterStruct failed!");
257             return HDF_FAILURE;
258         }
259 
260         ret = CfgDumpAdapterInfo(&info);
261         if (ret != HDF_SUCCESS) {
262             AUDIO_FUNC_LOGE("CfgDumpAdapterInfo failed!");
263             return HDF_FAILURE;
264         }
265     }
266 
267     return HDF_SUCCESS;
268 }
269 
CfgSaveAdapterFromFile(void)270 int32_t CfgSaveAdapterFromFile(void)
271 {
272     int32_t ret;
273     cJSON *adapterObj = NULL;
274     char *configBuf = NULL;
275 
276     configBuf = CfgReadAdapterFile(ALSA_CARD_CONFIG_FILE);
277     if (configBuf == NULL) {
278         AUDIO_FUNC_LOGE("CfgReadAdapterFile failed!");
279         return HDF_FAILURE;
280     }
281     adapterObj = cJSON_Parse(configBuf);
282     if (adapterObj == NULL) {
283         AUDIO_FUNC_LOGE("Parse json file failed!");
284         AudioMemFree((void **)&configBuf);
285         return HDF_FAILURE;
286     }
287     AudioMemFree((void **)&configBuf);
288 
289     ret = CfgParseAdapterItems(adapterObj);
290     if (ret != HDF_SUCCESS) {
291         cJSON_Delete(adapterObj);
292         AUDIO_FUNC_LOGE("Parse adapter items failed!");
293         return HDF_FAILURE;
294     }
295 
296     cJSON_Delete(adapterObj);
297     return HDF_SUCCESS;
298 }
299 
DevGetInfoByCardId(int32_t cardId)300 static struct AlsaDevInfo *DevGetInfoByCardId(int32_t cardId)
301 {
302     struct AlsaDevInfo *info = NULL;
303     int num = g_alsaCardsDevList.num;
304     for (int i = 0; i < num; ++i) {
305         info = &g_alsaCardsDevList.alsaDevIns[i];
306         if (info->card == cardId) {
307             return info;
308         }
309     }
310     return NULL;
311 }
312 
DevGetInfoByPcmInfoId(const char * name)313 static struct AlsaDevInfo *DevGetInfoByPcmInfoId(const char * name)
314 {
315     struct AlsaDevInfo *info = NULL;
316     int num = g_alsaCardsDevList.num;
317     for (int i = 0; i < num; ++i) {
318         info = &g_alsaCardsDevList.alsaDevIns[i];
319         if (strcmp(name, info->pcmInfoId) == 0) {
320             return info;
321         }
322     }
323 
324     return NULL;
325 }
326 
DevSaveCardPcmInfo(snd_ctl_t * handle,snd_pcm_stream_t stream,int card,const char * deviceName)327 static int32_t DevSaveCardPcmInfo(snd_ctl_t *handle, snd_pcm_stream_t stream, int card, const char *deviceName)
328 {
329     int32_t ret;
330     int pcmDev = -1;
331     snd_ctl_card_info_t *info = NULL;
332     snd_pcm_info_t *pcminfo = NULL;
333     snd_ctl_card_info_alloca(&info);
334     snd_pcm_info_alloca(&pcminfo);
335 
336     if (snd_ctl_card_info(handle, info) != 0) {
337         AUDIO_FUNC_LOGE("snd_ctl_card_info failed.");
338         return HDF_FAILURE;
339     }
340     if (snd_ctl_pcm_next_device(handle, &pcmDev) < 0 || pcmDev < 0) {
341         AUDIO_FUNC_LOGE("No pcm device found");
342         return HDF_FAILURE;
343     }
344     while (pcmDev >= 0) {
345         snd_pcm_info_set_device(pcminfo, pcmDev);
346         snd_pcm_info_set_subdevice(pcminfo, 0);
347         snd_pcm_info_set_stream(pcminfo, stream);
348         ret = snd_ctl_pcm_info(handle, pcminfo);
349         if (ret < 0) {
350             if (ret != -ENOENT) {
351                 AUDIO_FUNC_LOGE("control digital audio info (%{public}d)", pcmDev);
352             }
353         } else {
354             struct AlsaDevInfo *devInfo = &g_alsaCardsDevList.alsaDevIns[g_alsaCardsDevList.num];
355             const char *cardId = snd_ctl_card_info_get_id(info);
356             const char *pcmInfoId = snd_pcm_info_get_id(pcminfo);
357             AUDIO_FUNC_LOGD("alsa cardName: %{public}s, pcmInfoId %{public}s", cardId, pcmInfoId);
358             devInfo->card = card;
359             devInfo->device = pcmDev;
360             if (strncpy_s(devInfo->cardId, MAX_CARD_NAME_LEN + 1, cardId, strlen(cardId)) != 0) {
361                 AUDIO_FUNC_LOGE("strncpy_s failed!");
362                 return HDF_FAILURE;
363             }
364             if (strncpy_s(devInfo->pcmInfoId, MAX_CARD_NAME_LEN + 1, pcmInfoId, strlen(pcmInfoId)) != 0) {
365                 AUDIO_FUNC_LOGE("strncpy_s failed!");
366                 return HDF_FAILURE;
367             }
368             g_alsaCardsDevList.num++;
369         }
370 
371         if (snd_ctl_pcm_next_device(handle, &pcmDev) < 0) {
372             AUDIO_FUNC_LOGE("snd_ctl_pcm_next_device error!");
373             return HDF_FAILURE;
374         }
375         AUDIO_FUNC_LOGD("soundcard pcm device number: %{public}d.", pcmDev);
376     }
377     return HDF_SUCCESS;
378 }
379 
DevSaveDriverInfo(snd_pcm_stream_t stream)380 static int32_t DevSaveDriverInfo(snd_pcm_stream_t stream)
381 {
382     int32_t ret;
383     snd_ctl_t *handle;
384     int card = -1;
385     char deviceName[MAX_CARD_NAME_LEN] = {0};
386 
387     ret = snd_card_next(&card);
388     if (ret < 0 || card < 0) {
389         AUDIO_FUNC_LOGE("No soundcards found: %{public}s.", snd_strerror(ret));
390         return HDF_FAILURE;
391     }
392 
393     while (card >= 0) {
394         (void)memset_s(deviceName, MAX_CARD_NAME_LEN, 0, MAX_CARD_NAME_LEN);
395         ret = snprintf_s(deviceName, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1, "hw:%d", card);
396         if (ret < 0) {
397             AUDIO_FUNC_LOGE("snprintf_s failed");
398             snd_ctl_close(handle);
399             return HDF_FAILURE;
400         }
401 
402         ret = snd_ctl_open(&handle, deviceName, 0);
403         if (ret != 0) {
404             AUDIO_FUNC_LOGE("snd_ctl_open failed.");
405             return HDF_FAILURE;
406         }
407 
408         ret = DevSaveCardPcmInfo(handle, stream, card, deviceName);
409         if (ret != HDF_SUCCESS) {
410             AUDIO_FUNC_LOGE("save alsa sound cards %{public}s pcm info failed!", deviceName);
411         }
412 
413         ret = snd_ctl_close(handle);
414         if (ret < 0) {
415             AUDIO_FUNC_LOGE("snd_ctl_close error: %{public}s.", snd_strerror(ret));
416             return HDF_FAILURE;
417         }
418 
419         ret = snd_card_next(&card);
420         if (ret < 0) {
421             AUDIO_FUNC_LOGE("snd_card_next error: %{public}s", snd_strerror(ret));
422             return HDF_FAILURE;
423         }
424     }
425 
426     return HDF_SUCCESS;
427 }
428 
SndSaveCardListInfo(snd_pcm_stream_t stream)429 int32_t SndSaveCardListInfo(snd_pcm_stream_t stream)
430 {
431     int32_t ret;
432 
433     (void)memset_s(&g_alsaAdapterList, sizeof(struct AlsaAdapterList) * SND_CARD_MAX,
434         0, sizeof(struct AlsaAdapterList) * SND_CARD_MAX);
435     (void)memset_s(&g_alsaCardsDevList, sizeof(struct AlsaCardsList),
436         0, sizeof(struct AlsaCardsList));
437 
438     /* Parse sound card from configuration file */
439     ret = CfgSaveAdapterFromFile();
440     if (ret != HDF_SUCCESS) {
441         AUDIO_FUNC_LOGE("parse config file failed! ret = %{public}d", ret);
442         return HDF_FAILURE;
443     }
444 
445     /* Read sound card list from alsa hardware */
446     ret = DevSaveDriverInfo(stream);
447     if (ret != HDF_SUCCESS) {
448         AUDIO_FUNC_LOGE("failed to save alsa sound cards driver info");
449         return HDF_FAILURE;
450     }
451 
452     /* if the alsa hardware include usb then add to adapter list */
453     struct AlsaDevInfo *devInfo = DevGetInfoByPcmInfoId(USB);
454     if (devInfo != NULL) {
455         g_alsaAdapterList[SND_CARD_USB].num = 1;
456         ret = memcpy_s((void*)&g_alsaAdapterList[SND_CARD_USB].list[0].adapterName, MAX_CARD_NAME_LEN,
457         USB, sizeof(USB));
458         if (ret != EOK) {
459             AUDIO_FUNC_LOGE("memcpy_s adapterName fail!");
460             return HDF_FAILURE;
461         }
462     }
463 
464     return HDF_SUCCESS;
465 }
466 
SndMatchSelAdapter(struct AlsaSoundCard * cardIns,const char * adapterName)467 int32_t SndMatchSelAdapter(struct AlsaSoundCard *cardIns, const char *adapterName)
468 {
469     int32_t ret;
470     enum SndCardType cardType;
471     struct AlsaAdapterCfgInfo *info = NULL;
472     struct AlsaDevInfo *devInfo = NULL;
473     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
474     CHECK_NULL_PTR_RETURN_DEFAULT(adapterName);
475 
476     cardType = CfgGetAdapterCardType(adapterName);
477     if (cardType == SND_CARD_UNKNOWN) {
478         AUDIO_FUNC_LOGE("unknow card type error.");
479         return HDF_FAILURE;
480     }
481     cardIns->cardType = cardType;
482 
483     info = CfgGetAdapterInfo(adapterName);
484     if (info == NULL) {
485         AUDIO_FUNC_LOGE("adapter %{public}s is not exits.", cardIns->adapterName);
486         return HDF_FAILURE;
487     }
488 
489     devInfo = DevGetInfoByCardId(info->cardId);
490     if (devInfo == NULL) {
491         AUDIO_FUNC_LOGE("adapter %{public}s cant not find sound card device.", cardIns->adapterName);
492         return HDF_FAILURE;
493     }
494 
495     ret = snprintf_s(cardIns->devName, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1,
496         "hw:%d,%d", devInfo->card, devInfo->device);
497     if (ret < 0) {
498         AUDIO_FUNC_LOGE("%{public}s snprintf_s devName failed", cardIns->adapterName);
499         return HDF_FAILURE;
500     }
501     ret = snprintf_s(cardIns->ctrlName, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1, "hw:%d", devInfo->card);
502     if (ret < 0) {
503         AUDIO_FUNC_LOGE("%{public}s snprintf_s ctrlName failed", cardIns->adapterName);
504         return HDF_FAILURE;
505     }
506     ret = snprintf_s(cardIns->alsaCardId, MAX_CARD_NAME_LEN, MAX_CARD_NAME_LEN - 1, "%s", devInfo->cardId);
507     if (ret < 0) {
508         AUDIO_FUNC_LOGE("%{public}s snprintf_s alsaCardId failed", cardIns->adapterName);
509         return HDF_FAILURE;
510     }
511 
512     return HDF_SUCCESS;
513 }
514 
SndConverAlsaPcmFormat(const struct AudioPcmHwParams * hwParams,snd_pcm_format_t * alsaPcmFormat)515 int32_t SndConverAlsaPcmFormat(const struct AudioPcmHwParams *hwParams, snd_pcm_format_t *alsaPcmFormat)
516 {
517     CHECK_NULL_PTR_RETURN_DEFAULT(hwParams);
518     CHECK_NULL_PTR_RETURN_DEFAULT(alsaPcmFormat);
519     enum AudioFormat audioFormat = hwParams->format;
520     bool isBigEndian = hwParams->isBigEndian;
521 
522     /** Little Endian */
523     if (!isBigEndian) {
524         switch (audioFormat) {
525             case AUDIO_FORMAT_TYPE_PCM_8_BIT:
526                 *alsaPcmFormat = SND_PCM_FORMAT_S8; /** Signed 8 bit */
527                 break;
528             case AUDIO_FORMAT_TYPE_PCM_16_BIT:
529                 *alsaPcmFormat = SND_PCM_FORMAT_S16_LE; /** Signed 16 bit Little Endian */
530                 break;
531             case AUDIO_FORMAT_TYPE_PCM_24_BIT:
532                 *alsaPcmFormat = SND_PCM_FORMAT_S24_LE; /** Signed 24 bit Little Endian */
533                 break;
534             case AUDIO_FORMAT_TYPE_PCM_32_BIT:
535                 *alsaPcmFormat = SND_PCM_FORMAT_S32_LE; /** Signed 32 bit Little Endian */
536                 break;
537             default:
538                 AUDIO_FUNC_LOGE("not support format %{public}d", audioFormat);
539                 return HDF_ERR_NOT_SUPPORT;
540         }
541     } else { /** Big Endian */
542         switch (audioFormat) {
543             case AUDIO_FORMAT_TYPE_PCM_8_BIT:
544                 *alsaPcmFormat = SND_PCM_FORMAT_S8; /** Signed 8 bit */
545                 break;
546             case AUDIO_FORMAT_TYPE_PCM_16_BIT:
547                 *alsaPcmFormat = SND_PCM_FORMAT_S16_BE; /** Signed 16 bit Big Endian */
548                 break;
549             case AUDIO_FORMAT_TYPE_PCM_24_BIT:
550                 *alsaPcmFormat = SND_PCM_FORMAT_S24_BE; /** Signed 24 bit Big Endian */
551                 break;
552             case AUDIO_FORMAT_TYPE_PCM_32_BIT:
553                 *alsaPcmFormat = SND_PCM_FORMAT_S32_BE; /** Signed 32 bit Big Endian */
554                 break;
555             default:
556                 AUDIO_FUNC_LOGE("not support format %{public}d", audioFormat);
557                 return HDF_ERR_NOT_SUPPORT;
558         }
559     }
560 
561     return HDF_SUCCESS;
562 }
563 
SndPcmPrepare(struct AlsaSoundCard * cardIns)564 int32_t SndPcmPrepare(struct AlsaSoundCard *cardIns)
565 {
566     int32_t ret;
567     ret = snd_pcm_prepare(cardIns->pcmHandle);
568     if (ret < 0) {
569         AUDIO_FUNC_LOGE("snd_pcm_prepare fail: %{public}s", snd_strerror(ret));
570         return HDF_FAILURE;
571     }
572     return HDF_SUCCESS;
573 }
574 
SndisBusy(struct AlsaSoundCard * cardIns)575 bool SndisBusy(struct AlsaSoundCard *cardIns)
576 {
577     return (cardIns->pcmHandle == NULL) ? false : true;
578 }
579 
SndOpenMixer(struct AlsaSoundCard * cardIns)580 int32_t SndOpenMixer(struct AlsaSoundCard *cardIns)
581 {
582     int32_t ret;
583 
584     if (strlen(cardIns->ctrlName) == 0) {
585         AUDIO_FUNC_LOGE("The soundcard ctrname is null.");
586         return HDF_FAILURE;
587     }
588 
589     ret = snd_mixer_open(&cardIns->mixerHandle, 0);
590     if (ret < 0) {
591         AUDIO_FUNC_LOGE("Failed to open mixer: %{public}s.", snd_strerror(ret));
592         return HDF_FAILURE;
593     }
594 
595     ret = snd_mixer_attach(cardIns->mixerHandle, cardIns->ctrlName);
596     if (ret < 0) {
597         AUDIO_FUNC_LOGE("Failed to attach mixer: %{public}s.", snd_strerror(ret));
598         ret = snd_mixer_close(cardIns->mixerHandle);
599         if (ret < 0) {
600             AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret));
601         }
602         cardIns->mixerHandle = NULL;
603         return HDF_FAILURE;
604     }
605 
606     ret = snd_mixer_selem_register(cardIns->mixerHandle, NULL, NULL);
607     if (ret < 0) {
608         AUDIO_FUNC_LOGE("Failed to register mixer element: %{public}s.", snd_strerror(ret));
609         ret = snd_mixer_close(cardIns->mixerHandle);
610         if (ret < 0) {
611             AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret));
612         }
613         cardIns->mixerHandle = NULL;
614         return HDF_FAILURE;
615     }
616 
617     ret = snd_mixer_load(cardIns->mixerHandle);
618     if (ret < 0) {
619         AUDIO_FUNC_LOGE("Failed to load mixer element: %{public}s.", snd_strerror(ret));
620         ret = snd_mixer_close(cardIns->mixerHandle);
621         if (ret < 0) {
622             AUDIO_FUNC_LOGE("mixer close error: %{public}s.", snd_strerror(ret));
623         }
624         cardIns->mixerHandle = NULL;
625         return HDF_FAILURE;
626     }
627     return HDF_SUCCESS;
628 }
629 
SndGetRunState(struct AlsaSoundCard * cardIns)630 snd_pcm_state_t SndGetRunState(struct AlsaSoundCard * cardIns)
631 {
632     return snd_pcm_state(cardIns->pcmHandle);
633 }
634 
SndCloseHandle(struct AlsaSoundCard * cardIns)635 void SndCloseHandle(struct AlsaSoundCard *cardIns)
636 {
637     int32_t ret;
638     if (cardIns->cardStatus > 0) {
639         cardIns->cardStatus -= 1;
640     }
641     if (cardIns->cardStatus == 0) {
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;
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     int32_t ret, idx;
733     int32_t adapterNum;
734     CHECK_NULL_PTR_RETURN_DEFAULT(descs);
735     CHECK_NULL_PTR_RETURN_DEFAULT(sndCardNum);
736 
737     ret = SndSaveCardListInfo(SND_PCM_STREAM_PLAYBACK);
738     if (ret != HDF_SUCCESS) {
739         return HDF_FAILURE;
740     }
741 
742     adapterNum = CfgGetAdapterCount();
743     if (*descs == NULL) {
744         AUDIO_FUNC_LOGW("*descs is null, need memcalloc.");
745         *descs = (struct AudioAdapterDescriptor *)OsalMemCalloc(sizeof(struct AudioAdapterDescriptor) * adapterNum);
746         if (*descs == NULL) {
747             AUDIO_FUNC_LOGE("OsalMemCalloc descs is NULL");
748             return HDF_ERR_MALLOC_FAIL;
749         }
750     }
751     *sndCardNum = adapterNum;
752 
753     idx = 0;
754     for (enum SndCardType type = SND_CARD_PRIMARY; type < SND_CARD_MAX; ++type) {
755         for (int32_t i = 0; i < g_alsaAdapterList[type].num; ++i) {
756             (*descs)[idx].adapterName = strdup(g_alsaAdapterList[type].list[i].adapterName);
757             AudioInitPorts(&(*descs)[idx], type);
758             AUDIO_FUNC_LOGI("adapter name : %{public}s", (*descs)[idx].adapterName);
759             idx++;
760         }
761     }
762 
763     return HDF_SUCCESS;
764 }
765 
HdfIoServiceBindName(const char * serviceName)766 struct HdfIoService *HdfIoServiceBindName(const char *serviceName)
767 {
768     (void)serviceName;
769     /* Nothing to do */
770     static struct HdfIoService hdfIoService;
771     return &hdfIoService;
772 }
773 
AudioBindService(const char * name)774 struct DevHandle *AudioBindService(const char *name)
775 {
776     struct DevHandle *handle = NULL;
777 
778     if (name == NULL) {
779         AUDIO_FUNC_LOGE("service name NULL!");
780         return NULL;
781     }
782 
783     handle = (struct DevHandle *)OsalMemCalloc(sizeof(struct DevHandle));
784     if (handle == NULL) {
785         AUDIO_FUNC_LOGE("OsalMemCalloc handle failed!!!");
786         return NULL;
787     }
788 
789     AUDIO_FUNC_LOGI("BIND SERVICE SUCCESS!");
790     return handle;
791 }
792 
AudioCloseService(const struct DevHandle * handle)793 void AudioCloseService(const struct DevHandle *handle)
794 {
795     if (handle != NULL) {
796         AudioMemFree((void **)&handle);
797     }
798 }
799 
SndElementItemInit(struct AlsaMixerCtlElement * m)800 void SndElementItemInit(struct AlsaMixerCtlElement *m)
801 {
802     m->iface = IFACE_MIXER;
803     m->index = -1;
804     m->device = -1;
805     m->subdevice = -1;
806 }
807 
ConvertIfaceType(enum SndIfaceType iface)808 static snd_ctl_elem_iface_t ConvertIfaceType(enum SndIfaceType iface)
809 {
810     snd_ctl_elem_iface_t snd_iface;
811     switch (iface) {
812         case IFACE_CARD:
813             snd_iface = SND_CTL_ELEM_IFACE_CARD;
814             break;
815         case IFACE_MIXER:
816             snd_iface = SND_CTL_ELEM_IFACE_MIXER;
817             break;
818         case IFACE_PCM:
819             snd_iface = SND_CTL_ELEM_IFACE_PCM;
820             break;
821         case IFACE_RAWMIDI:
822             snd_iface = SND_CTL_ELEM_IFACE_RAWMIDI;
823             break;
824         case IFACE_TIMER:
825             snd_iface = SND_CTL_ELEM_IFACE_TIMER;
826             break;
827         case IFACE_SEQUENCER:
828             snd_iface = SND_CTL_ELEM_IFACE_SEQUENCER;
829             break;
830         default:
831             snd_iface = SND_CTL_ELEM_IFACE_MIXER;
832             break;
833     }
834     return snd_iface;
835 }
836 
SetElementInfo(snd_ctl_t * alsaHandle,const struct AlsaMixerCtlElement * ctlElem,snd_ctl_elem_info_t * info,snd_ctl_elem_id_t * id)837 static int32_t SetElementInfo(snd_ctl_t *alsaHandle, const struct AlsaMixerCtlElement *ctlElem,
838     snd_ctl_elem_info_t *info, snd_ctl_elem_id_t *id)
839 {
840     int32_t ret;
841     snd_ctl_elem_iface_t ifaceType;
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     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     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     int ret;
880     snd_ctl_t *alsaHandle = NULL;
881     snd_ctl_elem_id_t *elem_id;
882     snd_ctl_elem_info_t *elem_info;
883     snd_ctl_elem_value_t *elem_value;
884     snd_ctl_elem_type_t type;
885 
886     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
887     CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
888 
889     ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
890     if (ret < 0) {
891         AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
892         return HDF_FAILURE;
893     }
894 
895     snd_ctl_elem_id_alloca(&elem_id);
896     snd_ctl_elem_info_alloca(&elem_info);
897     snd_ctl_elem_value_alloca(&elem_value);
898     ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
899     if (ret != HDF_SUCCESS) {
900         AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
901         return HDF_FAILURE;
902     }
903     snd_ctl_elem_value_set_id(elem_value, elem_id);
904 
905     if (!snd_ctl_elem_info_is_readable(elem_info)) {
906         AUDIO_FUNC_LOGE("Element read enable\n");
907         return HDF_FAILURE;
908     }
909     ret = snd_ctl_elem_read(alsaHandle, elem_value);
910     if (ret < 0) {
911         AUDIO_FUNC_LOGE("Cannot read the given element from elem_value \n");
912         return HDF_FAILURE;
913     }
914 
915     type = snd_ctl_elem_info_get_type(elem_info);
916     if (type == SND_CTL_ELEM_TYPE_INTEGER) {
917         *value = snd_ctl_elem_value_get_integer(elem_value, 0);
918     } else if (type == SND_CTL_ELEM_TYPE_INTEGER64) {
919         *value = (long)snd_ctl_elem_value_get_integer64(elem_value, 0);
920     } else {
921         AUDIO_FUNC_LOGE("Element type is not interger\n");
922         return HDF_FAILURE;
923     }
924 
925     return HDF_SUCCESS;
926 }
927 
SndElementReadEnum(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,unsigned int * item)928 int32_t SndElementReadEnum(
929     struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, unsigned int *item)
930 {
931     int ret;
932     snd_ctl_t *alsaHandle = NULL;
933     snd_ctl_elem_id_t *elem_id;
934     snd_ctl_elem_info_t *elem_info;
935     snd_ctl_elem_value_t *elem_value;
936     snd_ctl_elem_type_t type;
937 
938     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
939     CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
940 
941     ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
942     if (ret < 0) {
943         AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
944         return HDF_FAILURE;
945     }
946 
947     snd_ctl_elem_id_alloca(&elem_id);
948     snd_ctl_elem_info_alloca(&elem_info);
949     snd_ctl_elem_value_alloca(&elem_value);
950     ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
951     if (ret != HDF_SUCCESS) {
952         AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
953         return HDF_FAILURE;
954     }
955     snd_ctl_elem_value_set_id(elem_value, elem_id);
956 
957     if (!snd_ctl_elem_info_is_readable(elem_info)) {
958         AUDIO_FUNC_LOGE("Element read enable\n");
959         return HDF_FAILURE;
960     }
961     ret = snd_ctl_elem_read(alsaHandle, elem_value);
962     if (ret < 0) {
963         AUDIO_FUNC_LOGE("Cannot read the given element from elem_value \n");
964         return HDF_FAILURE;
965     }
966 
967     type = snd_ctl_elem_info_get_type(elem_info);
968     if (type == SND_CTL_ELEM_TYPE_ENUMERATED) {
969         *item = snd_ctl_elem_value_get_enumerated(elem_value, 0);
970     } else {
971         AUDIO_FUNC_LOGE("Element type is not enumerated\n");
972         return HDF_FAILURE;
973     }
974 
975     return HDF_SUCCESS;
976 }
977 
SndElementReadRange(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,long * mix,long * max)978 int32_t SndElementReadRange(
979     struct AlsaSoundCard * cardIns, const struct AlsaMixerCtlElement * ctlElem, long * mix, long * max)
980 {
981     int ret;
982     snd_ctl_t *alsaHandle = NULL;
983     snd_ctl_elem_id_t *elem_id;
984     snd_ctl_elem_info_t *elem_info;
985     snd_ctl_elem_value_t *elem_value;
986     snd_ctl_elem_type_t type;
987 
988     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
989     CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
990 
991     ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
992     if (ret < 0) {
993         AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
994         return HDF_FAILURE;
995     }
996 
997     snd_ctl_elem_id_alloca(&elem_id);
998     snd_ctl_elem_info_alloca(&elem_info);
999     snd_ctl_elem_value_alloca(&elem_value);
1000     ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
1001     if (ret != HDF_SUCCESS) {
1002         AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
1003         return HDF_FAILURE;
1004     }
1005     snd_ctl_elem_value_set_id(elem_value, elem_id);
1006 
1007     if (!snd_ctl_elem_info_is_readable(elem_info)) {
1008         AUDIO_FUNC_LOGE("Element read enable\n");
1009         return HDF_FAILURE;
1010     }
1011     ret = snd_ctl_elem_read(alsaHandle, elem_value);
1012     if (ret < 0) {
1013         AUDIO_FUNC_LOGE("Cannot read the given element from elem_value \n");
1014         return HDF_FAILURE;
1015     }
1016 
1017     type = snd_ctl_elem_info_get_type(elem_info);
1018     if (type == SND_CTL_ELEM_TYPE_INTEGER) {
1019         *mix = snd_ctl_elem_info_get_min(elem_info);
1020         *max = snd_ctl_elem_info_get_max(elem_info);
1021     } else if (type == SND_CTL_ELEM_TYPE_INTEGER64) {
1022         *mix = (long)snd_ctl_elem_info_get_min64(elem_info);
1023         *max = (long)snd_ctl_elem_info_get_max64(elem_info);
1024     } else {
1025         AUDIO_FUNC_LOGE("Element value is not integer type!\n");
1026         return HDF_FAILURE;
1027     }
1028 
1029     return HDF_SUCCESS;
1030 }
1031 
SndElementReadSwitch(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,bool * on)1032 int32_t SndElementReadSwitch(
1033     struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, bool *on)
1034 {
1035     int ret;
1036     snd_ctl_t *alsaHandle = NULL;
1037     snd_ctl_elem_id_t *elem_id;
1038     snd_ctl_elem_info_t *elem_info;
1039     snd_ctl_elem_value_t *elem_value;
1040     snd_ctl_elem_type_t type;
1041 
1042     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1043     CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
1044 
1045     ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
1046     if (ret < 0) {
1047         AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
1048         return HDF_FAILURE;
1049     }
1050 
1051     snd_ctl_elem_id_alloca(&elem_id);
1052     snd_ctl_elem_info_alloca(&elem_info);
1053     snd_ctl_elem_value_alloca(&elem_value);
1054     ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
1055     if (ret != HDF_SUCCESS) {
1056         AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
1057         return HDF_FAILURE;
1058     }
1059     snd_ctl_elem_value_set_id(elem_value, elem_id);
1060 
1061     if (!snd_ctl_elem_info_is_readable(elem_info)) {
1062         AUDIO_FUNC_LOGE("Element read enable\n");
1063         return HDF_FAILURE;
1064     }
1065     ret = snd_ctl_elem_read(alsaHandle, elem_value);
1066     if (ret < 0) {
1067         AUDIO_FUNC_LOGE("Cannot read the given element from elem_value \n");
1068         return HDF_FAILURE;
1069     }
1070 
1071     type = snd_ctl_elem_info_get_type(elem_info);
1072     if (type == SND_CTL_ELEM_TYPE_BOOLEAN) {
1073         ret = snd_ctl_elem_value_get_boolean(elem_value, 0);
1074         *on = (ret > 0) ? true : false;
1075     } else {
1076         AUDIO_FUNC_LOGE("Element type is not boolean\n");
1077         return HDF_FAILURE;
1078     }
1079 
1080     return HDF_SUCCESS;
1081 }
1082 
SndElementWriteInt(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,long value)1083 int32_t SndElementWriteInt(
1084     struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, long value)
1085 {
1086     int ret;
1087     snd_ctl_t *alsaHandle = NULL;
1088     snd_ctl_elem_id_t *elem_id;
1089     snd_ctl_elem_info_t *elem_info;
1090     snd_ctl_elem_value_t *elem_value;
1091     snd_ctl_elem_type_t type;
1092 
1093     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1094     CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
1095 
1096     ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
1097     if (ret < 0) {
1098         AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
1099         return HDF_FAILURE;
1100     }
1101 
1102     snd_ctl_elem_id_alloca(&elem_id);
1103     snd_ctl_elem_info_alloca(&elem_info);
1104     snd_ctl_elem_value_alloca(&elem_value);
1105     ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
1106     if (ret != HDF_SUCCESS) {
1107         AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
1108         return HDF_FAILURE;
1109     }
1110 
1111     if (!snd_ctl_elem_info_is_writable(elem_info)) {
1112         AUDIO_FUNC_LOGE("Element write enable\n");
1113         return HDF_FAILURE;
1114     }
1115 
1116     snd_ctl_elem_value_set_id(elem_value, elem_id);
1117     type = snd_ctl_elem_info_get_type(elem_info);
1118     if (type == SND_CTL_ELEM_TYPE_INTEGER) {
1119         snd_ctl_elem_value_set_integer(elem_value, 0, value);
1120     } else if (type == SND_CTL_ELEM_TYPE_INTEGER64) {
1121         snd_ctl_elem_value_set_integer64(elem_value, 0, (long long)value);
1122     } else {
1123         AUDIO_FUNC_LOGE("Element value is not integer type!\n");
1124         return HDF_FAILURE;
1125     }
1126 
1127     ret = snd_ctl_elem_write(alsaHandle, elem_value);
1128     if (ret < 0) {
1129         AUDIO_FUNC_LOGE("snd_ctl_elem_write failed!\n");
1130         return HDF_FAILURE;
1131     }
1132 
1133     return HDF_SUCCESS;
1134 }
1135 
SndElementWriteEnum(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,unsigned int item)1136 int32_t SndElementWriteEnum(
1137     struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, unsigned int item)
1138 {
1139     int ret;
1140     snd_ctl_t *alsaHandle = NULL;
1141     snd_ctl_elem_id_t *elem_id;
1142     snd_ctl_elem_info_t *elem_info;
1143     snd_ctl_elem_value_t *elem_value;
1144     snd_ctl_elem_type_t type;
1145 
1146     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1147     CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
1148 
1149     ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
1150     if (ret < 0) {
1151         AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
1152         return HDF_FAILURE;
1153     }
1154 
1155     snd_ctl_elem_id_alloca(&elem_id);
1156     snd_ctl_elem_info_alloca(&elem_info);
1157     snd_ctl_elem_value_alloca(&elem_value);
1158     ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
1159     if (ret != HDF_SUCCESS) {
1160         AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
1161         return HDF_FAILURE;
1162     }
1163 
1164     if (!snd_ctl_elem_info_is_writable(elem_info)) {
1165         AUDIO_FUNC_LOGE("Element write enable\n");
1166         return HDF_FAILURE;
1167     }
1168 
1169     snd_ctl_elem_value_set_id(elem_value, elem_id);
1170     type = snd_ctl_elem_info_get_type(elem_info);
1171     if (type == SND_CTL_ELEM_TYPE_ENUMERATED) {
1172         snd_ctl_elem_value_set_enumerated(elem_value, 0, item);
1173     } else {
1174         AUDIO_FUNC_LOGE("Element value is not enum type!\n");
1175         return HDF_FAILURE;
1176     }
1177 
1178     ret = snd_ctl_elem_write(alsaHandle, elem_value);
1179     if (ret < 0) {
1180         AUDIO_FUNC_LOGE("snd_ctl_elem_write failed!\n");
1181         return HDF_FAILURE;
1182     }
1183 
1184     return HDF_SUCCESS;
1185 }
1186 
SndElementWriteSwitch(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem,bool on)1187 int32_t SndElementWriteSwitch(
1188     struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem, bool on)
1189 {
1190     int ret;
1191     int value;
1192     snd_ctl_t *alsaHandle = NULL;
1193     snd_ctl_elem_id_t *elem_id;
1194     snd_ctl_elem_info_t *elem_info;
1195     snd_ctl_elem_value_t *elem_value;
1196     snd_ctl_elem_type_t type;
1197 
1198     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1199     CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
1200 
1201     ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
1202     if (ret < 0) {
1203         AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
1204         return HDF_FAILURE;
1205     }
1206 
1207     snd_ctl_elem_id_alloca(&elem_id);
1208     snd_ctl_elem_info_alloca(&elem_info);
1209     snd_ctl_elem_value_alloca(&elem_value);
1210     ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
1211     if (ret != HDF_SUCCESS) {
1212         AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
1213         return HDF_FAILURE;
1214     }
1215 
1216     if (!snd_ctl_elem_info_is_writable(elem_info)) {
1217         AUDIO_FUNC_LOGE("Element write enable\n");
1218         return HDF_FAILURE;
1219     }
1220 
1221     snd_ctl_elem_value_set_id(elem_value, elem_id);
1222     type = snd_ctl_elem_info_get_type(elem_info);
1223     if (type == SND_CTL_ELEM_TYPE_BOOLEAN) {
1224         value = on ? 1 : 0;
1225         snd_ctl_elem_value_set_boolean(elem_value, 0, value);
1226     } else {
1227         AUDIO_FUNC_LOGE("Element value is not boolean type!\n");
1228         return HDF_FAILURE;
1229     }
1230 
1231     ret = snd_ctl_elem_write(alsaHandle, elem_value);
1232     if (ret < 0) {
1233         AUDIO_FUNC_LOGE("snd_ctl_elem_write failed!\n");
1234         return HDF_FAILURE;
1235     }
1236 
1237     return HDF_SUCCESS;
1238 }
1239 
SndElementWrite(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * ctlElem)1240 int32_t SndElementWrite(
1241     struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement *ctlElem)
1242 {
1243     int ret;
1244     snd_ctl_t *alsaHandle = NULL;
1245     snd_ctl_elem_id_t *elem_id;
1246     snd_ctl_elem_info_t *elem_info;
1247     snd_ctl_elem_value_t *elem_value;
1248 
1249     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1250     CHECK_NULL_PTR_RETURN_DEFAULT(ctlElem);
1251 
1252     ret = snd_ctl_open(&alsaHandle, cardIns->ctrlName, 0);
1253     if (ret < 0) {
1254         AUDIO_FUNC_LOGE("snd_ctl_open error: %{public}s", snd_strerror(ret));
1255         return HDF_FAILURE;
1256     }
1257 
1258     snd_ctl_elem_id_alloca(&elem_id);
1259     snd_ctl_elem_info_alloca(&elem_info);
1260     snd_ctl_elem_value_alloca(&elem_value);
1261     ret = SetElementInfo(alsaHandle, ctlElem, elem_info, elem_id);
1262     if (ret != HDF_SUCCESS) {
1263         AUDIO_FUNC_LOGE("Set element %{public}s elem_info failed!\n", ctlElem->name);
1264         return HDF_FAILURE;
1265     }
1266 
1267     if (!snd_ctl_elem_info_is_writable(elem_info)) {
1268         AUDIO_FUNC_LOGE("Element write enable\n");
1269         return HDF_FAILURE;
1270     }
1271 
1272     snd_ctl_elem_value_set_id(elem_value, elem_id);
1273     ret = snd_ctl_ascii_value_parse(alsaHandle, elem_value, elem_info, ctlElem->value);
1274     if (ret < 0) {
1275         AUDIO_FUNC_LOGE("Control parse error: %s\n", snd_strerror(ret));
1276         return HDF_FAILURE;
1277     }
1278     ret = snd_ctl_elem_write(alsaHandle, elem_value);
1279     if (ret < 0) {
1280         AUDIO_FUNC_LOGE("Control element write error: %s\n", snd_strerror(ret));
1281         return HDF_FAILURE;
1282     }
1283 
1284     return HDF_SUCCESS;
1285 }
1286 
SndElementGroupWrite(struct AlsaSoundCard * cardIns,const struct AlsaMixerCtlElement * elemGroup,int32_t groupSize)1287 int32_t SndElementGroupWrite(
1288     struct AlsaSoundCard *cardIns, const struct AlsaMixerCtlElement* elemGroup, int32_t groupSize)
1289 {
1290     int err;
1291     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1292 
1293     for (int i = 0; i < groupSize; ++i) {
1294         err = SndElementWrite(cardIns, &elemGroup[i]);
1295         if (err < 0) {
1296             AUDIO_FUNC_LOGE("Cant't set element %{public}s", elemGroup[i].name);
1297         }
1298     }
1299 
1300     return HDF_SUCCESS;
1301 }
1302 
SndTraversalMixerElement(struct AlsaSoundCard * cardIns,bool (* callback)(void * data,snd_ctl_elem_id_t * elem_id),void * data)1303 int32_t SndTraversalMixerElement(struct AlsaSoundCard *cardIns,
1304     bool (*callback)(void *data, snd_ctl_elem_id_t *elem_id), void *data)
1305 {
1306     int ret;
1307     snd_hctl_t *handle;
1308     snd_hctl_elem_t *elem;
1309     snd_ctl_elem_id_t *elem_id;
1310     snd_ctl_elem_info_t *elem_info;
1311     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
1312     CHECK_NULL_PTR_RETURN_DEFAULT(callback);
1313 
1314     ret = snd_hctl_open(&handle, cardIns->ctrlName, 0);
1315     if (ret < 0) {
1316         AUDIO_FUNC_LOGE("Control %{public}s open error: %{public}s",
1317             cardIns->ctrlName, snd_strerror(ret));
1318         return HDF_FAILURE;
1319     }
1320     ret = snd_hctl_load(handle);
1321     if (ret < 0) {
1322         AUDIO_FUNC_LOGE("Control %{public}s local error: %{public}s\n",
1323             cardIns->ctrlName, snd_strerror(ret));
1324         return HDF_FAILURE;
1325     }
1326 
1327     snd_ctl_elem_id_alloca(&elem_id);
1328     snd_ctl_elem_info_alloca(&elem_info);
1329     for (elem = snd_hctl_first_elem(handle); elem; elem = snd_hctl_elem_next(elem)) {
1330         ret = snd_hctl_elem_info(elem, elem_info);
1331         if (ret < 0) {
1332             AUDIO_FUNC_LOGE("Control %{public}s snd_hctl_elem_info error: %{public}s\n",
1333                 cardIns->ctrlName, snd_strerror(ret));
1334             return HDF_FAILURE;
1335         }
1336         if (snd_ctl_elem_info_is_inactive(elem_info)) {
1337             continue;
1338         }
1339         snd_hctl_elem_get_id(elem, elem_id);
1340         if (callback(data, elem_id)) {
1341             (void)snd_hctl_close(handle);
1342             return HDF_SUCCESS;
1343         }
1344     }
1345     (void)snd_hctl_close(handle);
1346     return HDF_FAILURE;
1347 }
1348