blob: 828ca6a85469b6a91dbb2ad61e6bec87f0cf76fd [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/*-----------------------------------------------------------------------------------------------*/
548int ql_voice_hangup(uint32_t id);
549
550/*-----------------------------------------------------------------------------------------------*/
551/**
552 @brief Holds the call when mutil calls is activated.
553 @param[in] id call id returned from dial.
554 @return Whether the voice call was successfully held.
555 @retval QL_ERR_OK successful.
556 @retval QL_ERR_INVALID_ARG invalid argument.
557 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
558 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
559 @retval Other error code defined by ql_type.h.
560 */
561/*-----------------------------------------------------------------------------------------------*/
562int ql_voice_hold(uint32_t id);
563
564/*-----------------------------------------------------------------------------------------------*/
565/**
566 @brief Releases the call from hold when mutil calls is activated.
567 @param[in] id call id returned from dial.
568 @return Whether the voice call was successfully unheld.
569 @retval QL_ERR_OK successful.
570 @retval QL_ERR_INVALID_ARG invalid argument.
571 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
572 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
573 @retval Other error code defined by ql_type.h.
574 */
575/*-----------------------------------------------------------------------------------------------*/
576int ql_voice_unhold(uint32_t id);
577
578/*-----------------------------------------------------------------------------------------------*/
579/**
580 @brief Gets call records.
581 @param[in] p_arr pointer to ql_voice_record_array_t.
582 @return Whether the call records were successfully obtained.
583 @retval QL_ERR_OK successful.
584 @retval QL_ERR_INVALID_ARG invalid argument.
585 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
586 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
587 @retval Other error code defined by ql_type.h.
588 */
589/*-----------------------------------------------------------------------------------------------*/
590int ql_voice_get_records(ql_voice_record_array_t *p_arr)
591{
592 if(NULL == p_arr)
593 {
594 LOGE("ql_voice_get_records p_arr NULL");
595 return QL_ERR_FAILED;
596 }
597 memcpy(p_arr, &voice_handle->record_array, sizeof(voice_handle->record_array));
598
599 return QL_ERR_OK;
600}
601
602/*-----------------------------------------------------------------------------------------------*/
603/**
604 @brief Registers or Unregisters forwarding.
605 @param[in] reg 0 - unregister, 1 - register.
606 @param[in] cond forwarding condition.
607 @param[in] num phone number.
608 @param[in] len length of phone numebr.
609 @return Whether the voice call forward was registered or unregistered successfully.
610 @retval QL_ERR_OK successful.
611 @retval QL_ERR_INVALID_ARG invalid argument.
612 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
613 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
614 @retval Other error code defined by ql_type.h.
615 */
616/*-----------------------------------------------------------------------------------------------*/
617int ql_voice_forwarding(int reg, QL_VOICE_FW_COND_E cond, char *num, int len);
618
619/*-----------------------------------------------------------------------------------------------*/
620/**
621 @brief Gets forwarding status.
622 @param[in] cond forwarding condition.
623 @param[out] p_status pointer to ql_voice_fw_status_t.
624 @return Whether the voice call forward status was successfully obtained.
625 @retval QL_ERR_OK successful.
626 @retval QL_ERR_INVALID_ARG invalid argument.
627 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
628 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
629 @retval Other error code defined by ql_type.h.
630 */
631/*-----------------------------------------------------------------------------------------------*/
632int ql_voice_get_forwarding_status(QL_VOICE_FW_COND_E cond, ql_voice_fw_status_t *p_status);
633
634/*-----------------------------------------------------------------------------------------------*/
635/**
636 @brief Enables or disables call waiting.
637 @param[in] enable 0 - disable, other - enable.
638 @return Whether the voice call waiting was enabled or disabled successfully.
639 @retval QL_ERR_OK successful.
640 @retval QL_ERR_INVALID_ARG invalid argument.
641 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
642 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
643 @retval Other error code defined by ql_type.h.
644 */
645/*-----------------------------------------------------------------------------------------------*/
646int ql_voice_waiting(int enable);
647
648/*-----------------------------------------------------------------------------------------------*/
649/**
650 @brief Gets call waiting status.
651 @param[out] enabled 0 - waiting is disabled, 1 - waiting is enabled.
652 @return Whether the voice call waiting status was successfully obtained.
653 @retval QL_ERR_OK successful.
654 @retval QL_ERR_INVALID_ARG invalid argument.
655 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
656 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
657 @retval Other error code defined by ql_type.h.
658 */
659/*-----------------------------------------------------------------------------------------------*/
660int ql_voice_get_waiting_status(int *enabled);
661
662/*-----------------------------------------------------------------------------------------------*/
663/**
664 @brief Enables or disables auto answer.
665 @param[in] enable 0 - disable, other - enable.
666 @param[in] sec wait this `sec' seconds before auto answer.
667 @return Whether the voice call autoanswer was enabled or disabled successfully.
668 @retval QL_ERR_OK successful.
669 @retval QL_ERR_INVALID_ARG invalid argument.
670 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
671 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
672 @retval Other error code defined by ql_type.h.
673 */
674/*-----------------------------------------------------------------------------------------------*/
675int ql_voice_autoanswer(int enable, uint32_t sec);
676
677/*-----------------------------------------------------------------------------------------------*/
678/**
679 @brief Sends a DTMF(Dual Tone Multi Frequency) character over the call ID.
680 @param[in] id call id returned from dial.
681 @param[in] c DTMF character to be sent. Valid DTMF characters are 0-9, A-D, '*', '#'.
682 @return Whether a DTMF character was successfully sent.
683 @retval QL_ERR_OK successful.
684 @retval QL_ERR_INVALID_ARG invalid argument.
685 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
686 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
687 @retval Other error code defined by ql_type.h.
688 */
689/*-----------------------------------------------------------------------------------------------*/
690int ql_voice_send_dtmf_char(uint32_t id, char c)
691{
692 int ret = 0;
693 int tmp;
694 char callnum_c;
695 mbtk_call_dtmf_info_t *dtmf = NULL;
696
697 if(voice_handle->handle == NULL)
698 {
699 LOGE("ql_voice_set_dtmf call_info_handle NULL");
700 return QL_ERR_FAILED;
701 }
702
703 dtmf = (mbtk_call_dtmf_info_t*)malloc(sizeof(mbtk_call_dtmf_info_t));
704 memset(dtmf,0x00, sizeof(mbtk_call_dtmf_info_t));
705
706 tmp = (int)c;
707
708 callnum_c = c;
709
710 if ((tmp >= 48 && tmp <= 57) || (tmp >= 65 && tmp <= 68) || (tmp == 42) || (tmp == 35))
711 {
712 dtmf->duration = 300;
713 dtmf->character = callnum_c;
714
l.yange4f94f42025-04-29 18:08:39 -0700715 ret = mbtk_ds_dtmf_send(voice_handle->handle,s_voice_slot, dtmf);
b.liud440f9f2025-04-18 10:44:31 +0800716 if (ret)
717 {
718 LOGE("mbtk_dtmf_send Error : %d", ret);
719 ret = QL_ERR_FAILED;
720 goto err;
721 }
722 }
723 else
724 {
725 LOGE("ql_voice_set_dtmf callnum demand ERR");
726 ret = QL_ERR_FAILED;
727 goto err;
728 }
729
730err:
731 free(dtmf);
732 return ret;
733
734}
735
736/*-----------------------------------------------------------------------------------------------*/
737/**
738 @brief Sets voice call callback handler.
739 @param[in] cb call back handler.
740 @return Whether the voice call callback handler was successfully set.
741 @retval QL_ERR_OK successful.
742 @retval QL_ERR_INVALID_ARG invalid argument.
743 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
744 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
745 @retval Other error code defined by ql_type.h.
746 */
747/*-----------------------------------------------------------------------------------------------*/
748int ql_voice_set_call_cb(ql_voice_call_cb_f cb)
749{
750 if(NULL == voice_handle)
751 {
752 LOGE("[ql_voice_set_msg_recv_cb] voice handle not init.");
753 return QL_ERR_NOT_INIT;
754 }
755
756 voice_handle->call_cb = cb;
757
758 return QL_ERR_OK;
759}
760
761/*-----------------------------------------------------------------------------------------------*/
762/**
763 @brief Sets voice dtmf callback handler.
764 @param[in] cb call back handler.
765 @return Whether the voice call DTMF repcetion callback handler was successfully set.
766 @retval QL_ERR_OK successful.
767 @retval QL_ERR_INVALID_ARG invalid argument.
768 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
769 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
770 @retval Other error code defined by ql_type.h.
771 */
772/*-----------------------------------------------------------------------------------------------*/
773int ql_voice_set_dtmf_cb(ql_voice_dtmf_cb_f cb);
774
775/*-----------------------------------------------------------------------------------------------*/
776/**
777 @brief Dials eCall.
778 @param[in] p_info eCall info.
779 @return Whether a eCall was successfully dialed.
780 @retval QL_ERR_OK successful.
781 @retval QL_ERR_INVALID_ARG invalid argument.
782 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
783 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
784 @retval Other error code defined by ql_type.h.
785 */
786/*-----------------------------------------------------------------------------------------------*/
787int ql_voice_ecall_dial(ql_voice_ecall_info_t *p_info);
788
789/*-----------------------------------------------------------------------------------------------*/
790/**
791 @brief Hangs up eCall.
792 @return Whether the eCall was successfully hung up.
793 @retval QL_ERR_OK successful.
794 @retval QL_ERR_INVALID_ARG invalid argument.
795 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
796 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
797 @retval Other error code defined by ql_type.h.
798 */
799/*-----------------------------------------------------------------------------------------------*/
800int ql_voice_ecall_hangup(void);
801
802/*-----------------------------------------------------------------------------------------------*/
803/**
804 @brief Updates eCall MSD.
805 @param[in] msd Minimum Set of Data.
806 @param[in] msd_len Length of Minimum Set of Data.
807 @return Whether the eCall MSD was successfully updated.
808 @retval QL_ERR_OK successful.
809 @retval QL_ERR_INVALID_ARG invalid argument.
810 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
811 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
812 @retval Other error code defined by ql_type.h.
813 */
814/*-----------------------------------------------------------------------------------------------*/
815int ql_voice_ecall_update_msd(const uint8_t *msd, uint32_t msd_len);
816
817/*-----------------------------------------------------------------------------------------------*/
818/**
819 @brief Pushes eCall MSD.
820 @param[out] state eCall state.
821 @return Whether the eCall MSD was successfully pushed.
822 @retval QL_ERR_OK successful.
823 @retval QL_ERR_INVALID_ARG invalid argument.
824 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
825 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
826 @retval Other error code defined by ql_type.h.
827 */
828/*-----------------------------------------------------------------------------------------------*/
q.huange8e9afa2025-08-15 18:38:35 +0800829int ql_voice_ecall_push_msd(QL_VOICE_ECALL_STATE_E *state)
830{
831 return 0;
832}
b.liud440f9f2025-04-18 10:44:31 +0800833
834/*-----------------------------------------------------------------------------------------------*/
835/**
836 @brief Gets eCall config.
837 @param[in] p_config eCall config.
838 @return Whether the eCall config was successfully obtained.
839 @retval QL_ERR_OK successful.
840 @retval QL_ERR_INVALID_ARG invalid argument.
841 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
842 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
843 @retval Other error code defined by ql_type.h.
844 */
845/*-----------------------------------------------------------------------------------------------*/
846int ql_voice_ecall_get_config(ql_voice_ecall_config_t *p_config);
847
848/*-----------------------------------------------------------------------------------------------*/
849/**
850 @brief Sets eCall config.
851 @param[in] item Items to set.
852 @param[in] p_config eCall config.
853 @return Whether the eCall config was successfully set.
854 @retval QL_ERR_OK successful.
855 @retval QL_ERR_INVALID_ARG invalid argument.
856 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
857 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
858 @retval Other error code defined by ql_type.h.
859 */
860/*-----------------------------------------------------------------------------------------------*/
861int ql_voice_ecall_set_config(int item, ql_voice_ecall_config_t *p_config);
862
863/*-----------------------------------------------------------------------------------------------*/
864/**
865 @brief Sets eCall event callback handler.
866 @param[in] cb call back handler.
867 @return Whether the eCall event callback handler was successfully set.
868 @retval QL_ERR_OK successful.
869 @retval QL_ERR_INVALID_ARG invalid argument.
870 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
871 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
872 @retval Other error code defined by ql_type.h.
873 */
874/*-----------------------------------------------------------------------------------------------*/
q.huange8e9afa2025-08-15 18:38:35 +0800875int ql_voice_ecall_set_event_cb(ql_voice_ecall_event_cb_f cb)
876{
877 return 0;
878}
b.liud440f9f2025-04-18 10:44:31 +0800879
880/*-----------------------------------------------------------------------------------------------*/
881/**
882 @brief Sets eCall status callback handler.
883 @param[in] cb call back handler.
884 @return Whether the eCall status callback handler was successfully set.
885 @retval QL_ERR_OK successful.
886 @retval QL_ERR_INVALID_ARG invalid argument.
887 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
888 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
889 @retval Other error code defined by ql_type.h.
890 */
891/*-----------------------------------------------------------------------------------------------*/
892int ql_voice_ecall_set_status_cb(ql_voice_ecall_status_cb_f cb);
893
894/*-----------------------------------------------------------------------------------------------*/
895/**
896 @brief Registration server error callback. Currently, only if the server exits abnormally,
897 the callback function will be executed, and the error code is QL_ERR_ABORTED;
898 @param[in] cb Callback function
899 @return
900 QL_ERR_OK - successful
901 Other - error code defined by ql_type.h
902 */
903/*-----------------------------------------------------------------------------------------------*/
904int ql_voice_set_service_error_cb(ql_voice_service_error_cb_f cb)
905{
906 if(NULL == voice_handle)
907 {
908 LOGE("[ql_voice_set_service_error_cb] voice handle not init.");
909 return QL_ERR_NOT_INIT;
910 }
911
912 voice_handle->server_cb = cb;
913
914 return QL_ERR_OK;
915}
916
917/*-----------------------------------------------------------------------------------------------*/
918/**
919 @brief Binds the current control point to a specific subscription.
920 @param[in] sub Subscription type.
921 @return Whether the subscription was successfully bound.
922 @retval QL_ERR_OK successful.
923 @retval QL_ERR_INVALID_ARG invalid argument.
924 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
925 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
926 @retval Other error code defined by ql_type.h.
927 */
928/*-----------------------------------------------------------------------------------------------*/
929//int ql_voice_bind_subscription(QL_VOICE_SUBSCRIPTION_E sub);
930
931