1 /*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "hdf_audio_pnp_server.h"
17 #include "audio_uhdf_log.h"
18 #include "hdf_audio_input_event.h"
19 #include "hdf_audio_pnp_uevent.h"
20 #include "hdf_audio_pnp_uevent_hdmi.h"
21 #include "hdf_device_desc.h"
22 #include "hdf_device_object.h"
23 #include "hdf_io_service_if.h"
24 #include "hdf_sbuf.h"
25 #include "hdf_service_status.h"
26 #include "securec.h"
27 #include "servmgr_hdi.h"
28
29 #define HDF_LOG_TAG HDF_AUDIO_HOST
30 #define AUDIO_HDI_SERVICE_NAME "audio_hdi_usb_service"
31 #define AUDIO_TOKEN_SERVER_NAME "ohos.hdi.audio_service"
32 #define AUDIO_PNP_INFO_LEN_MAX 256
33 #define AUDIO_CONTROL "hdf_audio_control"
34
35 #define AUDIODRV_CTRL_IOCTRL_ELEM_HDMI 5 // define from adm control stream id
36
37 static struct HdfDeviceObject *g_audioPnpDevice = NULL;
38
AudioPnpUpdateInfo(const char * statusInfo)39 int32_t AudioPnpUpdateInfo(const char *statusInfo)
40 {
41 if (g_audioPnpDevice == NULL) {
42 AUDIO_FUNC_LOGE("g_audioPnpDevice is null!");
43 return HDF_ERR_INVALID_PARAM;
44 }
45 if (statusInfo == NULL) {
46 AUDIO_FUNC_LOGE("statusInfo is null!");
47 return HDF_ERR_INVALID_PARAM;
48 }
49
50 if (HdfDeviceObjectSetServInfo(g_audioPnpDevice, statusInfo) != HDF_SUCCESS) {
51 AUDIO_FUNC_LOGE("set audio new status info failed!");
52 return HDF_FAILURE;
53 }
54 if (HdfDeviceObjectUpdate(g_audioPnpDevice) != HDF_SUCCESS) {
55 AUDIO_FUNC_LOGE("update audio status info failed!");
56 return HDF_FAILURE;
57 }
58
59 return HDF_SUCCESS;
60 }
61
AudioPnpUpdateInfoOnly(struct AudioEvent audioEvent)62 int32_t AudioPnpUpdateInfoOnly(struct AudioEvent audioEvent)
63 {
64 int32_t ret;
65 char pnpInfo[AUDIO_PNP_INFO_LEN_MAX] = {0};
66
67 ret = snprintf_s(pnpInfo, AUDIO_PNP_INFO_LEN_MAX, AUDIO_PNP_INFO_LEN_MAX - 1, "EVENT_TYPE=%u;DEVICE_TYPE=%u",
68 audioEvent.eventType, audioEvent.deviceType);
69 if (ret < 0) {
70 AUDIO_FUNC_LOGE("snprintf_s failed!");
71 return HDF_FAILURE;
72 }
73
74 ret = AudioPnpUpdateInfo(pnpInfo);
75 if (ret != HDF_SUCCESS) {
76 AUDIO_FUNC_LOGE("Update info failed: ret = %{public}d", ret);
77 return HDF_FAILURE;
78 }
79 AUDIO_FUNC_LOGD("Audio uevent:%{public}s", pnpInfo);
80
81 return HDF_SUCCESS;
82 }
83
HdfAudioPnpBind(struct HdfDeviceObject * device)84 static int32_t HdfAudioPnpBind(struct HdfDeviceObject *device)
85 {
86 AUDIO_FUNC_LOGI("enter.");
87 if (device == NULL) {
88 AUDIO_FUNC_LOGE("device is null!");
89 return HDF_ERR_INVALID_PARAM;
90 }
91 AUDIO_FUNC_LOGI("end.");
92
93 return HDF_SUCCESS;
94 }
95
HdfAudioPnpInit(struct HdfDeviceObject * device)96 static int32_t HdfAudioPnpInit(struct HdfDeviceObject *device)
97 {
98 AUDIO_FUNC_LOGI("enter.");
99 if (device == NULL) {
100 AUDIO_FUNC_LOGE("device is null!");
101 return HDF_ERR_INVALID_PARAM;
102 }
103
104 if (!HdfDeviceSetClass(device, DEVICE_CLASS_AUDIO)) {
105 AUDIO_FUNC_LOGE("set audio class failed!");
106 return HDF_FAILURE;
107 }
108
109 g_audioPnpDevice = device;
110 DetectAudioDevice(device);
111 AudioUsbPnpUeventStartThread();
112 AudioHeadsetPnpInputStartThread();
113 AudioHdmiPnpUeventStartThread();
114
115 AUDIO_FUNC_LOGI("end.");
116 return HDF_SUCCESS;
117 }
118
HdfAudioPnpRelease(struct HdfDeviceObject * device)119 static void HdfAudioPnpRelease(struct HdfDeviceObject *device)
120 {
121 AUDIO_FUNC_LOGI("enter.");
122 if (device == NULL) {
123 AUDIO_FUNC_LOGE("device is null!");
124 return;
125 }
126
127 AudioUsbPnpUeventStopThread();
128 AudioHeadsetPnpInputEndThread();
129 AudioHdmiPnpUeventStopThread();
130 device->service = NULL;
131
132 AUDIO_FUNC_LOGI("end.");
133 return;
134 }
135
AudioUhdfUnloadDriver(const char * driverName)136 int32_t AudioUhdfUnloadDriver(const char *driverName)
137 {
138 struct HdfSBuf *sBuf = NULL;
139 struct HdfIoService *service = NULL;
140
141 if (driverName == NULL) {
142 AUDIO_FUNC_LOGE("param is NULL!");
143 return HDF_ERR_INVALID_PARAM;
144 }
145
146 service = HdfIoServiceBind(AUDIO_CONTROL);
147 if (service == NULL || service->dispatcher == NULL || service->dispatcher->Dispatch == NULL) {
148 AUDIO_FUNC_LOGE("Bind service failed!");
149 return HDF_FAILURE;
150 }
151
152 sBuf = HdfSbufObtainDefaultSize();
153 if (sBuf == NULL) {
154 HdfIoServiceRecycle(service);
155 AUDIO_FUNC_LOGE("sbuf data malloc failed!");
156 return HDF_FAILURE;
157 }
158
159 if (!HdfSbufWriteString(sBuf, driverName)) {
160 HdfSbufRecycle(sBuf);
161 HdfIoServiceRecycle(service);
162 AUDIO_FUNC_LOGE("driverName Write Fail!");
163 return HDF_FAILURE;
164 }
165
166 int32_t ret = service->dispatcher->Dispatch(&service->object, AUDIODRV_CTRL_IOCTRL_ELEM_HDMI, sBuf, NULL);
167 if (ret != HDF_SUCCESS) {
168 HdfSbufRecycle(sBuf);
169 HdfIoServiceRecycle(service);
170 AUDIO_FUNC_LOGE("Unload HDMI Driver dispatch error");
171 return HDF_FAILURE;
172 }
173
174 HdfSbufRecycle(sBuf);
175 HdfIoServiceRecycle(service);
176 return HDF_SUCCESS;
177 }
178
AudioUhdfLoadDriver(const char * driverName)179 int32_t AudioUhdfLoadDriver(const char *driverName)
180 {
181 struct HdfIoService *serv = NULL;
182
183 if (driverName == NULL) {
184 AUDIO_FUNC_LOGE("param is NULL!");
185 return HDF_ERR_INVALID_PARAM;
186 }
187
188 serv = HdfIoServiceBind(driverName);
189 if (serv == NULL) {
190 AUDIO_FUNC_LOGE("error HdfIoServiceBind %{public}s", driverName);
191 return HDF_FAILURE;
192 }
193
194 HdfIoServiceRecycle(serv);
195 return HDF_SUCCESS;
196 }
197
198 struct HdfDriverEntry g_hdiAudioPnpEntry = {
199 .moduleVersion = 1,
200 .moduleName = "hdi_audio_pnp_server",
201 .Bind = HdfAudioPnpBind,
202 .Init = HdfAudioPnpInit,
203 .Release = HdfAudioPnpRelease,
204 };
205
206 HDF_INIT(g_hdiAudioPnpEntry);
207