2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.tizenopensource.org/license
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include <ITapiModem.h>
23 /* Call Module File Includes */
24 #include "vc-core-engine.h"
25 #include "vc-core-callagent.h"
26 #include "vc-core-callmanager.h"
27 #include "vc-core-util.h"
28 #include "vc-core-tapi-evnt.h"
29 #include "vc-core-tapi-rqst.h"
30 #include "vc-core-svcall.h"
31 #include "vc-core-engine-status.h"
32 #include "vc-core-ecc.h"
34 /*Global Variable Declerations */
36 /*Incoming Call Details used for Self Event*/
37 static call_vc_handle gincoming_call_handle = VC_TAPI_INVALID_CALLHANDLE;
38 static TelCallIncomingCallInfo_t gincoming_call_info;
40 /*Initialization Global Variables*/
41 static gboolean gphone_init_finished = FALSE;
42 static call_vc_handle gphone_rejected_call = VC_TAPI_INVALID_CALLHANDLE;
44 static call_vc_callagent_state_t *gpcall_agent_for_callback = NULL; /*jspark event subscribe & callback function*/
46 /* SAT call detail used for self event */
47 static int gsat_event_type = 0;
49 static void *gpresult = NULL;
50 static TelSatSetupCallIndCallData_t gSatSetupCallInfo;
51 //static TelSatSendDtmfIndDtmfData_t gSatSendDtmfInfo;
53 /*Local Function Declarations*/
55 * This function handles the end event for outgoing call
58 * @return Returns TRUE on success and FALSE on failure
59 * @param[in] pcall_agent Handle to the call agent
60 * @param[in] call_handle call handle of the outgoing call
61 * @param[in] type type of the tapi event
62 * @param[in] tapi_cause tapi cause
64 static gboolean __call_vc_outgoingcall_endhandle(call_vc_callagent_state_t *pcall_agent, call_vc_handle call_handle, const char *type, TelTapiEndCause_t tapi_cause);
66 * This function handles the end event for incoming call
69 * @return Returns TRUE on success and FALSE on failure
70 * @param[in] pcall_agent Handle to the call agent
71 * @param[in] call_handle call handle of the outgoing call
73 static gboolean __call_vc_incomingcall_endhandle(call_vc_callagent_state_t *pcall_agent, call_vc_handle call_handle);
75 * This function checks whether the call agent is in any of the wait state
78 * @return Returns TRUE on if call agent is in wait state or FALSE
79 * @param[in] pcall_agent Handle to the call agent
81 static gboolean __call_vc_is_callagent_waitstate(call_vc_callagent_state_t *pcall_agent);
83 * This function creates call details for outgoign call with the given setup info
86 * @return Returns TRUE on if call agent is in wait state or FALSE
87 * @param[in] pagent Handle to the call agent
88 * @param[in] psetup_call_info Setup info
89 * @param[out] pcall_object Call object containing call details
90 * @param[out] error_code Error Code
92 static gboolean __call_vc_create_outgoing_callinfo(call_vc_callagent_state_t *pagent, voicecall_setup_info_t *psetup_call_info, call_vc_call_objectinfo_t *pcall_object, int *error_code);
95 * This function handles all telephony events
99 * @param[in] tapi_handle tapi handle
100 * @param[in] noti_id event type
101 * @param[in] data tapi event data
102 * @param[in] userdata user callback data
105 static void __call_vc_handle_tapi_events(TapiHandle *handle, const char *noti_id, void *data, void *user_data);
108 * This function handles sat engine notification
112 * @param[in] tapi_handle tapi handle
113 * @param[in] noti_id event type
114 * @param[in] data tapi event data
115 * @param[in] userdata user callback data
117 static void __call_vc_handle_sat_engine_events_cb(TapiHandle *handle, const char *noti_id, void *data, void *user_data);
120 * This function subscribes for all notifications required for voicecall engine
123 * @return Returns TRUE on success or FALSE on failure
124 * @param[in] pcall_agent handle to voicecall agent structure
126 static gboolean __call_vc_subscribe_call_events(call_vc_callagent_state_t *pcall_agent);
129 * This function handles telephony initialized notifications
132 * @return Returns TRUE on success or FALSE on failure
133 * @param[in] tapi_handle tapi handle
134 * @param[in] noti_id event type
135 * @param[in] data tapi event data
136 * @param[in] userdata user callback data
138 static void __call_vc_tapi_initialized_cb(TapiHandle *handle, const char *noti_id, void *data, void *user_data);
141 * This function subscribes for telephony call notifications
144 * @return Returns TRUE on success or FALSE on failure
145 * @param[in] pcall_agent handle to voicecall agent structure
147 static gboolean __call_vc_subscribe_tapi_event(call_vc_callagent_state_t *pcall_agent);
150 * This function request the engine to setup a sat call
153 * @return Returns TRUE on success or FALSE on failure
154 * @param[in] pagent handle to voicecall agent structure
155 * @param[in] mo_call_index call index of the mo call prepared for sat call
156 * @param[in] ret_code Error code
157 * @exception ERROR_VOICECALL_TAPI_CAUSE_CALL_FAILED
159 static gboolean __call_vc_request_sat_call(call_vc_callagent_state_t *pagent, int mo_call_index, int *ret_code);
162 * This function hadles the events from the sat engine
165 * @return Returns TRUE on success or FALSE on failure
166 * @param[in] pcall_agent handle to voicecall agent structure
167 * @param[in] sat_event event type (sat request / sat response)
168 * @param[in] sat_event_type sat event sub type
169 * @param[in] type event type received from sat
170 * @param[in] result data received from sat
172 static gboolean __call_vc_handle_sat_engine_events(call_vc_callagent_state_t *pcall_agent, int sat_event, int sat_event_type, int type, void *result);
175 * This function request the engine to setup a normal voice call
178 * @return Returns TRUE on success or FALSE on failure
179 * @param[in] pagent handle to voicecall agent structure
180 * @param[in] mo_call_index call index of the mo call prepared for sat call
181 * @param[in] ret_code Error code
182 * @exception ERROR_VOICECALL_TAPI_CAUSE_CALL_FAILED
184 static gboolean __call_vc_request_call(call_vc_callagent_state_t *pagent, int mo_call_index, int *ret_code);
187 * This function serves as the callback function for the incoming call idle add function
189 * @return Returns TRUE - if the callback has to be called again, FALSE otherwise
190 * @param[in] puser_data data set by the user
192 static gboolean __call_vc_incoming_idle_cb(gpointer puser_data);
193 static gboolean __call_vc_incoming_call_end_idle_cb(gpointer puser_data);
194 static gboolean __call_vc_reject_call_idle_cb(gpointer puser_data);
195 static gboolean __call_vc_reject_call_full_idle_cb(gpointer puser_data);
198 * This function serves as the callback function for the SAT idle add function
200 * @return Returns TRUE - if the callback has to be called again, FALSE otherwise
201 * @param[in] puser_data data set by the user
203 static gboolean __call_vc_sat_idle_cb(gpointer puser_data);
206 * This function checks the voicecall engine's idle status and send VC_ACTION_NO_ACTIVE_TASK to client if engine is idle
209 * @param[in] pcall_agent Pointer to the call agent structure
211 static void __vc_core_check_engine_active_task(call_vc_callagent_state_t *pcall_agent);
214 * This function checks whether dtmf is possible
216 * @return This function returns TRUE if dtmf is possible or else FALSE
217 * @param[in] pcall_agent Pointer to the call agent structure
219 static gboolean __vc_core_is_dtmf_possible(call_vc_callagent_state_t *pcall_agent);
222 * This function initializes the voicecall engine
224 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
225 * @param[out] pcall_agent_out Pointer to the address of call agent
226 * @param[in] pcallback_func Call back function
227 * @param[in] puser_data Data set by user
228 * @remarks pcall_agent_out and pcallback_func cannot be NULL.
229 * Output Parameter pcall_agent_out should be initialized to NULL
231 voicecall_error_t _vc_core_engine_init(voicecall_engine_t **pcall_agent_out, voicecall_cb pcallback_func, void *puser_data)
233 call_vc_callagent_state_t *pcall_agent = NULL;
235 CALL_ENG_DEBUG(ENG_DEBUG, "Voicecall Engine");
237 VOICECALL_RETURN_VALUE_IF_FAIL(pcall_agent_out != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
238 VOICECALL_RETURN_VALUE_IF_FAIL(*pcall_agent_out == NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
240 /*Initialize Call Agent*/
241 pcall_agent = _vc_core_ca_init_agent();
242 if (NULL == pcall_agent) {
243 return ERROR_VOICECALL_MEMALLOC_FAILURE;
246 if (FALSE == __call_vc_subscribe_call_events(pcall_agent)) {
247 CALL_ENG_DEBUG(ENG_DEBUG, "Event Subscrition Failed");
248 _vc_core_ca_finish_agent(pcall_agent);
249 return ERROR_VOICECALL_NOTI_FAILED;
251 /*Store the Callback Pointer*/
252 pcall_agent->client_callback = pcallback_func;
253 pcall_agent->puser_data = puser_data;
255 /*Calls to Tapi Should not be made in the application initialization, because this code will be executed if application is launched during
256 an incoming call also. so DBus Lock up can happen.*/
257 gphone_init_finished = TRUE;
259 /*Init Success, Assign Output Parameters*/
260 *pcall_agent_out = (voicecall_engine_t *)pcall_agent;
262 return ERROR_VOICECALL_NONE;
265 void _vc_core_engine_handle_sat_events_cb(void *sat_setup_call_data, void *userdata)
267 char *data = sat_setup_call_data;
269 call_vc_callagent_state_t *pcall_agent = gpcall_agent_for_callback;
271 CALL_ENG_DEBUG(ENG_DEBUG, "sat event callback.");
273 memset(&gSatSetupCallInfo, 0, sizeof(TelSatSetupCallIndCallData_t));
274 memcpy(&gSatSetupCallInfo, data, sizeof(TelSatSetupCallIndCallData_t));
276 gsat_event_type = SAT_RQST_SETUP_CALL;
277 //gtype = TAPI_EVENT_SAT_SETUP_CALL_IND;
278 gpresult = &gSatSetupCallInfo;
279 g_idle_add(__call_vc_sat_idle_cb, pcall_agent);
281 CALL_ENG_DEBUG(ENG_DEBUG, "Call back Ends and returning..");
284 static void __call_vc_handle_sat_engine_events_cb(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
286 // call_vc_callagent_state_t *pcall_agent = gpcall_agent_for_callback;
288 CALL_ENG_DEBUG(ENG_DEBUG, "sat event callback.");
291 int event_type = event->EventType;
292 /*int status = event->Status;*/
293 char *data = event->pData;
295 switch (event_type) {
296 case TAPI_EVENT_SAT_SETUP_CALL_IND:
298 /*it will be processed in _vc_core_engine_handle_sat_events_cb().*/
303 case TAPI_EVENT_SAT_SEND_DTMF_IND:
305 /* async for SAT sync noti */
306 memset(&gSatSendDtmfInfo, 0, sizeof(TelSatSendDtmfIndDtmfData_t));
307 memcpy(&gSatSendDtmfInfo, data, sizeof(TelSatSendDtmfIndDtmfData_t));
309 gsat_event_type = SAT_RQST_SEND_DTMF;
311 gpresult = &gSatSendDtmfInfo;
313 g_idle_add(__call_vc_sat_idle_cb, pcall_agent);
317 case TAPI_EVENT_SAT_CALL_CONTROL_IND:
319 __call_vc_handle_sat_engine_events(pcall_agent, VC_ACTION_SAT_RESPONSE, SAT_RESP_SETUP_CALL, event_type, data);
324 CALL_ENG_DEBUG(ENG_DEBUG, "Default: event_type = %d", event_type);
328 CALL_ENG_DEBUG(ENG_DEBUG, "Call back Ends and returning..");
330 /*Send Process Termintate Event to the Client */
331 if ((event_type == TAPI_EVENT_SAT_SETUP_CALL_IND) || (event_type == TAPI_EVENT_SAT_SEND_DTMF_IND)) {
332 CALL_ENG_DEBUG(ENG_DEBUG, "Do not check an active task here");
334 __vc_core_check_engine_active_task(pcall_agent);
339 /*Subscribe Noti Events*/
340 static gboolean __call_vc_subscribe_call_events(call_vc_callagent_state_t *pcall_agent)
342 CALL_ENG_KPI("__call_vc_subscribe_tapi_event start");
343 /* Subscribe Tapi Events */
344 if (FALSE == __call_vc_subscribe_tapi_event(pcall_agent)) {
345 CALL_ENG_DEBUG(ENG_DEBUG, "Noti subscribe to Tapi Events failed");
349 CALL_ENG_KPI("__call_vc_subscribe_tapi_event done");
351 CALL_ENG_DEBUG(ENG_DEBUG, "Noti Subscription Sucess");
356 * This function sends response event to the registered client
358 * @return This function returns TRUE on success and FALSE on failure
359 * @param[in] pcall_agent Pointer to the call agent structure
360 * @param[in] event response event type
361 * @param[in] param1 param 1 to be passed to the client
362 * @param[in] param2 param 2 to be passed to the client
363 * @param[in] param3 param 3 to be passed to the client
365 gboolean _vc_core_ca_send_event_to_client(call_vc_callagent_state_t *pcall_agent, int event, int param1, int param2, void *param3)
367 CALL_ENG_DEBUG(ENG_DEBUG, "Sending Event to Client");
368 if (pcall_agent->client_callback != NULL) {
369 return pcall_agent->client_callback(event, param1, param2, param3, pcall_agent->puser_data);
374 static void __call_vc_tapi_initialized_cb(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
376 call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
377 TapiResult_t tapi_err = TAPI_API_SUCCESS;
378 TelSimCardStatus_t sim_status = 0;
379 TelSimCardType_t card_type = 0;
382 VOICECALL_RETURN_IF_FAIL(data != NULL);
383 tapi_power_phone_power_status_t *power = (tapi_power_phone_power_status_t *)data;
385 if (power != TAPI_PHONE_POWER_STATUS_ON) {
386 CALL_ENG_DEBUG(ENG_DEBUG, "Modem is not available");
390 CALL_ENG_DEBUG(ENG_DEBUG, "gphone_init_finished %d", gphone_init_finished);
392 if (gphone_init_finished != TRUE) {
393 gphone_init_finished = TRUE;
395 CALL_ENG_DEBUG(ENG_DEBUG, "Query Card Status ..");
397 memset(&sim_status, 0, sizeof(sim_status));
398 tapi_err = tel_get_sim_init_info(pagent->tapi_handle, &sim_status, &sim_changed);
400 if (TAPI_API_SUCCESS != tapi_err) {
401 CALL_ENG_DEBUG(ENG_DEBUG, "tel_get_sim_init_info failed.. tapi_err = %d", tapi_err);
402 pagent->bis_no_sim = TRUE;
405 tapi_err = tel_get_sim_type(pagent->tapi_handle, &card_type);
406 if (TAPI_API_SUCCESS == tapi_err) {
407 CALL_ENG_DEBUG(ENG_DEBUG, "tel_get_sim_type failed.. tapi_err = %d", tapi_err);
410 pagent->card_type = card_type;
412 CALL_ENG_DEBUG(ENG_DEBUG, "card_status = %d, card_type = %d", sim_status, pagent->card_type);
413 /*Telephony team's reqeust..*/
414 switch (sim_status) {
415 case TAPI_SIM_STATUS_CARD_NOT_PRESENT: /* = 0x01, < Card not present */
416 case TAPI_SIM_STATUS_CARD_REMOVED: /* =0x0b, < Card removed **/
417 pagent->bis_no_sim = TRUE;
419 case TAPI_SIM_STATUS_CARD_ERROR: /* = 0x00, < Bad card / On the fly SIM gone bad **/
420 case TAPI_SIM_STATUS_SIM_INITIALIZING: /* = 0x02, < Sim is Initializing state **/
421 case TAPI_SIM_STATUS_SIM_INIT_COMPLETED: /* = 0x03, < Sim Initialization ok **/
422 case TAPI_SIM_STATUS_SIM_PIN_REQUIRED: /* = 0x04, < PIN required state **/
423 case TAPI_SIM_STATUS_SIM_PUK_REQUIRED: /* = 0x05, < PUK required state **/
424 case TAPI_SIM_STATUS_CARD_BLOCKED: /* = 0x06, < PIN/PUK blocked(permanently blocked- All the attempts for PIN/PUK failed) **/
425 case TAPI_SIM_STATUS_SIM_NCK_REQUIRED: /* = 0x07, < Network Control Key required state **/
426 case TAPI_SIM_STATUS_SIM_NSCK_REQUIRED: /* = 0x08, < Network Subset Control Key required state **/
427 case TAPI_SIM_STATUS_SIM_SPCK_REQUIRED: /* = 0x09, < Service Provider Control Key required state **/
428 case TAPI_SIM_STATUS_SIM_CCK_REQUIRED: /* = 0x0a, < Corporate Control Key required state **/
429 case TAPI_SIM_STATUS_SIM_LOCK_REQUIRED:
430 pagent->bis_no_sim = FALSE;
433 CALL_ENG_DEBUG(ENG_DEBUG, "Unknown Card_status = %d", sim_status);
434 pagent->bis_no_sim = TRUE;
439 CALL_ENG_DEBUG(ENG_DEBUG, "gphone_init_finished is TRUE.");
442 /*As a Backup, whenever this event is arrived, just update this variable*/
443 gphone_init_finished = TRUE;
446 static gboolean __call_vc_subscribe_tapi_event(call_vc_callagent_state_t *pcall_agent)
450 TapiResult_t api_err = TAPI_API_SUCCESS;
453 pcall_agent->tapi_handle = tel_init(NULL);
454 if (pcall_agent->tapi_handle != NULL) {
455 CALL_ENG_DEBUG(ENG_DEBUG, "tel_init() success.");
457 CALL_ENG_DEBUG(ENG_DEBUG, "tel_init() failed.");
461 const char *call_event_list[] = {
462 TAPI_NOTI_VOICE_CALL_STATUS_IDLE,
463 TAPI_NOTI_VOICE_CALL_STATUS_ACTIVE,
464 TAPI_NOTI_VOICE_CALL_STATUS_DIALING,
465 TAPI_NOTI_VOICE_CALL_STATUS_ALERT,
466 TAPI_NOTI_VOICE_CALL_STATUS_INCOMING,
467 TAPI_NOTI_VOICE_CALL_STATUS_WAITING,
468 TAPI_NOTI_CALL_INFO_CALL_CONNECTED_LINE,
469 TAPI_NOTI_CALL_INFO_WAITING,
470 TAPI_NOTI_CALL_INFO_CUG,
471 TAPI_NOTI_CALL_INFO_FORWARDED,
472 TAPI_NOTI_CALL_INFO_BARRED_INCOMING,
473 TAPI_NOTI_CALL_INFO_BARRED_OUTGOING,
474 TAPI_NOTI_CALL_INFO_DEFLECTED,
475 TAPI_NOTI_CALL_INFO_CLIR_SUPPRESSION_REJECT,
476 TAPI_NOTI_CALL_INFO_FORWARD_UNCONDITIONAL,
477 TAPI_NOTI_CALL_INFO_FORWARD_CONDITIONAL,
478 TAPI_NOTI_CALL_INFO_CALL_LINE_IDENTITY,
479 TAPI_NOTI_CALL_INFO_CALL_NAME_INFORMATION,
480 TAPI_NOTI_CALL_INFO_FORWARDED_CALL,
481 TAPI_NOTI_CALL_INFO_CUG_CALL,
482 TAPI_NOTI_CALL_INFO_DEFLECTED_CALL,
483 TAPI_NOTI_CALL_INFO_TRANSFERED_CALL,
484 TAPI_NOTI_CALL_INFO_HELD,
485 TAPI_NOTI_CALL_INFO_ACTIVE,
486 TAPI_NOTI_CALL_INFO_JOINED,
487 TAPI_NOTI_CALL_INFO_RELEASED_ON_HOLD,
488 TAPI_NOTI_CALL_INFO_TRANSFER_ALERT,
489 TAPI_NOTI_CALL_INFO_TRANSFERED,
490 TAPI_NOTI_CALL_SOUND_WBAMR,
492 num_event = sizeof(call_event_list) / sizeof(int);
493 for (index = 0; index < num_event; index++) {
494 api_err = tel_register_noti_event(pcall_agent->tapi_handle, call_event_list[index], __call_vc_handle_tapi_events, NULL);
495 if (api_err != TAPI_API_SUCCESS) {
496 CALL_ENG_DEBUG(ENG_DEBUG, "tel_register_noti_event() failed.. event id:[%s], api_err:[%d]", call_event_list[index], api_err);
501 const char *ready_event_list[] = {
502 TAPI_NOTI_MODEM_POWER,
504 num_event = sizeof(ready_event_list) / sizeof(int);
505 for (index = 0; index < num_event; index++) {
506 api_err = tel_register_noti_event(pcall_agent->tapi_handle, ready_event_list[index], __call_vc_tapi_initialized_cb, NULL);
507 if (api_err != TAPI_API_SUCCESS) {
508 CALL_ENG_DEBUG(ENG_DEBUG, "tel_register_noti_event() failed.. event id:[%s], api_err:[%d]", ready_event_list[index], api_err);
514 const char *sat_event_list[] = {
515 "SETUP CALL"/*TAPI_EVENT_SAT_SETUP_CALL_IND*/,
516 "CALL CONTROL" /*TAPI_EVENT_SAT_CALL_CONTROL_IND*/,
517 "SEND DTMF" /*TAPI_EVENT_SAT_SEND_DTMF_IND*/, /*CALL_VC_SIMATK_EVENT_MAX_NUM : 3*/
519 num_event = sizeof(sat_event_list) / sizeof(int);
520 for (index = 0; index < num_event; index++) {
521 api_err = tel_register_noti_event(pcall_agent->tapi_handle, sat_event_list[index], __call_vc_handle_sat_engine_events_cb, NULL);
522 if (api_err != TAPI_API_SUCCESS) {
523 CALL_ENG_DEBUG(ENG_DEBUG, "tel_register_noti_event() failed.. event id:[%s], api_err:[%d]", sat_event_list[index], api_err);
529 gpcall_agent_for_callback = pcall_agent;
531 CALL_ENG_DEBUG(ENG_DEBUG, "Subscribe to TAPI Success");
537 static gboolean __call_vc_create_outgoing_callinfo(call_vc_callagent_state_t *pagent, voicecall_setup_info_t *psetup_call_info, call_vc_call_objectinfo_t *pcall_object, int *error_code)
539 char call_number[VC_PHONE_NUMBER_LENGTH_MAX] = { 0, };
541 CALL_ENG_DEBUG(ENG_DEBUG, "call_type=%d", psetup_call_info->call_type);
543 _vc_core_cm_clear_call_object(pcall_object);
545 /*Update CallObjects state to Prepare Outgoing*/
546 pcall_object->state = VC_CALL_STATE_PREPARE_OUTGOING;
548 /*Update Call|Objects Call Type*/
549 pcall_object->call_type = psetup_call_info->call_type;
551 /*Update Call Objects Identity*/
552 pcall_object->identity_mode = psetup_call_info->identity_mode;
554 /*Differentiate the call by its source of origination*/
555 switch (pcall_object->call_type) {
556 case VC_CALL_ORIG_TYPE_EMERGENCY:
558 pcall_object->bemergency_number = TRUE;
559 _vc_core_util_strcpy(pcall_object->source_tel_number, sizeof(pcall_object->source_tel_number), psetup_call_info->source_tel_number);
560 _vc_core_util_strcpy(pcall_object->tel_number, sizeof(pcall_object->tel_number), psetup_call_info->tel_number);
564 case VC_CALL_ORIG_TYPE_PINLOCK:
566 CALL_ENG_DEBUG(ENG_DEBUG, "PIN LOCK!!!!");
567 _vc_core_util_strcpy(pcall_object->source_tel_number, sizeof(pcall_object->source_tel_number), psetup_call_info->source_tel_number);
568 _vc_core_util_strcpy(pcall_object->tel_number, sizeof(pcall_object->tel_number), psetup_call_info->tel_number);
571 case VC_CALL_ORIG_TYPE_NOSIM: /*no sim (pagent->bis_no_sim == TRUE)*/
573 _vc_core_util_strcpy(pcall_object->source_tel_number, sizeof(pcall_object->source_tel_number), psetup_call_info->source_tel_number);
574 _vc_core_util_strcpy(pcall_object->tel_number, sizeof(pcall_object->tel_number), psetup_call_info->tel_number);
577 case VC_CALL_ORIG_TYPE_NORMAL:
578 case VC_CALL_ORIG_TYPE_SAT:
580 _vc_core_util_strcpy(pcall_object->source_tel_number, sizeof(pcall_object->source_tel_number), psetup_call_info->source_tel_number);
581 _vc_core_util_strcpy(pcall_object->tel_number, sizeof(pcall_object->tel_number), psetup_call_info->tel_number);
584 case VC_CALL_ORIG_TYPE_VOICEMAIL:
586 _vc_core_util_strcpy(pcall_object->source_tel_number, sizeof(pcall_object->source_tel_number), psetup_call_info->source_tel_number);
587 _vc_core_util_strcpy(pcall_object->tel_number, sizeof(pcall_object->tel_number), psetup_call_info->tel_number);
591 CALL_ENG_DEBUG(ENG_DEBUG, "Invalide Call Type: %d", pcall_object->call_type);
592 *error_code = ERROR_VOICECALL_INVALID_CALL_TYPE;
596 /*Copy CUG Details */
597 memcpy(&pcall_object->cug_info, &psetup_call_info->cug_info, sizeof(voicecall_cug_info_t));
599 /*Check for Emergency Number */
600 _vc_core_util_extract_call_number(pcall_object->tel_number, call_number, sizeof(call_number));
601 pcall_object->bemergency_number = _vc_core_ecc_check_emergency_number(pagent->tapi_handle, pagent->card_type, call_number, pagent->bis_no_sim, &pcall_object->ecc_category);
603 CALL_ENG_DEBUG(ENG_DEBUG, "no_sim=%d, emergency_number=%d", pagent->bis_no_sim, pcall_object->bemergency_number);
605 if (VC_CALL_ORIG_TYPE_PINLOCK == pcall_object->call_type && pcall_object->bemergency_number == FALSE) {
606 CALL_ENG_DEBUG(ENG_DEBUG, "PIN/PUK Lock and number is no emergency number, call cannot be made");
607 *error_code = ERROR_VOICECALL_EMERGENCY_CALLS_ONLY;
611 if (pagent->bis_no_sim == TRUE && pcall_object->bemergency_number == FALSE) {
612 CALL_ENG_DEBUG(ENG_DEBUG, "Sim Not available and number is no emergency number, call cannot be made");
613 *error_code = ERROR_VOICECALL_CALL_IMPOSSIBLE_NOSIM_NOEMERGNUM;
617 if (TRUE == pcall_object->bemergency_number) {
618 CALL_ENG_DEBUG(ENG_DEBUG, "Number is Emergency Number, Change call type to emergency");
619 psetup_call_info->call_type = pcall_object->call_type = VC_CALL_ORIG_TYPE_EMERGENCY;
620 psetup_call_info->ecc_category = pcall_object->ecc_category;
626 static gboolean __call_vc_request_sat_call(call_vc_callagent_state_t *pagent, int mo_call_index, int *ret_code)
628 call_vc_call_objectinfo_t callInfo;
629 TelSatCmdQualiSetupCall_t sat_request_type = 0;
631 CALL_ENG_DEBUG(ENG_DEBUG, "mo_call_index = %d", mo_call_index);
633 VOICECALL_RETURN_FALSE_IF_FAIL(pagent->call_manager.setupcall_info.mocall_index == mo_call_index);
635 if (FALSE == _vc_core_cm_get_outgoing_call_info(&pagent->call_manager, &callInfo)) {
636 CALL_ENG_DEBUG(ENG_DEBUG, "Outgoing call info does not exist!");
637 *ret_code = ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
641 sat_request_type = pagent->call_manager.setupcall_info.satcall_setup_info.satengine_setupcall_data.calltype;
643 CALL_ENG_DEBUG(ENG_DEBUG, " SAT_CALL sat_request_type=%d", sat_request_type);
645 switch (sat_request_type) {
646 case TAPI_SAT_SETUP_CALL_IF_ANOTHER_CALL_NOT_BUSY_WITH_REDIAL:
648 pagent->call_manager.setupcall_info.satcall_setup_info.redial = TRUE;
650 case TAPI_SAT_SETUP_CALL_IF_ANOTHER_CALL_NOT_BUSY: /*Fall Through*/
652 /* one is the call set up by SAT, so more than 1 means another call exists */
653 if (_vc_core_cm_get_call_member_count(&pagent->call_manager) > 1) {
654 /* voice call agent is busy */
655 CALL_ENG_DEBUG(ENG_DEBUG, "Call Exists, SAT call connot be continued");
656 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND);
657 _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
658 *ret_code = ERROR_VOICECALL_CALL_NOT_ALLOWED;
662 _vc_core_cm_set_outgoing_call_info(&pagent->call_manager, &callInfo);
664 if (_vc_core_tapi_rqst_prepare_setup_call(pagent) == FALSE) {
665 CALL_ENG_DEBUG(ENG_DEBUG, "SAT_CALL fail to setup call");
666 _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
667 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND);
668 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_OUTGOING_ABORTED);
669 *ret_code = ERROR_VOICECALL_TAPI_CAUSE_CALL_FAILED;
672 CALL_ENG_DEBUG(ENG_DEBUG, "Prepare Setup Call Success");
676 case TAPI_SAT_SETUP_CALL_PUT_ALL_OTHER_CALLS_ON_HOLD_WITH_REDIAL:
678 pagent->call_manager.setupcall_info.satcall_setup_info.redial = TRUE;
680 case TAPI_SAT_SETUP_CALL_PUT_ALL_OTHER_CALLS_ON_HOLD: /*Fall Through */
682 if (_vc_core_cm_isexists_active_call(&pagent->call_manager) && _vc_core_cm_isexists_held_call(&pagent->call_manager)) {
683 CALL_ENG_DEBUG(ENG_DEBUG, "Both Activee & Hld call exists, SAT Call cannot be continued");
684 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND);
685 _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
686 *ret_code = ERROR_VOICECALL_CALL_NOT_ALLOWED;
689 if (_vc_core_cm_isexists_connected_call(&pagent->call_manager)) {
690 if (FALSE == _vc_core_tapi_rqst_prepare_setup_call(pagent)) {
691 CALL_ENG_DEBUG(ENG_DEBUG, "SAT_CALL hold fail");
692 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND);
693 _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
694 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_OUTGOING_ABORTED);
695 *ret_code = ERROR_VOICECALL_TAPI_CAUSE_CALL_FAILED;
699 /*If no other calls to hold, setup the call directly */
700 if (FALSE == _vc_core_tapi_rqst_setup_call(pagent)) {
701 CALL_ENG_DEBUG(ENG_DEBUG, "SAT_CALL fail to setup call");
702 _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
703 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND);
704 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_OUTGOING_ABORTED);
705 *ret_code = ERROR_VOICECALL_TAPI_CAUSE_CALL_FAILED;
711 case TAPI_SAT_SETUP_CALL_DISCONN_ALL_OTHER_CALLS_WITH_REDIAL:
713 pagent->call_manager.setupcall_info.satcall_setup_info.redial = TRUE;
715 case TAPI_SAT_SETUP_CALL_DISCONN_ALL_OTHER_CALLS: /*Fall Through */
717 if (_vc_core_cm_isexists_active_call(&pagent->call_manager) || _vc_core_cm_isexists_held_call(&pagent->call_manager)) {
718 /*Disconnect all calls and setup call */
719 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_RELEASE_ALL_CALLS_TO_SETUP);
720 _vc_core_tapi_rqst_release_all_calls(pagent);
722 if (FALSE == _vc_core_tapi_rqst_prepare_setup_call(pagent)) {
723 CALL_ENG_DEBUG(ENG_DEBUG, "SAT_CALL fail to setup call");
724 _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
725 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND);
726 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_OUTGOING_ABORTED);
727 *ret_code = ERROR_VOICECALL_TAPI_CAUSE_CALL_FAILED;
734 CALL_ENG_DEBUG(ENG_DEBUG, "Action not defined for this SAT Request Type");
741 static gboolean __call_vc_request_call(call_vc_callagent_state_t *pagent, int mo_call_index, int *ret_code)
743 call_vc_call_objectinfo_t callInfo;
745 CALL_ENG_DEBUG(ENG_DEBUG, "");
747 VOICECALL_RETURN_FALSE_IF_FAIL(pagent->call_manager.setupcall_info.mocall_index == mo_call_index);
749 _vc_core_cm_clear_call_object(&callInfo);
750 if (_vc_core_cm_get_outgoing_call_info(&pagent->call_manager, &callInfo) == FALSE) {
751 CALL_ENG_DEBUG(ENG_DEBUG, "Outgoing call info does not exist!");
752 *ret_code = ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
755 /*Switch according to the CallType requested*/
756 switch (callInfo.call_type) {
757 case VC_CALL_ORIG_TYPE_NORMAL:
758 case VC_CALL_ORIG_TYPE_EMERGENCY:
759 case VC_CALL_ORIG_TYPE_NOSIM:
760 case VC_CALL_ORIG_TYPE_SAT:
761 case VC_CALL_ORIG_TYPE_PINLOCK:
763 /*Set the updated Object Info to the Call Manager*/
764 _vc_core_cm_set_outgoing_call_info(&pagent->call_manager, &callInfo);
766 if (_vc_core_tapi_rqst_prepare_setup_call(pagent) == FALSE) {
767 _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
768 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_OUTGOING_ABORTED);
769 *ret_code = ERROR_VOICECALL_TAPI_CAUSE_CALL_FAILED;
770 CALL_ENG_DEBUG(ENG_DEBUG, "Prepare Setup Call Failed");
774 CALL_ENG_DEBUG(ENG_DEBUG, "Prepare Setup Call Success");
779 *ret_code = ERROR_VOICECALL_INVALID_CALL_TYPE;
780 CALL_ENG_DEBUG(ENG_DEBUG, "Not defined call type=%d", pagent->call_manager.setupcall_info.call_type);
789 * This function prepares the call setup info structure for making call
791 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
792 * @param[in] pvoicecall_agent Handle to voicecall engine
793 * @param[in] psetup_call_info Pointer to the call setup info structure.
794 * @remarks pvoicecall_agent and psetup_call_info cannot be NULL
795 * Only on successfull completion of this API, _vc_core_engine_make_call can be made
796 * @see See following API's also
797 * -_vc_core_engine_make_call
798 * -voicecall_clear_prepared_call
801 voicecall_error_t _vc_core_engine_prepare_call(voicecall_engine_t *pvoicecall_agent, voicecall_setup_info_t *psetup_call_info)
803 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
804 call_vc_call_objectinfo_t callobject_info;
805 TapiResult_t tapi_err = TAPI_API_SUCCESS;
806 TelSimCardStatus_t sim_status;
807 TelSimCardType_t card_type = 0;
813 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
814 VOICECALL_RETURN_VALUE_IF_FAIL(psetup_call_info != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
816 CALL_ENG_DEBUG(ENG_DEBUG, "");
818 if (FALSE == _vc_core_util_isvalid_telephone_number(psetup_call_info->tel_number)) {
819 return ERROR_VOICECALL_INVALID_TELEPHONE_NUMBER;
822 CALL_ENG_KPI("tel_check_modem_power_status start");
823 tapi_err = tel_check_modem_power_status(pagent->tapi_handle, &status);
824 CALL_ENG_KPI("tel_check_modem_power_status done");
825 if (TAPI_API_SUCCESS != tapi_err || 1 /* offline */ == status || 2 /* Error */== status) {
826 CALL_ENG_DEBUG(ENG_DEBUG, "Tapi not initialized");
827 return ERROR_VOICECALL_PHONE_NOT_INITIALIZED;
829 /*Check the Call Engines IO State*/
830 if (pagent->io_state != VC_INOUT_STATE_NONE && pagent->io_state != VC_INOUT_STATE_OUTGOING_SHOW_RETRY_CALLBOX) {
831 CALL_ENG_DEBUG(ENG_DEBUG, "pagent->io_state != VC_INOUT_STATE_NONE..io_state=%d", pagent->io_state);
832 return ERROR_VOICECALL_ENGINE_STATE_NOT_NONE;
835 CALL_ENG_DEBUG(ENG_DEBUG, "Checking for SIM Availablity");
837 /*memset(&sim_status, 0, sizeof(sim_status));*/
838 CALL_ENG_KPI("tel_get_sim_init_info start");
839 tapi_err = tel_get_sim_init_info(pagent->tapi_handle, &sim_status, &sim_changed);
840 CALL_ENG_KPI("tel_get_sim_init_info done");
842 if (TAPI_API_SUCCESS != tapi_err) {
843 CALL_ENG_DEBUG(ENG_DEBUG, "tel_get_sim_init_info failed.. tapi_err = %d", tapi_err);
845 pagent->bis_no_sim = TRUE;
846 psetup_call_info->call_type = VC_CALL_ORIG_TYPE_NOSIM;
848 CALL_ENG_KPI("tel_get_sim_type start");
849 tapi_err = tel_get_sim_type(pagent->tapi_handle, &card_type);
850 if (TAPI_API_SUCCESS != tapi_err) {
851 CALL_ENG_DEBUG(ENG_DEBUG, "tel_get_sim_type failed.. tapi_err = %d", tapi_err);
853 CALL_ENG_KPI("tel_get_sim_type done");
854 pagent->card_type = card_type;
856 CALL_ENG_DEBUG(ENG_DEBUG, "card_status = %d, card_type = %d", sim_status, pagent->card_type);
857 switch (sim_status) {
858 case TAPI_SIM_STATUS_CARD_NOT_PRESENT: /* = 0x01, < Card not present **/
859 case TAPI_SIM_STATUS_CARD_REMOVED: /* =0x0b, < Card removed **/
860 pagent->bis_no_sim = TRUE;
862 case TAPI_SIM_STATUS_CARD_ERROR: /* = 0x00, < Bad card / On the fly SIM gone bad **/
863 case TAPI_SIM_STATUS_SIM_INITIALIZING: /* = 0x02, < Sim is Initializing state **/
864 case TAPI_SIM_STATUS_SIM_INIT_COMPLETED: /* = 0x03, < Sim Initialization ok **/
865 case TAPI_SIM_STATUS_SIM_PIN_REQUIRED: /* = 0x04, < PIN required state **/
866 case TAPI_SIM_STATUS_SIM_PUK_REQUIRED: /* = 0x05, < PUK required state **/
867 case TAPI_SIM_STATUS_CARD_BLOCKED: /* = 0x06, < PIN/PUK blocked(permanently blocked- All the attempts for PIN/PUK failed) **/
868 case TAPI_SIM_STATUS_SIM_NCK_REQUIRED: /* = 0x07, < Network Control Key required state **/
869 case TAPI_SIM_STATUS_SIM_NSCK_REQUIRED: /* = 0x08, < Network Subset Control Key required state **/
870 case TAPI_SIM_STATUS_SIM_SPCK_REQUIRED: /* = 0x09, < Service Provider Control Key required state **/
871 case TAPI_SIM_STATUS_SIM_CCK_REQUIRED: /* = 0x0a, < Corporate Control Key required state **/
872 case TAPI_SIM_STATUS_SIM_LOCK_REQUIRED:
873 pagent->bis_no_sim = FALSE;
876 CALL_ENG_DEBUG(ENG_DEBUG, "Unknown Card_status = %d", sim_status);
877 pagent->bis_no_sim = TRUE;
882 /*Prepare Outgoing Call Info*/
883 _vc_core_cm_clear_call_object(&callobject_info);
884 if (__call_vc_create_outgoing_callinfo(pagent, psetup_call_info, &callobject_info, &error_code) == FALSE) {
888 /* Check for MO Call Possiblity */
889 if (_vc_core_ca_is_mocall_possible(pagent, callobject_info.bemergency_number) == FALSE) {
890 return ERROR_VOICECALL_CALL_NOT_ALLOWED;
893 /* Add the prepared call object to the CallManager */
894 nIndex = _vc_core_cm_add_call_object(&pagent->call_manager, &callobject_info);
896 /*If there is a previously made MO Call, clear that before setting the new mo call */
897 _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
898 _vc_core_cm_set_outgoing_call(&pagent->call_manager, nIndex);
899 psetup_call_info->mo_call_index = nIndex;
901 return ERROR_VOICECALL_CALL_NOT_ALLOWED;
904 return ERROR_VOICECALL_NONE;
908 * This function clears the data of the given call type.
910 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
911 * @param[in] pvoicecall_agent Handle to voicecall engine
912 * @param[in] call_type call type
913 * @param[in] call_handle Call handle of the connected call to be cleared
914 * @remarks This will clear the call data only when the call data are currently not being used
915 * i,e) the data will be cleared only if the corresponding call is ended or the call data is not used at all.
916 * call_handle argument is required only in case of connected call, Engine ignores call_handle for other
919 voicecall_error_t _vc_core_engine_finalize_call(voicecall_engine_t *pvoicecall_agent, voicecall_call_type_t call_type, int call_handle)
921 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
922 gboolean bret_val = FALSE;
924 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
926 CALL_ENG_DEBUG(ENG_DEBUG, "call_type = %d", call_type);
929 case VC_OUTGOING_CALL:
931 if ((VC_INOUT_STATE_OUTGOING_WAIT_CONNECTED == pagent->io_state) || (VC_INOUT_STATE_OUTGOING_WAIT_ORIG == pagent->io_state) || (VC_INOUT_STATE_OUTGOING_WAIT_ALERT == pagent->io_state)) {
932 return ERROR_VOICECALL_CALL_IS_IN_PROGRESS;
935 bret_val = _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
938 case VC_CONNECTED_CALL:
940 call_vc_call_objectinfo_t call_object;
942 if (TRUE == _vc_core_cm_get_call_object(&pagent->call_manager, call_handle, &call_object)) {
943 if (VC_CALL_STATE_ENDED == call_object.state) {
944 bret_val = _vc_core_ca_clear_connected_call(pagent, call_handle);
946 return ERROR_VOICECALL_CALL_IS_IN_PROGRESS;
951 case VC_INCOMING_CALL:
953 return ERROR_VOICECALL_NOT_SUPPORTED;
957 return ERROR_VOICECALL_INVALID_CALL_TYPE;
960 return (TRUE == bret_val) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
964 * This function establishes an outgoing call with the details prepared using _vc_core_engine_prepare_call
966 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
967 * @param[in] pvoicecall_agent Handle to voicecall engine
968 * @param[in] mo_call_index Index of the prepare mo call
969 * @param[out] pcall_handle Handle of the MO Call Made
970 * @remarks pvoicecall_agent and pcall_handle cannot be NULL
971 * @see _vc_core_engine_end_call
973 voicecall_error_t _vc_core_engine_make_call(voicecall_engine_t *pvoicecall_agent, int mo_call_index, int *pcall_handle)
975 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
976 gboolean ret_val = FALSE;
977 call_vc_call_objectinfo_t call_object;
978 int error_code = ERROR_VOICECALL_NONE;
980 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
981 VOICECALL_RETURN_VALUE_IF_FAIL(mo_call_index >= 0 && mo_call_index <= 7, ERROR_VOICECALL_INVALID_ARGUMENTS);
982 VOICECALL_RETURN_VALUE_IF_FAIL(pcall_handle != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
984 CALL_ENG_DEBUG(ENG_DEBUG, "...");
986 _vc_core_cm_clear_call_object(&call_object);
987 if (_vc_core_cm_get_outgoing_call_info(&pagent->call_manager, &call_object) == FALSE) {
988 CALL_ENG_DEBUG(ENG_DEBUG, "Outgoing call info does not exist!");
989 return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
992 if (VC_CALL_ORIG_TYPE_SAT == call_object.call_type) {
993 ret_val = __call_vc_request_sat_call(pagent, mo_call_index, &error_code);
995 ret_val = __call_vc_request_call(pagent, mo_call_index, &error_code);
998 if ((TRUE == ret_val) && (pagent->io_state == VC_INOUT_STATE_OUTGOING_WAIT_ALERT || pagent->io_state == VC_INOUT_STATE_OUTGOING_WAIT_CONNECTED || pagent->io_state == VC_INOUT_STATE_OUTGOING_WAIT_ORIG)) {
999 *pcall_handle = _vc_core_cm_get_outgoing_call_handle(&pagent->call_manager);
1000 CALL_ENG_DEBUG(ENG_DEBUG, "Outgoing call Handle: %d", *pcall_handle);
1004 return (TRUE == ret_val) ? ERROR_VOICECALL_NONE : error_code;
1007 static gboolean __call_vc_handle_sat_engine_events(call_vc_callagent_state_t *pcall_agent, int sat_event, int sat_event_type, int type, void *result)
1009 call_vc_callagent_state_t *pagent = pcall_agent;
1010 call_vc_satsetup_info_t *psatsetup_info = NULL;
1011 voicecall_sat_callinfo_t call_vc_sat_callinfo;
1013 VOICECALL_RETURN_FALSE_IF_FAIL(pcall_agent != NULL);
1015 CALL_ENG_DEBUG(ENG_DEBUG, "sat_event: %d, sat_event_type: %d, command_type: %d", sat_event, sat_event_type, type);
1017 psatsetup_info = (call_vc_satsetup_info_t *) &(pagent->call_manager.setupcall_info.satcall_setup_info);
1019 switch (sat_event) {
1020 case VC_ACTION_SAT_REQUEST:
1022 switch (sat_event_type) {
1023 case SAT_RQST_SETUP_CALL:
1025 CALL_ENG_DEBUG(ENG_DEBUG, "SAT_RQST_SETUP_CALL SAT Event is recieved...");
1027 if ((pagent->io_state != VC_INOUT_STATE_NONE) || (pagent->callagent_state != CALL_VC_CA_STATE_NORMAL)) {
1028 CALL_ENG_DEBUG(ENG_DEBUG, "SAT_CALL unable to process command!");
1029 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND);
1033 /*Initialize Call Setup Data */
1034 psatsetup_info->psat_rgb_data = NULL;
1035 memset(&(psatsetup_info->satengine_setupcall_data), 0, sizeof(TelSatSetupCallIndCallData_t));
1036 memcpy(&(psatsetup_info->satengine_setupcall_data), result, sizeof(TelSatSetupCallIndCallData_t));
1037 psatsetup_info->satengine_event_type = type;
1038 memset(&call_vc_sat_callinfo, 0, sizeof(voicecall_sat_callinfo_t));
1040 _vc_core_util_strcpy(call_vc_sat_callinfo.call_number, sizeof(call_vc_sat_callinfo.call_number), (char *)psatsetup_info->satengine_setupcall_data.callNumber.string);
1041 _vc_core_util_strcpy(call_vc_sat_callinfo.disp_text, sizeof(call_vc_sat_callinfo.disp_text), (char *)psatsetup_info->satengine_setupcall_data.dispText.string);
1042 call_vc_sat_callinfo.duration = psatsetup_info->satengine_setupcall_data.duration;
1043 if (call_vc_sat_callinfo.duration > 0) {
1044 psatsetup_info->bduration = TRUE;
1046 /*Store the duration, this remaining duration will be reduced in subsequent redial attempts */
1047 psatsetup_info->remaining_duration = call_vc_sat_callinfo.duration;
1049 CALL_ENG_DEBUG(ENG_DEBUG, "Voice call set up request sent to voice call application psatsetup_info->bduration = %d", psatsetup_info->bduration);
1050 CALL_ENG_DEBUG(ENG_DEBUG, "psatsetup_info->remaining_duration = %lu", psatsetup_info->remaining_duration);
1051 CALL_ENG_DEBUG(ENG_DEBUG, "sat call type = %d", psatsetup_info->satengine_setupcall_data.calltype);
1053 _vc_core_ca_send_event_to_client(pagent, VC_ACTION_SAT_REQUEST, SAT_RQST_SETUP_CALL, 0, &call_vc_sat_callinfo);
1056 case SAT_RQST_SEND_DTMF:
1058 memset(&(psatsetup_info->satengine_dtmf_data), 0, sizeof(TelSatSendDtmfIndDtmfData_t));
1059 memcpy(&(psatsetup_info->satengine_dtmf_data), result, sizeof(TelSatSendDtmfIndDtmfData_t));
1060 psatsetup_info->satengine_event_type = type;
1062 if (FALSE == __vc_core_is_dtmf_possible(pagent)) {
1063 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SEND_DTMF, CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND);
1065 memset(&call_vc_sat_callinfo, 0, sizeof(voicecall_sat_callinfo_t));
1067 _vc_core_util_strcpy(call_vc_sat_callinfo.call_number, sizeof(call_vc_sat_callinfo.call_number), (char *)psatsetup_info->satengine_dtmf_data.dtmfString.string);
1068 call_vc_sat_callinfo.bsat_hidden = psatsetup_info->satengine_dtmf_data.bIsHiddenMode;
1069 _vc_core_ca_send_event_to_client(pagent, VC_ACTION_SAT_REQUEST, SAT_RQST_SEND_DTMF, 0, &call_vc_sat_callinfo);
1076 case VC_ACTION_SAT_RESPONSE:
1078 call_vc_call_objectinfo_t objectInfo;
1079 switch (sat_event_type) {
1080 case SAT_RESP_SETUP_CALL:
1082 if (_vc_core_cm_get_outgoing_call_info(&pagent->call_manager, &objectInfo) == FALSE) {
1083 CALL_ENG_DEBUG(ENG_DEBUG, "SAT_CALL_CONTROL Outgoing call info does not exist..");
1084 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_NONE);
1087 memset(&(psatsetup_info->satengine_callctrl_data), 0, sizeof(psatsetup_info->satengine_callctrl_data));
1088 memcpy(&(psatsetup_info->satengine_callctrl_data), result, sizeof(psatsetup_info->satengine_callctrl_data));
1090 switch (psatsetup_info->satengine_callctrl_data.callCtrlResult) {
1091 case TAPI_SAT_CALL_CTRL_R_ALLOWED_NO_MOD:
1093 CALL_ENG_DEBUG(ENG_DEBUG, "ret=TAPI_SAT_CALL_CTRL_R_ALLOWED_NO_MOD");
1094 pagent->call_manager.setupcall_info.call_control_type = CALL_VC_SAT_CC_ALLOWED;
1097 case TAPI_SAT_CALL_CTRL_R_NOT_ALLOWED:
1099 CALL_ENG_DEBUG(ENG_DEBUG, "ret=TAPI_SAT_CALL_CTRL_R_NOT_ALLOWED");
1100 pagent->call_manager.setupcall_info.call_control_type = CALL_VC_SAT_CC_NOT_ALLOWED;
1101 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_NONE);
1103 if (objectInfo.call_type == VC_CALL_ORIG_TYPE_SAT) {
1104 _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
1105 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_CONTROL_PERMANENT_PROBLEM);
1107 _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
1110 memset(&call_vc_sat_callinfo, 0, sizeof(voicecall_sat_callinfo_t));
1111 call_vc_sat_callinfo.sat_mo_call_ctrl_res = CALL_NOT_ALLOWED;
1112 _vc_core_ca_send_event_to_client(pagent, VC_ACTION_SAT_RESPONSE, SAT_RESP_SETUP_CALL, 0, &call_vc_sat_callinfo);
1115 case TAPI_SAT_CALL_CTRL_R_ALLOWED_WITH_MOD:
1117 gboolean bsscode = FALSE;
1119 CALL_ENG_DEBUG(ENG_DEBUG, "ret=TAPI_SAT_CALL_CTRL_R_ALLOWED_WITH_MOD");
1120 pagent->call_manager.setupcall_info.call_control_type = CALL_VC_SAT_CC_ALLOWED_WITH_MODIFIED;
1122 memset(objectInfo.connected_telnumber, 0, sizeof(objectInfo.connected_telnumber));
1123 memset(objectInfo.connected_name, 0, sizeof(objectInfo.connected_name));
1125 _vc_core_util_strcpy(objectInfo.connected_telnumber, sizeof(objectInfo.connected_telnumber), (char *)psatsetup_info->satengine_callctrl_data.u.callCtrlCnfCallData.address.string);
1126 _vc_core_util_strcpy(objectInfo.connected_name, sizeof(objectInfo.connected_name), (char *)psatsetup_info->satengine_callctrl_data.dispData.string);
1128 /*Prepare the data to be sent to the client */
1129 memset(&call_vc_sat_callinfo, 0, sizeof(voicecall_sat_callinfo_t));
1130 _vc_core_util_strcpy(call_vc_sat_callinfo.call_number, sizeof(call_vc_sat_callinfo.call_number), objectInfo.connected_telnumber);
1131 _vc_core_util_strcpy(call_vc_sat_callinfo.disp_text, sizeof(call_vc_sat_callinfo.disp_text), objectInfo.connected_name);
1133 /* when call number is changed as SS string */
1134 _vc_core_engine_status_isvalid_ss_code((voicecall_engine_t *)pcall_agent, objectInfo.connected_telnumber, &bsscode);
1135 if (TRUE == bsscode) {
1136 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_NONE);
1138 call_vc_sat_callinfo.sat_mo_call_ctrl_res = CALL_CHANGED_TO_SS;
1139 CALL_ENG_DEBUG(ENG_DEBUG, "VC Call Control Response Event: %d", call_vc_sat_callinfo.sat_mo_call_ctrl_res);
1141 objectInfo.bemergency_number = _vc_core_ecc_check_emergency_number(pagent->tapi_handle, pagent->card_type, objectInfo.connected_telnumber, pagent->bis_no_sim, &objectInfo.ecc_category);
1142 _vc_core_cm_set_outgoing_call_info(&pagent->call_manager, &objectInfo);
1144 call_vc_sat_callinfo.duration = psatsetup_info->satengine_setupcall_data.duration;
1145 call_vc_sat_callinfo.sat_mo_call_ctrl_res = CALL_ALLOWED_WITH_MOD;
1146 CALL_ENG_DEBUG(ENG_DEBUG, "VC Call Control Response Event: %d", call_vc_sat_callinfo.sat_mo_call_ctrl_res);
1149 /*Send the Call Control response event to the client */
1150 _vc_core_ca_send_event_to_client(pagent, VC_ACTION_SAT_RESPONSE, SAT_RESP_SETUP_CALL, 0, &call_vc_sat_callinfo);
1154 CALL_ENG_DEBUG(ENG_DEBUG, "SAT_CALL_CONTROL - not defined return code");
1160 CALL_ENG_DEBUG(ENG_DEBUG, "Invalid Sat Event Type");
1166 CALL_ENG_DEBUG(ENG_DEBUG, "Invalid SAT Event");
1172 static gboolean __call_vc_incoming_idle_cb(gpointer puser_data)
1174 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)puser_data;
1175 call_vc_call_objectinfo_t callobject_info;
1177 CALL_ENG_DEBUG(ENG_DEBUG, "Handling Incoming call in Idle Callback");
1179 if (FALSE == _vc_core_cm_get_incoming_call_info(&pagent->call_manager, &callobject_info)) {
1180 CALL_ENG_DEBUG(ENG_ERR, "Incoming Call Info not available");
1184 /*If the Incoming End event arrived before processing the Incoming request, then donot change the state to Incombox */
1185 if (pagent->io_state != VC_INOUT_STATE_INCOME_END) {
1186 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_INCOME_BOX);
1189 /* Send Incoming Call Event to Client */
1190 /*_vc_core_ca_send_event_to_client(pagent, VC_CALL_INCOM, callobject_info.call_handle, callobject_info.bincoming_call_is_fwded, callobject_info.tel_number);*/
1191 _vc_core_ca_send_event_to_client(pagent, VC_CALL_INCOM, callobject_info.call_handle, 0, callobject_info.tel_number);
1193 /* Reset Incoming Call Details */
1194 gincoming_call_handle = VC_TAPI_INVALID_CALLHANDLE;
1195 memset(&gincoming_call_info, 0, sizeof(TelCallIncomingCallInfo_t));
1197 /*Check whether the incoming call is accepted or rejected by
1198 cheking the Incoming callobjects status */
1199 if (_vc_core_cm_get_call_state(&pagent->call_manager, callobject_info.call_handle) != VC_CALL_STATE_INCOME) {
1200 CALL_ENG_DEBUG(ENG_DEBUG, "[Call :%d] not in VC_CALL_STATE_INCOME state", callobject_info.call_handle);
1204 /*Always Return FALSE from this g_idle callback, so it will not be called again */
1208 /*Rejects the call, only if the call state is in rejected state*/
1209 static gboolean __call_vc_reject_call_full_idle_cb(gpointer puser_data)
1211 call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)puser_data;
1212 TapiResult_t tapi_err = TAPI_API_SUCCESS;
1213 call_vc_call_objectinfo_t call_object;
1215 CALL_ENG_DEBUG(ENG_DEBUG, "Rejecting the [Call:%d] in IDLE CB", gincoming_call_handle);
1217 if (gincoming_call_handle != -1) {
1218 _vc_core_cm_get_call_object(&pcall_agent->call_manager, gincoming_call_handle, &call_object);
1220 if (VC_CALL_STATE_REJECTED == call_object.state) {
1221 /*Answer the incoming call by accepting or rejecting the call */
1222 tapi_err = tel_answer_call(pcall_agent->tapi_handle, gincoming_call_handle, TAPI_CALL_ANSWER_REJECT, _vc_core_engine_answer_call_resp_cb, NULL);
1223 if (TAPI_API_SUCCESS != tapi_err) {
1224 CALL_ENG_DEBUG(ENG_ERR, "tel_answer_call failed, Error: %d", tapi_err);
1227 gincoming_call_handle = -1;
1233 /*Always reject the call, if the reject call handle is valid*/
1234 static gboolean __call_vc_reject_call_idle_cb(gpointer puser_data)
1236 call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)puser_data;
1237 TapiResult_t tapi_err = TAPI_API_SUCCESS;
1239 CALL_ENG_DEBUG(ENG_DEBUG, "Rejecting the [Call Handle :%d] in IDLE CB", gincoming_call_handle);
1241 if (gphone_rejected_call != -1) {
1242 /*Answer the incoming call by accepting or rejecting the call */
1243 tapi_err = tel_answer_call(pcall_agent->tapi_handle, gphone_rejected_call, TAPI_CALL_ANSWER_REJECT, _vc_core_engine_answer_call_resp_cb, NULL);
1244 if (TAPI_API_SUCCESS != tapi_err) {
1245 CALL_ENG_DEBUG(ENG_ERR, "tel_answer_call failed, Error: %d", tapi_err);
1247 gphone_rejected_call = -1;
1252 static gboolean __call_vc_sat_idle_cb(gpointer puser_data)
1254 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)puser_data;
1256 TelSatSetupCallIndCallData_t temp_data = { 0, };
1258 memset(&temp_data, 0, sizeof(TelSatSetupCallIndCallData_t));
1259 memcpy(&temp_data, gpresult, sizeof(TelSatSetupCallIndCallData_t));
1260 CALL_ENG_DEBUG(ENG_DEBUG, "[SAT] call_data->calltype = 0x%x", temp_data.calltype);
1261 CALL_ENG_DEBUG(ENG_DEBUG, "[SAT] call_data->dispText.string = %s", temp_data.dispText.string);
1262 CALL_ENG_DEBUG(ENG_DEBUG, "[SAT] call_data->callNumber.string = %s", temp_data.callNumber.string);
1263 CALL_ENG_DEBUG(ENG_DEBUG, "[SAT] call_data->duration = %d", (int)temp_data.duration);
1265 __call_vc_handle_sat_engine_events(pagent, VC_ACTION_SAT_REQUEST, gsat_event_type, gtype, gpresult);
1267 /*Free the result after copying the data */
1268 /*g_free(gpresult);*/
1270 /*Always Return FALSE from this g_idle callback, so it will not be called again */
1274 void _vc_core_engine_handle_incoming_tapi_events(void *mt_data, void *userdata)
1276 char *data = mt_data;
1278 call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
1280 VOICECALL_RETURN_IF_FAIL(pagent != NULL);
1282 int current_mt_call_handle = -1;
1283 CALL_ENG_DEBUG(ENG_DEBUG, "event_type == TAPI_EVENT_CALL_INCOM_IND...");
1285 /*Safety Check to avoid the mutiple incoming noti for the same call */
1286 current_mt_call_handle = _vc_core_cm_get_incoming_call_handle(&pagent->call_manager);
1287 CALL_ENG_DEBUG(ENG_ERR, "current_mt_call_handle = %d", current_mt_call_handle);
1289 if (current_mt_call_handle != VC_TAPI_INVALID_CALLHANDLE) {
1290 TelCallIncomingCallInfo_t mt_call_info;
1291 CALL_ENG_DEBUG(ENG_ERR, "Already an Incoming Call exits ,Problem in accpeting the incoming call, Current Call Details");
1292 CALL_VC_DUMP_CALLDETAILS(&pagent->call_manager);
1293 CALL_ENG_DEBUG(ENG_ERR, "****************Currently received call details *************************");
1295 memset(&mt_call_info, 0, sizeof(TelCallIncomingCallInfo_t));
1296 memcpy(&mt_call_info, data, sizeof(TelCallIncomingCallInfo_t));
1297 CALL_ENG_DEBUG(ENG_ERR, "****************call handle = [%d] *************************", mt_call_info.CallHandle);
1298 CALL_ENG_DEBUG(ENG_ERR, "****************call Number = [%s] *************************", mt_call_info.szCallingPartyNumber);
1299 CALL_ENG_DEBUG(ENG_ERR, "**************** Ignoring this incoming notification *************************");
1303 memset(&gincoming_call_info, 0, sizeof(TelCallIncomingCallInfo_t));
1304 memcpy(&gincoming_call_info, data, sizeof(TelCallIncomingCallInfo_t));
1305 gincoming_call_handle = gincoming_call_info.CallHandle;
1307 CALL_ENG_DEBUG(ENG_DEBUG, "CallHandle = %d, Number = %s", gincoming_call_info.CallHandle, gincoming_call_info.szCallingPartyNumber);
1309 /* Reject the Incoming call */
1310 if (FALSE == gphone_init_finished) {
1311 CALL_ENG_DEBUG(ENG_ERR, "Phone is not initialized, So reject the Call");
1313 gphone_rejected_call = gincoming_call_handle;
1315 /*Reject the Call in the Idle Callback */
1316 g_idle_add_full(G_PRIORITY_HIGH_IDLE, __call_vc_reject_call_idle_cb, pagent, NULL);
1321 /* Check the IO State before accepting the call */
1322 switch (pagent->io_state) {
1323 case VC_INOUT_STATE_OUTGOING_WAIT_HOLD:
1324 case VC_INOUT_STATE_OUTGOING_WAIT_ALERT:
1325 case VC_INOUT_STATE_OUTGOING_WAIT_ORIG:
1326 case VC_INOUT_STATE_OUTGOING_WAIT_CONNECTED:
1327 case VC_INOUT_STATE_INCOME_END: /*If the Previous End event is still not prcocessed then reject the call */
1329 call_vc_call_objectinfo_t objectInfo;
1331 /* setting the new member info */
1332 _vc_core_cm_clear_call_object(&objectInfo);
1333 objectInfo.call_handle = gincoming_call_handle;
1334 _vc_core_cm_change_call_state(&objectInfo, VC_CALL_STATE_REJECTED);
1336 /* add new member info */
1337 _vc_core_cm_add_call_object(&pagent->call_manager, &objectInfo);
1339 /*Reject the Call in the Idle Callback */
1340 g_idle_add_full(G_PRIORITY_HIGH_IDLE, __call_vc_reject_call_full_idle_cb, pagent, NULL);
1345 /*If Outgoing call is in any of the following wait state during an Incoming Event Cancel the Outgoing Call */
1346 case VC_INOUT_STATE_OUTGOING_WAIT_RELEASE: /*If Outgoing call is in any of the following wait state during an Incoming Event Cancel the Outgoing Call */
1347 case VC_INOUT_STATE_OUTGOING_ABORTED:
1348 case VC_INOUT_STATE_OUTGOING_SHOW_REDIALCAUSE:
1349 case VC_INOUT_STATE_OUTGOING_WAIT_REDIAL:
1350 case VC_INOUT_STATE_OUTGOING_SHOW_RETRY_CALLBOX:
1352 int mo_call_handle = -1;
1353 mo_call_handle = _vc_core_cm_get_outgoing_call_handle(&pagent->call_manager);
1354 _vc_core_cm_remove_call_object(&pagent->call_manager, mo_call_handle);
1356 /* Inform the Client that waiting outgoing call are cleaned up to accept the incoming call , */
1357 _vc_core_ca_send_event_to_client(pagent, VC_ACTION_INCOM_FORCE, mo_call_handle, 0, NULL);
1363 /*If Incoming End event is still pending, First Process the incoming end indication before processing the new
1365 if (VC_INOUT_STATE_INCOME_END == pagent->io_state) {
1366 int mt_call_handle = -1;
1368 CALL_ENG_DEBUG(ENG_ERR, "Previous Incoming End Call Not processed, Processing Here");
1369 mt_call_handle = _vc_core_cm_get_incoming_call_handle(&pagent->call_manager);
1370 if (mt_call_handle != -1) {
1371 __call_vc_incomingcall_endhandle(pagent, mt_call_handle);
1375 /* Handle Incoming Call */
1376 if (TRUE == _vc_core_tapi_event_handle_incoming_event(pagent, gincoming_call_handle, &gincoming_call_info)) {
1377 CALL_ENG_DEBUG(ENG_DEBUG, "Using Idle Add Full with G_PRIORITY_HIGH_IDLE for processing Incoming Call");
1378 g_idle_add_full(G_PRIORITY_HIGH_IDLE, __call_vc_incoming_idle_cb, pagent, NULL);
1381 CALL_ENG_DEBUG(ENG_DEBUG, "MT CALL event processed done.");
1386 static void __call_vc_handle_tapi_events(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
1389 call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
1391 VOICECALL_RETURN_IF_FAIL(pagent != NULL);
1393 CALL_ENG_DEBUG(ENG_WARN, "event_type:[%s]", noti_id);
1395 /* Process TAPI events */
1396 if (strcmp(noti_id, TAPI_NOTI_VOICE_CALL_STATUS_IDLE) == 0) {
1398 call_vc_call_objectinfo_t objectInfo;
1399 voicecall_call_state_t present_call_state = VC_CALL_STATE_NONE;
1400 call_vc_handle incoming_call_handle = VC_TAPI_INVALID_CALLHANDLE;
1401 TelTapiEndCause_t tapi_cause = TAPI_CALL_END_NO_CAUSE;
1402 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1403 TelCallStatusIdleNoti_t callIdleInfo;
1405 CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_NOTI_VOICE_CALL_STATUS_IDLE..");
1407 /* tapicallback data = TelCallStatusIdleNoti_t */
1409 memset(&callIdleInfo, 0, sizeof(TelCallStatusIdleNoti_t));
1410 memcpy(&callIdleInfo, data, sizeof(TelCallStatusIdleNoti_t));
1412 call_handle = callIdleInfo.id;
1413 tapi_cause = callIdleInfo.cause;
1416 CALL_ENG_DEBUG(ENG_DEBUG, "Call Handle = %d,end cause:%d", call_handle, tapi_cause);
1418 /*the end of incoming call rejected by callagent, because the call had come before the phone is initialized */
1419 if (call_handle == gphone_rejected_call) {
1420 CALL_ENG_DEBUG(ENG_DEBUG, "Rejected call..phone not initialized");
1422 gphone_rejected_call = VC_TAPI_INVALID_CALLHANDLE;
1424 /*If no more calls available, End the Application */
1425 __vc_core_check_engine_active_task(pagent);
1429 incoming_call_handle = _vc_core_cm_get_incoming_call_handle(&pagent->call_manager);
1430 present_call_state = _vc_core_cm_get_call_state(&pagent->call_manager, call_handle);
1432 CALL_ENG_DEBUG(ENG_DEBUG, "New Call Handle = %d, Already registered MT call handle : %d", call_handle, incoming_call_handle);
1433 switch (present_call_state) {
1434 case VC_CALL_STATE_NONE:
1435 case VC_CALL_STATE_ENDED:
1436 case VC_CALL_STATE_ENDED_FINISH:
1438 CALL_ENG_DEBUG(ENG_DEBUG, "Call Handle = %d state is %d", call_handle, present_call_state);
1439 /*If no more calls available, End the Application */
1440 __vc_core_check_engine_active_task(pagent);
1444 case VC_CALL_STATE_REJECTED:
1446 /*End of incoming call (not registered as incoming call in CallAgent) rejected by callagent */
1447 if (incoming_call_handle != call_handle) {
1448 _vc_core_cm_remove_call_object(&pagent->call_manager, call_handle);
1449 CALL_ENG_DEBUG(ENG_DEBUG, "end of call rejected by callagent");
1451 /*If no more calls available, End the Application */
1452 __vc_core_check_engine_active_task(pagent);
1461 /*End of the call rejected by user or by callagent (when hold is failed) */
1462 if ((VC_INOUT_STATE_INCOME_WAIT_RELEASE == pagent->io_state) && (incoming_call_handle == call_handle)) {
1463 _vc_core_cm_remove_call_object(&pagent->call_manager, call_handle);
1465 /*Change the In Out state to None*/
1466 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_NONE);
1468 /*Notify Client about rejected Event*/
1469 _vc_core_ca_send_event_to_client(pagent, VC_CALL_REJECTED_END, call_handle, 0, NULL);
1474 /*End of Incoming Call */
1475 if (incoming_call_handle == call_handle) {
1476 CALL_ENG_DEBUG(ENG_DEBUG, "Adding Incoming End Event to Idle Callback");
1477 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_INCOME_END);
1478 /*Make sure that the End Indication is processed always after the Incoming Indication , as both are
1479 processed in Idle Add Callbacks */
1480 g_idle_add(__call_vc_incoming_call_end_idle_cb, pagent);
1484 /*End of Outgoing Call */
1485 if (_vc_core_cm_get_outgoing_call_handle(&pagent->call_manager) == call_handle) {
1486 __call_vc_outgoingcall_endhandle(pagent, call_handle, TAPI_NOTI_VOICE_CALL_STATUS_IDLE, tapi_cause);
1490 /*End of Normal Connected Call */
1491 _vc_core_tapi_event_handle_call_end_event(pagent, noti_id, call_handle, tapi_cause);
1493 CALL_VC_DUMP_CALLDETAILS(&pagent->call_manager);
1494 _vc_core_cm_clear_call_object(&objectInfo);
1495 if (FALSE == _vc_core_cm_get_call_object(&pagent->call_manager, call_handle, &objectInfo)) {
1496 CALL_ENG_DEBUG(ENG_DEBUG, "Call Already Cleared for Call Handle = %d", call_handle);
1499 * Because of _vc_core_tapi_rqst_answer_call( .., VC_ANSWER_HOLD_ACTIVE_AND_ACCEPT,.. ) inside _vc_core_tapi_event_handle_call_end_event(),
1500 * pagent->call_manager is cleared. so, we didn't send VC_CALL_NORMAL_END to call-ui.
1501 * so we should send this event to call-ui.
1504 voice_call_end_cause_type_t end_cause_type;
1505 _vc_core_tapi_event_get_end_cause_type(pagent, noti_id, tapi_cause, &end_cause_type);
1506 _vc_core_ca_send_event_to_client(pagent, VC_CALL_NORMAL_END, call_handle, end_cause_type, NULL);
1509 _vc_core_ca_send_event_to_client(pagent, VC_CALL_NORMAL_END, objectInfo.call_handle, objectInfo.end_cause_type, NULL);
1511 } else if (strcmp(noti_id, TAPI_NOTI_VOICE_CALL_STATUS_ACTIVE) == 0) {
1512 CALL_ENG_DEBUG(ENG_DEBUG, "event_type == TAPI_NOTI_VOICE_CALL_STATUS_ACTIVE...");
1513 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1514 TelCallStatusActiveNoti_t callActiveInfo;
1517 memset(&callActiveInfo, 0, sizeof(TelCallStatusActiveNoti_t));
1518 memcpy(&callActiveInfo, data, sizeof(TelCallStatusActiveNoti_t));
1519 call_handle = callActiveInfo.id;
1521 CALL_ENG_DEBUG(ENG_DEBUG, "IO State: %d", pagent->io_state);
1522 CALL_ENG_DEBUG(ENG_DEBUG, "Connected Call Handle = %d", call_handle);
1524 if (call_handle == _vc_core_cm_get_incoming_call_handle(&pagent->call_manager)) {
1525 CALL_ENG_DEBUG(ENG_DEBUG, "Incoming call is being connected...");
1526 } else if (call_handle == _vc_core_cm_get_outgoing_call_handle(&pagent->call_manager)) {
1527 CALL_ENG_DEBUG(ENG_DEBUG, "Outgoing call is being connected...");
1529 CALL_ENG_DEBUG(ENG_ERR, "invalid connected event Call Handle = %d", call_handle);
1531 if ((VC_INVALID_CALL_INDEX != pagent->call_manager.mtcall_index) || (VC_INVALID_CALL_INDEX != pagent->call_manager.setupcall_info.mocall_index)) {
1532 CALL_ENG_DEBUG(ENG_DEBUG, "incoming/outgoin calls call exits, invalid call handle [PROBLEM]");
1533 CALL_VC_DUMP_CALLDETAILS(&pagent->call_manager);
1537 CALL_ENG_DEBUG(ENG_ERR, "No pending calls to connect, ignoreing connect event for call handle= %d", call_handle);
1543 /*Handle Connected Call Event */
1544 _vc_core_tapi_event_handle_call_connect_event(pagent, call_handle);
1545 CALL_ENG_KPI("TAPI_NOTI_VOICE_CALL_STATUS_ACTIVE done");
1546 } else if (strcmp(noti_id, TAPI_NOTI_VOICE_CALL_STATUS_DIALING) == 0) {
1548 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1549 TelCallStatusDialingNoti_t callDialingInfo;
1550 call_vc_call_objectinfo_t objectInfo;
1552 CALL_ENG_DEBUG(ENG_DEBUG, "Data Received for DIALING_IND is %p", data);
1554 if (TRUE == _vc_core_cm_get_outgoing_call_info(&pagent->call_manager, &objectInfo)) {
1555 CALL_ENG_DEBUG(ENG_DEBUG, "MO call index (%d)",objectInfo.call_id);
1557 CALL_ENG_DEBUG(ENG_ERR, "EXCEPTION:Outgoing call Info Missing..");
1561 /* tapicallback data = TelCallStatusHeldNoti_t */
1563 memset(&callDialingInfo, 0, sizeof(TelCallStatusDialingNoti_t));
1564 memcpy(&callDialingInfo, data, sizeof(TelCallStatusDialingNoti_t));
1565 call_handle = callDialingInfo.id;
1566 CALL_ENG_DEBUG(ENG_DEBUG, "Received Call Handle = %d", call_handle);
1569 if (VC_INOUT_STATE_OUTGOING_WAIT_ORIG != pagent->io_state) {
1570 CALL_ENG_DEBUG(ENG_DEBUG, "Io State not in WAIT_ORIG, current io state is : %d", pagent->io_state);
1574 /* Get the outgoing call handle from CallManger and check */
1575 if ((VC_TAPI_INVALID_CALLHANDLE == call_handle)) {
1576 CALL_ENG_DEBUG(ENG_DEBUG, "Outgoing call does not exist or call_handle doesn't match");
1580 /* Set the Call Handle to the CallbObject for future reference */
1581 objectInfo.call_handle = call_handle;
1582 _vc_core_cm_set_outgoing_call_info(&pagent->call_manager, &objectInfo);
1584 _vc_core_tapi_event_handle_originated_event(pagent, call_handle);
1585 CALL_ENG_KPI("TAPI_NOTI_VOICE_CALL_STATUS_DIALING done");
1586 } else if (strcmp(noti_id, TAPI_NOTI_VOICE_CALL_STATUS_ALERT) == 0) {
1587 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1588 call_vc_handle mo_call_handle = VC_TAPI_INVALID_CALLHANDLE;
1589 TelCallStatusAlertNoti_t callAlertInfo;
1591 CALL_ENG_KPI("TAPI_NOTI_VOICE_CALL_STATUS_ALERT START");
1592 /*There are possiblities, that TAPI issued the Alert Notification and it is pending in the gmain loop, but meanwhile, the call
1593 is released by the user - so ignore the event if it doesn't match with the IN OUT Wait state */
1594 if (VC_INOUT_STATE_OUTGOING_WAIT_ALERT != pagent->io_state) {
1595 CALL_ENG_DEBUG(ENG_DEBUG, "Io State not in WAIT_ORIG, current io state is : %d", pagent->io_state);
1600 memset(&callAlertInfo, 0, sizeof(TelCallStatusAlertNoti_t));
1601 memcpy(&callAlertInfo, data, sizeof(TelCallStatusAlertNoti_t));
1602 call_handle = callAlertInfo.id;
1605 CALL_ENG_DEBUG(ENG_DEBUG, "Alert Call Handle = %d", call_handle);
1607 mo_call_handle = _vc_core_cm_get_outgoing_call_handle(&pagent->call_manager);
1608 CALL_ENG_DEBUG(ENG_DEBUG, "MO Call Handle = %d", mo_call_handle);
1610 /*Get the outgoing call handle from CallManger and check*/
1611 if ((VC_TAPI_INVALID_CALLHANDLE == call_handle) || (mo_call_handle != call_handle)) {
1612 CALL_ENG_DEBUG(ENG_DEBUG, "Outgoing call does not exist or call_handle doesn't match");
1616 _vc_core_tapi_event_handle_alert_event(pagent, call_handle);
1617 CALL_ENG_KPI("TAPI_NOTI_VOICE_CALL_STATUS_ALERT done");
1618 } else if (strcmp(noti_id, TAPI_NOTI_VOICE_CALL_STATUS_INCOMING) == 0) {
1619 CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_NOTI_VOICE_CALL_STATUS_INCOMING is not used.");
1620 } else if (strcmp(noti_id, TAPI_NOTI_CALL_INFO_ACTIVE) == 0) {
1621 CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_NOTI_CALL_INFO_ACTIVE");
1622 _vc_core_ca_send_event_to_client(pagent, VC_CALL_IND_ACTIVATE, 0, 0, NULL);
1623 } else if (strcmp(noti_id, TAPI_NOTI_CALL_INFO_HELD) == 0) {
1624 CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_NOTI_CALL_INFO_HELD");
1625 _vc_core_ca_send_event_to_client(pagent, VC_CALL_IND_HOLD, 0, 0, NULL);
1626 } else if (strcmp(noti_id, TAPI_NOTI_CALL_INFO_TRANSFERED) == 0) {
1627 CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_NOTI_CALL_INFO_TRANSFERRED");
1628 _vc_core_ca_send_event_to_client(pagent, VC_CALL_IND_TRANSFER, 0, 0, NULL);
1629 } else if (strcmp(noti_id, TAPI_NOTI_CALL_INFO_JOINED) == 0) {
1630 CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_NOTI_CALL_INFO_JOINED");
1631 _vc_core_ca_send_event_to_client(pagent, VC_CALL_IND_SETUPCONFERENCE, 0, 0, NULL);
1632 } else if (strcmp(noti_id, TAPI_NOTI_CALL_INFO_WAITING) == 0) {
1633 CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_NOTI_CALL_INFO_WAITING");
1634 _vc_core_ca_send_event_to_client(pagent, VC_CALL_IND_WAITING, 0, 0, NULL);
1635 } else if (strcmp(noti_id, TAPI_NOTI_CALL_INFO_FORWARDED) == 0) {
1636 CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_NOTI_CALL_INFO_FORWARDED");
1637 _vc_core_ca_send_event_to_client(pagent, VC_CALL_IND_FORWARD, VC_FRWD_IND_INCOM_IS_FRWD, 0, NULL);
1638 } else if (strcmp(noti_id, TAPI_NOTI_CALL_INFO_BARRED_OUTGOING) == 0) {
1639 CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_NOTI_CALL_INFO_BARRED_OUTGOING");
1640 pagent->barring_ind_type = VC_BARR_IND_ALL;
1641 } else if (strcmp(noti_id, TAPI_NOTI_CALL_INFO_CUG) == 0) {
1642 CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_NOTI_CALL_INFO_CUG");
1643 _vc_core_ca_send_event_to_client(pagent, VC_CALL_IND_CUGINFO, 0, 0, NULL);
1644 } else if (strcmp(noti_id, TAPI_NOTI_CALL_INFO_CALL_NAME_INFORMATION) == 0) {
1645 CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_NOTI_CALL_INFO_CALL_NAME_INFORMATION");
1646 _vc_core_ca_send_event_to_client(pagent, VC_CALL_IND_CALLINGNAMEINFO, 0, 0, NULL);
1647 } else if (strcmp(noti_id, TAPI_NOTI_CALL_INFO_DEFLECTED) == 0) {
1648 CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_NOTI_CALL_INFO_DEFLECTED");
1649 } else if (strcmp(noti_id, TAPI_NOTI_CALL_INFO_FORWARD_UNCONDITIONAL) == 0) {
1650 CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_NOTI_CALL_INFO_FORWARD_UNCONDITIONAL");
1651 _vc_core_ca_send_event_to_client(pagent, VC_CALL_IND_SSNOTIFY, VC_SSNOTIFY_IND_CFU, 0, NULL);
1652 } else if (strcmp(noti_id, TAPI_NOTI_CALL_INFO_FORWARD_CONDITIONAL) == 0) {
1653 CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_NOTI_CALL_INFO_FORWARD_CONDITIONAL");
1654 _vc_core_ca_send_event_to_client(pagent, VC_CALL_IND_SSNOTIFY, VC_SSNOTIFY_IND_ALL_COND_FORWARDING, 0, NULL);
1655 } else if (strcmp(noti_id, TAPI_NOTI_CALL_SOUND_WBAMR) == 0) {
1656 CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_NOTI_CALL_SOUND_WBAMR");
1657 TelCallSoundWbamrNoti_t wbamrInfo;
1658 int wbamr_status = FALSE;
1661 memset(&wbamrInfo, 0, sizeof(TelCallSoundWbamrNoti_t));
1662 memcpy(&wbamrInfo, data, sizeof(TelCallSoundWbamrNoti_t));
1665 CALL_ENG_DEBUG(ENG_DEBUG, "WBAMR is %d", wbamrInfo);
1666 if (wbamrInfo == TAPI_CALL_SOUND_WBAMR_STATUS_ON) {
1667 wbamr_status = TRUE;
1670 _vc_core_ca_send_event_to_client(pagent, VC_CALL_NOTI_WBAMR, wbamr_status, 0, NULL);
1671 } else if (strcmp(noti_id, TAPI_NOTI_CALL_SOUND_NOISE_REDUCTION) == 0) {
1672 CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_NOTI_CALL_SOUND_NOISE_REDUCTION");
1674 CALL_ENG_DEBUG(ENG_DEBUG, "ERROR!! Noti is not defined");
1677 CALL_ENG_DEBUG(ENG_DEBUG, "tapi noti(%s) processed done.", noti_id);
1682 static gboolean __call_vc_outgoingcall_endhandle(call_vc_callagent_state_t *pagent, call_vc_handle call_handle, const char *type, TelTapiEndCause_t tapi_cause)
1684 call_vc_call_objectinfo_t objectInfo;
1685 voice_call_end_cause_type_t endcause_type = 0;
1687 VOICECALL_RETURN_FALSE_IF_FAIL(pagent != NULL);
1689 _vc_core_cm_clear_call_object(&objectInfo);
1690 _vc_core_cm_get_call_object(&pagent->call_manager, call_handle, &objectInfo);
1692 /*Inform Client App about MO Call Disconnect */
1693 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_OUTGOING_ABORTED);
1694 _vc_core_tapi_event_get_end_cause_type(pagent, type, tapi_cause, &endcause_type);
1695 _vc_core_ca_send_event_to_client(pagent, VC_CALL_OUTGOING_END, call_handle, (int)endcause_type, NULL);
1697 /* Response call setup result to SAT if this is SAT call */
1698 if (VC_CALL_ORIG_TYPE_SAT == objectInfo.call_type) {
1699 /*Cancelled by user */
1700 if (VC_CALL_STATE_CANCELLED == objectInfo.state) {
1701 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_CLEAR_DOWN_BEFORE_CONN);
1702 } else { /* Disconnected by Network */
1704 call_vc_satsetup_info_t *pcall_vc_satcall_info = NULL;
1706 pcall_vc_satcall_info = (call_vc_satsetup_info_t *) &(pagent->call_manager.setupcall_info.satcall_setup_info);
1708 if (FALSE == pcall_vc_satcall_info->redial) {
1709 /*Send only if SAT redial is not enabled */
1710 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_NETWORK_UNABLE_TO_PROCESS_COMMAND);
1714 /*Free SAT Icon data if available */
1715 if (pagent->call_manager.setupcall_info.satcall_setup_info.psat_rgb_data != NULL) {
1716 free(pagent->call_manager.setupcall_info.satcall_setup_info.psat_rgb_data);
1717 pagent->call_manager.setupcall_info.satcall_setup_info.psat_rgb_data = NULL;
1721 /* SS: 1 send, while outgoing is CONNECTING state... */
1722 if (CALL_VC_CA_STATE_SS_WAIT_RELEASE_ALL_ACTIVECALL == pagent->callagent_state) {
1723 gboolean bActiveCall = _vc_core_cm_isexists_active_call(&pagent->call_manager);
1724 gboolean bHoldCall = _vc_core_cm_isexists_held_call(&pagent->call_manager);
1726 if (FALSE == bActiveCall) {
1727 if (TRUE == bHoldCall) {
1728 CALL_ENG_DEBUG(ENG_DEBUG, "Continue SS Action");
1730 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_NONE);
1732 if (_vc_core_tapi_rqst_retrieve_call(pagent) == TRUE) {
1733 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_UNHOLD);
1735 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
1738 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
1741 CALL_ENG_DEBUG(ENG_DEBUG, "active call must not exist!");
1742 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
1749 static gboolean __call_vc_incoming_call_end_idle_cb(gpointer puser_data)
1751 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)puser_data;
1752 call_vc_handle call_handle = -1;
1754 CALL_ENG_DEBUG(ENG_DEBUG, "Ending the Incoming Call in Idle Callback");
1755 /*Send the Incoming end indication to the client, only if the io state is in VC_INOUT_STATE_INCOME_END */
1756 if (VC_INOUT_STATE_INCOME_END == pagent->io_state) {
1757 call_handle = _vc_core_cm_get_incoming_call_handle(&pagent->call_manager);
1758 if (-1 != call_handle) {
1759 __call_vc_incomingcall_endhandle(pagent, call_handle);
1765 static gboolean __call_vc_incomingcall_endhandle(call_vc_callagent_state_t *pagent, call_vc_handle call_handle)
1767 CALL_ENG_DEBUG(ENG_DEBUG, "");
1769 CALL_VC_DUMP_CALLDETAILS(&pagent->call_manager);
1771 if (TRUE == _vc_core_ca_send_event_to_client(pagent, VC_CALL_INCOM_END, call_handle, 0, NULL)) {
1772 CALL_ENG_DEBUG(ENG_DEBUG, "client call back returned TRUE Removing Inomcing call Object");
1774 /*Remove Call Object Once the Incoming Call Got Ended*/
1775 _vc_core_cm_remove_call_object(&pagent->call_manager, call_handle);
1777 CALL_VC_DUMP_CALLDETAILS(&pagent->call_manager);
1779 /*Finally Move the IO State None*/
1780 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_NONE);
1785 static gboolean __call_vc_is_callagent_waitstate(call_vc_callagent_state_t *pagent)
1788 switch (pagent->callagent_state) {
1789 case CALL_VC_CA_STATE_WAIT_SPLIT:
1790 case CALL_VC_CA_STATE_WAIT_DROP:
1791 case CALL_VC_CA_STATE_WAIT_SWAP:
1792 case CALL_VC_CA_STATE_WAIT_HOLD:
1793 case CALL_VC_CA_STATE_WAIT_UNHOLD:
1794 case CALL_VC_CA_STATE_WAIT_JOIN:
1795 case CALL_VC_CA_STATE_WAIT_TRANSFER_CNF:
1796 case CALL_VC_CA_STATE_WAIT_TRANSFER_CALLEND:
1797 case CALL_VC_CA_STATE_WAIT_RELEASE_ALL_ACTIVECALL:
1798 case CALL_VC_CA_STATE_WAIT_RELEASE_ALL_HOLDCALL:
1799 case CALL_VC_CA_STATE_SS_WAIT_RELEASE_ALL_ACTIVECALL:
1800 case CALL_VC_CA_STATE_WAIT_RELEASE_ALL_CALLS:
1801 case CALL_VC_CA_STATE_WAIT_RELEASE_ALL_CALLS_TO_SETUP:
1802 case CALL_VC_CA_STATE_WAIT_RELEASE_ALL_CALLS_TO_SWITCH_TO_VIDEO_CALL:
1813 * This function checks whether dtmf is possible
1815 * @return This function returns TRUE if dtmf is possible or else FALSE
1816 * @param[in] pcall_agent Pointer to the call agent structure
1818 static gboolean __vc_core_is_dtmf_possible(call_vc_callagent_state_t *pcall_agent)
1820 VOICECALL_RETURN_FALSE_IF_FAIL(pcall_agent != NULL);
1821 CALL_ENG_DEBUG(ENG_DEBUG, "");
1823 if (VC_INOUT_STATE_NONE != pcall_agent->io_state) {
1824 CALL_ENG_DEBUG(ENG_DEBUG, "__vc_core_is_dtmf_possible, io_state not idle");
1828 if (CALL_VC_CA_STATE_NORMAL != pcall_agent->callagent_state) {
1829 CALL_ENG_DEBUG(ENG_DEBUG, "__vc_core_is_dtmf_possible, callagent_state not idle");
1833 if (FALSE == _vc_core_cm_isexists_active_call(&pcall_agent->call_manager)) {
1834 CALL_ENG_DEBUG(ENG_DEBUG, "NO Active Calls available to send DTMF");
1838 CALL_ENG_DEBUG(ENG_DEBUG, "DTMF Possible");
1843 * This function checks the voicecall engine's idle status and send VC_ACTION_NO_ACTIVE_TASK to client if engine is idle
1846 * @param[in] pcall_agent Pointer to the call agent structure
1848 void __vc_core_check_engine_active_task(call_vc_callagent_state_t *pcall_agent)
1850 VOICECALL_RETURN_IF_FAIL(pcall_agent != NULL);
1851 if (_vc_core_ca_check_end(pcall_agent)) {
1852 CALL_ENG_DEBUG(ENG_DEBUG, "Engine is Idle, Informing the Client");
1853 _vc_core_ca_send_event_to_client(pcall_agent, VC_ACTION_NO_ACTIVE_TASK, 0, 0, NULL);
1858 * This function ends only the connected call corresponding to the given call handle
1860 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
1861 * @param[in] pvoicecall_agent Handle to voicecall engine
1862 * @param[in] call_handle Call handle of the call to be ended
1863 * @remarks pvoicecall_agent cannot be NULL
1864 * @see See also following functions
1865 * - _vc_core_engine_make_call
1866 * - _vc_core_engine_end_call
1867 * - _vc_core_engine_end_call_bycallId
1869 voicecall_error_t _vc_core_engine_end_call_byhandle(voicecall_engine_t *pvoicecall_agent, int call_handle)
1871 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
1872 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
1873 VOICECALL_RETURN_VALUE_IF_FAIL(call_handle >= 0, ERROR_VOICECALL_INVALID_ARGUMENTS);
1875 return (TRUE == _vc_core_tapi_rqst_end_call_by_callhandle(pagent, call_handle)) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
1879 * This function ends a call corresponding to the given call ID
1881 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
1882 * @param[in] pvoicecall_agent Handle to voicecall engine
1883 * @param[in] call_id call id of the call to be ended
1884 * @remarks pvoicecall_agent cannot be NULL
1885 * call_id shall take only values between 1 to 7
1886 * @see See also following functions
1887 * - _vc_core_engine_make_call
1888 * - _vc_core_engine_end_call
1889 * - _vc_core_engine_end_call_byhandle
1891 voicecall_error_t _vc_core_engine_end_call_bycallId(voicecall_engine_t *pvoicecall_agent, int call_id)
1893 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
1894 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1895 call_vc_groupstate_t call_group_state = CALL_VC_GROUP_STATE_NONE;
1897 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
1898 VOICECALL_RETURN_VALUE_IF_FAIL((call_id >= 1 && call_id <= 7), ERROR_VOICECALL_INVALID_ARGUMENTS);
1900 call_handle = _vc_core_cm_get_call_handle_ingroup_bycallId(&pagent->call_manager, call_id);
1901 if (VC_TAPI_INVALID_CALLHANDLE == call_handle) {
1902 return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
1905 call_group_state = _vc_core_cm_get_group_state_callid(&pagent->call_manager, call_id);
1906 if (CALL_VC_GROUP_STATE_ACTIVE == call_group_state) {
1908 if (-1 == _vc_core_cm_get_active_group_index(&pagent->call_manager)) {
1909 return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
1912 if (TRUE == _vc_core_tapi_rqst_end_call_by_callhandle(pagent, call_handle)) {
1913 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_DROP);
1914 return ERROR_VOICECALL_NONE;
1916 } else if (CALL_VC_GROUP_STATE_HOLD == call_group_state) {
1917 int held_group_member_num = 0;
1918 int held_group_index = -1;
1920 held_group_index = _vc_core_cm_get_held_group_index(&pagent->call_manager);
1921 if (-1 == held_group_index) {
1925 held_group_member_num = _vc_core_cm_get_member_count_ingroup(&pagent->call_manager, held_group_index);
1926 if (held_group_member_num > 1) {
1927 /*Individual calls cannot be ended when the conf call in held state */
1928 return ERROR_VOICECALL_OPERATION_NOT_ALLOWED;
1931 if (TRUE == _vc_core_tapi_rqst_end_call_by_callhandle(pagent, call_handle)) {
1932 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_DROP);
1933 return ERROR_VOICECALL_NONE;
1937 return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
1941 * This function ends the call according to the given end call type
1943 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
1944 * @param[in] pvoicecall_agent Handle to voicecall engine
1945 * @param[in] end_call_type End Call Type
1946 * @remarks pvoicecall_agent cannot be NULL
1947 * @see See also following functions
1948 * - _vc_core_engine_make_call
1949 * - _vc_core_engine_end_call_byhandle
1950 * - _vc_core_engine_end_call_bycallId
1953 voicecall_error_t _vc_core_engine_end_call(voicecall_engine_t *pvoicecall_agent, _vc_core_engine_end_call_type_t end_call_type)
1955 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
1956 gboolean bret_val = FALSE;
1958 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
1960 /*If Call Agent is waiting for any of the release event then ignore the end call request */
1961 if ((CALL_VC_CA_STATE_WAIT_RELEASE_ALL_ACTIVECALL == pagent->callagent_state) || (CALL_VC_CA_STATE_WAIT_RELEASE_ALL_HOLDCALL == pagent->callagent_state) || (CALL_VC_CA_STATE_WAIT_RELEASE_ALL_CALLS == pagent->callagent_state)) {
1962 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
1965 CALL_ENG_DEBUG(ENG_DEBUG, "end_call_type = %d", end_call_type);
1967 switch (end_call_type) {
1968 case VC_END_OUTGOING_CALL:
1970 bret_val = _vc_core_tapi_rqst_release_outgoing_call(pagent);
1973 case VC_END_INCOMING_CALL:
1975 bret_val = _vc_core_tapi_rqst_release_incoming_call(pagent);
1978 case VC_END_ACTIVE_OR_HELD_CALLS:
1980 bret_val = _vc_core_tapi_rqst_end_call(pagent);
1983 case VC_END_ALL_ACTIVE_CALLS:
1985 bret_val = _vc_core_ca_end_active_calls(pagent);
1988 case VC_END_ALL_HELD_CALLS:
1990 bret_val = _vc_core_ca_end_held_calls(pagent);
1993 case VC_END_ALL_CALLS:
1995 bret_val = _vc_core_ca_end_all_calls(pagent);
1999 return ERROR_VOICECALL_INVALID_CALL_TYPE;
2002 return (TRUE == bret_val) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_INCOMPLETE;
2006 * This function does the explicit call transfer
2008 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2009 * @param[in] pvoicecall_agent Handle to voicecall engine
2010 * @remarks pvoicecall_agent cannot be NULL
2012 voicecall_error_t _vc_core_engine_transfer_calls(voicecall_engine_t *pvoicecall_agent)
2014 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2016 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2018 if (CALL_VC_CA_STATE_WAIT_TRANSFER_CNF == pagent->callagent_state) {
2019 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
2020 } else if (FALSE == _vc_core_ca_is_transfer_call_possible(pagent)) {
2021 return ERROR_VOICECALL_TRANSFER_CALL_NOT_POSSIBLE;
2023 if (TRUE == _vc_core_tapi_rqst_transfer_call(pagent)) {
2024 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_TRANSFER_CNF);
2025 return ERROR_VOICECALL_NONE;
2029 return ERROR_VOICECALL_TRANSFER_FAILED;
2033 * This function swaps the active and held calls if any available
2035 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2036 * @param[in] pvoicecall_agent Handle to voicecall engine
2037 * @remarks pvoicecall_agent cannot be NULL
2038 * @see See also the following APIs
2039 * - _vc_core_engine_hold_call
2040 * - _vc_core_engine_retrieve_call
2043 voicecall_error_t _vc_core_engine_swap_calls(voicecall_engine_t *pvoicecall_agent)
2045 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2046 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2048 /*If call agent is in any of the wait states, then ignore the request */
2049 if (TRUE == __call_vc_is_callagent_waitstate(pagent)) {
2050 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
2053 if (TRUE == _vc_core_tapi_rqst_swap_calls(pagent)) {
2055 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_SWAP_HOLD_OR_ACTIVATE);
2057 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_SWAP);
2059 return ERROR_VOICECALL_NONE;
2062 return ERROR_VOICECALL_SWAP_FAILED;
2066 * This function puts the active call if any on hold
2068 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2069 * @param[in] pvoicecall_agent Handle to voicecall engine
2070 * @remarks pvoicecall_agent cannot be NULL
2071 * @see voicecall_retreive_call
2073 voicecall_error_t _vc_core_engine_hold_call(voicecall_engine_t *pvoicecall_agent)
2075 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2076 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2078 if (TRUE == __call_vc_is_callagent_waitstate(pagent)) {
2079 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
2081 #ifdef _CPHS_DEFINED_
2082 if (TRUE == _vc_core_svcall_cphs_csp_get_status(pagent, VC_CPHS_CSP_HOLD)) {
2083 if (TRUE == _vc_core_tapi_rqst_hold_call(pagent)) {
2084 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_HOLD);
2085 return ERROR_VOICECALL_NONE;
2088 return ERROR_VOICECALL_HOLD_NOT_SUPPORTED;
2091 if (TRUE == _vc_core_tapi_rqst_hold_call(pagent)) {
2092 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_HOLD);
2093 return ERROR_VOICECALL_NONE;
2096 return ERROR_VOICECALL_HOLD_FAILED;
2100 * This function retrieves/activates the held call
2102 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2103 * @param[in] pvoicecall_agent Handle to voicecall engine
2104 * @remarks pvoicecall_agent cannot be NULL
2105 * @see _vc_core_engine_hold_call
2107 voicecall_error_t _vc_core_engine_retrieve_call(voicecall_engine_t *pvoicecall_agent)
2109 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2111 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2113 if (TRUE == __call_vc_is_callagent_waitstate(pagent)) {
2114 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
2117 if (TRUE == _vc_core_tapi_rqst_retrieve_call(pagent)) {
2118 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_UNHOLD);
2119 return ERROR_VOICECALL_NONE;
2121 return ERROR_VOICECALL_RETREIVE_FAILED;
2125 * This function sets up a conference beween the currently available active and held calls
2127 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2128 * @param[in] pvoicecall_agent Handle to voicecall engine
2129 * @remarks pvoicecall_agent cannot be NULL
2130 * @see See also the following APIs
2131 * - _vc_core_engine_private_call
2132 * - _vc_core_engine_private_call_by_callid
2135 voicecall_error_t _vc_core_engine_setup_conference(voicecall_engine_t *pvoicecall_agent)
2137 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2139 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2141 /*If call agent is in any of the wait states, then ignore the request */
2142 if (CALL_VC_CA_STATE_WAIT_JOIN == pagent->callagent_state) {
2143 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
2144 } else if (FALSE == _vc_core_ca_is_conf_call_possible(pagent)) {
2145 return ERROR_VOICECALL_CONF_NOT_POSSIBLE;
2147 if (TRUE == _vc_core_tapi_rqst_join_calls(pagent)) {
2148 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_JOIN);
2149 return ERROR_VOICECALL_NONE;
2152 return ERROR_VOICECALL_SETUP_CONF_FAILED;
2156 * This function makes a private call to the call member corressponding to the given call id.
2158 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2159 * @param[in] pvoicecall_agent Handle to voicecall engine
2160 * @param[in] call_id Call ID of the call to be made private
2161 * @remarks pvoicecall_agent cannot be NULL
2162 * @see See also the following APIs
2163 * - _vc_core_engine_setup_conference
2164 * - _vc_core_engine_private_call
2167 voicecall_error_t _vc_core_engine_private_call_by_callid(voicecall_engine_t *pvoicecall_agent, int call_id)
2169 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2171 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2172 VOICECALL_RETURN_VALUE_IF_FAIL((call_id >= 1 && call_id <= 7), ERROR_VOICECALL_INVALID_ARGUMENTS);
2174 if (CALL_VC_CA_STATE_WAIT_SPLIT == pagent->callagent_state) {
2175 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
2176 } else if (FALSE == _vc_core_ca_is_private_call_possible(pagent)) {
2177 return ERROR__vc_core_engine_private_call_NOT_POSSIBLE;
2179 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
2181 call_handle = _vc_core_cm_get_call_handle_ingroup_bycallId(&pagent->call_manager, call_id);
2183 if (VC_TAPI_INVALID_CALLHANDLE != call_handle) {
2184 return (TRUE == _vc_core_tapi_rqst_private_call(pagent, call_handle)) ? ERROR_VOICECALL_NONE : ERROR__vc_core_engine_private_call_FAILED;
2188 return ERROR_VOICECALL_INVALID_CALLID;
2192 * This function makes a private call to the given call member from the currently available active conference call
2194 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2195 * @param[in] pvoicecall_agent Handle to voicecall engine
2196 * @param[in] call_handle call handle of the call to be made private
2197 * @remarks pvoicecall_agent cannot be NULL
2198 * @see See also the following APIs
2199 * - _vc_core_engine_setup_conference
2200 * - _vc_core_engine_private_call_by_callid
2203 voicecall_error_t _vc_core_engine_private_call(voicecall_engine_t *pvoicecall_agent, int call_handle)
2205 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2207 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2208 VOICECALL_RETURN_VALUE_IF_FAIL(call_handle >= 0, ERROR_VOICECALL_INVALID_ARGUMENTS);
2210 if (CALL_VC_CA_STATE_WAIT_SPLIT == pagent->callagent_state) {
2211 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
2212 } else if (FALSE == _vc_core_ca_is_private_call_possible(pagent)) {
2213 return ERROR__vc_core_engine_private_call_NOT_POSSIBLE;
2216 return (TRUE == _vc_core_tapi_rqst_private_call(pagent, call_handle)) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_REQUEST_FAILED;
2220 * This function rejects the incoming call if any
2222 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2223 * @param[in] pvoicecall_agent Handle to voicecall engine
2224 * @param[in] budub User Determined User Busy - TRUE, Else - FALSE
2225 * @exception In case of exceptions return value contains appropriate error code.
2226 * @remarks pvoicecall_agent cannot be NULL
2227 * @see _vc_core_engine_answer_call
2229 voicecall_error_t _vc_core_engine_reject_call(voicecall_engine_t *pvoicecall_agent, gboolean budub)
2231 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2232 int error_code = -1;
2233 gboolean ret = FALSE;
2235 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2237 ret = _vc_core_tapi_rqst_reject_mt_call(pagent, budub, &error_code);
2239 return (TRUE == ret) ? ERROR_VOICECALL_NONE : error_code;
2243 * This function answers a call according to the given answer type
2245 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2246 * @param[in] pvoicecall_agent Handle to voicecall engine
2247 * @param[in] answer_type The answer type to be used
2248 * @remarks pvoicecall_agent and pcall_handle cannot be NULL
2249 * @see _vc_core_engine_reject_call
2251 voicecall_error_t _vc_core_engine_answer_call(voicecall_engine_t *pvoicecall_agent, voicecall_answer_type_t answer_type)
2253 call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
2255 gboolean ret = FALSE;
2257 VOICECALL_RETURN_VALUE_IF_FAIL(pcall_agent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2258 #ifdef RELEASE_ALL_AND_ACCEPT_SUPPORT
2259 VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(answer_type, VC_ANSWER_NORMAL, VC_ANSWER_RELEASE_ALL_AND_ACCEPT, ERROR_VOICECALL_INVALID_ARGUMENTS);
2261 VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(answer_type, VC_ANSWER_NORMAL, VC_ANSWER_RELEASE_HOLD_AND_ACCEPT, ERROR_VOICECALL_INVALID_ARGUMENTS);
2263 ret = _vc_core_tapi_rqst_answer_call(pcall_agent, answer_type, &error_code);
2265 return (TRUE == ret) ? ERROR_VOICECALL_NONE : error_code;
2269 * This function sends the given dtmf digits
2271 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2272 * @param[in] pvoicecall_agent Handle to voicecall engine
2273 * @param[in] pdtmf_string dtmf digits to be sent
2274 * @remarks pvoicecall_agent and pdtmf_string cannot be NULL
2275 * pdtmf_string shall only accept strings containing the digit value (0-9,A,B,C,D,*,#)
2278 voicecall_error_t _vc_core_engine_send_dtmf(voicecall_engine_t *pvoicecall_agent, char *pdtmf_string)
2280 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2282 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2283 VOICECALL_RETURN_VALUE_IF_FAIL(pdtmf_string != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2285 if (FALSE == _vc_core_util_isvalid_dtmf_number(pdtmf_string)) {
2286 _vc_core_ca_send_event_to_client(pagent, VC_ERROR_OCCURED, ERROR_VOICECALL_INVALID_DTMF_CHAR, -1, NULL);
2287 return ERROR_VOICECALL_INVALID_DTMF_CHAR;
2290 return (TRUE == _vc_core_tapi_rqst_start_dtmf(pagent, pdtmf_string)) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_DTMF_FAILED;
2294 * This function sends response to sat based on the given sat response type
2296 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2297 * @param[in] pvoicecall_agent Handle to voicecall engine
2298 * @param[in] sat_rqst_resp_type sat rqst/response type sent by client
2299 * @param[in] sat_response_type sat response type to be sent to SAT
2301 voicecall_error_t _vc_core_engine_send_sat_response(voicecall_engine_t *pvoicecall_agent, voicecall_engine_sat_rqst_resp_type sat_rqst_resp_type, call_vc_sat_reponse_type_t sat_response_type)
2303 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2304 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2305 VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(sat_rqst_resp_type, SAT_RQST_SETUP_CALL, SAT_RESP_SETUP_CALL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2306 VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(sat_response_type, CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND, CALL_VC_ME_RET_SUCCESS, ERROR_VOICECALL_INVALID_ARGUMENTS);
2308 return (TRUE == _vc_core_ca_send_sat_response(pagent, sat_rqst_resp_type, sat_response_type)) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_REQUEST_FAILED;
2312 * This function finalizes the voiecall engine and removes all allocated resources
2315 * @param[in] pvoicecall_agent Handle to Voicecall Engine
2316 * @remarks pvoicecall_agent cannot be NULL
2318 void _vc_core_engine_engine_finish(voicecall_engine_t *pvoicecall_agent)
2320 call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
2321 VOICECALL_RETURN_IF_FAIL(pvoicecall_agent != NULL);
2323 /*Unsubscribe Events */
2324 CALL_ENG_DEBUG(ENG_DEBUG, "Unsubscribing Events");
2326 tel_deinit(pcall_agent->tapi_handle);
2328 VOICECALL_RETURN_IF_FAIL(pcall_agent != NULL);
2329 _vc_core_ca_finish_agent(pcall_agent);
2334 * This function requests SAT Engine to setup SIM services Menu
2336 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2337 * @param[in] pvoicecall_agent Handle to Voicecall Engine
2338 * @remarks Voicecall Engine only requests the SAT engine to display the menu.
2340 voicecall_error_t voicecall_request_sat_menu(voicecall_engine_t *pvoicecall_agent)
2342 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2343 TelSatSetupMenuInfo_t sim_menu; /*LiMo SAT*/
2345 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2347 CALL_ENG_DEBUG(ENG_DEBUG, "");
2348 memset(&sim_menu, 0, sizeof(TelSatSetupMenuInfo_t));
2350 if (FALSE == TelTapiSatGetMainMenuList(&sim_menu)) {
2351 CALL_ENG_DEBUG(ENG_DEBUG, "TelTapiSatGetMainMenuList failed");
2352 return ERROR_VOICECALL_REQUEST_FAILED;
2355 return ERROR_VOICECALL_NONE;
2359 * This function retreives the SIM Menu Title from the SAT Engine
2361 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2362 * @param[in] pvoicecall_agent Handle to Voicecall Engine
2363 * @param[out] title contains the sat menu title on sucess
2365 voicecall_error_t voicecall_request_sat_menu_title(voicecall_engine_t *pvoicecall_agent, char *title)
2367 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2368 TelSatMainMenuTitleInfo_t sat_menu_title; /*LiMo SAT*/
2370 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2371 VOICECALL_RETURN_VALUE_IF_FAIL(title != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2373 CALL_ENG_DEBUG(ENG_DEBUG, "");
2375 memset(&sat_menu_title, 0, sizeof(TelSatMainMenuTitleInfo_t));
2376 if (TRUE == TelTapiSatGetMainMenuTitle(&sat_menu_title)) {
2377 if (TRUE == sat_menu_title.bIsMainMenuPresent) {
2378 strcpy(title, (char *)sat_menu_title.mainMenuTitle.string);
2379 return ERROR_VOICECALL_NONE;
2383 return ERROR_VOICECALL_REQUEST_FAILED;
2388 * This function prepares the engine for the redial call. It preserves the previsouly made call object to used for the next make call
2390 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2391 * @param[in] pvoicecall_agent Handle to Voicecall Engine
2392 * @param[in] call_handle call handle
2393 * @remarks If this API is used, _vc_core_engine_prepare_call is not reqired for making the call again. The last prepared call details will
2394 * be used for the redialling. Application has to just use _vc_core_engine_make_call API to redial the call
2396 voicecall_error_t _vc_core_engine_prepare_redial(voicecall_engine_t *pvoicecall_agent, int call_handle)
2398 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2399 call_vc_call_objectinfo_t call_object;
2400 int mo_call_handle = -1;
2402 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2403 VOICECALL_RETURN_VALUE_IF_FAIL(call_handle >= 0, ERROR_VOICECALL_INVALID_ARGUMENTS);
2405 /*Check the validity of the call handle */
2406 mo_call_handle = _vc_core_cm_get_outgoing_call_handle(&pagent->call_manager);
2407 if ((mo_call_handle == -1) || (mo_call_handle != call_handle)) {
2408 return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
2411 if (FALSE == _vc_core_cm_get_call_object(&pagent->call_manager, call_handle, &call_object)) {
2412 return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
2415 /*Set the callobject status */
2416 call_object.state = VC_CALL_STATE_REDIAL;
2418 /*Reintialize Call ID */
2419 call_object.call_id = 0;
2420 _vc_core_cm_set_call_object(&pagent->call_manager, &call_object);
2422 /*Set Engine IO State */
2423 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_OUTGOING_SHOW_REDIALCAUSE);
2425 /*todo Set SAT Redial Data */
2427 return ERROR_VOICECALL_NONE;
2432 * This function checks whether SAT redial duration is valid
2434 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2435 * @param[in] pvoicecall_agent Handle to Voicecall Engine
2436 * @param[out] bredial_duration Contains TRUE if SAT redial duration is enabled, FALSE otherwise
2437 * @remarks pvoicecall_agent and bredial_duration cannot be NULL
2439 voicecall_error_t voicecall_get_sat_redial_duration_status(voicecall_engine_t *pvoicecall_agent, gboolean *bredial_duration)
2441 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2442 call_vc_satsetup_info_t *pcall_vc_satcall_info = NULL;
2444 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2445 VOICECALL_RETURN_VALUE_IF_FAIL(bredial_duration != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2447 pcall_vc_satcall_info = (call_vc_satsetup_info_t *) &(pagent->call_manager.setupcall_info.satcall_setup_info);
2449 CALL_ENG_DEBUG(ENG_DEBUG, "SAT Redial Duration Status= %d", pcall_vc_satcall_info->bduration);
2451 *bredial_duration = pcall_vc_satcall_info->bduration;
2452 return ERROR_VOICECALL_NONE;
2456 * This function sets the current duration and retrieves the modified remaining SAT redial duration
2458 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2459 * @param[in] pvoicecall_agent Handle to Voicecall Engine
2460 * @param[out] remaining_duration remaining sat duration
2461 * @remarks pvoicecall_agent and remaining_duration cannot be NULL
2463 voicecall_error_t voicecall_get_set_sat_remaining_duration(voicecall_engine_t *pvoicecall_agent, long *remaining_duration)
2465 call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
2466 call_vc_satsetup_info_t *pcall_vc_satcall_info = NULL;
2468 VOICECALL_RETURN_VALUE_IF_FAIL(pcall_agent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2469 VOICECALL_RETURN_VALUE_IF_FAIL(remaining_duration != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2471 pcall_vc_satcall_info = (call_vc_satsetup_info_t *) &(pcall_agent->call_manager.setupcall_info.satcall_setup_info);
2472 *remaining_duration = pcall_vc_satcall_info->remaining_duration;
2473 CALL_ENG_DEBUG(ENG_DEBUG, "Remaining Duration: %ld", *remaining_duration);
2475 return ERROR_VOICECALL_NONE;
2479 voicecall_error_t _vc_core_engine_get_sat_dtmf_hidden_mode(voicecall_engine_t *pvoicecall_agent, gboolean *bhidden_mode)
2481 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2482 call_vc_satsetup_info_t *pcall_vc_satcall_info = NULL;
2484 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2485 VOICECALL_RETURN_VALUE_IF_FAIL(bhidden_mode != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2487 pcall_vc_satcall_info = (call_vc_satsetup_info_t *) &(pagent->call_manager.setupcall_info.satcall_setup_info);
2489 CALL_ENG_DEBUG(ENG_DEBUG, "SAT Hidden Mode= %d", pcall_vc_satcall_info->satengine_dtmf_data.bIsHiddenMode);
2491 *bhidden_mode = pcall_vc_satcall_info->satengine_dtmf_data.bIsHiddenMode;
2492 return ERROR_VOICECALL_NONE;
2496 * This function changes the voice audio path
2498 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2499 * @param[in] pvoicecall_agent Handle to Voicecall Engine
2500 * @param[in] audio_path audio path to be changed
2501 * @remarks pvoicecall_agent cannot be NULL
2503 voicecall_error_t _vc_core_engine_change_audio_path(voicecall_engine_t *pvoicecall_agent, voicecall_audio_path_t audio_path, gboolean bextra_volume)
2505 call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
2506 TelCallSoundPathInfo_t tapi_sound_path;
2507 /*Enum for encapsulating errors from TAPI Lib */
2508 TapiResult_t tapi_error = TAPI_API_SUCCESS;
2510 VOICECALL_RETURN_VALUE_IF_FAIL(pcall_agent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2512 /*Voicecall Path Should not be modified if calls are not available */
2513 if (_vc_core_cm_get_call_member_count(&pcall_agent->call_manager) <= 0) {
2514 return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
2517 switch (audio_path) {
2518 case VC_AUDIO_PATH_HANDSET:
2520 tapi_sound_path.path = TAPI_SOUND_PATH_HANDSET;
2523 case VC_AUDIO_PATH_HEADSET:
2525 tapi_sound_path.path = TAPI_SOUND_PATH_HEADSET;
2528 case VC_AUDIO_PATH_HANDSFREE:
2530 tapi_sound_path.path = TAPI_SOUND_PATH_HANDSFREE;
2533 case VC_AUDIO_PATH_BLUETOOTH:
2535 tapi_sound_path.path = TAPI_SOUND_PATH_BLUETOOTH;
2538 case VC_AUDIO_PATH_STEREO_BLUETOOTH:
2540 tapi_sound_path.path = TAPI_SOUND_PATH_STEREO_BLUETOOTH;
2543 case VC_AUDIO_PATH_SPK_PHONE:
2545 tapi_sound_path.path = TAPI_SOUND_PATH_SPK_PHONE;
2548 case VC_AUDIO_PATH_HEADSET_3_5PI:
2550 tapi_sound_path.path = TAPI_SOUND_PATH_HEADSET_3_5PI;
2555 CALL_ENG_DEBUG(ENG_DEBUG, "Invalid audio path");
2556 return ERROR_VOICECALL_INVALID_ARGUMENTS;
2561 CALL_ENG_DEBUG(ENG_DEBUG, "tapi_audio_path: %d(extra voluem: %d)", tapi_sound_path, bextra_volume);
2563 && ((tapi_sound_path.path == TAPI_SOUND_PATH_HANDSET)
2564 || (tapi_sound_path.path = TAPI_SOUND_PATH_SPK_PHONE))) {
2565 tapi_sound_path.ex_volume = TAPI_SOUND_EX_VOLUME_ON;
2567 tapi_sound_path.ex_volume = TAPI_SOUND_EX_VOLUME_OFF;
2570 tapi_error = tel_set_call_sound_path(pcall_agent->tapi_handle, &tapi_sound_path, _vc_core_engine_set_sound_path_resp_cb, NULL);
2571 if (tapi_error != TAPI_API_SUCCESS) {
2572 CALL_ENG_DEBUG(ENG_DEBUG, "tel_set_sound_path error: %d", tapi_error);
2573 return ERROR_VOICECALL_TAPI_ERROR;
2576 return ERROR_VOICECALL_NONE;
2579 voicecall_error_t _vc_core_engine_set_audio_mute(voicecall_engine_t *pvoicecall_agent, gboolean bmute_audio)
2581 call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
2582 TapiResult_t error = TAPI_API_SUCCESS;
2583 TelSoundMuteStatus_t micmute_set = TAPI_SOUND_MUTE_STATUS_OFF;
2585 micmute_set = (TRUE == bmute_audio) ? TAPI_SOUND_MUTE_STATUS_ON : TAPI_SOUND_MUTE_STATUS_OFF;
2587 error = tel_set_call_mute_status(pcall_agent->tapi_handle, micmute_set, _vc_core_engine_set_mute_status_resp_cb, NULL);
2589 if (error != TAPI_API_SUCCESS) {
2590 CALL_ENG_DEBUG(ENG_DEBUG, "tel_set_sound_mute_status Error: %d", error);
2591 return ERROR_VOICECALL_TAPI_ERROR;
2594 CALL_ENG_DEBUG(ENG_DEBUG, "End");
2595 return ERROR_VOICECALL_NONE;
2599 * This function sets the voice call audio volume for the given audio path type
2601 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2602 * @param[in] pvoicecall_agent Handle to Voicecall Engine
2603 * @param[in] audio_path_type audio path for the volume to be set
2604 * @param[in] vol_level volume level
2605 * @remarks pvoicecall_agent cannot be NULL
2607 voicecall_error_t _vc_core_engine_set_audio_volume(voicecall_engine_t *pvoicecall_agent, voicecall_audio_path_t audio_path_type, voicecall_audio_volume_t vol_level)
2609 call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
2610 /*Enum for encapsulating errors from TAPI Lib */
2611 TapiResult_t error = TAPI_API_SUCCESS;
2612 TelCallVolumeInfo_t vol_info;
2614 CALL_ENG_DEBUG(ENG_DEBUG, "Start! path(%d), volume(%d)", audio_path_type, vol_level);
2616 VOICECALL_RETURN_VALUE_IF_FAIL(pcall_agent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2617 VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(audio_path_type, VC_AUDIO_PATH_HANDSET, VC_AUDIO_PATH_HEADSET_3_5PI, ERROR_VOICECALL_INVALID_ARGUMENTS);
2618 VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(vol_level, VC_AUDIO_VOLUME_LEVEL_0, VC_AUDIO_VOLUME_LEVEL_9, ERROR_VOICECALL_INVALID_ARGUMENTS);
2620 /*Ignore the request if calls are not available */
2621 if (_vc_core_cm_get_call_member_count(&pcall_agent->call_manager) <= 0) {
2622 CALL_ENG_DEBUG(ENG_DEBUG, "End");
2623 return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
2626 vol_info.volume = vol_level;
2627 vol_info.type = TAPI_SOUND_TYPE_VOICE;
2628 switch (audio_path_type) {
2629 case VC_AUDIO_PATH_HEADSET:
2630 vol_info.device = TAPI_SOUND_DEVICE_HEADSET;
2632 case VC_AUDIO_PATH_BLUETOOTH:
2633 case VC_AUDIO_PATH_STEREO_BLUETOOTH:
2634 vol_info.device = TAPI_SOUND_DEVICE_BLUETOOTH;
2636 case VC_AUDIO_PATH_SPK_PHONE:
2637 vol_info.device = TAPI_SOUND_DEVICE_SPEAKER_PHONE;
2640 vol_info.device = TAPI_SOUND_DEVICE_RECEIVER;
2644 error = tel_set_call_volume_info(pcall_agent->tapi_handle, &vol_info, _vc_core_engine_set_volume_resp_cb, NULL);
2646 if (error != TAPI_API_SUCCESS) {
2647 CALL_ENG_DEBUG(ENG_DEBUG, "Tapi API Error: %d", error);
2648 return ERROR_VOICECALL_TAPI_ERROR;
2651 CALL_ENG_DEBUG(ENG_DEBUG, "End");
2652 return ERROR_VOICECALL_NONE;
2656 * This function retreives the voice call audio volume for the given audio path type
2658 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2659 * @param[in] pvoicecall_agent Handle to Voicecall Engine
2660 * @param[in] audio_path_type audio path for the volume to be retreived
2661 * @remarks pvoicecall_agent cannot be NULL
2662 * The audio volume level will be send as a response with the below details
2663 * event - VC_CALL_GET_VOLUME_RESP
2664 * param1 - audio_path_type
2665 * param2 - volume level
2668 voicecall_error_t _vc_core_engine_get_audio_volume(voicecall_engine_t *pvoicecall_agent, voicecall_audio_path_t audio_path_type)
2670 call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
2671 TapiResult_t error = TAPI_API_SUCCESS;
2672 TelSoundDevice_t volume_type = TAPI_SOUND_DEVICE_RECEIVER;
2674 VOICECALL_RETURN_VALUE_IF_FAIL(pcall_agent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2675 VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(audio_path_type, VC_AUDIO_PATH_HANDSET, VC_AUDIO_PATH_HEADSET_3_5PI, ERROR_VOICECALL_INVALID_ARGUMENTS);
2677 /*Ignore the request if calls are not available */
2678 if (_vc_core_cm_get_call_member_count(&pcall_agent->call_manager) <= 0) {
2679 return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
2682 switch (audio_path_type) {
2683 case VC_AUDIO_PATH_HEADSET:
2684 volume_type = TAPI_SOUND_DEVICE_HEADSET;
2686 case VC_AUDIO_PATH_BLUETOOTH:
2687 case VC_AUDIO_PATH_STEREO_BLUETOOTH:
2688 volume_type = TAPI_SOUND_DEVICE_BLUETOOTH;
2690 case VC_AUDIO_PATH_SPK_PHONE:
2691 volume_type = TAPI_SOUND_DEVICE_SPEAKER_PHONE;
2694 volume_type = TAPI_SOUND_DEVICE_RECEIVER;
2698 CALL_ENG_DEBUG(ENG_DEBUG, "volume_type = %d", volume_type);
2700 pcall_agent->curr_tapi_path = volume_type;
2701 error = tel_get_call_volume_info(pcall_agent->tapi_handle, volume_type, TAPI_SOUND_TYPE_VOICE, _vc_core_engine_get_volume_resp_cb, NULL);
2703 if (error != TAPI_API_SUCCESS) {
2704 CALL_ENG_DEBUG(ENG_DEBUG, "Tapi API Error: %d", error);
2705 return ERROR_VOICECALL_TAPI_ERROR;
2708 return ERROR_VOICECALL_NONE;
2712 * This function changes the inout state of the engine to the given state
2714 * @return ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2715 * @param[in] pvoicecall_agent Handle to voicecall engine
2716 * @param[in] io_state Inout state to be set
2717 * @remarks pvoicecall_agent cannot be NULL
2718 * @see _vc_core_engine_status_get_engine_iostate
2720 voicecall_error_t _vc_core_engine_change_engine_iostate(voicecall_engine_t *pvoicecall_agent, int io_state)
2722 call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2723 VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_CALL_HANDLE);
2724 VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(io_state, VC_INOUT_STATE_NONE, VC_INOUT_STATE_INCOME_END, ERROR_VOICECALL_INVALID_CALL_HANDLE);
2726 if (TRUE == _vc_core_ca_change_inout_state(pagent, (voicecall_inout_state_t) io_state)) {
2727 return ERROR_VOICECALL_NONE;
2730 return ERROR_VOICECALL_INVALID_ARGUMENTS;
2733 voicecall_error_t _vc_core_engine_extract_phone_number(const char *source_tel_number, char *phone_number, const int buf_size)
2735 VOICECALL_RETURN_VALUE_IF_FAIL(source_tel_number != NULL, ERROR_VOICECALL_INVALID_CALL_HANDLE);
2736 VOICECALL_RETURN_VALUE_IF_FAIL(phone_number != NULL, ERROR_VOICECALL_INVALID_CALL_HANDLE);
2738 if (FALSE == _vc_core_util_extract_call_number(source_tel_number, phone_number, buf_size)) {
2739 _vc_core_util_strcpy(phone_number, buf_size, source_tel_number);
2742 return ERROR_VOICECALL_NONE;
2745 voicecall_error_t _vc_core_engine_set_to_default_values(voicecall_engine_t *pvoicecall_agent)
2747 call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
2749 CALL_ENG_DEBUG(ENG_DEBUG, "Start");
2750 /*Initialize Call Manager */
2751 _vc_core_call_manager_init(&pcall_agent->call_manager);
2753 /* Initialize Call Agent Flags */
2754 _vc_core_ca_init_data(pcall_agent);
2756 #ifdef _CCBS_DEFINED_
2757 /* Init CCBS Info */
2758 _vc_core_init_ccbs_info(pcall_agent);
2761 /* Init CPHS Info */
2762 #ifdef _CPHS_DEFINED_
2763 _vc_core_svcall_init_cphs_info(pcall_agent);
2766 CALL_VC_DUMP_CALLDETAILS(&pcall_agent->call_manager);
2767 CALL_ENG_DEBUG(ENG_DEBUG, "End");
2769 return ERROR_VOICECALL_NONE;
2772 void _vc_core_engine_dial_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
2774 CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_dial_call_resp_cb");
2776 call_vc_call_objectinfo_t objectInfo;
2777 call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
2779 if (TAPI_CAUSE_SUCCESS != result) {
2780 CALL_ENG_DEBUG(ENG_DEBUG, "MO Call Dial call Failed with error cause: %d", result);
2782 _vc_core_cm_clear_call_object(&objectInfo);
2784 __call_vc_outgoingcall_endhandle(pagent, objectInfo.call_handle, TAPI_NOTI_VOICE_CALL_STATUS_IDLE, TAPI_CC_CAUSE_FACILITY_REJECTED);
2785 /* Need to make warning popup for abnormal status... */
2789 void _vc_core_engine_answer_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
2791 CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_answer_call_resp_cb");
2793 call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
2794 if (result != TAPI_CAUSE_SUCCESS) {
2795 /*If IO State is waiting for Answer Response */
2796 if ((VC_INOUT_STATE_INCOME_WAIT_CONNECTED == pagent->io_state) || (VC_INOUT_STATE_INCOME_WAIT_HOLD_CONNECTED == pagent->io_state) || (VC_INOUT_STATE_INCOME_WAIT_RELEASE_ACTIVE_CONNECTED == pagent->io_state)) {
2797 int mt_call_handle = -1;
2799 mt_call_handle = _vc_core_cm_get_incoming_call_handle(&pagent->call_manager);
2801 if (mt_call_handle != -1) {
2802 CALL_ENG_DEBUG(ENG_DEBUG, "mt_call_handle = %d", mt_call_handle);
2804 /*Send Hold Failed Notification to client UI */
2805 if (pagent->callagent_state == CALL_VC_CA_STATE_WAIT_HOLD) {
2806 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
2807 _vc_core_ca_send_event_to_client(pagent, VC_ERROR_OCCURED, ERROR_VOICECALL_HOLD_FAILED, 0, NULL);
2810 /*Send Incoming call MT End Indication to Client UI */
2811 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_INCOME_END);
2812 g_idle_add(__call_vc_incoming_call_end_idle_cb, pagent);
2816 _vc_core_ca_send_event_to_client(pagent, VC_CALL_ANSWER_CNF, 0, 0, NULL);
2820 void _vc_core_engine_end_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
2822 CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_end_call_resp_cb..");
2824 TelCallEndCnf_t callEndInfo ;
2825 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
2826 TelCallEndType_t call_end_type = TAPI_CALL_END;
2827 call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
2829 memset(&callEndInfo, 0, sizeof(TelCallEndCnf_t));
2830 memcpy(&callEndInfo, tapi_data, sizeof(TelCallEndCnf_t));
2832 call_handle = callEndInfo.id;
2833 call_end_type = callEndInfo.type;
2835 if (TAPI_CAUSE_SUCCESS == result) {
2836 /*Ignore this event as endication will be received from TAPI for the call release request */
2837 CALL_ENG_DEBUG(ENG_DEBUG, "Success response for tel_end_call request");
2839 CALL_ENG_DEBUG(ENG_ERR, "Call Release request failed, proceeding with Call end process");
2840 call_vc_call_objectinfo_t objectInfo;
2841 voicecall_call_state_t present_call_state = VC_CALL_STATE_NONE;
2842 call_vc_handle incoming_call_handle = VC_TAPI_INVALID_CALLHANDLE;
2843 TelTapiEndCause_t tapi_cause = TAPI_CALL_END_NO_CAUSE;
2845 CALL_ENG_DEBUG(ENG_DEBUG, "Call Handle = %d,end cause:%d", call_handle, tapi_cause);
2847 /*the end of incoming call rejected by callagent, because the call had come before the phone is initialized */
2848 if (call_handle == gphone_rejected_call) {
2849 CALL_ENG_DEBUG(ENG_DEBUG, "Rejected call..phone not initialized");
2851 gphone_rejected_call = VC_TAPI_INVALID_CALLHANDLE;
2853 /*If no more calls available, End the Application */
2854 __vc_core_check_engine_active_task(pagent);
2858 incoming_call_handle = _vc_core_cm_get_incoming_call_handle(&pagent->call_manager);
2859 present_call_state = _vc_core_cm_get_call_state(&pagent->call_manager, call_handle);
2861 CALL_ENG_DEBUG(ENG_DEBUG, "New Call Handle = %d, Already registered MT call handle : %d", call_handle, incoming_call_handle);
2862 switch (present_call_state) {
2863 case VC_CALL_STATE_NONE:
2864 case VC_CALL_STATE_ENDED:
2865 case VC_CALL_STATE_ENDED_FINISH:
2867 CALL_ENG_DEBUG(ENG_DEBUG, "Call Handle = %d state is %d", call_handle, present_call_state);
2868 /*If no more calls available, End the Application */
2869 __vc_core_check_engine_active_task(pagent);
2873 case VC_CALL_STATE_REJECTED:
2875 /*End of incoming call (not registered as incoming call in CallAgent) rejected by callagent */
2876 if (incoming_call_handle != call_handle) {
2877 _vc_core_cm_remove_call_object(&pagent->call_manager, call_handle);
2878 CALL_ENG_DEBUG(ENG_DEBUG, "end of call rejected by callagent");
2880 /*If no more calls available, End the Application */
2881 __vc_core_check_engine_active_task(pagent);
2890 /*End of the call rejected by user or by callagent (when hold is failed) */
2891 if ((VC_INOUT_STATE_INCOME_WAIT_RELEASE == pagent->io_state) && (incoming_call_handle == call_handle)) {
2892 _vc_core_cm_remove_call_object(&pagent->call_manager, call_handle);
2894 /*Change the In Out state to None*/
2895 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_NONE);
2897 /*Notify Client about rejected Event*/
2898 _vc_core_ca_send_event_to_client(pagent, VC_CALL_REJECTED_END, call_handle, 0, NULL);
2903 /*End of Incoming Call */
2904 if (incoming_call_handle == call_handle) {
2905 CALL_ENG_DEBUG(ENG_DEBUG, "Adding Incoming End Event to Idle Callback");
2906 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_INCOME_END);
2907 /*Make sure that the End Indication is processed always after the Incoming Indication , as both are
2908 processed in Idle Add Callbacks */
2909 g_idle_add(__call_vc_incoming_call_end_idle_cb, pagent);
2913 /*End of Outgoing Call */
2914 if (_vc_core_cm_get_outgoing_call_handle(&pagent->call_manager) == call_handle) {
2915 __call_vc_outgoingcall_endhandle(pagent, call_handle, TAPI_NOTI_VOICE_CALL_STATUS_IDLE, tapi_cause);
2919 /*End of Normal Connected Call */
2920 _vc_core_tapi_event_handle_call_end_event(pagent, "", call_handle, tapi_cause);
2922 CALL_VC_DUMP_CALLDETAILS(&pagent->call_manager);
2923 _vc_core_cm_clear_call_object(&objectInfo);
2924 if (FALSE == _vc_core_cm_get_call_object(&pagent->call_manager, call_handle, &objectInfo)) {
2925 CALL_ENG_DEBUG(ENG_DEBUG, "Call Already Cleared for Call Handle = %d", call_handle);
2928 * Because of _vc_core_tapi_rqst_answer_call( .., VC_ANSWER_HOLD_ACTIVE_AND_ACCEPT,.. ) inside _vc_core_tapi_event_handle_call_end_event(),
2929 * pagent->call_manager is cleared. so, we didn't send VC_CALL_NORMAL_END to call-ui.
2930 * so we should send this event to call-ui.
2933 voice_call_end_cause_type_t end_cause_type;
2934 _vc_core_tapi_event_get_end_cause_type(pagent, "", tapi_cause, &end_cause_type);
2935 _vc_core_ca_send_event_to_client(pagent, VC_CALL_NORMAL_END, call_handle, end_cause_type, NULL);
2938 _vc_core_ca_send_event_to_client(pagent, VC_CALL_NORMAL_END, objectInfo.call_handle, objectInfo.end_cause_type, NULL);
2944 void _vc_core_engine_hold_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
2946 CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_hold_call_resp_cb");
2947 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
2948 call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
2950 if (TAPI_CAUSE_SUCCESS == result) {
2951 memcpy(&call_handle, tapi_data, sizeof(call_vc_handle));
2953 _vc_core_cm_get_first_active_call_handle(&pagent->call_manager, &call_handle);
2956 if (_vc_core_tapi_event_handle_call_held_event(pagent, call_handle, result) == FALSE) {
2957 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
2960 Be carefull in clearing the end call member, because _vc_core_engine_status_is_any_call_ending
2961 function depends on the end call object status. If it is cleared often, the check by
2962 _vc_core_engine_status_is_any_call_ending becomes invalid
2964 _vc_core_cm_clear_endcall_member(&pagent->call_manager);
2968 void _vc_core_engine_active_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
2970 CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_active_call_resp_cb");
2971 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
2972 call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
2973 TelCallActiveCnf_t callActiveInfo;
2975 if (TAPI_CAUSE_SUCCESS == result) {
2976 memset(&callActiveInfo, 0, sizeof(TelCallActiveCnf_t));
2977 memcpy(&callActiveInfo, tapi_data, sizeof(TelCallActiveCnf_t));
2978 call_handle = callActiveInfo.id;
2980 _vc_core_cm_get_first_held_call_handle(&pagent->call_manager, &call_handle);
2983 if (_vc_core_tapi_event_handle_call_retrieve_event(pagent, call_handle, result) == FALSE) {
2984 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
2987 Be carefull in clearing the end call member, because _vc_core_engine_status_is_any_call_ending
2988 function depends on the end call object status. If it is cleared often, the check by
2989 _vc_core_engine_status_is_any_call_ending becomes invalid
2991 _vc_core_cm_clear_endcall_member(&pagent->call_manager);
2995 void _vc_core_engine_swap_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
2997 CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_swap_call_resp_cb : %d", result);
3000 void _vc_core_engine_join_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3002 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
3003 call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
3004 TelCallJoinCnf_t callJoinInfo;
3006 CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_join_call_resp_cb...");
3008 if (TAPI_CAUSE_SUCCESS == result) {
3009 memset(&callJoinInfo, 0, sizeof(TelCallJoinCnf_t));
3010 memcpy(&callJoinInfo, tapi_data, sizeof(TelCallJoinCnf_t));
3011 call_handle = callJoinInfo.id;
3016 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
3017 _vc_core_tapi_event_handle_call_join_event(pagent, call_handle, result);
3020 void _vc_core_engine_split_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3022 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
3023 call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
3024 TelCallSplitCnf_t callSplitInfo;
3026 CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_split_call_resp_cb");
3028 if (TAPI_CAUSE_SUCCESS == result) {
3029 memset(&callSplitInfo, 0, sizeof(TelCallSplitCnf_t));
3030 memcpy(&callSplitInfo, tapi_data, sizeof(TelCallSplitCnf_t));
3031 call_handle = callSplitInfo.id;
3034 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
3035 _vc_core_tapi_event_handle_call_split_event(pagent, call_handle, result);
3038 void _vc_core_engine_transfer_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3040 call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
3042 CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_transfer_call_resp_cb");
3044 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
3045 _vc_core_tapi_event_handle_call_transfer_event(pagent, result);
3048 void _vc_core_engine_dtmf_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3050 call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
3052 CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_dtmf_call_resp_cb");
3054 if (TAPI_CAUSE_SUCCESS != result) {
3055 CALL_ENG_DEBUG(ENG_DEBUG, "Tapi Error Code %d", result);
3056 /*Forward the events to client */
3057 _vc_core_ca_send_event_to_client(pagent, VC_CALL_DTMF_ACK, FALSE, 0, NULL);
3059 /*Forward the events to client */
3060 _vc_core_ca_send_event_to_client(pagent, VC_CALL_DTMF_ACK, TRUE, 0, NULL);
3064 void _vc_core_engine_set_volume_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3066 CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_set_volume_resp_cb : %d", result);
3069 void _vc_core_engine_get_volume_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3071 int tapi_sound_path = 0;
3072 int volume_level = 0;
3073 TelCallGetVolumeInfoResp_t snd_resp_data;
3074 call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
3076 memset(&snd_resp_data, 0, sizeof(TelCallGetVolumeInfoResp_t));
3077 memcpy(&snd_resp_data, tapi_data, sizeof(TelCallGetVolumeInfoResp_t));
3080 tapi_sound_path = pagent->curr_tapi_path;
3081 for (i = 0; i < snd_resp_data.record_num; i++) {
3082 if (tapi_sound_path == snd_resp_data.record[i].device) {
3083 volume_level = snd_resp_data.record[i].volume;
3087 CALL_ENG_DEBUG(ENG_DEBUG, "Changed Vol Type = %d, Vol Level = %d", tapi_sound_path, volume_level);
3089 _vc_core_ca_send_event_to_client(pagent, VC_CALL_GET_VOLUME_RESP, tapi_sound_path, volume_level, NULL);
3092 void _vc_core_engine_set_sound_path_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3094 CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_set_sound_path_resp_cb : %d", result);
3097 void _vc_core_engine_set_mute_status_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3099 CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_set_mute_status_resp_cb : %d", result);
3102 void _vc_core_engine_get_aoc_info_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3104 CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_get_aoc_info_cb : %d", result);