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