blob: 2b9988aacfd714bd6fbc85c69f96aa474e8c4804 [file] [log] [blame]
liubin281ac462023-07-19 14:22:54 +08001/**
2 * \file mbtk_audio.c
3 * \brief A Documented file.
4 *
5 * Detailed description
6 * \Author: js.wang <js.wang@mobiletek.cn>
7 * \Version: 1.0.0
8 * \Date: 2022-03-31
9 */
10#include <fcntl.h>
11#include <stdint.h>
12#include <limits.h>
13#include <termios.h>
14#include <stdarg.h>
15#include <dirent.h>
16#include <sys/stat.h>
17#include <sys/statfs.h>
18#include <sys/types.h>
19#include "mbtk_log.h"
20#include "mbtk_type.h"
21#include <libubox/blobmsg_json.h>
22#include "libubus.h"
23#include "mbtk_audio.h"
24
25/******************************************************************************\
26 * Macros / Defines
27\******************************************************************************/
28
29#ifndef UNUSEDPARAM
30#define UNUSEDPARAM(a) (void)(a)
31#endif
32
33#define AUDIO_UBUS_REQUEST_NAME "audio_if"
34#define mbtk_dtmf_UBUS_NAME "proslic_uBus" //Used by wake lock
35#define DTMFCODEID "dtmfcode"
36#define DTMFCODE_NOTIFICATION_NAME "audioif.dtmfcode"
37#define AUDIO_UBUS_VOLUME_SET "volume_set"
38#define AUDIO_UBUS_VOLUME_GET "volume_status"
39#define AUDIO_UBUS_MODE_SET "audio_mode_set"
LUOJian5bbddc22023-09-04 18:49:11 +080040#define AUDIO_UBUS_PATH_ENABLE "audio_path_enable"
41#define AUDIO_UBUS_SWITCH_PCM "switch_pcm"
liubin281ac462023-07-19 14:22:54 +080042#define AUDIO_UBUS_DSP_SET "config_dspgain"
43#define AUDIO_UBUS_LOOPBACK_EN "loopback_enable"
44#define AUDIO_UBUS_LOOPBACK_DIS "loopback_disable"
b.liu79884c22023-09-21 15:10:16 +080045#define AUDIO_UBUS_AUDIO_GAIN_SET "audio_gain_set"
b.liu0e1a3792024-02-26 17:10:31 +080046#define AUDIO_UBUS_AUDIO_REG_SET "audio_reg_set"
47
liubin281ac462023-07-19 14:22:54 +080048
49// #define DEBUG 1
50
51#ifdef DEBUG
52 #define mbtk_audio_log(...) mbtk_audio_log(__VA_ARGS__)
53#else
54 #define mbtk_audio_log(...)
55#endif
56
57typedef enum {
58 PARAM_INT_POLICY_0,
59 PARAM_INT_POLICY_1,
60 PARAM_INT_POLICY_2,
61 PARAM_INT_POLICY_3,
62 PARAM_INT_POLICY_MAX,
63} PARAM_INT_POLICY;
zhangzhd04babd2023-10-24 16:55:57 +080064
65#define FAILURE -1
66#define ID_RIFF 0x46464952
67#define ID_WAVE 0x45564157
68#define ID_FMT 0x20746d66
69#define ID_DATA 0x61746164
70#define FORMAT_PCM 1
71
72struct wav_header {
73 uint32_t riff_id;
74 uint32_t riff_sz;
75 uint32_t riff_fmt;
76 uint32_t fmt_id;
77 uint32_t fmt_sz;
78 uint16_t audio_format;
79 uint16_t num_channels;
80 uint32_t sample_rate;
81 uint32_t byte_rate; /* sample_rate * num_channels * bps / 8 */
82 uint16_t block_align; /* num_channels * bps / 8 */
83 uint16_t bits_per_sample;
84 uint32_t data_id;
85 uint32_t data_sz;
86};
87
liubin281ac462023-07-19 14:22:54 +080088const struct blobmsg_policy int_policy[] ={
89 [PARAM_INT_POLICY_0] = {
90 .name = "param0",
91 .type = BLOBMSG_TYPE_INT32,
92 },
93};
94
95const struct blobmsg_policy dtmf_code_policy[] = {
96 [0] = {
97 .name = DTMFCODEID,
98 .type = BLOBMSG_TYPE_INT32,
99 },
100};
101
102static void mbtk_dtmf_add_subscriber_AudioIf(struct uloop_timeout *timeout);
103static struct uloop_timeout mbtk_dtmf_add_subscribe_timeout_AudioIf =
104{
105 .cb = mbtk_dtmf_add_subscriber_AudioIf,
106};
107
108static struct blob_buf audio_cm_b;
109pthread_mutex_t mbtk_dtmf_mutex;
110int mbtk_dtmf_PMConstraintWorks;
111//For UBUS listening to RILD & audio_if
112struct mbtk_audio_ubus_db_t
113{
114 pthread_t dtmf_pthread;
115 mbtk_dtmf_cb dtmf_cb;
116 mbtk_volume_cb audio_volume_get_cb;
117 int work_state;
118 struct ubus_context *ctx;
119
120 /* Audio_If */
121 struct ubus_subscriber audioif_event;
122 uint32_t audioif_subscriber_id;
123 uint32_t audioif_request_id;
124};
125
126static struct mbtk_audio_ubus_db_t *mbtk_audio_ubus_db = NULL;
127
b.liua896b3d2024-02-06 17:15:37 +0800128#ifdef MBTK_YX_SUPPORT
129static struct ubus_context *audio_ctx = NULL;
130static uint32_t ubus_id_audio_if = 0;
131#endif
liubin281ac462023-07-19 14:22:54 +0800132
133static int record_fd = 0;
134
135#define AUDIO_FILE_DIR "/data"
136#define MBTK_AUD_DEMO_WAV "/data/demo.wav"
137
zhangzhd04babd2023-10-24 16:55:57 +0800138int MBTK_wav_pcm16Le_set(int fd)
139{
140 struct wav_header hdr;
141
142 if (fd <= 0)
143 return -1;
144
145 memset(&hdr, 0, sizeof(struct wav_header));
146
147 hdr.riff_id = ID_RIFF;
148 hdr.riff_fmt = ID_WAVE;
149 hdr.fmt_id = ID_FMT;
150 hdr.fmt_sz = 16;
151 hdr.audio_format = FORMAT_PCM;
152 hdr.num_channels = 1;
153 hdr.sample_rate = 8000;
154 hdr.bits_per_sample = 16;
155 hdr.byte_rate = (8000 * 1 * hdr.bits_per_sample) / 8;
156 hdr.block_align = (hdr.bits_per_sample * 1) / 8;
157 hdr.data_id = ID_DATA;
158 hdr.data_sz = 0;
159
160 hdr.riff_sz = hdr.data_sz + 44 - 8;
161 if (write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
162 return -1;
163 }
164
165 return 0;
166}
167
liubin281ac462023-07-19 14:22:54 +0800168int create_audio_dir(const char *dirname)
169{
170 DIR *p_dir;
171 int res = -1;
172
173 if(NULL == (p_dir = opendir((const char *)dirname)))
174 {
175 if(mkdir(dirname, 0777) == 0)
176 {
177 res = 0;
178 }
179 else
180 {
181 fprintf(stderr, "create audio dir error \n");
182 res = -1;
183 }
184 }
185 else
186 {
187 closedir(p_dir);
188 res = 0;
189 }
190 return res;
191}
192int mbtk_at_play(const char *args)
193{
194 int fd = 0;
195 int play_hdl = 0;
196 char databuf[1024];
197 int size;
198
199 LOGI("%s %d", __FUNCTION__, __LINE__);
200 // play_hdl = Ql_AudPlayer_Open(NULL, NULL);
201 play_hdl = mbtk_audio_open(0, 1, 8000, NULL);
202 if(0 == play_hdl)
203 printf("Ql_AudPlayer_Open fail\n");
204
205 fd = open(MBTK_AUD_DEMO_WAV, O_RDWR);
206 if (fd <= 0)
207 {
208 printf("file open error\n");
209 goto err;
210 }
211 memset(databuf, 0, sizeof(databuf));
212 while(0 < (size = read(fd, databuf, sizeof(databuf))))
213 {
214 if(-1 == mbtk_audio_play_stream(play_hdl, databuf, size))
215 break;
216 }
217 mbtk_audio_log("aplay Stream end \n");
218
219err:
220 if(fd > 0)
221 close(fd);
222 mbtk_audio_close(play_hdl);
223
224 return 0;
225}
226
227void record_cb_func(int cb_result, char* databuf, unsigned int len)
228{
229 int rc;
230
231 if(NULL != databuf && len > 0 && record_fd > 0)
232 {
233 //for debug:save into file
234 rc = write(record_fd, databuf, len);
235 if (rc < 0) {
236 printf("%s: error writing to file!\n", __FUNCTION__);
237 } else if (rc < len) {
238 printf("%s: wrote less the buffer size!\n", __FUNCTION__);
239 }
240 }
241}
242
243int mbtk_at_rec(const char *args)
244{
245 LOGI("%s %d", __FUNCTION__, __LINE__);
246 //hdl = Ql_AudRecorder_Open(NULL, record_cb_func);
247 void *record_hdl = mbtk_audio_open(1, 1, 8000, NULL);
248 if (record_hdl == NULL)
249 {
250 printf("AudRecorder open error\n");
251 return -1;
252 }
253
254 create_audio_dir(AUDIO_FILE_DIR);
255 record_fd = open(MBTK_AUD_DEMO_WAV, O_RDWR|O_CREAT|O_TRUNC, 0644);
256 if (record_fd <= 0)
257 {
258 printf("file open error\n");
259 goto err;
260 }
261
zhangzhd04babd2023-10-24 16:55:57 +0800262 if(0 == MBTK_wav_pcm16Le_set(record_fd))// 设置格式,否则音频播放不了
liubin281ac462023-07-19 14:22:54 +0800263 {
zhangzhd04babd2023-10-24 16:55:57 +0800264 if( 0 != mbtk_audio_record(record_hdl, record_cb_func, NULL))
265 {
266 printf("file write error\n");
267 close(record_fd);
268 record_fd = 0;
269 }
270 }
271 else
272 {
273 printf("arec set file header error\n");
liubin281ac462023-07-19 14:22:54 +0800274 close(record_fd);
275 record_fd = 0;
276 }
zhangzhd04babd2023-10-24 16:55:57 +0800277
278 sleep(10);// 录音 10S
liubin281ac462023-07-19 14:22:54 +0800279err:
zhangzhd04babd2023-10-24 16:55:57 +0800280 mbtk_audio_close(record_hdl);// 关闭录音
liubin281ac462023-07-19 14:22:54 +0800281 record_hdl = NULL;
282 if(record_fd > 0)
283 {
284 close(record_fd);
285 record_fd = 0;
286 }
287
288 return 0;
289}
290
291static void mbtk_ubus_complete_cb(struct ubus_request *req, int rc)
292{
293 if(NULL == mbtk_audio_ubus_db)
294 {
295 printf("mbtk_dtmf_ubus not init!\n");
296 return;
297 }
298 if (req)
299 {
300 free(req);
301 req = NULL;
302 }
303 mbtk_audio_log("%s do nothing, rc=%d\n", __FUNCTION__, rc);
304 LOGI("%s do nothing, rc=%d\n", __FUNCTION__, rc);
305 if(mbtk_audio_ubus_db->work_state)
306 mbtk_audio_ubus_db->work_state--;
307}
308/**
309 * @brief mbtk_audio_mode_set
310 *
311 * @details detailed description
312 *
313 * @param param
314 * "param0": UINT32
315 * typedef enum {
316 * AUDIO_MODE_INVALID = -2,
317 * AUDIO_MODE_CURRENT = -1,
318 * AUDIO_MODE_NORMAL = 0,
319 * AUDIO_MODE_RINGTONE = 1,
320 * AUDIO_MODE_IN_CALL = 2,
321 * AUDIO_MODE_IN_COMMUNICATION=3,
322 * AUDIO_MODE_IN_VT_CALL= 4,
323 * AUDIO_MODE_CNT,
324 * AUDIO_MODE_MAX = AUDIO_MODE_CNT-1,
325 * } audio_mode_
326 * @return return type
327 */
LUOJian5bbddc22023-09-04 18:49:11 +0800328void mbtk_audio_mode_set(int mode)
liubin281ac462023-07-19 14:22:54 +0800329{
330 int rc = 0;
b.liuc7ffd092024-01-03 15:23:07 +0800331#ifndef MBTK_YX_SUPPORT
liubin281ac462023-07-19 14:22:54 +0800332 if(NULL == mbtk_audio_ubus_db)
333 {
334 printf("mbtk_dtmf_ubus not init!\n");
335 return;
336 }
liubin281ac462023-07-19 14:22:54 +0800337 blob_buf_init(&audio_cm_b, 0);
338 blobmsg_add_u32(&audio_cm_b, "param0", mode);
b.liu1c1c7212023-12-22 16:35:27 +0800339 if ((rc = ubus_invoke(mbtk_audio_ubus_db->ctx,
liubin281ac462023-07-19 14:22:54 +0800340 mbtk_audio_ubus_db->audioif_request_id,
341 AUDIO_UBUS_MODE_SET,
b.liuc7ffd092024-01-03 15:23:07 +0800342 audio_cm_b.head, NULL, NULL, 2 * 1000)) != UBUS_STATUS_OK)
liubin281ac462023-07-19 14:22:54 +0800343 {
liubin281ac462023-07-19 14:22:54 +0800344 printf("%s, ubus_invoke_async %s failed %s\n", __FUNCTION__, AUDIO_UBUS_MODE_SET, ubus_strerror(rc));
345 }
346 else
347 {
348 printf("%s: ubus_invoke_async success\n", __FUNCTION__);
liubin281ac462023-07-19 14:22:54 +0800349 }
b.liuc7ffd092024-01-03 15:23:07 +0800350#else
351 static struct ubus_context *ctx;
352 ctx = ubus_connect(NULL);
353 if (!ctx) {
354 printf("Failed to connect to ubus\n");
355 return;
356 }
357
358 static struct blob_buf b;
359 uint32_t id;
360 int ret;
361 ret = ubus_lookup_id(ctx, AUDIO_UBUS_REQUEST_NAME, &id);
362 if (ret) {
363 printf("ubus_lookup_id() fail.\n");
364 return ret;
365 }
366
367 blob_buf_init(&b, 0);
368 blobmsg_add_u32(&b, "param0", mode);
369 if((ret = ubus_invoke(ctx, id, AUDIO_UBUS_MODE_SET, b.head, NULL, NULL, 0)) != UBUS_STATUS_OK) {
370 printf("ubus_invoke fail:%d.\n", ret);
371 } else {
372 printf("ubus_invoke success.\n");
373 }
374#endif
liubin281ac462023-07-19 14:22:54 +0800375}
LUOJian5bbddc22023-09-04 18:49:11 +0800376
377
378void mbtk_audio_path_enable(int mode)
379{
380 int rc = 0;
b.liuc7ffd092024-01-03 15:23:07 +0800381#ifndef MBTK_YX_SUPPORT
LUOJian5bbddc22023-09-04 18:49:11 +0800382 if(NULL == mbtk_audio_ubus_db)
383 {
384 printf("mbtk_dtmf_ubus not init!\n");
385 return;
386 }
b.liu1c1c7212023-12-22 16:35:27 +0800387
LUOJian5bbddc22023-09-04 18:49:11 +0800388 blob_buf_init(&audio_cm_b, 0);
389 blobmsg_add_u32(&audio_cm_b, "param0", mode);
b.liu1c1c7212023-12-22 16:35:27 +0800390 if ((rc = ubus_invoke(mbtk_audio_ubus_db->ctx,
LUOJian5bbddc22023-09-04 18:49:11 +0800391 mbtk_audio_ubus_db->audioif_request_id,
392 AUDIO_UBUS_PATH_ENABLE,
b.liu1c1c7212023-12-22 16:35:27 +0800393 audio_cm_b.head, NULL, NULL, 0)) != UBUS_STATUS_OK)
LUOJian5bbddc22023-09-04 18:49:11 +0800394 {
LUOJian5bbddc22023-09-04 18:49:11 +0800395 printf("%s, ubus_invoke_async %s failed %s\n", __FUNCTION__, AUDIO_UBUS_PATH_ENABLE, ubus_strerror(rc));
396 }
397 else
398 {
399 printf("%s: ubus_invoke_async success\n", __FUNCTION__);
LUOJian5bbddc22023-09-04 18:49:11 +0800400 }
b.liuc7ffd092024-01-03 15:23:07 +0800401#else
402 static struct ubus_context *ctx;
403 ctx = ubus_connect(NULL);
404 if (!ctx) {
405 printf("Failed to connect to ubus\n");
406 return;
407 }
408
409 static struct blob_buf b;
410 uint32_t id;
411 int ret;
412 ret = ubus_lookup_id(ctx, AUDIO_UBUS_REQUEST_NAME, &id);
413 if (ret) {
414 printf("ubus_lookup_id() fail.\n");
415 return ret;
416 }
417
418 blob_buf_init(&b, 0);
419 blobmsg_add_u32(&b, "param0", mode);
420 if((ret = ubus_invoke(ctx, id, AUDIO_UBUS_PATH_ENABLE, b.head, NULL, NULL, 0)) != UBUS_STATUS_OK) {
421 printf("ubus_invoke fail:%d.\n", ret);
422 } else {
423 printf("ubus_invoke success.\n");
424 }
425
426#endif
LUOJian5bbddc22023-09-04 18:49:11 +0800427}
428
429
430/**
431 * @brief mbtk_audio_switch_pcm
432 *
433 * @details detailed description
434 *
435 * @param param
436 * "param0":UINT32 mode
437 * 0: Turn off MSA PCM
438 * 1: Turn on MSA PCM as NB PCM(i.e. 8KHz sample rate)
439 * 2: Turn on MSA PCM as WB PCM(i.e. 16KHz sample rate)
440 * @return return type
441 */
442void mbtk_audio_switch_pcm(int mode)
443{
444 int rc = 0;
b.liuc7ffd092024-01-03 15:23:07 +0800445#ifndef MBTK_YX_SUPPORT
LUOJian5bbddc22023-09-04 18:49:11 +0800446 if(NULL == mbtk_audio_ubus_db)
447 {
448 printf("mbtk_dtmf_ubus not init!\n");
449 return;
450 }
b.liuc7ffd092024-01-03 15:23:07 +0800451
LUOJian5bbddc22023-09-04 18:49:11 +0800452 blob_buf_init(&audio_cm_b, 0);
453 blobmsg_add_u32(&audio_cm_b, "param0", mode);
b.liuc7ffd092024-01-03 15:23:07 +0800454 if ((rc = ubus_invoke(mbtk_audio_ubus_db->ctx,
LUOJian5bbddc22023-09-04 18:49:11 +0800455 mbtk_audio_ubus_db->audioif_request_id,
456 AUDIO_UBUS_SWITCH_PCM,
b.liuc7ffd092024-01-03 15:23:07 +0800457 audio_cm_b.head, NULL, NULL, 0/*2 * 1000*/)) != UBUS_STATUS_OK)
LUOJian5bbddc22023-09-04 18:49:11 +0800458 {
b.liuc7ffd092024-01-03 15:23:07 +0800459 printf("%s, ubus_invoke %s failed %s\n", __FUNCTION__, AUDIO_UBUS_SWITCH_PCM, ubus_strerror(rc));
LUOJian5bbddc22023-09-04 18:49:11 +0800460 }
461 else
462 {
b.liuc7ffd092024-01-03 15:23:07 +0800463 printf("%s: ubus_invoke success\n", __FUNCTION__);
LUOJian5bbddc22023-09-04 18:49:11 +0800464 }
b.liuc7ffd092024-01-03 15:23:07 +0800465#else
466
b.liuc7ffd092024-01-03 15:23:07 +0800467 static struct blob_buf b;
b.liuc7ffd092024-01-03 15:23:07 +0800468 int ret;
b.liua896b3d2024-02-06 17:15:37 +0800469 if(audio_ctx == NULL || ubus_id_audio_if == 0) {
470 return;
471 }
b.liuc7ffd092024-01-03 15:23:07 +0800472
473 blob_buf_init(&b, 0);
474 blobmsg_add_u32(&b, "param0", mode);
b.liua896b3d2024-02-06 17:15:37 +0800475 if((ret = ubus_invoke(audio_ctx, ubus_id_audio_if, AUDIO_UBUS_SWITCH_PCM, b.head, NULL, NULL, 2000)) != UBUS_STATUS_OK) {
b.liuc7ffd092024-01-03 15:23:07 +0800476 printf("ubus_invoke fail:%d.\n", ret);
477 } else {
478 printf("ubus_invoke success.\n");
479 }
480
481#endif
LUOJian5bbddc22023-09-04 18:49:11 +0800482}
483
liubin281ac462023-07-19 14:22:54 +0800484int mbtk_audio_dsp_set(int type, int gain)
485{
486 LOGE("1type:%d, gain:%d\n", type, gain);
487 int rc = 0;
488 struct ubus_request *req = NULL;
489
490 if(NULL == mbtk_audio_ubus_db)
491 {
492 LOGE("mbtk_dtmf_ubus not init!\n");
493 return -1;
494 }
495 req = (struct ubus_request *)malloc(sizeof(struct ubus_request));
496 if (req == NULL)
497 {
498 LOGE("leave %s: lack of memory\n", __FUNCTION__);
499 return -1;
500 }
501
502 memset(req, 0, sizeof(struct ubus_request));
503 blob_buf_init(&audio_cm_b, 0);
504 blobmsg_add_u32(&audio_cm_b, "type", type);
505 blobmsg_add_u32(&audio_cm_b, "gain", gain);
506 if ((rc = ubus_invoke_async(mbtk_audio_ubus_db->ctx,
507 mbtk_audio_ubus_db->audioif_request_id,
508 AUDIO_UBUS_DSP_SET,
509 audio_cm_b.head, req)) != UBUS_STATUS_OK)
510 {
511 free(req);
512 LOGE("%s, ubus_invoke_async %s failed %s\n", __FUNCTION__, AUDIO_UBUS_DSP_SET, ubus_strerror(rc));
513 return -1;
514 }
515 else
516 {
517 LOGE("%s: ubus_invoke_async success\n", __FUNCTION__);
518 mbtk_audio_ubus_db->work_state++;
519 req->complete_cb = mbtk_ubus_complete_cb;
520 ubus_complete_request_async(mbtk_audio_ubus_db->ctx, req);
521 }
522 return 0;
523}
524/**
525 * @brief mbtk_audio_loopback_start
526 *
527 * @details detailed description
528 *
529 * @param param
530 * device: UINT32
531 * 0: earpiece
532 * 1: speaker
533 * 2: headset
534 * @return return type
535 */
536static void mbtk_audio_loopback_start(int device)
537{
538 int rc = 0;
539 struct ubus_request *req = NULL;
540
541 if(NULL == mbtk_audio_ubus_db)
542 {
543 LOGI("mbtk_dtmf_ubus not init!\n");
544 return;
545 }
546 req = (struct ubus_request *)malloc(sizeof(struct ubus_request));
547 if (req == NULL)
548 {
549 LOGI("leave %s: lack of memory\n", __FUNCTION__);
550 return;
551 }
552 memset(req, 0, sizeof(struct ubus_request));
553 blob_buf_init(&audio_cm_b, 0);
554 blobmsg_add_u32(&audio_cm_b, "param0", device);
555 if ((rc = ubus_invoke_async(mbtk_audio_ubus_db->ctx,
556 mbtk_audio_ubus_db->audioif_request_id,
557 AUDIO_UBUS_LOOPBACK_EN,
558 audio_cm_b.head, req)) != UBUS_STATUS_OK)
559 {
560 free(req);
561 LOGI("%s, ubus_invoke_async volume get failed %s\n", __FUNCTION__, ubus_strerror(rc));
562 }
563 else
564 {
565 LOGI("%s: ubus_invoke_async success\n", __FUNCTION__);
566 req->complete_cb = mbtk_ubus_complete_cb;
567 ubus_complete_request_async(mbtk_audio_ubus_db->ctx, req);
568 }
569}
570
571static void mbtk_audio_loopback_stop(void)
572{
573 int rc = 0;
574
575 if(NULL == mbtk_audio_ubus_db)
576 {
577 printf("mbtk_dtmf_ubus not init!\n");
578 return;
579 }
580 blob_buf_init(&audio_cm_b, 0);
581
582 if ((rc = ubus_invoke(mbtk_audio_ubus_db->ctx,
583 mbtk_audio_ubus_db->audioif_request_id,
584 AUDIO_UBUS_LOOPBACK_DIS,
585 audio_cm_b.head, NULL, 0, 0)) != UBUS_STATUS_OK)
586 {
587 LOGI("%s, ubus_invoke volume get failed %s\n", __FUNCTION__, ubus_strerror(rc));
588 }
589 else
590 {
591 LOGI("%s: ubus_invoke success\n", __FUNCTION__);
592 }
593}
594
595int mbtk_at_loopback(int type)
596{
597 static mbtk_audio_client_handle_type audio_handle = 0;
598 int ret = 0;
599
600 LOGI("%s %d:%d", __FUNCTION__, __LINE__, type);
601 if(0 == type) // Stop
602 {
603 mbtk_audio_loopback_stop();
604 if(audio_handle)
605 {
606 mbtk_audio_ubus_client_deinit(audio_handle);
607 audio_handle = 0;
608 }
609 }
610 else // Start
611 {
612 if(NULL == mbtk_audio_ubus_db)
613 ret = mbtk_audio_ubus_client_init(&audio_handle, NULL);
614 if(ret)
615 {
616 return -1;
617 }
618 mbtk_audio_mode_set(0);
619 mbtk_audio_loopback_start(2);
620 }
621
622 return 0;
623}
624
625/***************************************************** \
626 * Retry mechanism to add subscriber for Audio_if
627\*****************************************************/
628static void mbtk_dtmf_add_subscriber_AudioIf(struct uloop_timeout *timeout)
629{
630 /* add subscriber for Audio_If */
631 if (ubus_lookup_id(mbtk_audio_ubus_db->ctx, DTMFCODE_NOTIFICATION_NAME, &mbtk_audio_ubus_db->audioif_subscriber_id))
632 {
633 printf("%s, Failed to look up %s\n", __FUNCTION__, DTMFCODE_NOTIFICATION_NAME);
634 uloop_timeout_set(timeout, 2000);
635 return;
636 }
637
638 ubus_subscribe(mbtk_audio_ubus_db->ctx, &mbtk_audio_ubus_db->audioif_event, mbtk_audio_ubus_db->audioif_subscriber_id);
639 mbtk_audio_log("Audio_If subscribe %s object ok\n", DTMFCODE_NOTIFICATION_NAME);
640 return;
641}
642/*******************************************************************************\
643* Function: mbtk_dtmf_uBus_pmConstraint
644* Description: Lock/unlock system power management.
645* 0: unlock
646* 1: lock
647* Returns:
648\*******************************************************************************/
649static void mbtk_dtmf_uBus_PMConstraint(int set)
650{
651 FILE *flk;
652 if (mbtk_dtmf_PMConstraintWorks != 0)
653 return; //wake_lock unavailable or not exist. Do nothing
654
655#ifdef PROSLIC_ENABLEFREERUN
656 mbtk_audio_log("%s(%d): %s\n", __FUNCTION__, set, set ? "no sleep" : "sleep after 7s");
657#else
658 mbtk_audio_log("%s(%d): free-run is disabled, no sleep\n", __FUNCTION__, set);
659#endif
660
661 /* Do Not check fopen success. It must be ok, if failed
662 ** (for any reason) better to crash for logging and recovery
663 */
664 flk = fopen("/sys/power/wake_lock", "w");
665 if(set)
666 {
667 fprintf(flk, mbtk_dtmf_UBUS_NAME);
668 }
669 else
670 {
671#ifdef PROSLIC_ENABLEFREERUN
672 /* Clear constraint but with TimeOut enough
673 ** Stay awake for (mbtk_dtmf_DIAL_TIMER + 1) seconds, wait for ringing timer expire
674 */
675 fprintf(flk, mbtk_dtmf_UBUS_NAME " 7000000000"/*nsec*/);
676#endif
677 }
678
679 fclose(flk);
680}
681
682/*******************************************************************************\
683* Function: mbtk_dtmf_uBusInd_AudioIf_remove
684* Description: Handle upon Audio_if remove indication.
685* Returns:
686\*******************************************************************************/
687static void mbtk_dtmf_uBusInd_AudioIf_remove(struct ubus_context *ctx, struct ubus_subscriber *s,
688 uint32_t id)
689{
690 UNUSEDPARAM(ctx);
691 UNUSEDPARAM(s);
692 UNUSEDPARAM(id);
693
694 mbtk_audio_log("%s\n", __FUNCTION__);
695 uloop_timeout_set(&mbtk_dtmf_add_subscribe_timeout_AudioIf, 2000);
696}
697
698
699/*******************************************************************************\
700* Function: mbtk_dtmf_uBusInd_AudioIf
701* Description: Handle upon Audio_If incoming indication.
702* Returns: 0 on success
703\*******************************************************************************/
704static int mbtk_dtmf_uBusInd_AudioIf(struct ubus_context *ctx, struct ubus_object *obj,
705 struct ubus_request_data *req, const char *method,
706 struct blob_attr *msg)
707{
708 UNUSEDPARAM(ctx);
709 UNUSEDPARAM(obj);
710 UNUSEDPARAM(req);
711 UNUSEDPARAM(method);
712
713 char DTMFCode = 0;
714 struct blob_attr *tb[1];
715 int rc = 0;
716
717 //Lock from mbtk_dtmf interrupt handler (mbtk_dtmf_MainLoop)
718 pthread_mutex_lock(&mbtk_dtmf_mutex);
719 mbtk_audio_log("==================================%s : Begin==================================\n", __FUNCTION__);
720 mbtk_dtmf_uBus_PMConstraint(1);
721
722 /*parsing blob to be accessed easily with tb array - parse "1" argument*/
723 rc = blobmsg_parse(dtmf_code_policy, 1, tb, blob_data(msg), blob_len(msg));
724
725 if (rc < 0) {
726 printf("%s: parsing fail, rc = 0x%x\n", __FUNCTION__, rc);
727 }
728 else {
729 DTMFCode = (char)blobmsg_get_u32(tb[0]);
730 if(mbtk_audio_ubus_db->dtmf_cb)
731 mbtk_audio_ubus_db->dtmf_cb(DTMFCode);
732 mbtk_audio_log("%s got DTMF Code: Char[%c]=ASCII[0x%x]\n", __FUNCTION__, DTMFCode, DTMFCode);
733 }
734
735 mbtk_dtmf_uBus_PMConstraint(0);
736 mbtk_audio_log("==================================%s : End==================================", __FUNCTION__);
737 pthread_mutex_unlock(&mbtk_dtmf_mutex);
738
739 return rc;
740}
741
742/*******************************************************************************\
743* Function: mbtk_dtmf_uBusRegisterNotifications
744* Description: Register UBUS notifications of RIL and Audio_If.
745* Returns: 0 on success
746\*******************************************************************************/
747static int mbtk_dtmf_uBusRegisterNotifications(void)
748{
749 int ret = 0;
750
751 /* register UBUS notifications of Audio_If */
752 ret = ubus_register_subscriber(mbtk_audio_ubus_db->ctx, &mbtk_audio_ubus_db->audioif_event);
753 if (ret)
754 {
755 printf("%s Failed to add audio_if watch handler: %s\n", __FUNCTION__, ubus_strerror(ret));
756 return -1;
757 }
758
759 /* specify callback to handle notifications */
760 mbtk_audio_ubus_db->audioif_event.remove_cb = mbtk_dtmf_uBusInd_AudioIf_remove;
761 mbtk_audio_ubus_db->audioif_event.cb = mbtk_dtmf_uBusInd_AudioIf;
762
763 /* add subscribe */
764 uloop_timeout_set(&mbtk_dtmf_add_subscribe_timeout_AudioIf, 0);
765
766 mbtk_audio_log("%s: Make use of DTMF detection in modem.\n", __FUNCTION__);
767
768 return 0;
769}
770
771void mbtk_switch_dtmf_detection_cb(struct ubus_request *req, int rc)
772{
773 if (req)
774 {
775 free(req);
776 req = NULL;
777 }
778 mbtk_audio_log("%s do nothing, rc=%d\n", __FUNCTION__, rc);
779}
780/**
781 * @brief mbtk_switch_dtmf_detection
782 *
783 * @details detailed description
784 *
785 * @param param
786 * “param0": UINT32 onoff
787 * 0: disbale Tx DTMF detection
788 * 1: enable Tx DTMF detection
789 * 2: disbale Rx DTMF detection
790 * 3: enable Rx DTMF detection
791 * @return return type
792 */
793void mbtk_switch_dtmf_detection(unsigned short on_off, unsigned short param1,
794 unsigned short param2, unsigned short param3)
795{
796#if PCM_CTRL_OVER_VCM
797 vcm_DTMFDetection(on_off, param1, param2, param3);
798#else
799 int rc = 0;
800 struct ubus_request *req = NULL;
801
802 if(NULL == mbtk_audio_ubus_db)
803 {
804 printf("mbtk_dtmf_ubus not init!\n");
805 return;
806 }
807 req = (struct ubus_request *)malloc(sizeof(struct ubus_request));
808 if (req == NULL)
809 {
810 printf("leave %s: lack of memory\n", __FUNCTION__);
811 return;
812 }
813 memset(req, 0, sizeof(struct ubus_request));
814 blob_buf_init(&audio_cm_b, 0);
815 blobmsg_add_u32(&audio_cm_b, "param0", on_off);
816 blobmsg_add_u32(&audio_cm_b, "param1", param1);
817 blobmsg_add_u32(&audio_cm_b, "param2", param2);
818 blobmsg_add_u32(&audio_cm_b, "param3", param3);
819
820 if ((rc = ubus_invoke_async(mbtk_audio_ubus_db->ctx, mbtk_audio_ubus_db->audioif_request_id, "dtmf_detection", audio_cm_b.head, req)) != UBUS_STATUS_OK)
821 {
822 free(req);
823 printf("%s, ubus_invoke dtmf_detection failed %s\n", __FUNCTION__, ubus_strerror(rc));
824 }
825 else
826 {
827 mbtk_audio_log("%s: ubus_invoke_async success\n", __FUNCTION__);
828 req->complete_cb = mbtk_switch_dtmf_detection_cb;
829 ubus_complete_request_async(mbtk_audio_ubus_db->ctx, req);
830 }
831#endif
832}
833/*******************************************************************************\
834* Function: mbtk_dtmf_uBusInit
835* Description: Init UBUS context and register UBUS notifications of RIL.
836* Returns: 0 on success
837\*******************************************************************************/
838int mbtk_dtmf_uBusInit(void)
839{
840 int rc = 0;
841
842 uloop_init();
843
844 mbtk_audio_ubus_db->ctx = ubus_connect(NULL);
845 if (mbtk_audio_ubus_db->ctx == NULL)
846 {
847 printf(" %s Failed to connect to ubus\n", __FUNCTION__);
848 return -1;
849 }
850
851 ubus_add_uloop(mbtk_audio_ubus_db->ctx);
852
853 /* lookup fail if audio_if is not ready */
854 while(1)
855 {
856 rc = ubus_lookup_id(mbtk_audio_ubus_db->ctx, AUDIO_UBUS_REQUEST_NAME, &mbtk_audio_ubus_db->audioif_request_id);
857 if (0 != rc)
858 {
859 printf("%s, Failed to look up(%s), rc=%d\n", __FUNCTION__, AUDIO_UBUS_REQUEST_NAME, rc);
860 usleep(600000); //600ms
861 }
862 else
863 break;
864 }
865 mbtk_audio_log("%s, ubus_lookup_id(%s) OK\n", __FUNCTION__, AUDIO_UBUS_REQUEST_NAME);
866
867 /* subscribe for RIL & audio_if notifications */
868 if (mbtk_dtmf_uBusRegisterNotifications() != 0)
869 return -1;
870
871 mbtk_audio_log("%s success!\n", __FUNCTION__);
872 return 0;
873}
874
875
876/*******************************************************************************\
877* Function: mbtk_dtmf_uBusRun
878* Description: Start running of UBUS.
879* Returns:
880\*******************************************************************************/
881static void mbtk_audio_ubus_thread(void* hdl)
882{
883 pthread_detach(pthread_self());
884 uloop_run();
885 mbtk_audio_log("%s exit!\n", __FUNCTION__);
886 pthread_exit(NULL);
887}
888
889int mbtk_audio_ubus_client_init(mbtk_audio_client_handle_type *ph_audio, mbtk_dtmf_cb cb)
890{
b.liuc7ffd092024-01-03 15:23:07 +0800891#ifndef MBTK_YX_SUPPORT
liubin281ac462023-07-19 14:22:54 +0800892 // Set call handle.
893 if(ph_audio == NULL || mbtk_audio_ubus_db != NULL)
894 {
895 printf("ARG error or has inited.");
896 return -1;
897 }
898 mbtk_audio_ubus_db = malloc(sizeof(struct mbtk_audio_ubus_db_t));
899 if(NULL == mbtk_audio_ubus_db)
900 {
901 printf("malloc memory error\n");
902 }
903 memset(mbtk_audio_ubus_db, 0, sizeof(struct mbtk_audio_ubus_db_t));
904
905 mbtk_dtmf_PMConstraintWorks = access("/sys/power/wake_lock", R_OK | W_OK);
906 mbtk_dtmf_uBusInit();
907 mbtk_audio_ubus_db->dtmf_cb = cb;
908
909 mbtk_switch_dtmf_detection(3, 50, 4, 3);
910 pthread_create(&mbtk_audio_ubus_db->dtmf_pthread, NULL, (void *)mbtk_audio_ubus_thread, (void *)mbtk_audio_ubus_db);
911
912 *ph_audio = mbtk_audio_ubus_db;
913 LOGI("%s %d:%x", __FUNCTION__, __LINE__, mbtk_audio_ubus_db);
b.liuc7ffd092024-01-03 15:23:07 +0800914#else
b.liua896b3d2024-02-06 17:15:37 +0800915 audio_ctx = ubus_connect(NULL);
916 if (!audio_ctx) {
917 printf("Failed to connect to ubus\n");
918 return -1;
919 }
920
921 int ret = ubus_lookup_id(audio_ctx, AUDIO_UBUS_REQUEST_NAME, &ubus_id_audio_if);
922 if (ret) {
923 printf("ubus_lookup_id() fail.\n");
924 return ret;
925 }
b.liuc7ffd092024-01-03 15:23:07 +0800926#endif
liubin281ac462023-07-19 14:22:54 +0800927 return 0;
928}
929
930int mbtk_audio_ubus_client_deinit(mbtk_audio_client_handle_type h_audio)
931{
932 int ret;
b.liuc7ffd092024-01-03 15:23:07 +0800933#ifndef MBTK_YX_SUPPORT
liubin281ac462023-07-19 14:22:54 +0800934 struct mbtk_audio_ubus_db_t *audio_ubus = (struct mbtk_audio_ubus_db_t *)h_audio;
935
936 mbtk_audio_log("%s \n", __FUNCTION__);
937 if(h_audio == NULL || mbtk_audio_ubus_db == NULL)
938 {
939 printf("ARG error or not inited.");
940 return -1;
941 }
942 LOGI("%s %d:%x", __FUNCTION__, __LINE__, audio_ubus);
943 ret = pthread_cancel(audio_ubus->dtmf_pthread);
944 mbtk_audio_log("kill pthread : %d \n", ret);
945 pthread_join(audio_ubus->dtmf_pthread, NULL);
946 do{
947 ret = pthread_kill(audio_ubus->dtmf_pthread, 0);
948 mbtk_audio_log("kill pthread: %d \n", ret);
949 if(ret == ESRCH)
950 mbtk_audio_log("The specified thread does not exist or has terminated\n");
951 else if(ret == EINVAL)
952 mbtk_audio_log("Useless signal\n");
953 else
954 mbtk_audio_log("The thread exists\n");
955 usleep(100000);
956 }while(0 == ret);
957 LOGI("%s %d", __FUNCTION__, __LINE__);
958
959 mbtk_switch_dtmf_detection(2, 0, 0, 0);
960 /*unregister uloop*/
961 /*thread will get here only if uloop stopped*/
962 ubus_free(mbtk_audio_ubus_db->ctx);
963 uloop_done();
964 LOGI("%s %d", __FUNCTION__, __LINE__);
965 free(h_audio);
966 mbtk_audio_ubus_db = NULL;
b.liuc7ffd092024-01-03 15:23:07 +0800967#else
b.liua896b3d2024-02-06 17:15:37 +0800968 if(audio_ctx) {
969 ubus_free(audio_ctx);
970 audio_ctx = NULL;
971 }
b.liuc7ffd092024-01-03 15:23:07 +0800972#endif
liubin281ac462023-07-19 14:22:54 +0800973 return 0;
974}
975
976/**********************************************************************\
977* Function: APP_Audio_VolumeSet
978* Description: This function is called to send command into audio_if.
979* unsigned int volume(0~100)
980* Returns: 0 on success
981\**********************************************************************/
982void mbtk_audio_ubus_volume_set(unsigned int volume)
983{
984 int rc = 0;
985 struct ubus_request *req = NULL;
986
987 if(NULL == mbtk_audio_ubus_db)
988 {
989 printf("mbtk_dtmf_ubus not init!\n");
990 return;
991 }
992 req = (struct ubus_request *)malloc(sizeof(struct ubus_request));
993 if (req == NULL)
994 {
995 printf("leave %s: lack of memory\n", __FUNCTION__);
996 return;
997 }
998 memset(req, 0, sizeof(struct ubus_request));
999 blob_buf_init(&audio_cm_b, 0);
1000 blobmsg_add_u32(&audio_cm_b, "param0", volume);
1001
1002 if ((rc = ubus_invoke_async(mbtk_audio_ubus_db->ctx, mbtk_audio_ubus_db->audioif_request_id, AUDIO_UBUS_VOLUME_SET, audio_cm_b.head, req)) != UBUS_STATUS_OK)
1003 {
1004 free(req);
1005 printf("%s, ubus_invoke_async volume set failed: %s\n", __FUNCTION__, ubus_strerror(rc));
1006 }
1007 else
1008 {
1009 mbtk_audio_log("%s: ubus_invoke_async success\n", __FUNCTION__);
1010 req->complete_cb = mbtk_ubus_complete_cb;
1011 ubus_complete_request_async(mbtk_audio_ubus_db->ctx, req);
1012 }
1013}
1014
b.liu0e1a3792024-02-26 17:10:31 +08001015#define MBTK_AUDIO_GAIN_NUM 11
1016void mbtk_audio_ubus_gain_set(mbtk_audio_gain_type_enum type, uint16 *gain, int gain_num)
b.liu79884c22023-09-21 15:10:16 +08001017{
1018 int rc = 0;
1019 struct ubus_request *req = NULL;
1020
1021 req = (struct ubus_request *)malloc(sizeof(struct ubus_request));
1022 if (req == NULL)
1023 {
1024 printf("leave %s: lack of memory\n", __FUNCTION__);
1025 return;
1026 }
b.liu0e1a3792024-02-26 17:10:31 +08001027 if((type == AUDIO_GAIN_TYPE_RX_CODECGAIN || type == AUDIO_GAIN_TYPE_RX_DSPGAIN)
1028 && gain_num != MBTK_AUDIO_GAIN_NUM) {
1029 printf("gain_num error:type = %d, gain_name = %d.\n", type, gain_num);
1030 return;
1031 }
1032 if((type == AUDIO_GAIN_TYPE_TX_CODECGAIN || type == AUDIO_GAIN_TYPE_TX_DSPGAIN)
1033 && gain_num != 1) {
1034 printf("gain_num error:type = %d, gain_name = %d.\n", type, gain_num);
b.liu79884c22023-09-21 15:10:16 +08001035 return;
1036 }
1037 memset(req, 0, sizeof(struct ubus_request));
1038 blob_buf_init(&audio_cm_b, 0);
1039
b.liu79884c22023-09-21 15:10:16 +08001040 // Set RX
b.liu0e1a3792024-02-26 17:10:31 +08001041 blobmsg_add_u16(&audio_cm_b, "volume_gain_type", type);
1042 if(type == AUDIO_GAIN_TYPE_TX_CODECGAIN || type == AUDIO_GAIN_TYPE_TX_DSPGAIN) {
1043 blobmsg_add_u16(&audio_cm_b, "volume_gain_0", gain[0]);
1044 } else {
1045 char name[20];
1046 int i = 0;
1047 // Set TX
1048 for(; i < gain_num; i++) {
1049 memset(name, 0x0, 20);
1050 sprintf(name, "volume_gain_%d", i);
1051 blobmsg_add_u16(&audio_cm_b, name, gain[i]);
1052 }
1053 }
b.liu79884c22023-09-21 15:10:16 +08001054
1055#if 1
1056 if ((rc = ubus_invoke_async(mbtk_audio_ubus_db->ctx, mbtk_audio_ubus_db->audioif_request_id, AUDIO_UBUS_AUDIO_GAIN_SET, audio_cm_b.head, req)) != UBUS_STATUS_OK)
1057 {
1058 free(req);
1059 printf("%s, ubus_invoke_async volume set failed: %s\n", __FUNCTION__, ubus_strerror(rc));
1060 }
1061 else
1062 {
1063 printf("%s: ubus_invoke_async success\n", __FUNCTION__);
1064 req->complete_cb = mbtk_ubus_complete_cb;
1065 ubus_complete_request_async(mbtk_audio_ubus_db->ctx, req);
1066 }
1067#else
1068 if ((rc = ubus_invoke(APP_ctx, APP_audio_request_id, AUDIO_UBUS_AUDIO_GAIN_SET, audio_cm_b.head, NULL, 0, 0)) != UBUS_STATUS_OK)
1069 {
1070 printf("%s, ubus_invoke_async volume set failed: %s\n", __FUNCTION__, ubus_strerror(rc));
1071 }
1072 else
1073 {
1074 printf("%s: ubus_invoke_async success\n", __FUNCTION__);
1075 }
1076 free(req);
1077#endif
1078}
1079
b.liu0e1a3792024-02-26 17:10:31 +08001080void mbtk_audio_ubus_reg_set(int reg_addr, int reg_value)
1081{
1082 int rc = 0;
1083 struct ubus_request *req = NULL;
1084
1085 req = (struct ubus_request *)malloc(sizeof(struct ubus_request));
1086 if (req == NULL)
1087 {
1088 printf("leave %s: lack of memory\n", __FUNCTION__);
1089 return;
1090 }
1091
1092 memset(req, 0, sizeof(struct ubus_request));
1093 blob_buf_init(&audio_cm_b, 0);
1094 blobmsg_add_u32(&audio_cm_b, "reg_addr", reg_addr);
1095 blobmsg_add_u32(&audio_cm_b, "reg_value", reg_value);
1096
1097#if 1
1098 if ((rc = ubus_invoke_async(mbtk_audio_ubus_db->ctx, mbtk_audio_ubus_db->audioif_request_id, AUDIO_UBUS_AUDIO_REG_SET, audio_cm_b.head, req)) != UBUS_STATUS_OK)
1099 {
1100 free(req);
1101 printf("%s, ubus_invoke_async volume set failed: %s\n", __FUNCTION__, ubus_strerror(rc));
1102 }
1103 else
1104 {
1105 printf("%s: ubus_invoke_async success\n", __FUNCTION__);
1106 req->complete_cb = mbtk_ubus_complete_cb;
1107 ubus_complete_request_async(mbtk_audio_ubus_db->ctx, req);
1108 }
1109#else
1110 if ((rc = ubus_invoke(APP_ctx, APP_audio_request_id, AUDIO_UBUS_AUDIO_GAIN_SET, audio_cm_b.head, NULL, 0, 0)) != UBUS_STATUS_OK)
1111 {
1112 printf("%s, ubus_invoke_async volume set failed: %s\n", __FUNCTION__, ubus_strerror(rc));
1113 }
1114 else
1115 {
1116 printf("%s: ubus_invoke_async success\n", __FUNCTION__);
1117 }
1118 free(req);
1119#endif
1120}
b.liu79884c22023-09-21 15:10:16 +08001121
liubin281ac462023-07-19 14:22:54 +08001122static void audio_volume_get_data_cb (struct ubus_request *req, int type, struct blob_attr *msg)
1123{
1124 UNUSEDPARAM(req);
1125 UNUSEDPARAM(type);
1126 struct blob_attr *tb[1];
1127 unsigned int volume = 888;
1128 int rc = 0;
1129
1130 rc = blobmsg_parse(int_policy, 1, tb, blob_data(msg), blob_len(msg));
1131 if (rc < 0)
1132 {
1133 printf("[%s] parsing blobmsg failed\n", __FUNCTION__);
1134 return;
1135 }
1136
1137 if(tb[0])
1138 volume = blobmsg_get_u32(tb[0]);
1139 if (mbtk_audio_ubus_db->audio_volume_get_cb)
1140 mbtk_audio_ubus_db->audio_volume_get_cb(volume);
1141 mbtk_audio_log("%s; volume:%d\n", __FUNCTION__, volume);
1142}
1143
1144void mbtk_audio_ubus_volume_get(mbtk_volume_cb cb)
1145{
1146 int rc = 0;
1147 struct ubus_request *req = NULL;
1148
1149 if(NULL == mbtk_audio_ubus_db || NULL == cb)
1150 {
1151 printf("mbtk_dtmf_ubus not init or callback invalid!\n");
1152 return;
1153 }
1154 mbtk_audio_ubus_db->audio_volume_get_cb = cb;
1155 req = (struct ubus_request *)malloc(sizeof(struct ubus_request));
1156 if (req == NULL)
1157 {
1158 printf("leave %s: lack of memory\n", __FUNCTION__);
1159 return;
1160 }
1161 memset(req, 0, sizeof(struct ubus_request));
1162 blob_buf_init(&audio_cm_b, 0);
1163
1164 if ((rc = ubus_invoke_async(mbtk_audio_ubus_db->ctx,
1165 mbtk_audio_ubus_db->audioif_request_id,
1166 AUDIO_UBUS_VOLUME_GET,
1167 audio_cm_b.head, req)) != UBUS_STATUS_OK)
1168 {
1169 free(req);
1170 printf("%s, ubus_invoke_async volume get failed %s\n", __FUNCTION__, ubus_strerror(rc));
1171 }
1172 else
1173 {
1174 mbtk_audio_log("%s: ubus_invoke_async success\n", __FUNCTION__);
1175 req->data_cb = audio_volume_get_data_cb;
1176 req->complete_cb = mbtk_ubus_complete_cb;
1177 ubus_complete_request_async(mbtk_audio_ubus_db->ctx, req);
1178 }
1179}