blob: 657d8c003a3affe8ef7ccaa12048ecbf7527a2c0 [file] [log] [blame]
l.yang8e8d5282023-06-15 10:48:26 +08001#include <stdio.h>
2#include <stdlib.h>
3#include <stdint.h>
4#include <string.h>
5#include <errno.h>
6#include <unistd.h>
7#include <liblog/lynq_deflog.h>
8#include <sys/types.h>
9#include <pthread.h>
10#include <libcall/lynq_call.h>
11
12#include "lynq-qser-voice.h"
13
14#define USER_LOG_TAG "LYNQ_QSER_CALL"
15
16#define RESULT_OK (0)
17#define RESULT_ERROR (-1)
18
l.yang6f3f70b2023-09-08 13:33:58 +080019#define MIN_VOLUME 0
20#define MAX_VOLUME 5
21
q.huang0d2cbed2024-03-28 10:50:55 +080022#ifdef ECALL_SUPPORT
23static pthread_t s_lynq_ecall_tid = -1;
24static QSER_ECall_IndHandlerFunc_t s_ecall_cb = NULL;
25static int s_ecall_thread_status = 0;
26#endif
l.yang6f3f70b2023-09-08 13:33:58 +080027
l.yang8e8d5282023-06-15 10:48:26 +080028static pthread_t s_lynq_voice_tid = -1;
29static QSER_VoiceCall_StateHandlerFunc_t s_voice_cb = NULL;
30static int s_voice_thread_status = 0;
31
32 typedef enum {
33 LYNQ_CALL_ACTIVE = 0,
34 LYNQ_CALL_HOLDING = 1,
35 LYNQ_CALL_DIALING = 2, /* MO call only */
36 LYNQ_CALL_ALERTING = 3, /* MO call only */
37 LYNQ_CALL_INCOMING = 4, /* MT call only */
38 LYNQ_CALL_WAITING = 5, /* MT call only */
39 /*warren add for T800 platform 2022/04/26 start*/
40 LYNQ_CALL_END = 6, /*CALL END*/
41 /*warren add for T800 platform 2022/04/26 end*/
42}lynq_call_state_t;
43
44
45void *voice_thread_recv(void *context)
46{
47 int handle = 0;
48 int call_state;
49 int toa;
50 int direction;
51 char addr[64];
52 E_QSER_VOICE_CALL_STATE_T voice_state;
53 while (s_voice_thread_status)
54 {
55 lynq_wait_call_state_change(&handle);
l.yang30254892023-09-18 10:35:05 +080056 if(s_voice_thread_status == 0)
57 {
58 return NULL;
59 }
l.yang8e8d5282023-06-15 10:48:26 +080060 lynq_get_current_call_state(&handle,&call_state,&toa,&direction,addr);
61 if (call_state == LYNQ_CALL_ACTIVE)
62 {
63 voice_state = E_QSER_VOICE_CALL_STATE_ACTIVE;
64 }
65 else if(call_state == LYNQ_CALL_HOLDING)
66 {
67 voice_state = E_QSER_VOICE_CALL_STATE_HOLDING;
68 }
69 else if(call_state == LYNQ_CALL_DIALING)
70 {
71 voice_state = E_QSER_VOICE_CALL_STATE_DIALING;
72 }
73 else if(call_state == LYNQ_CALL_ALERTING)
74 {
75 voice_state = E_QSER_VOICE_CALL_STATE_ALERTING;
76 }
77 else if(call_state == LYNQ_CALL_INCOMING)
78 {
79 voice_state = E_QSER_VOICE_CALL_STATE_INCOMING;
80 }
81 else if(call_state == LYNQ_CALL_WAITING)
82 {
83 voice_state = E_QSER_VOICE_CALL_STATE_WAITING;
84 }
85 else if(call_state == LYNQ_CALL_END)
86 {
87 voice_state = E_QSER_VOICE_CALL_STATE_END;
88 }
89 else
90 {
91 LYERRLOG("unknow call state");
92 continue;
93 }
94 if (s_voice_cb != NULL)
95 {
96 s_voice_cb(handle,addr,voice_state,context);
97 }
98 }
99 return NULL;
100}
101
102int qser_voice_call_client_init(voice_client_handle_type *ph_voice)
103{
104 if(NULL == ph_voice)
105 {
106 LYERRLOG("input error");
107 return RESULT_ERROR;
108 }
109 *ph_voice = (voice_client_handle_type)getpid();
110 return lynq_init_call(*ph_voice);
111}
112
113int qser_voice_call_client_deinit(voice_client_handle_type h_voice)
114{
l.yang6f131362023-07-25 09:45:37 +0800115 if (0 == h_voice)
l.yang8e8d5282023-06-15 10:48:26 +0800116 {
117 LYERRLOG("init first");
118 return RESULT_ERROR;
119 }
q.huang0d2cbed2024-03-28 10:50:55 +0800120
121
122#ifdef ECALL_SUPPORT
123 s_ecall_thread_status = 0;
124
125 if(s_lynq_ecall_tid!=-1)
126 {
127 int ret = pthread_cancel(s_lynq_ecall_tid);
128 LYINFLOG("pthread cancel waiting urc thread, ret = %d",ret);
129
130 ret = pthread_join(s_lynq_ecall_tid,NULL);
131 LYINFLOG("pthread join waiting urc thread ret = %d",ret);
132 s_lynq_ecall_tid =-1;
133 }
134
135 s_ecall_cb=NULL;
136#endif
137
l.yang8e8d5282023-06-15 10:48:26 +0800138 return lynq_deinit_call();
139}
140
141int qser_voice_call_addstatehandler(voice_client_handle_type h_voice,
142 QSER_VoiceCall_StateHandlerFunc_t handlerPtr,
143 void* contextPtr)
144{
145 if(h_voice == 0 || handlerPtr== NULL)
146 {
147 LYERRLOG("input error");
148 return RESULT_ERROR;
149 }
150 if (s_voice_cb != NULL)
151 {
152 LYERRLOG("The existing state handle does not need to be added");
153 return RESULT_ERROR;
154 }
155 s_voice_cb = handlerPtr;
156 s_voice_thread_status = 1;
157 int rt = pthread_create(&s_lynq_voice_tid, NULL, voice_thread_recv, contextPtr);
158 if(rt < 0)
159 {
160 LYDBGLOG("qser_voice_call_addstatehandler pthread_create error!!!\n");
161 s_voice_cb = NULL;
162 s_voice_thread_status = 0;
163 s_lynq_voice_tid = -1;
164 return RESULT_ERROR;
165 }
166 return RESULT_OK;
167}
168
169int qser_voice_call_removestatehandle(voice_client_handle_type h_voice)
170{
l.yang30254892023-09-18 10:35:05 +0800171
172 LYINFLOG("Enter removestatehandle !!!");
l.yang8e8d5282023-06-15 10:48:26 +0800173 s_voice_thread_status = 0;
l.yang30254892023-09-18 10:35:05 +0800174 if(s_lynq_voice_tid != -1)
175 {
176 lynq_release_wait_call();
177 }
178
l.yang6f131362023-07-25 09:45:37 +0800179 s_voice_cb = NULL;
l.yang8e8d5282023-06-15 10:48:26 +0800180 return RESULT_OK;
181}
182
183int qser_voice_call_start(voice_client_handle_type h_voice,
184 E_QSER_VCALL_ID_T simId,
185 char* phone_number,
186 int *call_id)
187{
188 if(h_voice == 0 || NULL == phone_number || NULL == call_id)
189 {
190 LYERRLOG("qser_voice_call_start input error");
191 return RESULT_ERROR;
192 }
193 return lynq_call(call_id,phone_number);
194}
195
196int qser_voice_call_end(voice_client_handle_type h_voice,int call_id)
197{
198 if(h_voice == 0 || call_id <= 0)
199 {
200 LYERRLOG("qser_voice_call_end input error");
201 return RESULT_ERROR;
202 }
203 return lynq_call_hungup(&call_id);
204}
205
206int qser_voice_call_answer(voice_client_handle_type h_voice,int call_id)
207{
208 if(h_voice == 0 || call_id <= 0)
209 {
210 LYERRLOG("qser_voice_call_answer input error");
211 return RESULT_ERROR;
212 }
213 return lynq_call_answer();
214}
215
l.yang6f131362023-07-25 09:45:37 +0800216int qser_voice_call_getwaitingstatus(int h_voice,qser_voice_call_waiting_service_t *pe_service)
l.yang8e8d5282023-06-15 10:48:26 +0800217{
218 LYINFLOG("To be completed");
219 return RESULT_OK;
220}
221
222int qser_voice_call_setwaiting(int h_voice, qser_voice_call_waiting_service_t e_service)
223{
224 LYINFLOG("To be completed");
225 return RESULT_OK;
226}
227
l.yang8e8d5282023-06-15 10:48:26 +0800228
l.yang6f131362023-07-25 09:45:37 +0800229int qser_voice_call_switch_waiting_or_holding_and_active(voice_client_handle_type h_voice)
l.yang8e8d5282023-06-15 10:48:26 +0800230{
231 if (h_voice == 0)
232 {
233 LYERRLOG("init first");
234 return RESULT_ERROR;
235 }
236 return lynq_switch_waiting_or_holding_and_active();
you.chen21c62b72023-09-08 09:41:11 +0800237}
238
l.yang6f3f70b2023-09-08 13:33:58 +0800239int qser_voice_set_speech_volume(const int volume)
240{
241 if(volume < MIN_VOLUME || volume > MAX_VOLUME)
242 {
243 LYERRLOG("Illeage input volume");
244 return RESULT_ERROR;
245 }
246 return lynq_set_speech_volume(volume);
247}
248
249
250int qser_voice_get_speech_volume(int *volume)
251{
252 return lynq_get_speech_volume(volume);
253}
254
l.yangaf69e4b2023-12-27 19:42:49 +0800255int qser_voice_set_dtmf(const char callnum)
256{
257 return lynq_set_DTMF(callnum);
258
259}
260
q.huang0d2cbed2024-03-28 10:50:55 +0800261#ifdef ECALL_SUPPORT
262int qser_voice_fast_ecall(voice_client_handle_type* h_voice,
263 int *call_id,
264 E_QSER_VOICE_ECALL_CATEGORY_T cat,
265 E_QSER_VOICE_ECALL_VARIANT_T variant,
266 const char *addr,
267 int addr_length,
268 const unsigned char *msd_data,
269 int msd_length)
270{
271 if(h_voice == NULL || (*h_voice) == 0 )
272 {
273 LYERRLOG("%s input error", __func__);
274 return RESULT_ERROR;
275 }
276
277 return lynq_fast_ecall(call_id,(LYNQ_ECall_Category) cat,(LYNQ_ECall_Variant) variant,addr,addr_length,msd_data,msd_length);
278}
279
280int qser_voice_set_test_num(voice_client_handle_type* h_voice,E_QSER_VOICE_ECALL_SET_TYPE_T type, const char *test_num, int test_num_length)
281{
282 if(h_voice == NULL || (*h_voice) == 0 )
283 {
284 LYERRLOG("%s input error", __func__);
285 return RESULT_ERROR;
286 }
287
288 return lynq_set_test_num((LYNQ_ECall_Set_Type) type, test_num, test_num_length);
289}
290
291int qser_voice_set_msd(int callid, const unsigned char *msd_data, int msd_length)
292{
293 return lynq_set_msd(callid, msd_data, msd_length);
294}
295
296void *ecall_thread_recv(void *context)
297{
298 int handle = 0;
299 LYNQ_ECall_Indication eCall_Indication;
300 while (s_ecall_thread_status)
301 {
302 lynq_wait_ecall_indication(&handle, &eCall_Indication);
303 if(s_ecall_thread_status == 0)
304 {
305 return NULL;
306 }
307
308 if (s_ecall_cb != NULL)
309 {
q.huangda55a992024-04-17 18:27:57 +0800310 s_ecall_cb(handle,(E_QSER_VOICE_ECALL_INDICATION_T) eCall_Indication,context);
q.huang0d2cbed2024-03-28 10:50:55 +0800311 }
312 }
313 return NULL;
314}
315
316int qser_voice_add_ecall_indhandler(voice_client_handle_type* h_voice,
317 QSER_ECall_IndHandlerFunc_t handlerPtr,
318 void* contextPtr)
319{
320 if(h_voice == NULL || (*h_voice) == 0 || handlerPtr== NULL)
321 {
322 LYERRLOG("input error");
323 return RESULT_ERROR;
324 }
325 if (s_ecall_cb != NULL)
326 {
327 LYERRLOG("The existing state handle does not need to be added");
328 return RESULT_ERROR;
329 }
330 s_ecall_cb = handlerPtr;
331 s_ecall_thread_status = 1;
332 int rt = pthread_create(&s_lynq_ecall_tid, NULL, ecall_thread_recv, contextPtr);
333 if(rt < 0)
334 {
335 LYDBGLOG("qser_voice_call_addstatehandler pthread_create error!!!\n");
336 s_ecall_cb = NULL;
337 s_ecall_thread_status = 0;
338 s_lynq_ecall_tid = -1;
339 return RESULT_ERROR;
340 }
341 return RESULT_OK;
342}
343#endif
344
you.chen21c62b72023-09-08 09:41:11 +0800345DEFINE_LYNQ_LIB_LOG(LYNQ_QSER_CALL)
346