1 /*
2  * Copyright (c) 2021-2023 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 "audio_interface_lib_common.h"
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include "audio_common.h"
22 #include "audio_if_lib_render.h"
23 #include "audio_uhdf_log.h"
24 #include "hdf_io_service_if.h"
25 #include "hdf_sbuf.h"
26 #include "osal_mem.h"
27 #include "securec.h"
28 
29 #define HDF_LOG_TAG HDF_AUDIO_HAL_LIB
30 
31 #define ADAPTER_PORT_ID_MSB        10
32 #define ADAPTER_NAME_SUFFIX        2
33 #define SUPPORT_CAPTURE_OR_RENDER  1
34 #define SUPPORT_CAPTURE_AND_RENDER 2
35 
36 #define DECADE 10
37 
38 #define PORTNUM_FIRST  1
39 #define PORTNUM_SECOND 2
40 
41 static int32_t AudioMixerCtlElemList(AudioPcmType pcm, OpCode cmd, const struct HdfIoService *service, void *data);
42 static int32_t AudioMixerCtlGetElemProp(AudioPcmType pcm, OpCode cmd, const struct HdfIoService *service, void *data);
43 static int32_t AudioMixerCtlSetElemProp(AudioPcmType pcm, OpCode cmd, const struct HdfIoService *service, void *data);
44 static int32_t AudioGetAllCardList(AudioPcmType pcm, OpCode cmd, const struct HdfIoService *service, void *data);
45 
46 static struct AudioMixerOps g_AudioMixerOpsTbl[] = {
47     {MIXER_CTL_IOCTL_ELEM_INFO,     NULL                    },
48     {MIXER_CTL_IOCTL_ELEM_READ,     NULL                    },
49     {MIXER_CTL_IOCTL_ELEM_WRITE,    NULL                    },
50     {MIXER_CTL_IOCTL_ELEM_LIST,     AudioMixerCtlElemList   },
51     {MIXER_CTL_IOCTL_ELEM_GET_PROP, AudioMixerCtlGetElemProp},
52     {MIXER_CTL_IOCTL_ELEM_SET_PROP, AudioMixerCtlSetElemProp},
53     {MIXER_CTL_IOCTL_GET_CARDS,     AudioGetAllCardList     },
54     {MIXER_CTL_IOCTL_GET_CHMAP,     NULL                    },
55     {MIXER_CTL_IOCTL_SET_CHMAP,     NULL                    },
56     {MIXER_CTL_IOCTL_BUTT,          NULL                    },
57 };
58 
AudioCheckServiceIsAvailable(const struct HdfIoService * service)59 static bool AudioCheckServiceIsAvailable(const struct HdfIoService *service)
60 {
61     if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
62         AUDIO_FUNC_LOGE("Invalid service handle!");
63         return false;
64     }
65 
66     return true;
67 }
68 
HdfIoServiceBindName(const char * serviceName)69 struct HdfIoService *HdfIoServiceBindName(const char *serviceName)
70 {
71     uint32_t i;
72 
73     if (serviceName == NULL) {
74         AUDIO_FUNC_LOGE("service name NULL!");
75         return NULL;
76     }
77 
78     static const char *serviceNameList [] = {
79         "hdf_audio_control",
80         "hdf_audio_render",
81         "hdf_audio_capture"
82     };
83 
84     for (i = 0; i < (uint32_t)HDF_ARRAY_SIZE(serviceNameList); i++) {
85         if (strcmp(serviceName, serviceNameList[i]) == 0) {
86             return HdfIoServiceBind(serviceName);
87         }
88     }
89     AUDIO_FUNC_LOGE("service name not support!");
90 
91     return NULL;
92 }
93 
AudioGetElemValue(struct HdfSBuf * reply,struct AudioCtrlElemInfo * volThreshold)94 int32_t AudioGetElemValue(struct HdfSBuf *reply, struct AudioCtrlElemInfo *volThreshold)
95 {
96     if (reply == NULL || volThreshold == NULL) {
97         AUDIO_FUNC_LOGE("reply or volThreshold is null!");
98         return HDF_FAILURE;
99     }
100     if (!HdfSbufReadInt32(reply, &volThreshold->type)) {
101         AUDIO_FUNC_LOGE("Failed to Get volThreshold->type!");
102         return HDF_FAILURE;
103     }
104     if (!HdfSbufReadInt32(reply, &volThreshold->max)) {
105         AUDIO_FUNC_LOGE("Failed to Get volThreshold->max!");
106         return HDF_FAILURE;
107     }
108     if (!HdfSbufReadInt32(reply, &volThreshold->min)) {
109         AUDIO_FUNC_LOGE("Failed to Get volThreshold->min!");
110         return HDF_FAILURE;
111     }
112     return HDF_SUCCESS;
113 }
114 
AudioFreeHdfSBuf(struct HdfSBuf * sBuf,struct HdfSBuf * reply)115 void AudioFreeHdfSBuf(struct HdfSBuf *sBuf, struct HdfSBuf *reply)
116 {
117     if (sBuf != NULL) {
118         HdfSbufRecycle(sBuf);
119         sBuf = NULL;
120     }
121 
122     if (reply != NULL) {
123         HdfSbufRecycle(reply);
124         reply = NULL;
125     }
126 }
127 
AudioServiceDispatch(void * obj,int cmdId,struct HdfSBuf * sBuf,struct HdfSBuf * reply)128 int32_t AudioServiceDispatch(void *obj, int cmdId, struct HdfSBuf *sBuf, struct HdfSBuf *reply)
129 {
130     struct HdfIoService *service = obj;
131 
132     if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
133         AUDIO_FUNC_LOGE("param is null!");
134         return HDF_FAILURE;
135     }
136 
137     return service->dispatcher->Dispatch(&(service->object), cmdId, sBuf, reply);
138 }
139 
AudioSetElemValue(struct HdfSBuf * sBuf,const struct AudioCtlElemValue * elemValue,bool isSendData)140 int32_t AudioSetElemValue(struct HdfSBuf *sBuf, const struct AudioCtlElemValue *elemValue, bool isSendData)
141 {
142     if (sBuf == NULL || elemValue == NULL) {
143         AUDIO_FUNC_LOGE("param is empty!");
144         return HDF_ERR_INVALID_PARAM;
145     }
146 
147     if (isSendData) {
148         if (!HdfSbufWriteInt32(sBuf, elemValue->value[0])) {
149             AUDIO_FUNC_LOGE("SetVolumeSBuf value[0] Write Fail!");
150             return HDF_FAILURE;
151         }
152     }
153 
154     if (!HdfSbufWriteInt32(sBuf, elemValue->id.iface)) {
155         AUDIO_FUNC_LOGE("GetVolumeSBuf iface Write Fail!");
156         return HDF_FAILURE;
157     }
158 
159     if (!HdfSbufWriteString(sBuf, elemValue->id.cardServiceName)) {
160         AUDIO_FUNC_LOGE("GetVolumeSBuf cardServiceName Write Fail!");
161         return HDF_FAILURE;
162     }
163 
164     if (!HdfSbufWriteString(sBuf, elemValue->id.itemName)) {
165         AUDIO_FUNC_LOGE("GetVolumeSBuf itemName Write Fail!");
166         return HDF_FAILURE;
167     }
168 
169     return HDF_SUCCESS;
170 }
171 
AudioAllocHdfSBuf(struct HdfSBuf ** reply,struct HdfSBuf ** sBuf)172 int32_t AudioAllocHdfSBuf(struct HdfSBuf **reply, struct HdfSBuf **sBuf)
173 {
174     if (reply == NULL || sBuf == NULL) {
175         AUDIO_FUNC_LOGE("param is empty!");
176         return HDF_ERR_INVALID_PARAM;
177     }
178 
179     *sBuf = HdfSbufObtainDefaultSize();
180     if (*sBuf == NULL) {
181         AUDIO_FUNC_LOGE("GetVolume Failed to obtain sBuf");
182         return HDF_FAILURE;
183     }
184 
185     *reply = HdfSbufObtainDefaultSize();
186     if (*reply == NULL) {
187         AUDIO_FUNC_LOGE("Failed to obtain reply");
188         AudioFreeHdfSBuf(*sBuf, NULL);
189         return HDF_FAILURE;
190     }
191 
192     return HDF_SUCCESS;
193 }
194 
AudioBindServiceObject(struct DevHandle * const handle,const char * name)195 static struct DevHandle *AudioBindServiceObject(struct DevHandle * const handle, const char *name)
196 {
197     if (handle == NULL || name == NULL) {
198         AUDIO_FUNC_LOGE("service name or handle is NULL!");
199         return NULL;
200     }
201 
202     char *serviceName = (char *)OsalMemCalloc(NAME_LEN);
203     if (serviceName == NULL) {
204         AUDIO_FUNC_LOGE("Failed to alloc serviceName");
205         AudioMemFree((void **)&handle);
206         return NULL;
207     }
208 
209     int ret = snprintf_s(serviceName, NAME_LEN - 1, SERVIC_NAME_MAX_LEN + 1, "hdf_audio_%s", name);
210     if (ret < 0) {
211         AUDIO_FUNC_LOGE("Failed to snprintf_s");
212         AudioMemFree((void **)&serviceName);
213         AudioMemFree((void **)&handle);
214         return NULL;
215     }
216 
217     struct HdfIoService *service = HdfIoServiceBindName(serviceName);
218     if (service == NULL) {
219         AUDIO_FUNC_LOGE("Failed to get service!");
220         AudioMemFree((void **)&serviceName);
221         AudioMemFree((void **)&handle);
222         return NULL;
223     }
224 
225     AudioMemFree((void **)&serviceName);
226     handle->object = service;
227     return handle->object;
228 }
229 
AudioBindService(const char * name)230 struct DevHandle *AudioBindService(const char *name)
231 {
232     struct DevHandle *handle = NULL;
233     struct DevHandle *object = NULL;
234     if (name == NULL) {
235         AUDIO_FUNC_LOGE("service name NULL!");
236         return NULL;
237     }
238 
239     handle = (struct DevHandle *)OsalMemCalloc(sizeof(struct DevHandle));
240     if (handle == NULL) {
241         AUDIO_FUNC_LOGE("Failed to alloc handle");
242         return NULL;
243     }
244 
245     object = AudioBindServiceObject(handle, name);
246     if (object != NULL) {
247         handle->object = object;
248     } else {
249         AUDIO_FUNC_LOGE("handle->object is NULL!");
250         return NULL;
251     }
252     AUDIO_FUNC_LOGI("BIND SERVICE SUCCESS!");
253     return handle;
254 }
255 
AudioCloseService(const struct DevHandle * handle)256 void AudioCloseService(const struct DevHandle *handle)
257 {
258     AUDIO_FUNC_LOGI();
259     if (handle == NULL || handle->object == NULL) {
260         AUDIO_FUNC_LOGE("Capture handle or handle->object is NULL");
261         return;
262     }
263     struct HdfIoService *service = (struct HdfIoService *)handle->object;
264     HdfIoServiceRecycle(service);
265     AudioMemFree((void **)&handle);
266     return;
267 }
268 
AudioCardParsePortId(const char * name)269 static int8_t AudioCardParsePortId(const char *name)
270 {
271     if (name == NULL) {
272         AUDIO_FUNC_LOGE("adapterName is null");
273         return HDF_FAILURE;
274     }
275 
276     uint8_t i = 0;
277     uint8_t portId = 0;
278     size_t nameLen = strlen(name);
279 
280     for (i = PORTNUM_SECOND; i > 0; i--) {
281         if (name[nameLen - i] > '9' || name[nameLen - i] < '0') {
282             continue;
283         }
284 
285         portId += (name[nameLen - i] - '0') * ((i - 1) ? DECADE : 1);
286     }
287 
288     return portId;
289 }
290 
AudioCardNameTransform(const char * name,int8_t * portId)291 static char *AudioCardNameTransform(const char *name, int8_t *portId)
292 {
293     if (name == NULL) {
294         AUDIO_FUNC_LOGE("adapterName is null");
295         return NULL;
296     }
297 
298     *portId = AudioCardParsePortId(name);
299     if (*portId < 0) {
300         AUDIO_FUNC_LOGE("AudioCardParsePortId failed");
301         return NULL;
302     }
303 
304     if (strstr(name, "primary") != NULL) {
305         return strdup("primary");
306     } else if (strstr(name, "hdmi") != NULL) {
307         return strdup("hdmi");
308     } else if (strstr(name, "usb") != NULL) {
309         return strdup("usb");
310     } else {
311         AUDIO_FUNC_LOGI("audio card fail to identify");
312         return NULL;
313     }
314 }
315 
AudioReadCardPortToDesc(struct HdfSBuf * reply,struct AudioAdapterDescriptor * desc,int8_t portId)316 static int32_t AudioReadCardPortToDesc(struct HdfSBuf *reply, struct AudioAdapterDescriptor *desc, int8_t portId)
317 {
318     uint8_t portNum = 0;
319 
320     if (desc == NULL) {
321         AUDIO_FUNC_LOGE("descs is null!");
322         return HDF_ERR_INVALID_PARAM;
323     }
324 
325     if (!HdfSbufReadUint8(reply, &portNum)) {
326         AUDIO_FUNC_LOGE("read portNum failed!");
327         return HDF_FAILURE;
328     }
329 
330     if (portNum == PORT_IN || portNum == PORT_OUT) {
331         portNum = PORTNUM_FIRST; // support capture | render
332     } else if (portNum == PORT_OUT_IN) {
333         portNum = PORTNUM_SECOND; // support capture & render
334     } else {
335         AUDIO_FUNC_LOGE("portNum value failed!");
336         return HDF_FAILURE;
337     }
338 
339 #ifndef AUDIO_HDI_SERVICE_MODE
340     desc->portNum = portNum;
341 #else
342     desc->portsLen = portNum;
343 #endif
344 
345     desc->ports = (struct AudioPort *)OsalMemCalloc(sizeof(struct AudioPort) * portNum);
346     if (desc->ports == NULL) {
347         AUDIO_FUNC_LOGE("OsalMemCalloc failed!");
348         return HDF_FAILURE;
349     }
350 
351     for (uint32_t i = 0; i < portNum; i++) {
352         if (!HdfSbufReadUint8(reply, (uint8_t *)&desc->ports[i].dir)) {
353             AUDIO_FUNC_LOGE("read dir failed!");
354             AudioMemFree((void **)&desc->ports);
355             return HDF_FAILURE;
356         }
357 
358         if (desc->ports[i].dir == PORT_IN) {
359             desc->ports[i].portName = strdup("AIP");
360         } else if (desc->ports[i].dir == PORT_OUT) {
361             desc->ports[i].portName = strdup("AOP");
362         } else if (desc->ports[i].dir == PORT_OUT_IN) {
363             desc->ports[i].portName = strdup("AOIP");
364         } else {
365             AudioMemFree((void **)&desc->ports);
366             AUDIO_FUNC_LOGE("desc->ports[i].dir = %{public}d", desc->ports[i].dir);
367             return HDF_FAILURE;
368         }
369         desc->ports[i].portId = portId;
370     }
371 
372     return HDF_SUCCESS;
373 }
374 
AudioPortNameFree(struct AudioPort * dataBlock,uint32_t portsLen)375 static void AudioPortNameFree(struct AudioPort *dataBlock, uint32_t portsLen)
376 {
377     if (dataBlock == NULL) {
378         return;
379     }
380 
381     for (uint32_t i = 0; i < portsLen; i++) {
382         OsalMemFree((void *)dataBlock[i].portName);
383         dataBlock[i].portName = NULL;
384     }
385     OsalMemFree(dataBlock);
386 }
387 
AudioFreeDesc(struct AudioAdapterDescriptor ** descs,uint32_t sndCardNum)388 static void AudioFreeDesc(struct AudioAdapterDescriptor **descs, uint32_t sndCardNum)
389 {
390     if (descs == NULL || *descs == NULL) {
391         AUDIO_FUNC_LOGE("AudioFreeDesc failed!");
392         return;
393     }
394 
395     for (uint32_t index = 0; index < sndCardNum; index++) {
396         if ((*descs)[index].adapterName != NULL) {
397             AudioMemFree((void **)&((*descs)[index].adapterName));
398             (*descs)[index].adapterName = NULL;
399         }
400 #ifndef AUDIO_HDI_SERVICE_MODE
401         AudioPortNameFree((*descs)[index].ports, (*descs)[index].portNum);
402 #else
403         AudioPortNameFree((*descs)[index].ports, (*descs)[index].portsLen);
404 #endif
405     }
406     AudioMemFree((void **)descs);
407 }
408 
AudioReadCardInfoToDesc(struct HdfSBuf * reply,struct AudioAdapterDescriptor ** descs,int * sndCardNum)409 static int32_t AudioReadCardInfoToDesc(struct HdfSBuf *reply, struct AudioAdapterDescriptor **descs, int *sndCardNum)
410 {
411     int32_t index = 0;
412     int8_t portId = 0;
413 
414     if (!HdfSbufReadInt32(reply, sndCardNum)) {
415         AUDIO_FUNC_LOGE("read snd card num failed!");
416         return HDF_FAILURE;
417     }
418 
419     if (*descs == NULL) {
420         AUDIO_FUNC_LOGI("*descs is NULL");
421         *descs = (struct AudioAdapterDescriptor *)OsalMemCalloc(sizeof(struct AudioAdapterDescriptor) * (*sndCardNum));
422         if (*descs == NULL) {
423             AUDIO_FUNC_LOGE("OsalMemCalloc descs is NULL");
424             return HDF_FAILURE;
425         }
426     }
427 
428     // Make sure the primary sound card is on the front
429     for (index = (*sndCardNum - 1); index >= 0; index--) {
430         (*descs)[index].adapterName = AudioCardNameTransform(HdfSbufReadString(reply), &portId);
431         if ((*descs)[index].adapterName == NULL) {
432             AudioFreeDesc(descs, *sndCardNum);
433             return HDF_FAILURE;
434         }
435 
436         if (AudioReadCardPortToDesc(reply, &(*descs)[index], portId) != HDF_SUCCESS) {
437             AUDIO_FUNC_LOGE("read port failed!");
438             AudioFreeDesc(descs, *sndCardNum);
439             return HDF_FAILURE;
440         }
441     }
442 
443     return HDF_SUCCESS;
444 }
445 
AudioGetAllCardInfo(struct AudioAdapterDescriptor ** descs,int32_t * sndCardNum)446 int32_t AudioGetAllCardInfo(struct AudioAdapterDescriptor **descs, int32_t *sndCardNum)
447 {
448     if (descs == NULL || sndCardNum == NULL) {
449         return HDF_FAILURE;
450     }
451 
452     struct DevHandle *handle = AudioBindService(CTRL_CMD);
453     if (handle == NULL) {
454         AUDIO_FUNC_LOGE("AudioBindService failed!");
455         return HDF_FAILURE;
456     }
457 
458     struct HdfSBuf *reply = HdfSbufObtainDefaultSize();
459     if (reply == NULL) {
460         AudioCloseService(handle);
461         AUDIO_FUNC_LOGE("HdfSbufObtainDefaultSize failed!");
462         return HDF_FAILURE;
463     }
464 
465     if (AudioServiceDispatch(handle->object, AUDIODRV_CTL_IOCTL_ELEM_CARD - CTRL_NUM, NULL, reply) != HDF_SUCCESS) {
466         AUDIO_FUNC_LOGE("GetAllCardInfo Failed to send service call!");
467         AudioFreeHdfSBuf(reply, NULL);
468         AudioCloseService(handle);
469         return HDF_FAILURE;
470     }
471 
472     if (AudioReadCardInfoToDesc(reply, descs, sndCardNum) != HDF_SUCCESS) {
473         AudioFreeHdfSBuf(reply, NULL);
474         AudioCloseService(handle);
475         return HDF_FAILURE;
476     }
477 
478     HdfSbufRecycle(reply);
479     AudioCloseService(handle);
480     return HDF_SUCCESS;
481 }
482 
AudioCloseServiceSub(struct HdfIoService * service)483 void AudioCloseServiceSub(struct HdfIoService *service)
484 {
485     if (service != NULL) {
486         HdfIoServiceRecycle(service);
487     }
488 }
489 
AudioCtlElemRealDataSpace(struct AudioCtlElemList * eList)490 static int32_t AudioCtlElemRealDataSpace(struct AudioCtlElemList *eList)
491 {
492     int32_t ret;
493     size_t dataSize = eList->count * sizeof(struct AudioHwCtlElemId);
494 
495     struct AudioHwCtlElemId *ctlElemListAddr = OsalMemCalloc(dataSize);
496     if (ctlElemListAddr == NULL) {
497         AUDIO_FUNC_LOGE("Out of memory!");
498         return HDF_FAILURE;
499     }
500 
501     ret = memcpy_s(ctlElemListAddr, dataSize, eList->ctlElemListAddr, dataSize);
502     if (ret != EOK) {
503         AUDIO_FUNC_LOGE("Failed to copy data.!");
504         AudioMemFree((void **)&ctlElemListAddr);
505         return HDF_FAILURE;
506     }
507     AudioMemFree((void **)&eList->ctlElemListAddr);
508     eList->ctlElemListAddr = ctlElemListAddr;
509     eList->space = eList->count;
510 
511     return HDF_SUCCESS;
512 }
513 
AudioCtlElemParseData(struct AudioCtlElemList * eList,struct HdfSBuf * reply)514 static int32_t AudioCtlElemParseData(struct AudioCtlElemList *eList, struct HdfSBuf *reply)
515 {
516     int32_t ret;
517     uint32_t countTmp = 0;
518     uint32_t spaceTmp = 0;
519 
520     const char *sndSvcName = HdfSbufReadString(reply);
521     if (sndSvcName == NULL) {
522         AUDIO_FUNC_LOGE("Failed to parse the cardServiceName!");
523         return HDF_FAILURE;
524     }
525     if (strcmp(eList->cardSrvName, sndSvcName) != 0) {
526         AUDIO_FUNC_LOGE("The service name does not match!");
527         return HDF_FAILURE;
528     }
529 
530     if (!HdfSbufReadUint32(reply, &countTmp)) {
531         AUDIO_FUNC_LOGE("Failed to parse the count!");
532         return HDF_FAILURE;
533     }
534     if (countTmp == 0) {
535         AUDIO_FUNC_LOGE("Can't find the element because count == 0!");
536         return HDF_FAILURE;
537     }
538 
539     if (!HdfSbufReadUint32(reply, &spaceTmp)) {
540         AUDIO_FUNC_LOGE("Failed to parse the space!");
541         return HDF_FAILURE;
542     }
543     if (eList->space != spaceTmp || spaceTmp <= countTmp) {
544         AUDIO_FUNC_LOGE("The data space does not match!");
545         return HDF_FAILURE;
546     }
547     eList->count = countTmp;
548 
549     /* Space is allocated based on actual data */
550     ret = AudioCtlElemRealDataSpace(eList);
551     if (ret != HDF_SUCCESS) {
552         return ret;
553     }
554 
555     return HDF_SUCCESS;
556 }
557 
AudioRenderCtlCmdId2String(int cmdId)558 static const char *AudioRenderCtlCmdId2String(int cmdId)
559 {
560     static const char *audioRenderCtlCmdString[] = {
561         "MIXER_CTL_IOCTL_ELEM_INFO",
562         "MIXER_CTL_IOCTL_ELEM_READ",
563         "MIXER_CTL_IOCTL_ELEM_WRITE",
564         "MIXER_CTL_IOCTL_ELEM_LIST",
565         "MIXER_CTL_IOCTL_ELEM_GET_PROP",
566         "MIXER_CTL_IOCTL_ELEM_SET_PROP",
567         "MIXER_CTL_IOCTL_GET_CARDS",
568         "MIXER_CTL_IOCTL_GET_CHMAP",
569         "MIXER_CTL_IOCTL_SET_CHMAP"
570     };
571 
572     if (cmdId < MIXER_CTL_IOCTL_ELEM_INFO || cmdId > MIXER_CTL_IOCTL_SET_CHMAP) {
573         AUDIO_FUNC_LOGE("cmdId Not Supported!");
574         return "Not found!";
575     }
576 
577     return audioRenderCtlCmdString[cmdId - MIXER_CTL_IOCTL_ELEM_INFO];
578 }
579 
AudioCtlGetElemList(const struct HdfIoService * service,struct AudioCtlElemList * eList,int cmdId)580 static int32_t AudioCtlGetElemList(const struct HdfIoService *service, struct AudioCtlElemList *eList, int cmdId)
581 {
582     int32_t ret;
583 
584     struct HdfSBuf *sBuf = HdfSbufObtainDefaultSize();
585     if (sBuf == NULL) {
586         AUDIO_FUNC_LOGE("Failed to obtain sBuf!");
587         return HDF_FAILURE;
588     }
589 
590     if (!HdfSbufWriteString(sBuf, eList->cardSrvName)) {
591         AUDIO_FUNC_LOGE("CardServiceName Write Fail!");
592         AudioFreeHdfSBuf(sBuf, NULL);
593         return HDF_FAILURE;
594     }
595 
596     if (!HdfSbufWriteUint32(sBuf, eList->space)) {
597         AUDIO_FUNC_LOGE("Elem list space Write Fail!");
598         AudioFreeHdfSBuf(sBuf, NULL);
599         return HDF_FAILURE;
600     }
601 
602     if (!HdfSbufWriteUint64(sBuf, (uint64_t)eList->ctlElemListAddr)) {
603         AUDIO_FUNC_LOGE("Elem list addr Write Fail!");
604         AudioFreeHdfSBuf(sBuf, NULL);
605         return HDF_FAILURE;
606     }
607 
608     struct HdfSBuf *reply = HdfSbufObtainDefaultSize();
609     if (reply == NULL) {
610         AUDIO_FUNC_LOGE("Failed to obtain reply!");
611         AudioFreeHdfSBuf(sBuf, NULL);
612         return HDF_FAILURE;
613     }
614 
615     struct HdfObject *srv = (struct HdfObject *)(&service->object);
616     ret = service->dispatcher->Dispatch(srv, cmdId, sBuf, reply);
617     if (ret != HDF_SUCCESS) {
618         AUDIO_FUNC_LOGE(
619             "Failed to send service call cmdId: %{public}s!", AudioRenderCtlCmdId2String(cmdId + MIXER_CMD_ID_BASE));
620         AudioFreeHdfSBuf(sBuf, reply);
621         return ret;
622     }
623 
624     ret = AudioCtlElemParseData(eList, reply);
625     if (ret != HDF_SUCCESS) {
626         AudioFreeHdfSBuf(sBuf, reply);
627         return ret;
628     }
629     AudioFreeHdfSBuf(sBuf, reply);
630 
631     return HDF_SUCCESS;
632 }
633 
AudioCtlElemListCts(const struct HdfIoService * service,int cmdId,struct AudioMixerContents * mData)634 static int32_t AudioCtlElemListCts(const struct HdfIoService *service, int cmdId, struct AudioMixerContents *mData)
635 {
636     int32_t ret;
637     struct AudioCtlElemList eList = {
638         .cardSrvName = mData->cardServiceName,
639         .count = 0,
640         .space = AUDIO_ELEMENT_NUM,
641         .ctlElemListAddr = NULL
642     };
643 
644     eList.ctlElemListAddr = OsalMemCalloc(eList.space * sizeof(struct AudioHwCtlElemId));
645     if (eList.ctlElemListAddr == NULL) {
646         AUDIO_FUNC_LOGE("Out of memory!");
647         return HDF_FAILURE;
648     }
649 
650     ret = AudioCtlGetElemList(service, &eList, cmdId);
651     if (ret != HDF_SUCCESS) {
652         AudioMemFree((void **)&eList.ctlElemListAddr);
653         return ret;
654     }
655     mData->data = eList.ctlElemListAddr;
656     mData->elemNum = eList.count;
657 
658     return HDF_SUCCESS;
659 }
660 
AudioCtlRenderElemList(const struct HdfIoService * service,int cmdId,struct AudioMixerContents * data)661 static int32_t AudioCtlRenderElemList(const struct HdfIoService *service, int cmdId, struct AudioMixerContents *data)
662 {
663     int32_t ret;
664 
665     ret = AudioCtlElemListCts(service, cmdId, data);
666     if (ret != HDF_SUCCESS) {
667         AUDIO_FUNC_LOGE("Failed to get the element list!");
668         return ret;
669     }
670 
671     return HDF_SUCCESS;
672 }
673 
AudioCtlCaptureElemList(const struct HdfIoService * service,int cmdId,struct AudioMixerContents * data)674 static int32_t AudioCtlCaptureElemList(const struct HdfIoService *service, int cmdId, struct AudioMixerContents *data)
675 {
676     return AudioCtlRenderElemList(service, cmdId, data);
677 }
678 
AudioChkMixerRenderCmdId(OpCode cmd)679 static bool AudioChkMixerRenderCmdId(OpCode cmd)
680 {
681     if (cmd < MIXER_CTL_IOCTL_ELEM_INFO || cmd > MIXER_CTL_IOCTL_SET_CHMAP) {
682         AUDIO_FUNC_LOGE("cmdId Not Supported!");
683         return false;
684     }
685 
686     return true;
687 }
688 
AudioChkMixerCaptureCmdId(OpCode cmd)689 static bool AudioChkMixerCaptureCmdId(OpCode cmd)
690 {
691     return AudioChkMixerRenderCmdId(cmd);
692 }
693 
AudioMixerCtlElemList(AudioPcmType pcm,OpCode cmd,const struct HdfIoService * service,void * data)694 static int32_t AudioMixerCtlElemList(AudioPcmType pcm, OpCode cmd, const struct HdfIoService *service, void *data)
695 {
696     struct AudioMixerContents *mContents = (struct AudioMixerContents *)data;
697 
698     if (pcm == PCM_CAPTURE) {
699         return AudioCtlCaptureElemList(service, cmd, mContents);
700     } else {
701         return AudioCtlRenderElemList(service, cmd, mContents);
702     }
703 }
704 
AudioFillAllAdapters(struct HdfSBuf * sbuf,int32_t num,struct AudioCardId * clist)705 static int32_t AudioFillAllAdapters(struct HdfSBuf *sbuf, int32_t num, struct AudioCardId *clist)
706 {
707     int32_t i, j, ret;
708     uint8_t offset = 0;
709     uint8_t portNum = 0;
710     const char *sndName = NULL;
711 
712     for (i = 0; i < num; i++) {
713         sndName = HdfSbufReadString(sbuf);
714         if (sndName == NULL) {
715             AUDIO_FUNC_LOGE("Failed to parse the cardServiceName!");
716             return HDF_FAILURE;
717         }
718 
719         ret = memcpy_s(clist[i].cardName, AUDIO_CARD_SRV_NAME_LEN, sndName, strlen(sndName) + 1);
720         if (ret != EOK) {
721             AUDIO_FUNC_LOGE("Failed to copy card information!");
722             return HDF_FAILURE;
723         }
724 
725         if (!HdfSbufReadUint8(sbuf, &portNum)) {
726             AUDIO_FUNC_LOGE("read portNum failed!");
727             return HDF_FAILURE;
728         }
729         if (portNum == PORT_IN || portNum == PORT_OUT) {
730             portNum = PORT_OUT;
731         } else if (portNum == PORT_OUT_IN) {
732             portNum = PORT_IN;
733         } else {
734             AUDIO_FUNC_LOGE("portNum error!");
735             return HDF_FAILURE;
736         }
737 
738         for (j = 0; j < portNum; j++) {
739             if (!HdfSbufReadUint8(sbuf, &offset)) {
740                 AUDIO_FUNC_LOGE("Failed to copy card information!");
741                 return HDF_FAILURE;
742             }
743         }
744         /* The sound card number starts at 0, so it needs (num -1) */
745         clist[i].index = (num - 1) - i;
746     }
747 
748     return HDF_SUCCESS;
749 }
750 
AudioParseAllAdaptersFromBuf(struct SndCardsList * sndCards,struct HdfSBuf * buf)751 static int32_t AudioParseAllAdaptersFromBuf(struct SndCardsList *sndCards, struct HdfSBuf *buf)
752 {
753     int32_t ret;
754     int32_t cnumber = 0;
755     struct AudioCardId *clist = NULL;
756 
757     if (!HdfSbufReadInt32(buf, &cnumber)) {
758         AUDIO_FUNC_LOGE("HdfSbufReadInt32 failed!");
759         return HDF_FAILURE;
760     }
761     if (cnumber <= 0) {
762         AUDIO_FUNC_LOGE("Card num error!");
763         return HDF_FAILURE;
764     }
765 
766     clist = OsalMemCalloc(sizeof(struct AudioCardId) * cnumber);
767     if (clist == NULL) {
768         AUDIO_FUNC_LOGE("Out of memory!");
769         return HDF_FAILURE;
770     }
771 
772     ret = AudioFillAllAdapters(buf, cnumber, clist);
773     if (ret != HDF_SUCCESS) {
774         AudioMemFree((void **)&clist);
775         return ret;
776     }
777     sndCards->cardNums = (uint32_t)cnumber;
778     sndCards->cardsList = clist;
779 
780     return HDF_SUCCESS;
781 }
782 
AudioCtlGetAllCards(const struct HdfIoService * service,int32_t cmdId,struct SndCardsList * sndCards)783 static int32_t AudioCtlGetAllCards(const struct HdfIoService *service, int32_t cmdId, struct SndCardsList *sndCards)
784 {
785     int32_t ret;
786     struct HdfSBuf *reply = NULL;
787     struct HdfObject *srv = NULL;
788 
789     reply = HdfSbufObtainDefaultSize();
790     if (reply == NULL) {
791         AUDIO_FUNC_LOGE("HdfSbufObtainDefaultSize failed!");
792         return HDF_FAILURE;
793     }
794 
795     srv = (struct HdfObject *)(&service->object);
796     ret = service->dispatcher->Dispatch(srv, cmdId, NULL, reply);
797     if (ret != HDF_SUCCESS) {
798         AUDIO_FUNC_LOGE("Failed to send service Dispatch!");
799         AudioFreeHdfSBuf(reply, NULL);
800         return ret;
801     }
802 
803     ret = AudioParseAllAdaptersFromBuf(sndCards, reply);
804     if (ret != HDF_SUCCESS) {
805         AudioFreeHdfSBuf(reply, NULL);
806         return ret;
807     }
808     AudioFreeHdfSBuf(reply, NULL);
809 
810     return HDF_SUCCESS;
811 }
812 
AudioGetAllCardList(AudioPcmType pcm,OpCode cmd,const struct HdfIoService * service,void * data)813 static int32_t AudioGetAllCardList(AudioPcmType pcm, OpCode cmd, const struct HdfIoService *service, void *data)
814 {
815     (void)pcm;
816     struct SndCardsList *sndCardsList = (struct SndCardsList *)data;
817 
818     cmd -= (MIXER_CTL_IOCTL_GET_CARDS - MIXER_CTL_IOCTL_ELEM_GET_PROP);
819     if (service == NULL || sndCardsList == NULL) {
820         AUDIO_FUNC_LOGE("Invalid parameter!");
821         return HDF_FAILURE;
822     }
823 
824     return AudioCtlGetAllCards(service, cmd, sndCardsList);
825 }
826 
AudioMixerCtlElemRoute(AudioPcmType pcm,const struct HdfIoService * service,OpCode cmd,void * data)827 static int32_t AudioMixerCtlElemRoute(AudioPcmType pcm, const struct HdfIoService *service, OpCode cmd, void *data)
828 {
829     uint32_t i, count;
830 
831     if (!AudioCheckServiceIsAvailable(service)) {
832         return HDF_FAILURE;
833     }
834 
835     if (pcm == PCM_CAPTURE) {
836         if (!AudioChkMixerCaptureCmdId(cmd)) {
837             return HDF_FAILURE;
838         }
839     } else {
840         if (!AudioChkMixerRenderCmdId(cmd)) {
841             return HDF_FAILURE;
842         }
843     }
844 
845     count = (uint32_t)HDF_ARRAY_SIZE(g_AudioMixerOpsTbl);
846     if (count == 0) {
847         AUDIO_FUNC_LOGE("The audio mixer operation table is empty!!!");
848         return HDF_FAILURE;
849     }
850 
851     for (i = 0; i < count; i++) {
852         if (cmd == g_AudioMixerOpsTbl[i].cmdId) {
853             /* Find the corresponding option */
854             break;
855         }
856     }
857     if (i == count) {
858         AUDIO_FUNC_LOGE("There's no corresponding option!!!");
859         return HDF_FAILURE;
860     }
861 
862     if (g_AudioMixerOpsTbl[i].func == NULL) {
863         AUDIO_FUNC_LOGE("The function handle is empty!!!");
864         return HDF_FAILURE;
865     }
866 
867     return g_AudioMixerOpsTbl[i].func(pcm, i, service, data);
868 }
869 
AudioFillDataBool(struct HdfSBuf * sBuf,struct AudioMixerCtlElemInfo * data)870 static int32_t AudioFillDataBool(struct HdfSBuf *sBuf, struct AudioMixerCtlElemInfo *data)
871 {
872     (void)sBuf;
873     (void)data;
874 
875     return HDF_ERR_NOT_SUPPORT;
876 }
877 
AudioFillDataInt(struct HdfSBuf * sBuf,struct AudioMixerCtlElemInfo * data)878 static int32_t AudioFillDataInt(struct HdfSBuf *sBuf, struct AudioMixerCtlElemInfo *data)
879 {
880     struct AudioCtlElemId eId = {
881         .cardServiceName = data->cardSrvName,
882         .itemName = data->eIndexId.eId.name,
883         .iface = data->eIndexId.eId.iface
884     };
885 
886     if (!HdfSbufWriteInt32(sBuf, eId.iface)) {
887         AUDIO_FUNC_LOGE("Element iface Write Fail!");
888         return HDF_FAILURE;
889     }
890     if (!HdfSbufWriteString(sBuf, eId.cardServiceName)) {
891         AUDIO_FUNC_LOGE("Element cardServiceName Write Fail!");
892         return HDF_FAILURE;
893     }
894     if (!HdfSbufWriteString(sBuf, eId.itemName)) {
895         AUDIO_FUNC_LOGE("Element itemName Write Fail!");
896         return HDF_FAILURE;
897     }
898 
899     return HDF_SUCCESS;
900 }
901 
AudioFillDataEnum(struct HdfSBuf * sBuf,struct AudioMixerCtlElemInfo * data)902 static int32_t AudioFillDataEnum(struct HdfSBuf *sBuf, struct AudioMixerCtlElemInfo *data)
903 {
904     (void)sBuf;
905     (void)data;
906 
907     return HDF_ERR_NOT_SUPPORT;
908 }
AudioFillDataBytes(struct HdfSBuf * sBuf,struct AudioMixerCtlElemInfo * data)909 static int32_t AudioFillDataBytes(struct HdfSBuf *sBuf, struct AudioMixerCtlElemInfo *data)
910 {
911     (void)sBuf;
912     (void)data;
913 
914     return HDF_ERR_NOT_SUPPORT;
915 }
916 
AudioFillSendDataToBuf(struct HdfSBuf * sBuf,struct AudioMixerCtlElemInfo * data)917 static int32_t AudioFillSendDataToBuf(struct HdfSBuf *sBuf, struct AudioMixerCtlElemInfo *data)
918 {
919     int32_t ret;
920 
921     switch (data->type) {
922         case AUDIO_CTL_ELEM_TYPE_BOOLEAN:
923             ret = AudioFillDataBool(sBuf, data);
924             break;
925         case AUDIO_CTL_ELEM_TYPE_INTEGER:
926             ret = AudioFillDataInt(sBuf, data);
927             break;
928         case AUDIO_CTL_ELEM_TYPE_ENUMERATED:
929             ret = AudioFillDataEnum(sBuf, data);
930             break;
931         case AUDIO_CTL_ELEM_TYPE_BYTES:
932             ret = AudioFillDataBytes(sBuf, data);
933             break;
934         default:
935             AUDIO_FUNC_LOGE("Unknown element value type!!!");
936             ret = HDF_FAILURE;
937             break;
938     }
939 
940     return ret;
941 }
942 
AudioParseIntegerFromBufOnly(struct HdfSBuf * reply,struct AudioMixerCtlElemInfo * data)943 static int32_t AudioParseIntegerFromBufOnly(struct HdfSBuf *reply, struct AudioMixerCtlElemInfo *data)
944 {
945     struct AudioCtlElemValue eVal;
946 
947     (void)memset_s(&eVal, sizeof(struct AudioCtlElemValue), 0, sizeof(struct AudioCtlElemValue));
948     if (!HdfSbufReadInt32(reply, &eVal.value[0])) {
949         AUDIO_FUNC_LOGE("Failed to get the value0 of the CTL element!");
950         return HDF_FAILURE;
951     }
952     if (!HdfSbufReadInt32(reply, &eVal.value[1])) {
953         AUDIO_FUNC_LOGE("Failed to get the value1 of the CTL element!");
954         return HDF_FAILURE;
955     }
956     data->count = eVal.value[1] <= 0 ? 1 : 2;   // 2 for number of values.
957     data->value.intVal.vals[0] = (long)eVal.value[0];
958     data->value.intVal.vals[1] = (long)eVal.value[1];
959 
960     return HDF_SUCCESS;
961 }
962 
AudioParseIntegerFromBuf(struct HdfSBuf * reply,struct AudioMixerCtlElemInfo * data)963 static int32_t AudioParseIntegerFromBuf(struct HdfSBuf *reply, struct AudioMixerCtlElemInfo *data)
964 {
965     struct AudioCtrlElemInfo eValue;
966 
967     (void)memset_s(&eValue, sizeof(struct AudioCtrlElemInfo), 0, sizeof(struct AudioCtrlElemInfo));
968     if (!HdfSbufReadInt32(reply, &eValue.max)) {
969         AUDIO_FUNC_LOGE("Failed to get the max value of the CTL element!");
970         return HDF_FAILURE;
971     }
972 
973     if (!HdfSbufReadInt32(reply, &eValue.min)) {
974         AUDIO_FUNC_LOGE("Failed to get the min value of the CTL element!");
975         return HDF_FAILURE;
976     }
977 
978     if (!HdfSbufReadUint32(reply, &eValue.count)) {
979         AUDIO_FUNC_LOGE("Failed to get the count of the CTL element!");
980         return HDF_FAILURE;
981     }
982     data->count = eValue.count;
983     data->value.intVal.max = eValue.max;
984     data->value.intVal.min = eValue.min;
985     data->value.intVal.step = 0; /* reserved */
986 
987     return HDF_SUCCESS;
988 }
989 
AudioParseEnumeratedFromBuf(struct HdfSBuf * reply,struct AudioMixerCtlElemInfo * data)990 static int32_t AudioParseEnumeratedFromBuf(struct HdfSBuf *reply, struct AudioMixerCtlElemInfo *data)
991 {
992     (void)reply;
993     (void)data;
994 
995     return HDF_SUCCESS;
996 }
997 
AudioParseBoolFromBuf(struct HdfSBuf * reply,struct AudioMixerCtlElemInfo * data)998 static int32_t AudioParseBoolFromBuf(struct HdfSBuf *reply, struct AudioMixerCtlElemInfo *data)
999 {
1000     (void)reply;
1001     (void)data;
1002 
1003     return HDF_ERR_NOT_SUPPORT;
1004 }
1005 
AudioParseStringFromBuf(struct HdfSBuf * reply,struct AudioMixerCtlElemInfo * data)1006 static int32_t AudioParseStringFromBuf(struct HdfSBuf *reply, struct AudioMixerCtlElemInfo *data)
1007 {
1008     (void)reply;
1009     (void)data;
1010 
1011     return HDF_ERR_NOT_SUPPORT;
1012 }
1013 
AudioParseRecvDataFromBuf(struct HdfSBuf * reply,struct AudioMixerCtlElemInfo * data,int cmdId)1014 static int32_t AudioParseRecvDataFromBuf(struct HdfSBuf *reply, struct AudioMixerCtlElemInfo *data, int cmdId)
1015 {
1016     int32_t ret;
1017     int32_t type = 0;
1018 
1019     if (cmdId == (MIXER_CTL_IOCTL_ELEM_INFO - MIXER_CMD_ID_BASE)) {
1020         if (!HdfSbufReadInt32(reply, &type)) {
1021             AUDIO_FUNC_LOGE("Failed to Get Volume type!");
1022             return HDF_FAILURE;
1023         }
1024         data->type = (AudioCtlElemType)type;
1025         switch (data->type) {
1026             case AUDIO_CTL_ELEM_TYPE_INTEGER:
1027                 ret = AudioParseIntegerFromBuf(reply, data);
1028                 break;
1029             case AUDIO_CTL_ELEM_TYPE_ENUMERATED:
1030                 ret = AudioParseEnumeratedFromBuf(reply, data);
1031                 break;
1032             case AUDIO_CTL_ELEM_TYPE_BOOLEAN:
1033                 ret = AudioParseBoolFromBuf(reply, data);
1034                 break;
1035             case AUDIO_CTL_ELEM_TYPE_BYTES:
1036                 ret = AudioParseStringFromBuf(reply, data);
1037                 break;
1038             default:
1039                 AUDIO_FUNC_LOGE("An unsupported type!");
1040                 ret = HDF_FAILURE;
1041                 break;
1042         }
1043     } else {
1044         ret = AudioParseIntegerFromBufOnly(reply, data);
1045     }
1046 
1047     return ret;
1048 }
1049 
AudioCtlElemGetProp(const struct HdfIoService * srv,int cmdId,struct AudioMixerCtlElemInfo * data)1050 static int32_t AudioCtlElemGetProp(const struct HdfIoService *srv, int cmdId, struct AudioMixerCtlElemInfo *data)
1051 {
1052     int32_t ret;
1053     struct HdfSBuf *sBuf = NULL;
1054     struct HdfSBuf *reply = NULL;
1055 
1056     sBuf = HdfSbufObtainDefaultSize();
1057     if (sBuf == NULL) {
1058         AUDIO_FUNC_LOGE("Failed to obtain sBuf!!!");
1059         return HDF_FAILURE;
1060     }
1061 
1062     ret = AudioFillSendDataToBuf(sBuf, data);
1063     if (ret != HDF_SUCCESS) {
1064         AudioFreeHdfSBuf(sBuf, NULL);
1065         return ret;
1066     }
1067 
1068     reply = HdfSbufObtainDefaultSize();
1069     if (reply == NULL) {
1070         AUDIO_FUNC_LOGE("Failed to obtain reply!!!");
1071         AudioFreeHdfSBuf(sBuf, NULL);
1072         return HDF_FAILURE;
1073     }
1074 
1075     struct HdfObject *service = (struct HdfObject *)(&srv->object);
1076     ret = srv->dispatcher->Dispatch(service, cmdId, sBuf, reply);
1077     if (ret != HDF_SUCCESS) {
1078         AudioFreeHdfSBuf(sBuf, reply);
1079         return HDF_FAILURE;
1080     }
1081 
1082     ret = AudioParseRecvDataFromBuf(reply, data, cmdId);
1083     if (ret != HDF_SUCCESS) {
1084         AudioFreeHdfSBuf(sBuf, reply);
1085         return ret;
1086     }
1087     AudioFreeHdfSBuf(sBuf, reply);
1088 
1089     return HDF_SUCCESS;
1090 }
1091 
AudioFillInfoDataToBuf(struct HdfSBuf * sBuf,struct AudioMixerCtlElemInfo * data)1092 static int32_t AudioFillInfoDataToBuf(struct HdfSBuf *sBuf, struct AudioMixerCtlElemInfo *data)
1093 {
1094     struct AudioCtrlElemInfo eInfo = {
1095         .id.cardServiceName = data->cardSrvName,
1096         .id.itemName = data->eIndexId.eId.name,
1097         .id.iface = data->eIndexId.eId.iface
1098     };
1099 
1100     if (!HdfSbufWriteInt32(sBuf, eInfo.id.iface)) {
1101         AUDIO_FUNC_LOGE("Element iface Write Fail!");
1102         return HDF_FAILURE;
1103     }
1104     if (!HdfSbufWriteString(sBuf, eInfo.id.cardServiceName)) {
1105         AUDIO_FUNC_LOGE("Element cardServiceName Write Fail!");
1106         return HDF_FAILURE;
1107     }
1108     if (!HdfSbufWriteString(sBuf, eInfo.id.itemName)) {
1109         AUDIO_FUNC_LOGE("Element itemName Write Fail!");
1110         return HDF_FAILURE;
1111     }
1112 
1113     return HDF_SUCCESS;
1114 }
1115 
AudioParseInfoDataFromBuf(struct HdfSBuf * reply,struct AudioMixerCtlElemInfo * data)1116 static int32_t AudioParseInfoDataFromBuf(struct HdfSBuf *reply, struct AudioMixerCtlElemInfo *data)
1117 {
1118     struct AudioCtrlElemInfo eValue;
1119 
1120     (void)memset_s(&eValue, sizeof(struct AudioCtrlElemInfo), 0, sizeof(struct AudioCtrlElemInfo));
1121     if (!HdfSbufReadInt32(reply, &eValue.type)) {
1122         AUDIO_FUNC_LOGE("Failed to get the value0 of the CTL element!");
1123         return HDF_FAILURE;
1124     }
1125 
1126     if (!HdfSbufReadInt32(reply, &eValue.max)) {
1127         AUDIO_FUNC_LOGE("Failed to get the value1 of the CTL element!");
1128         return HDF_FAILURE;
1129     }
1130 
1131     if (!HdfSbufReadInt32(reply, &eValue.min)) {
1132         AUDIO_FUNC_LOGE("Failed to get the value1 of the CTL element!");
1133         return HDF_FAILURE;
1134     }
1135 
1136     if (!HdfSbufReadUint32(reply, &eValue.count)) {
1137         AUDIO_FUNC_LOGE("Failed to get the value1 of the CTL element!");
1138         return HDF_FAILURE;
1139     }
1140     /* type: 0-AUDIO_CONTROL_MIXER (integer), 1-AUDIO_CONTROL_MUX (enum) */
1141     if (eValue.type == AUDIO_CONTROL_MIXER) {
1142         data->type = AUDIO_CTL_ELEM_TYPE_INTEGER;
1143         data->count = eValue.count; /* channels */
1144         data->value.intVal.min = eValue.min;
1145         data->value.intVal.max = eValue.max;
1146         data->value.intVal.step = 0; /* reserved */
1147     } else if (eValue.type == AUDIO_CONTROL_ENUM) {
1148         data->type = AUDIO_CTL_ELEM_TYPE_ENUMERATED;
1149         data->count = eValue.count; /* channels */
1150         data->value.intVal.min = eValue.min;
1151         data->value.intVal.max = eValue.max;
1152         data->value.intVal.step = 0; /* reserved */
1153     } else {
1154         AUDIO_FUNC_LOGI("type is AUDIO_CONTROL_MUX!");
1155     }
1156 
1157     return HDF_SUCCESS;
1158 }
1159 
AudioCtlElemInfoProp(const struct HdfIoService * srv,int cmdId,struct AudioMixerCtlElemInfo * data)1160 static int32_t AudioCtlElemInfoProp(const struct HdfIoService *srv, int cmdId, struct AudioMixerCtlElemInfo *data)
1161 {
1162     int32_t ret;
1163     struct HdfSBuf *sBuf = NULL;
1164     struct HdfSBuf *reply = NULL;
1165 
1166     sBuf = HdfSbufObtainDefaultSize();
1167     if (sBuf == NULL) {
1168         AUDIO_FUNC_LOGE("Failed to obtain sBuf!!!");
1169         return HDF_FAILURE;
1170     }
1171 
1172     ret = AudioFillInfoDataToBuf(sBuf, data);
1173     if (ret != HDF_SUCCESS) {
1174         AudioFreeHdfSBuf(sBuf, NULL);
1175         return ret;
1176     }
1177 
1178     reply = HdfSbufObtainDefaultSize();
1179     if (reply == NULL) {
1180         AUDIO_FUNC_LOGE("Failed to obtain reply!!!");
1181         AudioFreeHdfSBuf(sBuf, NULL);
1182         return HDF_FAILURE;
1183     }
1184 
1185     struct HdfObject *service = (struct HdfObject *)(&srv->object);
1186     ret = srv->dispatcher->Dispatch(service, cmdId, sBuf, reply);
1187     if (ret != HDF_SUCCESS) {
1188         AudioFreeHdfSBuf(sBuf, reply);
1189         return HDF_FAILURE;
1190     }
1191 
1192     ret = AudioParseInfoDataFromBuf(reply, data);
1193     if (ret != HDF_SUCCESS) {
1194         AudioFreeHdfSBuf(sBuf, reply);
1195         return ret;
1196     }
1197     AudioFreeHdfSBuf(sBuf, reply);
1198 
1199     return HDF_SUCCESS;
1200 }
1201 
AudioFillSetDataToBuf(struct HdfSBuf * sBuf,struct AudioMixerCtlElemInfo * data)1202 static int32_t AudioFillSetDataToBuf(struct HdfSBuf *sBuf, struct AudioMixerCtlElemInfo *data)
1203 {
1204     struct AudioCtlElemValue eValue = {
1205         .id.cardServiceName = data->cardSrvName,
1206         .id.itemName = data->eIndexId.eId.name,
1207         .id.iface = data->eIndexId.eId.iface,
1208         .value[0] = data->value.intVal.vals[0],
1209         .value[1] = data->value.intVal.vals[1]
1210     };
1211 
1212     if (!HdfSbufWriteInt32(sBuf, eValue.value[0])) {
1213         AUDIO_FUNC_LOGE("Element iface Write Fail!");
1214         return HDF_FAILURE;
1215     }
1216     if (!HdfSbufWriteInt32(sBuf, eValue.id.iface)) {
1217         AUDIO_FUNC_LOGE("Element iface Write Fail!");
1218         return HDF_FAILURE;
1219     }
1220     if (!HdfSbufWriteString(sBuf, eValue.id.cardServiceName)) {
1221         AUDIO_FUNC_LOGE("Element cardServiceName Write Fail!");
1222         return HDF_FAILURE;
1223     }
1224     if (!HdfSbufWriteString(sBuf, eValue.id.itemName)) {
1225         AUDIO_FUNC_LOGE("Element itemName Write Fail!");
1226         return HDF_FAILURE;
1227     }
1228 
1229     return HDF_SUCCESS;
1230 }
1231 
AudioCtlElemSetProp(const struct HdfIoService * srv,int cmdId,struct AudioMixerCtlElemInfo * data)1232 static int32_t AudioCtlElemSetProp(const struct HdfIoService *srv, int cmdId, struct AudioMixerCtlElemInfo *data)
1233 {
1234     int32_t ret;
1235     struct HdfSBuf *sBuf = NULL;
1236 
1237     sBuf = HdfSbufObtainDefaultSize();
1238     if (sBuf == NULL) {
1239         AUDIO_FUNC_LOGE("Failed to obtain sBuf!!!");
1240         return HDF_FAILURE;
1241     }
1242 
1243     ret = AudioFillSetDataToBuf(sBuf, data);
1244     if (ret != HDF_SUCCESS) {
1245         AudioFreeHdfSBuf(sBuf, NULL);
1246         return ret;
1247     }
1248 
1249     struct HdfObject *service = (struct HdfObject *)(&srv->object);
1250     ret = srv->dispatcher->Dispatch(service, cmdId, sBuf, NULL);
1251     if (ret != HDF_SUCCESS) {
1252         AUDIO_FUNC_LOGE("Dispatch failed!!!");
1253         AudioFreeHdfSBuf(sBuf, NULL);
1254         return HDF_FAILURE;
1255     }
1256     AudioFreeHdfSBuf(sBuf, NULL);
1257 
1258     return HDF_SUCCESS;
1259 }
1260 
AudioCtlElemRoute(const struct HdfIoService * service,OpCode cmdId,struct AudioMixerCtlElemInfo * data)1261 static int32_t AudioCtlElemRoute(const struct HdfIoService *service, OpCode cmdId, struct AudioMixerCtlElemInfo *data)
1262 {
1263     int32_t ret;
1264     int32_t fOpcode = MIXER_CTL_IOCTL_ELEM_INFO - MIXER_CMD_ID_BASE;
1265     int32_t rOpcode = MIXER_CTL_IOCTL_ELEM_READ - MIXER_CMD_ID_BASE;
1266     int32_t wOpcode = MIXER_CTL_IOCTL_ELEM_WRITE - MIXER_CMD_ID_BASE;
1267 
1268     if (cmdId == MIXER_CTL_IOCTL_ELEM_INFO) {
1269         cmdId = fOpcode;
1270         return AudioCtlElemInfoProp(service, cmdId, data);
1271     }
1272 
1273     cmdId -= MIXER_CTL_IOCTL_ELEM_LIST - MIXER_CMD_ID_BASE;
1274     if (cmdId == rOpcode) { // Read element property.
1275         ret = AudioCtlElemGetProp(service, cmdId, data);
1276         if (ret != HDF_SUCCESS) {
1277             return ret;
1278         }
1279         ret = AudioCtlElemGetProp(service, fOpcode, data);
1280     } else if (cmdId == wOpcode) { // Write element property.
1281         ret = AudioCtlElemSetProp(service, cmdId, data);
1282     } else {
1283         AUDIO_FUNC_LOGE("Invalid opcode for the control!");
1284         ret = HDF_FAILURE;
1285     }
1286 
1287     return ret;
1288 }
1289 
AudioCtlGetElemCts(const struct HdfIoService * service,OpCode cmdId,struct AudioMixerCtlElemInfo * data)1290 static int32_t AudioCtlGetElemCts(const struct HdfIoService *service, OpCode cmdId, struct AudioMixerCtlElemInfo *data)
1291 {
1292     return AudioCtlElemRoute(service, cmdId, data);
1293 }
1294 
AudioCtlSetElemCts(const struct HdfIoService * srv,OpCode cmdId,struct AudioMixerCtlElemInfo * data)1295 static int32_t AudioCtlSetElemCts(const struct HdfIoService *srv, OpCode cmdId, struct AudioMixerCtlElemInfo *data)
1296 {
1297     return AudioCtlElemRoute(srv, cmdId, data);
1298 }
1299 
AudioCtlRenderGetElemProp(const struct HdfIoService * service,OpCode cmdId,struct AudioMixerCtlElemInfo * data)1300 static int32_t AudioCtlRenderGetElemProp(
1301     const struct HdfIoService *service, OpCode cmdId, struct AudioMixerCtlElemInfo *data)
1302 {
1303     int32_t ret;
1304 
1305     ret = AudioCtlGetElemCts(service, cmdId, data);
1306     if (ret != HDF_SUCCESS) {
1307         return ret;
1308     }
1309 
1310     return HDF_SUCCESS;
1311 }
1312 
AudioCtlCaptureGetElemProp(const struct HdfIoService * service,OpCode cmdId,struct AudioMixerCtlElemInfo * data)1313 static int32_t AudioCtlCaptureGetElemProp(
1314     const struct HdfIoService *service, OpCode cmdId, struct AudioMixerCtlElemInfo *data)
1315 {
1316     return AudioCtlRenderGetElemProp(service, cmdId, data);
1317 }
1318 
AudioMixerCtlGetElemProp(AudioPcmType pcm,OpCode cmd,const struct HdfIoService * service,void * data)1319 static int32_t AudioMixerCtlGetElemProp(AudioPcmType pcm, OpCode cmd, const struct HdfIoService *service, void *data)
1320 {
1321     struct AudioMixerCtlElemInfo *infoData = (struct AudioMixerCtlElemInfo *)data;
1322 
1323     return (pcm == PCM_CAPTURE) ? AudioCtlCaptureGetElemProp(service, cmd, infoData) :
1324                                   AudioCtlRenderGetElemProp(service, cmd, infoData);
1325 }
1326 
AudioCtlRenderSetElemProp(const struct HdfIoService * service,OpCode cmdId,struct AudioMixerCtlElemInfo * data)1327 static int32_t AudioCtlRenderSetElemProp(
1328     const struct HdfIoService *service, OpCode cmdId, struct AudioMixerCtlElemInfo *data)
1329 {
1330     int32_t ret;
1331 
1332     ret = AudioCtlSetElemCts(service, cmdId, data);
1333     if (ret != HDF_SUCCESS) {
1334         AUDIO_FUNC_LOGE("Failed to set the element!");
1335         return ret;
1336     }
1337 
1338     return HDF_SUCCESS;
1339 }
1340 
AudioCtlCaptureSetElemProp(const struct HdfIoService * service,int cmdId,struct AudioMixerCtlElemInfo * data)1341 static int32_t AudioCtlCaptureSetElemProp(
1342     const struct HdfIoService *service, int cmdId, struct AudioMixerCtlElemInfo *data)
1343 {
1344     return AudioCtlRenderSetElemProp(service, cmdId, data);
1345 }
1346 
AudioMixerCtlSetElemProp(AudioPcmType pcm,OpCode cmd,const struct HdfIoService * service,void * data)1347 static int32_t AudioMixerCtlSetElemProp(AudioPcmType pcm, OpCode cmd, const struct HdfIoService *service, void *data)
1348 {
1349     struct AudioMixerCtlElemInfo *infoData = (struct AudioMixerCtlElemInfo *)data;
1350 
1351     return (pcm == PCM_CAPTURE) ? AudioCtlCaptureSetElemProp(service, cmd, infoData) :
1352                                   AudioCtlRenderSetElemProp(service, cmd, infoData);
1353 }
1354 
AudioMixerCtlElem(AudioPcmType pcm,const struct HdfIoService * service,struct AudioMixerContents * mixerCts)1355 int32_t AudioMixerCtlElem(AudioPcmType pcm, const struct HdfIoService *service, struct AudioMixerContents *mixerCts)
1356 {
1357     OpCode cmd = MIXER_CTL_IOCTL_ELEM_LIST;
1358     AudioPcmType stream = (pcm == PCM_CAPTURE) ? PCM_CAPTURE : PCM_RENDER;
1359 
1360     if (service == NULL || mixerCts == NULL) {
1361         AUDIO_FUNC_LOGE("Invalid parameters!");
1362         return HDF_FAILURE;
1363     }
1364 
1365     return AudioMixerCtlElemRoute(stream, service, cmd, mixerCts);
1366 }
1367 
AudioMixerCtlGetElem(AudioPcmType pcm,const struct HdfIoService * srv,struct AudioMixerCtlElemInfo * infoData)1368 int32_t AudioMixerCtlGetElem(AudioPcmType pcm, const struct HdfIoService *srv, struct AudioMixerCtlElemInfo *infoData)
1369 {
1370     OpCode cmd = MIXER_CTL_IOCTL_ELEM_GET_PROP;
1371     AudioPcmType stream = (pcm == PCM_CAPTURE) ? PCM_CAPTURE : PCM_RENDER;
1372 
1373     if (srv == NULL || infoData == NULL) {
1374         AUDIO_FUNC_LOGE("Invalid parameters!");
1375         return HDF_FAILURE;
1376     }
1377 
1378     return AudioMixerCtlElemRoute(stream, srv, cmd, infoData);
1379 }
1380 
AudioMixerCtlSetElem(AudioPcmType pcm,const struct HdfIoService * service,struct AudioMixerCtlElemInfo * infoData)1381 int32_t AudioMixerCtlSetElem(
1382     AudioPcmType pcm, const struct HdfIoService *service, struct AudioMixerCtlElemInfo *infoData)
1383 {
1384     OpCode cmd = MIXER_CTL_IOCTL_ELEM_SET_PROP;
1385     AudioPcmType stream = (pcm == PCM_CAPTURE) ? PCM_CAPTURE : PCM_RENDER;
1386 
1387     if (service == NULL || infoData == NULL) {
1388         AUDIO_FUNC_LOGE("Invalid parameters!");
1389         return HDF_FAILURE;
1390     }
1391 
1392     return AudioMixerCtlElemRoute(stream, service, cmd, infoData);
1393 }
1394 
AudioMixerGetAllAdapters(const struct HdfIoService * service,struct SndCardsList * clist)1395 int32_t AudioMixerGetAllAdapters(const struct HdfIoService *service, struct SndCardsList *clist)
1396 {
1397     OpCode cmd = MIXER_CTL_IOCTL_GET_CARDS;
1398 
1399     if (service == NULL || clist == NULL) {
1400         AUDIO_FUNC_LOGE("Invalid parameters!");
1401         return HDF_FAILURE;
1402     }
1403 
1404     return AudioMixerCtlElemRoute(PCM_BOTTOM, service, cmd, clist);
1405 }
1406