1 /*
2  * Copyright (c) 2022 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 <stdio.h>
17 #include <signal.h>
18 #include <unistd.h>
19 #include "securec.h"
20 #include "hdf_base.h"
21 #include "hdf_io_service_if.h"
22 #include "hdf_service_status.h"
23 #include "servmgr_hdi.h"
24 #include "servstat_listener_hdi.h"
25 #include "audio_events.h"
26 #include "hdf_audio_events.h"
27 
28 #define AUDIO_FUNC_LOGE(fmt, arg...) do { \
29         printf("%s: [%s]: [%d]:[ERROR]:" fmt"\n", __FILE__, __func__, __LINE__, ##arg); \
30     } while (0)
31 
AudioServiceDeviceVal(enum AudioDeviceType deviceType)32 static int32_t AudioServiceDeviceVal(enum AudioDeviceType deviceType)
33 {
34     switch (deviceType) {
35         case HDF_AUDIO_PRIMARY_DEVICE: // primary Service
36             printf("*****************: Primary service valid.\n");
37             return HDF_SUCCESS;
38         case HDF_AUDIO_USB_DEVICE: // Usb Service
39             printf("*****************: USB service valid.\n");
40             return HDF_SUCCESS;
41         case HDF_AUDIO_A2DP_DEVICE: // A2dp Service
42             return HDF_ERR_NOT_SUPPORT;
43         default:
44             return HDF_FAILURE;
45     }
46 }
47 
AudioServiceDeviceInVal(enum AudioDeviceType deviceType)48 static int32_t AudioServiceDeviceInVal(enum AudioDeviceType deviceType)
49 {
50     switch (deviceType) {
51         case HDF_AUDIO_PRIMARY_DEVICE: // primary Service
52             printf("*****************: Primary service Invalid.\n");
53             return HDF_SUCCESS;
54         case HDF_AUDIO_USB_DEVICE: // Usb Service
55             printf("*****************: USB service Invalid.\n");
56             return HDF_SUCCESS;
57         case HDF_AUDIO_A2DP_DEVICE: // A2dp Service
58             return HDF_ERR_NOT_SUPPORT;
59         default:
60             return HDF_FAILURE;
61     }
62 }
63 
AudioServiceMsgParse(struct AudioEvent * svcMsg)64 static int32_t AudioServiceMsgParse(struct AudioEvent *svcMsg)
65 {
66     if (svcMsg == NULL) {
67         return HDF_FAILURE;
68     }
69 
70     switch (svcMsg->eventType) {
71         case HDF_AUDIO_EVENT_UNKOWN:
72             return HDF_FAILURE;
73         case HDF_AUDIO_SERVICE_VALID:
74             return AudioServiceDeviceVal(svcMsg->deviceType);
75         case HDF_AUDIO_SERVICE_INVALID:
76             return AudioServiceDeviceInVal(svcMsg->deviceType);
77         default:
78             return HDF_FAILURE;
79     }
80 }
81 
AudioGetServiceStatus(const struct ServiceStatus * svcStatus)82 static int AudioGetServiceStatus(const struct ServiceStatus *svcStatus)
83 {
84     if (svcStatus == NULL) {
85         return HDF_FAILURE;
86     }
87 
88     struct AudioEvent serviceMsg = {
89         .eventType = HDF_AUDIO_EVENT_UNKOWN,
90         .deviceType = HDF_AUDIO_DEVICE_UNKOWN,
91     };
92     char strTemp[AUDIO_PNP_MSG_LEN_MAX] = {0};
93     if (memcpy_s(strTemp, AUDIO_PNP_MSG_LEN_MAX, (char *)svcStatus->info, strlen((char *)svcStatus->info))) {
94         return HDF_FAILURE;
95     }
96     if ((AudioPnpMsgReadValue(strTemp, "EVENT_SERVICE_TYPE", &(serviceMsg.eventType)) != HDF_SUCCESS) ||
97         (AudioPnpMsgReadValue(strTemp, "DEVICE_TYPE", &(serviceMsg.deviceType)) != HDF_SUCCESS)) {
98         return HDF_FAILURE;
99     }
100     if (AudioServiceMsgParse(&serviceMsg) != HDF_SUCCESS) {
101         return HDF_FAILURE;
102     }
103 
104     return HDF_SUCCESS;
105 }
106 
AudioLoadDeviceSucc(enum AudioDeviceType deviceType)107 static int32_t AudioLoadDeviceSucc(enum AudioDeviceType deviceType)
108 {
109     switch (deviceType) {
110         case HDF_AUDIO_PRIMARY_DEVICE: // primary load
111             printf("*****************: Primary load success.\n");
112             return HDF_SUCCESS;
113         case HDF_AUDIO_USB_DEVICE: // Usb load
114             printf("*****************: USB load success.\n");
115             return HDF_SUCCESS;
116         case HDF_AUDIO_A2DP_DEVICE: // A2dp load
117             return HDF_ERR_NOT_SUPPORT;
118         default:
119             return HDF_FAILURE;
120     }
121 }
122 
AudioLoadDeviceFail(enum AudioDeviceType deviceType)123 static int32_t AudioLoadDeviceFail(enum AudioDeviceType deviceType)
124 {
125     switch (deviceType) {
126         case HDF_AUDIO_PRIMARY_DEVICE: // primary load
127             printf("*****************: Primary load fail.\n");
128             return HDF_SUCCESS;
129         case HDF_AUDIO_USB_DEVICE: // Usb load
130             printf("*****************: USB load fail.\n");
131             return HDF_SUCCESS;
132         case HDF_AUDIO_A2DP_DEVICE: // A2dp load
133             return HDF_ERR_NOT_SUPPORT;
134         default:
135             return HDF_FAILURE;
136     }
137 }
138 
AudioUnLoadDevice(enum AudioDeviceType deviceType)139 static int32_t AudioUnLoadDevice(enum AudioDeviceType deviceType)
140 {
141     switch (deviceType) {
142         case HDF_AUDIO_PRIMARY_DEVICE: // primary load
143             printf("*****************: Primary unload.\n");
144             return HDF_SUCCESS;
145         case HDF_AUDIO_USB_DEVICE: // Usb load
146             printf("*****************: USB unload.\n");
147             return HDF_SUCCESS;
148         case HDF_AUDIO_A2DP_DEVICE: // A2dp load
149             return HDF_ERR_NOT_SUPPORT;
150         default:
151             return HDF_FAILURE;
152     }
153 }
154 
AudioLoadMsgParse(struct AudioEvent * loadMsg)155 static int32_t AudioLoadMsgParse(struct AudioEvent *loadMsg)
156 {
157     if (loadMsg == NULL) {
158         return HDF_FAILURE;
159     }
160 
161     switch (loadMsg->eventType) {
162         case HDF_AUDIO_LOAD_SUCCESS:
163             return AudioLoadDeviceSucc(loadMsg->deviceType);
164         case HDF_AUDIO_LOAD_FAILURE:
165             return AudioLoadDeviceFail(loadMsg->deviceType);
166         case HDF_AUDIO_UNLOAD:
167             return AudioUnLoadDevice(loadMsg->deviceType);
168         default:
169             return HDF_FAILURE;
170     }
171 }
172 
AudioGetLoadStatus(struct ServiceStatus * svcStatus)173 static int AudioGetLoadStatus(struct ServiceStatus *svcStatus)
174 {
175     if (svcStatus == NULL) {
176         return HDF_FAILURE;
177     }
178 
179     struct AudioEvent loadMsg = {
180         .eventType = HDF_AUDIO_EVENT_UNKOWN,
181         .deviceType = HDF_AUDIO_DEVICE_UNKOWN,
182     };
183     char strTemp[AUDIO_PNP_MSG_LEN_MAX] = {0};
184     if (memcpy_s(strTemp, AUDIO_PNP_MSG_LEN_MAX, (char *)svcStatus->info, strlen((char *)svcStatus->info))) {
185         return HDF_FAILURE;
186     }
187     if ((AudioPnpMsgReadValue(strTemp, "EVENT_LOAD_TYPE", &(loadMsg.eventType)) != HDF_SUCCESS) ||
188         (AudioPnpMsgReadValue(strTemp, "DEVICE_TYPE", &(loadMsg.deviceType)) != HDF_SUCCESS)) {
189         return HDF_FAILURE;
190     }
191     if (AudioLoadMsgParse(&loadMsg) != HDF_SUCCESS) {
192         return HDF_FAILURE;
193     }
194 
195     return HDF_SUCCESS;
196 }
197 
AudioPnpDeviceAdd(enum AudioDeviceType deviceType)198 static int32_t AudioPnpDeviceAdd(enum AudioDeviceType deviceType)
199 {
200     switch (deviceType) {
201         case HDF_AUDIO_USB_HEADPHONE: // USB Audio Add
202         case HDF_AUDIO_USBA_HEADPHONE:
203             printf("*****************: USB Audio earphone microphone add.\n");
204             return HDF_SUCCESS;
205         case HDF_AUDIO_USB_HEADSET:
206         case HDF_AUDIO_USBA_HEADSET:
207             printf("*****************: USB Audio earphone mic&speaker add.\n");
208             return HDF_SUCCESS;
209         case HDF_AUDIO_A2DP_DEVICE: // A2dp Add
210             return HDF_ERR_NOT_SUPPORT;
211         default:
212             return HDF_FAILURE;
213     }
214 }
215 
AudioPnpDeviceRemove(enum AudioDeviceType deviceType)216 static int32_t AudioPnpDeviceRemove(enum AudioDeviceType deviceType)
217 {
218     switch (deviceType) {
219         case HDF_AUDIO_USB_HEADPHONE: // USB Audio Remove
220         case HDF_AUDIO_USBA_HEADPHONE:
221             printf("*****************: USB Audio earphone microphone remove.\n");
222             return HDF_SUCCESS;
223         case HDF_AUDIO_USB_HEADSET:
224         case HDF_AUDIO_USBA_HEADSET:
225             printf("*****************: USB Audio earphone mic&speaker remove.\n");
226             return HDF_SUCCESS;
227         case HDF_AUDIO_A2DP_DEVICE: // A2dp Remove
228             return HDF_ERR_NOT_SUPPORT;
229         default:
230             return HDF_FAILURE;
231     }
232 }
233 
AudioPnpMsgParse(struct AudioEvent * pnpMsg)234 static int32_t AudioPnpMsgParse(struct AudioEvent *pnpMsg)
235 {
236     if (pnpMsg == NULL) {
237         return HDF_FAILURE;
238     }
239 
240     switch (pnpMsg->eventType) {
241         case HDF_AUDIO_EVENT_UNKOWN:
242             return HDF_FAILURE;
243         case HDF_AUDIO_DEVICE_ADD:
244             return AudioPnpDeviceAdd(pnpMsg->deviceType);
245         case HDF_AUDIO_DEVICE_REMOVE:
246             return AudioPnpDeviceRemove(pnpMsg->deviceType);
247         default:
248             return HDF_FAILURE;
249     }
250 }
251 
AudioGetUsbPnpStatus(struct ServiceStatus * svcStatus)252 static int AudioGetUsbPnpStatus(struct ServiceStatus *svcStatus)
253 {
254     if (svcStatus == NULL) {
255         return HDF_FAILURE;
256     }
257 
258     struct AudioEvent pnpMsg = {
259         .eventType = HDF_AUDIO_EVENT_UNKOWN,
260         .deviceType = HDF_AUDIO_DEVICE_UNKOWN,
261     };
262     char strTemp[AUDIO_PNP_MSG_LEN_MAX] = {0};
263     if (memcpy_s(strTemp, AUDIO_PNP_MSG_LEN_MAX, (char *)svcStatus->info, strlen((char *)svcStatus->info))) {
264         return HDF_FAILURE;
265     }
266     if ((AudioPnpMsgReadValue(strTemp, "EVENT_TYPE", &(pnpMsg.eventType)) != HDF_SUCCESS) ||
267         (AudioPnpMsgReadValue(strTemp, "DEVICE_TYPE", &(pnpMsg.deviceType)) != HDF_SUCCESS)) {
268         return HDF_FAILURE;
269     }
270     if (AudioPnpMsgParse(&pnpMsg) != HDF_SUCCESS) {
271         return HDF_FAILURE;
272     }
273 
274     return HDF_SUCCESS;
275 }
276 
AudioUsbPnpOnSvcStatusReceived(struct ServiceStatusListener * listener,struct ServiceStatus * svcStatus)277 static void AudioUsbPnpOnSvcStatusReceived(struct ServiceStatusListener *listener, struct ServiceStatus *svcStatus)
278 {
279     if (listener == NULL || svcStatus == NULL) {
280         AUDIO_FUNC_LOGE("listener or svcStatus is NULL!");
281         return;
282     }
283 
284     printf("\n===============================================================================\n"
285            "@@@@@ serviceName: %s\n"
286            "@@@@@ deviceClass: %d\n"
287            "@@@@@ status     : %d\n"
288            "@@@@@ info       : %s"
289            "\n===============================================================================\n",
290         svcStatus->serviceName, svcStatus->deviceClass, svcStatus->status, svcStatus->info);
291 
292     (void)AudioGetUsbPnpStatus(svcStatus);
293     (void)AudioGetLoadStatus(svcStatus);
294     (void)AudioGetServiceStatus(svcStatus);
295 }
296 
297 static struct HDIServiceManager *g_servmgr = NULL;
298 static struct ServiceStatusListener *g_listener = NULL;
299 static bool g_listenerState = false;
300 
StopListenerBySig(int32_t sig)301 static void StopListenerBySig(int32_t sig)
302 {
303     printf("%s: Signal = %d\n", __func__, sig);
304     if (g_servmgr == NULL || g_listener == NULL) {
305         AUDIO_FUNC_LOGE("g_servmgr or g_listener is null!\n");
306         return;
307     }
308 
309     int32_t ret = g_servmgr->UnregisterServiceStatusListener(g_servmgr, g_listener);
310     if (ret != HDF_SUCCESS) {
311         AUDIO_FUNC_LOGE("UnregisterServiceStatusListener fail! ret = %d.\n", ret);
312         return;
313     }
314     HdiServiceStatusListenerFree(g_listener);
315     HDIServiceManagerRelease(g_servmgr);
316     g_listenerState = false;
317     g_servmgr = NULL;
318     return;
319 }
320 
main(void)321 int main(void)
322 {
323     printf("%s: system audio listener start \n", __func__);
324     g_servmgr = HDIServiceManagerGet();
325     if (g_servmgr == NULL) {
326         AUDIO_FUNC_LOGE("HDIServiceManagerGet failed.\n");
327         return HDF_FAILURE;
328     }
329     g_listener = HdiServiceStatusListenerNewInstance();
330     if (g_listener == NULL) {
331         AUDIO_FUNC_LOGE("HdiServiceStatusListenerNewInstance failed.\n");
332         HDIServiceManagerRelease(g_servmgr);
333         g_servmgr = NULL;
334         return HDF_FAILURE;
335     }
336     g_listener->callback = AudioUsbPnpOnSvcStatusReceived;
337     int32_t status = g_servmgr->RegisterServiceStatusListener(g_servmgr, g_listener, DEVICE_CLASS_AUDIO);
338     if (status != HDF_SUCCESS) {
339         AUDIO_FUNC_LOGE("RegisterServiceStatusListener fail! ret = %d.\n", status);
340         HDIServiceManagerRelease(g_servmgr);
341         g_servmgr = NULL;
342         HdiServiceStatusListenerFree(g_listener);
343         return HDF_FAILURE;
344     }
345     g_listenerState = true;
346     (void)signal(SIGINT, StopListenerBySig);
347     (void)signal(SIGTERM, StopListenerBySig);
348     while (g_listenerState) {
349         sleep(1); // Wait for 1 second
350     }
351 
352     return HDF_SUCCESS;
353 }
354