blob: 407a1a9ea18642dc47913ad0b37d05f285b5e667 [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/*-----------------------------------------------------------------------------------------------*/
q.huangd6b1ecd2025-08-25 17:57:35 +0800465int ql_voice_cancel_dial(uint32_t id)
466{
467 return QL_ERR_OK;
468}
b.liud440f9f2025-04-18 10:44:31 +0800469
470/*-----------------------------------------------------------------------------------------------*/
471/**
472 @brief hangup all dialing.
473 @return Whether all voice call were successfully hangup.
474 @retval QL_ERR_OK successful.
475 @retval QL_ERR_INVALID_ARG invalid argument.
476 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
477 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
478 @retval Other error code defined by ql_type.h.
479 */
480/*-----------------------------------------------------------------------------------------------*/
481int ql_voice_hangup_all(void)
482{
483 int err;
484
485 if(voice_handle->handle == NULL)
486 {
487 LOGE("ql_voice_call_end call_info_handle NULL");
488 return QL_ERR_FAILED;
489 }
490
q.huange45908b2025-06-06 11:13:51 +0800491 err = mbtk_ds_call_hang(voice_handle->handle,urc_voice_slot);
b.liud440f9f2025-04-18 10:44:31 +0800492 if(err)
493 {
494 LOGE("Error : %d", err);
495 return QL_ERR_FAILED;
496 }
497 else
498 {
499 LOGI("Call hang up a all.");
500 }
501 return QL_ERR_OK;
502}
503
504/*-----------------------------------------------------------------------------------------------*/
505/**
506 @brief Answers the call.
507 @param[in] id call id returned from dial.
508 @return Whether the voice call was successfully answered.
509 @retval QL_ERR_OK successful.
510 @retval QL_ERR_INVALID_ARG invalid argument.
511 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
512 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
513 @retval Other error code defined by ql_type.h.
514 */
515/*-----------------------------------------------------------------------------------------------*/
516int ql_voice_answer(uint32_t id)
517{
518 int err;
519
520 if(voice_handle->handle == NULL)
521 {
522 LOGE("ql_voice_call_anser call_info_handle NULL");
523 return QL_ERR_FAILED;
524 }
525
q.huange45908b2025-06-06 11:13:51 +0800526 err = mbtk_ds_call_answer(voice_handle->handle,urc_voice_slot);
b.liud440f9f2025-04-18 10:44:31 +0800527 if(err)
528 {
529 LOGE("Error : %d", err);
530 return QL_ERR_FAILED;
531 }
532 else
533 {
534 LOGI("Answer success.");
535 }
536 return QL_ERR_OK;
537}
538
539/*-----------------------------------------------------------------------------------------------*/
540/**
541 @brief Hangs up the call.
542 @param[in] id call id returned from dial.
543 @return Whether the voice call was successfully hung up.
544 @retval QL_ERR_OK successful.
545 @retval QL_ERR_INVALID_ARG invalid argument.
546 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
547 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
548 @retval Other error code defined by ql_type.h.
549 */
550/*-----------------------------------------------------------------------------------------------*/
q.huang6bf00742025-08-25 16:00:07 +0800551int ql_voice_hangup(uint32_t id)
552{
553 ql_auto_answer_thread_free(voice_handle,0);
554
555 if(voice_handle->handle == NULL)
556 {
557 LOGE("ql_voice_call_end call_info_handle NULL");
558 return QL_ERR_FAILED;
559 }
560
561 int err = mbtk_a_call_hang(voice_handle->handle,id);
562 if(err)
563 {
564 LOGE("Error : %d", err);
565 return QL_ERR_FAILED;
566 }
567 else
568 {
569 LOGI("Call hang up %d suc.",id);
570 }
571 return QL_ERR_OK;
572
573}
b.liud440f9f2025-04-18 10:44:31 +0800574
575/*-----------------------------------------------------------------------------------------------*/
576/**
577 @brief Holds the call when mutil calls is activated.
578 @param[in] id call id returned from dial.
579 @return Whether the voice call was successfully held.
580 @retval QL_ERR_OK successful.
581 @retval QL_ERR_INVALID_ARG invalid argument.
582 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
583 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
584 @retval Other error code defined by ql_type.h.
585 */
586/*-----------------------------------------------------------------------------------------------*/
q.huangd6b1ecd2025-08-25 17:57:35 +0800587int ql_voice_hold(uint32_t id)
588{
589 return QL_ERR_OK;
590}
b.liud440f9f2025-04-18 10:44:31 +0800591
592/*-----------------------------------------------------------------------------------------------*/
593/**
594 @brief Releases the call from hold when mutil calls is activated.
595 @param[in] id call id returned from dial.
596 @return Whether the voice call was successfully unheld.
597 @retval QL_ERR_OK successful.
598 @retval QL_ERR_INVALID_ARG invalid argument.
599 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
600 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
601 @retval Other error code defined by ql_type.h.
602 */
603/*-----------------------------------------------------------------------------------------------*/
q.huangd6b1ecd2025-08-25 17:57:35 +0800604int ql_voice_unhold(uint32_t id)
605{
606 return QL_ERR_OK;
607}
b.liud440f9f2025-04-18 10:44:31 +0800608
609/*-----------------------------------------------------------------------------------------------*/
610/**
611 @brief Gets call records.
612 @param[in] p_arr pointer to ql_voice_record_array_t.
613 @return Whether the call records were successfully obtained.
614 @retval QL_ERR_OK successful.
615 @retval QL_ERR_INVALID_ARG invalid argument.
616 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
617 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
618 @retval Other error code defined by ql_type.h.
619 */
620/*-----------------------------------------------------------------------------------------------*/
621int ql_voice_get_records(ql_voice_record_array_t *p_arr)
622{
623 if(NULL == p_arr)
624 {
625 LOGE("ql_voice_get_records p_arr NULL");
626 return QL_ERR_FAILED;
627 }
628 memcpy(p_arr, &voice_handle->record_array, sizeof(voice_handle->record_array));
629
630 return QL_ERR_OK;
631}
632
633/*-----------------------------------------------------------------------------------------------*/
634/**
635 @brief Registers or Unregisters forwarding.
636 @param[in] reg 0 - unregister, 1 - register.
637 @param[in] cond forwarding condition.
638 @param[in] num phone number.
639 @param[in] len length of phone numebr.
640 @return Whether the voice call forward was registered or unregistered successfully.
641 @retval QL_ERR_OK successful.
642 @retval QL_ERR_INVALID_ARG invalid argument.
643 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
644 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
645 @retval Other error code defined by ql_type.h.
646 */
647/*-----------------------------------------------------------------------------------------------*/
q.huangd6b1ecd2025-08-25 17:57:35 +0800648int ql_voice_forwarding(int reg, QL_VOICE_FW_COND_E cond, char *num, int len)
649{
650 return QL_ERR_OK;
651}
b.liud440f9f2025-04-18 10:44:31 +0800652
653/*-----------------------------------------------------------------------------------------------*/
654/**
655 @brief Gets forwarding status.
656 @param[in] cond forwarding condition.
657 @param[out] p_status pointer to ql_voice_fw_status_t.
658 @return Whether the voice call forward status was successfully obtained.
659 @retval QL_ERR_OK successful.
660 @retval QL_ERR_INVALID_ARG invalid argument.
661 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
662 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
663 @retval Other error code defined by ql_type.h.
664 */
665/*-----------------------------------------------------------------------------------------------*/
q.huangd6b1ecd2025-08-25 17:57:35 +0800666int ql_voice_get_forwarding_status(QL_VOICE_FW_COND_E cond, ql_voice_fw_status_t *p_status)
667{
668 return QL_ERR_OK;
669}
b.liud440f9f2025-04-18 10:44:31 +0800670
671/*-----------------------------------------------------------------------------------------------*/
672/**
673 @brief Enables or disables call waiting.
674 @param[in] enable 0 - disable, other - enable.
675 @return Whether the voice call waiting was enabled or disabled successfully.
676 @retval QL_ERR_OK successful.
677 @retval QL_ERR_INVALID_ARG invalid argument.
678 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
679 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
680 @retval Other error code defined by ql_type.h.
681 */
682/*-----------------------------------------------------------------------------------------------*/
q.huangd6b1ecd2025-08-25 17:57:35 +0800683int ql_voice_waiting(int enable)
684{
685 return QL_ERR_OK;
686}
687
b.liud440f9f2025-04-18 10:44:31 +0800688
689/*-----------------------------------------------------------------------------------------------*/
690/**
691 @brief Gets call waiting status.
692 @param[out] enabled 0 - waiting is disabled, 1 - waiting is enabled.
693 @return Whether the voice call waiting status was successfully obtained.
694 @retval QL_ERR_OK successful.
695 @retval QL_ERR_INVALID_ARG invalid argument.
696 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
697 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
698 @retval Other error code defined by ql_type.h.
699 */
700/*-----------------------------------------------------------------------------------------------*/
q.huangd6b1ecd2025-08-25 17:57:35 +0800701int ql_voice_get_waiting_status(int *enabled)
702{
703 return QL_ERR_OK;
704}
b.liud440f9f2025-04-18 10:44:31 +0800705
706/*-----------------------------------------------------------------------------------------------*/
707/**
708 @brief Enables or disables auto answer.
709 @param[in] enable 0 - disable, other - enable.
710 @param[in] sec wait this `sec' seconds before auto answer.
711 @return Whether the voice call autoanswer was enabled or disabled successfully.
712 @retval QL_ERR_OK successful.
713 @retval QL_ERR_INVALID_ARG invalid argument.
714 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
715 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
716 @retval Other error code defined by ql_type.h.
717 */
718/*-----------------------------------------------------------------------------------------------*/
719int ql_voice_autoanswer(int enable, uint32_t sec);
720
721/*-----------------------------------------------------------------------------------------------*/
722/**
723 @brief Sends a DTMF(Dual Tone Multi Frequency) character over the call ID.
724 @param[in] id call id returned from dial.
725 @param[in] c DTMF character to be sent. Valid DTMF characters are 0-9, A-D, '*', '#'.
726 @return Whether a DTMF character was successfully sent.
727 @retval QL_ERR_OK successful.
728 @retval QL_ERR_INVALID_ARG invalid argument.
729 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
730 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
731 @retval Other error code defined by ql_type.h.
732 */
733/*-----------------------------------------------------------------------------------------------*/
734int ql_voice_send_dtmf_char(uint32_t id, char c)
735{
736 int ret = 0;
737 int tmp;
738 char callnum_c;
739 mbtk_call_dtmf_info_t *dtmf = NULL;
740
741 if(voice_handle->handle == NULL)
742 {
743 LOGE("ql_voice_set_dtmf call_info_handle NULL");
744 return QL_ERR_FAILED;
745 }
746
747 dtmf = (mbtk_call_dtmf_info_t*)malloc(sizeof(mbtk_call_dtmf_info_t));
748 memset(dtmf,0x00, sizeof(mbtk_call_dtmf_info_t));
749
750 tmp = (int)c;
751
752 callnum_c = c;
753
754 if ((tmp >= 48 && tmp <= 57) || (tmp >= 65 && tmp <= 68) || (tmp == 42) || (tmp == 35))
755 {
756 dtmf->duration = 300;
757 dtmf->character = callnum_c;
758
l.yange4f94f42025-04-29 18:08:39 -0700759 ret = mbtk_ds_dtmf_send(voice_handle->handle,s_voice_slot, dtmf);
b.liud440f9f2025-04-18 10:44:31 +0800760 if (ret)
761 {
762 LOGE("mbtk_dtmf_send Error : %d", ret);
763 ret = QL_ERR_FAILED;
764 goto err;
765 }
766 }
767 else
768 {
769 LOGE("ql_voice_set_dtmf callnum demand ERR");
770 ret = QL_ERR_FAILED;
771 goto err;
772 }
773
774err:
775 free(dtmf);
776 return ret;
777
778}
779
780/*-----------------------------------------------------------------------------------------------*/
781/**
782 @brief Sets voice call callback handler.
783 @param[in] cb call back handler.
784 @return Whether the voice call callback handler was successfully set.
785 @retval QL_ERR_OK successful.
786 @retval QL_ERR_INVALID_ARG invalid argument.
787 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
788 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
789 @retval Other error code defined by ql_type.h.
790 */
791/*-----------------------------------------------------------------------------------------------*/
792int ql_voice_set_call_cb(ql_voice_call_cb_f cb)
793{
794 if(NULL == voice_handle)
795 {
796 LOGE("[ql_voice_set_msg_recv_cb] voice handle not init.");
797 return QL_ERR_NOT_INIT;
798 }
799
800 voice_handle->call_cb = cb;
801
802 return QL_ERR_OK;
803}
804
805/*-----------------------------------------------------------------------------------------------*/
806/**
807 @brief Sets voice dtmf callback handler.
808 @param[in] cb call back handler.
809 @return Whether the voice call DTMF repcetion callback handler was successfully set.
810 @retval QL_ERR_OK successful.
811 @retval QL_ERR_INVALID_ARG invalid argument.
812 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
813 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
814 @retval Other error code defined by ql_type.h.
815 */
816/*-----------------------------------------------------------------------------------------------*/
q.huangd6b1ecd2025-08-25 17:57:35 +0800817int ql_voice_set_dtmf_cb(ql_voice_dtmf_cb_f cb)
818{
819 return QL_ERR_OK;
820}
b.liud440f9f2025-04-18 10:44:31 +0800821
822/*-----------------------------------------------------------------------------------------------*/
823/**
824 @brief Dials eCall.
825 @param[in] p_info eCall info.
826 @return Whether a eCall was successfully dialed.
827 @retval QL_ERR_OK successful.
828 @retval QL_ERR_INVALID_ARG invalid argument.
829 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
830 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
831 @retval Other error code defined by ql_type.h.
832 */
833/*-----------------------------------------------------------------------------------------------*/
q.huangd6b1ecd2025-08-25 17:57:35 +0800834int ql_voice_ecall_dial(ql_voice_ecall_info_t *p_info)
835{
836 return QL_ERR_OK;
837}
b.liud440f9f2025-04-18 10:44:31 +0800838
839/*-----------------------------------------------------------------------------------------------*/
840/**
841 @brief Hangs up eCall.
842 @return Whether the eCall was successfully hung up.
843 @retval QL_ERR_OK successful.
844 @retval QL_ERR_INVALID_ARG invalid argument.
845 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
846 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
847 @retval Other error code defined by ql_type.h.
848 */
849/*-----------------------------------------------------------------------------------------------*/
q.huangd6b1ecd2025-08-25 17:57:35 +0800850int ql_voice_ecall_hangup(void)
851{
852 return QL_ERR_OK;
853}
b.liud440f9f2025-04-18 10:44:31 +0800854
855/*-----------------------------------------------------------------------------------------------*/
856/**
857 @brief Updates eCall MSD.
858 @param[in] msd Minimum Set of Data.
859 @param[in] msd_len Length of Minimum Set of Data.
860 @return Whether the eCall MSD was successfully updated.
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/*-----------------------------------------------------------------------------------------------*/
q.huangd6b1ecd2025-08-25 17:57:35 +0800868int ql_voice_ecall_update_msd(const uint8_t *msd, uint32_t msd_len)
869{
870 return QL_ERR_OK;
871}
b.liud440f9f2025-04-18 10:44:31 +0800872
873/*-----------------------------------------------------------------------------------------------*/
874/**
875 @brief Pushes eCall MSD.
876 @param[out] state eCall state.
877 @return Whether the eCall MSD was successfully pushed.
878 @retval QL_ERR_OK successful.
879 @retval QL_ERR_INVALID_ARG invalid argument.
880 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
881 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
882 @retval Other error code defined by ql_type.h.
883 */
884/*-----------------------------------------------------------------------------------------------*/
q.huange8e9afa2025-08-15 18:38:35 +0800885int ql_voice_ecall_push_msd(QL_VOICE_ECALL_STATE_E *state)
886{
q.huangd6b1ecd2025-08-25 17:57:35 +0800887 return QL_ERR_OK;
q.huange8e9afa2025-08-15 18:38:35 +0800888}
b.liud440f9f2025-04-18 10:44:31 +0800889
890/*-----------------------------------------------------------------------------------------------*/
891/**
892 @brief Gets eCall config.
893 @param[in] p_config eCall config.
894 @return Whether the eCall config was successfully obtained.
895 @retval QL_ERR_OK successful.
896 @retval QL_ERR_INVALID_ARG invalid argument.
897 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
898 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
899 @retval Other error code defined by ql_type.h.
900 */
901/*-----------------------------------------------------------------------------------------------*/
q.huangd6b1ecd2025-08-25 17:57:35 +0800902int ql_voice_ecall_get_config(ql_voice_ecall_config_t *p_config)
903{
904 return QL_ERR_OK;
905}
b.liud440f9f2025-04-18 10:44:31 +0800906
907/*-----------------------------------------------------------------------------------------------*/
908/**
909 @brief Sets eCall config.
910 @param[in] item Items to set.
911 @param[in] p_config eCall config.
912 @return Whether the eCall config was successfully set.
913 @retval QL_ERR_OK successful.
914 @retval QL_ERR_INVALID_ARG invalid argument.
915 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
916 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
917 @retval Other error code defined by ql_type.h.
918 */
919/*-----------------------------------------------------------------------------------------------*/
q.huangd6b1ecd2025-08-25 17:57:35 +0800920int ql_voice_ecall_set_config(int item, ql_voice_ecall_config_t *p_config)
921{
922 return QL_ERR_OK;
923}
b.liud440f9f2025-04-18 10:44:31 +0800924
925/*-----------------------------------------------------------------------------------------------*/
926/**
927 @brief Sets eCall event callback handler.
928 @param[in] cb call back handler.
929 @return Whether the eCall event callback handler was successfully set.
930 @retval QL_ERR_OK successful.
931 @retval QL_ERR_INVALID_ARG invalid argument.
932 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
933 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
934 @retval Other error code defined by ql_type.h.
935 */
936/*-----------------------------------------------------------------------------------------------*/
q.huange8e9afa2025-08-15 18:38:35 +0800937int ql_voice_ecall_set_event_cb(ql_voice_ecall_event_cb_f cb)
938{
q.huangd6b1ecd2025-08-25 17:57:35 +0800939 return QL_ERR_OK;
q.huange8e9afa2025-08-15 18:38:35 +0800940}
b.liud440f9f2025-04-18 10:44:31 +0800941
942/*-----------------------------------------------------------------------------------------------*/
943/**
944 @brief Sets eCall status callback handler.
945 @param[in] cb call back handler.
946 @return Whether the eCall status callback handler was successfully set.
947 @retval QL_ERR_OK successful.
948 @retval QL_ERR_INVALID_ARG invalid argument.
949 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
950 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
951 @retval Other error code defined by ql_type.h.
952 */
953/*-----------------------------------------------------------------------------------------------*/
q.huangd6b1ecd2025-08-25 17:57:35 +0800954int ql_voice_ecall_set_status_cb(ql_voice_ecall_status_cb_f cb)
955{
956 return QL_ERR_OK;
957}
b.liud440f9f2025-04-18 10:44:31 +0800958
959/*-----------------------------------------------------------------------------------------------*/
960/**
961 @brief Registration server error callback. Currently, only if the server exits abnormally,
962 the callback function will be executed, and the error code is QL_ERR_ABORTED;
963 @param[in] cb Callback function
964 @return
965 QL_ERR_OK - successful
966 Other - error code defined by ql_type.h
967 */
968/*-----------------------------------------------------------------------------------------------*/
969int ql_voice_set_service_error_cb(ql_voice_service_error_cb_f cb)
970{
971 if(NULL == voice_handle)
972 {
973 LOGE("[ql_voice_set_service_error_cb] voice handle not init.");
974 return QL_ERR_NOT_INIT;
975 }
976
977 voice_handle->server_cb = cb;
978
979 return QL_ERR_OK;
980}
981
982/*-----------------------------------------------------------------------------------------------*/
983/**
984 @brief Binds the current control point to a specific subscription.
985 @param[in] sub Subscription type.
986 @return Whether the subscription was successfully bound.
987 @retval QL_ERR_OK successful.
988 @retval QL_ERR_INVALID_ARG invalid argument.
989 @retval QL_ERR_UNKNOWN unknown error, failed to connect to service.
990 @retval QL_ERR_SERVICE_NOT_READY service is not ready, need to retry.
991 @retval Other error code defined by ql_type.h.
992 */
993/*-----------------------------------------------------------------------------------------------*/
994//int ql_voice_bind_subscription(QL_VOICE_SUBSCRIPTION_E sub);
995
996