/* * Copyright (c) 2021-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "hdf_audio_server_common.h" #include "audio_adapter_info_common.h" #include "audio_events.h" #include "audio_types.h" #include "audio_uhdf_log.h" #include "hdf_audio_events.h" #include "hdf_audio_server.h" #include "hdf_audio_server_capture.h" #include "hdf_audio_server_render.h" #include "hdf_audio_server_manager.h" #include "hdf_device_object.h" #include "osal_mem.h" #define HDF_LOG_TAG HDF_AUDIO_HAL_STUB struct AudioAdapterDescriptor *g_descs = NULL; struct AudioManager *g_serverManager = NULL; #define MAX_AUDIO_ADAPTER_NUM_SERVER 8 // Limit the number of sound cards supported to a maximum of 8 #define SERVER_INFO_LEN 128 #define SUPPORT_PORT_NUM_MAX 10 static struct AudioEvent g_audioEventPnp = { .eventType = HDF_AUDIO_EVENT_UNKOWN, .deviceType = HDF_AUDIO_DEVICE_UNKOWN, }; static struct AudioEvent g_audioEventLoad = { .eventType = HDF_AUDIO_EVENT_UNKOWN, .deviceType = HDF_AUDIO_DEVICE_UNKOWN, }; static struct AudioEvent g_audioEventService = { .eventType = HDF_AUDIO_EVENT_UNKOWN, .deviceType = HDF_AUDIO_DEVICE_UNKOWN, }; static int32_t AdaptersServerManageInit(const struct AudioAdapterDescriptor *descs, int32_t num) { num = ServerManageGetAdapterNum(num); if (AdapterManageInit(descs, num) != HDF_SUCCESS) { AUDIO_FUNC_LOGE("AdapterManageInit Failed"); return HDF_FAILURE; } return HDF_SUCCESS; } int32_t HdiServiceRenderCaptureReadData(struct HdfSBuf *data, const char **adapterName, uint32_t *pid) { if (adapterName == NULL || data == NULL || pid == NULL) { return HDF_FAILURE; } if ((*adapterName = HdfSbufReadString(data)) == NULL) { AUDIO_FUNC_LOGE("adapterName Is NULL "); return HDF_FAILURE; } if (!HdfSbufReadUint32(data, pid)) { AUDIO_FUNC_LOGE("read buf fail "); return HDF_FAILURE; } return HDF_SUCCESS; } int32_t WriteAudioSampleAttributes(struct HdfSBuf *reply, const struct AudioSampleAttributes *attrs) { if (reply == NULL || attrs == NULL) { return HDF_FAILURE; } uint32_t tempAttrParam = (uint32_t)attrs->type; if (!HdfSbufWriteUint32(reply, tempAttrParam)) { return HDF_FAILURE; } tempAttrParam = (uint32_t)attrs->interleaved; if (!HdfSbufWriteUint32(reply, tempAttrParam)) { return HDF_FAILURE; } tempAttrParam = (uint32_t)attrs->format; if (!HdfSbufWriteUint32(reply, tempAttrParam)) { return HDF_FAILURE; } if (!HdfSbufWriteUint32(reply, attrs->sampleRate)) { return HDF_FAILURE; } if (!HdfSbufWriteUint32(reply, attrs->channelCount)) { return HDF_FAILURE; } if (!HdfSbufWriteUint32(reply, attrs->period)) { return HDF_FAILURE; } if (!HdfSbufWriteUint32(reply, attrs->frameSize)) { return HDF_FAILURE; } tempAttrParam = (uint32_t)(attrs->isBigEndian); if (!HdfSbufWriteUint32(reply, tempAttrParam)) { return HDF_FAILURE; } tempAttrParam = (uint32_t)(attrs->isSignedData); if (!HdfSbufWriteUint32(reply, tempAttrParam)) { return HDF_FAILURE; } if (!HdfSbufWriteUint32(reply, attrs->startThreshold)) { return HDF_FAILURE; } if (!HdfSbufWriteUint32(reply, attrs->stopThreshold)) { return HDF_FAILURE; } if (!HdfSbufWriteUint32(reply, attrs->silenceThreshold)) { return HDF_FAILURE; } return HDF_SUCCESS; } int32_t ReadAudioSapmleAttrbutes(struct HdfSBuf *data, struct AudioSampleAttributes *attrs) { if (data == NULL || attrs == NULL) { return HDF_FAILURE; } uint32_t tempAttrParam = 0; if (!HdfSbufReadUint32(data, &tempAttrParam)) { return HDF_FAILURE; } attrs->type = (enum AudioCategory)tempAttrParam; if (!HdfSbufReadUint32(data, &tempAttrParam)) { return HDF_FAILURE; } attrs->interleaved = (bool)tempAttrParam; if (!HdfSbufReadUint32(data, &tempAttrParam)) { return HDF_FAILURE; } attrs->format = (enum AudioFormat)tempAttrParam; if (!HdfSbufReadUint32(data, &(attrs->sampleRate))) { return HDF_FAILURE; } if (!HdfSbufReadUint32(data, &(attrs->channelCount))) { return HDF_FAILURE; } if (!HdfSbufReadUint32(data, &(attrs->period))) { return HDF_FAILURE; } if (!HdfSbufReadUint32(data, &(attrs->frameSize))) { return HDF_FAILURE; } if (!HdfSbufReadUint32(data, &tempAttrParam)) { return HDF_FAILURE; } attrs->isBigEndian = (bool)tempAttrParam; if (!HdfSbufReadUint32(data, &tempAttrParam)) { return HDF_FAILURE; } attrs->isSignedData = (bool)tempAttrParam; if (!HdfSbufReadUint32(data, &(attrs->startThreshold))) { return HDF_FAILURE; } if (!HdfSbufReadUint32(data, &(attrs->stopThreshold))) { return HDF_FAILURE; } if (!HdfSbufReadUint32(data, &(attrs->silenceThreshold))) { return HDF_FAILURE; } return HDF_SUCCESS; } int32_t AudioAdapterListCheckAndGetRender(struct AudioRender **render, struct HdfSBuf *data) { if (render == NULL || data == NULL) { AUDIO_FUNC_LOGE("render or data is null!"); return HDF_FAILURE; } struct AudioRender *renderTemp = NULL; const char *adapterName = NULL; uint32_t pid = 0; if (HdiServiceRenderCaptureReadData(data, &adapterName, &pid) < 0) { AUDIO_FUNC_LOGE("HdiServiceRenderStart: HdiServiceRenderCaptureReadData fail "); return HDF_FAILURE; } int ret = AudioAdapterListGetRender(adapterName, &renderTemp, pid); if (ret < 0) { return ret; } if (renderTemp == NULL) { return HDF_FAILURE; } *render = renderTemp; return HDF_SUCCESS; } int32_t AudioAdapterListCheckAndGetCapture(struct AudioCapture **capture, struct HdfSBuf *data) { if (capture == NULL || data == NULL) { AUDIO_FUNC_LOGE("capture or data is null!"); return HDF_FAILURE; } struct AudioCapture *captureTemp = NULL; const char *adapterName = NULL; uint32_t pid = 0; if (HdiServiceRenderCaptureReadData(data, &adapterName, &pid) < 0) { AUDIO_FUNC_LOGE("HdiServiceCaptureStart: HdiServiceRenderCaptureReadData fail "); return HDF_FAILURE; } int ret = AudioAdapterListGetCapture(adapterName, &captureTemp, pid); if (ret < 0) { return ret; } if (captureTemp == NULL) { return HDF_FAILURE; } *capture = captureTemp; return HDF_SUCCESS; } int32_t HdiServicePositionWrite(struct HdfSBuf *reply, uint64_t frames, struct AudioTimeStamp time) { if (reply == NULL) { return HDF_FAILURE; } if (!HdfSbufWriteUint64(reply, frames)) { return HDF_FAILURE; } if (!HdfSbufWriteInt64(reply, time.tvSec)) { return HDF_FAILURE; } if (!HdfSbufWriteInt64(reply, time.tvNSec)) { return HDF_FAILURE; } return HDF_SUCCESS; } int32_t HdiServiceReqMmapBuffer(struct AudioMmapBufferDescriptor *desc, struct HdfSBuf *data) { int32_t ret; if (desc == NULL || data == NULL) { AUDIO_FUNC_LOGE("desc or data is null!"); return AUDIO_HAL_ERR_INTERNAL; } uint64_t memAddr = 0; if (!HdfSbufReadUint64(data, &memAddr)) { AUDIO_FUNC_LOGE("memAddr Is NULL"); return AUDIO_HAL_ERR_INTERNAL; } desc->memoryAddress = (void *)(uintptr_t)memAddr; ret = HdfSbufReadFileDescriptor(data); if (ret < 0) { return AUDIO_HAL_ERR_INTERNAL; } desc->memoryFd = ret; if (!HdfSbufReadInt32(data, &desc->totalBufferFrames)) { return AUDIO_HAL_ERR_INTERNAL; } if (!HdfSbufReadInt32(data, &desc->transferFrameSize)) { return AUDIO_HAL_ERR_INTERNAL; } if (!HdfSbufReadInt32(data, &desc->isShareable)) { return AUDIO_HAL_ERR_INTERNAL; } if (!HdfSbufReadUint32(data, &desc->offset)) { return AUDIO_HAL_ERR_INTERNAL; } return AUDIO_HAL_SUCCESS; } static bool AudioPortBlockMarshalling(struct HdfSBuf *data, const struct AudioPort *dataBlock) { if (data == NULL) { HDF_LOGE("%{public}s: invalid sbuf", __func__); return false; } if (dataBlock == NULL) { HDF_LOGE("%{public}s: invalid data block", __func__); return false; } if (!HdfSbufWriteInt32(data, dataBlock->dir)) { HDF_LOGE("%{public}s: write dataBlock->dir failed!", __func__); return false; } if (!HdfSbufWriteUint32(data, dataBlock->portId)) { HDF_LOGE("%{public}s: write dataBlock->portId failed!", __func__); return false; } if (!HdfSbufWriteString(data, dataBlock->portName)) { HDF_LOGE("%{public}s: write dataBlock->portName failed!", __func__); return false; } return true; } static bool AudioAdapterDescriptorBlockMarshalling(struct HdfSBuf *data, const struct AudioAdapterDescriptor *dataBlock) { if (data == NULL) { HDF_LOGE("%{public}s: invalid sbuf", __func__); return false; } if (dataBlock == NULL) { HDF_LOGE("%{public}s: invalid data block", __func__); return false; } if (!HdfSbufWriteString(data, dataBlock->adapterName)) { HDF_LOGE("%{public}s: write dataBlock->adapterName failed!", __func__); return false; } if (!HdfSbufWriteUint32(data, dataBlock->portNum)) { HDF_LOGE("%{public}s: write dataBlock->portNum failed!", __func__); return false; } if (dataBlock->portNum == 0 || dataBlock->portNum > SUPPORT_PORT_NUM_MAX) { HDF_LOGE("%{public}s: error portNum is %{public}u", __func__, dataBlock->portNum); return false; } for (uint32_t i = 0; i < dataBlock->portNum; i++) { if (!AudioPortBlockMarshalling(data, &(dataBlock->ports)[i])) { HDF_LOGE("%{public}s: write (dataBlock->ports)[i] failed!", __func__); return false; } } return true; } static bool AudioSubPortCapabilityBlockMarshalling(struct HdfSBuf *data, const struct AudioPortCapability *dataBlock) { if (!HdfSbufWriteUint32(data, dataBlock->subPortsNum)) { HDF_LOGE("%{public}s: write dataBlock->subPortsLen failed!", __func__); return false; } for (uint32_t i = 0; i < dataBlock->subPortsNum; i++) { struct AudioSubPortCapability *item = &dataBlock->subPorts[i]; if (!HdfSbufWriteUint32(data, item->portId)) { HDF_LOGE("%{public}s: write dataBlock->portId failed!", __func__); return false; } if (!HdfSbufWriteString(data, item->desc)) { HDF_LOGE("%{public}s: write dataBlock->desc failed!", __func__); return false; } if (!HdfSbufWriteInt32(data, (int32_t)item->mask)) { HDF_LOGE("%{public}s: write dataBlock->mask failed!", __func__); return false; } } return true; } bool AudioPortCapabilityBlockMarshalling(struct HdfSBuf *data, const struct AudioPortCapability *dataBlock) { if (data == NULL || dataBlock == NULL) { HDF_LOGE("%{public}s: invalid sbuf or data block", __func__); return false; } if (!HdfSbufWriteUint32(data, dataBlock->deviceType)) { HDF_LOGE("%{public}s: write dataBlock->deviceType failed!", __func__); return false; } if (!HdfSbufWriteUint32(data, dataBlock->deviceId)) { HDF_LOGE("%{public}s: write dataBlock->deviceId failed!", __func__); return false; } if (!HdfSbufWriteInt8(data, dataBlock->hardwareMode ? 1 : 0)) { HDF_LOGE("%{public}s: write dataBlock->hardwareMode failed!", __func__); return false; } if (!HdfSbufWriteUint32(data, dataBlock->formatNum)) { HDF_LOGE("%{public}s: write dataBlock->formatNum failed!", __func__); return false; } if (!HdfSbufWriteInt32(data, *(dataBlock->formats))) { HDF_LOGE("%{public}s: failed to write dataBlock->formats", __func__); return false; } if (!HdfSbufWriteUint32(data, dataBlock->sampleRateMasks)) { HDF_LOGE("%{public}s: write dataBlock->sampleRateMasks failed!", __func__); return false; } if (!HdfSbufWriteInt32(data, (int32_t)dataBlock->channelMasks)) { HDF_LOGE("%{public}s: write dataBlock->channelMasks failed!", __func__); return false; } if (!HdfSbufWriteUint32(data, dataBlock->channelCount)) { HDF_LOGE("%{public}s: write dataBlock->channelCount failed!", __func__); return false; } if (!AudioSubPortCapabilityBlockMarshalling(data, dataBlock)) { HDF_LOGE("%{public}s: write (dataBlock->subPorts)[i] failed!", __func__); return false; } return true; } /**************************public************************/ int32_t HdiServiceGetFuncs() { AUDIO_FUNC_LOGD("enter"); if (g_serverManager != NULL) { return AUDIO_HAL_SUCCESS; } char *error = NULL; struct AudioManager *(*managerFuncs)(void); const char *hdiAudioVendorLibPath = HDF_LIBRARY_FULL_PATH("libhdi_audio"); void *handle = dlopen(hdiAudioVendorLibPath, RTLD_LAZY); if (handle == NULL) { error = dlerror(); AUDIO_FUNC_LOGE("audio load path %{public}s, dlopen err=%{public}s", hdiAudioVendorLibPath, error); return AUDIO_HAL_ERR_INTERNAL; } managerFuncs = dlsym(handle, "GetAudioManagerFuncs"); g_serverManager = managerFuncs(); if (g_serverManager == NULL) { error = dlerror(); AUDIO_FUNC_LOGE("dlsym GetAudioManagerFuncs err=%{public}s", error); dlclose(handle); handle = NULL; return AUDIO_HAL_ERR_INTERNAL; } AUDIO_FUNC_LOGD("end"); return AUDIO_HAL_SUCCESS; } void AudioHdiServerRelease(void) { AUDIO_FUNC_LOGI("enter to %{public}s!", __func__); if (g_serverManager == NULL) { AUDIO_FUNC_LOGE("manager func is null!"); return; } ReleaseAudioManagerObjectComm(g_serverManager); AUDIO_FUNC_LOGD("%{public}s success", __func__); return; } int32_t HdiServiceGetAllAdapter(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { (void)data; (void)client; if (reply == NULL) { AUDIO_FUNC_LOGE("reply is NULL!"); return AUDIO_HAL_ERR_INVALID_PARAM; } int32_t index; int32_t size = 0; struct AudioAdapterDescriptor *descs = NULL; int32_t ret = g_serverManager->GetAllAdapters(g_serverManager, &descs, &size); if (ret < 0) { AUDIO_FUNC_LOGE("g_manager->GetAllAdapters error"); return AUDIO_HAL_ERR_INTERNAL; } if (size > MAX_AUDIO_ADAPTER_NUM_SERVER || size <= 0 || descs == NULL) { AUDIO_FUNC_LOGE("size or g_descs is error"); return AUDIO_HAL_ERR_NOT_SUPPORT; } if (!HdfSbufWriteUint32(reply, size)) { AUDIO_FUNC_LOGE("write descs failed!"); return AUDIO_HAL_ERR_INTERNAL; } for (index = 0; index < size; index++) { if (!AudioAdapterDescriptorBlockMarshalling(reply, &descs[index])) { AUDIO_FUNC_LOGE("write &descs[%{public}d] failed!", index); return AUDIO_HAL_ERR_INTERNAL; } } g_descs = descs; ret = AdaptersServerManageInit(descs, size); if (ret != AUDIO_HAL_SUCCESS) { AUDIO_FUNC_LOGE("AdapterServerManageInit fail"); return ret; } return AUDIO_HAL_SUCCESS; } int32_t HdiServiceReleaseAudioManagerObject(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { (void)data; (void)reply; (void)client; AUDIO_FUNC_LOGI(); if (g_descs == NULL) { AUDIO_FUNC_LOGI("g_descs is NULL"); return AUDIO_HAL_SUCCESS; } AudioAdapterReleaseDescs(g_descs, AudioServerGetAdapterNum()); g_descs = NULL; return AUDIO_HAL_SUCCESS; } static int SwitchAdapter(struct AudioAdapterDescriptor *descs, const char *adapterNameCase, enum AudioPortDirection portFlag, struct AudioPort *renderPort, const int size) { if (descs == NULL || adapterNameCase == NULL || renderPort == NULL) { return HDF_FAILURE; } for (int index = 0; index < size; index++) { struct AudioAdapterDescriptor *desc = &descs[index]; if (desc == NULL) { continue; } if (desc->adapterName == NULL) { return HDF_FAILURE; } if (strcmp(desc->adapterName, adapterNameCase) != 0) { continue; } for (uint32_t port = 0; port < desc->portNum; port++) { if (desc->ports[port].dir == portFlag) { *renderPort = desc->ports[port]; AUDIO_FUNC_LOGI("portFlag=%{public}d index=%{public}d success!", portFlag, index); return index; } } } AUDIO_FUNC_LOGE("out! adapterNameCase=%{public}s", adapterNameCase); return HDF_FAILURE; } /* Adapter Check */ static enum AudioServerType g_loadServerFlag = AUDIO_SERVER_BOTTOM; enum AudioServerType AudioHdiGetLoadServerFlag(void) { return g_loadServerFlag; } void AudioHdiSetLoadServerFlag(enum AudioServerType serverType) { g_loadServerFlag = serverType; } void AudioHdiClearLoadServerFlag(void) { g_loadServerFlag = AUDIO_SERVER_BOTTOM; } static int32_t MatchAppropriateAdapter(enum AudioAdapterType adapterType) { switch (adapterType) { case AUDIO_ADAPTER_PRIMARY: case AUDIO_ADAPTER_PRIMARY_EXT: case AUDIO_ADAPTER_HDMI: if (AudioHdiGetLoadServerFlag() != AUDIO_SERVER_PRIMARY) { AUDIO_FUNC_LOGE("Can't loadAdapterPrimary."); return AUDIO_HAL_ERR_INTERNAL; } break; case AUDIO_ADAPTER_USB: if (AudioHdiGetLoadServerFlag() != AUDIO_SERVER_USB) { AUDIO_FUNC_LOGE("Can't loadAdapterUsb."); return AUDIO_HAL_ERR_INTERNAL; } break; case AUDIO_ADAPTER_A2DP: if (AudioHdiGetLoadServerFlag() != AUDIO_SERVER_A2DP) { AUDIO_FUNC_LOGE("Can't loadAdapterA2dp."); return AUDIO_HAL_ERR_INTERNAL; } break; default: AUDIO_FUNC_LOGE("An unsupported Adapter."); return AUDIO_HAL_ERR_NOT_SUPPORT; } return AUDIO_HAL_SUCCESS; } static int AudioServiceUpateDevice(struct HdfDeviceObject *device, const char *servInfo) { if (device == NULL || servInfo == NULL) { AUDIO_FUNC_LOGE("device or servInfo is null!"); return AUDIO_HAL_ERR_INVALID_PARAM; } if (HdfDeviceObjectSetServInfo(device, servInfo) != HDF_SUCCESS) { AUDIO_FUNC_LOGW("HdfDeviceObjectSetServInfo failed!"); return AUDIO_HAL_ERR_INTERNAL; } if (HdfDeviceObjectUpdate(device) != AUDIO_HAL_SUCCESS) { AUDIO_FUNC_LOGW("HdfDeviceObjectUpdate failed!"); return AUDIO_HAL_ERR_INTERNAL; } return AUDIO_HAL_SUCCESS; } int32_t AudioServiceStateChange(struct HdfDeviceObject *device, struct AudioEvent *audioSrvEvent) { if (device == NULL || audioSrvEvent == NULL) { AUDIO_FUNC_LOGE("device or audioSrvEvent is null!"); return AUDIO_HAL_ERR_INVALID_PARAM; } g_audioEventService.eventType = audioSrvEvent->eventType; g_audioEventService.deviceType = audioSrvEvent->deviceType; char strMsg[AUDIO_PNP_MSG_LEN_MAX] = {0}; int ret = snprintf_s(strMsg, AUDIO_PNP_MSG_LEN_MAX, AUDIO_PNP_MSG_LEN_MAX - 1, "EVENT_SERVICE_TYPE=0x%x;EVENT_LOAD_TYPE=0x%x;DEVICE_TYPE=0x%x", g_audioEventService.eventType, g_audioEventLoad.eventType, g_audioEventService.deviceType); if (ret >= 0) { if (AudioServiceUpateDevice(device, (const char *)strMsg) != AUDIO_HAL_SUCCESS) { AUDIO_FUNC_LOGW("AudioServiceUpate fail!"); return AUDIO_HAL_ERR_INTERNAL; } } return AUDIO_HAL_SUCCESS; } static int32_t AudioLoadStateChange(struct HdfDeviceObject *device, struct AudioEvent *audioLoadEvent) { if (device == NULL || audioLoadEvent == NULL) { AUDIO_FUNC_LOGE("device or audioLoadEvent is null!"); return AUDIO_HAL_ERR_INVALID_PARAM; } g_audioEventLoad.eventType = audioLoadEvent->eventType; g_audioEventLoad.deviceType = audioLoadEvent->deviceType; char strMsg[AUDIO_PNP_MSG_LEN_MAX] = {0}; int ret = snprintf_s(strMsg, AUDIO_PNP_MSG_LEN_MAX, AUDIO_PNP_MSG_LEN_MAX - 1, "EVENT_SERVICE_TYPE=0x%x;EVENT_LOAD_TYPE=0x%x;DEVICE_TYPE=0x%x", g_audioEventService.eventType, g_audioEventLoad.eventType, g_audioEventLoad.deviceType); if (ret >= 0) { if (AudioServiceUpateDevice(device, (const char *)strMsg) != AUDIO_HAL_SUCCESS) { AUDIO_FUNC_LOGE("AudioLoadUpate fail!"); return AUDIO_HAL_ERR_INTERNAL; } } return AUDIO_HAL_SUCCESS; } static int32_t HdiServiceDevOnLine(struct HdfDeviceObject *device, struct AudioManager *manager, const struct AudioAdapterDescriptor *desc, struct AudioAdapter **adapter, const char* adapterName) { if (device == NULL || manager == NULL || desc == NULL || adapter == NULL || adapterName == NULL) { AUDIO_FUNC_LOGE("param is null!"); return AUDIO_HAL_ERR_INVALID_PARAM; } int32_t ret = manager->LoadAdapter(manager, desc, adapter); if (ret < 0) { g_audioEventLoad.eventType = HDF_AUDIO_LOAD_FAILURE; } else { g_audioEventLoad.eventType = HDF_AUDIO_LOAD_SUCCESS; } if (AudioLoadStateChange(device, &g_audioEventLoad) != AUDIO_HAL_SUCCESS) { AUDIO_FUNC_LOGE("AudioLoadStateChange fail!"); } if (*adapter == NULL) { AUDIO_FUNC_LOGE("load audio device failed"); return AUDIO_HAL_ERR_INVALID_PARAM; } if (AudioAdapterListAdd(adapterName, *adapter)) { AUDIO_FUNC_LOGE("AudioAdapterListAdd error!"); manager->UnloadAdapter(manager, *adapter); return AUDIO_HAL_ERR_INTERNAL; } return AUDIO_HAL_SUCCESS; } static int32_t HdiServiceDevOffLine(struct HdfDeviceObject *device) { if (device == NULL) { AUDIO_FUNC_LOGE("device is null!"); return AUDIO_HAL_ERR_INVALID_PARAM; } g_audioEventLoad.eventType = HDF_AUDIO_LOAD_FAILURE; if (AudioLoadStateChange(device, &g_audioEventLoad) != AUDIO_HAL_SUCCESS) { AUDIO_FUNC_LOGE("AudioLoadStateChange fail!"); return AUDIO_HAL_ERR_INTERNAL; } return AUDIO_HAL_SUCCESS; } static int32_t HdiServiceLoadAdapterSubUsb(struct HdfDeviceObject *device, struct AudioManager *manager, const struct AudioAdapterDescriptor *desc, struct AudioAdapter **adapter, const char* adapterName) { if (device == NULL || manager == NULL || desc == NULL || adapter == NULL || adapterName == NULL) { AUDIO_FUNC_LOGE("param is null!"); return AUDIO_HAL_ERR_INVALID_PARAM; } if (g_audioEventPnp.eventType == HDF_AUDIO_DEVICE_REMOVE || g_audioEventPnp.eventType == HDF_AUDIO_EVENT_UNKOWN) { HdiServiceDevOffLine(device); AUDIO_FUNC_LOGE("eventType=0x%{public}x", g_audioEventPnp.eventType); return AUDIO_HAL_ERR_NOT_SUPPORT; } else if (g_audioEventPnp.eventType == HDF_AUDIO_DEVICE_ADD) { return HdiServiceDevOnLine(device, manager, desc, adapter, adapterName); } else { AUDIO_FUNC_LOGE("eventType=0x%{public}x nothing", g_audioEventPnp.eventType); return AUDIO_HAL_ERR_INTERNAL; } } static int32_t HdiServiceLoadAdapterSub(struct HdfDeviceObject *device, struct AudioManager *manager, const struct AudioAdapterDescriptor *desc, struct AudioAdapter **adapter, const char* adapterName) { AUDIO_FUNC_LOGD("enter"); if (device == NULL || manager == NULL || desc == NULL || adapter == NULL || adapterName == NULL) { AUDIO_FUNC_LOGE("param is null!"); return AUDIO_HAL_ERR_INVALID_PARAM; } enum AudioAdapterType sndCardType = MatchAdapterType(adapterName, desc->ports[0].portId); int32_t ret = MatchAppropriateAdapter(sndCardType); if (ret != AUDIO_HAL_SUCCESS) { AUDIO_FUNC_LOGE("load audio device not matched"); return AUDIO_HAL_ERR_INTERNAL; } switch (sndCardType) { case AUDIO_ADAPTER_PRIMARY: case AUDIO_ADAPTER_PRIMARY_EXT: case AUDIO_ADAPTER_HDMI: g_audioEventService.eventType = HDF_AUDIO_SERVICE_VALID; g_audioEventLoad.deviceType = HDF_AUDIO_PRIMARY_DEVICE; return HdiServiceDevOnLine(device, manager, desc, adapter, adapterName); case AUDIO_ADAPTER_USB: g_audioEventLoad.deviceType = HDF_AUDIO_USB_DEVICE; return HdiServiceLoadAdapterSubUsb(device, manager, desc, adapter, adapterName); case AUDIO_ADAPTER_A2DP: return AUDIO_HAL_ERR_NOT_SUPPORT; default: return AUDIO_HAL_ERR_NOT_SUPPORT; } } int32_t HdiServiceLoadAdapter(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { AUDIO_FUNC_LOGD("enter"); if (client == NULL || data == NULL || reply == NULL) { return AUDIO_HAL_ERR_INVALID_PARAM; } struct AudioAdapter *adapter = NULL; struct AudioPort renderPort; const char *adapterName = NULL; uint32_t tempDir = 0; if ((adapterName = HdfSbufReadString(data)) == NULL) { AUDIO_FUNC_LOGE("adapterNameCase Is NULL"); return AUDIO_HAL_ERR_INVALID_PARAM; } int32_t ret = AudioAdapterCheckListExist(adapterName); if (ret == AUDIO_HAL_ERR_INVALID_PARAM) { return AUDIO_HAL_ERR_INTERNAL; } if (ret == AUDIO_HAL_SUCCESS) { AUDIO_FUNC_LOGE("adapte[%{public}s] already exist !", adapterName); return AUDIO_HAL_SUCCESS; } if (!HdfSbufReadUint32(data, &tempDir)) { AUDIO_FUNC_LOGE("sbuf read tempDir failed!"); return AUDIO_HAL_ERR_INTERNAL; } enum AudioPortDirection port = (enum AudioPortDirection)tempDir; struct AudioManager *manager = g_serverManager; if (adapterName == NULL || manager == NULL || g_descs == NULL) { AUDIO_FUNC_LOGE("Point is NULL!"); return AUDIO_HAL_ERR_INTERNAL; } int index = SwitchAdapter(g_descs, adapterName, port, &renderPort, ServerManageGetAdapterNum(AudioServerGetAdapterNum())); if (index < 0) { return AUDIO_HAL_ERR_NOT_SUPPORT; } struct AudioAdapterDescriptor *desc = &g_descs[index]; ret = HdiServiceLoadAdapterSub(client->device, manager, desc, &adapter, adapterName); return ret; } int32_t HdiServiceInitAllPorts(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { if (client == NULL || data == NULL || reply == NULL) { return AUDIO_HAL_ERR_INVALID_PARAM; } const char *adapterName = NULL; struct AudioAdapter *adapter = NULL; if ((adapterName = HdfSbufReadString(data)) == NULL) { AUDIO_FUNC_LOGE("adapterNameCase Is NULL"); return AUDIO_HAL_ERR_INVALID_PARAM; } if (AudioAdapterListGetAdapter(adapterName, &adapter)) { AUDIO_FUNC_LOGE("AudioAdapterListGetAdapter fail"); return AUDIO_HAL_ERR_INTERNAL; } if (adapter == NULL) { AUDIO_FUNC_LOGE("adapter is NULL"); return AUDIO_HAL_ERR_INTERNAL; } if (adapter->InitAllPorts(adapter)) { AUDIO_FUNC_LOGE("InitAllPorts fail"); return AUDIO_HAL_ERR_INTERNAL; } return AUDIO_HAL_SUCCESS; } int32_t HdiServiceUnloadAdapter(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { if (client == NULL || data == NULL || reply == NULL) { return AUDIO_HAL_ERR_INVALID_PARAM; } struct AudioAdapter *adapter = NULL; const char *adapterName = NULL; int ret; struct AudioManager *manager = g_serverManager; if (manager == NULL) { AUDIO_FUNC_LOGE("Point is NULL!"); return AUDIO_HAL_ERR_INVALID_PARAM; } if ((adapterName = HdfSbufReadString(data)) == NULL) { AUDIO_FUNC_LOGE("adapterNameCase Is NULL"); return AUDIO_HAL_ERR_INVALID_PARAM; } ret = AudioAdapterListDestory(adapterName, &adapter); if (ret == AUDIO_HAL_ERR_INTERNAL) { AUDIO_FUNC_LOGI("Other dev Use the adapter"); return AUDIO_HAL_SUCCESS; } else if (ret == AUDIO_HAL_ERR_INVALID_PARAM) { AUDIO_FUNC_LOGE("param invalid!"); return AUDIO_HAL_ERR_INTERNAL; } if (adapter == NULL) { return AUDIO_HAL_ERR_INVALID_PARAM; } manager->UnloadAdapter(manager, adapter); g_audioEventLoad.eventType = HDF_AUDIO_UNLOAD; if (AudioLoadStateChange(client->device, &g_audioEventLoad) != AUDIO_HAL_SUCCESS) { AUDIO_FUNC_LOGE("AudioLoadStateChange fail!"); } AUDIO_FUNC_LOGI("Unload the adapter success!"); return AUDIO_HAL_SUCCESS; } int32_t HdiServiceGetPortCapability(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { if (client == NULL || data == NULL || reply == NULL) { return AUDIO_HAL_ERR_INVALID_PARAM; } struct AudioPort port; struct AudioPortCapability capability; struct AudioAdapter *adapter = NULL; const char *adapterName = HdfSbufReadString(data); if (adapterName == NULL) { AUDIO_FUNC_LOGE("adapterNameCase Is NULL"); return AUDIO_HAL_ERR_INVALID_PARAM; } if (!HdfSbufReadUint32(data, (uint32_t *)&port.dir)) { AUDIO_FUNC_LOGE("read port.dir error"); return AUDIO_HAL_ERR_INTERNAL; } if (!HdfSbufReadUint32(data, &port.portId)) { AUDIO_FUNC_LOGE("read port.portId error"); return AUDIO_HAL_ERR_INTERNAL; } if ((port.portName = HdfSbufReadString(data)) == NULL) { AUDIO_FUNC_LOGE("read port.portName error"); return AUDIO_HAL_ERR_INTERNAL; } if (AudioAdapterListGetAdapter(adapterName, &adapter)) { AUDIO_FUNC_LOGE("AudioAdapterListGetAdapter fail"); return AUDIO_HAL_ERR_INTERNAL; } if (adapter == NULL) { AUDIO_FUNC_LOGE("HdiServiceCreatRender adapter is NULL!"); return AUDIO_HAL_ERR_INVALID_PARAM; } int32_t ret = adapter->GetPortCapability(adapter, &port, &capability); if (ret < 0) { AUDIO_FUNC_LOGE("GetPortCapability failed ret = %{public}d", ret); return AUDIO_HAL_ERR_INTERNAL; } if (!AudioPortCapabilityBlockMarshalling(reply, &capability)) { AUDIO_FUNC_LOGE("AudioPortCapabilityBlockMarshalling failed"); return AUDIO_HAL_ERR_INTERNAL; } return AUDIO_HAL_SUCCESS; } int32_t HdiServiceSetPassthroughMode(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { if (client == NULL || data == NULL || reply == NULL) { return AUDIO_HAL_ERR_INVALID_PARAM; } struct AudioPort port; enum AudioPortPassthroughMode mode; struct AudioAdapter *adapter = NULL; const char *adapterName = NULL; if ((adapterName = HdfSbufReadString(data)) == NULL) { AUDIO_FUNC_LOGE("adapterNameCase Is NULL"); return AUDIO_HAL_ERR_INVALID_PARAM; } uint32_t tempDir = 0; if (!HdfSbufReadUint32(data, &tempDir)) { return AUDIO_HAL_ERR_INTERNAL; } port.dir = (enum AudioPortDirection)tempDir; AUDIO_FUNC_LOGD("port.dir = %{public}d", port.dir); if (!HdfSbufReadUint32(data, &port.portId)) { return AUDIO_HAL_ERR_INTERNAL; } if ((port.portName = HdfSbufReadString(data)) == NULL) { AUDIO_FUNC_LOGE("read port.portName failed"); return AUDIO_HAL_ERR_INTERNAL; } uint32_t tempMode = 0; if (!HdfSbufReadUint32(data, &tempMode)) { return AUDIO_HAL_ERR_INTERNAL; } mode = (enum AudioPortPassthroughMode)tempMode; AUDIO_FUNC_LOGD("ready in, mode = %{public}d", mode); if (AudioAdapterListGetAdapter(adapterName, &adapter)) { AUDIO_FUNC_LOGE("AudioAdapterListGetAdapter fail"); return AUDIO_HAL_ERR_INTERNAL; } if (adapter == NULL) { AUDIO_FUNC_LOGE("HdiServiceCreatRender adapter is NULL!"); return AUDIO_HAL_ERR_INVALID_PARAM; } if (adapter->SetPassthroughMode == NULL) { AUDIO_FUNC_LOGE("SetPassthroughMode is NULL"); return AUDIO_HAL_ERR_INTERNAL; } int ret = adapter->SetPassthroughMode(adapter, &port, mode); return ret; } int32_t HdiServiceGetPassthroughMode(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { if (client == NULL || data == NULL || reply == NULL) { return AUDIO_HAL_ERR_INVALID_PARAM; } enum AudioPortPassthroughMode mode = PORT_PASSTHROUGH_AUTO; struct AudioAdapter *adapter = NULL; const char *adapterName = NULL; struct AudioPort port; int32_t ret = memset_s(&port, sizeof(struct AudioPort), 0, sizeof(struct AudioPort)); if (ret != HDF_SUCCESS) { AUDIO_FUNC_LOGE("memset_s failed"); return AUDIO_HAL_ERR_INTERNAL; } if ((adapterName = HdfSbufReadString(data)) == NULL) { AUDIO_FUNC_LOGE("adapterNameCase Is NULL"); return AUDIO_HAL_ERR_INVALID_PARAM; } uint32_t tempDir = port.dir; if (!HdfSbufReadUint32(data, &tempDir)) { return AUDIO_HAL_ERR_INTERNAL; } port.dir = (enum AudioPortDirection)tempDir; if (!HdfSbufReadUint32(data, &port.portId)) { return AUDIO_HAL_ERR_INTERNAL; } if ((port.portName = HdfSbufReadString(data)) == NULL) { AUDIO_FUNC_LOGE("read port.portName failed"); return AUDIO_HAL_ERR_INTERNAL; } if (AudioAdapterListGetAdapter(adapterName, &adapter)) { AUDIO_FUNC_LOGE("AudioAdapterListGetAdapter fail"); return AUDIO_HAL_ERR_INTERNAL; } CHECK_NULL_PTR_RETURN_VALUE(adapter, AUDIO_HAL_ERR_INVALID_PARAM); if (adapter->GetPassthroughMode == NULL) { AUDIO_FUNC_LOGE("GetPassthroughMode is NULL"); return AUDIO_HAL_ERR_INTERNAL; } ret = adapter->GetPassthroughMode(adapter, &port, &mode); if (ret < 0) { AUDIO_FUNC_LOGE("GetPassthroughMode ret failed"); return AUDIO_HAL_ERR_INTERNAL; } uint32_t tempMode = (uint32_t)mode; if (!HdfSbufWriteUint32(reply, tempMode)) { return AUDIO_HAL_ERR_INTERNAL; } return AUDIO_HAL_SUCCESS; } static int32_t HdiServiceGetDevStatusByPnp(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { (void)reply; const char *strDevPlugMsg = NULL; if (client == NULL || data == NULL) { AUDIO_FUNC_LOGE("client or data is null!"); return AUDIO_HAL_ERR_INVALID_PARAM; } if ((strDevPlugMsg = HdfSbufReadString(data)) == NULL) { AUDIO_FUNC_LOGE("data is null!"); return AUDIO_HAL_ERR_INTERNAL; } if ((AudioPnpMsgReadValue(strDevPlugMsg, "EVENT_TYPE", &(g_audioEventPnp.eventType)) != HDF_SUCCESS) || (AudioPnpMsgReadValue(strDevPlugMsg, "DEVICE_TYPE", &(g_audioEventPnp.deviceType)) != HDF_SUCCESS)) { AUDIO_FUNC_LOGE("DeSerialize fail!"); return AUDIO_HAL_ERR_INTERNAL; } if (g_audioEventPnp.deviceType == HDF_AUDIO_USB_HEADSET || g_audioEventPnp.deviceType == HDF_AUDIO_USB_HEADPHONE || g_audioEventPnp.deviceType == HDF_AUDIO_USBA_HEADSET || g_audioEventPnp.deviceType == HDF_AUDIO_USBA_HEADPHONE) { g_audioEventService.deviceType = HDF_AUDIO_USB_DEVICE; if (g_audioEventPnp.eventType == HDF_AUDIO_DEVICE_ADD) { g_audioEventService.eventType = HDF_AUDIO_SERVICE_VALID; } else if (g_audioEventPnp.eventType == HDF_AUDIO_DEVICE_REMOVE) { g_audioEventService.eventType = HDF_AUDIO_SERVICE_INVALID; } } if (AudioServiceStateChange(client->device, &g_audioEventService) != AUDIO_HAL_SUCCESS) { AUDIO_FUNC_LOGE("AudioServiceStateChange fail!"); return AUDIO_HAL_ERR_INTERNAL; } return AUDIO_HAL_SUCCESS; } static bool AudioDevExtInfoBlockUnmarshalling(struct HdfSBuf *data, struct AudioDevExtInfo *dataBlock) { if (dataBlock == NULL) { HDF_LOGE("%{public}s: invalid data block", __func__); return false; } if (data == NULL) { HDF_LOGE("%{public}s: invalid sbuf or data block", __func__); goto ERROR; } if (!HdfSbufReadInt32(data, &dataBlock->moduleId)) { HDF_LOGE("%{public}s: read dataBlock->moduleId failed!", __func__); goto ERROR; } if (!HdfSbufReadInt32(data, (int32_t*)&dataBlock->type)) { HDF_LOGE("%{public}s: read dataBlock->type failed!", __func__); goto ERROR; } const char *descCp = HdfSbufReadString(data); if (descCp == NULL) { HDF_LOGE("%{public}s: read descCp failed!", __func__); goto ERROR; } dataBlock->desc = strdup(descCp); if (dataBlock->desc == NULL) { HDF_LOGE("strdup fail in %{public}s", __func__); goto ERROR; } return true; ERROR: if (dataBlock->desc != NULL) { OsalMemFree((void*)dataBlock->desc); dataBlock->desc = NULL; } return false; } static bool AudioMixExtInfoBlockUnmarshalling(struct HdfSBuf *data, struct AudioMixExtInfo *dataBlock) { if (data == NULL || dataBlock == NULL) { HDF_LOGE("%{public}s: invalid sbuf or data block", __func__); return false; } const struct AudioMixExtInfo *dataBlockPtr = (const struct AudioMixExtInfo *)HdfSbufReadUnpadBuffer(data, sizeof(struct AudioMixExtInfo)); if (dataBlockPtr == NULL) { HDF_LOGE("%{public}s: failed to read buffer data", __func__); return false; } if (memcpy_s(dataBlock, sizeof(struct AudioMixExtInfo), dataBlockPtr, sizeof(struct AudioMixExtInfo)) != EOK) { HDF_LOGE("%{public}s: failed to memcpy data", __func__); return false; } return true; } static bool AudioSessionExtInfoBlockUnmarshalling(struct HdfSBuf *data, struct AudioSessionExtInfo *dataBlock) { if (data == NULL || dataBlock == NULL) { HDF_LOGE("%{public}s: invalid sbuf or data block", __func__); return false; } const struct AudioSessionExtInfo *dataBlockPtr = (const struct AudioSessionExtInfo *)HdfSbufReadUnpadBuffer(data, sizeof(struct AudioSessionExtInfo)); if (dataBlockPtr == NULL) { HDF_LOGE("%{public}s: failed to read buffer data", __func__); return false; } if (memcpy_s(dataBlock, sizeof(struct AudioSessionExtInfo), dataBlockPtr, sizeof(struct AudioSessionExtInfo)) != EOK) { HDF_LOGE("%{public}s: failed to memcpy data", __func__); return false; } return true; } static void AudioDevExtInfoFree(struct AudioDevExtInfo *dataBlock, bool freeSelf) { if (dataBlock == NULL) { return; } if (dataBlock->desc != NULL) { OsalMemFree((void*)dataBlock->desc); dataBlock->desc = NULL; } if (freeSelf) { OsalMemFree(dataBlock); } } static bool AudioInfoBlockUnmarshalling(enum AudioPortType type, struct HdfSBuf *data, RouteExtInfo *dataBlock) { if (data == NULL || dataBlock == NULL) { HDF_LOGE("%{public}s: invalid sbuf or data block", __func__); return false; } bool ret = true; switch (type) { case AUDIO_PORT_DEVICE_TYPE: if (!AudioDevExtInfoBlockUnmarshalling(data, &dataBlock->device)) { HDF_LOGE("%{public}s: write dataBlock->device failed!", __func__); AudioDevExtInfoFree(&dataBlock->device, false); ret = false; } break; case AUDIO_PORT_MIX_TYPE: if (!AudioMixExtInfoBlockUnmarshalling(data, &dataBlock->mix)) { HDF_LOGE("%{public}s: write dataBlock->mix failed!", __func__); ret = false; } break; case AUDIO_PORT_SESSION_TYPE: if (!AudioSessionExtInfoBlockUnmarshalling(data, &dataBlock->session)) { HDF_LOGE("%{public}s: write dataBlock->session failed!", __func__); ret = false; } break; case AUDIO_PORT_UNASSIGNED_TYPE: default: ret = false; break; } return ret; } static bool AudioRouteNodeBlockUnmarshalling(struct HdfSBuf *data, struct AudioRouteNode *dataBlock) { if (data == NULL || dataBlock == NULL) { HDF_LOGE("%{public}s: invalid sbuf or data block", __func__); return false; } if (!HdfSbufReadInt32(data, &dataBlock->portId)) { HDF_LOGE("%{public}s: read dataBlock->portId failed!", __func__); return false; } if (!HdfSbufReadInt32(data, (int32_t*)&dataBlock->role)) { HDF_LOGE("%{public}s: read dataBlock->role failed!", __func__); return false; } if (!HdfSbufReadInt32(data, (int32_t*)&dataBlock->type)) { HDF_LOGE("%{public}s: read dataBlock->type failed!", __func__); return false; } if (!AudioInfoBlockUnmarshalling(dataBlock->type, data, (RouteExtInfo*)&dataBlock->ext)) { HDF_LOGE("%{public}s: read &dataBlock->ext failed!", __func__); return false; } return true; } static bool AudioRouteSinksBlockUnmarshalling( struct HdfSBuf *data, struct AudioRouteNode **sourcesOrSinksCp, uint32_t *sourcesOrSinksNum) { if (!HdfSbufReadUint32(data, sourcesOrSinksNum)) { HDF_LOGE("%{public}s: read sourcesOrSinksNum failed!", __func__); return false; } if (*sourcesOrSinksNum > 0) { *sourcesOrSinksCp = (struct AudioRouteNode*)OsalMemCalloc(sizeof(struct AudioRouteNode) * (*sourcesOrSinksNum)); if (*sourcesOrSinksCp == NULL) { return false; } for (uint32_t i = 0; i < *sourcesOrSinksNum; i++) { if (!AudioRouteNodeBlockUnmarshalling(data, (*sourcesOrSinksCp) + i)) { HDF_LOGE("%{public}s: read &sourcesOrSinksCp[i] failed!", __func__); OsalMemFree((void*)*sourcesOrSinksCp); return false; } } } return true; } static bool AudioRouteSourceBlockUnmarshalling(struct HdfSBuf *data, struct AudioRoute *dataBlock) { if (data == NULL || dataBlock == NULL) { HDF_LOGE("%{public}s: invalid sbuf or data block", __func__); return false; } struct AudioRouteNode* sourcesCp = NULL; uint32_t sourcesNum = 0; struct AudioRouteNode* sinksCp = NULL; uint32_t sinksNum = 0; if (!AudioRouteSinksBlockUnmarshalling(data, &sourcesCp, &sourcesNum)) { HDF_LOGE("%{public}s: read sources failed!", __func__); return false; } dataBlock->sources = sourcesCp; dataBlock->sourcesNum = sourcesNum; if (!AudioRouteSinksBlockUnmarshalling(data, &sinksCp, &sinksNum)) { HDF_LOGE("%{public}s: read sinks failed!", __func__); OsalMemFree((void*)sourcesCp); return false; } dataBlock->sinks = sinksCp; dataBlock->sinksNum = sinksNum; return true; } static void AudioRouteDevFreeByNum(const struct AudioRouteNode *routeNode, uint32_t num) { uint32_t nodeCnt; if (routeNode == NULL) { AUDIO_FUNC_LOGI("routeNode has been freed"); return; } for (nodeCnt = 0; nodeCnt < num; nodeCnt++) { if (routeNode[nodeCnt].type == AUDIO_PORT_DEVICE_TYPE) { AudioDevExtInfoFree((struct AudioDevExtInfo *)&routeNode[nodeCnt].ext.device, false); } } } static void AudioRouteFree(struct AudioRoute *dataBlock, bool freeSelf) { if (dataBlock == NULL) { AUDIO_FUNC_LOGI("dataBlock has been freed"); return; } if (dataBlock->sources != NULL) { AudioRouteDevFreeByNum(dataBlock->sources, dataBlock->sourcesNum); OsalMemFree((void*)dataBlock->sources); } if (dataBlock->sinks != NULL) { AudioRouteDevFreeByNum(dataBlock->sinks, dataBlock->sinksNum); OsalMemFree((void*)dataBlock->sinks); } if (freeSelf) { OsalMemFree((void*)dataBlock); } } static int32_t HdiSerStubUpdateAudioRoute(const struct HdfDeviceIoClient *client, struct HdfSBuf *audioAdapterData, struct HdfSBuf *audioAdapterReply) { int32_t audioAdapterRet = HDF_FAILURE; struct AudioRoute* route = NULL; int32_t routeHandle = 0; struct AudioAdapter *adapter = NULL; const char *adapterName = NULL; if ((adapterName = HdfSbufReadString(audioAdapterData)) == NULL) { AUDIO_FUNC_LOGE("adapterNameCase Is NULL"); return AUDIO_HAL_ERR_INVALID_PARAM; } route = (struct AudioRoute*)OsalMemAlloc(sizeof(struct AudioRoute)); if (route == NULL) { HDF_LOGE("%{public}s: malloc route failed", __func__); audioAdapterRet = HDF_ERR_MALLOC_FAIL; goto FINISHED; } if (!AudioRouteSourceBlockUnmarshalling(audioAdapterData, route)) { HDF_LOGE("%{public}s: read route failed!", __func__); audioAdapterRet = HDF_ERR_INVALID_PARAM; goto FINISHED; } if (AudioAdapterListGetAdapter(adapterName, &adapter)) { AUDIO_FUNC_LOGE("AudioAdapterListGetAdapter fail"); return AUDIO_HAL_ERR_INTERNAL; } if (adapter == NULL) { AUDIO_FUNC_LOGE("adapter is NULL!"); return AUDIO_HAL_ERR_INVALID_PARAM; } if (adapter->UpdateAudioRoute == NULL) { AUDIO_FUNC_LOGE("UpdateAudioRoute is NULL"); return AUDIO_HAL_ERR_INTERNAL; } audioAdapterRet = adapter->UpdateAudioRoute(adapter, route, &routeHandle); if (audioAdapterRet != HDF_SUCCESS) { HDF_LOGE("%{public}s: call UpdateAudioRoute function failed!", __func__); goto FINISHED; } if (!HdfSbufWriteInt32(audioAdapterReply, routeHandle)) { HDF_LOGE("%{public}s: write routeHandle failed!", __func__); audioAdapterRet = HDF_ERR_INVALID_PARAM; goto FINISHED; } FINISHED: if (route != NULL) { AudioRouteFree(route, true); route = NULL; } return audioAdapterRet; } static int32_t HdiSerStubReleaseAudioRoute(const struct HdfDeviceIoClient *client, struct HdfSBuf *audioAdapterData, struct HdfSBuf *audioAdapterReply) { int32_t audioAdapterRet = HDF_FAILURE; int32_t routeHandle = 0; struct AudioAdapter *adapter = NULL; const char *adapterName = NULL; if ((adapterName = HdfSbufReadString(audioAdapterData)) == NULL) { AUDIO_FUNC_LOGE("adapterNameCase Is NULL"); return AUDIO_HAL_ERR_INVALID_PARAM; } if (!HdfSbufReadInt32(audioAdapterData, &routeHandle)) { HDF_LOGE("%{public}s: read &routeHandle failed!", __func__); return HDF_ERR_INVALID_PARAM; } if (AudioAdapterListGetAdapter(adapterName, &adapter)) { AUDIO_FUNC_LOGE("AudioAdapterListGetAdapter fail"); return AUDIO_HAL_ERR_INTERNAL; } if (adapter == NULL || adapter->ReleaseAudioRoute == NULL) { AUDIO_FUNC_LOGE("adapter or ReleaseAudioRoute is NULL"); return AUDIO_HAL_ERR_INTERNAL; } audioAdapterRet = adapter->ReleaseAudioRoute(adapter, routeHandle); if (audioAdapterRet != HDF_SUCCESS) { HDF_LOGE("%{public}s: call ReleaseAudioRoute function failed!", __func__); } return audioAdapterRet; } static int32_t HdiServiceAdapterSetMicMute(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { bool mute = false; uint32_t tempMute = 0; struct AudioAdapter *adapter = NULL; const char *adapterName = NULL; if (client == NULL || data == NULL || reply == NULL) { AUDIO_FUNC_LOGE("client or data or reply is NULL"); return AUDIO_HAL_ERR_INVALID_PARAM; } if ((adapterName = HdfSbufReadString(data)) == NULL) { AUDIO_FUNC_LOGE("adapterName Is NULL "); return HDF_FAILURE; } if (!HdfSbufReadUint32(data, &tempMute)) { AUDIO_FUNC_LOGE("tempMute Is NULL "); return HDF_FAILURE; } mute = (bool)tempMute; if (AudioAdapterListGetAdapter(adapterName, &adapter) != HDF_SUCCESS) { AUDIO_FUNC_LOGE("AudioAdapterListGetAdapter fail"); return AUDIO_HAL_ERR_INTERNAL; } if (adapter == NULL || adapter->SetMicMute == NULL) { AUDIO_FUNC_LOGE("adapter or SetMicMute is NULL"); return AUDIO_HAL_ERR_INTERNAL; } return adapter->SetMicMute(adapter, mute); } static int32_t HdiServiceAdapterGetMicMute(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { if (client == NULL || data == NULL || reply == NULL) { AUDIO_FUNC_LOGE("client or data or reply is NULL"); return AUDIO_HAL_ERR_INVALID_PARAM; } bool mute = false; struct AudioAdapter *adapter = NULL; const char *adapterName = NULL; if ((adapterName = HdfSbufReadString(data)) == NULL) { AUDIO_FUNC_LOGE("adapterName Is NULL "); return HDF_FAILURE; } if (AudioAdapterListGetAdapter(adapterName, &adapter) != HDF_SUCCESS) { AUDIO_FUNC_LOGE("AudioAdapterListGetAdapter fail"); return AUDIO_HAL_ERR_INTERNAL; } if (adapter == NULL || adapter->GetMicMute == NULL) { AUDIO_FUNC_LOGE("adapter or SetMicMute is NULL"); return AUDIO_HAL_ERR_INTERNAL; } int ret = adapter->GetMicMute(adapter, &mute); if (ret < 0) { AUDIO_FUNC_LOGE("GetMicMute FAIL"); return ret; } if (!HdfSbufWriteUint32(reply, (uint32_t)mute)) { return AUDIO_HAL_ERR_INTERNAL; } return AUDIO_HAL_SUCCESS; } static int32_t HdiServiceAdapterSetVoiceVolume(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { float volume = 0; struct AudioAdapter *adapter = NULL; const char *adapterName = NULL; if (client == NULL || data == NULL || reply == NULL) { AUDIO_FUNC_LOGE("client or data or reply is NULL"); return AUDIO_HAL_ERR_INVALID_PARAM; } if ((adapterName = HdfSbufReadString(data)) == NULL) { AUDIO_FUNC_LOGE("adapterName Is NULL "); return HDF_FAILURE; } if (!HdfSbufReadFloat(data, &volume)) { AUDIO_FUNC_LOGE("volume Is NULL "); return HDF_FAILURE; } if (AudioAdapterListGetAdapter(adapterName, &adapter) != HDF_SUCCESS) { AUDIO_FUNC_LOGE("AudioAdapterListGetAdapter fail"); return AUDIO_HAL_ERR_INTERNAL; } if (adapter == NULL || adapter->SetVoiceVolume == NULL) { AUDIO_FUNC_LOGE("adapter or SetVoiceVolume is NULL"); return AUDIO_HAL_ERR_INTERNAL; } return adapter->SetVoiceVolume(adapter, volume); } static int32_t HdiServiceAdapterSetExtraParams(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { if (client == NULL || data == NULL || reply == NULL) { AUDIO_FUNC_LOGE("the parameter is empty"); return AUDIO_HAL_ERR_INVALID_PARAM; } struct AudioAdapter *adapter = NULL; const char *adapterName = NULL; const char *value = NULL; enum AudioExtParamKey key = AUDIO_EXT_PARAM_KEY_NONE; const char *condition = NULL; if ((adapterName = HdfSbufReadString(data)) == NULL) { AUDIO_FUNC_LOGE("adapterName is NULL"); return HDF_FAILURE; } if (AudioAdapterListGetAdapter(adapterName, &adapter)) { AUDIO_FUNC_LOGE("AudioAdapterListGetAdapter FAIL"); return AUDIO_HAL_ERR_INTERNAL; } if (adapter == NULL) { AUDIO_FUNC_LOGE("adapter is NULL"); return AUDIO_HAL_ERR_INTERNAL; } value = HdfSbufReadString(data); if (value == NULL) { AUDIO_FUNC_LOGE("value is NULL"); return AUDIO_HAL_ERR_INTERNAL; } if (adapter->SetExtraParams == NULL) { AUDIO_FUNC_LOGE("adapter or SetExtraParams is NULL"); return AUDIO_HAL_ERR_INTERNAL; } return adapter->SetExtraParams(adapter, key, condition, value); } static int32_t HdiServiceAdapterGetExtraParams(const struct HdfDeviceIoClient *client, struct HdfSBuf *data, struct HdfSBuf *reply) { if (client == NULL || data == NULL || reply == NULL) { AUDIO_FUNC_LOGE("the parameter is empty"); return AUDIO_HAL_ERR_INVALID_PARAM; } int32_t length = 0; struct AudioAdapter *adapter = NULL; const char *adapterName = NULL; enum AudioExtParamKey key = AUDIO_EXT_PARAM_KEY_NONE; const char *condition = NULL; char value[STR_MAX] = { 0 }; if ((adapterName = HdfSbufReadString(data)) == NULL) { AUDIO_FUNC_LOGE("adapterName is NULL"); return HDF_FAILURE; } if (AudioAdapterListGetAdapter(adapterName, &adapter)) { AUDIO_FUNC_LOGE("AudioAdapterListGetAdapter FAIL"); return AUDIO_HAL_ERR_INTERNAL; } if (adapter == NULL) { AUDIO_FUNC_LOGE("adapter is NULL"); return AUDIO_HAL_ERR_INTERNAL; } if (!HdfSbufReadInt32(data, &length)) { AUDIO_FUNC_LOGE("HdiServiceAdapterGetExtraParams FAIL! length is 0."); return AUDIO_HAL_ERR_INTERNAL; } if (adapter->GetExtraParams == NULL) { AUDIO_FUNC_LOGE("adapter or GetExtraParams is NULL"); return AUDIO_HAL_ERR_INTERNAL; } int32_t ret = adapter->GetExtraParams(adapter, key, condition, value, length); if (ret < 0) { AUDIO_FUNC_LOGE("GetExtraParams FAIL"); return ret; } if (!HdfSbufWriteString(reply, value)) { AUDIO_FUNC_LOGE("value write fail"); return AUDIO_HAL_ERR_INTERNAL; } return AUDIO_HAL_SUCCESS; } struct HdiServiceDispatchCmdHandleList g_hdiServiceDispatchCmdHandleList[] = { {AUDIO_HDI_MGR_GET_FUNCS, HdiServiceGetFuncs}, {AUDIO_HDI_MGR_GET_ALL_ADAPTER, HdiServiceGetAllAdapter}, {AUDIO_HDI_MGR_RELEASE, HdiServiceReleaseAudioManagerObject}, {AUDIO_HDI_MGR_LOAD_ADAPTER, HdiServiceLoadAdapter}, {AUDIO_HDI_MGR_UNLOAD_ADAPTER, HdiServiceUnloadAdapter}, {AUDIO_HDI_ADT_INIT_PORTS, HdiServiceInitAllPorts}, {AUDIO_HDI_ADT_GET_PORT_CAPABILITY, HdiServiceGetPortCapability}, {AUDIO_HDI_ADT_SET_PASS_MODE, HdiServiceSetPassthroughMode}, {AUDIO_HDI_ADT_GET_PASS_MODE, HdiServiceGetPassthroughMode}, {AUDIO_HDI_ADT_UPDATE_ROUTE, HdiSerStubUpdateAudioRoute}, {AUDIO_HDI_ADT_RELEASE_ROUTE, HdiSerStubReleaseAudioRoute}, {AUDIO_HDI_ADT_SET_MIC_MUTE, HdiServiceAdapterSetMicMute}, {AUDIO_HDI_ADT_GET_MIC_MUTE, HdiServiceAdapterGetMicMute}, {AUDIO_HDI_ADT_SET_VOICE_VOLUME, HdiServiceAdapterSetVoiceVolume}, {AUDIO_HDI_ADT_SET_EXTRA_PARAMS, HdiServiceAdapterSetExtraParams}, {AUDIO_HDI_ADT_GET_EXTRA_PARAMS, HdiServiceAdapterGetExtraParams}, {AUDIO_HDI_PNP_DEV_STATUS, HdiServiceGetDevStatusByPnp}, {AUDIO_HDI_RENDER_CREATE_RENDER, HdiServiceCreatRender}, {AUDIO_HDI_RENDER_DESTROY, HdiServiceRenderDestory}, {AUDIO_HDI_RENDER_START, HdiServiceRenderStart}, {AUDIO_HDI_RENDER_STOP, HdiServiceRenderStop}, {AUDIO_HDI_RENDER_PAUSE, HdiServiceRenderPause}, {AUDIO_HDI_RENDER_RESUME, HdiServiceRenderResume}, {AUDIO_HDI_RENDER_FLUSH, HdiServiceRenderFlush}, {AUDIO_HDI_RENDER_GET_FRAME_SIZE, HdiServiceRenderGetFrameSize}, {AUDIO_HDI_RENDER_GET_FRAME_COUNT, HdiServiceRenderGetFrameCount}, {AUDIO_HDI_RENDER_SET_SAMPLE_ATTR, HdiServiceRenderSetSampleAttr}, {AUDIO_HDI_RENDER_GET_SAMPLE_ATTR, HdiServiceRenderGetSampleAttr}, {AUDIO_HDI_RENDER_GET_CUR_CHANNEL_ID, HdiServiceRenderGetCurChannelId}, {AUDIO_HDI_RENDER_CHECK_SCENE_CAPABILITY, HdiServiceRenderCheckSceneCapability}, {AUDIO_HDI_RENDER_SELECT_SCENE, HdiServiceRenderSelectScene}, {AUDIO_HDI_RENDER_GET_MUTE, HdiServiceRenderGetMute}, {AUDIO_HDI_RENDER_SET_MUTE, HdiServiceRenderSetMute}, {AUDIO_HDI_RENDER_SET_VOLUME, HdiServiceRenderSetVolume}, {AUDIO_HDI_RENDER_GET_VOLUME, HdiServiceRenderGetVolume}, {AUDIO_HDI_RENDER_GET_GAIN_THRESHOLD, HdiServiceRenderGetGainThreshold}, {AUDIO_HDI_RENDER_GET_GAIN, HdiServiceRenderGetGain}, {AUDIO_HDI_RENDER_SET_GAIN, HdiServiceRenderSetGain}, {AUDIO_HDI_RENDER_GET_LATENCY, HdiServiceRenderGetLatency}, {AUDIO_HDI_RENDER_RENDER_FRAME, HdiServiceRenderRenderFrame}, {AUDIO_HDI_RENDER_GET_RENDER_POSITION, HdiServiceRenderGetRenderPosition}, {AUDIO_HDI_RENDER_GET_SPEED, HdiServiceRenderGetSpeed}, {AUDIO_HDI_RENDER_SET_SPEED, HdiServiceRenderSetSpeed}, {AUDIO_HDI_RENDER_SET_CHANNEL_MODE, HdiServiceRenderSetChannelMode}, {AUDIO_HDI_RENDER_GET_CHANNEL_MODE, HdiServiceRenderGetChannelMode}, {AUDIO_HDI_RENDER_SET_EXTRA_PARAMS, HdiServiceRenderSetExtraParams}, {AUDIO_HDI_RENDER_GET_EXTRA_PARAMS, HdiServiceRenderGetExtraParams}, {AUDIO_HDI_RENDER_REQ_MMAP_BUFFER, HdiServiceRenderReqMmapBuffer}, {AUDIO_HDI_RENDER_GET_MMAP_POSITION, HdiServiceRenderGetMmapPosition}, {AUDIO_HDI_RENDER_ADD_EFFECT, HdiServiceRenderAddEffect}, {AUDIO_HDI_RENDER_REMOVE_EFFECT, HdiServiceRenderRemoveEffect}, {AUDIO_HDI_RENDER_TURN_STAND_BY_MODE, HdiServiceRenderTurnStandbyMode}, {AUDIO_HDI_RENDER_DEV_DUMP, HdiServiceRenderDevDump}, {AUDIO_HDI_RENDER_REG_CALLBACK, HdiServiceRenderRegCallback}, {AUDIO_HDI_RENDER_DRAIN_BUFFER, HdiServiceRenderDrainBuffer}, }; static struct HdiServiceDispatchCmdHandleList g_hdiServiceDispatchCmdHandleCapList[] = { {AUDIO_HDI_CAPTURE_CREATE_CAPTURE, HdiServiceCreatCapture}, {AUDIO_HDI_CAPTURE_DESTROY, HdiServiceCaptureDestory}, {AUDIO_HDI_CAPTURE_START, HdiServiceCaptureStart}, {AUDIO_HDI_CAPTURE_STOP, HdiServiceCaptureStop}, {AUDIO_HDI_CAPTURE_PAUSE, HdiServiceCapturePause}, {AUDIO_HDI_CAPTURE_RESUME, HdiServiceCaptureResume}, {AUDIO_HDI_CAPTURE_FLUSH, HdiServiceCaptureFlush}, {AUDIO_HDI_CAPTURE_GET_FRAME_SIZE, HdiServiceCaptureGetFrameSize}, {AUDIO_HDI_CAPTURE_GET_FRAME_COUNT, HdiServiceCaptureGetFrameCount}, {AUDIO_HDI_CAPTURE_SET_SAMPLE_ATTR, HdiServiceCaptureSetSampleAttr}, {AUDIO_HDI_CAPTURE_GET_SAMPLE_ATTR, HdiServiceCaptureGetSampleAttr}, {AUDIO_HDI_CAPTURE_GET_CUR_CHANNEL_ID, HdiServiceCaptureGetCurChannelId}, {AUDIO_HDI_CAPTURE_CHECK_SCENE_CAPABILITY, HdiServiceCaptureCheckSceneCapability}, {AUDIO_HDI_CAPTURE_SELECT_SCENE, HdiServiceCaptureSelectScene}, {AUDIO_HDI_CAPTURE_GET_MUTE, HdiServiceCaptureGetMute}, {AUDIO_HDI_CAPTURE_SET_MUTE, HdiServiceCaptureSetMute}, {AUDIO_HDI_CAPTURE_SET_VOLUME, HdiServiceCaptureSetVolume}, {AUDIO_HDI_CAPTURE_GET_VOLUME, HdiServiceCaptureGetVolume}, {AUDIO_HDI_CAPTURE_GET_GAIN_THRESHOLD, HdiServiceCaptureGetGainThreshold}, {AUDIO_HDI_CAPTURE_GET_GAIN, HdiServiceCaptureGetGain}, {AUDIO_HDI_CAPTURE_SET_GAIN, HdiServiceCaptureSetGain}, {AUDIO_HDI_CAPTURE_CAPTURE_FRAME, HdiServiceCaptureCaptureFrame}, {AUDIO_HDI_CAPTURE_GET_CAPTURE_POSITION, HdiServiceCaptureGetCapturePosition}, {AUDIO_HDI_CAPTURE_SET_EXTRA_PARAMS, HdiServiceCaptureSetExtraParams}, {AUDIO_HDI_CAPTURE_GET_EXTRA_PARAMS, HdiServiceCaptureGetExtraParams}, {AUDIO_HDI_CAPTURE_REQ_MMAP_BUFFER, HdiServiceCaptureReqMmapBuffer}, {AUDIO_HDI_CAPTURE_GET_MMAP_POSITION, HdiServiceCaptureGetMmapPosition}, {AUDIO_HDI_CAPTURE_ADD_EFFECT, HdiServiceCaptureAddEffect}, {AUDIO_HDI_CAPTURE_REMOVE_EFFECT, HdiServiceCaptureRemoveEffect}, {AUDIO_HDI_CAPTURE_TURN_STAND_BY_MODE, HdiServiceCaptureTurnStandbyMode}, {AUDIO_HDI_CAPTURE_DEV_DUMP, HdiServiceCaptureDevDump}, }; int32_t HdiServiceDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply) { unsigned int i; AUDIO_FUNC_LOGD("cmdId = %{public}d", cmdId); if (client == NULL) { AUDIO_FUNC_LOGE("ControlDispatch: input para is NULL."); return AUDIO_HAL_ERR_INVALID_PARAM; } if (!HdfDeviceObjectCheckInterfaceDesc(client->device, data)) { AUDIO_FUNC_LOGE("check interface token failed"); return AUDIO_HAL_ERR_INVALID_PARAM; } if (cmdId > AUDIO_HDI_CAPTURE_DEV_DUMP || cmdId < 0) { AUDIO_FUNC_LOGE("ControlDispatch: invalid cmdId = %{public}d", cmdId); return AUDIO_HAL_ERR_INTERNAL; } else if (cmdId <= AUDIO_HDI_RENDER_DRAIN_BUFFER) { for (i = 0; i < sizeof(g_hdiServiceDispatchCmdHandleList) / sizeof(g_hdiServiceDispatchCmdHandleList[0]); ++i) { if ((cmdId == (int)(g_hdiServiceDispatchCmdHandleList[i].cmd)) && (g_hdiServiceDispatchCmdHandleList[i].func != NULL)) { return g_hdiServiceDispatchCmdHandleList[i].func(client, data, reply); } } } else { for (i = 0; i < sizeof(g_hdiServiceDispatchCmdHandleCapList) / sizeof(g_hdiServiceDispatchCmdHandleCapList[0]); ++i) { if ((cmdId == (int)(g_hdiServiceDispatchCmdHandleCapList[i].cmd)) && (g_hdiServiceDispatchCmdHandleCapList[i].func != NULL)) { return g_hdiServiceDispatchCmdHandleCapList[i].func(client, data, reply); } } } return AUDIO_HAL_ERR_INTERNAL; }