blob: 700f93d7cac9353e5b3b505c429b5e5c1288c02c [file] [log] [blame]
b.liu1c74d692024-08-14 17:43:59 +08001/**
2 * \file ql_call.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-01-18
9 */
10#include "ql/ql_mcm_call.h"
11#include <telephony/ril.h>
12#include <telephony/ril_ext.h>
13#include "ql/ql_mcm.h"
14#include "rilutil.h"
15#include "mbtk_log.h"
16
17// #define DEBUG 1
18
19#ifdef DEBUG
20 #define mbtk_call_log(...) printf(__VA_ARGS__)
21#else
22 #define mbtk_call_log(...)
23#endif
24
25struct ql_call_ubus_t
26{
27 struct ubus_context *ctx;
28
29 /* RIL */
30 struct ubus_subscriber ril_ind_event;
31 uint32_t ril_subscriber_id;
32 uint32_t ril_request_id;
33 uint8_t auto_answer;
34 uint32_t answer_time;
35 pthread_t call_status_pthread;
36 ql_mcm_voice_calls_state_t call_state;
37 QL_VoiceCall_CommonStateHandlerFunc_t _voice_call_common_state_handler;
38 QL_VoiceCall_StateHandlerFunc_t _voice_call_state_handler;
39};
40
41const char *RIL_MessageMap[] =
42{
43 "RIL_CALL_ACTIVE", //0,
44 "RIL_CALL_HOLDING", //1,
45 "RIL_CALL_DIALING", //2, /* MO call only */
46 "RIL_CALL_ALERTING", //3, /* MO call only */
47 "RIL_CALL_INCOMING", //4, /* MT call only */
48 "RIL_CALL_WAITING", //5, /* MT call only */
49 "RIL_CALL_OFFERING", //6, /* MT call offering (call setup) */
50 "RIL_CALL_DISCONNECTING",//7, /* call in disconnect procedure */
51 "RIL_CALL_DISCONNECTED" //8, /* call is disconnected */
52};
53static struct ql_call_ubus_t *ql_call_ubus = NULL;
54static void ql_voice_call_answer(struct uloop_timeout *timeout);
55static struct uloop_timeout voice_call_answer_timeout =
56{
57 .cb = ql_voice_call_answer,
58};
59
60static void ql_voice_call_answer(struct uloop_timeout *timeout)
61{
62 QL_Voice_Call_Answer(ql_call_ubus, 0);
63 // uloop_timeout_set(timeout, 2000);
64 return;
65}
66
67int ql_call_handle_ril_ind(struct ubus_context *ctx, unsigned int rilid, unsigned int rilerror, char *data, int data_len)
68{
69 UNUSED(data_len);
70 UNUSED(ctx);
71
72 int datalen = 0, callID = 0;
73 int ret = 0;
74
75 if (rilerror) {
76 return -1;
77 }
78
79 mbtk_call_log("call_handle_ril_ind: rcv %d\n", rilid);
80
81 switch(rilid)
82 {
83 case RIL_UNSOL_ECALLDATA: //+ecalldata
84 // ecallHandleEcalldata(data);
85 break;
86
87 case RIL_UNSOL_ECALLONLY: //+ecallonly
88 // ecallHandleEcallonly(data);
89 break;
90
91 case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED_EXT: /*"CC" 1510*/
92 {
93 RIL_Call *rilCall = (RIL_Call *)data;
94 callID = rilCall->index;
95
96 mbtk_call_log("%s: id %d=RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED_EXT (len=%d) (state=%s), call index=%d\n",
97 __FUNCTION__, rilid, datalen, RIL_MessageMap[(int)rilCall->state], callID);
98
99 mbtk_call_log("Received from Ril, name=%s, num=%s\n", rilCall->name, rilCall->number);
100 ql_call_ubus->call_state.calls_len = 1;
101 ql_call_ubus->call_state.calls[0].call_id;
102 memcpy(ql_call_ubus->call_state.calls[0].number, rilCall->number, strlen(rilCall->number));
103 ql_call_ubus->call_state.calls[0].state = rilCall->state;
104 switch (rilCall->state)
105 {
106 //Call connected, for MO & MT both
107 case RIL_CALL_ACTIVE:
108 mbtk_call_log("%s, RIL_CALL_ACTIVE, call index=%d connected!!\n", __FUNCTION__, callID);
109 ql_call_ubus->call_state.calls[0].state = E_QL_MCM_VOICE_CALL_STATE_ACTIVE;
110 break;
111
112 //MT call only
113 case RIL_CALL_INCOMING:
114 mbtk_call_log("%s, RIL_CALL_INCOMING!!\n", __FUNCTION__);
115 ql_call_ubus->call_state.calls[0].state = E_QL_MCM_VOICE_CALL_STATE_INCOMING;
116 if(!ql_call_ubus->auto_answer)
117 {
118 mbtk_call_log("%s, auto_answer:%d!!\n", __FUNCTION__, ql_call_ubus->answer_time);
119 uloop_timeout_set(&voice_call_answer_timeout, ql_call_ubus->answer_time);
120 }
121 break;
122
123 //MO call only
124 case RIL_CALL_ALERTING:
125 mbtk_call_log("%s, RIL_CALL_ALERTING, call index=%d alerting!!\n", __FUNCTION__, callID);
126 ql_call_ubus->call_state.calls[0].state = E_QL_MCM_VOICE_CALL_STATE_ALERTING;
127 break;
128
129 case RIL_CALL_WAITING: //MT call only
130 mbtk_call_log("%s, RIL_CALL_WAITING, call index=%d alerting!!\n", __FUNCTION__, callID);
131 ql_call_ubus->call_state.calls[0].state = E_QL_MCM_VOICE_CALL_STATE_WAITING;
132 break;
133
134 case RIL_CALL_DISCONNECTED:
135 mbtk_call_log("%s, RIL_CALL_DISCONNECTED, call index=%d disconnected!!\n", __FUNCTION__, callID);
136 ql_call_ubus->call_state.calls[0].state = E_QL_MCM_VOICE_CALL_STATE_END;
137 break;
138
139 case RIL_CALL_HOLDING:
140 ql_call_ubus->call_state.calls[0].state = E_QL_MCM_VOICE_CALL_STATE_HOLDING;
141 mbtk_call_log("%s, RIL_CALL_HOLDING, call index=%d hold!!\n", __FUNCTION__, callID);
142 break;
143
144 case RIL_CALL_DIALING: //MO call only
145 ql_call_ubus->call_state.calls[0].state = E_QL_MCM_VOICE_CALL_STATE_DIALING;
146 mbtk_call_log("%s, RIL_CALL_DIALING, call index=%d hold!!\n", __FUNCTION__, callID);
147 break;
148 case RIL_CALL_OFFERING:
149 case RIL_CALL_DISCONNECTING:
150 default:
151 printf("%s, state=%s ignored!!\n", __FUNCTION__, RIL_MessageMap[(int)rilCall->state]);
152 ql_call_ubus->call_state.calls[0].state = E_QL_MCM_VOICE_CALL_STATE_END;
153 break;
154 }
155 if(ql_call_ubus->_voice_call_common_state_handler && ql_call_ubus)
156 {
157 ql_call_ubus->_voice_call_common_state_handler(E_QL_MCM_VOICE_CALL_IND, &ql_call_ubus->call_state, sizeof(ql_mcm_voice_call_ind));
158 }
159 }
160 break;
161 case RIL_UNSOL_CALL_NO_CARRIER_EXT: /*"CC" 1511*/
162 mbtk_call_log("%s: id %d=RIL_UNSOL_CALL_NO_CARRIER_EXT (len=%d)\n",
163 __FUNCTION__, rilid, datalen);
164 ql_call_ubus->call_state.calls[0].state = E_QL_MCM_VOICE_CALL_STATE_END;
165 if(ql_call_ubus->_voice_call_common_state_handler && ql_call_ubus)
166 {
167 ql_call_ubus->_voice_call_common_state_handler(E_QL_MCM_VOICE_CALL_IND, &ql_call_ubus->call_state, sizeof(ql_mcm_voice_call_ind));
168 }
169 break;
170
171 case RIL_UNSOL_CALL_RING: /*"CC" 1018*/
172 printf("%s: id %d=RIL_UNSOL_CALL_RING (len=%d), ignored!!\n",
173 __FUNCTION__, rilid, datalen);
174 break;
175
176 case RIL_UNSOL_DISCONNECT_CALLID: /*"CC" 1538*/
177 callID = *(int *)data;
178 ql_call_ubus->call_state.calls[0].state = E_QL_MCM_VOICE_CALL_STATE_END;
179 mbtk_call_log("%s: id %d=RIL_UNSOL_DISCONNECT_CALLID (len=%d), call index=%d!\n",
180 __FUNCTION__, rilid, datalen, *(int *)data);
181 break;
182 default:
183 break;
184 }
185
186 return ret;
187}
188static void ql_call_requset_cb(struct ubus_request *req, int type, struct blob_attr *msg)
189{
190 unsigned int requestid;
191 unsigned int rilerrno;
192 void *response = NULL;
193 int responselen;
194 int ret = 0;
195
196 ret = rilutil_parseResponse(msg, &requestid, &rilerrno, &response, &responselen);
197 if(ret)
198 {
199 fprintf(stderr, "parse blob error\n");
200 goto done;
201 }
202
203 if(rilerrno)
204 {
205 // RIL_REQUEST_RELEASE_CALL
206 fprintf(stderr, "unsolicited id %d, error code %d\n", requestid, rilerrno);
207 goto done;
208 }
209
210 //process response here
211
212done:
213 if(response)
214 rilutil_freeResponseData(requestid, response, responselen);
215
216 return;
217}
218
219int ql_call_subscriber_cb(struct ubus_context *ctx, struct ubus_object *obj,
220 struct ubus_request_data *req, const char *method, struct blob_attr *msg)
221{
222 UNUSED(ctx);
223 UNUSED(obj);
224 UNUSED(req);
225 UNUSED(method);
226
227 unsigned int requestid = 0;
228 unsigned int rilerrno = 0;
229 void *response = NULL;
230 int responselen = 0;
231 int ret = 0;
232
233 ret = rilutil_parseResponse(msg, &requestid, &rilerrno, &response, &responselen);
234 if (ret)
235 goto end;
236
237 mbtk_call_log("call_subscriber_cb: rcv %d\n", requestid);
238
239 ql_call_handle_ril_ind(ctx, requestid, rilerrno, response, responselen);
240
241end:
242 if (response)
243 rilutil_freeResponseData(requestid,response,responselen);
244
245 return 0;
246}
247
248void ql_call_subscriber_remove_cb(struct ubus_context *ctx, struct ubus_subscriber *obj, uint32_t id)
249{
250 UNUSED(ctx);
251 UNUSED(obj);
252 UNUSED(id);
253 mbtk_call_log("ql_call_subscriber_remove_cb\n");
254}
255
256static void ql_call_register_ril(void* hdl)
257{
258 static struct ubus_request req;
259 struct ql_call_ubus_t *voice_call_ubus = (struct ql_call_ubus_t *)hdl;
260 int ret;
261
262 if(hdl == NULL || ql_call_ubus == NULL)
263 {
264 printf("ARG error or not inited.");
265 return -1;
266 }
267 pthread_detach(pthread_self());
268 ret = ubus_register_subscriber(voice_call_ubus->ctx, &voice_call_ubus->ril_ind_event);
269 if (ret) {
270 printf("call_daemon: Failed to add ecall_subscriber: %s\n", ubus_strerror(ret));
271 return ret;
272 }
273
274 voice_call_ubus->ril_ind_event.cb = ql_call_subscriber_cb;
275 voice_call_ubus->ril_ind_event.remove_cb = ql_call_subscriber_remove_cb;
276
277 //register for CC ind
278 if (ubus_lookup_id(voice_call_ubus->ctx, "ril.unsol.cc", &voice_call_ubus->ril_subscriber_id)) {
279 printf("call_daemon: Failed to look up ril.unsol.cc object\n");
280 return ret;
281 }
282
283 ubus_subscribe(voice_call_ubus->ctx, &voice_call_ubus->ril_ind_event, voice_call_ubus->ril_subscriber_id);
284 mbtk_call_log("call_daemon: subscribe ril.unsol.cc object ok\n");
285 mbtk_call_log("%s!\n", __FUNCTION__);
286 while(1)
287 {
288 uloop_run();
289 printf("%s uloop_run done!\n", __FUNCTION__);
290 }
291 pthread_exit(NULL);
292}
293/* Init voice module and return h_voice, this should be called before any other APIs */
294int QL_Voice_Call_Client_Init(voice_client_handle_type *ph_voice)
295{
296 int id;
297 // Set call handle.
298 //*ph_voice = 1;
299 if(ph_voice == NULL)
300 {
301 printf("ARG error or has inited.");
302 return -1;
303 }
304 ql_call_ubus = malloc(sizeof(struct ql_call_ubus_t));
305 if(NULL == ql_call_ubus)
306 {
307 printf("malloc memory error\n");
308 }
309 memset(ql_call_ubus, 0, sizeof(struct ql_call_ubus_t));
310 uloop_init();
311
312 ql_call_ubus->ctx = ubus_connect(NULL);
313 if(!ql_call_ubus->ctx)
314 {
315 printf("Failed to connect to ubus");
316 goto out;
317 }
318
319 ubus_add_uloop(ql_call_ubus->ctx);
320
321 if (ubus_lookup_id(ql_call_ubus->ctx, "ril", &ql_call_ubus->ril_request_id)) {
322 fprintf(stderr, "%s, Failed to look up test object\n", __FUNCTION__);
323 return -1;
324 }
325 ql_call_ubus->auto_answer = E_QL_MCM_VOICE_AUTO_ANSWER_DISABLE;
326 ql_call_ubus->call_state.calls[0].state = E_QL_MCM_VOICE_CALL_STATE_END;
327 pthread_create(&ql_call_ubus->call_status_pthread, NULL, (void *)ql_call_register_ril, (void *)ql_call_ubus);
328 *ph_voice = ql_call_ubus;
329
330 return 0;
331out:
332 //uloop_done();
333
334 return 0;
335}
336
337/* DeInit voice module and release resources, this should be called at last */
338int QL_Voice_Call_Client_Deinit(voice_client_handle_type h_voice)
339{
340 int ret;
341 struct ql_call_ubus_t *voice_call_ubus = (struct ql_call_ubus_t *)h_voice;
342 // Free handle.
343
344 if(h_voice == NULL || ql_call_ubus == NULL)
345 {
346 LOGE("ARG error or not inited.");
347 printf("ARG error or not inited.");
348 return -1;
349 }
350 ret = pthread_cancel(voice_call_ubus->call_status_pthread);
351 mbtk_call_log("kill pthread : %d \n", ret);
352 pthread_join(voice_call_ubus->call_status_pthread, NULL);
353 do{
354 ret = pthread_kill(voice_call_ubus->call_status_pthread, 0);
355 mbtk_call_log("kill pthread: %d \n", ret);
356 if(ret == ESRCH)
357 printf("The specified thread does not exist or has terminated\n");
358 else if(ret == EINVAL)
359 printf("Useless signal\n");
360 else
361 mbtk_call_log("The thread exists\n");
362 usleep(100000);
363 }while(0 == ret);
364 free(h_voice);
365 ql_call_ubus = NULL;
366 uloop_done();
367 ubus_free(voice_call_ubus->ctx);
368 return 0;
369}
370
371/* Add callback function, if any call state changed, handlerPtr will be called to notify App */
372int QL_Voice_Call_AddStateHandler(voice_client_handle_type h_voice,
373 QL_VoiceCall_StateHandlerFunc_t handlerPtr,
374 void* contextPtr)
375{
376 static struct ubus_request req;
377 struct ql_call_ubus_t *voice_call_ubus = (struct ql_call_ubus_t *)h_voice;
378 int ret;
379
380 if(h_voice == NULL || ql_call_ubus == NULL)
381 {
382 printf("ARG error or not inited.");
383 return -1;
384 }
385 ret = pthread_kill(voice_call_ubus->call_status_pthread, 0);
386 mbtk_call_log("kill pthread: %d \n", ret);
387 if(ret == ESRCH)
388 mbtk_call_log("The specified thread does not exist or has terminated\n");
389 else if(ret == EINVAL)
390 printf("Useless signal\n");
391 else
392 mbtk_call_log("The thread exists\n");
393 if(voice_call_ubus->ril_subscriber_id)
394 {
395 voice_call_ubus->_voice_call_state_handler = handlerPtr;
396 }
397 else
398 {
399 printf("%s error!!\n", __func__);
400 return -1;
401 }
402
403 return 0;
404}
405
406/* Remove callback function, won't receive any notify anymore */
407int QL_Voice_Call_RemoveStateHandler(voice_client_handle_type h_voice)
408{
409 struct ql_call_ubus_t *voice_call_ubus = (struct ql_call_ubus_t *)h_voice;
410
411 if(h_voice == NULL || ql_call_ubus == NULL)
412 {
413 LOGE("ARG error or not inited.");
414 return -1;
415 }
416 voice_call_ubus->_voice_call_state_handler = NULL;
417
418 return 0;
419}
420
421
422/* Add callback function, if any call state changed, handlerPtr will be called to notify App */
423int QL_Voice_Call_AddCommonStateHandler(voice_client_handle_type h_voice,
424 QL_VoiceCall_CommonStateHandlerFunc_t handlerPtr)
425{
426 static struct ubus_request req;
427 struct ql_call_ubus_t *voice_call_ubus = (struct ql_call_ubus_t *)h_voice;
428 int ret;
429
430 if(h_voice == NULL || ql_call_ubus == NULL)
431 {
432 LOGE("ARG error or not inited.");
433 return -1;
434 }
435 ret = pthread_kill(voice_call_ubus->call_status_pthread, 0);
436 mbtk_call_log("kill pthread: %d \n", ret);
437 if(ret == ESRCH)
438 mbtk_call_log("The specified thread does not exist or has terminated\n");
439 else if(ret == EINVAL)
440 printf("Useless signal\n");
441 else
442 mbtk_call_log("The thread exists\n");
443 if(voice_call_ubus->ril_subscriber_id)
444 {
445 voice_call_ubus->_voice_call_common_state_handler = handlerPtr;
446 }
447 else
448 {
449 printf("%s error!!\n", __func__);
450 return -1;
451 }
452
453
454 return 0;
455}
456
457/* Remove callback function, won't receive any notify anymore */
458int QL_Voice_Call_RemoveCommonStateHandler(voice_client_handle_type h_voice)
459{
460 struct ql_call_ubus_t *voice_call_ubus = (struct ql_call_ubus_t *)h_voice;
461
462 if(h_voice == NULL || ql_call_ubus == NULL)
463 {
464 LOGE("ARG error or not inited.");
465 return -1;
466 }
467 voice_call_ubus->_voice_call_common_state_handler = NULL;
468
469 return 0;
470}
471
472
473/* Start call and return call_id, this can be used in the later */
474int QL_Voice_Call_Start(voice_client_handle_type h_voice,
475 E_QL_VCALL_ID_T simId,
476 char* phone_number, ///< [IN] Destination identifier for the voice
477 int *call_id) ///< [OUT] call id
478{
479 static struct ubus_request req;
480 struct ql_call_ubus_t *voice_call_ubus = (struct ql_call_ubus_t *)h_voice;
481 static struct blob_buf b;
482 int id, ret;
483 RIL_Dial dial_data;
484
485 if(h_voice == NULL || ql_call_ubus == NULL)
486 {
487 printf("ARG error or not inited.");
488 return -1;
489 }
490 if(voice_call_ubus->call_state.calls[0].state == E_QL_MCM_VOICE_CALL_STATE_ACTIVE ||
491 voice_call_ubus->call_state.calls[0].state == E_QL_MCM_VOICE_CALL_STATE_INCOMING ||
492 voice_call_ubus->call_state.calls[0].state == E_QL_MCM_VOICE_CALL_STATE_ALERTING)
493 {
494 printf("A call already exists, Voice Call incoming or active!!\n");
495 return -1;
496 }
497 memset(&dial_data, 0, sizeof(RIL_Dial));
498 dial_data.address = phone_number;
499 printf("call number %s\n", dial_data.address);
500 if (ubus_lookup_id(ql_call_ubus->ctx, "ril", &ql_call_ubus->ril_request_id)) {
501 fprintf(stderr, "%s, Failed to look up test object\n", __FUNCTION__);
502 return -1;
503 }
504 rilutil_makeRequestBlob(&b, RIL_REQUEST_DIAL, &dial_data, 0);
505 ret = ubus_invoke(voice_call_ubus->ctx, voice_call_ubus->ril_request_id, "ril_request", b.head, ql_call_requset_cb, 0,0);
506 if(ret != 0)
507 {
508 printf("sim_get_imsi,ubus_invoke Failed %s\n", ubus_strerror(ret));
509 return E_QL_ERROR_GENERIC;
510 }
511
512 return 0;
513}
514
515/* End call of call_id, which returned by QL_Voice_Call_Start or callback func register via QL_Voice_Call_AddStateHandler */
516int QL_Voice_Call_End(voice_client_handle_type h_voice,
517 int call_id) ///< [IN] call id, return by QL_Voice_Start
518{
519 static struct ubus_request req;
520 static struct blob_buf b;
521 int ret;
522 struct ql_call_ubus_t *voice_call_ubus = (struct ql_call_ubus_t *)h_voice;
523
524 if(h_voice == NULL || ql_call_ubus == NULL)
525 {
526 printf("ARG error or not inited.");
527 return -1;
528 }
529 mbtk_call_log("Voice Call State:%s, %d\n", voice_call_ubus->call_state.calls[0].number, voice_call_ubus->call_state.calls[0].state);
530 if(voice_call_ubus->call_state.calls[0].state != E_QL_MCM_VOICE_CALL_STATE_ACTIVE &&
531 voice_call_ubus->call_state.calls[0].state != E_QL_MCM_VOICE_CALL_STATE_INCOMING &&
532 voice_call_ubus->call_state.calls[0].state != E_QL_MCM_VOICE_CALL_STATE_ALERTING)
533 {
534 printf("No Voice Call incoming or active!!\n");
535 return -1;
536 }
537 //use rilutil's API, just a example
538 rilutil_makeRequestBlob(&b, RIL_REQUEST_RELEASE_CALL, NULL, 0);
539 ret = ubus_invoke(voice_call_ubus->ctx, voice_call_ubus->ril_request_id, "ril_request", b.head, ql_call_requset_cb, 0,0);
540 if(ret != 0)
541 {
542 printf("sim_get_imsi,ubus_invoke Failed %s", ubus_strerror(ret));
543 return E_QL_ERROR_GENERIC;
544 }
545 return 0;
546}
547
548/* Answer the call of call_id, which returned by callback func register via QL_Voice_Call_AddStateHandler */
549int QL_Voice_Call_Answer(voice_client_handle_type h_voice,
550 int call_id )
551{
552 static struct ubus_request req;
553 static struct blob_buf b;
554 struct ql_call_ubus_t *voice_call_ubus = (struct ql_call_ubus_t *)h_voice;
555 int ret;
556
557 if(h_voice == NULL || ql_call_ubus == NULL)
558 {
559 printf("ARG error or not inited.");
560 return -1;
561 }
562 rilutil_makeRequestBlob(&b, RIL_REQUEST_ANSWER, NULL, 0);
563 ret = ubus_invoke(voice_call_ubus->ctx, voice_call_ubus->ril_request_id, "ril_request", b.head, ql_call_requset_cb, 0,0);
564 if(ret != 0)
565 {
566 printf("ql call, ubus_invoke Failed %s", ubus_strerror(ret));
567 return E_QL_ERROR_GENERIC;
568 }
569 return 0;
570}
571
572int QL_Voice_Call_Hold( voice_client_handle_type h_voice)
573{
574 static struct ubus_request req;
575 struct ql_call_ubus_t *voice_call_ubus = (struct ql_call_ubus_t *)h_voice;
576 static struct blob_buf b;
577 int ret;
578
579 if(h_voice == NULL || ql_call_ubus == NULL)
580 {
581 printf("ARG error or not inited.");
582 return -1;
583 }
584 rilutil_makeRequestBlob(&b, RIL_REQUEST_HANGUP, NULL, 0);
585 ret = ubus_invoke(voice_call_ubus->ctx, voice_call_ubus->ril_request_id, "ril_request", b.head, ql_call_requset_cb, 0,0);
586 if(ret != 0)
587 {
588 printf("ql call, ubus_invoke Failed %s", ubus_strerror(ret));
589 return E_QL_ERROR_GENERIC;
590 }
591 return 0;
592}
593
594int QL_Voice_Call_UnHold( voice_client_handle_type h_voice)
595{
596
597 return 0;
598}
599
600int QL_Voice_Call_Conference( voice_client_handle_type h_voice)
601{
602 static struct ubus_request req;
603 struct ql_call_ubus_t *voice_call_ubus = (struct ql_call_ubus_t *)h_voice;
604 static struct blob_buf b;
605 int ret;
606
607 if(h_voice == NULL || ql_call_ubus == NULL)
608 {
609 printf("ARG error or not inited.");
610 return -1;
611 }
612 rilutil_makeRequestBlob(&b, RIL_REQUEST_CONFERENCE, NULL, 0);
613 ret = ubus_invoke(voice_call_ubus->ctx, voice_call_ubus->ril_request_id, "ril_request", b.head, ql_call_requset_cb, 0,0);
614 if(ret != 0)
615 {
616 printf("ql call, ubus_invoke Failed %s", ubus_strerror(ret));
617 return E_QL_ERROR_GENERIC;
618 }
619 return 0;
620}
621
622int QL_Voice_Call_EndConference( voice_client_handle_type h_voice)
623{
624
625 return 0;
626}
627
628int QL_Voice_Call_Ecall(voice_client_handle_type h_voice,
629 E_QL_VCALL_ID_T simId,
630 char* phone_number,
631 ql_mcm_ecall_info ecall_info,
632 int *call_id)
633{
634// RIL_REQUEST_SET_CECALL
635// RIL_REQUEST_GET_CECALL
636// RIL_REQUEST_SET_ECALLONLY
637// RIL_REQUEST_GET_ECALLONLY
638// RIL_REQUEST_SET_ECALLREG
639 static struct ubus_request req;
640 struct ql_call_ubus_t *voice_call_ubus = (struct ql_call_ubus_t *)h_voice;
641 static struct blob_buf b;
642 int ret;
643
644 if(h_voice == NULL || ql_call_ubus == NULL)
645 {
646 printf("ARG error or not inited.");
647 return -1;
648 }
649 //use rilutil's API, just a example
650 rilutil_makeRequestBlob(&b, RIL_REQUEST_CONFERENCE, NULL, 0);
651 ret = ubus_invoke(voice_call_ubus->ctx, voice_call_ubus->ril_request_id, "ril_request", b.head, ql_call_requset_cb, 0,0);
652 if(ret != 0)
653 {
654 printf("ql call, ubus_invoke Failed %s", ubus_strerror(ret));
655 return E_QL_ERROR_GENERIC;
656 }
657 return 0;
658}
659
660
661int QL_Voice_Call_SetAutoAnswer(voice_client_handle_type h_voice,
662 E_QL_MCM_VOICE_AUTO_ANSWER_T eAnswerType,
663 uint32_t uAnswerTime)
664{
665 struct ql_call_ubus_t *voice_call_ubus = (struct ql_call_ubus_t *)h_voice;
666
667 if(h_voice == NULL || ql_call_ubus == NULL)
668 {
669 printf("ARG error or not inited.");
670 return -1;
671 }
672 voice_call_ubus->auto_answer = eAnswerType;
673 voice_call_ubus->answer_time = uAnswerTime;
674
675 return 0;
676}
677
678int QL_Voice_Call_Ecall_HangUp(voice_client_handle_type h_voice)
679{
680 return 0;
681}
682
683int QL_Voice_Call_Ecall_UpdateMsd(voice_client_handle_type h_voice,const char *msd,uint32_t msd_len)
684{
685 return 0;
686}
687
688//Ecall Push caommand
689int QL_Voice_Call_Ecall_MsdPush(voice_client_handle_type h_voice,
690 E_QL_MCM_ECALL_STATE_T *ecall_state)
691{
692 return 0;
693}
694
695//Get Ecall config info
696int QL_Voice_Call_Ecall_GetConfigInfo(voice_client_handle_type h_voice,
697 ql_mcm_ecall_config_info *ecall_config)
698{
699// RIL_REQUEST_SET_ECALLCFG
700// RIL_REQUEST_GET_ECALLCFG
701 return 0;
702}
703
704int QL_Voice_Call_Ecall_SetConfigInfo(voice_client_handle_type h_voice,
705 E_QL_MCM_ECALL_CONFIG_T ecall_config_type,
706 uint8_t value)
707{
708 return 0;
709}
710
711//Cancel dial
712int QL_Voice_Call_CancelDial( voice_client_handle_type h_voice)
713{
714 static struct ubus_request req;
715 static struct blob_buf b;
716 int ret;
717 struct ql_call_ubus_t *voice_call_ubus = (struct ql_call_ubus_t *)h_voice;
718
719 if(h_voice == NULL || ql_call_ubus == NULL)
720 {
721 printf("ARG error or not inited.");
722 return -1;
723 }
724 //use rilutil's API, just a example
725 rilutil_makeRequestBlob(&b, RIL_REQUEST_RELEASE_CALL, NULL, 0);
726 ret = ubus_invoke(voice_call_ubus->ctx, voice_call_ubus->ril_request_id, "ril_request", b.head, ql_call_requset_cb, 0,0);
727 if(ret != 0)
728 {
729 printf("sim_get_imsi,ubus_invoke Failed %s", ubus_strerror(ret));
730 return E_QL_ERROR_GENERIC;
731 }
732 return 0;
733}
734
735//VTS API
736int QL_Voice_Call_Dtmf(voice_client_handle_type h_voice, uint8_t digit, int call_id)
737{
738 static struct ubus_request req;
739 struct ql_call_ubus_t *voice_call_ubus = (struct ql_call_ubus_t *)h_voice;
740 static struct blob_buf b;
741 int ret;
742 char code = digit;
743
744 if(h_voice == NULL || ql_call_ubus == NULL)
745 {
746 printf("ARG error or not inited.");
747 return -1;
748 }
749 rilutil_makeRequestBlob(&b, RIL_REQUEST_DTMF, &code, 0);
750 ret = ubus_invoke(voice_call_ubus->ctx, voice_call_ubus->ril_request_id, "ril_request", b.head, ql_call_requset_cb, 0,0);
751 if(ret != 0)
752 {
753 printf("ql call, ubus_invoke Failed %s", ubus_strerror(ret));
754 return E_QL_ERROR_GENERIC;
755 }
756 return 0;
757}
758
759int QL_Voice_Call_GetCallStatus
760(
761 int h_voice,
762 int call_id, // If call_id<0, means to get all calls state, or get specified call_id info
763 ql_mcm_voice_calls_state_t *pt_callstate
764)
765{
766 struct ql_call_ubus_t *voice_call_ubus = (struct ql_call_ubus_t *)h_voice;
767
768 if(h_voice == NULL || ql_call_ubus == NULL)
769 {
770 printf("ARG error or not inited.");
771 return -1;
772 }
773 memcpy((void *)pt_callstate, &voice_call_ubus->call_state, sizeof(ql_mcm_voice_calls_state_t));
774 return 0;
775}
776
777//Set forwarding
778int QL_Voice_Call_SetForwarding
779(
780 int h_voice,
781 E_QL_MCM_VOICE_CALL_SERVICE_T service,
782 E_QL_MCM_VOICE_CALL_FORWARDING_REASON_T reason,
783 char *number
784)
785{
786
787 return 0;
788}
789
790//Get forwarding status
791int QL_Voice_Call_GetForwardingStatus(
792 int h_voice,
793 E_QL_MCM_VOICE_CALL_FORWARDING_REASON_T reason,
794 ql_mcm_voice_call_forwarding_status_list_t *pt_status)
795{
796
797 return 0;
798}
799
800
801//Set voice call waiting
802int QL_Voice_Call_SetWaiting
803(
804 int h_voice,
805 ql_mcm_voice_call_waiting_service_t e_service
806)
807{
808// RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND
809 return 0;
810}
811
812//Get voice call waiting status
813int QL_Voice_Call_GetWaitingStatus
814(
815 int h_voice,
816 ql_mcm_voice_call_waiting_service_t *pe_service
817)
818{
819
820 return 0;
821}