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