• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 && *sBuf != NULL) {
118         HdfSbufRecycle(*sBuf);
119         *sBuf = NULL;
120     }
121 
122     if (reply != NULL && *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     CHECK_NULL_PTR_RETURN_VALUE(desc, HDF_ERR_INVALID_PARAM);
321 
322     if (!HdfSbufReadUint8(reply, &portNum)) {
323         AUDIO_FUNC_LOGE("read portNum failed!");
324         return HDF_FAILURE;
325     }
326 
327     if (portNum == PORT_IN || portNum == PORT_OUT) {
328         portNum = PORTNUM_FIRST; // support capture | render
329     } else if (portNum == PORT_OUT_IN) {
330         portNum = PORTNUM_SECOND; // support capture & render
331     } else {
332         AUDIO_FUNC_LOGE("portNum value failed!");
333         return HDF_FAILURE;
334     }
335 
336 #ifndef AUDIO_HDI_SERVICE_MODE
337     desc->portNum = portNum;
338 #else
339     desc->portsLen = portNum;
340 #endif
341     if (portNum == 0) {
342         AUDIO_FUNC_LOGE("portNum is zero");
343         return HDF_FAILURE;
344     }
345     desc->ports = (struct AudioPort *)OsalMemCalloc(sizeof(struct AudioPort) * portNum);
346     CHECK_NULL_PTR_RETURN_VALUE(desc->ports, HDF_FAILURE);
347 
348     for (uint32_t i = 0; i < portNum; i++) {
349         if (!HdfSbufReadUint8(reply, (uint8_t *)&desc->ports[i].dir)) {
350             AUDIO_FUNC_LOGE("read dir failed!");
351             AudioMemFree((void **)&desc->ports);
352             return HDF_FAILURE;
353         }
354 
355         if (desc->ports[i].dir == PORT_IN) {
356             desc->ports[i].portName = strdup("AIP");
357         } else if (desc->ports[i].dir == PORT_OUT) {
358             desc->ports[i].portName = strdup("AOP");
359         } else if (desc->ports[i].dir == PORT_OUT_IN) {
360             desc->ports[i].portName = strdup("AOIP");
361         } else {
362             AudioMemFree((void **)&desc->ports);
363             return HDF_FAILURE;
364         }
365         desc->ports[i].portId = portId;
366     }
367 
368     return HDF_SUCCESS;
369 }
370 
AudioPortNameFree(struct AudioPort * dataBlock,uint32_t portsLen)371 static void AudioPortNameFree(struct AudioPort *dataBlock, uint32_t portsLen)
372 {
373     if (dataBlock == NULL) {
374         return;
375     }
376 
377     for (uint32_t i = 0; i < portsLen; i++) {
378         OsalMemFree((void *)dataBlock[i].portName);
379         dataBlock[i].portName = NULL;
380     }
381     OsalMemFree(dataBlock);
382 }
383 
AudioFreeDesc(struct AudioAdapterDescriptor ** descs,uint32_t sndCardNum)384 static void AudioFreeDesc(struct AudioAdapterDescriptor **descs, uint32_t sndCardNum)
385 {
386     if (descs == NULL || *descs == NULL) {
387         AUDIO_FUNC_LOGE("AudioFreeDesc failed!");
388         return;
389     }
390 
391     for (uint32_t index = 0; index < sndCardNum; index++) {
392         if ((*descs)[index].adapterName != NULL) {
393             AudioMemFree((void **)&((*descs)[index].adapterName));
394             (*descs)[index].adapterName = NULL;
395         }
396 #ifndef AUDIO_HDI_SERVICE_MODE
397         AudioPortNameFree((*descs)[index].ports, (*descs)[index].portNum);
398 #else
399         AudioPortNameFree((*descs)[index].ports, (*descs)[index].portsLen);
400 #endif
401     }
402     AudioMemFree((void **)descs);
403 }
404 
AudioReadCardInfoToDesc(struct HdfSBuf * reply,struct AudioAdapterDescriptor ** descs,int * sndCardNum)405 static int32_t AudioReadCardInfoToDesc(struct HdfSBuf *reply, struct AudioAdapterDescriptor **descs, int *sndCardNum)
406 {
407     int32_t index = 0;
408     int8_t portId = 0;
409 
410     if (!HdfSbufReadInt32(reply, sndCardNum)) {
411         AUDIO_FUNC_LOGE("read snd card num failed!");
412         return HDF_FAILURE;
413     }
414 
415     if (*descs == NULL && *sndCardNum > 0) {
416         AUDIO_FUNC_LOGI("*descs is NULL");
417         *descs = (struct AudioAdapterDescriptor *)OsalMemCalloc(sizeof(struct AudioAdapterDescriptor) * (*sndCardNum));
418         if (*descs == NULL) {
419             AUDIO_FUNC_LOGE("OsalMemCalloc descs is NULL");
420             return HDF_FAILURE;
421         }
422     }
423 
424     // Make sure the primary sound card is on the front
425     for (index = (*sndCardNum - 1); index >= 0; index--) {
426         (*descs)[index].adapterName = AudioCardNameTransform(HdfSbufReadString(reply), &portId);
427         if ((*descs)[index].adapterName == NULL) {
428             AudioFreeDesc(descs, *sndCardNum);
429             return HDF_FAILURE;
430         }
431 
432         if (AudioReadCardPortToDesc(reply, &(*descs)[index], portId) != HDF_SUCCESS) {
433             AUDIO_FUNC_LOGE("read port failed!");
434             AudioFreeDesc(descs, *sndCardNum);
435             return HDF_FAILURE;
436         }
437     }
438 
439     return HDF_SUCCESS;
440 }
441 
AudioGetAllCardInfo(struct AudioAdapterDescriptor ** descs,int32_t * sndCardNum)442 int32_t AudioGetAllCardInfo(struct AudioAdapterDescriptor **descs, int32_t *sndCardNum)
443 {
444     if (descs == NULL || sndCardNum == NULL) {
445         return HDF_FAILURE;
446     }
447 
448     struct DevHandle *handle = AudioBindService(CTRL_CMD);
449     if (handle == NULL) {
450         AUDIO_FUNC_LOGE("AudioBindService failed!");
451         return HDF_FAILURE;
452     }
453 
454     struct HdfSBuf *reply = HdfSbufObtainDefaultSize();
455     if (reply == NULL) {
456         AudioCloseService(handle);
457         AUDIO_FUNC_LOGE("HdfSbufObtainDefaultSize failed!");
458         return HDF_FAILURE;
459     }
460 
461     if (AudioServiceDispatch(handle->object, AUDIODRV_CTL_IOCTL_ELEM_CARD - CTRL_NUM, NULL, reply) != HDF_SUCCESS) {
462         AUDIO_FUNC_LOGE("GetAllCardInfo Failed to send service call!");
463         AudioFreeHdfSBuf(&reply, NULL);
464         AudioCloseService(handle);
465         return HDF_FAILURE;
466     }
467 
468     if (AudioReadCardInfoToDesc(reply, descs, sndCardNum) != HDF_SUCCESS) {
469         AudioFreeHdfSBuf(&reply, NULL);
470         AudioCloseService(handle);
471         return HDF_FAILURE;
472     }
473 
474     HdfSbufRecycle(reply);
475     AudioCloseService(handle);
476     return HDF_SUCCESS;
477 }
478 
AudioCloseServiceSub(struct HdfIoService * service)479 void AudioCloseServiceSub(struct HdfIoService *service)
480 {
481     if (service != NULL) {
482         HdfIoServiceRecycle(service);
483     }
484 }
485 
AudioCtlElemRealDataSpace(struct AudioCtlElemList * eList)486 static int32_t AudioCtlElemRealDataSpace(struct AudioCtlElemList *eList)
487 {
488     int32_t ret;
489     size_t dataSize = eList->count * sizeof(struct AudioHwCtlElemId);
490     if (dataSize <= 0) {
491         AUDIO_FUNC_LOGE("dataSize is zero");
492         return HDF_FAILURE;
493     }
494     struct AudioHwCtlElemId *ctlElemListAddr = OsalMemCalloc(dataSize);
495     if (ctlElemListAddr == NULL) {
496         AUDIO_FUNC_LOGE("Out of memory!");
497         return HDF_FAILURE;
498     }
499 
500     ret = memcpy_s(ctlElemListAddr, dataSize, eList->ctlElemListAddr, dataSize);
501     if (ret != EOK) {
502         AUDIO_FUNC_LOGE("Failed to copy data.!");
503         AudioMemFree((void **)&ctlElemListAddr);
504         return HDF_FAILURE;
505     }
506     AudioMemFree((void **)&eList->ctlElemListAddr);
507     eList->ctlElemListAddr = ctlElemListAddr;
508     eList->space = eList->count;
509 
510     return HDF_SUCCESS;
511 }
512 
AudioCtlElemParseData(struct AudioCtlElemList * eList,struct HdfSBuf * reply)513 static int32_t AudioCtlElemParseData(struct AudioCtlElemList *eList, struct HdfSBuf *reply)
514 {
515     int32_t ret;
516     uint32_t countTmp = 0;
517     uint32_t spaceTmp = 0;
518 
519     const char *sndSvcName = HdfSbufReadString(reply);
520     if (sndSvcName == NULL) {
521         AUDIO_FUNC_LOGE("Failed to parse the cardServiceName!");
522         return HDF_FAILURE;
523     }
524     if (strcmp(eList->cardSrvName, sndSvcName) != 0) {
525         AUDIO_FUNC_LOGE("The service name does not match!");
526         return HDF_FAILURE;
527     }
528 
529     if (!HdfSbufReadUint32(reply, &countTmp)) {
530         AUDIO_FUNC_LOGE("Failed to parse the count!");
531         return HDF_FAILURE;
532     }
533     if (countTmp == 0) {
534         AUDIO_FUNC_LOGE("Can't find the element because count == 0!");
535         return HDF_FAILURE;
536     }
537 
538     if (!HdfSbufReadUint32(reply, &spaceTmp)) {
539         AUDIO_FUNC_LOGE("Failed to parse the space!");
540         return HDF_FAILURE;
541     }
542     if (eList->space != spaceTmp || spaceTmp <= countTmp) {
543         AUDIO_FUNC_LOGE("The data space does not match!");
544         return HDF_FAILURE;
545     }
546     eList->count = countTmp;
547 
548     /* Space is allocated based on actual data */
549     ret = AudioCtlElemRealDataSpace(eList);
550     if (ret != HDF_SUCCESS) {
551         return ret;
552     }
553 
554     return HDF_SUCCESS;
555 }
556 
AudioRenderCtlCmdId2String(int cmdId)557 static const char *AudioRenderCtlCmdId2String(int cmdId)
558 {
559     static const char *audioRenderCtlCmdString[] = {
560         "MIXER_CTL_IOCTL_ELEM_INFO",
561         "MIXER_CTL_IOCTL_ELEM_READ",
562         "MIXER_CTL_IOCTL_ELEM_WRITE",
563         "MIXER_CTL_IOCTL_ELEM_LIST",
564         "MIXER_CTL_IOCTL_ELEM_GET_PROP",
565         "MIXER_CTL_IOCTL_ELEM_SET_PROP",
566         "MIXER_CTL_IOCTL_GET_CARDS",
567         "MIXER_CTL_IOCTL_GET_CHMAP",
568         "MIXER_CTL_IOCTL_SET_CHMAP"
569     };
570 
571     if (cmdId < MIXER_CTL_IOCTL_ELEM_INFO || cmdId > MIXER_CTL_IOCTL_SET_CHMAP) {
572         AUDIO_FUNC_LOGE("cmdId Not Supported!");
573         return "Not found!";
574     }
575 
576     return audioRenderCtlCmdString[cmdId - MIXER_CTL_IOCTL_ELEM_INFO];
577 }
578 
AudioCtlGetElemList(const struct HdfIoService * service,struct AudioCtlElemList * eList,int cmdId)579 static int32_t AudioCtlGetElemList(const struct HdfIoService *service, struct AudioCtlElemList *eList, int cmdId)
580 {
581     int32_t ret;
582 
583     struct HdfSBuf *sBuf = HdfSbufObtainDefaultSize();
584     if (sBuf == NULL) {
585         AUDIO_FUNC_LOGE("Failed to obtain sBuf!");
586         return HDF_FAILURE;
587     }
588 
589     if (!HdfSbufWriteString(sBuf, eList->cardSrvName)) {
590         AUDIO_FUNC_LOGE("CardServiceName Write Fail!");
591         AudioFreeHdfSBuf(&sBuf, NULL);
592         return HDF_FAILURE;
593     }
594 
595     if (!HdfSbufWriteUint32(sBuf, eList->space)) {
596         AUDIO_FUNC_LOGE("Elem list space Write Fail!");
597         AudioFreeHdfSBuf(&sBuf, NULL);
598         return HDF_FAILURE;
599     }
600 
601     if (!HdfSbufWriteUint64(sBuf, (uint64_t)eList->ctlElemListAddr)) {
602         AUDIO_FUNC_LOGE("Elem list addr Write Fail!");
603         AudioFreeHdfSBuf(&sBuf, NULL);
604         return HDF_FAILURE;
605     }
606 
607     struct HdfSBuf *reply = HdfSbufObtainDefaultSize();
608     if (reply == NULL) {
609         AUDIO_FUNC_LOGE("Failed to obtain reply!");
610         AudioFreeHdfSBuf(&sBuf, NULL);
611         return HDF_FAILURE;
612     }
613 
614     struct HdfObject *srv = (struct HdfObject *)(&service->object);
615     ret = service->dispatcher->Dispatch(srv, cmdId, sBuf, reply);
616     if (ret != HDF_SUCCESS) {
617         AUDIO_FUNC_LOGE(
618             "Failed to send service call cmdId: %{public}s!", AudioRenderCtlCmdId2String(cmdId + MIXER_CMD_ID_BASE));
619         AudioFreeHdfSBuf(&sBuf, &reply);
620         return ret;
621     }
622 
623     ret = AudioCtlElemParseData(eList, reply);
624     if (ret != HDF_SUCCESS) {
625         AudioFreeHdfSBuf(&sBuf, &reply);
626         return ret;
627     }
628     AudioFreeHdfSBuf(&sBuf, &reply);
629 
630     return HDF_SUCCESS;
631 }
632 
AudioCtlElemListCts(const struct HdfIoService * service,int cmdId,struct AudioMixerContents * mData)633 static int32_t AudioCtlElemListCts(const struct HdfIoService *service, int cmdId, struct AudioMixerContents *mData)
634 {
635     int32_t ret;
636     struct AudioCtlElemList eList = {
637         .cardSrvName = mData->cardServiceName,
638         .count = 0,
639         .space = AUDIO_ELEMENT_NUM,
640         .ctlElemListAddr = NULL
641     };
642 
643     eList.ctlElemListAddr = OsalMemCalloc(eList.space * sizeof(struct AudioHwCtlElemId));
644     if (eList.ctlElemListAddr == NULL) {
645         AUDIO_FUNC_LOGE("Out of memory!");
646         return HDF_FAILURE;
647     }
648 
649     ret = AudioCtlGetElemList(service, &eList, cmdId);
650     if (ret != HDF_SUCCESS) {
651         AudioMemFree((void **)&eList.ctlElemListAddr);
652         return ret;
653     }
654     mData->data = eList.ctlElemListAddr;
655     mData->elemNum = eList.count;
656 
657     return HDF_SUCCESS;
658 }
659 
AudioCtlRenderElemList(const struct HdfIoService * service,int cmdId,struct AudioMixerContents * data)660 static int32_t AudioCtlRenderElemList(const struct HdfIoService *service, int cmdId, struct AudioMixerContents *data)
661 {
662     int32_t ret;
663 
664     ret = AudioCtlElemListCts(service, cmdId, data);
665     if (ret != HDF_SUCCESS) {
666         AUDIO_FUNC_LOGE("Failed to get the element list!");
667         return ret;
668     }
669 
670     return HDF_SUCCESS;
671 }
672 
AudioCtlCaptureElemList(const struct HdfIoService * service,int cmdId,struct AudioMixerContents * data)673 static int32_t AudioCtlCaptureElemList(const struct HdfIoService *service, int cmdId, struct AudioMixerContents *data)
674 {
675     return AudioCtlRenderElemList(service, cmdId, data);
676 }
677 
AudioChkMixerRenderCmdId(OpCode cmd)678 static bool AudioChkMixerRenderCmdId(OpCode cmd)
679 {
680     if (cmd < MIXER_CTL_IOCTL_ELEM_INFO || cmd > MIXER_CTL_IOCTL_SET_CHMAP) {
681         AUDIO_FUNC_LOGE("cmdId Not Supported!");
682         return false;
683     }
684 
685     return true;
686 }
687 
AudioChkMixerCaptureCmdId(OpCode cmd)688 static bool AudioChkMixerCaptureCmdId(OpCode cmd)
689 {
690     return AudioChkMixerRenderCmdId(cmd);
691 }
692 
AudioMixerCtlElemList(AudioPcmType pcm,OpCode cmd,const struct HdfIoService * service,void * data)693 static int32_t AudioMixerCtlElemList(AudioPcmType pcm, OpCode cmd, const struct HdfIoService *service, void *data)
694 {
695     struct AudioMixerContents *mContents = (struct AudioMixerContents *)data;
696 
697     if (pcm == PCM_CAPTURE) {
698         return AudioCtlCaptureElemList(service, cmd, mContents);
699     } else {
700         return AudioCtlRenderElemList(service, cmd, mContents);
701     }
702 }
703 
AudioFillAllAdapters(struct HdfSBuf * sbuf,int32_t num,struct AudioCardId * clist)704 static int32_t AudioFillAllAdapters(struct HdfSBuf *sbuf, int32_t num, struct AudioCardId *clist)
705 {
706     int32_t i, j, ret;
707     uint8_t offset = 0;
708     uint8_t portNum = 0;
709     const char *sndName = NULL;
710 
711     for (i = 0; i < num; i++) {
712         sndName = HdfSbufReadString(sbuf);
713         if (sndName == NULL) {
714             AUDIO_FUNC_LOGE("Failed to parse the cardServiceName!");
715             return HDF_FAILURE;
716         }
717 
718         ret = memcpy_s(clist[i].cardName, AUDIO_CARD_SRV_NAME_LEN, sndName, strlen(sndName) + 1);
719         if (ret != EOK) {
720             AUDIO_FUNC_LOGE("Failed to copy card information!");
721             return HDF_FAILURE;
722         }
723 
724         if (!HdfSbufReadUint8(sbuf, &portNum)) {
725             AUDIO_FUNC_LOGE("read portNum failed!");
726             return HDF_FAILURE;
727         }
728         if (portNum == PORT_IN || portNum == PORT_OUT) {
729             portNum = PORT_OUT;
730         } else if (portNum == PORT_OUT_IN) {
731             portNum = PORT_IN;
732         } else {
733             AUDIO_FUNC_LOGE("portNum error!");
734             return HDF_FAILURE;
735         }
736 
737         for (j = 0; j < portNum; j++) {
738             if (!HdfSbufReadUint8(sbuf, &offset)) {
739                 AUDIO_FUNC_LOGE("Failed to copy card information!");
740                 return HDF_FAILURE;
741             }
742         }
743         /* The sound card number starts at 0, so it needs (num -1) */
744         clist[i].index = (num - 1) - i;
745     }
746 
747     return HDF_SUCCESS;
748 }
749 
AudioParseAllAdaptersFromBuf(struct SndCardsList * sndCards,struct HdfSBuf * buf)750 static int32_t AudioParseAllAdaptersFromBuf(struct SndCardsList *sndCards, struct HdfSBuf *buf)
751 {
752     int32_t ret;
753     int32_t cnumber = 0;
754     struct AudioCardId *clist = NULL;
755 
756     if (!HdfSbufReadInt32(buf, &cnumber)) {
757         AUDIO_FUNC_LOGE("HdfSbufReadInt32 failed!");
758         return HDF_FAILURE;
759     }
760     if (cnumber <= 0) {
761         AUDIO_FUNC_LOGE("Card num error!");
762         return HDF_FAILURE;
763     }
764 
765     clist = OsalMemCalloc(sizeof(struct AudioCardId) * cnumber);
766     if (clist == NULL) {
767         AUDIO_FUNC_LOGE("Out of memory!");
768         return HDF_FAILURE;
769     }
770 
771     ret = AudioFillAllAdapters(buf, cnumber, clist);
772     if (ret != HDF_SUCCESS) {
773         AudioMemFree((void **)&clist);
774         return ret;
775     }
776     sndCards->cardNums = (uint32_t)cnumber;
777     sndCards->cardsList = clist;
778 
779     return HDF_SUCCESS;
780 }
781 
AudioCtlGetAllCards(const struct HdfIoService * service,int32_t cmdId,struct SndCardsList * sndCards)782 static int32_t AudioCtlGetAllCards(const struct HdfIoService *service, int32_t cmdId, struct SndCardsList *sndCards)
783 {
784     int32_t ret;
785     struct HdfSBuf *reply = NULL;
786     struct HdfObject *srv = NULL;
787 
788     reply = HdfSbufObtainDefaultSize();
789     if (reply == NULL) {
790         AUDIO_FUNC_LOGE("HdfSbufObtainDefaultSize failed!");
791         return HDF_FAILURE;
792     }
793 
794     srv = (struct HdfObject *)(&service->object);
795     ret = service->dispatcher->Dispatch(srv, cmdId, NULL, reply);
796     if (ret != HDF_SUCCESS) {
797         AUDIO_FUNC_LOGE("Failed to send service Dispatch!");
798         AudioFreeHdfSBuf(&reply, NULL);
799         return ret;
800     }
801 
802     ret = AudioParseAllAdaptersFromBuf(sndCards, reply);
803     if (ret != HDF_SUCCESS) {
804         AudioFreeHdfSBuf(&reply, NULL);
805         return ret;
806     }
807     AudioFreeHdfSBuf(&reply, NULL);
808 
809     return HDF_SUCCESS;
810 }
811 
AudioGetAllCardList(AudioPcmType pcm,OpCode cmd,const struct HdfIoService * service,void * data)812 static int32_t AudioGetAllCardList(AudioPcmType pcm, OpCode cmd, const struct HdfIoService *service, void *data)
813 {
814     (void)pcm;
815     struct SndCardsList *sndCardsList = (struct SndCardsList *)data;
816 
817     cmd -= (MIXER_CTL_IOCTL_GET_CARDS - MIXER_CTL_IOCTL_ELEM_GET_PROP);
818     if (service == NULL || sndCardsList == NULL) {
819         AUDIO_FUNC_LOGE("Invalid parameter!");
820         return HDF_FAILURE;
821     }
822 
823     return AudioCtlGetAllCards(service, cmd, sndCardsList);
824 }
825 
AudioMixerCtlElemRoute(AudioPcmType pcm,const struct HdfIoService * service,OpCode cmd,void * data)826 static int32_t AudioMixerCtlElemRoute(AudioPcmType pcm, const struct HdfIoService *service, OpCode cmd, void *data)
827 {
828     uint32_t i, count;
829 
830     if (!AudioCheckServiceIsAvailable(service)) {
831         return HDF_FAILURE;
832     }
833 
834     if (pcm == PCM_CAPTURE) {
835         if (!AudioChkMixerCaptureCmdId(cmd)) {
836             return HDF_FAILURE;
837         }
838     } else {
839         if (!AudioChkMixerRenderCmdId(cmd)) {
840             return HDF_FAILURE;
841         }
842     }
843 
844     count = (uint32_t)HDF_ARRAY_SIZE(g_AudioMixerOpsTbl);
845     if (count == 0) {
846         AUDIO_FUNC_LOGE("The audio mixer operation table is empty!!!");
847         return HDF_FAILURE;
848     }
849 
850     for (i = 0; i < count; i++) {
851         if (cmd == g_AudioMixerOpsTbl[i].cmdId) {
852             /* Find the corresponding option */
853             break;
854         }
855     }
856     if (i == count) {
857         AUDIO_FUNC_LOGE("There's no corresponding option!!!");
858         return HDF_FAILURE;
859     }
860 
861     if (g_AudioMixerOpsTbl[i].func == NULL) {
862         AUDIO_FUNC_LOGE("The function handle is empty!!!");
863         return HDF_FAILURE;
864     }
865 
866     return g_AudioMixerOpsTbl[i].func(pcm, i, service, data);
867 }
868 
AudioFillDataBool(struct HdfSBuf * sBuf,struct AudioMixerCtlElemInfo * data)869 static int32_t AudioFillDataBool(struct HdfSBuf *sBuf, struct AudioMixerCtlElemInfo *data)
870 {
871     (void)sBuf;
872     (void)data;
873 
874     return HDF_ERR_NOT_SUPPORT;
875 }
876 
AudioFillDataInt(struct HdfSBuf * sBuf,struct AudioMixerCtlElemInfo * data)877 static int32_t AudioFillDataInt(struct HdfSBuf *sBuf, struct AudioMixerCtlElemInfo *data)
878 {
879     struct AudioCtlElemId eId = {
880         .cardServiceName = data->cardSrvName,
881         .itemName = data->eIndexId.eId.name,
882         .iface = data->eIndexId.eId.iface
883     };
884 
885     if (!HdfSbufWriteInt32(sBuf, eId.iface)) {
886         AUDIO_FUNC_LOGE("Element iface Write Fail!");
887         return HDF_FAILURE;
888     }
889     if (!HdfSbufWriteString(sBuf, eId.cardServiceName)) {
890         AUDIO_FUNC_LOGE("Element cardServiceName Write Fail!");
891         return HDF_FAILURE;
892     }
893     if (!HdfSbufWriteString(sBuf, eId.itemName)) {
894         AUDIO_FUNC_LOGE("Element itemName Write Fail!");
895         return HDF_FAILURE;
896     }
897 
898     return HDF_SUCCESS;
899 }
900 
AudioFillDataEnum(struct HdfSBuf * sBuf,struct AudioMixerCtlElemInfo * data)901 static int32_t AudioFillDataEnum(struct HdfSBuf *sBuf, struct AudioMixerCtlElemInfo *data)
902 {
903     (void)sBuf;
904     (void)data;
905 
906     return HDF_ERR_NOT_SUPPORT;
907 }
AudioFillDataBytes(struct HdfSBuf * sBuf,struct AudioMixerCtlElemInfo * data)908 static int32_t AudioFillDataBytes(struct HdfSBuf *sBuf, struct AudioMixerCtlElemInfo *data)
909 {
910     (void)sBuf;
911     (void)data;
912 
913     return HDF_ERR_NOT_SUPPORT;
914 }
915 
AudioFillSendDataToBuf(struct HdfSBuf * sBuf,struct AudioMixerCtlElemInfo * data)916 static int32_t AudioFillSendDataToBuf(struct HdfSBuf *sBuf, struct AudioMixerCtlElemInfo *data)
917 {
918     int32_t ret;
919 
920     switch (data->type) {
921         case AUDIO_CTL_ELEM_TYPE_BOOLEAN:
922             ret = AudioFillDataBool(sBuf, data);
923             break;
924         case AUDIO_CTL_ELEM_TYPE_INTEGER:
925             ret = AudioFillDataInt(sBuf, data);
926             break;
927         case AUDIO_CTL_ELEM_TYPE_ENUMERATED:
928             ret = AudioFillDataEnum(sBuf, data);
929             break;
930         case AUDIO_CTL_ELEM_TYPE_BYTES:
931             ret = AudioFillDataBytes(sBuf, data);
932             break;
933         default:
934             AUDIO_FUNC_LOGE("Unknown element value type!!!");
935             ret = HDF_FAILURE;
936             break;
937     }
938 
939     return ret;
940 }
941 
AudioParseIntegerFromBufOnly(struct HdfSBuf * reply,struct AudioMixerCtlElemInfo * data)942 static int32_t AudioParseIntegerFromBufOnly(struct HdfSBuf *reply, struct AudioMixerCtlElemInfo *data)
943 {
944     struct AudioCtlElemValue eVal;
945 
946     (void)memset_s(&eVal, sizeof(struct AudioCtlElemValue), 0, sizeof(struct AudioCtlElemValue));
947     if (!HdfSbufReadInt32(reply, &eVal.value[0])) {
948         AUDIO_FUNC_LOGE("Failed to get the value0 of the CTL element!");
949         return HDF_FAILURE;
950     }
951     if (!HdfSbufReadInt32(reply, &eVal.value[1])) {
952         AUDIO_FUNC_LOGE("Failed to get the value1 of the CTL element!");
953         return HDF_FAILURE;
954     }
955     data->count = eVal.value[1] <= 0 ? 1 : 2;   // 2 for number of values.
956     data->value.intVal.vals[0] = (long)eVal.value[0];
957     data->value.intVal.vals[1] = (long)eVal.value[1];
958 
959     return HDF_SUCCESS;
960 }
961 
AudioParseIntegerFromBuf(struct HdfSBuf * reply,struct AudioMixerCtlElemInfo * data)962 static int32_t AudioParseIntegerFromBuf(struct HdfSBuf *reply, struct AudioMixerCtlElemInfo *data)
963 {
964     struct AudioCtrlElemInfo eValue;
965 
966     (void)memset_s(&eValue, sizeof(struct AudioCtrlElemInfo), 0, sizeof(struct AudioCtrlElemInfo));
967     if (!HdfSbufReadInt32(reply, &eValue.max)) {
968         AUDIO_FUNC_LOGE("Failed to get the max value of the CTL element!");
969         return HDF_FAILURE;
970     }
971 
972     if (!HdfSbufReadInt32(reply, &eValue.min)) {
973         AUDIO_FUNC_LOGE("Failed to get the min value of the CTL element!");
974         return HDF_FAILURE;
975     }
976 
977     if (!HdfSbufReadUint32(reply, &eValue.count)) {
978         AUDIO_FUNC_LOGE("Failed to get the count of the CTL element!");
979         return HDF_FAILURE;
980     }
981     data->count = eValue.count;
982     data->value.intVal.max = eValue.max;
983     data->value.intVal.min = eValue.min;
984     data->value.intVal.step = 0; /* reserved */
985 
986     return HDF_SUCCESS;
987 }
988 
AudioParseEnumeratedFromBuf(struct HdfSBuf * reply,struct AudioMixerCtlElemInfo * data)989 static int32_t AudioParseEnumeratedFromBuf(struct HdfSBuf *reply, struct AudioMixerCtlElemInfo *data)
990 {
991     (void)reply;
992     (void)data;
993 
994     return HDF_SUCCESS;
995 }
996 
AudioParseBoolFromBuf(struct HdfSBuf * reply,struct AudioMixerCtlElemInfo * data)997 static int32_t AudioParseBoolFromBuf(struct HdfSBuf *reply, struct AudioMixerCtlElemInfo *data)
998 {
999     (void)reply;
1000     (void)data;
1001 
1002     return HDF_ERR_NOT_SUPPORT;
1003 }
1004 
AudioParseStringFromBuf(struct HdfSBuf * reply,struct AudioMixerCtlElemInfo * data)1005 static int32_t AudioParseStringFromBuf(struct HdfSBuf *reply, struct AudioMixerCtlElemInfo *data)
1006 {
1007     (void)reply;
1008     (void)data;
1009 
1010     return HDF_ERR_NOT_SUPPORT;
1011 }
1012 
AudioParseRecvDataFromBuf(struct HdfSBuf * reply,struct AudioMixerCtlElemInfo * data,int cmdId)1013 static int32_t AudioParseRecvDataFromBuf(struct HdfSBuf *reply, struct AudioMixerCtlElemInfo *data, int cmdId)
1014 {
1015     int32_t ret;
1016     int32_t type = 0;
1017 
1018     if (cmdId == (MIXER_CTL_IOCTL_ELEM_INFO - MIXER_CMD_ID_BASE)) {
1019         if (!HdfSbufReadInt32(reply, &type)) {
1020             AUDIO_FUNC_LOGE("Failed to Get Volume type!");
1021             return HDF_FAILURE;
1022         }
1023         data->type = (AudioCtlElemType)type;
1024         switch (data->type) {
1025             case AUDIO_CTL_ELEM_TYPE_INTEGER:
1026                 ret = AudioParseIntegerFromBuf(reply, data);
1027                 break;
1028             case AUDIO_CTL_ELEM_TYPE_ENUMERATED:
1029                 ret = AudioParseEnumeratedFromBuf(reply, data);
1030                 break;
1031             case AUDIO_CTL_ELEM_TYPE_BOOLEAN:
1032                 ret = AudioParseBoolFromBuf(reply, data);
1033                 break;
1034             case AUDIO_CTL_ELEM_TYPE_BYTES:
1035                 ret = AudioParseStringFromBuf(reply, data);
1036                 break;
1037             default:
1038                 AUDIO_FUNC_LOGE("An unsupported type!");
1039                 ret = HDF_FAILURE;
1040                 break;
1041         }
1042     } else {
1043         ret = AudioParseIntegerFromBufOnly(reply, data);
1044     }
1045 
1046     return ret;
1047 }
1048 
AudioCtlElemGetProp(const struct HdfIoService * srv,int cmdId,struct AudioMixerCtlElemInfo * data)1049 static int32_t AudioCtlElemGetProp(const struct HdfIoService *srv, int cmdId, struct AudioMixerCtlElemInfo *data)
1050 {
1051     int32_t ret;
1052     struct HdfSBuf *sBuf = NULL;
1053     struct HdfSBuf *reply = NULL;
1054 
1055     sBuf = HdfSbufObtainDefaultSize();
1056     if (sBuf == NULL) {
1057         AUDIO_FUNC_LOGE("Failed to obtain sBuf!!!");
1058         return HDF_FAILURE;
1059     }
1060 
1061     ret = AudioFillSendDataToBuf(sBuf, data);
1062     if (ret != HDF_SUCCESS) {
1063         AudioFreeHdfSBuf(&sBuf, NULL);
1064         return ret;
1065     }
1066 
1067     reply = HdfSbufObtainDefaultSize();
1068     if (reply == NULL) {
1069         AUDIO_FUNC_LOGE("Failed to obtain reply!!!");
1070         AudioFreeHdfSBuf(&sBuf, NULL);
1071         return HDF_FAILURE;
1072     }
1073 
1074     struct HdfObject *service = (struct HdfObject *)(&srv->object);
1075     ret = srv->dispatcher->Dispatch(service, cmdId, sBuf, reply);
1076     if (ret != HDF_SUCCESS) {
1077         AudioFreeHdfSBuf(&sBuf, &reply);
1078         return HDF_FAILURE;
1079     }
1080 
1081     ret = AudioParseRecvDataFromBuf(reply, data, cmdId);
1082     if (ret != HDF_SUCCESS) {
1083         AudioFreeHdfSBuf(&sBuf, &reply);
1084         return ret;
1085     }
1086     AudioFreeHdfSBuf(&sBuf, &reply);
1087 
1088     return HDF_SUCCESS;
1089 }
1090 
AudioFillInfoDataToBuf(struct HdfSBuf * sBuf,struct AudioMixerCtlElemInfo * data)1091 static int32_t AudioFillInfoDataToBuf(struct HdfSBuf *sBuf, struct AudioMixerCtlElemInfo *data)
1092 {
1093     struct AudioCtrlElemInfo eInfo = {
1094         .id.cardServiceName = data->cardSrvName,
1095         .id.itemName = data->eIndexId.eId.name,
1096         .id.iface = data->eIndexId.eId.iface
1097     };
1098 
1099     if (!HdfSbufWriteInt32(sBuf, eInfo.id.iface)) {
1100         AUDIO_FUNC_LOGE("Element iface Write Fail!");
1101         return HDF_FAILURE;
1102     }
1103     if (!HdfSbufWriteString(sBuf, eInfo.id.cardServiceName)) {
1104         AUDIO_FUNC_LOGE("Element cardServiceName Write Fail!");
1105         return HDF_FAILURE;
1106     }
1107     if (!HdfSbufWriteString(sBuf, eInfo.id.itemName)) {
1108         AUDIO_FUNC_LOGE("Element itemName Write Fail!");
1109         return HDF_FAILURE;
1110     }
1111 
1112     return HDF_SUCCESS;
1113 }
1114 
AudioParseInfoDataFromBuf(struct HdfSBuf * reply,struct AudioMixerCtlElemInfo * data)1115 static int32_t AudioParseInfoDataFromBuf(struct HdfSBuf *reply, struct AudioMixerCtlElemInfo *data)
1116 {
1117     struct AudioCtrlElemInfo eValue;
1118 
1119     (void)memset_s(&eValue, sizeof(struct AudioCtrlElemInfo), 0, sizeof(struct AudioCtrlElemInfo));
1120     if (!HdfSbufReadInt32(reply, &eValue.type)) {
1121         AUDIO_FUNC_LOGE("Failed to get the value0 of the CTL element!");
1122         return HDF_FAILURE;
1123     }
1124 
1125     if (!HdfSbufReadInt32(reply, &eValue.max)) {
1126         AUDIO_FUNC_LOGE("Failed to get the value1 of the CTL element!");
1127         return HDF_FAILURE;
1128     }
1129 
1130     if (!HdfSbufReadInt32(reply, &eValue.min)) {
1131         AUDIO_FUNC_LOGE("Failed to get the value1 of the CTL element!");
1132         return HDF_FAILURE;
1133     }
1134 
1135     if (!HdfSbufReadUint32(reply, &eValue.count)) {
1136         AUDIO_FUNC_LOGE("Failed to get the value1 of the CTL element!");
1137         return HDF_FAILURE;
1138     }
1139     /* type: 0-AUDIO_CONTROL_MIXER (integer), 1-AUDIO_CONTROL_MUX (enum) */
1140     if (eValue.type == AUDIO_CONTROL_MIXER) {
1141         data->type = AUDIO_CTL_ELEM_TYPE_INTEGER;
1142         data->count = eValue.count; /* channels */
1143         data->value.intVal.min = eValue.min;
1144         data->value.intVal.max = eValue.max;
1145         data->value.intVal.step = 0; /* reserved */
1146     } else if (eValue.type == AUDIO_CONTROL_ENUM) {
1147         data->type = AUDIO_CTL_ELEM_TYPE_ENUMERATED;
1148         data->count = eValue.count; /* channels */
1149         data->value.intVal.min = eValue.min;
1150         data->value.intVal.max = eValue.max;
1151         data->value.intVal.step = 0; /* reserved */
1152     } else {
1153         AUDIO_FUNC_LOGI("type is AUDIO_CONTROL_MUX!");
1154     }
1155 
1156     return HDF_SUCCESS;
1157 }
1158 
AudioCtlElemInfoProp(const struct HdfIoService * srv,int cmdId,struct AudioMixerCtlElemInfo * data)1159 static int32_t AudioCtlElemInfoProp(const struct HdfIoService *srv, int cmdId, struct AudioMixerCtlElemInfo *data)
1160 {
1161     int32_t ret;
1162     struct HdfSBuf *sBuf = NULL;
1163     struct HdfSBuf *reply = NULL;
1164 
1165     sBuf = HdfSbufObtainDefaultSize();
1166     if (sBuf == NULL) {
1167         AUDIO_FUNC_LOGE("Failed to obtain sBuf!!!");
1168         return HDF_FAILURE;
1169     }
1170 
1171     ret = AudioFillInfoDataToBuf(sBuf, data);
1172     if (ret != HDF_SUCCESS) {
1173         AudioFreeHdfSBuf(&sBuf, NULL);
1174         return ret;
1175     }
1176 
1177     reply = HdfSbufObtainDefaultSize();
1178     if (reply == NULL) {
1179         AUDIO_FUNC_LOGE("Failed to obtain reply!!!");
1180         AudioFreeHdfSBuf(&sBuf, NULL);
1181         return HDF_FAILURE;
1182     }
1183 
1184     struct HdfObject *service = (struct HdfObject *)(&srv->object);
1185     ret = srv->dispatcher->Dispatch(service, cmdId, sBuf, reply);
1186     if (ret != HDF_SUCCESS) {
1187         AudioFreeHdfSBuf(&sBuf, &reply);
1188         return HDF_FAILURE;
1189     }
1190 
1191     ret = AudioParseInfoDataFromBuf(reply, data);
1192     if (ret != HDF_SUCCESS) {
1193         AudioFreeHdfSBuf(&sBuf, &reply);
1194         return ret;
1195     }
1196     AudioFreeHdfSBuf(&sBuf, &reply);
1197 
1198     return HDF_SUCCESS;
1199 }
1200 
AudioFillSetDataToBuf(struct HdfSBuf * sBuf,struct AudioMixerCtlElemInfo * data)1201 static int32_t AudioFillSetDataToBuf(struct HdfSBuf *sBuf, struct AudioMixerCtlElemInfo *data)
1202 {
1203     struct AudioCtlElemValue eValue = {
1204         .id.cardServiceName = data->cardSrvName,
1205         .id.itemName = data->eIndexId.eId.name,
1206         .id.iface = data->eIndexId.eId.iface,
1207         .value[0] = data->value.intVal.vals[0],
1208         .value[1] = data->value.intVal.vals[1]
1209     };
1210 
1211     if (!HdfSbufWriteInt32(sBuf, eValue.value[0])) {
1212         AUDIO_FUNC_LOGE("Element iface Write Fail!");
1213         return HDF_FAILURE;
1214     }
1215     if (!HdfSbufWriteInt32(sBuf, eValue.id.iface)) {
1216         AUDIO_FUNC_LOGE("Element iface Write Fail!");
1217         return HDF_FAILURE;
1218     }
1219     if (!HdfSbufWriteString(sBuf, eValue.id.cardServiceName)) {
1220         AUDIO_FUNC_LOGE("Element cardServiceName Write Fail!");
1221         return HDF_FAILURE;
1222     }
1223     if (!HdfSbufWriteString(sBuf, eValue.id.itemName)) {
1224         AUDIO_FUNC_LOGE("Element itemName Write Fail!");
1225         return HDF_FAILURE;
1226     }
1227 
1228     return HDF_SUCCESS;
1229 }
1230 
AudioCtlElemSetProp(const struct HdfIoService * srv,int cmdId,struct AudioMixerCtlElemInfo * data)1231 static int32_t AudioCtlElemSetProp(const struct HdfIoService *srv, int cmdId, struct AudioMixerCtlElemInfo *data)
1232 {
1233     int32_t ret;
1234     struct HdfSBuf *sBuf = NULL;
1235 
1236     sBuf = HdfSbufObtainDefaultSize();
1237     if (sBuf == NULL) {
1238         AUDIO_FUNC_LOGE("Failed to obtain sBuf!!!");
1239         return HDF_FAILURE;
1240     }
1241 
1242     ret = AudioFillSetDataToBuf(sBuf, data);
1243     if (ret != HDF_SUCCESS) {
1244         AudioFreeHdfSBuf(&sBuf, NULL);
1245         return ret;
1246     }
1247 
1248     struct HdfObject *service = (struct HdfObject *)(&srv->object);
1249     ret = srv->dispatcher->Dispatch(service, cmdId, sBuf, NULL);
1250     if (ret != HDF_SUCCESS) {
1251         AUDIO_FUNC_LOGE("Dispatch failed!!!");
1252         AudioFreeHdfSBuf(&sBuf, NULL);
1253         return HDF_FAILURE;
1254     }
1255     AudioFreeHdfSBuf(&sBuf, NULL);
1256 
1257     return HDF_SUCCESS;
1258 }
1259 
AudioCtlElemRoute(const struct HdfIoService * service,OpCode cmdId,struct AudioMixerCtlElemInfo * data)1260 static int32_t AudioCtlElemRoute(const struct HdfIoService *service, OpCode cmdId, struct AudioMixerCtlElemInfo *data)
1261 {
1262     int32_t ret;
1263     int32_t fOpcode = MIXER_CTL_IOCTL_ELEM_INFO - MIXER_CMD_ID_BASE;
1264     int32_t rOpcode = MIXER_CTL_IOCTL_ELEM_READ - MIXER_CMD_ID_BASE;
1265     int32_t wOpcode = MIXER_CTL_IOCTL_ELEM_WRITE - MIXER_CMD_ID_BASE;
1266 
1267     if (cmdId == MIXER_CTL_IOCTL_ELEM_INFO) {
1268         cmdId = fOpcode;
1269         return AudioCtlElemInfoProp(service, cmdId, data);
1270     }
1271 
1272     cmdId -= MIXER_CTL_IOCTL_ELEM_LIST - MIXER_CMD_ID_BASE;
1273     if (cmdId == rOpcode) { // Read element property.
1274         ret = AudioCtlElemGetProp(service, cmdId, data);
1275         if (ret != HDF_SUCCESS) {
1276             return ret;
1277         }
1278         ret = AudioCtlElemGetProp(service, fOpcode, data);
1279     } else if (cmdId == wOpcode) { // Write element property.
1280         ret = AudioCtlElemSetProp(service, cmdId, data);
1281     } else {
1282         AUDIO_FUNC_LOGE("Invalid opcode for the control!");
1283         ret = HDF_FAILURE;
1284     }
1285 
1286     return ret;
1287 }
1288 
AudioCtlGetElemCts(const struct HdfIoService * service,OpCode cmdId,struct AudioMixerCtlElemInfo * data)1289 static int32_t AudioCtlGetElemCts(const struct HdfIoService *service, OpCode cmdId, struct AudioMixerCtlElemInfo *data)
1290 {
1291     return AudioCtlElemRoute(service, cmdId, data);
1292 }
1293 
AudioCtlSetElemCts(const struct HdfIoService * srv,OpCode cmdId,struct AudioMixerCtlElemInfo * data)1294 static int32_t AudioCtlSetElemCts(const struct HdfIoService *srv, OpCode cmdId, struct AudioMixerCtlElemInfo *data)
1295 {
1296     return AudioCtlElemRoute(srv, cmdId, data);
1297 }
1298 
AudioCtlRenderGetElemProp(const struct HdfIoService * service,OpCode cmdId,struct AudioMixerCtlElemInfo * data)1299 static int32_t AudioCtlRenderGetElemProp(
1300     const struct HdfIoService *service, OpCode cmdId, struct AudioMixerCtlElemInfo *data)
1301 {
1302     int32_t ret;
1303 
1304     ret = AudioCtlGetElemCts(service, cmdId, data);
1305     if (ret != HDF_SUCCESS) {
1306         return ret;
1307     }
1308 
1309     return HDF_SUCCESS;
1310 }
1311 
AudioCtlCaptureGetElemProp(const struct HdfIoService * service,OpCode cmdId,struct AudioMixerCtlElemInfo * data)1312 static int32_t AudioCtlCaptureGetElemProp(
1313     const struct HdfIoService *service, OpCode cmdId, struct AudioMixerCtlElemInfo *data)
1314 {
1315     return AudioCtlRenderGetElemProp(service, cmdId, data);
1316 }
1317 
AudioMixerCtlGetElemProp(AudioPcmType pcm,OpCode cmd,const struct HdfIoService * service,void * data)1318 static int32_t AudioMixerCtlGetElemProp(AudioPcmType pcm, OpCode cmd, const struct HdfIoService *service, void *data)
1319 {
1320     struct AudioMixerCtlElemInfo *infoData = (struct AudioMixerCtlElemInfo *)data;
1321 
1322     return (pcm == PCM_CAPTURE) ? AudioCtlCaptureGetElemProp(service, cmd, infoData) :
1323                                   AudioCtlRenderGetElemProp(service, cmd, infoData);
1324 }
1325 
AudioCtlRenderSetElemProp(const struct HdfIoService * service,OpCode cmdId,struct AudioMixerCtlElemInfo * data)1326 static int32_t AudioCtlRenderSetElemProp(
1327     const struct HdfIoService *service, OpCode cmdId, struct AudioMixerCtlElemInfo *data)
1328 {
1329     int32_t ret;
1330 
1331     ret = AudioCtlSetElemCts(service, cmdId, data);
1332     if (ret != HDF_SUCCESS) {
1333         AUDIO_FUNC_LOGE("Failed to set the element!");
1334         return ret;
1335     }
1336 
1337     return HDF_SUCCESS;
1338 }
1339 
AudioCtlCaptureSetElemProp(const struct HdfIoService * service,int cmdId,struct AudioMixerCtlElemInfo * data)1340 static int32_t AudioCtlCaptureSetElemProp(
1341     const struct HdfIoService *service, int cmdId, struct AudioMixerCtlElemInfo *data)
1342 {
1343     return AudioCtlRenderSetElemProp(service, cmdId, data);
1344 }
1345 
AudioMixerCtlSetElemProp(AudioPcmType pcm,OpCode cmd,const struct HdfIoService * service,void * data)1346 static int32_t AudioMixerCtlSetElemProp(AudioPcmType pcm, OpCode cmd, const struct HdfIoService *service, void *data)
1347 {
1348     struct AudioMixerCtlElemInfo *infoData = (struct AudioMixerCtlElemInfo *)data;
1349 
1350     return (pcm == PCM_CAPTURE) ? AudioCtlCaptureSetElemProp(service, cmd, infoData) :
1351                                   AudioCtlRenderSetElemProp(service, cmd, infoData);
1352 }
1353 
AudioMixerCtlElem(AudioPcmType pcm,const struct HdfIoService * service,struct AudioMixerContents * mixerCts)1354 int32_t AudioMixerCtlElem(AudioPcmType pcm, const struct HdfIoService *service, struct AudioMixerContents *mixerCts)
1355 {
1356     OpCode cmd = MIXER_CTL_IOCTL_ELEM_LIST;
1357     AudioPcmType stream = (pcm == PCM_CAPTURE) ? PCM_CAPTURE : PCM_RENDER;
1358 
1359     if (service == NULL || mixerCts == NULL) {
1360         AUDIO_FUNC_LOGE("Invalid parameters!");
1361         return HDF_FAILURE;
1362     }
1363 
1364     return AudioMixerCtlElemRoute(stream, service, cmd, mixerCts);
1365 }
1366 
AudioMixerCtlGetElem(AudioPcmType pcm,const struct HdfIoService * srv,struct AudioMixerCtlElemInfo * infoData)1367 int32_t AudioMixerCtlGetElem(AudioPcmType pcm, const struct HdfIoService *srv, struct AudioMixerCtlElemInfo *infoData)
1368 {
1369     OpCode cmd = MIXER_CTL_IOCTL_ELEM_GET_PROP;
1370     AudioPcmType stream = (pcm == PCM_CAPTURE) ? PCM_CAPTURE : PCM_RENDER;
1371 
1372     if (srv == NULL || infoData == NULL) {
1373         AUDIO_FUNC_LOGE("Invalid parameters!");
1374         return HDF_FAILURE;
1375     }
1376 
1377     return AudioMixerCtlElemRoute(stream, srv, cmd, infoData);
1378 }
1379 
AudioMixerCtlSetElem(AudioPcmType pcm,const struct HdfIoService * service,struct AudioMixerCtlElemInfo * infoData)1380 int32_t AudioMixerCtlSetElem(
1381     AudioPcmType pcm, const struct HdfIoService *service, struct AudioMixerCtlElemInfo *infoData)
1382 {
1383     OpCode cmd = MIXER_CTL_IOCTL_ELEM_SET_PROP;
1384     AudioPcmType stream = (pcm == PCM_CAPTURE) ? PCM_CAPTURE : PCM_RENDER;
1385 
1386     if (service == NULL || infoData == NULL) {
1387         AUDIO_FUNC_LOGE("Invalid parameters!");
1388         return HDF_FAILURE;
1389     }
1390 
1391     return AudioMixerCtlElemRoute(stream, service, cmd, infoData);
1392 }
1393 
AudioMixerGetAllAdapters(const struct HdfIoService * service,struct SndCardsList * clist)1394 int32_t AudioMixerGetAllAdapters(const struct HdfIoService *service, struct SndCardsList *clist)
1395 {
1396     OpCode cmd = MIXER_CTL_IOCTL_GET_CARDS;
1397 
1398     if (service == NULL || clist == NULL) {
1399         AUDIO_FUNC_LOGE("Invalid parameters!");
1400         return HDF_FAILURE;
1401     }
1402 
1403     return AudioMixerCtlElemRoute(PCM_BOTTOM, service, cmd, clist);
1404 }
1405