mirror of
https://github.com/openharmony/drivers_peripheral.git
synced 2026-08-25 02:23:31 -04:00
4d06f9a1c1
Signed-off-by: vb6174 <zhangyunhu@huawei.com>
355 lines
11 KiB
C
355 lines
11 KiB
C
/*
|
|
* Copyright (c) 2022 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 <stdio.h>
|
|
#include <signal.h>
|
|
#include <unistd.h>
|
|
#include "securec.h"
|
|
#include "hdf_base.h"
|
|
#include "hdf_io_service_if.h"
|
|
#include "hdf_service_status.h"
|
|
#include "servmgr_hdi.h"
|
|
#include "servstat_listener_hdi.h"
|
|
#include "audio_events.h"
|
|
#include "hdf_audio_events.h"
|
|
|
|
#define AUDIO_FUNC_LOGE(fmt, arg...) do { \
|
|
printf("%s: [%s]: [%d]:[ERROR]:" fmt"\n", __FILE__, __func__, __LINE__, ##arg); \
|
|
} while (0)
|
|
|
|
static int32_t AudioServiceDeviceVal(enum AudioDeviceType deviceType)
|
|
{
|
|
switch (deviceType) {
|
|
case HDF_AUDIO_PRIMARY_DEVICE: // primary Service
|
|
printf("*****************: Primary service valid.\n");
|
|
return HDF_SUCCESS;
|
|
case HDF_AUDIO_USB_DEVICE: // Usb Service
|
|
printf("*****************: USB service valid.\n");
|
|
return HDF_SUCCESS;
|
|
case HDF_AUDIO_A2DP_DEVICE: // A2dp Service
|
|
return HDF_ERR_NOT_SUPPORT;
|
|
default:
|
|
return HDF_FAILURE;
|
|
}
|
|
}
|
|
|
|
static int32_t AudioServiceDeviceInVal(enum AudioDeviceType deviceType)
|
|
{
|
|
switch (deviceType) {
|
|
case HDF_AUDIO_PRIMARY_DEVICE: // primary Service
|
|
printf("*****************: Primary service Invalid.\n");
|
|
return HDF_SUCCESS;
|
|
case HDF_AUDIO_USB_DEVICE: // Usb Service
|
|
printf("*****************: USB service Invalid.\n");
|
|
return HDF_SUCCESS;
|
|
case HDF_AUDIO_A2DP_DEVICE: // A2dp Service
|
|
return HDF_ERR_NOT_SUPPORT;
|
|
default:
|
|
return HDF_FAILURE;
|
|
}
|
|
}
|
|
|
|
static int32_t AudioServiceMsgParse(struct AudioEvent *svcMsg)
|
|
{
|
|
if (svcMsg == NULL) {
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
switch (svcMsg->eventType) {
|
|
case HDF_AUDIO_EVENT_UNKOWN:
|
|
return HDF_FAILURE;
|
|
case HDF_AUDIO_SERVICE_VALID:
|
|
return AudioServiceDeviceVal(svcMsg->deviceType);
|
|
case HDF_AUDIO_SERVICE_INVALID:
|
|
return AudioServiceDeviceInVal(svcMsg->deviceType);
|
|
default:
|
|
return HDF_FAILURE;
|
|
}
|
|
}
|
|
|
|
static int AudioGetServiceStatus(const struct ServiceStatus *svcStatus)
|
|
{
|
|
if (svcStatus == NULL) {
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
struct AudioEvent serviceMsg = {
|
|
.eventType = HDF_AUDIO_EVENT_UNKOWN,
|
|
.deviceType = HDF_AUDIO_DEVICE_UNKOWN,
|
|
};
|
|
char strTemp[AUDIO_PNP_MSG_LEN_MAX] = {0};
|
|
if (memcpy_s(strTemp, AUDIO_PNP_MSG_LEN_MAX, (char *)svcStatus->info, strlen((char *)svcStatus->info))) {
|
|
return HDF_FAILURE;
|
|
}
|
|
if ((AudioPnpMsgReadValue(strTemp, "EVENT_SERVICE_TYPE", &(serviceMsg.eventType)) != HDF_SUCCESS) ||
|
|
(AudioPnpMsgReadValue(strTemp, "DEVICE_TYPE", &(serviceMsg.deviceType)) != HDF_SUCCESS)) {
|
|
return HDF_FAILURE;
|
|
}
|
|
if (AudioServiceMsgParse(&serviceMsg) != HDF_SUCCESS) {
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
return HDF_SUCCESS;
|
|
}
|
|
|
|
static int32_t AudioLoadDeviceSucc(enum AudioDeviceType deviceType)
|
|
{
|
|
switch (deviceType) {
|
|
case HDF_AUDIO_PRIMARY_DEVICE: // primary load
|
|
printf("*****************: Primary load success.\n");
|
|
return HDF_SUCCESS;
|
|
case HDF_AUDIO_USB_DEVICE: // Usb load
|
|
printf("*****************: USB load success.\n");
|
|
return HDF_SUCCESS;
|
|
case HDF_AUDIO_A2DP_DEVICE: // A2dp load
|
|
return HDF_ERR_NOT_SUPPORT;
|
|
default:
|
|
return HDF_FAILURE;
|
|
}
|
|
}
|
|
|
|
static int32_t AudioLoadDeviceFail(enum AudioDeviceType deviceType)
|
|
{
|
|
switch (deviceType) {
|
|
case HDF_AUDIO_PRIMARY_DEVICE: // primary load
|
|
printf("*****************: Primary load fail.\n");
|
|
return HDF_SUCCESS;
|
|
case HDF_AUDIO_USB_DEVICE: // Usb load
|
|
printf("*****************: USB load fail.\n");
|
|
return HDF_SUCCESS;
|
|
case HDF_AUDIO_A2DP_DEVICE: // A2dp load
|
|
return HDF_ERR_NOT_SUPPORT;
|
|
default:
|
|
return HDF_FAILURE;
|
|
}
|
|
}
|
|
|
|
static int32_t AudioUnLoadDevice(enum AudioDeviceType deviceType)
|
|
{
|
|
switch (deviceType) {
|
|
case HDF_AUDIO_PRIMARY_DEVICE: // primary load
|
|
printf("*****************: Primary unload.\n");
|
|
return HDF_SUCCESS;
|
|
case HDF_AUDIO_USB_DEVICE: // Usb load
|
|
printf("*****************: USB unload.\n");
|
|
return HDF_SUCCESS;
|
|
case HDF_AUDIO_A2DP_DEVICE: // A2dp load
|
|
return HDF_ERR_NOT_SUPPORT;
|
|
default:
|
|
return HDF_FAILURE;
|
|
}
|
|
}
|
|
|
|
static int32_t AudioLoadMsgParse(struct AudioEvent *loadMsg)
|
|
{
|
|
if (loadMsg == NULL) {
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
switch (loadMsg->eventType) {
|
|
case HDF_AUDIO_LOAD_SUCCESS:
|
|
return AudioLoadDeviceSucc(loadMsg->deviceType);
|
|
case HDF_AUDIO_LOAD_FAILURE:
|
|
return AudioLoadDeviceFail(loadMsg->deviceType);
|
|
case HDF_AUDIO_UNLOAD:
|
|
return AudioUnLoadDevice(loadMsg->deviceType);
|
|
default:
|
|
return HDF_FAILURE;
|
|
}
|
|
}
|
|
|
|
static int AudioGetLoadStatus(struct ServiceStatus *svcStatus)
|
|
{
|
|
if (svcStatus == NULL) {
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
struct AudioEvent loadMsg = {
|
|
.eventType = HDF_AUDIO_EVENT_UNKOWN,
|
|
.deviceType = HDF_AUDIO_DEVICE_UNKOWN,
|
|
};
|
|
char strTemp[AUDIO_PNP_MSG_LEN_MAX] = {0};
|
|
if (memcpy_s(strTemp, AUDIO_PNP_MSG_LEN_MAX, (char *)svcStatus->info, strlen((char *)svcStatus->info))) {
|
|
return HDF_FAILURE;
|
|
}
|
|
if ((AudioPnpMsgReadValue(strTemp, "EVENT_LOAD_TYPE", &(loadMsg.eventType)) != HDF_SUCCESS) ||
|
|
(AudioPnpMsgReadValue(strTemp, "DEVICE_TYPE", &(loadMsg.deviceType)) != HDF_SUCCESS)) {
|
|
return HDF_FAILURE;
|
|
}
|
|
if (AudioLoadMsgParse(&loadMsg) != HDF_SUCCESS) {
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
return HDF_SUCCESS;
|
|
}
|
|
|
|
static int32_t AudioPnpDeviceAdd(enum AudioDeviceType deviceType)
|
|
{
|
|
switch (deviceType) {
|
|
case HDF_AUDIO_USB_HEADPHONE: // USB Audio Add
|
|
case HDF_AUDIO_USBA_HEADPHONE:
|
|
printf("*****************: USB Audio earphone microphone add.\n");
|
|
return HDF_SUCCESS;
|
|
case HDF_AUDIO_USB_HEADSET:
|
|
case HDF_AUDIO_USBA_HEADSET:
|
|
printf("*****************: USB Audio earphone mic&speaker add.\n");
|
|
return HDF_SUCCESS;
|
|
case HDF_AUDIO_A2DP_DEVICE: // A2dp Add
|
|
return HDF_ERR_NOT_SUPPORT;
|
|
default:
|
|
return HDF_FAILURE;
|
|
}
|
|
}
|
|
|
|
static int32_t AudioPnpDeviceRemove(enum AudioDeviceType deviceType)
|
|
{
|
|
switch (deviceType) {
|
|
case HDF_AUDIO_USB_HEADPHONE: // USB Audio Remove
|
|
case HDF_AUDIO_USBA_HEADPHONE:
|
|
printf("*****************: USB Audio earphone microphone remove.\n");
|
|
return HDF_SUCCESS;
|
|
case HDF_AUDIO_USB_HEADSET:
|
|
case HDF_AUDIO_USBA_HEADSET:
|
|
printf("*****************: USB Audio earphone mic&speaker remove.\n");
|
|
return HDF_SUCCESS;
|
|
case HDF_AUDIO_A2DP_DEVICE: // A2dp Remove
|
|
return HDF_ERR_NOT_SUPPORT;
|
|
default:
|
|
return HDF_FAILURE;
|
|
}
|
|
}
|
|
|
|
|
|
static int32_t AudioPnpMsgParse(struct AudioEvent *pnpMsg)
|
|
{
|
|
if (pnpMsg == NULL) {
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
switch (pnpMsg->eventType) {
|
|
case HDF_AUDIO_EVENT_UNKOWN:
|
|
return HDF_FAILURE;
|
|
case HDF_AUDIO_DEVICE_ADD:
|
|
return AudioPnpDeviceAdd(pnpMsg->deviceType);
|
|
case HDF_AUDIO_DEVICE_REMOVE:
|
|
return AudioPnpDeviceRemove(pnpMsg->deviceType);
|
|
default:
|
|
return HDF_FAILURE;
|
|
}
|
|
}
|
|
|
|
static int AudioGetUsbPnpStatus(struct ServiceStatus *svcStatus)
|
|
{
|
|
if (svcStatus == NULL) {
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
struct AudioEvent pnpMsg = {
|
|
.eventType = HDF_AUDIO_EVENT_UNKOWN,
|
|
.deviceType = HDF_AUDIO_DEVICE_UNKOWN,
|
|
};
|
|
char strTemp[AUDIO_PNP_MSG_LEN_MAX] = {0};
|
|
if (memcpy_s(strTemp, AUDIO_PNP_MSG_LEN_MAX, (char *)svcStatus->info, strlen((char *)svcStatus->info))) {
|
|
return HDF_FAILURE;
|
|
}
|
|
if ((AudioPnpMsgReadValue(strTemp, "EVENT_TYPE", &(pnpMsg.eventType)) != HDF_SUCCESS) ||
|
|
(AudioPnpMsgReadValue(strTemp, "DEVICE_TYPE", &(pnpMsg.deviceType)) != HDF_SUCCESS)) {
|
|
return HDF_FAILURE;
|
|
}
|
|
if (AudioPnpMsgParse(&pnpMsg) != HDF_SUCCESS) {
|
|
return HDF_FAILURE;
|
|
}
|
|
|
|
return HDF_SUCCESS;
|
|
}
|
|
|
|
static void AudioUsbPnpOnSvcStatusReceived(struct ServiceStatusListener *listener, struct ServiceStatus *svcStatus)
|
|
{
|
|
if (listener == NULL || svcStatus == NULL) {
|
|
AUDIO_FUNC_LOGE("listener or svcStatus is NULL!");
|
|
return;
|
|
}
|
|
|
|
printf("\n===============================================================================\n"
|
|
"@@@@@ serviceName: %s\n"
|
|
"@@@@@ deviceClass: %d\n"
|
|
"@@@@@ status : %d\n"
|
|
"@@@@@ info : %s"
|
|
"\n===============================================================================\n",
|
|
svcStatus->serviceName, svcStatus->deviceClass, svcStatus->status, svcStatus->info);
|
|
|
|
(void)AudioGetUsbPnpStatus(svcStatus);
|
|
(void)AudioGetLoadStatus(svcStatus);
|
|
(void)AudioGetServiceStatus(svcStatus);
|
|
}
|
|
|
|
static struct HDIServiceManager *g_servmgr = NULL;
|
|
static struct ServiceStatusListener *g_listener = NULL;
|
|
static bool g_listenerState = false;
|
|
|
|
static void StopListenerBySig(int32_t sig)
|
|
{
|
|
printf("%s: Signal = %d\n", __func__, sig);
|
|
if (g_servmgr == NULL || g_listener == NULL) {
|
|
AUDIO_FUNC_LOGE("g_servmgr or g_listener is null!\n");
|
|
return;
|
|
}
|
|
|
|
int32_t ret = g_servmgr->UnregisterServiceStatusListener(g_servmgr, g_listener);
|
|
if (ret != HDF_SUCCESS) {
|
|
AUDIO_FUNC_LOGE("UnregisterServiceStatusListener fail! ret = %d.\n", ret);
|
|
return;
|
|
}
|
|
HdiServiceStatusListenerFree(g_listener);
|
|
HDIServiceManagerRelease(g_servmgr);
|
|
g_listenerState = false;
|
|
g_servmgr = NULL;
|
|
return;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
printf("%s: system audio listener start \n", __func__);
|
|
g_servmgr = HDIServiceManagerGet();
|
|
if (g_servmgr == NULL) {
|
|
AUDIO_FUNC_LOGE("HDIServiceManagerGet failed.\n");
|
|
return HDF_FAILURE;
|
|
}
|
|
g_listener = HdiServiceStatusListenerNewInstance();
|
|
if (g_listener == NULL) {
|
|
AUDIO_FUNC_LOGE("HdiServiceStatusListenerNewInstance failed.\n");
|
|
HDIServiceManagerRelease(g_servmgr);
|
|
g_servmgr = NULL;
|
|
return HDF_FAILURE;
|
|
}
|
|
g_listener->callback = AudioUsbPnpOnSvcStatusReceived;
|
|
int32_t status = g_servmgr->RegisterServiceStatusListener(g_servmgr, g_listener, DEVICE_CLASS_AUDIO);
|
|
if (status != HDF_SUCCESS) {
|
|
AUDIO_FUNC_LOGE("RegisterServiceStatusListener fail! ret = %d.\n", status);
|
|
HDIServiceManagerRelease(g_servmgr);
|
|
g_servmgr = NULL;
|
|
HdiServiceStatusListenerFree(g_listener);
|
|
return HDF_FAILURE;
|
|
}
|
|
g_listenerState = true;
|
|
(void)signal(SIGINT, StopListenerBySig);
|
|
(void)signal(SIGTERM, StopListenerBySig);
|
|
while (g_listenerState) {
|
|
sleep(1); // Wait for 1 second
|
|
}
|
|
|
|
return HDF_SUCCESS;
|
|
}
|