1094332d3Sopenharmony_ci/* 2094332d3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License. 5094332d3Sopenharmony_ci * You may obtain a copy of the License at 6094332d3Sopenharmony_ci * 7094332d3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8094332d3Sopenharmony_ci * 9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and 13094332d3Sopenharmony_ci * limitations under the License. 14094332d3Sopenharmony_ci */ 15094332d3Sopenharmony_ci 16094332d3Sopenharmony_ci#include "audio_mixer.h" 17094332d3Sopenharmony_ci 18094332d3Sopenharmony_ci#include <assert.h> 19094332d3Sopenharmony_ci#include <ctype.h> 20094332d3Sopenharmony_ci#include <dlfcn.h> 21094332d3Sopenharmony_ci#include <errno.h> 22094332d3Sopenharmony_ci#include <limits.h> 23094332d3Sopenharmony_ci#include <string.h> 24094332d3Sopenharmony_ci#include <strings.h> 25094332d3Sopenharmony_ci#include <stdio.h> 26094332d3Sopenharmony_ci#include <stdlib.h> 27094332d3Sopenharmony_ci#include <unistd.h> 28094332d3Sopenharmony_ci 29094332d3Sopenharmony_ci#include "hdf_base.h" 30094332d3Sopenharmony_ci#include "securec.h" 31094332d3Sopenharmony_ci 32094332d3Sopenharmony_ci#define AUDIO_UTIL_VERSION_STR "V1.0.0" 33094332d3Sopenharmony_ci 34094332d3Sopenharmony_ci#define AUDIO_DEV_FILE_PATH "/dev/" 35094332d3Sopenharmony_ci#define CTL_SRV_NAME_PRE "hdf_audio_control" 36094332d3Sopenharmony_ci#define CTL_SRV_DEFAULT CTL_SRV_NAME_PRE 37094332d3Sopenharmony_ci#define MIXER_SRV_NAME_PRE "hdf_audio_codec_" 38094332d3Sopenharmony_ci#define MIXER_SRV_NAME MIXER_SRV_NAME_PRE "%s_dev%i" 39094332d3Sopenharmony_ci#define MIXER_SRV_NAME_DEFAULT MIXER_SRV_NAME_PRE "primary_dev0" 40094332d3Sopenharmony_ci#define SERVICE_NAME_LEN 64 41094332d3Sopenharmony_ci#define BUF_SIZE_T 256 42094332d3Sopenharmony_ci#define CHN_MONO (1 << 0) 43094332d3Sopenharmony_ci#define CHN_STEREO (1 << 1) 44094332d3Sopenharmony_ci#define OUTPUT_ALIGN 16 45094332d3Sopenharmony_ci#define BIT_VALULE_OFFSET 31 46094332d3Sopenharmony_ci#define STRTOL_BASE 10 47094332d3Sopenharmony_ci 48094332d3Sopenharmony_ci#define IFACE(v) [AUDIO_CTL_ELEM_IFACE_##v] = #v 49094332d3Sopenharmony_ci#define TYPE(v) [AUDIO_CTL_ELEM_TYPE_##v] = #v 50094332d3Sopenharmony_ci 51094332d3Sopenharmony_cistatic struct AudioMixer g_audioMixer; 52094332d3Sopenharmony_cistatic struct AudioMixerContents g_mixerCts; 53094332d3Sopenharmony_ci 54094332d3Sopenharmony_cistatic const char *g_capLibPath = HDF_LIBRARY_FULL_PATH("libaudio_capture_adapter"); 55094332d3Sopenharmony_cistatic const char *g_renLibPath = HDF_LIBRARY_FULL_PATH("libaudio_render_adapter"); 56094332d3Sopenharmony_cistatic void *g_soHandle = NULL; 57094332d3Sopenharmony_cistatic AudioPcmType g_pcmT = PCM_RENDER; 58094332d3Sopenharmony_cistatic bool g_debugFlag = false; 59094332d3Sopenharmony_ci 60094332d3Sopenharmony_cistatic const char * const ctlEIfNames[] = { 61094332d3Sopenharmony_ci IFACE(CARD), 62094332d3Sopenharmony_ci IFACE(PCM), 63094332d3Sopenharmony_ci IFACE(MIXER), 64094332d3Sopenharmony_ci}; 65094332d3Sopenharmony_ci 66094332d3Sopenharmony_cistatic const char * const ctlElemTypeNames[] = { 67094332d3Sopenharmony_ci TYPE(NONE), 68094332d3Sopenharmony_ci TYPE(BOOLEAN), 69094332d3Sopenharmony_ci TYPE(INTEGER), 70094332d3Sopenharmony_ci TYPE(ENUMERATED), 71094332d3Sopenharmony_ci TYPE(BYTES), 72094332d3Sopenharmony_ci}; 73094332d3Sopenharmony_ci 74094332d3Sopenharmony_civoid DebugLog(bool flag) 75094332d3Sopenharmony_ci{ 76094332d3Sopenharmony_ci g_debugFlag = flag; 77094332d3Sopenharmony_ci} 78094332d3Sopenharmony_ci 79094332d3Sopenharmony_cistatic void *CallLibFunction(const char *funcName) 80094332d3Sopenharmony_ci{ 81094332d3Sopenharmony_ci void *func = NULL; 82094332d3Sopenharmony_ci char *error = NULL; 83094332d3Sopenharmony_ci 84094332d3Sopenharmony_ci if (g_soHandle == NULL) { 85094332d3Sopenharmony_ci DEBUG_LOG("Invalid dynamic library handle!\n"); 86094332d3Sopenharmony_ci return NULL; 87094332d3Sopenharmony_ci } 88094332d3Sopenharmony_ci 89094332d3Sopenharmony_ci (void)dlerror(); /* Clear any existing error */ 90094332d3Sopenharmony_ci func = dlsym(g_soHandle, funcName); 91094332d3Sopenharmony_ci error = dlerror(); 92094332d3Sopenharmony_ci if (error != NULL) { 93094332d3Sopenharmony_ci DEBUG_LOG("%s\n", error); 94094332d3Sopenharmony_ci printf("%s\n", error); 95094332d3Sopenharmony_ci return NULL; 96094332d3Sopenharmony_ci } 97094332d3Sopenharmony_ci 98094332d3Sopenharmony_ci return func; 99094332d3Sopenharmony_ci} 100094332d3Sopenharmony_ci 101094332d3Sopenharmony_cistatic int32_t AudioMixerList(const struct HdfIoService *service, struct AudioMixerContents *mixerCts) 102094332d3Sopenharmony_ci{ 103094332d3Sopenharmony_ci int32_t (*AmixerCtlElemList)(AudioPcmType, const struct HdfIoService *, struct AudioMixerContents *); 104094332d3Sopenharmony_ci 105094332d3Sopenharmony_ci AmixerCtlElemList = CallLibFunction("AudioMixerCtlElem"); 106094332d3Sopenharmony_ci if (AmixerCtlElemList == NULL) { 107094332d3Sopenharmony_ci return U_FAILURE; 108094332d3Sopenharmony_ci } 109094332d3Sopenharmony_ci 110094332d3Sopenharmony_ci return AmixerCtlElemList(g_pcmT, service, mixerCts); 111094332d3Sopenharmony_ci} 112094332d3Sopenharmony_ci 113094332d3Sopenharmony_cistatic int32_t AudioMixerGet(const struct HdfIoService *service, struct AudioMixerCtlElemInfo *infoData) 114094332d3Sopenharmony_ci{ 115094332d3Sopenharmony_ci int32_t (*AmixerGetCtlElem)(AudioPcmType, const struct HdfIoService *, struct AudioMixerCtlElemInfo *); 116094332d3Sopenharmony_ci 117094332d3Sopenharmony_ci AmixerGetCtlElem = CallLibFunction("AudioMixerCtlGetElem"); 118094332d3Sopenharmony_ci if (AmixerGetCtlElem == NULL) { 119094332d3Sopenharmony_ci return U_FAILURE; 120094332d3Sopenharmony_ci } 121094332d3Sopenharmony_ci 122094332d3Sopenharmony_ci return AmixerGetCtlElem(g_pcmT, service, infoData); 123094332d3Sopenharmony_ci} 124094332d3Sopenharmony_ci 125094332d3Sopenharmony_cistatic int32_t AudioMixerSet(const struct HdfIoService *service, struct AudioMixerCtlElemInfo *infoData) 126094332d3Sopenharmony_ci{ 127094332d3Sopenharmony_ci int32_t (*AmixerSetCtlElem)(AudioPcmType, const struct HdfIoService *, struct AudioMixerCtlElemInfo *); 128094332d3Sopenharmony_ci 129094332d3Sopenharmony_ci AmixerSetCtlElem = CallLibFunction("AudioMixerCtlSetElem"); 130094332d3Sopenharmony_ci if (AmixerSetCtlElem == NULL) { 131094332d3Sopenharmony_ci return U_FAILURE; 132094332d3Sopenharmony_ci } 133094332d3Sopenharmony_ci 134094332d3Sopenharmony_ci return AmixerSetCtlElem(g_pcmT, service, infoData); 135094332d3Sopenharmony_ci} 136094332d3Sopenharmony_ci 137094332d3Sopenharmony_cistatic int32_t GetSoHandle(const char *filename) 138094332d3Sopenharmony_ci{ 139094332d3Sopenharmony_ci char buf[PATH_MAX] = {0}; 140094332d3Sopenharmony_ci 141094332d3Sopenharmony_ci if (realpath(filename, buf) == NULL) { 142094332d3Sopenharmony_ci return U_FAILURE; 143094332d3Sopenharmony_ci } 144094332d3Sopenharmony_ci 145094332d3Sopenharmony_ci if (g_soHandle != NULL) { 146094332d3Sopenharmony_ci DEBUG_LOG("It's been initialized!\n"); 147094332d3Sopenharmony_ci return U_SUCCESS; 148094332d3Sopenharmony_ci } 149094332d3Sopenharmony_ci 150094332d3Sopenharmony_ci g_soHandle = dlopen(buf, RTLD_LAZY); 151094332d3Sopenharmony_ci if (g_soHandle == NULL) { 152094332d3Sopenharmony_ci DEBUG_LOG("%s\n", dlerror()); 153094332d3Sopenharmony_ci printf("%s\n", dlerror()); 154094332d3Sopenharmony_ci return U_FAILURE; 155094332d3Sopenharmony_ci } 156094332d3Sopenharmony_ci 157094332d3Sopenharmony_ci return U_SUCCESS; 158094332d3Sopenharmony_ci} 159094332d3Sopenharmony_ci 160094332d3Sopenharmony_ciint32_t GetLibsoHandle(AudioPcmType pcm) 161094332d3Sopenharmony_ci{ 162094332d3Sopenharmony_ci int32_t ret; 163094332d3Sopenharmony_ci 164094332d3Sopenharmony_ci g_pcmT = pcm; 165094332d3Sopenharmony_ci switch (pcm) { 166094332d3Sopenharmony_ci default: 167094332d3Sopenharmony_ci DEBUG_LOG("Wrong PCM type!\n"); 168094332d3Sopenharmony_ci /* fall through */ 169094332d3Sopenharmony_ci __attribute__((fallthrough)); 170094332d3Sopenharmony_ci case PCM_RENDER: 171094332d3Sopenharmony_ci ret = GetSoHandle(g_renLibPath); 172094332d3Sopenharmony_ci if (ret != U_SUCCESS) { 173094332d3Sopenharmony_ci DEBUG_LOG("Failed to open the render dynamic library!\n"); 174094332d3Sopenharmony_ci } 175094332d3Sopenharmony_ci break; 176094332d3Sopenharmony_ci case PCM_CAPTURE: 177094332d3Sopenharmony_ci ret = GetSoHandle(g_capLibPath); 178094332d3Sopenharmony_ci if (ret != U_SUCCESS) { 179094332d3Sopenharmony_ci DEBUG_LOG("Failed to open the capture dynamic library!\n"); 180094332d3Sopenharmony_ci } 181094332d3Sopenharmony_ci break; 182094332d3Sopenharmony_ci } 183094332d3Sopenharmony_ci 184094332d3Sopenharmony_ci return ret; 185094332d3Sopenharmony_ci} 186094332d3Sopenharmony_ci 187094332d3Sopenharmony_civoid CloseLibsoHandle(void) 188094332d3Sopenharmony_ci{ 189094332d3Sopenharmony_ci if (g_soHandle != NULL) { 190094332d3Sopenharmony_ci (void)dlclose(g_soHandle); 191094332d3Sopenharmony_ci g_soHandle = NULL; 192094332d3Sopenharmony_ci } 193094332d3Sopenharmony_ci} 194094332d3Sopenharmony_ci 195094332d3Sopenharmony_civoid AudioMixerOpsInit(void) 196094332d3Sopenharmony_ci{ 197094332d3Sopenharmony_ci g_audioMixer.GetElemList = AudioMixerList; 198094332d3Sopenharmony_ci g_audioMixer.GetElemProp = AudioMixerGet; 199094332d3Sopenharmony_ci g_audioMixer.SetElemProp = AudioMixerSet; 200094332d3Sopenharmony_ci 201094332d3Sopenharmony_ci g_mixerCts.data = NULL; 202094332d3Sopenharmony_ci g_mixerCts.elemNum = 0; 203094332d3Sopenharmony_ci (void)memset_s(g_mixerCts.cardServiceName, AUDIO_CARD_SRV_NAME_LEN, 0x0, AUDIO_CARD_SRV_NAME_LEN); 204094332d3Sopenharmony_ci} 205094332d3Sopenharmony_ci 206094332d3Sopenharmony_ciconst char *ShowVersion(void) 207094332d3Sopenharmony_ci{ 208094332d3Sopenharmony_ci return AUDIO_UTIL_VERSION_STR; 209094332d3Sopenharmony_ci} 210094332d3Sopenharmony_ci 211094332d3Sopenharmony_cistatic bool CheckMixerDevFile(const char *file) 212094332d3Sopenharmony_ci{ 213094332d3Sopenharmony_ci char buf[PATH_MAX] = {0}; 214094332d3Sopenharmony_ci 215094332d3Sopenharmony_ci if (realpath(file, buf) == NULL) { 216094332d3Sopenharmony_ci DEBUG_LOG("%s\n", strerror(errno)); 217094332d3Sopenharmony_ci return false; 218094332d3Sopenharmony_ci } 219094332d3Sopenharmony_ci 220094332d3Sopenharmony_ci if (access(file, F_OK)) { 221094332d3Sopenharmony_ci DEBUG_LOG("%s\n", strerror(errno)); 222094332d3Sopenharmony_ci return false; 223094332d3Sopenharmony_ci } 224094332d3Sopenharmony_ci 225094332d3Sopenharmony_ci return true; 226094332d3Sopenharmony_ci} 227094332d3Sopenharmony_ci 228094332d3Sopenharmony_cistruct HdfIoService *MixerBindCrlSrvDefault(void) 229094332d3Sopenharmony_ci{ 230094332d3Sopenharmony_ci int ret; 231094332d3Sopenharmony_ci char buf[BUF_SIZE_T + 1] = {0}; 232094332d3Sopenharmony_ci struct HdfIoService *(*SrvBindDef)(const char *); 233094332d3Sopenharmony_ci 234094332d3Sopenharmony_ci ret = snprintf_s(buf, BUF_SIZE_T, BUF_SIZE_T, "%s%s", AUDIO_DEV_FILE_PATH, MIXER_SRV_NAME_DEFAULT); 235094332d3Sopenharmony_ci if (ret < 0) { 236094332d3Sopenharmony_ci DEBUG_LOG("Failed to synthesize the service path!\n"); 237094332d3Sopenharmony_ci return NULL; 238094332d3Sopenharmony_ci } 239094332d3Sopenharmony_ci 240094332d3Sopenharmony_ci if (!CheckMixerDevFile(buf)) { 241094332d3Sopenharmony_ci /* The sound card service file does not exist */ 242094332d3Sopenharmony_ci return NULL; 243094332d3Sopenharmony_ci } 244094332d3Sopenharmony_ci 245094332d3Sopenharmony_ci SrvBindDef = CallLibFunction("HdfIoServiceBindName"); 246094332d3Sopenharmony_ci if (SrvBindDef == NULL) { 247094332d3Sopenharmony_ci return NULL; 248094332d3Sopenharmony_ci } 249094332d3Sopenharmony_ci 250094332d3Sopenharmony_ci return SrvBindDef(CTL_SRV_DEFAULT); 251094332d3Sopenharmony_ci} 252094332d3Sopenharmony_ci 253094332d3Sopenharmony_cistruct HdfIoService *MixerBindCrlSrv(const char *serviceName) 254094332d3Sopenharmony_ci{ 255094332d3Sopenharmony_ci int ret; 256094332d3Sopenharmony_ci char path[BUF_SIZE_T + 1] = {0}; 257094332d3Sopenharmony_ci struct HdfIoService *(*SrvBind)(const char *); 258094332d3Sopenharmony_ci 259094332d3Sopenharmony_ci if (serviceName == NULL) { 260094332d3Sopenharmony_ci DEBUG_LOG("Invalid parameters!\n"); 261094332d3Sopenharmony_ci return NULL; 262094332d3Sopenharmony_ci } 263094332d3Sopenharmony_ci 264094332d3Sopenharmony_ci if (strncmp(serviceName, MIXER_SRV_NAME_PRE, strlen(MIXER_SRV_NAME_PRE))) { 265094332d3Sopenharmony_ci DEBUG_LOG("The service name does not match!\n"); 266094332d3Sopenharmony_ci return NULL; 267094332d3Sopenharmony_ci } 268094332d3Sopenharmony_ci 269094332d3Sopenharmony_ci ret = snprintf_s(path, BUF_SIZE_T, BUF_SIZE_T, "%s%s", AUDIO_DEV_FILE_PATH, serviceName); 270094332d3Sopenharmony_ci if (ret < 0) { 271094332d3Sopenharmony_ci DEBUG_LOG("Failed to synthesize the service path!\n"); 272094332d3Sopenharmony_ci return NULL; 273094332d3Sopenharmony_ci } 274094332d3Sopenharmony_ci if (!CheckMixerDevFile(path)) { 275094332d3Sopenharmony_ci /* The sound card service file does not exist */ 276094332d3Sopenharmony_ci return NULL; 277094332d3Sopenharmony_ci } 278094332d3Sopenharmony_ci 279094332d3Sopenharmony_ci SrvBind = CallLibFunction("HdfIoServiceBindName"); 280094332d3Sopenharmony_ci if (SrvBind == NULL) { 281094332d3Sopenharmony_ci return NULL; 282094332d3Sopenharmony_ci } 283094332d3Sopenharmony_ci 284094332d3Sopenharmony_ci return SrvBind(CTL_SRV_DEFAULT); 285094332d3Sopenharmony_ci} 286094332d3Sopenharmony_ci 287094332d3Sopenharmony_civoid MixerRecycleCrlSrv(struct HdfIoService *srv) 288094332d3Sopenharmony_ci{ 289094332d3Sopenharmony_ci void (*SrvRecycle)(struct HdfIoService *); 290094332d3Sopenharmony_ci 291094332d3Sopenharmony_ci if (srv != NULL) { 292094332d3Sopenharmony_ci SrvRecycle = CallLibFunction("AudioCloseServiceSub"); 293094332d3Sopenharmony_ci if (SrvRecycle != NULL) { 294094332d3Sopenharmony_ci SrvRecycle(srv); 295094332d3Sopenharmony_ci } 296094332d3Sopenharmony_ci } 297094332d3Sopenharmony_ci} 298094332d3Sopenharmony_ci 299094332d3Sopenharmony_cistatic const char *CtlElemIfaceName(AudioCtlElemIfaceType iface) 300094332d3Sopenharmony_ci{ 301094332d3Sopenharmony_ci return ctlEIfNames[iface]; 302094332d3Sopenharmony_ci} 303094332d3Sopenharmony_ci 304094332d3Sopenharmony_cistatic const char *CtlElemName(struct AudioHwCtlElemIndex *id) 305094332d3Sopenharmony_ci{ 306094332d3Sopenharmony_ci return (const char *)id->eId.name; 307094332d3Sopenharmony_ci} 308094332d3Sopenharmony_ci 309094332d3Sopenharmony_cistatic void PrintCtlElemInfo(struct AudioHwCtlElemId *id) 310094332d3Sopenharmony_ci{ 311094332d3Sopenharmony_ci printf("iface=%s, name='%s'\n", CtlElemIfaceName(id->iface), id->name); 312094332d3Sopenharmony_ci} 313094332d3Sopenharmony_ci 314094332d3Sopenharmony_cistatic void PrintCtlElemInfoidx(struct MixerCtsElemIdx *eidx) 315094332d3Sopenharmony_ci{ 316094332d3Sopenharmony_ci printf("index=%u, numid=%u, ", eidx->index, eidx->index + 1); 317094332d3Sopenharmony_ci PrintCtlElemInfo(eidx->id); 318094332d3Sopenharmony_ci} 319094332d3Sopenharmony_ci 320094332d3Sopenharmony_cistatic void PrintCtlElemList(struct AudioMixerContents *contents) 321094332d3Sopenharmony_ci{ 322094332d3Sopenharmony_ci uint32_t num, idx; 323094332d3Sopenharmony_ci struct MixerCtsElemIdx eidx; 324094332d3Sopenharmony_ci struct AudioHwCtlElemId *id = NULL; 325094332d3Sopenharmony_ci 326094332d3Sopenharmony_ci num = contents->elemNum; 327094332d3Sopenharmony_ci id = (struct AudioHwCtlElemId *)contents->data; 328094332d3Sopenharmony_ci for (idx = 0; idx < num; idx++) { 329094332d3Sopenharmony_ci eidx.id = id++; 330094332d3Sopenharmony_ci eidx.index = idx; 331094332d3Sopenharmony_ci PrintCtlElemInfoidx(&eidx); 332094332d3Sopenharmony_ci } 333094332d3Sopenharmony_ci} 334094332d3Sopenharmony_ci 335094332d3Sopenharmony_civoid ReleaseCtlElemList(void) 336094332d3Sopenharmony_ci{ 337094332d3Sopenharmony_ci if (g_mixerCts.data != NULL) { 338094332d3Sopenharmony_ci free(g_mixerCts.data); 339094332d3Sopenharmony_ci g_mixerCts.data = NULL; 340094332d3Sopenharmony_ci } 341094332d3Sopenharmony_ci g_mixerCts.elemNum = 0; 342094332d3Sopenharmony_ci (void)memset_s(g_mixerCts.cardServiceName, AUDIO_CARD_SRV_NAME_LEN, 0x0, AUDIO_CARD_SRV_NAME_LEN); 343094332d3Sopenharmony_ci} 344094332d3Sopenharmony_ci 345094332d3Sopenharmony_cistatic int32_t MctlListSub(const struct HdfIoService *service, const char *cardSrv) 346094332d3Sopenharmony_ci{ 347094332d3Sopenharmony_ci int32_t ret; 348094332d3Sopenharmony_ci 349094332d3Sopenharmony_ci ret = strncpy_s(g_mixerCts.cardServiceName, AUDIO_CARD_SRV_NAME_LEN - 1, cardSrv, AUDIO_CARD_SRV_NAME_LEN - 1); 350094332d3Sopenharmony_ci if (ret != 0) { 351094332d3Sopenharmony_ci DEBUG_LOG("strncpy_s fail!\n"); 352094332d3Sopenharmony_ci return U_FAILURE; 353094332d3Sopenharmony_ci } 354094332d3Sopenharmony_ci g_mixerCts.cardServiceName[AUDIO_CARD_SRV_NAME_LEN - 1] = '\0'; 355094332d3Sopenharmony_ci if (g_audioMixer.GetElemList == NULL) { 356094332d3Sopenharmony_ci DEBUG_LOG("The callback function is NULL!\n"); 357094332d3Sopenharmony_ci return U_FAILURE; 358094332d3Sopenharmony_ci } 359094332d3Sopenharmony_ci 360094332d3Sopenharmony_ci if (g_mixerCts.data != NULL && g_mixerCts.elemNum > 0) { 361094332d3Sopenharmony_ci /* The list of control elements has been obtained */ 362094332d3Sopenharmony_ci return U_SUCCESS; 363094332d3Sopenharmony_ci } 364094332d3Sopenharmony_ci 365094332d3Sopenharmony_ci if (g_mixerCts.data != NULL) { 366094332d3Sopenharmony_ci free(g_mixerCts.data); 367094332d3Sopenharmony_ci g_mixerCts.data = NULL; 368094332d3Sopenharmony_ci } 369094332d3Sopenharmony_ci g_mixerCts.elemNum = 0; 370094332d3Sopenharmony_ci 371094332d3Sopenharmony_ci ret = g_audioMixer.GetElemList(service, &g_mixerCts); 372094332d3Sopenharmony_ci if (ret != U_SUCCESS) { 373094332d3Sopenharmony_ci return ret; 374094332d3Sopenharmony_ci } 375094332d3Sopenharmony_ci if (g_mixerCts.data == NULL) { 376094332d3Sopenharmony_ci g_mixerCts.elemNum = 0; 377094332d3Sopenharmony_ci (void)memset_s(g_mixerCts.cardServiceName, AUDIO_CARD_SRV_NAME_LEN, 0x0, AUDIO_CARD_SRV_NAME_LEN); 378094332d3Sopenharmony_ci DEBUG_LOG("Failed to obtain data!\n"); 379094332d3Sopenharmony_ci return U_FAILURE; 380094332d3Sopenharmony_ci } 381094332d3Sopenharmony_ci if (g_mixerCts.elemNum == 0) { 382094332d3Sopenharmony_ci free(g_mixerCts.data); 383094332d3Sopenharmony_ci g_mixerCts.data = NULL; 384094332d3Sopenharmony_ci (void)memset_s(g_mixerCts.cardServiceName, AUDIO_CARD_SRV_NAME_LEN, 0x0, AUDIO_CARD_SRV_NAME_LEN); 385094332d3Sopenharmony_ci DEBUG_LOG("Description Failed to obtain the number of data!\n"); 386094332d3Sopenharmony_ci return U_FAILURE; 387094332d3Sopenharmony_ci } 388094332d3Sopenharmony_ci 389094332d3Sopenharmony_ci return U_SUCCESS; 390094332d3Sopenharmony_ci} 391094332d3Sopenharmony_ci 392094332d3Sopenharmony_ciint32_t MctlList(const struct HdfIoService *service, const char *cardSrv) 393094332d3Sopenharmony_ci{ 394094332d3Sopenharmony_ci int32_t ret; 395094332d3Sopenharmony_ci 396094332d3Sopenharmony_ci if (service == NULL || cardSrv == NULL) { 397094332d3Sopenharmony_ci DEBUG_LOG("Invalid parameters!\n"); 398094332d3Sopenharmony_ci return U_INVALID_PARAM; 399094332d3Sopenharmony_ci } 400094332d3Sopenharmony_ci 401094332d3Sopenharmony_ci ret = MctlListSub(service, cardSrv); 402094332d3Sopenharmony_ci if (ret != U_SUCCESS) { 403094332d3Sopenharmony_ci return ret; 404094332d3Sopenharmony_ci } 405094332d3Sopenharmony_ci PrintCtlElemList(&g_mixerCts); 406094332d3Sopenharmony_ci 407094332d3Sopenharmony_ci return U_SUCCESS; 408094332d3Sopenharmony_ci} 409094332d3Sopenharmony_ci 410094332d3Sopenharmony_ciint32_t MctlInfo(const struct HdfIoService *service, const char *cardSrv) 411094332d3Sopenharmony_ci{ 412094332d3Sopenharmony_ci int32_t ret; 413094332d3Sopenharmony_ci uint32_t num; 414094332d3Sopenharmony_ci struct AudioHwCtlElemId *id; 415094332d3Sopenharmony_ci 416094332d3Sopenharmony_ci if (g_mixerCts.data == NULL || g_mixerCts.elemNum == 0) { 417094332d3Sopenharmony_ci ReleaseCtlElemList(); 418094332d3Sopenharmony_ci ret = MctlListSub(service, cardSrv); 419094332d3Sopenharmony_ci if (ret != U_SUCCESS) { 420094332d3Sopenharmony_ci DEBUG_LOG("No reference data\n"); 421094332d3Sopenharmony_ci return ret; 422094332d3Sopenharmony_ci } 423094332d3Sopenharmony_ci } 424094332d3Sopenharmony_ci 425094332d3Sopenharmony_ci /* The list of control elements has been obtained */ 426094332d3Sopenharmony_ci num = g_mixerCts.elemNum; 427094332d3Sopenharmony_ci id = (struct AudioHwCtlElemId *)g_mixerCts.data; 428094332d3Sopenharmony_ci while (num--) { 429094332d3Sopenharmony_ci PrintCtlElemInfo(id++); 430094332d3Sopenharmony_ci } 431094332d3Sopenharmony_ci ReleaseCtlElemList(); 432094332d3Sopenharmony_ci 433094332d3Sopenharmony_ci return U_SUCCESS; 434094332d3Sopenharmony_ci} 435094332d3Sopenharmony_ci 436094332d3Sopenharmony_cibool MixerFindSelem(const struct HdfIoService *srv, const char *cardSrv, const struct AudioHwCtlElemId *eId) 437094332d3Sopenharmony_ci{ 438094332d3Sopenharmony_ci int32_t ret; 439094332d3Sopenharmony_ci uint32_t index; 440094332d3Sopenharmony_ci struct AudioHwCtlElemId *findElem; 441094332d3Sopenharmony_ci 442094332d3Sopenharmony_ci if (eId == NULL) { 443094332d3Sopenharmony_ci DEBUG_LOG("Invalid parameters\n"); 444094332d3Sopenharmony_ci return false; 445094332d3Sopenharmony_ci } 446094332d3Sopenharmony_ci 447094332d3Sopenharmony_ci if (g_mixerCts.elemNum == 0 || g_mixerCts.data == NULL) { 448094332d3Sopenharmony_ci ReleaseCtlElemList(); 449094332d3Sopenharmony_ci ret = MctlListSub(srv, cardSrv); 450094332d3Sopenharmony_ci if (ret != U_SUCCESS) { 451094332d3Sopenharmony_ci DEBUG_LOG("No reference data\n"); 452094332d3Sopenharmony_ci return false; 453094332d3Sopenharmony_ci } 454094332d3Sopenharmony_ci } 455094332d3Sopenharmony_ci 456094332d3Sopenharmony_ci findElem = g_mixerCts.data; 457094332d3Sopenharmony_ci for (index = 0; index < g_mixerCts.elemNum; index++) { 458094332d3Sopenharmony_ci if (strcmp(eId->name, findElem[index].name) == 0) { 459094332d3Sopenharmony_ci break; 460094332d3Sopenharmony_ci } 461094332d3Sopenharmony_ci } 462094332d3Sopenharmony_ci if (index == g_mixerCts.elemNum) { 463094332d3Sopenharmony_ci DEBUG_LOG("The corresponding control does not match!\n"); 464094332d3Sopenharmony_ci ReleaseCtlElemList(); 465094332d3Sopenharmony_ci return false; 466094332d3Sopenharmony_ci } 467094332d3Sopenharmony_ci ReleaseCtlElemList(); 468094332d3Sopenharmony_ci 469094332d3Sopenharmony_ci return true; 470094332d3Sopenharmony_ci} 471094332d3Sopenharmony_ci 472094332d3Sopenharmony_cistatic AudioCtlElemIfaceType GetCtlElemIface(struct AudioHwCtlElemIndex *id) 473094332d3Sopenharmony_ci{ 474094332d3Sopenharmony_ci return id->eId.iface; 475094332d3Sopenharmony_ci} 476094332d3Sopenharmony_ci 477094332d3Sopenharmony_cistatic unsigned int CtlElemGetIdx(struct AudioHwCtlElemIndex *id) 478094332d3Sopenharmony_ci{ 479094332d3Sopenharmony_ci return id->index; 480094332d3Sopenharmony_ci} 481094332d3Sopenharmony_ci 482094332d3Sopenharmony_cistatic unsigned int CtlElemInfoCnt(struct AudioMixerCtlElemInfo *info) 483094332d3Sopenharmony_ci{ 484094332d3Sopenharmony_ci return info->count; 485094332d3Sopenharmony_ci} 486094332d3Sopenharmony_ci 487094332d3Sopenharmony_cistatic AudioCtlElemType CtlElemGetInfoType(struct AudioMixerCtlElemInfo *info) 488094332d3Sopenharmony_ci{ 489094332d3Sopenharmony_ci return info->type; 490094332d3Sopenharmony_ci} 491094332d3Sopenharmony_ci 492094332d3Sopenharmony_cistatic const char *CtlElemTypeName(AudioCtlElemType type) 493094332d3Sopenharmony_ci{ 494094332d3Sopenharmony_ci return ctlElemTypeNames[type]; 495094332d3Sopenharmony_ci} 496094332d3Sopenharmony_ci 497094332d3Sopenharmony_cistatic const char *MixerCtlType(struct AudioMixerCtlElemInfo *info) 498094332d3Sopenharmony_ci{ 499094332d3Sopenharmony_ci return CtlElemTypeName(CtlElemGetInfoType(info)); 500094332d3Sopenharmony_ci} 501094332d3Sopenharmony_ci 502094332d3Sopenharmony_cistatic int32_t CtlElemInfoGetMin(struct AudioMixerCtlElemInfo *info) 503094332d3Sopenharmony_ci{ 504094332d3Sopenharmony_ci return info->value.intVal.min; 505094332d3Sopenharmony_ci} 506094332d3Sopenharmony_ci 507094332d3Sopenharmony_cistatic int32_t CtlElemInfoGetMax(struct AudioMixerCtlElemInfo *info) 508094332d3Sopenharmony_ci{ 509094332d3Sopenharmony_ci return info->value.intVal.max; 510094332d3Sopenharmony_ci} 511094332d3Sopenharmony_ci 512094332d3Sopenharmony_cistatic int32_t CtlElemInfoGetStep(struct AudioMixerCtlElemInfo *info) 513094332d3Sopenharmony_ci{ 514094332d3Sopenharmony_ci return info->value.intVal.step; 515094332d3Sopenharmony_ci} 516094332d3Sopenharmony_ci 517094332d3Sopenharmony_cistatic long *CtlElemInfoGetVals(struct AudioMixerCtlElemInfo *info) 518094332d3Sopenharmony_ci{ 519094332d3Sopenharmony_ci return info->value.intVal.vals; 520094332d3Sopenharmony_ci} 521094332d3Sopenharmony_ci 522094332d3Sopenharmony_cistatic void CtlElemInfoSetItem(struct AudioMixerCtlElemInfo *info, uint32_t val) 523094332d3Sopenharmony_ci{ 524094332d3Sopenharmony_ci info->value.enumVal.item = val; 525094332d3Sopenharmony_ci} 526094332d3Sopenharmony_ci 527094332d3Sopenharmony_cistatic uint32_t CtlElemInfoGetItems(struct AudioMixerCtlElemInfo *info) 528094332d3Sopenharmony_ci{ 529094332d3Sopenharmony_ci return info->value.enumVal.items; 530094332d3Sopenharmony_ci} 531094332d3Sopenharmony_ci 532094332d3Sopenharmony_cistatic uint32_t CtlElemInfoGetItem(struct AudioMixerCtlElemInfo *info) 533094332d3Sopenharmony_ci{ 534094332d3Sopenharmony_ci return info->value.enumVal.item; 535094332d3Sopenharmony_ci} 536094332d3Sopenharmony_ci 537094332d3Sopenharmony_cistatic char *CtlElemInfoGetItemName(struct AudioMixerCtlElemInfo *info) 538094332d3Sopenharmony_ci{ 539094332d3Sopenharmony_ci return info->value.enumVal.name; 540094332d3Sopenharmony_ci} 541094332d3Sopenharmony_ci 542094332d3Sopenharmony_cistatic int32_t CtlElemValueGetBoolean(struct AudioMixerCtlElemInfo *info, uint32_t idx) 543094332d3Sopenharmony_ci{ 544094332d3Sopenharmony_ci if (idx > BIT_VALULE_OFFSET - 1) { 545094332d3Sopenharmony_ci return 0; 546094332d3Sopenharmony_ci } 547094332d3Sopenharmony_ci 548094332d3Sopenharmony_ci return ((info->value.intVal.max >> idx) & 0x1); 549094332d3Sopenharmony_ci} 550094332d3Sopenharmony_ci 551094332d3Sopenharmony_cistatic int32_t CtlElemValueGetInt(struct AudioMixerCtlElemInfo *info, uint32_t idx) 552094332d3Sopenharmony_ci{ 553094332d3Sopenharmony_ci return CtlElemValueGetBoolean(info, idx); 554094332d3Sopenharmony_ci} 555094332d3Sopenharmony_ci 556094332d3Sopenharmony_cistatic char CtlElemValueGetByte(struct AudioMixerCtlElemInfo *info, uint32_t idx) 557094332d3Sopenharmony_ci{ 558094332d3Sopenharmony_ci if (idx >= RESERVED_BUF_LEN) { 559094332d3Sopenharmony_ci return '?'; 560094332d3Sopenharmony_ci } 561094332d3Sopenharmony_ci 562094332d3Sopenharmony_ci return info->value.reserved[idx]; 563094332d3Sopenharmony_ci} 564094332d3Sopenharmony_ci 565094332d3Sopenharmony_cistatic unsigned char *CtlElemValueGetBytes(struct AudioMixerCtlElemInfo *info) 566094332d3Sopenharmony_ci{ 567094332d3Sopenharmony_ci return info->value.reserved; 568094332d3Sopenharmony_ci} 569094332d3Sopenharmony_ci 570094332d3Sopenharmony_cistatic uint32_t CtlElemValueGetEnum(struct AudioMixerCtlElemInfo *info, uint32_t idx) 571094332d3Sopenharmony_ci{ 572094332d3Sopenharmony_ci if (idx > BIT_VALULE_OFFSET) { 573094332d3Sopenharmony_ci return 0; 574094332d3Sopenharmony_ci } 575094332d3Sopenharmony_ci 576094332d3Sopenharmony_ci return ((info->value.enumVal.item >> idx) & 0x1); 577094332d3Sopenharmony_ci} 578094332d3Sopenharmony_ci 579094332d3Sopenharmony_cistatic void PrintOtherVal(struct AudioMixerCtlElemInfo *info) 580094332d3Sopenharmony_ci{ 581094332d3Sopenharmony_ci uint32_t idx; 582094332d3Sopenharmony_ci unsigned int count; 583094332d3Sopenharmony_ci AudioCtlElemType type; 584094332d3Sopenharmony_ci 585094332d3Sopenharmony_ci type = CtlElemGetInfoType(info); 586094332d3Sopenharmony_ci count = CtlElemInfoCnt(info); 587094332d3Sopenharmony_ci for (idx = 0; idx < count; idx++) { 588094332d3Sopenharmony_ci if (idx > 0) { 589094332d3Sopenharmony_ci printf(", "); 590094332d3Sopenharmony_ci } 591094332d3Sopenharmony_ci 592094332d3Sopenharmony_ci switch (type) { 593094332d3Sopenharmony_ci case AUDIO_CTL_ELEM_TYPE_BOOLEAN: 594094332d3Sopenharmony_ci printf("%s", CtlElemValueGetBoolean(info, idx) ? "on" : "off"); 595094332d3Sopenharmony_ci break; 596094332d3Sopenharmony_ci case AUDIO_CTL_ELEM_TYPE_BYTES: 597094332d3Sopenharmony_ci printf("0x%02x", CtlElemValueGetByte(info, idx)); 598094332d3Sopenharmony_ci break; 599094332d3Sopenharmony_ci case AUDIO_CTL_ELEM_TYPE_INTEGER: 600094332d3Sopenharmony_ci printf("%i", CtlElemValueGetInt(info, idx)); 601094332d3Sopenharmony_ci break; 602094332d3Sopenharmony_ci case AUDIO_CTL_ELEM_TYPE_ENUMERATED: 603094332d3Sopenharmony_ci printf("%u", CtlElemValueGetEnum(info, idx)); 604094332d3Sopenharmony_ci break; 605094332d3Sopenharmony_ci default: 606094332d3Sopenharmony_ci printf("?"); 607094332d3Sopenharmony_ci break; 608094332d3Sopenharmony_ci } 609094332d3Sopenharmony_ci } 610094332d3Sopenharmony_ci printf("\n"); 611094332d3Sopenharmony_ci} 612094332d3Sopenharmony_ci 613094332d3Sopenharmony_cistatic void PrintValue(struct AudioMixerCtlElemInfo *info) 614094332d3Sopenharmony_ci{ 615094332d3Sopenharmony_ci long *ptr; 616094332d3Sopenharmony_ci uint32_t idx, items; 617094332d3Sopenharmony_ci AudioCtlElemType type; 618094332d3Sopenharmony_ci 619094332d3Sopenharmony_ci type = CtlElemGetInfoType(info); 620094332d3Sopenharmony_ci switch (type) { 621094332d3Sopenharmony_ci case AUDIO_CTL_ELEM_TYPE_INTEGER: 622094332d3Sopenharmony_ci printf(", min=%i, max=%i, step=%i\n", 623094332d3Sopenharmony_ci CtlElemInfoGetMin(info), 624094332d3Sopenharmony_ci CtlElemInfoGetMax(info), 625094332d3Sopenharmony_ci CtlElemInfoGetStep(info)); 626094332d3Sopenharmony_ci ptr = CtlElemInfoGetVals(info); 627094332d3Sopenharmony_ci printf(" : values="); 628094332d3Sopenharmony_ci for (idx = 0; idx < info->count; idx++) { 629094332d3Sopenharmony_ci if (idx > 0) { 630094332d3Sopenharmony_ci printf(", "); 631094332d3Sopenharmony_ci } 632094332d3Sopenharmony_ci printf("%i", (int)ptr[idx]); 633094332d3Sopenharmony_ci } 634094332d3Sopenharmony_ci printf("\n"); 635094332d3Sopenharmony_ci break; 636094332d3Sopenharmony_ci case AUDIO_CTL_ELEM_TYPE_ENUMERATED: 637094332d3Sopenharmony_ci { 638094332d3Sopenharmony_ci items = CtlElemInfoGetItems(info); 639094332d3Sopenharmony_ci printf(", items=%u\n", items); 640094332d3Sopenharmony_ci for (idx = 0; idx < items; idx++) { 641094332d3Sopenharmony_ci CtlElemInfoSetItem(info, idx); 642094332d3Sopenharmony_ci printf("%s; Item #%u '%s'\n", " ", idx, CtlElemInfoGetItemName(info)); 643094332d3Sopenharmony_ci } 644094332d3Sopenharmony_ci printf(" : values=%u\n", CtlElemInfoGetItem(info)); 645094332d3Sopenharmony_ci } 646094332d3Sopenharmony_ci break; 647094332d3Sopenharmony_ci case AUDIO_CTL_ELEM_TYPE_BOOLEAN: 648094332d3Sopenharmony_ci printf("\n : values="); 649094332d3Sopenharmony_ci PrintOtherVal(info); 650094332d3Sopenharmony_ci break; 651094332d3Sopenharmony_ci case AUDIO_CTL_ELEM_TYPE_BYTES: 652094332d3Sopenharmony_ci printf(" : values=%s\n", CtlElemValueGetBytes(info)); 653094332d3Sopenharmony_ci break; 654094332d3Sopenharmony_ci default: 655094332d3Sopenharmony_ci DEBUG_LOG("Mismatched control value type!\n"); 656094332d3Sopenharmony_ci break; 657094332d3Sopenharmony_ci } 658094332d3Sopenharmony_ci} 659094332d3Sopenharmony_ci 660094332d3Sopenharmony_cistatic void ShowIntVal(struct AudioMixerCtlElemInfo *info) 661094332d3Sopenharmony_ci{ 662094332d3Sopenharmony_ci int32_t ret; 663094332d3Sopenharmony_ci uint32_t index; 664094332d3Sopenharmony_ci unsigned int count; 665094332d3Sopenharmony_ci const char *iface; 666094332d3Sopenharmony_ci const char *space = " "; 667094332d3Sopenharmony_ci char buf[BUF_SIZE_T + 1] = {0}; 668094332d3Sopenharmony_ci 669094332d3Sopenharmony_ci index = CtlElemGetIdx(&info->eIndexId); 670094332d3Sopenharmony_ci iface = CtlElemIfaceName(GetCtlElemIface(&info->eIndexId)); 671094332d3Sopenharmony_ci if (index > 0) { 672094332d3Sopenharmony_ci ret = snprintf_s(buf, BUF_SIZE_T, BUF_SIZE_T, "index=%u, iface=%s, name=%s", 673094332d3Sopenharmony_ci index, iface, CtlElemName(&info->eIndexId)); 674094332d3Sopenharmony_ci } else { 675094332d3Sopenharmony_ci ret = snprintf_s(buf, BUF_SIZE_T, BUF_SIZE_T, "iface=%s, name=%s", 676094332d3Sopenharmony_ci iface, CtlElemName(&info->eIndexId)); 677094332d3Sopenharmony_ci } 678094332d3Sopenharmony_ci if (ret < 0) { 679094332d3Sopenharmony_ci DEBUG_LOG("Failed to snprintf_s!\n"); 680094332d3Sopenharmony_ci return; 681094332d3Sopenharmony_ci } 682094332d3Sopenharmony_ci 683094332d3Sopenharmony_ci buf[BUF_SIZE_T] = '\0'; 684094332d3Sopenharmony_ci printf("%s\n", buf); 685094332d3Sopenharmony_ci 686094332d3Sopenharmony_ci count = CtlElemInfoCnt(info); 687094332d3Sopenharmony_ci printf("%s; type=%s, values=%u", space, MixerCtlType(info), count); 688094332d3Sopenharmony_ci PrintValue(info); 689094332d3Sopenharmony_ci} 690094332d3Sopenharmony_ci 691094332d3Sopenharmony_cistatic void ShowEnumVal(struct AudioMixerCtlElemInfo *info) 692094332d3Sopenharmony_ci{ 693094332d3Sopenharmony_ci printf(" : values=%u\n", CtlElemInfoGetItem(info)); 694094332d3Sopenharmony_ci} 695094332d3Sopenharmony_ci 696094332d3Sopenharmony_cistatic void ShowBytesVal(const unsigned char *data) 697094332d3Sopenharmony_ci{ 698094332d3Sopenharmony_ci int i; 699094332d3Sopenharmony_ci const unsigned char *p = data; 700094332d3Sopenharmony_ci 701094332d3Sopenharmony_ci printf("\ndata:\t"); 702094332d3Sopenharmony_ci for (i = 0; i < RESERVED_BUF_LEN; i++) { 703094332d3Sopenharmony_ci if (*p == '\0') { 704094332d3Sopenharmony_ci break; 705094332d3Sopenharmony_ci } 706094332d3Sopenharmony_ci 707094332d3Sopenharmony_ci if ((i % OUTPUT_ALIGN) == 0) { 708094332d3Sopenharmony_ci printf("\n"); 709094332d3Sopenharmony_ci } 710094332d3Sopenharmony_ci printf("0x%02x \n", *p++); 711094332d3Sopenharmony_ci } 712094332d3Sopenharmony_ci printf("\n"); 713094332d3Sopenharmony_ci printf("string: %s\n", data); 714094332d3Sopenharmony_ci} 715094332d3Sopenharmony_ci 716094332d3Sopenharmony_cistatic void ShowElemInfo(struct AudioMixerCtlElemInfo *info) 717094332d3Sopenharmony_ci{ 718094332d3Sopenharmony_ci switch (info->type) { 719094332d3Sopenharmony_ci case AUDIO_CTL_ELEM_TYPE_INTEGER: 720094332d3Sopenharmony_ci case AUDIO_CTL_ELEM_TYPE_BOOLEAN: 721094332d3Sopenharmony_ci ShowIntVal(info); 722094332d3Sopenharmony_ci break; 723094332d3Sopenharmony_ci case AUDIO_CTL_ELEM_TYPE_ENUMERATED: 724094332d3Sopenharmony_ci ShowEnumVal(info); 725094332d3Sopenharmony_ci break; 726094332d3Sopenharmony_ci case AUDIO_CTL_ELEM_TYPE_BYTES: 727094332d3Sopenharmony_ci ShowBytesVal(info->value.reserved); 728094332d3Sopenharmony_ci break; 729094332d3Sopenharmony_ci default: 730094332d3Sopenharmony_ci DEBUG_LOG("Mismatched control value type!\n"); 731094332d3Sopenharmony_ci break; 732094332d3Sopenharmony_ci } 733094332d3Sopenharmony_ci} 734094332d3Sopenharmony_ci 735094332d3Sopenharmony_ciint32_t MctlGetElem(const struct HdfIoService *service, struct MixerCardCtlInfo *ctlInfo) 736094332d3Sopenharmony_ci{ 737094332d3Sopenharmony_ci int32_t ret; 738094332d3Sopenharmony_ci struct AudioMixerCtlElemInfo info; 739094332d3Sopenharmony_ci 740094332d3Sopenharmony_ci if (service == NULL || ctlInfo == NULL) { 741094332d3Sopenharmony_ci DEBUG_LOG("Invalid parameters!\n"); 742094332d3Sopenharmony_ci return U_INVALID_PARAM; 743094332d3Sopenharmony_ci } 744094332d3Sopenharmony_ci 745094332d3Sopenharmony_ci ret = strncpy_s(info.cardSrvName, AUDIO_CARD_SRV_NAME_LEN - 1, ctlInfo->cardSrvName, AUDIO_CARD_SRV_NAME_LEN - 1); 746094332d3Sopenharmony_ci if (ret != 0) { 747094332d3Sopenharmony_ci DEBUG_LOG("strncpy_s cardSrvName fail!\n"); 748094332d3Sopenharmony_ci return U_FAILURE; 749094332d3Sopenharmony_ci } 750094332d3Sopenharmony_ci info.cardSrvName[AUDIO_CARD_SRV_NAME_LEN - 1] = '\0'; 751094332d3Sopenharmony_ci ret = strncpy_s(info.eIndexId.eId.name, AUDIO_ELEM_NAME_LEN - 1, ctlInfo->edx.eId.name, AUDIO_ELEM_NAME_LEN - 1); 752094332d3Sopenharmony_ci if (ret != 0) { 753094332d3Sopenharmony_ci DEBUG_LOG("strncpy_s element name fail!\n"); 754094332d3Sopenharmony_ci return U_FAILURE; 755094332d3Sopenharmony_ci } 756094332d3Sopenharmony_ci info.eIndexId.eId.name[AUDIO_ELEM_NAME_LEN - 1] = '\0'; 757094332d3Sopenharmony_ci info.eIndexId.eId.iface = ctlInfo->edx.eId.iface; 758094332d3Sopenharmony_ci // need info.type 759094332d3Sopenharmony_ci info.type = AUDIO_CTL_ELEM_TYPE_INTEGER; 760094332d3Sopenharmony_ci 761094332d3Sopenharmony_ci if (g_audioMixer.GetElemProp == NULL) { 762094332d3Sopenharmony_ci DEBUG_LOG("The callback function is NULL!\n"); 763094332d3Sopenharmony_ci return U_FAILURE; 764094332d3Sopenharmony_ci } 765094332d3Sopenharmony_ci ret = g_audioMixer.GetElemProp(service, &info); 766094332d3Sopenharmony_ci if (ret != U_SUCCESS) { 767094332d3Sopenharmony_ci DEBUG_LOG("Failed to get control!\n"); 768094332d3Sopenharmony_ci return U_FAILURE; 769094332d3Sopenharmony_ci } 770094332d3Sopenharmony_ci ShowElemInfo(&info); 771094332d3Sopenharmony_ci 772094332d3Sopenharmony_ci return U_SUCCESS; 773094332d3Sopenharmony_ci} 774094332d3Sopenharmony_ci 775094332d3Sopenharmony_cistatic const struct ChannelMask g_chnMask[] = { 776094332d3Sopenharmony_ci {"frontleft", 1 << AMIXER_CHN_FRONT_LEFT }, 777094332d3Sopenharmony_ci {"frontright", 1 << AMIXER_CHN_FRONT_RIGHT }, 778094332d3Sopenharmony_ci {"frontcenter", 1 << AMIXER_CHN_FRONT_CENTER }, 779094332d3Sopenharmony_ci {"front", ((1 << AMIXER_CHN_FRONT_LEFT) | (1 << AMIXER_CHN_FRONT_RIGHT))}, 780094332d3Sopenharmony_ci {"center", 1 << AMIXER_CHN_FRONT_CENTER }, 781094332d3Sopenharmony_ci {"rearleft", 1 << AMIXER_CHN_REAR_LEFT }, 782094332d3Sopenharmony_ci {"rearright", 1 << AMIXER_CHN_REAR_RIGHT }, 783094332d3Sopenharmony_ci {"rear", ((1 << AMIXER_CHN_REAR_LEFT) | (1 << AMIXER_CHN_REAR_RIGHT)) }, 784094332d3Sopenharmony_ci {"woofer", 1 << AMIXER_CHN_WOOFER }, 785094332d3Sopenharmony_ci {NULL, 0 } 786094332d3Sopenharmony_ci}; 787094332d3Sopenharmony_ci 788094332d3Sopenharmony_cistatic uint32_t ChannelsMask(char **ptr, unsigned int chns) 789094332d3Sopenharmony_ci{ 790094332d3Sopenharmony_ci const struct ChannelMask *msk; 791094332d3Sopenharmony_ci 792094332d3Sopenharmony_ci for (msk = g_chnMask; msk->name != NULL; msk++) { 793094332d3Sopenharmony_ci if (strncasecmp(*ptr, msk->name, strlen(msk->name)) == 0) { 794094332d3Sopenharmony_ci /* Stop loop at specified character. */ 795094332d3Sopenharmony_ci while (**ptr != '\0' && **ptr != ',' && **ptr != ' ' && **ptr != '\t') { 796094332d3Sopenharmony_ci (*ptr)++; 797094332d3Sopenharmony_ci } 798094332d3Sopenharmony_ci /* Skip the specified character. */ 799094332d3Sopenharmony_ci if (**ptr == ',' || **ptr == ' ' || **ptr == '\t') { 800094332d3Sopenharmony_ci (*ptr)++; 801094332d3Sopenharmony_ci } 802094332d3Sopenharmony_ci 803094332d3Sopenharmony_ci return msk->mask; 804094332d3Sopenharmony_ci } 805094332d3Sopenharmony_ci } 806094332d3Sopenharmony_ci 807094332d3Sopenharmony_ci return chns; 808094332d3Sopenharmony_ci} 809094332d3Sopenharmony_ci 810094332d3Sopenharmony_cistatic uint32_t DirMask(char **ptr, unsigned int dir) 811094332d3Sopenharmony_ci{ 812094332d3Sopenharmony_ci int find = 0; 813094332d3Sopenharmony_ci 814094332d3Sopenharmony_ci /* Stop loop at specified character. */ 815094332d3Sopenharmony_ci while (**ptr != '\0' && **ptr != ',' && **ptr != ' ' && **ptr != '\t') { 816094332d3Sopenharmony_ci (*ptr)++; 817094332d3Sopenharmony_ci } 818094332d3Sopenharmony_ci 819094332d3Sopenharmony_ci /* Skip the specified character. */ 820094332d3Sopenharmony_ci if (**ptr == ',' || **ptr == ' ' || **ptr == '\t') { 821094332d3Sopenharmony_ci (*ptr)++; 822094332d3Sopenharmony_ci } 823094332d3Sopenharmony_ci 824094332d3Sopenharmony_ci if (strncasecmp(*ptr, "render", strlen("render")) == 0) { 825094332d3Sopenharmony_ci dir = find = PCM_RENDER + 1; 826094332d3Sopenharmony_ci } else if (strncasecmp(*ptr, "capture", strlen("capture")) == 0) { 827094332d3Sopenharmony_ci dir = find = PCM_CAPTURE + 1; 828094332d3Sopenharmony_ci } 829094332d3Sopenharmony_ci 830094332d3Sopenharmony_ci if (find) { 831094332d3Sopenharmony_ci /* Stop loop at specified character. */ 832094332d3Sopenharmony_ci while (**ptr != '\0' && **ptr != ',' && **ptr != ' ' && **ptr != '\t') { 833094332d3Sopenharmony_ci (*ptr)++; 834094332d3Sopenharmony_ci } 835094332d3Sopenharmony_ci 836094332d3Sopenharmony_ci /* Skip the specified character. */ 837094332d3Sopenharmony_ci if (**ptr == ',' || **ptr == ' ' || **ptr == '\t') { 838094332d3Sopenharmony_ci (*ptr)++; 839094332d3Sopenharmony_ci } 840094332d3Sopenharmony_ci } 841094332d3Sopenharmony_ci 842094332d3Sopenharmony_ci return dir; 843094332d3Sopenharmony_ci} 844094332d3Sopenharmony_ci 845094332d3Sopenharmony_cistatic bool IsRenderChannel(AudioMixerChannelIdType chn) 846094332d3Sopenharmony_ci{ 847094332d3Sopenharmony_ci return !!(chn); 848094332d3Sopenharmony_ci} 849094332d3Sopenharmony_ci 850094332d3Sopenharmony_cistatic bool IsCaptureChannel(AudioMixerChannelIdType chn) 851094332d3Sopenharmony_ci{ 852094332d3Sopenharmony_ci return !(chn); 853094332d3Sopenharmony_ci} 854094332d3Sopenharmony_ci 855094332d3Sopenharmony_cistatic int32_t FillChnmap(struct AudioMixerCtlElemInfo *info, uint32_t chns, uint32_t dir, char **ptr) 856094332d3Sopenharmony_ci{ 857094332d3Sopenharmony_ci char *sp; 858094332d3Sopenharmony_ci AudioMixerChannelIdType chn; 859094332d3Sopenharmony_ci 860094332d3Sopenharmony_ci /* Matches the specified channel. */ 861094332d3Sopenharmony_ci for (chn = AMIXER_CHN_FRONT_LEFT; chn < AMIXER_CHN_LAST; chn++) { 862094332d3Sopenharmony_ci sp = NULL; 863094332d3Sopenharmony_ci if (!(chns & (1 << (uint32_t)chn))) { 864094332d3Sopenharmony_ci continue; 865094332d3Sopenharmony_ci } 866094332d3Sopenharmony_ci 867094332d3Sopenharmony_ci if (!((dir & PCM_RENDER) && IsRenderChannel(chn)) && !((dir & PCM_CAPTURE) && IsCaptureChannel(chn))) { 868094332d3Sopenharmony_ci DEBUG_LOG("Unable to set channel!\n"); 869094332d3Sopenharmony_ci return U_FAILURE; 870094332d3Sopenharmony_ci } 871094332d3Sopenharmony_ci 872094332d3Sopenharmony_ci info->value.enumVal.item |= (chns & (1 << chn)); 873094332d3Sopenharmony_ci /* Search for the next channel. */ 874094332d3Sopenharmony_ci while (**ptr != '\0' && **ptr != ',') { 875094332d3Sopenharmony_ci (*ptr)++; 876094332d3Sopenharmony_ci } 877094332d3Sopenharmony_ci if (**ptr == '\0') { 878094332d3Sopenharmony_ci break; 879094332d3Sopenharmony_ci } 880094332d3Sopenharmony_ci (*ptr)++; // skip ',' 881094332d3Sopenharmony_ci DEBUG_LOG("skip, = %s\n", *ptr); 882094332d3Sopenharmony_ci } 883094332d3Sopenharmony_ci 884094332d3Sopenharmony_ci if (info->value.enumVal.item > CHN_STEREO) { 885094332d3Sopenharmony_ci info->value.enumVal.item = CHN_STEREO; 886094332d3Sopenharmony_ci } else { 887094332d3Sopenharmony_ci info->value.enumVal.item = CHN_MONO; 888094332d3Sopenharmony_ci } 889094332d3Sopenharmony_ci DEBUG_LOG("chns = %i\n", info->value.enumVal.item); 890094332d3Sopenharmony_ci 891094332d3Sopenharmony_ci return U_SUCCESS; 892094332d3Sopenharmony_ci} 893094332d3Sopenharmony_ci 894094332d3Sopenharmony_cistatic int32_t FillChnlsIntVal(struct AudioMixerCtlElemInfo *info, unsigned int argc, char *argv) 895094332d3Sopenharmony_ci{ 896094332d3Sopenharmony_ci bool mchns; 897094332d3Sopenharmony_ci int32_t ret; 898094332d3Sopenharmony_ci char *ptr = NULL; 899094332d3Sopenharmony_ci uint32_t dir = 3; 900094332d3Sopenharmony_ci uint32_t chns = ~0U; 901094332d3Sopenharmony_ci 902094332d3Sopenharmony_ci ptr = argv; 903094332d3Sopenharmony_ci chns = ChannelsMask(&ptr, chns); 904094332d3Sopenharmony_ci if (*ptr == '\0') { 905094332d3Sopenharmony_ci DEBUG_LOG("Channels Mask = %u\n", chns); 906094332d3Sopenharmony_ci return U_FAILURE; 907094332d3Sopenharmony_ci } 908094332d3Sopenharmony_ci 909094332d3Sopenharmony_ci dir = DirMask(&ptr, dir); 910094332d3Sopenharmony_ci if (*ptr == '\0') { 911094332d3Sopenharmony_ci DEBUG_LOG("Direct Mask = %u\n", chns); 912094332d3Sopenharmony_ci return U_FAILURE; 913094332d3Sopenharmony_ci } 914094332d3Sopenharmony_ci 915094332d3Sopenharmony_ci mchns = (strchr(ptr, ',') != NULL); 916094332d3Sopenharmony_ci if (!mchns) { 917094332d3Sopenharmony_ci info->value.enumVal.item = CHN_MONO; 918094332d3Sopenharmony_ci return U_SUCCESS; 919094332d3Sopenharmony_ci } 920094332d3Sopenharmony_ci 921094332d3Sopenharmony_ci ret = FillChnmap(info, chns, dir, &ptr); 922094332d3Sopenharmony_ci if (ret != U_SUCCESS) { 923094332d3Sopenharmony_ci return ret; 924094332d3Sopenharmony_ci } 925094332d3Sopenharmony_ci 926094332d3Sopenharmony_ci return U_SUCCESS; 927094332d3Sopenharmony_ci} 928094332d3Sopenharmony_ci 929094332d3Sopenharmony_ciint32_t SetChannels(const struct HdfIoService *srv, const char *cardSrv, unsigned int argc, char *argv) 930094332d3Sopenharmony_ci{ 931094332d3Sopenharmony_ci int32_t ret; 932094332d3Sopenharmony_ci struct AudioMixerCtlElemInfo infoData; 933094332d3Sopenharmony_ci 934094332d3Sopenharmony_ci if (srv == NULL || cardSrv == NULL || argc == 0) { 935094332d3Sopenharmony_ci DEBUG_LOG("Invalid parameters!\n"); 936094332d3Sopenharmony_ci return U_INVALID_PARAM; 937094332d3Sopenharmony_ci } 938094332d3Sopenharmony_ci 939094332d3Sopenharmony_ci DEBUG_LOG("argc = %u, argv = %s\n", argc, argv); 940094332d3Sopenharmony_ci (void)memset_s(infoData.cardSrvName, AUDIO_CARD_SRV_NAME_LEN, 0, AUDIO_CARD_SRV_NAME_LEN); 941094332d3Sopenharmony_ci ret = strncpy_s(infoData.cardSrvName, AUDIO_CARD_SRV_NAME_LEN, cardSrv, strlen(cardSrv) + 1); 942094332d3Sopenharmony_ci if (ret != 0) { 943094332d3Sopenharmony_ci DEBUG_LOG("strncpy_s card service name is faild!\n"); 944094332d3Sopenharmony_ci return U_FAILURE; 945094332d3Sopenharmony_ci } 946094332d3Sopenharmony_ci infoData.cardSrvName[AUDIO_CARD_SRV_NAME_LEN - 1] = '\0'; 947094332d3Sopenharmony_ci 948094332d3Sopenharmony_ci (void)memset_s(infoData.eIndexId.eId.name, AUDIO_ELEM_NAME_LEN, 0, AUDIO_ELEM_NAME_LEN); 949094332d3Sopenharmony_ci ret = strncpy_s( 950094332d3Sopenharmony_ci infoData.eIndexId.eId.name, AUDIO_ELEM_NAME_LEN, "Captrue Channel Mode", strlen("Captrue Channel Mode") + 1); 951094332d3Sopenharmony_ci if (ret != 0) { 952094332d3Sopenharmony_ci DEBUG_LOG("strncpy_s element name is failed!\n"); 953094332d3Sopenharmony_ci return U_FAILURE; 954094332d3Sopenharmony_ci } 955094332d3Sopenharmony_ci infoData.eIndexId.eId.iface = AUDIO_CTL_ELEM_IFACE_MIXER; 956094332d3Sopenharmony_ci infoData.type = AUDIO_CTL_ELEM_TYPE_INTEGER; 957094332d3Sopenharmony_ci ret = FillChnlsIntVal(&infoData, argc, argv); 958094332d3Sopenharmony_ci if (ret != U_SUCCESS) { 959094332d3Sopenharmony_ci return ret; 960094332d3Sopenharmony_ci } 961094332d3Sopenharmony_ci 962094332d3Sopenharmony_ci if (g_audioMixer.SetElemProp == NULL) { 963094332d3Sopenharmony_ci DEBUG_LOG("The callback function is NULL!\n"); 964094332d3Sopenharmony_ci return U_FAILURE; 965094332d3Sopenharmony_ci } 966094332d3Sopenharmony_ci ret = g_audioMixer.SetElemProp(srv, &infoData); 967094332d3Sopenharmony_ci if (ret != U_SUCCESS) { 968094332d3Sopenharmony_ci return ret; 969094332d3Sopenharmony_ci } 970094332d3Sopenharmony_ci 971094332d3Sopenharmony_ci ret = strncpy_s( 972094332d3Sopenharmony_ci infoData.eIndexId.eId.name, AUDIO_ELEM_NAME_LEN, "Render Channel Mode", strlen("Render Channel Mode") + 1); 973094332d3Sopenharmony_ci if (ret != 0) { 974094332d3Sopenharmony_ci DEBUG_LOG("strncpy_s element name is failed!\n"); 975094332d3Sopenharmony_ci return U_FAILURE; 976094332d3Sopenharmony_ci } 977094332d3Sopenharmony_ci 978094332d3Sopenharmony_ci return g_audioMixer.SetElemProp(srv, &infoData); 979094332d3Sopenharmony_ci} 980094332d3Sopenharmony_ci 981094332d3Sopenharmony_cistatic int32_t FillIntVal(struct AudioMixerCtlElemInfo *info, unsigned int argc, char *argv[]) 982094332d3Sopenharmony_ci{ 983094332d3Sopenharmony_ci char *vals, *minPtr, *maxPtr, *stepPtr; 984094332d3Sopenharmony_ci char *ptr = NULL; 985094332d3Sopenharmony_ci char *outPtr = NULL; 986094332d3Sopenharmony_ci 987094332d3Sopenharmony_ci if (argc != 2) { // 2 for numbers of argc 988094332d3Sopenharmony_ci DEBUG_LOG("Unable to set too much value!\n"); 989094332d3Sopenharmony_ci return U_FAILURE; 990094332d3Sopenharmony_ci } 991094332d3Sopenharmony_ci 992094332d3Sopenharmony_ci ptr = argv[argc - 1]; 993094332d3Sopenharmony_ci DEBUG_LOG("argv[%u] = %s\n", argc - 1, ptr); 994094332d3Sopenharmony_ci vals = strtok_r(ptr, ",", &outPtr); 995094332d3Sopenharmony_ci if (outPtr == NULL) { 996094332d3Sopenharmony_ci info->value.intVal.vals[0] = strtol(ptr, NULL, STRTOL_BASE); 997094332d3Sopenharmony_ci info->value.intVal.min = 0; 998094332d3Sopenharmony_ci info->value.intVal.step = 0; 999094332d3Sopenharmony_ci 1000094332d3Sopenharmony_ci return U_SUCCESS; 1001094332d3Sopenharmony_ci } 1002094332d3Sopenharmony_ci 1003094332d3Sopenharmony_ci info->value.intVal.vals[0] = strtol(vals, NULL, STRTOL_BASE); 1004094332d3Sopenharmony_ci maxPtr = strtok_r(NULL, ",", &outPtr); 1005094332d3Sopenharmony_ci if (outPtr == NULL) { 1006094332d3Sopenharmony_ci info->value.intVal.max = (int32_t)strtol(maxPtr, NULL, STRTOL_BASE); 1007094332d3Sopenharmony_ci info->value.intVal.min = 0; 1008094332d3Sopenharmony_ci info->value.intVal.step = 0; 1009094332d3Sopenharmony_ci 1010094332d3Sopenharmony_ci return U_SUCCESS; 1011094332d3Sopenharmony_ci } 1012094332d3Sopenharmony_ci 1013094332d3Sopenharmony_ci info->value.intVal.max = (int32_t)strtol(maxPtr, NULL, STRTOL_BASE); 1014094332d3Sopenharmony_ci minPtr = strtok_r(NULL, ",", &outPtr); 1015094332d3Sopenharmony_ci if (outPtr != NULL) { 1016094332d3Sopenharmony_ci info->value.intVal.min = (int32_t)strtol(minPtr, NULL, STRTOL_BASE); 1017094332d3Sopenharmony_ci stepPtr = strtok_r(NULL, ",", &outPtr); 1018094332d3Sopenharmony_ci info->value.intVal.step = outPtr != NULL ? (int32_t)strtol(stepPtr, NULL, STRTOL_BASE) : 0; 1019094332d3Sopenharmony_ci } else { 1020094332d3Sopenharmony_ci info->value.intVal.min = (int32_t)strtol(minPtr, NULL, STRTOL_BASE); 1021094332d3Sopenharmony_ci info->value.intVal.step = 0; 1022094332d3Sopenharmony_ci } 1023094332d3Sopenharmony_ci 1024094332d3Sopenharmony_ci return U_SUCCESS; 1025094332d3Sopenharmony_ci} 1026094332d3Sopenharmony_ci 1027094332d3Sopenharmony_cistatic int32_t FillEnumVal(struct AudioMixerCtlElemInfo *info, unsigned int argc, char *argv[]) 1028094332d3Sopenharmony_ci{ 1029094332d3Sopenharmony_ci int32_t ret; 1030094332d3Sopenharmony_ci unsigned int idx; 1031094332d3Sopenharmony_ci char *ptr = NULL; 1032094332d3Sopenharmony_ci 1033094332d3Sopenharmony_ci printf("\n"); 1034094332d3Sopenharmony_ci /* Multiple enumerated values are output line by line. */ 1035094332d3Sopenharmony_ci for (idx = 1; idx < argc; idx++) { 1036094332d3Sopenharmony_ci ptr = argv[idx]; 1037094332d3Sopenharmony_ci // Control Settings with enumerated values. 1038094332d3Sopenharmony_ci ret = strcpy_s(info->value.enumVal.name, AUDIO_ELEM_NAME_LEN - 1, ptr); 1039094332d3Sopenharmony_ci if (ret != EOK) { 1040094332d3Sopenharmony_ci printf("strcpy_s failed: argv = %s\n", ptr); 1041094332d3Sopenharmony_ci } else { 1042094332d3Sopenharmony_ci printf("%s\n", ptr); 1043094332d3Sopenharmony_ci } 1044094332d3Sopenharmony_ci } 1045094332d3Sopenharmony_ci 1046094332d3Sopenharmony_ci return U_SUCCESS; 1047094332d3Sopenharmony_ci} 1048094332d3Sopenharmony_ci 1049094332d3Sopenharmony_cistatic int32_t FillBytesVal(unsigned char *buf, unsigned int argc, char *argv[]) 1050094332d3Sopenharmony_ci{ 1051094332d3Sopenharmony_ci int32_t ret; 1052094332d3Sopenharmony_ci size_t len; 1053094332d3Sopenharmony_ci unsigned int idx; 1054094332d3Sopenharmony_ci unsigned char *ptr = buf; 1055094332d3Sopenharmony_ci char *sptr = NULL; 1056094332d3Sopenharmony_ci size_t size = RESERVED_BUF_LEN; 1057094332d3Sopenharmony_ci 1058094332d3Sopenharmony_ci /* Multiple input parameters are separated and combined with a ",". */ 1059094332d3Sopenharmony_ci for (idx = 1; idx < argc; idx++) { 1060094332d3Sopenharmony_ci sptr = argv[idx]; 1061094332d3Sopenharmony_ci len = strlen(argv[idx]); 1062094332d3Sopenharmony_ci if (size <= len) { 1063094332d3Sopenharmony_ci DEBUG_LOG("The callback function is NULL!\n"); 1064094332d3Sopenharmony_ci break; 1065094332d3Sopenharmony_ci } 1066094332d3Sopenharmony_ci ret = strncpy_s((char *)ptr, RESERVED_BUF_LEN - 1, sptr, len); 1067094332d3Sopenharmony_ci if (ret != 0) { 1068094332d3Sopenharmony_ci DEBUG_LOG("strncpy_s faild!\n"); 1069094332d3Sopenharmony_ci return U_FAILURE; 1070094332d3Sopenharmony_ci } 1071094332d3Sopenharmony_ci ptr += len; 1072094332d3Sopenharmony_ci *ptr++ = ','; 1073094332d3Sopenharmony_ci size -= len + 1; 1074094332d3Sopenharmony_ci } 1075094332d3Sopenharmony_ci if (idx < argc) { 1076094332d3Sopenharmony_ci DEBUG_LOG("Unable to set too much data!\n"); 1077094332d3Sopenharmony_ci return U_FAILURE; 1078094332d3Sopenharmony_ci } 1079094332d3Sopenharmony_ci printf("data buf = %s\n", buf); 1080094332d3Sopenharmony_ci 1081094332d3Sopenharmony_ci return U_SUCCESS; 1082094332d3Sopenharmony_ci} 1083094332d3Sopenharmony_ci 1084094332d3Sopenharmony_ci 1085094332d3Sopenharmony_ciint32_t MctlSetElem(const struct HdfIoService *srv, 1086094332d3Sopenharmony_ci struct MixerCardCtlInfo *ctlInfo, 1087094332d3Sopenharmony_ci unsigned int argc, char *argv[]) 1088094332d3Sopenharmony_ci{ 1089094332d3Sopenharmony_ci int32_t ret; 1090094332d3Sopenharmony_ci struct AudioMixerCtlElemInfo infoData; 1091094332d3Sopenharmony_ci 1092094332d3Sopenharmony_ci if (srv == NULL || ctlInfo == NULL || argc == 0) { 1093094332d3Sopenharmony_ci DEBUG_LOG("Invalid parameters!\n"); 1094094332d3Sopenharmony_ci return U_INVALID_PARAM; 1095094332d3Sopenharmony_ci } 1096094332d3Sopenharmony_ci 1097094332d3Sopenharmony_ci ret = strncpy_s(infoData.cardSrvName, AUDIO_CARD_SRV_NAME_LEN, ctlInfo->cardSrvName, AUDIO_CARD_SRV_NAME_LEN); 1098094332d3Sopenharmony_ci if (ret != 0) { 1099094332d3Sopenharmony_ci DEBUG_LOG("strncpy_s card service name is faild!\n"); 1100094332d3Sopenharmony_ci return U_FAILURE; 1101094332d3Sopenharmony_ci } 1102094332d3Sopenharmony_ci infoData.cardSrvName[AUDIO_CARD_SRV_NAME_LEN - 1] = '\0'; 1103094332d3Sopenharmony_ci 1104094332d3Sopenharmony_ci ret = strncpy_s(infoData.eIndexId.eId.name, AUDIO_ELEM_NAME_LEN, ctlInfo->edx.eId.name, AUDIO_ELEM_NAME_LEN); 1105094332d3Sopenharmony_ci if (ret != 0) { 1106094332d3Sopenharmony_ci DEBUG_LOG("strncpy_s element name is failed!\n"); 1107094332d3Sopenharmony_ci return U_FAILURE; 1108094332d3Sopenharmony_ci } 1109094332d3Sopenharmony_ci infoData.eIndexId.eId.name[AUDIO_ELEM_NAME_LEN - 1] = '\0'; 1110094332d3Sopenharmony_ci infoData.eIndexId.eId.iface = AUDIO_CTL_ELEM_IFACE_MIXER; 1111094332d3Sopenharmony_ci 1112094332d3Sopenharmony_ci // First, read the value type.(infoData.type) 1113094332d3Sopenharmony_ci infoData.type = AUDIO_CTL_ELEM_TYPE_INTEGER; 1114094332d3Sopenharmony_ci switch (infoData.type) { 1115094332d3Sopenharmony_ci case AUDIO_CTL_ELEM_TYPE_INTEGER: 1116094332d3Sopenharmony_ci case AUDIO_CTL_ELEM_TYPE_BOOLEAN: 1117094332d3Sopenharmony_ci ret = FillIntVal(&infoData, argc, argv); 1118094332d3Sopenharmony_ci break; 1119094332d3Sopenharmony_ci case AUDIO_CTL_ELEM_TYPE_ENUMERATED: 1120094332d3Sopenharmony_ci ret = FillEnumVal(&infoData, argc, argv); 1121094332d3Sopenharmony_ci break; 1122094332d3Sopenharmony_ci case AUDIO_CTL_ELEM_TYPE_BYTES: 1123094332d3Sopenharmony_ci ret = FillBytesVal(infoData.value.reserved, argc, argv); 1124094332d3Sopenharmony_ci break; 1125094332d3Sopenharmony_ci default: 1126094332d3Sopenharmony_ci ret = U_FAILURE; 1127094332d3Sopenharmony_ci break; 1128094332d3Sopenharmony_ci } 1129094332d3Sopenharmony_ci if (ret != U_SUCCESS) { 1130094332d3Sopenharmony_ci DEBUG_LOG("The value type does not match!\n"); 1131094332d3Sopenharmony_ci return U_FAILURE; 1132094332d3Sopenharmony_ci } 1133094332d3Sopenharmony_ci 1134094332d3Sopenharmony_ci if (g_audioMixer.SetElemProp == NULL) { 1135094332d3Sopenharmony_ci DEBUG_LOG("The callback function is NULL!\n"); 1136094332d3Sopenharmony_ci return U_FAILURE; 1137094332d3Sopenharmony_ci } 1138094332d3Sopenharmony_ci 1139094332d3Sopenharmony_ci return g_audioMixer.SetElemProp(srv, &infoData); 1140094332d3Sopenharmony_ci} 1141094332d3Sopenharmony_ci 1142094332d3Sopenharmony_cistatic char *SkipSpecifyStr(const char *src, const char *needle) 1143094332d3Sopenharmony_ci{ 1144094332d3Sopenharmony_ci char *p = NULL; 1145094332d3Sopenharmony_ci 1146094332d3Sopenharmony_ci p = strstr(src, needle); 1147094332d3Sopenharmony_ci if (p != NULL) { 1148094332d3Sopenharmony_ci p += strlen(needle); 1149094332d3Sopenharmony_ci } 1150094332d3Sopenharmony_ci 1151094332d3Sopenharmony_ci return p; 1152094332d3Sopenharmony_ci} 1153094332d3Sopenharmony_ci 1154094332d3Sopenharmony_cistatic int32_t GetSndCardType(const char *name, char *buf, uint32_t len) 1155094332d3Sopenharmony_ci{ 1156094332d3Sopenharmony_ci int32_t ret; 1157094332d3Sopenharmony_ci char *ptr = NULL; 1158094332d3Sopenharmony_ci char *out = NULL; 1159094332d3Sopenharmony_ci 1160094332d3Sopenharmony_ci if (name == NULL || buf == NULL || len == 0) { 1161094332d3Sopenharmony_ci DEBUG_LOG("Invalid parameters!\n"); 1162094332d3Sopenharmony_ci return U_INVALID_PARAM; 1163094332d3Sopenharmony_ci } 1164094332d3Sopenharmony_ci 1165094332d3Sopenharmony_ci ptr = SkipSpecifyStr(name, MIXER_SRV_NAME_PRE); 1166094332d3Sopenharmony_ci if (ptr == NULL) { 1167094332d3Sopenharmony_ci DEBUG_LOG("No found card type!\n"); 1168094332d3Sopenharmony_ci return U_FAILURE; 1169094332d3Sopenharmony_ci } 1170094332d3Sopenharmony_ci 1171094332d3Sopenharmony_ci ret = memcpy_s(buf, len, ptr, strlen(ptr) + 1); 1172094332d3Sopenharmony_ci if (ret != EOK) { 1173094332d3Sopenharmony_ci DEBUG_LOG("memcpy_s fail!\n"); 1174094332d3Sopenharmony_ci return U_FAILURE; 1175094332d3Sopenharmony_ci } 1176094332d3Sopenharmony_ci ptr = strtok_r(buf, "_", &out); 1177094332d3Sopenharmony_ci ret = memcpy_s(buf, len, ptr, strlen(ptr) + 1); 1178094332d3Sopenharmony_ci if (ret != EOK) { 1179094332d3Sopenharmony_ci DEBUG_LOG("memcpy_s fail!\n"); 1180094332d3Sopenharmony_ci return U_FAILURE; 1181094332d3Sopenharmony_ci } 1182094332d3Sopenharmony_ci 1183094332d3Sopenharmony_ci return U_SUCCESS; 1184094332d3Sopenharmony_ci} 1185094332d3Sopenharmony_ci 1186094332d3Sopenharmony_cistatic void ShowAllAdapters(struct SndCardsList *sndList) 1187094332d3Sopenharmony_ci{ 1188094332d3Sopenharmony_ci int32_t i, ret; 1189094332d3Sopenharmony_ci uint32_t cnums; 1190094332d3Sopenharmony_ci char ctype[AUDIO_BASE_LEN] = {0}; 1191094332d3Sopenharmony_ci struct AudioCardId *clist = NULL; 1192094332d3Sopenharmony_ci 1193094332d3Sopenharmony_ci if (sndList->cardNums == 0 || sndList->cardsList == NULL) { 1194094332d3Sopenharmony_ci DEBUG_LOG("No sound cards found...!\n"); 1195094332d3Sopenharmony_ci goto end; 1196094332d3Sopenharmony_ci } 1197094332d3Sopenharmony_ci 1198094332d3Sopenharmony_ci cnums = sndList->cardNums; 1199094332d3Sopenharmony_ci clist = sndList->cardsList; 1200094332d3Sopenharmony_ci printf("****** List of Audio Hardware Devices ******\n"); 1201094332d3Sopenharmony_ci /* To keep the primary sound card always in front of the total, 1202094332d3Sopenharmony_ci * output it in the following order. 1203094332d3Sopenharmony_ci */ 1204094332d3Sopenharmony_ci for (i = (int32_t)cnums - 1; i >= 0; i--) { 1205094332d3Sopenharmony_ci (void)memset_s(ctype, AUDIO_BASE_LEN, 0, AUDIO_BASE_LEN); 1206094332d3Sopenharmony_ci ret = GetSndCardType(clist[i].cardName, ctype, AUDIO_BASE_LEN); 1207094332d3Sopenharmony_ci if (ret != U_SUCCESS) { 1208094332d3Sopenharmony_ci goto end; 1209094332d3Sopenharmony_ci } 1210094332d3Sopenharmony_ci printf("card %i: %s [%s], device 0\n", clist[i].index, ctype, clist[i].cardName); 1211094332d3Sopenharmony_ci printf(" Subdevices: 1/1\n"); 1212094332d3Sopenharmony_ci printf(" Subdevice #0: subdevice #0\n"); 1213094332d3Sopenharmony_ci } 1214094332d3Sopenharmony_ci 1215094332d3Sopenharmony_ciend: 1216094332d3Sopenharmony_ci if (sndList->cardsList != NULL) { 1217094332d3Sopenharmony_ci free(sndList->cardsList); 1218094332d3Sopenharmony_ci sndList->cardsList = NULL; 1219094332d3Sopenharmony_ci } 1220094332d3Sopenharmony_ci} 1221094332d3Sopenharmony_ci 1222094332d3Sopenharmony_ciint32_t GetAllCards(const struct HdfIoService *service) 1223094332d3Sopenharmony_ci{ 1224094332d3Sopenharmony_ci int32_t ret; 1225094332d3Sopenharmony_ci struct SndCardsList sndcards; 1226094332d3Sopenharmony_ci int32_t (*GetAllAdapters)(const struct HdfIoService *, struct SndCardsList *); 1227094332d3Sopenharmony_ci 1228094332d3Sopenharmony_ci if (service == NULL) { 1229094332d3Sopenharmony_ci DEBUG_LOG("Invalid parameter!\n"); 1230094332d3Sopenharmony_ci return U_INVALID_PARAM; 1231094332d3Sopenharmony_ci } 1232094332d3Sopenharmony_ci 1233094332d3Sopenharmony_ci GetAllAdapters = CallLibFunction("AudioMixerGetAllAdapters"); 1234094332d3Sopenharmony_ci if (GetAllAdapters == NULL) { 1235094332d3Sopenharmony_ci return U_FAILURE; 1236094332d3Sopenharmony_ci } 1237094332d3Sopenharmony_ci 1238094332d3Sopenharmony_ci (void)memset_s(&sndcards, sizeof(struct SndCardsList), 0, sizeof(struct SndCardsList)); 1239094332d3Sopenharmony_ci ret = GetAllAdapters(service, &sndcards); 1240094332d3Sopenharmony_ci if (ret != U_SUCCESS) { 1241094332d3Sopenharmony_ci DEBUG_LOG("Description Failed to obtain the sound card list!\n"); 1242094332d3Sopenharmony_ci return U_FAILURE; 1243094332d3Sopenharmony_ci } 1244094332d3Sopenharmony_ci ShowAllAdapters(&sndcards); 1245094332d3Sopenharmony_ci 1246094332d3Sopenharmony_ci return U_SUCCESS; 1247094332d3Sopenharmony_ci} 1248094332d3Sopenharmony_ci 1249094332d3Sopenharmony_cistatic char *FindSpecificCardName(int card, struct SndCardsList *cardList) 1250094332d3Sopenharmony_ci{ 1251094332d3Sopenharmony_ci int32_t i; 1252094332d3Sopenharmony_ci uint32_t cnums; 1253094332d3Sopenharmony_ci struct AudioCardId *clist = NULL; 1254094332d3Sopenharmony_ci 1255094332d3Sopenharmony_ci if (cardList->cardNums == 0 || cardList->cardsList == NULL) { 1256094332d3Sopenharmony_ci DEBUG_LOG("No sound cards found...!\n"); 1257094332d3Sopenharmony_ci goto end; 1258094332d3Sopenharmony_ci } 1259094332d3Sopenharmony_ci 1260094332d3Sopenharmony_ci cnums = cardList->cardNums; 1261094332d3Sopenharmony_ci clist = cardList->cardsList; 1262094332d3Sopenharmony_ci for (i = 0; i < (int32_t)cnums; i++) { 1263094332d3Sopenharmony_ci if (card == clist[i].index) { 1264094332d3Sopenharmony_ci DEBUG_LOG("I found this sound card. [card%i: %s]\n", card, clist[i].cardName); 1265094332d3Sopenharmony_ci return clist[i].cardName; 1266094332d3Sopenharmony_ci } 1267094332d3Sopenharmony_ci } 1268094332d3Sopenharmony_ci 1269094332d3Sopenharmony_ciend: 1270094332d3Sopenharmony_ci if (cardList->cardsList != NULL) { 1271094332d3Sopenharmony_ci free(cardList->cardsList); 1272094332d3Sopenharmony_ci cardList->cardsList = NULL; 1273094332d3Sopenharmony_ci } 1274094332d3Sopenharmony_ci cardList->cardNums = 0; 1275094332d3Sopenharmony_ci 1276094332d3Sopenharmony_ci return NULL; 1277094332d3Sopenharmony_ci} 1278094332d3Sopenharmony_ci 1279094332d3Sopenharmony_civoid UpdateCardSname(int card, const struct HdfIoService *srv, char * const sname, size_t snameLen) 1280094332d3Sopenharmony_ci{ 1281094332d3Sopenharmony_ci int32_t ret; 1282094332d3Sopenharmony_ci struct SndCardsList cardList; 1283094332d3Sopenharmony_ci int32_t (*GetAllCardsFunc)(const struct HdfIoService *, struct SndCardsList *); 1284094332d3Sopenharmony_ci char *cname = NULL; 1285094332d3Sopenharmony_ci 1286094332d3Sopenharmony_ci if (card < 0 || srv == NULL || sname == NULL || snameLen == 0) { 1287094332d3Sopenharmony_ci DEBUG_LOG("Invalid parameter!\n"); 1288094332d3Sopenharmony_ci return; 1289094332d3Sopenharmony_ci } 1290094332d3Sopenharmony_ci 1291094332d3Sopenharmony_ci GetAllCardsFunc = CallLibFunction("AudioMixerGetAllAdapters"); 1292094332d3Sopenharmony_ci if (GetAllCardsFunc == NULL) { 1293094332d3Sopenharmony_ci DEBUG_LOG("Description Failed to obtain the current sound card list of the system!\n"); 1294094332d3Sopenharmony_ci return; 1295094332d3Sopenharmony_ci } 1296094332d3Sopenharmony_ci 1297094332d3Sopenharmony_ci (void)memset_s(&cardList, sizeof(struct SndCardsList), 0, sizeof(struct SndCardsList)); 1298094332d3Sopenharmony_ci ret = GetAllCardsFunc(srv, &cardList); 1299094332d3Sopenharmony_ci if (ret != U_SUCCESS) { 1300094332d3Sopenharmony_ci DEBUG_LOG("Update failed: Description Failed to obtain the sound card list!\n"); 1301094332d3Sopenharmony_ci return; 1302094332d3Sopenharmony_ci } 1303094332d3Sopenharmony_ci 1304094332d3Sopenharmony_ci cname = FindSpecificCardName(card, &cardList); 1305094332d3Sopenharmony_ci if (cname == NULL) { 1306094332d3Sopenharmony_ci DEBUG_LOG("Update failed: The corresponding sound card cannot be matched!\n"); 1307094332d3Sopenharmony_ci return; 1308094332d3Sopenharmony_ci } 1309094332d3Sopenharmony_ci 1310094332d3Sopenharmony_ci ret = memcpy_s(sname, snameLen, cname, strlen(cname) + 1); 1311094332d3Sopenharmony_ci if (ret != EOK) { 1312094332d3Sopenharmony_ci DEBUG_LOG("Update failed: memcpy_s fail!\n"); 1313094332d3Sopenharmony_ci } 1314094332d3Sopenharmony_ci sname[snameLen - 1] = '\0'; 1315094332d3Sopenharmony_ci if (g_debugFlag) { 1316094332d3Sopenharmony_ci printf("|--> [%s]\n", sname); 1317094332d3Sopenharmony_ci } 1318094332d3Sopenharmony_ci 1319094332d3Sopenharmony_ci if (cardList.cardsList != NULL) { 1320094332d3Sopenharmony_ci free(cardList.cardsList); 1321094332d3Sopenharmony_ci cardList.cardsList = NULL; 1322094332d3Sopenharmony_ci } 1323094332d3Sopenharmony_ci cardList.cardNums = 0; 1324094332d3Sopenharmony_ci} 1325