blob: 80f9578278016caa11b778adf09c99129cbd4ff5 [file] [log] [blame]
b.liud440f9f2025-04-18 10:44:31 +08001/*-----------------------------------------------------------------------------------------------*/
2/**
3 @file ql_voice.h
4 @brief Voice service API.
5*/
6/*-----------------------------------------------------------------------------------------------*/
7
8/*-------------------------------------------------------------------------------------------------
9 Copyright (c) 2019 Quectel Wireless Solution, Co., Ltd. All Rights Reserved.
10 Quectel Wireless Solution Proprietary and Confidential.
11-------------------------------------------------------------------------------------------------*/
12
13/*-------------------------------------------------------------------------------------------------
14 EDIT HISTORY
15 This section contains comments describing changes made to the file.
16 Notice that changes are listed in reverse chronological order.
17 $Header: $
18 when who what, where, why
19 -------- --- ----------------------------------------------------------
20 20210622 Rambo.shan Added Voice DSDA API.
21 20210203 Rambo.shan Added Voice bind API for DSDA.
22 20210104 Rambo.shan Added DTMF event indication.
23 20200928 Rambo.shan Added eCall set option of T3.
24 20200907 Rambo.shan Added SETUP voice state.
25 20200622 Rambo.shan Add eCall auto answer function
26 20191225 solomon.cui Modify fucntion description.
27 20191111 solomon.cui Add eCall APIs.
28 20190815 solomon.cui Add service type for sending message.
29 20190625 solomon.cui Created.
30-------------------------------------------------------------------------------------------------*/
31#include "mbtk_type.h"
32#include "mbtk_ril_api.h"
33#include "mbtk_log.h"
34#include "ql_voice.h"
35#include "ql_type.h"
36
37#include <stdint.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <sys/epoll.h>
41#include <unistd.h>
42#include <errno.h>
43#include <pthread.h>
44#include <string.h>
45#include <fcntl.h>
46#include <time.h>
47
48#define MBTK_ERR_OK 0
49
50typedef struct {
51 mbtk_ril_handle* handle;
52 int state_t;
53 ql_voice_record_array_t record_array;
54 ql_voice_call_cb_f call_cb;
55 ql_voice_service_error_cb_f server_cb;
56}ql_voice_info_handle_t;
57
58
59static ql_voice_info_handle_t* voice_handle = NULL;
60
61
62typedef struct {
63 mbtk_voice_end_reason_enum mbtk_end_reason;
64 QL_VOICE_END_REASON_E ql_end_reason;
65}end_reason_t;
66
67
68
69end_reason_t g_end_reason[] = {
70{MBTK_VOICE_END_REASON_UNASSIGNED_NUMBER, QL_VOICE_END_REASON_UNASSIGNED_NUMBER},
71{MBTK_VOICE_END_REASON_NO_ROUTE_DES, QL_VOICE_END_REASON_NO_ROUTE_TO_DESTINATION},
72{MBTK_VOICE_END_REASON_CHANNEL_UNACCEPTABLE, QL_VOICE_END_REASON_CHANNEL_UNACCEPTABLE},
73{MBTK_VOICE_END_REASON_OPERATOR_DETERMINED_BARRING, QL_VOICE_END_REASON_OPERATOR_DETERMINED_BARRING},
74{MBTK_VOICE_END_REASON_NORMAL_CALL_CLEARING, QL_VOICE_END_REASON_NORMAL_CALL_CLEARING},
75{MBTK_VOICE_END_REASON_USER_BUSY, QL_VOICE_END_REASON_USER_BUSY},
76
77{MBTK_VOICE_END_REASON_NO_USER_RESPONDING, QL_VOICE_END_REASON_NO_USER_RESPONDING},
78{MBTK_VOICE_END_REASON_USER_ALERTING_NO_ANSWER, QL_VOICE_END_REASON_USER_ALERTING_NO_ANSWER},
79{MBTK_VOICE_END_REASON_CALL_REJECTED, QL_VOICE_END_REASON_CALL_REJECTED},
80{MBTK_VOICE_END_REASON_NUMBER_CHANGED, QL_VOICE_END_REASON_NUMBER_CHANGED},
81{MBTK_VOICE_END_REASON_PREEMPTION, QL_VOICE_END_REASON_PREEMPTION},
82{MBTK_VOICE_END_REASON_NON_SELECTED_USER_CLEARING, QL_VOICE_END_REASON_NONE},
83{MBTK_VOICE_END_REASON_DESTINATION_OUT_OF_ORDER, QL_VOICE_END_REASON_DESTINATION_OUT_OF_ORDER},
84{MBTK_VOICE_END_REASON_INVALID_NUMBER_FORMAT, QL_VOICE_END_REASON_INVALID_NUMBER_FORMAT},
85{MBTK_VOICE_END_REASON_FACILITY_REJECTED, QL_VOICE_END_REASON_FACILITY_REJECTED},
86{MBTK_VOICE_END_REASON_STATUS_ENQUIRY, QL_VOICE_END_REASON_RESP_TO_STATUS_ENQUIRY},
87{MBTK_VOICE_END_REASON_NORMAL_UNSPECIFIED, QL_VOICE_END_REASON_NORMAL_UNSPECIFIED},
88{MBTK_VOICE_END_REASON_NO_CIRCUIT_AVAILABLE, QL_VOICE_END_REASON_NO_CIRCUIT_OR_CHANNEL_AVAILABLE},
89{MBTK_VOICE_END_REASON_NETWORK_OUT_OF_ORDER, QL_VOICE_END_REASON_NETWORK_OUT_OF_ORDER},
90{MBTK_VOICE_END_REASON_TEMPORARY_FAILURE, QL_VOICE_END_REASON_TEMPORARY_FAILURE},
91{MBTK_VOICE_END_REASON_SWITCHING_EQUIPMENT_CONGESTION, QL_VOICE_END_REASON_SWITCHING_EQUIPMENT_CONGESTION},
92{MBTK_VOICE_END_REASON_ACCESS_INFORMATION_DISCARDED, QL_VOICE_END_REASON_ACCESS_INFORMATION_DISCARDED},
93{MBTK_VOICE_END_REASON_REQUESTED_CIRCUIT_UNAVAILABLE, QL_VOICE_END_REASON_REQUESTED_CIRCUIT_OR_CHANNEL_NOT_AVAILABLE},
94
95{MBTK_VOICE_END_REASON_SERVICE_NOT_AVAILABLE, QL_VOICE_END_REASON_SERVICE_OPTION_NOT_AVAILABLE},
96
97{MBTK_VOICE_END_REASON_END, QL_VOICE_END_REASON_NONE}
98
99};
100
101
l.yange4f94f42025-04-29 18:08:39 -0700102/*
b.liud440f9f2025-04-18 10:44:31 +0800103 static int end_reason_mbtk_to_ql(char* mbtk_reason, int* ql_reason)
104{
105 int bufefer_i = 0;
106 *ql_reason = QL_VOICE_END_REASON_NONE;
107
108 bufefer_i = atoi(mbtk_reason);
109
110 for(int i = 0; g_end_reason[i].mbtk_end_reason != MBTK_VOICE_END_REASON_END; i++)
111 {
112 if(bufefer_i == g_end_reason[i].mbtk_end_reason)
113 {
114 *ql_reason = g_end_reason[i].ql_end_reason;
115 break;
116 }
117 }
118
119 return 0;
120}
l.yange4f94f42025-04-29 18:08:39 -0700121*/
b.liud440f9f2025-04-18 10:44:31 +0800122
l.yange4f94f42025-04-29 18:08:39 -0700123static mbtk_sim_type_enum s_voice_slot = MBTK_SIM_1;
q.huange45908b2025-06-06 11:13:51 +0800124static mbtk_sim_type_enum urc_voice_slot = MBTK_SIM_1;
l.yange4f94f42025-04-29 18:08:39 -0700125
126static bool check_slot_valid(QL_SIM_SLOT_E slot)
127{
128 if (slot !=QL_SIM_SLOT_1 && slot != QL_SIM_SLOT_2)
129 {
130 LOG("bad slot: %d, slot should be 1 or 2", slot);
131 return false;
132 }
133
134 return true;
135}
136
137static void ql_slot_convert_to_mbtk(QL_SIM_SLOT_E ql_slot,mbtk_sim_type_enum *mbtk_slot)
138{
139 if(ql_slot == QL_SIM_SLOT_1)
140 {
141 *mbtk_slot = MBTK_SIM_1;
142 }
143
144 if(ql_slot == QL_SIM_SLOT_2)
145 {
146 *mbtk_slot = MBTK_SIM_2;
147 }
148 return;
149
150}
151
152int ql_set_voice_slot(QL_SIM_SLOT_E log_slot)
153{
154 if(!check_slot_valid(log_slot))
155 {
156 LOG("[%s] check_slot_valid failed.", __func__);
157 return QL_ERR_INVALID_ARG;
158 }
159 ql_slot_convert_to_mbtk(log_slot,&s_voice_slot);
160 LOG("s_net_slot is %d",s_voice_slot);
161 return QL_ERR_OK;
162}
b.liud440f9f2025-04-18 10:44:31 +0800163
164static void ql_voice_state_change_cb(const void* data, int data_len)
165{
166 if(NULL == data)
167 {
168 LOGE("[ql_voice_state_change_cb] data is null.");
169 return;
170 }
171
172 if(voice_handle->call_cb == NULL) {
173 LOGW("voice_state_change_cb not set.");
174 return;
175 }
176
l.yange4f94f42025-04-29 18:08:39 -0700177 mbtk_ril_call_state_info_t *reg = (mbtk_ril_call_state_info_t *)data;
b.liud440f9f2025-04-18 10:44:31 +0800178
179 int ql_reason = 0;
l.yange4f94f42025-04-29 18:08:39 -0700180 //end_reason_mbtk_to_ql((char*)reg->end_reason, &ql_reason);
b.liud440f9f2025-04-18 10:44:31 +0800181 LOG("ql_voice_state_change_cb ql_reason:%d", ql_reason);
182
183
184 if(MBTK_RIL_CALL_STATE_DISCONNECT != reg->state)
185 {
q.huange45908b2025-06-06 11:13:51 +0800186 LOG("ql_voice_state_change_cb : %d, %d, %d, %d, %d, %s", reg->sim_id, reg->call_id, reg->dir, reg->state, reg->num_type, reg->call_number);
187 printf("ql_voice_state_change_cb : %d\n", reg->sim_id);
b.liud440f9f2025-04-18 10:44:31 +0800188 switch(reg->state)
189 {
q.huange45908b2025-06-06 11:13:51 +0800190 case MBTK_RIL_CALL_STATE_ACTIVE:
b.liud440f9f2025-04-18 10:44:31 +0800191 voice_handle->state_t = QL_VOICE_STATE_ACTIVE;
q.huange45908b2025-06-06 11:13:51 +0800192 urc_voice_slot=reg->sim_id;
b.liud440f9f2025-04-18 10:44:31 +0800193 break;
q.huange45908b2025-06-06 11:13:51 +0800194 case MBTK_RIL_CALL_STATE_HELD:
b.liud440f9f2025-04-18 10:44:31 +0800195 voice_handle->state_t = QL_VOICE_STATE_HOLDING;
q.huange45908b2025-06-06 11:13:51 +0800196 urc_voice_slot=reg->sim_id;
b.liud440f9f2025-04-18 10:44:31 +0800197 break;
q.huange45908b2025-06-06 11:13:51 +0800198 case MBTK_RIL_CALL_STATE_DIALING:
b.liud440f9f2025-04-18 10:44:31 +0800199 voice_handle->state_t = QL_VOICE_STATE_DIALING;
q.huange45908b2025-06-06 11:13:51 +0800200 urc_voice_slot=reg->sim_id;
b.liud440f9f2025-04-18 10:44:31 +0800201 break;
q.huange45908b2025-06-06 11:13:51 +0800202 case MBTK_RIL_CALL_STATE_ALERTING:
b.liud440f9f2025-04-18 10:44:31 +0800203 voice_handle->state_t = QL_VOICE_STATE_ALERTING;
q.huange45908b2025-06-06 11:13:51 +0800204 urc_voice_slot=reg->sim_id;
b.liud440f9f2025-04-18 10:44:31 +0800205 break;
q.huange45908b2025-06-06 11:13:51 +0800206 case MBTK_RIL_CALL_STATE_INCOMING:
b.liud440f9f2025-04-18 10:44:31 +0800207 voice_handle->state_t = QL_VOICE_STATE_INCOMING;
q.huange45908b2025-06-06 11:13:51 +0800208 urc_voice_slot=reg->sim_id;
b.liud440f9f2025-04-18 10:44:31 +0800209 break;
q.huange45908b2025-06-06 11:13:51 +0800210 case MBTK_RIL_CALL_STATE_WAITING:
b.liud440f9f2025-04-18 10:44:31 +0800211 voice_handle->state_t = QL_VOICE_STATE_WAITING;
q.huange45908b2025-06-06 11:13:51 +0800212 urc_voice_slot=reg->sim_id;
b.liud440f9f2025-04-18 10:44:31 +0800213 break;
q.huange45908b2025-06-06 11:13:51 +0800214 case MBTK_RIL_CALL_STATE_DISCONNECT:
b.liud440f9f2025-04-18 10:44:31 +0800215 voice_handle->state_t = QL_VOICE_STATE_END;
216 break;
l.yange4f94f42025-04-29 18:08:39 -0700217 default:
218 break;
b.liud440f9f2025-04-18 10:44:31 +0800219 }
220
l.yange4f94f42025-04-29 18:08:39 -0700221 if (voice_handle->record_array.records[0].id == 0 || voice_handle->record_array.records[0].id == reg->call_id)
b.liud440f9f2025-04-18 10:44:31 +0800222 {
223 voice_handle->record_array.len = 1;
l.yange4f94f42025-04-29 18:08:39 -0700224 voice_handle->record_array.records[0].id = reg->call_id;
b.liud440f9f2025-04-18 10:44:31 +0800225 voice_handle->record_array.records[0].tech = 1;
226 voice_handle->record_array.records[0].dir = reg->dir;
227 voice_handle->record_array.records[0].end_reason = ql_reason;
228 voice_handle->record_array.records[0].state = voice_handle->state_t;
l.yange4f94f42025-04-29 18:08:39 -0700229 memcpy(voice_handle->record_array.records[0].number, reg->call_number, strlen((char *)reg->call_number));
b.liud440f9f2025-04-18 10:44:31 +0800230 }
l.yange4f94f42025-04-29 18:08:39 -0700231 else if (voice_handle->record_array.records[0].id != reg->call_id)
b.liud440f9f2025-04-18 10:44:31 +0800232 {
233 voice_handle->record_array.len = 2;
l.yange4f94f42025-04-29 18:08:39 -0700234 voice_handle->record_array.records[1].id = reg->call_id;
b.liud440f9f2025-04-18 10:44:31 +0800235 voice_handle->record_array.records[1].tech = 1;
236 voice_handle->record_array.records[1].dir = reg->dir;
237 voice_handle->record_array.records[1].end_reason = ql_reason;
238 voice_handle->record_array.records[1].state = voice_handle->state_t;
l.yange4f94f42025-04-29 18:08:39 -0700239 memcpy(voice_handle->record_array.records[1].number, reg->call_number, strlen((char *)reg->call_number));
b.liud440f9f2025-04-18 10:44:31 +0800240 }
241
242 voice_handle->call_cb(&voice_handle->record_array);
243 }
244 else
245 {
246 LOGI("RING : call dis connected!");
247 voice_handle->record_array.records[0].end_reason = ql_reason;
248 voice_handle->record_array.records[1].end_reason = ql_reason;
l.yange4f94f42025-04-29 18:08:39 -0700249 if(voice_handle->record_array.records[0].id == reg->call_id)
b.liud440f9f2025-04-18 10:44:31 +0800250 {
251 voice_handle->record_array.records[0].state = QL_VOICE_STATE_END;
252 voice_handle->record_array.records[0].id = 0;
253 }
l.yange4f94f42025-04-29 18:08:39 -0700254 if(voice_handle->record_array.records[1].id == reg->call_id)
b.liud440f9f2025-04-18 10:44:31 +0800255 {
256 voice_handle->record_array.records[1].state = QL_VOICE_STATE_END;
257 voice_handle->record_array.records[1].id = 0;
258 voice_handle->record_array.len = 1;
259 }
l.yange4f94f42025-04-29 18:08:39 -0700260 if (reg->call_id == voice_handle->record_array.records[1].id)
b.liud440f9f2025-04-18 10:44:31 +0800261 voice_handle->call_cb(&voice_handle->record_array);
262 else
263 voice_handle->call_cb(&voice_handle->record_array);
264 }
265
266}
267
268static void ql_voice_server_change_cb(const void* data, int data_len)
269{
l.yange4f94f42025-04-29 18:08:39 -0700270 if(data)
b.liud440f9f2025-04-18 10:44:31 +0800271 {
l.yange4f94f42025-04-29 18:08:39 -0700272 mbtk_ril_ser_state_enum server_state = *(mbtk_ril_ser_state_enum *)data;
273 if(voice_handle->server_cb && server_state == MBTK_RIL_SER_STATE_EXIT)
b.liud440f9f2025-04-18 10:44:31 +0800274 {
275 voice_handle->server_cb(QL_ERR_ABORTED);
276 }
277 }
278}
279
280
281/*-----------------------------------------------------------------------------------------------*/
282/**
283 @brief Initializes voice service.
284 @return Whether the voice service was initialized successfully.
285 @retval QL_ERR_OK successful.
286 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
287 @retval Other error code defined by ql_type.h.
288 */
289/*-----------------------------------------------------------------------------------------------*/
290int ql_voice_init(void)
291{
292 if(NULL == voice_handle)
293 {
294 voice_handle = (ql_voice_info_handle_t*)malloc(sizeof(ql_voice_info_handle_t));
295 memset(voice_handle, 0, sizeof(ql_voice_info_handle_t));
296 voice_handle->record_array.records[0].id = 0;
297 if(NULL == voice_handle)
298 {
299 LOGE("[ql_voice_init] voice handle malloc fail.");
300 return QL_ERR_FAILED;
301 }
302
l.yange4f94f42025-04-29 18:08:39 -0700303 voice_handle->handle = mbtk_ril_open(MBTK_AT_PORT_VOICE);
b.liud440f9f2025-04-18 10:44:31 +0800304 if(NULL == voice_handle->handle)
305 {
306 LOGE("[ql_voice_init] mbtk handle init fail.");
307 if(voice_handle)
308 {
309 free(voice_handle);
310 voice_handle = NULL;
311 return QL_ERR_FAILED;
312 }
313 }
314
l.yange4f94f42025-04-29 18:08:39 -0700315 int ret = mbtk_ds_call_state_change_cb_reg(MBTK_SIM_1,ql_voice_state_change_cb);
b.liud440f9f2025-04-18 10:44:31 +0800316 if(ret != MBTK_ERR_OK)
317 {
318 LOGE("[ql_voice_init] set voice state cb fail.[%d]", ret);
319 if(voice_handle->handle)
320 {
l.yange4f94f42025-04-29 18:08:39 -0700321 mbtk_ril_close(MBTK_AT_PORT_VOICE);
322 voice_handle->handle = NULL;
323 return QL_ERR_FAILED;
324 }
325 }
326 ret = mbtk_ds_call_state_change_cb_reg(MBTK_SIM_2,ql_voice_state_change_cb);
327 if(ret != MBTK_ERR_OK)
328 {
329 LOGE("[ql_voice_init] set voice state cb fail.[%d]", ret);
330 if(voice_handle->handle)
331 {
332 mbtk_ril_close(MBTK_AT_PORT_VOICE);
b.liud440f9f2025-04-18 10:44:31 +0800333 voice_handle->handle = NULL;
334 return QL_ERR_FAILED;
335 }
336 }
337
338 ret = mbtk_ril_ser_state_change_cb_reg(ql_voice_server_change_cb);
339 if(ret != MBTK_ERR_OK)
340 {
341 LOGE("[ql_sim_init] set sim server cb fail.[%d]", ret);
342 if(voice_handle->handle)
343 {
l.yange4f94f42025-04-29 18:08:39 -0700344 mbtk_ril_close(MBTK_AT_PORT_VOICE);
b.liud440f9f2025-04-18 10:44:31 +0800345 voice_handle->handle = NULL;
346 return QL_ERR_FAILED;
347 }
348 }
349
350 voice_handle->call_cb = NULL;
351 voice_handle->server_cb = NULL;
352 }
353 return QL_ERR_OK;
354}
355
356/*-----------------------------------------------------------------------------------------------*/
357/**
358 @brief Deinitializes voice service.
359 @return Whether the voice service was deinitialized successfully.
360 @retval QL_ERR_OK successful.
361 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
362 @retval Other error code defined by ql_type.h.
363 */
364/*-----------------------------------------------------------------------------------------------*/
365int ql_voice_deinit(void)
366{
367 if(NULL == voice_handle)
368 {
369 LOGE("[ql_voice_deinit] voice handle not init.");
370 return QL_ERR_NOT_INIT;
371 }
372
373 int ret = 0;
374 voice_handle->server_cb = NULL;
375 voice_handle->call_cb = NULL;
376
377 if(NULL != voice_handle->handle)
378 {
l.yange4f94f42025-04-29 18:08:39 -0700379 ret = mbtk_ril_close(MBTK_AT_PORT_VOICE);
b.liud440f9f2025-04-18 10:44:31 +0800380 if(ret != MBTK_ERR_OK)
381 {
382 LOGE("[ql_voice_deinit] mbtk handle deinit fail.[%d]", ret);
383 return QL_ERR_FAILED;
384 }
385 voice_handle->handle = NULL;
386 }
387
388 if(ret != QL_ERR_OK)
389 {
390 LOGE("[ql_voice_deinit] cb thread free deinit fail.");
391 return QL_ERR_FAILED;
392 }
393
394 free(voice_handle);
395 voice_handle = NULL;
396 return QL_ERR_OK;
397}
398
399/*-----------------------------------------------------------------------------------------------*/
400/**
401 @brief Dials a call.
402 @param[in] num phone number to dial.
403 @param[in] len length of phone number, should be less than
404 or euqnal to QL_VOICE_MAX_PHONE_NUMBER.
405 @param[out] id call id.
406 @return Whether a voice call was successfully dialed.
407 @retval QL_ERR_OK successful.
408 @retval QL_ERR_INVALID_ARG invalid argument.
409 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
410 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
411 @retval Other error code defined by ql_type.h.
412 */
413/*-----------------------------------------------------------------------------------------------*/
414int ql_voice_dial(char *num, int len, uint32_t *id)
415{
416 char* phone_num_t = NULL;
417 mbtk_call_info_t reg = {0};
418 int err;
419
420 if(voice_handle->handle == NULL)
421 {
422 LOGE("ql_voice_call_start call_info_handle NULL");
423 return QL_ERR_FAILED;
424 }
425
426 if (num == NULL)
427 {
428 LOGE("ql_voice_call_start phone_number NULL");
429 return QL_ERR_FAILED;
430
431 }
432
433 phone_num_t = num;
434
l.yange4f94f42025-04-29 18:08:39 -0700435 err = mbtk_ds_call_start(voice_handle->handle, s_voice_slot,phone_num_t);
b.liud440f9f2025-04-18 10:44:31 +0800436 if(err)
437 {
438 LOGE("Error : %d\n", err);
439 return QL_ERR_FAILED;
440 }
441 else
442 {
443 LOGI("Call success.");
444 }
445
l.yange4f94f42025-04-29 18:08:39 -0700446 mbtk_ds_call_reg_get(voice_handle->handle, s_voice_slot,&reg);
b.liud440f9f2025-04-18 10:44:31 +0800447 *id = reg.dir1;
448 LOG("ql_voice_dial call_id: %d\n", reg.dir1, *id);
449
450 return QL_ERR_OK;
451}
452
453/*-----------------------------------------------------------------------------------------------*/
454/**
455 @brief Cancels dialing with given id.
456 @param[in] id call id returned from dial.
457 @return Whether the voice call was successfully cancelled.
458 @retval QL_ERR_OK successful.
459 @retval QL_ERR_INVALID_ARG invalid argument.
460 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
461 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
462 @retval Other error code defined by ql_type.h.
463 */
464/*-----------------------------------------------------------------------------------------------*/
465int ql_voice_cancel_dial(uint32_t id);
466
467/*-----------------------------------------------------------------------------------------------*/
468/**
469 @brief hangup all dialing.
470 @return Whether all voice call were successfully hangup.
471 @retval QL_ERR_OK successful.
472 @retval QL_ERR_INVALID_ARG invalid argument.
473 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
474 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
475 @retval Other error code defined by ql_type.h.
476 */
477/*-----------------------------------------------------------------------------------------------*/
478int ql_voice_hangup_all(void)
479{
480 int err;
481
482 if(voice_handle->handle == NULL)
483 {
484 LOGE("ql_voice_call_end call_info_handle NULL");
485 return QL_ERR_FAILED;
486 }
487
q.huange45908b2025-06-06 11:13:51 +0800488 err = mbtk_ds_call_hang(voice_handle->handle,urc_voice_slot);
b.liud440f9f2025-04-18 10:44:31 +0800489 if(err)
490 {
491 LOGE("Error : %d", err);
492 return QL_ERR_FAILED;
493 }
494 else
495 {
496 LOGI("Call hang up a all.");
497 }
498 return QL_ERR_OK;
499}
500
501/*-----------------------------------------------------------------------------------------------*/
502/**
503 @brief Answers the call.
504 @param[in] id call id returned from dial.
505 @return Whether the voice call was successfully answered.
506 @retval QL_ERR_OK successful.
507 @retval QL_ERR_INVALID_ARG invalid argument.
508 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
509 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
510 @retval Other error code defined by ql_type.h.
511 */
512/*-----------------------------------------------------------------------------------------------*/
513int ql_voice_answer(uint32_t id)
514{
515 int err;
516
517 if(voice_handle->handle == NULL)
518 {
519 LOGE("ql_voice_call_anser call_info_handle NULL");
520 return QL_ERR_FAILED;
521 }
522
q.huange45908b2025-06-06 11:13:51 +0800523 err = mbtk_ds_call_answer(voice_handle->handle,urc_voice_slot);
b.liud440f9f2025-04-18 10:44:31 +0800524 if(err)
525 {
526 LOGE("Error : %d", err);
527 return QL_ERR_FAILED;
528 }
529 else
530 {
531 LOGI("Answer success.");
532 }
533 return QL_ERR_OK;
534}
535
536/*-----------------------------------------------------------------------------------------------*/
537/**
538 @brief Hangs up the call.
539 @param[in] id call id returned from dial.
540 @return Whether the voice call was successfully hung up.
541 @retval QL_ERR_OK successful.
542 @retval QL_ERR_INVALID_ARG invalid argument.
543 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
544 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
545 @retval Other error code defined by ql_type.h.
546 */
547/*-----------------------------------------------------------------------------------------------*/
q.huang6bf00742025-08-25 16:00:07 +0800548int ql_voice_hangup(uint32_t id)
549{
550 ql_auto_answer_thread_free(voice_handle,0);
551
552 if(voice_handle->handle == NULL)
553 {
554 LOGE("ql_voice_call_end call_info_handle NULL");
555 return QL_ERR_FAILED;
556 }
557
558 int err = mbtk_a_call_hang(voice_handle->handle,id);
559 if(err)
560 {
561 LOGE("Error : %d", err);
562 return QL_ERR_FAILED;
563 }
564 else
565 {
566 LOGI("Call hang up %d suc.",id);
567 }
568 return QL_ERR_OK;
569
570}
b.liud440f9f2025-04-18 10:44:31 +0800571
572/*-----------------------------------------------------------------------------------------------*/
573/**
574 @brief Holds the call when mutil calls is activated.
575 @param[in] id call id returned from dial.
576 @return Whether the voice call was successfully held.
577 @retval QL_ERR_OK successful.
578 @retval QL_ERR_INVALID_ARG invalid argument.
579 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
580 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
581 @retval Other error code defined by ql_type.h.
582 */
583/*-----------------------------------------------------------------------------------------------*/
584int ql_voice_hold(uint32_t id);
585
586/*-----------------------------------------------------------------------------------------------*/
587/**
588 @brief Releases the call from hold when mutil calls is activated.
589 @param[in] id call id returned from dial.
590 @return Whether the voice call was successfully unheld.
591 @retval QL_ERR_OK successful.
592 @retval QL_ERR_INVALID_ARG invalid argument.
593 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
594 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
595 @retval Other error code defined by ql_type.h.
596 */
597/*-----------------------------------------------------------------------------------------------*/
598int ql_voice_unhold(uint32_t id);
599
600/*-----------------------------------------------------------------------------------------------*/
601/**
602 @brief Gets call records.
603 @param[in] p_arr pointer to ql_voice_record_array_t.
604 @return Whether the call records were successfully obtained.
605 @retval QL_ERR_OK successful.
606 @retval QL_ERR_INVALID_ARG invalid argument.
607 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
608 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
609 @retval Other error code defined by ql_type.h.
610 */
611/*-----------------------------------------------------------------------------------------------*/
612int ql_voice_get_records(ql_voice_record_array_t *p_arr)
613{
614 if(NULL == p_arr)
615 {
616 LOGE("ql_voice_get_records p_arr NULL");
617 return QL_ERR_FAILED;
618 }
619 memcpy(p_arr, &voice_handle->record_array, sizeof(voice_handle->record_array));
620
621 return QL_ERR_OK;
622}
623
624/*-----------------------------------------------------------------------------------------------*/
625/**
626 @brief Registers or Unregisters forwarding.
627 @param[in] reg 0 - unregister, 1 - register.
628 @param[in] cond forwarding condition.
629 @param[in] num phone number.
630 @param[in] len length of phone numebr.
631 @return Whether the voice call forward was registered or unregistered successfully.
632 @retval QL_ERR_OK successful.
633 @retval QL_ERR_INVALID_ARG invalid argument.
634 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
635 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
636 @retval Other error code defined by ql_type.h.
637 */
638/*-----------------------------------------------------------------------------------------------*/
639int ql_voice_forwarding(int reg, QL_VOICE_FW_COND_E cond, char *num, int len);
640
641/*-----------------------------------------------------------------------------------------------*/
642/**
643 @brief Gets forwarding status.
644 @param[in] cond forwarding condition.
645 @param[out] p_status pointer to ql_voice_fw_status_t.
646 @return Whether the voice call forward status was successfully obtained.
647 @retval QL_ERR_OK successful.
648 @retval QL_ERR_INVALID_ARG invalid argument.
649 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
650 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
651 @retval Other error code defined by ql_type.h.
652 */
653/*-----------------------------------------------------------------------------------------------*/
654int ql_voice_get_forwarding_status(QL_VOICE_FW_COND_E cond, ql_voice_fw_status_t *p_status);
655
656/*-----------------------------------------------------------------------------------------------*/
657/**
658 @brief Enables or disables call waiting.
659 @param[in] enable 0 - disable, other - enable.
660 @return Whether the voice call waiting was enabled or disabled successfully.
661 @retval QL_ERR_OK successful.
662 @retval QL_ERR_INVALID_ARG invalid argument.
663 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
664 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
665 @retval Other error code defined by ql_type.h.
666 */
667/*-----------------------------------------------------------------------------------------------*/
668int ql_voice_waiting(int enable);
669
670/*-----------------------------------------------------------------------------------------------*/
671/**
672 @brief Gets call waiting status.
673 @param[out] enabled 0 - waiting is disabled, 1 - waiting is enabled.
674 @return Whether the voice call waiting status was successfully obtained.
675 @retval QL_ERR_OK successful.
676 @retval QL_ERR_INVALID_ARG invalid argument.
677 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
678 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
679 @retval Other error code defined by ql_type.h.
680 */
681/*-----------------------------------------------------------------------------------------------*/
682int ql_voice_get_waiting_status(int *enabled);
683
684/*-----------------------------------------------------------------------------------------------*/
685/**
686 @brief Enables or disables auto answer.
687 @param[in] enable 0 - disable, other - enable.
688 @param[in] sec wait this `sec' seconds before auto answer.
689 @return Whether the voice call autoanswer was enabled or disabled successfully.
690 @retval QL_ERR_OK successful.
691 @retval QL_ERR_INVALID_ARG invalid argument.
692 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
693 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
694 @retval Other error code defined by ql_type.h.
695 */
696/*-----------------------------------------------------------------------------------------------*/
697int ql_voice_autoanswer(int enable, uint32_t sec);
698
699/*-----------------------------------------------------------------------------------------------*/
700/**
701 @brief Sends a DTMF(Dual Tone Multi Frequency) character over the call ID.
702 @param[in] id call id returned from dial.
703 @param[in] c DTMF character to be sent. Valid DTMF characters are 0-9, A-D, '*', '#'.
704 @return Whether a DTMF character was successfully sent.
705 @retval QL_ERR_OK successful.
706 @retval QL_ERR_INVALID_ARG invalid argument.
707 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
708 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
709 @retval Other error code defined by ql_type.h.
710 */
711/*-----------------------------------------------------------------------------------------------*/
712int ql_voice_send_dtmf_char(uint32_t id, char c)
713{
714 int ret = 0;
715 int tmp;
716 char callnum_c;
717 mbtk_call_dtmf_info_t *dtmf = NULL;
718
719 if(voice_handle->handle == NULL)
720 {
721 LOGE("ql_voice_set_dtmf call_info_handle NULL");
722 return QL_ERR_FAILED;
723 }
724
725 dtmf = (mbtk_call_dtmf_info_t*)malloc(sizeof(mbtk_call_dtmf_info_t));
726 memset(dtmf,0x00, sizeof(mbtk_call_dtmf_info_t));
727
728 tmp = (int)c;
729
730 callnum_c = c;
731
732 if ((tmp >= 48 && tmp <= 57) || (tmp >= 65 && tmp <= 68) || (tmp == 42) || (tmp == 35))
733 {
734 dtmf->duration = 300;
735 dtmf->character = callnum_c;
736
l.yange4f94f42025-04-29 18:08:39 -0700737 ret = mbtk_ds_dtmf_send(voice_handle->handle,s_voice_slot, dtmf);
b.liud440f9f2025-04-18 10:44:31 +0800738 if (ret)
739 {
740 LOGE("mbtk_dtmf_send Error : %d", ret);
741 ret = QL_ERR_FAILED;
742 goto err;
743 }
744 }
745 else
746 {
747 LOGE("ql_voice_set_dtmf callnum demand ERR");
748 ret = QL_ERR_FAILED;
749 goto err;
750 }
751
752err:
753 free(dtmf);
754 return ret;
755
756}
757
758/*-----------------------------------------------------------------------------------------------*/
759/**
760 @brief Sets voice call callback handler.
761 @param[in] cb call back handler.
762 @return Whether the voice call callback handler was successfully set.
763 @retval QL_ERR_OK successful.
764 @retval QL_ERR_INVALID_ARG invalid argument.
765 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
766 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
767 @retval Other error code defined by ql_type.h.
768 */
769/*-----------------------------------------------------------------------------------------------*/
770int ql_voice_set_call_cb(ql_voice_call_cb_f cb)
771{
772 if(NULL == voice_handle)
773 {
774 LOGE("[ql_voice_set_msg_recv_cb] voice handle not init.");
775 return QL_ERR_NOT_INIT;
776 }
777
778 voice_handle->call_cb = cb;
779
780 return QL_ERR_OK;
781}
782
783/*-----------------------------------------------------------------------------------------------*/
784/**
785 @brief Sets voice dtmf callback handler.
786 @param[in] cb call back handler.
787 @return Whether the voice call DTMF repcetion callback handler was successfully set.
788 @retval QL_ERR_OK successful.
789 @retval QL_ERR_INVALID_ARG invalid argument.
790 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
791 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
792 @retval Other error code defined by ql_type.h.
793 */
794/*-----------------------------------------------------------------------------------------------*/
795int ql_voice_set_dtmf_cb(ql_voice_dtmf_cb_f cb);
796
797/*-----------------------------------------------------------------------------------------------*/
798/**
799 @brief Dials eCall.
800 @param[in] p_info eCall info.
801 @return Whether a eCall was successfully dialed.
802 @retval QL_ERR_OK successful.
803 @retval QL_ERR_INVALID_ARG invalid argument.
804 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
805 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
806 @retval Other error code defined by ql_type.h.
807 */
808/*-----------------------------------------------------------------------------------------------*/
809int ql_voice_ecall_dial(ql_voice_ecall_info_t *p_info);
810
811/*-----------------------------------------------------------------------------------------------*/
812/**
813 @brief Hangs up eCall.
814 @return Whether the eCall was successfully hung up.
815 @retval QL_ERR_OK successful.
816 @retval QL_ERR_INVALID_ARG invalid argument.
817 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
818 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
819 @retval Other error code defined by ql_type.h.
820 */
821/*-----------------------------------------------------------------------------------------------*/
822int ql_voice_ecall_hangup(void);
823
824/*-----------------------------------------------------------------------------------------------*/
825/**
826 @brief Updates eCall MSD.
827 @param[in] msd Minimum Set of Data.
828 @param[in] msd_len Length of Minimum Set of Data.
829 @return Whether the eCall MSD was successfully updated.
830 @retval QL_ERR_OK successful.
831 @retval QL_ERR_INVALID_ARG invalid argument.
832 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
833 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
834 @retval Other error code defined by ql_type.h.
835 */
836/*-----------------------------------------------------------------------------------------------*/
837int ql_voice_ecall_update_msd(const uint8_t *msd, uint32_t msd_len);
838
839/*-----------------------------------------------------------------------------------------------*/
840/**
841 @brief Pushes eCall MSD.
842 @param[out] state eCall state.
843 @return Whether the eCall MSD was successfully pushed.
844 @retval QL_ERR_OK successful.
845 @retval QL_ERR_INVALID_ARG invalid argument.
846 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
847 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
848 @retval Other error code defined by ql_type.h.
849 */
850/*-----------------------------------------------------------------------------------------------*/
q.huange8e9afa2025-08-15 18:38:35 +0800851int ql_voice_ecall_push_msd(QL_VOICE_ECALL_STATE_E *state)
852{
853 return 0;
854}
b.liud440f9f2025-04-18 10:44:31 +0800855
856/*-----------------------------------------------------------------------------------------------*/
857/**
858 @brief Gets eCall config.
859 @param[in] p_config eCall config.
860 @return Whether the eCall config was successfully obtained.
861 @retval QL_ERR_OK successful.
862 @retval QL_ERR_INVALID_ARG invalid argument.
863 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
864 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
865 @retval Other error code defined by ql_type.h.
866 */
867/*-----------------------------------------------------------------------------------------------*/
868int ql_voice_ecall_get_config(ql_voice_ecall_config_t *p_config);
869
870/*-----------------------------------------------------------------------------------------------*/
871/**
872 @brief Sets eCall config.
873 @param[in] item Items to set.
874 @param[in] p_config eCall config.
875 @return Whether the eCall config was successfully set.
876 @retval QL_ERR_OK successful.
877 @retval QL_ERR_INVALID_ARG invalid argument.
878 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
879 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
880 @retval Other error code defined by ql_type.h.
881 */
882/*-----------------------------------------------------------------------------------------------*/
883int ql_voice_ecall_set_config(int item, ql_voice_ecall_config_t *p_config);
884
885/*-----------------------------------------------------------------------------------------------*/
886/**
887 @brief Sets eCall event callback handler.
888 @param[in] cb call back handler.
889 @return Whether the eCall event callback handler was successfully set.
890 @retval QL_ERR_OK successful.
891 @retval QL_ERR_INVALID_ARG invalid argument.
892 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
893 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
894 @retval Other error code defined by ql_type.h.
895 */
896/*-----------------------------------------------------------------------------------------------*/
q.huange8e9afa2025-08-15 18:38:35 +0800897int ql_voice_ecall_set_event_cb(ql_voice_ecall_event_cb_f cb)
898{
899 return 0;
900}
b.liud440f9f2025-04-18 10:44:31 +0800901
902/*-----------------------------------------------------------------------------------------------*/
903/**
904 @brief Sets eCall status callback handler.
905 @param[in] cb call back handler.
906 @return Whether the eCall status callback handler was successfully set.
907 @retval QL_ERR_OK successful.
908 @retval QL_ERR_INVALID_ARG invalid argument.
909 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
910 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
911 @retval Other error code defined by ql_type.h.
912 */
913/*-----------------------------------------------------------------------------------------------*/
914int ql_voice_ecall_set_status_cb(ql_voice_ecall_status_cb_f cb);
915
916/*-----------------------------------------------------------------------------------------------*/
917/**
918 @brief Registration server error callback. Currently, only if the server exits abnormally,
919 the callback function will be executed, and the error code is QL_ERR_ABORTED;
920 @param[in] cb Callback function
921 @return
922 QL_ERR_OK - successful
923 Other - error code defined by ql_type.h
924 */
925/*-----------------------------------------------------------------------------------------------*/
926int ql_voice_set_service_error_cb(ql_voice_service_error_cb_f cb)
927{
928 if(NULL == voice_handle)
929 {
930 LOGE("[ql_voice_set_service_error_cb] voice handle not init.");
931 return QL_ERR_NOT_INIT;
932 }
933
934 voice_handle->server_cb = cb;
935
936 return QL_ERR_OK;
937}
938
939/*-----------------------------------------------------------------------------------------------*/
940/**
941 @brief Binds the current control point to a specific subscription.
942 @param[in] sub Subscription type.
943 @return Whether the subscription was successfully bound.
944 @retval QL_ERR_OK successful.
945 @retval QL_ERR_INVALID_ARG invalid argument.
946 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
947 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
948 @retval Other error code defined by ql_type.h.
949 */
950/*-----------------------------------------------------------------------------------------------*/
951//int ql_voice_bind_subscription(QL_VOICE_SUBSCRIPTION_E sub);
952
953