Make TIZEN 2.0
[apps/home/call.git] / call-engine / core / vc-core-engine.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
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
7  *
8  * http://www.tizenopensource.org/license
9  *
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.
15  */
16
17
18 #include <assert.h>
19 #include <string.h>
20 #include <errno.h>
21 #include <ITapiModem.h>
22
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"
33
34 /*Global Variable Declerations */
35
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;
39
40 /*Initialization Global Variables*/
41 static gboolean gphone_init_finished = FALSE;
42 static call_vc_handle gphone_rejected_call = VC_TAPI_INVALID_CALLHANDLE;
43
44 static call_vc_callagent_state_t *gpcall_agent_for_callback = NULL;     /*jspark event subscribe & callback function*/
45
46 /* SAT call detail used for self event */
47 static int gsat_event_type = 0;
48 static int gtype = 0;
49 static void *gpresult = NULL;
50 static TelSatSetupCallIndCallData_t gSatSetupCallInfo;
51 //static TelSatSendDtmfIndDtmfData_t gSatSendDtmfInfo;
52
53 /*Local Function Declarations*/
54 /**
55  * This function handles the end event for outgoing call
56  *
57  * @internal
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
63  */
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);
65 /**
66  * This function handles the end event for incoming call
67  *
68  * @internal
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
72  */
73 static gboolean __call_vc_incomingcall_endhandle(call_vc_callagent_state_t *pcall_agent, call_vc_handle call_handle);
74 /**
75  * This function checks whether the call agent is in any of the wait state
76  *
77  * @internal
78  * @return              Returns TRUE on if call agent is in wait state or FALSE
79  * @param[in]           pcall_agent             Handle to the call agent
80  */
81 static gboolean __call_vc_is_callagent_waitstate(call_vc_callagent_state_t *pcall_agent);
82 /**
83  * This function creates call details for outgoign call with the given setup info
84  *
85  * @internal
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
91  */
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);
93
94 /**
95  * This function handles all telephony events
96  *
97  * @internal
98  * @return              void
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
103  */
104
105 static void __call_vc_handle_tapi_events(TapiHandle *handle, const char *noti_id, void *data, void *user_data);
106
107 /**
108 * This function handles sat engine notification
109 *
110 * @internal
111 * @return               void
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
116 */
117 static void __call_vc_handle_sat_engine_events_cb(TapiHandle *handle, const char *noti_id, void *data, void *user_data);
118
119 /**
120 * This function subscribes for all notifications required for voicecall engine
121 *
122 * @internal
123 * @return               Returns TRUE on success or FALSE on failure
124 * @param[in]            pcall_agent             handle to voicecall agent structure
125 */
126 static gboolean __call_vc_subscribe_call_events(call_vc_callagent_state_t *pcall_agent);
127
128 /**
129 * This function handles telephony initialized notifications
130 *
131 * @internal
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
137 */
138 static void __call_vc_tapi_initialized_cb(TapiHandle *handle, const char *noti_id, void *data, void *user_data);
139
140 /**
141 * This function subscribes for telephony call notifications
142 *
143 * @internal
144 * @return               Returns TRUE on success or FALSE on failure
145 * @param[in]            pcall_agent             handle to voicecall agent structure
146 */
147 static gboolean __call_vc_subscribe_tapi_event(call_vc_callagent_state_t *pcall_agent);
148
149 /**
150 * This function request the engine to setup a sat call
151 *
152 * @internal
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
158 */
159 static gboolean __call_vc_request_sat_call(call_vc_callagent_state_t *pagent, int mo_call_index, int *ret_code);
160
161 /**
162 * This function hadles the events from the sat engine
163 *
164 * @internal
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
171 */
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);
173
174 /**
175 * This function request the engine to setup a normal voice call
176 *
177 * @internal
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
183 */
184 static gboolean __call_vc_request_call(call_vc_callagent_state_t *pagent, int mo_call_index, int *ret_code);
185
186 /**
187 * This function serves as the callback function for the incoming call idle add function
188 *
189 * @return               Returns TRUE - if the callback has to be called again, FALSE otherwise
190 * @param[in]            puser_data      data set by the user
191 */
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);
196
197 /**
198 * This function serves as the callback function for the SAT idle add function
199 *
200 * @return               Returns TRUE - if the callback has to be called again, FALSE otherwise
201 * @param[in]            puser_data      data set by the user
202 */
203 static gboolean __call_vc_sat_idle_cb(gpointer puser_data);
204
205 /**
206  * This function checks the voicecall engine's idle status and send VC_ACTION_NO_ACTIVE_TASK to client if engine is idle
207  *
208  * @return              void
209  * @param[in]           pcall_agent     Pointer to the call agent structure
210  */
211 static void __vc_core_check_engine_active_task(call_vc_callagent_state_t *pcall_agent);
212
213 /**
214  * This function checks whether dtmf is possible
215  *
216  * @return              This function returns TRUE if dtmf is possible or else FALSE
217  * @param[in]           pcall_agent                     Pointer to the call agent structure
218  */
219 static gboolean __vc_core_is_dtmf_possible(call_vc_callagent_state_t *pcall_agent);
220
221 /**
222 * This function initializes the voicecall engine
223 *
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
230 */
231 voicecall_error_t _vc_core_engine_init(voicecall_engine_t **pcall_agent_out, voicecall_cb pcallback_func, void *puser_data)
232 {
233         call_vc_callagent_state_t *pcall_agent = NULL;
234
235         CALL_ENG_DEBUG(ENG_DEBUG, "Voicecall Engine");
236
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);
239
240         /*Initialize Call Agent*/
241         pcall_agent = _vc_core_ca_init_agent();
242         if (NULL == pcall_agent) {
243                 return ERROR_VOICECALL_MEMALLOC_FAILURE;
244         }
245
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;
250         }
251         /*Store the Callback Pointer*/
252         pcall_agent->client_callback = pcallback_func;
253         pcall_agent->puser_data = puser_data;
254
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;
258
259         /*Init Success, Assign Output Parameters*/
260         *pcall_agent_out = (voicecall_engine_t *)pcall_agent;
261
262         return ERROR_VOICECALL_NONE;
263 }
264
265 void _vc_core_engine_handle_sat_events_cb(void *sat_setup_call_data, void *userdata)
266 {
267         char *data = sat_setup_call_data;
268
269         call_vc_callagent_state_t *pcall_agent = gpcall_agent_for_callback;
270
271         CALL_ENG_DEBUG(ENG_DEBUG, "sat event callback.");
272
273         memset(&gSatSetupCallInfo, 0, sizeof(TelSatSetupCallIndCallData_t));
274         memcpy(&gSatSetupCallInfo, data, sizeof(TelSatSetupCallIndCallData_t));
275
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);
280
281         CALL_ENG_DEBUG(ENG_DEBUG, "Call back Ends and returning..");
282 }
283
284 static void __call_vc_handle_sat_engine_events_cb(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
285 {
286 //      call_vc_callagent_state_t *pcall_agent = gpcall_agent_for_callback;
287
288         CALL_ENG_DEBUG(ENG_DEBUG, "sat event callback.");
289
290 #if 0
291         int event_type = event->EventType;
292         /*int status = event->Status;*/
293         char *data = event->pData;
294
295         switch (event_type) {
296         case TAPI_EVENT_SAT_SETUP_CALL_IND:
297                 {
298                         /*it will be processed in _vc_core_engine_handle_sat_events_cb().*/
299                         return;
300                 }
301                 break;
302
303         case TAPI_EVENT_SAT_SEND_DTMF_IND:
304                 {
305                         /* async for SAT sync noti */
306                         memset(&gSatSendDtmfInfo, 0, sizeof(TelSatSendDtmfIndDtmfData_t));
307                         memcpy(&gSatSendDtmfInfo, data, sizeof(TelSatSendDtmfIndDtmfData_t));
308
309                         gsat_event_type = SAT_RQST_SEND_DTMF;
310                         gtype = event_type;
311                         gpresult = &gSatSendDtmfInfo;
312
313                         g_idle_add(__call_vc_sat_idle_cb, pcall_agent);
314                 }
315                 break;
316
317         case TAPI_EVENT_SAT_CALL_CONTROL_IND:
318                 {
319                         __call_vc_handle_sat_engine_events(pcall_agent, VC_ACTION_SAT_RESPONSE, SAT_RESP_SETUP_CALL, event_type, data);
320                 }
321                 break;
322
323         default:
324                 CALL_ENG_DEBUG(ENG_DEBUG, "Default: event_type = %d", event_type);
325                 break;
326         }
327
328         CALL_ENG_DEBUG(ENG_DEBUG, "Call back Ends and returning..");
329
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");
333         } else {
334                 __vc_core_check_engine_active_task(pcall_agent);
335         }
336 #endif
337 }
338
339 /*Subscribe Noti Events*/
340 static gboolean __call_vc_subscribe_call_events(call_vc_callagent_state_t *pcall_agent)
341 {
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");
346                 return FALSE;
347
348         }
349         CALL_ENG_KPI("__call_vc_subscribe_tapi_event done");
350
351         CALL_ENG_DEBUG(ENG_DEBUG, "Noti Subscription Sucess");
352         return TRUE;
353 }
354
355 /**
356  * This function sends response event to the registered client
357  *
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
364  */
365 gboolean _vc_core_ca_send_event_to_client(call_vc_callagent_state_t *pcall_agent, int event, int param1, int param2, void *param3)
366 {
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);
370         }
371         return FALSE;
372 }
373
374 static void __call_vc_tapi_initialized_cb(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
375 {
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;
380         int sim_changed = 0;
381
382         VOICECALL_RETURN_IF_FAIL(data != NULL);
383         tapi_power_phone_power_status_t *power = (tapi_power_phone_power_status_t *)data;
384
385         if (power != TAPI_PHONE_POWER_STATUS_ON) {
386                 CALL_ENG_DEBUG(ENG_DEBUG, "Modem is not available");
387                 return;
388         }
389
390         CALL_ENG_DEBUG(ENG_DEBUG, "gphone_init_finished %d", gphone_init_finished);
391
392         if (gphone_init_finished != TRUE) {
393                 gphone_init_finished = TRUE;
394
395                 CALL_ENG_DEBUG(ENG_DEBUG, "Query Card Status ..");
396
397                 memset(&sim_status, 0, sizeof(sim_status));
398                 tapi_err = tel_get_sim_init_info(pagent->tapi_handle, &sim_status, &sim_changed);
399
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;
403                 } else {
404
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);
408                         }
409
410                         pagent->card_type = card_type;
411
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;
418                                 break;
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;
431                                 break;
432                         default:
433                                 CALL_ENG_DEBUG(ENG_DEBUG, "Unknown Card_status = %d", sim_status);
434                                 pagent->bis_no_sim = TRUE;
435                                 break;
436                         }
437                 }
438         } else {
439                 CALL_ENG_DEBUG(ENG_DEBUG, "gphone_init_finished is TRUE.");
440         }
441
442         /*As a Backup, whenever this event is arrived, just update this variable*/
443         gphone_init_finished = TRUE;
444 }
445
446 static gboolean __call_vc_subscribe_tapi_event(call_vc_callagent_state_t *pcall_agent)
447 {
448         int index = 0;
449
450         TapiResult_t api_err = TAPI_API_SUCCESS;
451         int num_event = 0;
452
453         pcall_agent->tapi_handle = tel_init(NULL);
454         if (pcall_agent->tapi_handle != NULL) {
455                 CALL_ENG_DEBUG(ENG_DEBUG, "tel_init() success.");
456         } else {
457                 CALL_ENG_DEBUG(ENG_DEBUG, "tel_init() failed.");
458                 return FALSE;
459         }
460
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,
491         };
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);
497                         return FALSE;
498                 }
499         }
500
501         const char *ready_event_list[] = {
502                 TAPI_NOTI_MODEM_POWER,
503         };
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);
509                         return FALSE;
510                 }
511         }
512
513 #if 0
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*/
518         };
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);
524                         return FALSE;
525                 }
526         }
527 #endif
528
529         gpcall_agent_for_callback = pcall_agent;
530
531         CALL_ENG_DEBUG(ENG_DEBUG, "Subscribe to TAPI Success");
532
533         return TRUE;
534
535 }
536
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)
538 {
539         char call_number[VC_PHONE_NUMBER_LENGTH_MAX] = { 0, };
540
541         CALL_ENG_DEBUG(ENG_DEBUG, "call_type=%d", psetup_call_info->call_type);
542
543         _vc_core_cm_clear_call_object(pcall_object);
544
545         /*Update CallObjects state to Prepare Outgoing*/
546         pcall_object->state = VC_CALL_STATE_PREPARE_OUTGOING;
547
548         /*Update Call|Objects Call Type*/
549         pcall_object->call_type = psetup_call_info->call_type;
550
551         /*Update Call Objects Identity*/
552         pcall_object->identity_mode = psetup_call_info->identity_mode;
553
554         /*Differentiate the call by its source of origination*/
555         switch (pcall_object->call_type) {
556         case VC_CALL_ORIG_TYPE_EMERGENCY:
557                 {
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);
561                         return TRUE;
562                 }
563                 break;
564         case VC_CALL_ORIG_TYPE_PINLOCK:
565                 {
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);
569                 }
570                 break;
571         case VC_CALL_ORIG_TYPE_NOSIM:   /*no sim (pagent->bis_no_sim == TRUE)*/
572                 {
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);
575                 }
576                 break;
577         case VC_CALL_ORIG_TYPE_NORMAL:
578         case VC_CALL_ORIG_TYPE_SAT:
579                 {
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);
582                 }
583                 break;
584         case VC_CALL_ORIG_TYPE_VOICEMAIL:
585                 {
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);
588                 }
589                 break;
590         default:
591                 CALL_ENG_DEBUG(ENG_DEBUG, "Invalide Call Type: %d", pcall_object->call_type);
592                 *error_code = ERROR_VOICECALL_INVALID_CALL_TYPE;
593                 return FALSE;
594         }
595
596         /*Copy CUG Details */
597         memcpy(&pcall_object->cug_info, &psetup_call_info->cug_info, sizeof(voicecall_cug_info_t));
598
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);
602
603         CALL_ENG_DEBUG(ENG_DEBUG, "no_sim=%d, emergency_number=%d", pagent->bis_no_sim, pcall_object->bemergency_number);
604
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;
608                 return FALSE;
609         }
610
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;
614                 return FALSE;
615         }
616
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;
621         }
622
623         return TRUE;
624 }
625
626 static gboolean __call_vc_request_sat_call(call_vc_callagent_state_t *pagent, int mo_call_index, int *ret_code)
627 {
628         call_vc_call_objectinfo_t callInfo;
629         TelSatCmdQualiSetupCall_t sat_request_type = 0;
630
631         CALL_ENG_DEBUG(ENG_DEBUG, "mo_call_index = %d", mo_call_index);
632
633         VOICECALL_RETURN_FALSE_IF_FAIL(pagent->call_manager.setupcall_info.mocall_index == mo_call_index);
634
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;
638                 return FALSE;
639         }
640
641         sat_request_type = pagent->call_manager.setupcall_info.satcall_setup_info.satengine_setupcall_data.calltype;
642
643         CALL_ENG_DEBUG(ENG_DEBUG, " SAT_CALL sat_request_type=%d", sat_request_type);
644
645         switch (sat_request_type) {
646         case TAPI_SAT_SETUP_CALL_IF_ANOTHER_CALL_NOT_BUSY_WITH_REDIAL:
647                 {
648                         pagent->call_manager.setupcall_info.satcall_setup_info.redial = TRUE;
649                 }
650         case TAPI_SAT_SETUP_CALL_IF_ANOTHER_CALL_NOT_BUSY:      /*Fall Through*/
651                 {
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;
659                                 return FALSE;
660                         }
661
662                         _vc_core_cm_set_outgoing_call_info(&pagent->call_manager, &callInfo);
663
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;
670                                 return FALSE;
671                         } else {
672                                 CALL_ENG_DEBUG(ENG_DEBUG, "Prepare Setup Call Success");
673                         }
674                 }
675                 break;
676         case TAPI_SAT_SETUP_CALL_PUT_ALL_OTHER_CALLS_ON_HOLD_WITH_REDIAL:
677                 {
678                         pagent->call_manager.setupcall_info.satcall_setup_info.redial = TRUE;
679                 }
680         case TAPI_SAT_SETUP_CALL_PUT_ALL_OTHER_CALLS_ON_HOLD:   /*Fall Through */
681                 {
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;
687                                 return FALSE;
688                         }
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;
696                                         return FALSE;
697                                 }
698                         } else {
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;
706                                         return FALSE;
707                                 }
708                         }
709                 }
710                 break;
711         case TAPI_SAT_SETUP_CALL_DISCONN_ALL_OTHER_CALLS_WITH_REDIAL:
712                 {
713                         pagent->call_manager.setupcall_info.satcall_setup_info.redial = TRUE;
714                 }
715         case TAPI_SAT_SETUP_CALL_DISCONN_ALL_OTHER_CALLS:       /*Fall Through */
716                 {
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);
721                         } else {
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;
728                                         return FALSE;
729                                 }
730                         }
731                 }
732                 break;
733         default:
734                 CALL_ENG_DEBUG(ENG_DEBUG, "Action not defined for this SAT Request Type");
735                 return FALSE;
736         }
737
738         return TRUE;
739 }
740
741 static gboolean __call_vc_request_call(call_vc_callagent_state_t *pagent, int mo_call_index, int *ret_code)
742 {
743         call_vc_call_objectinfo_t callInfo;
744
745         CALL_ENG_DEBUG(ENG_DEBUG, "");
746
747         VOICECALL_RETURN_FALSE_IF_FAIL(pagent->call_manager.setupcall_info.mocall_index == mo_call_index);
748
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;
753                 return FALSE;
754         }
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:
762
763                 /*Set the updated Object Info to the Call Manager*/
764                 _vc_core_cm_set_outgoing_call_info(&pagent->call_manager, &callInfo);
765
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");
771
772                         return FALSE;
773                 } else {
774                         CALL_ENG_DEBUG(ENG_DEBUG, "Prepare Setup Call Success");
775                 }
776
777                 break;
778         default:
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);
781                 return FALSE;
782                 break;
783         }
784
785         return TRUE;
786 }
787
788 /**
789 * This function prepares the call setup info structure for making call
790  *
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
799 *
800  */
801 voicecall_error_t _vc_core_engine_prepare_call(voicecall_engine_t *pvoicecall_agent, voicecall_setup_info_t *psetup_call_info)
802 {
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;
808         int sim_changed = 0;
809         int status = 0;
810         int nIndex = 0;
811         int error_code = 0;
812
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);
815
816         CALL_ENG_DEBUG(ENG_DEBUG, "");
817
818         if (FALSE == _vc_core_util_isvalid_telephone_number(psetup_call_info->tel_number)) {
819                 return ERROR_VOICECALL_INVALID_TELEPHONE_NUMBER;
820         }
821
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;
828         }
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;
833         }
834
835         CALL_ENG_DEBUG(ENG_DEBUG, "Checking for SIM Availablity");
836
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");
841
842         if (TAPI_API_SUCCESS != tapi_err) {
843                 CALL_ENG_DEBUG(ENG_DEBUG, "tel_get_sim_init_info failed.. tapi_err = %d", tapi_err);
844
845                 pagent->bis_no_sim = TRUE;
846                 psetup_call_info->call_type = VC_CALL_ORIG_TYPE_NOSIM;
847         } else {
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);
852                 }
853                 CALL_ENG_KPI("tel_get_sim_type done");
854                 pagent->card_type = card_type;
855
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;
861                         break;
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;
874                         break;
875                 default:
876                         CALL_ENG_DEBUG(ENG_DEBUG, "Unknown Card_status = %d", sim_status);
877                         pagent->bis_no_sim = TRUE;
878                         break;
879                 }
880         }
881
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) {
885                 return error_code;
886         }
887
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;
891         }
892
893         /* Add the prepared call object to the CallManager */
894         nIndex = _vc_core_cm_add_call_object(&pagent->call_manager, &callobject_info);
895         if (nIndex != -1) {
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;
900         } else {
901                 return ERROR_VOICECALL_CALL_NOT_ALLOWED;
902         }
903
904         return ERROR_VOICECALL_NONE;
905 }
906
907 /**
908 * This function clears the data of the given call type.
909 *
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
917 *                               call types.
918 */
919 voicecall_error_t _vc_core_engine_finalize_call(voicecall_engine_t *pvoicecall_agent, voicecall_call_type_t call_type, int call_handle)
920 {
921         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
922         gboolean bret_val = FALSE;
923
924         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
925
926         CALL_ENG_DEBUG(ENG_DEBUG, "call_type = %d", call_type);
927
928         switch (call_type) {
929         case VC_OUTGOING_CALL:
930                 {
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;
933                         }
934
935                         bret_val = _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
936                 }
937                 break;
938         case VC_CONNECTED_CALL:
939                 {
940                         call_vc_call_objectinfo_t call_object;
941
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);
945                                 } else {
946                                         return ERROR_VOICECALL_CALL_IS_IN_PROGRESS;
947                                 }
948                         }
949                 }
950                 break;
951         case VC_INCOMING_CALL:
952                 {
953                         return ERROR_VOICECALL_NOT_SUPPORTED;
954                 }
955                 break;
956         default:
957                 return ERROR_VOICECALL_INVALID_CALL_TYPE;
958         }
959
960         return (TRUE == bret_val) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
961 }
962
963 /**
964 * This function establishes an outgoing call with the details prepared using _vc_core_engine_prepare_call
965 *
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
972 */
973 voicecall_error_t _vc_core_engine_make_call(voicecall_engine_t *pvoicecall_agent, int mo_call_index, int *pcall_handle)
974 {
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;
979
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);
983
984         CALL_ENG_DEBUG(ENG_DEBUG, "...");
985
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;
990         }
991
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);
994         } else {
995                 ret_val = __call_vc_request_call(pagent, mo_call_index, &error_code);
996         }
997
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);
1001
1002         }
1003
1004         return (TRUE == ret_val) ? ERROR_VOICECALL_NONE : error_code;
1005 }
1006
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)
1008 {
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;
1012
1013         VOICECALL_RETURN_FALSE_IF_FAIL(pcall_agent != NULL);
1014
1015         CALL_ENG_DEBUG(ENG_DEBUG, "sat_event: %d, sat_event_type: %d, command_type: %d", sat_event, sat_event_type, type);
1016
1017         psatsetup_info = (call_vc_satsetup_info_t *) &(pagent->call_manager.setupcall_info.satcall_setup_info);
1018
1019         switch (sat_event) {
1020         case VC_ACTION_SAT_REQUEST:
1021                 {
1022                         switch (sat_event_type) {
1023                         case SAT_RQST_SETUP_CALL:
1024                                 {
1025                                         CALL_ENG_DEBUG(ENG_DEBUG, "SAT_RQST_SETUP_CALL SAT Event is recieved...");
1026
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);
1030                                                 return FALSE;
1031                                         }
1032
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));
1039
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;
1045
1046                                                 /*Store the duration, this remaining duration will be reduced in subsequent redial attempts */
1047                                                 psatsetup_info->remaining_duration = call_vc_sat_callinfo.duration;
1048                                         }
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);
1052
1053                                         _vc_core_ca_send_event_to_client(pagent, VC_ACTION_SAT_REQUEST, SAT_RQST_SETUP_CALL, 0, &call_vc_sat_callinfo);
1054                                 }
1055                                 break;
1056                         case SAT_RQST_SEND_DTMF:
1057                                 {
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;
1061
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);
1064                                         } else {
1065                                                 memset(&call_vc_sat_callinfo, 0, sizeof(voicecall_sat_callinfo_t));
1066
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);
1070                                         }
1071                                 }
1072                                 break;
1073                         }
1074                 }
1075                 break;
1076         case VC_ACTION_SAT_RESPONSE:
1077                 {
1078                         call_vc_call_objectinfo_t objectInfo;
1079                         switch (sat_event_type) {
1080                         case SAT_RESP_SETUP_CALL:
1081                                 {
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);
1085                                                 break;
1086                                         }
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));
1089
1090                                         switch (psatsetup_info->satengine_callctrl_data.callCtrlResult) {
1091                                         case TAPI_SAT_CALL_CTRL_R_ALLOWED_NO_MOD:
1092                                                 {
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;
1095                                                 }
1096                                                 break;
1097                                         case TAPI_SAT_CALL_CTRL_R_NOT_ALLOWED:
1098                                                 {
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);
1102
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);
1106                                                         } else {
1107                                                                 _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
1108                                                         }
1109
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);
1113                                                 }
1114                                                 break;
1115                                         case TAPI_SAT_CALL_CTRL_R_ALLOWED_WITH_MOD:
1116                                                 {
1117                                                         gboolean bsscode = FALSE;
1118
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;
1121
1122                                                         memset(objectInfo.connected_telnumber, 0, sizeof(objectInfo.connected_telnumber));
1123                                                         memset(objectInfo.connected_name, 0, sizeof(objectInfo.connected_name));
1124
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);
1127
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);
1132
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);
1137
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);
1140                                                         } else {
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);
1143
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);
1147                                                         }
1148
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);
1151                                                 }
1152                                                 break;
1153                                         default:
1154                                                 CALL_ENG_DEBUG(ENG_DEBUG, "SAT_CALL_CONTROL - not defined return code");
1155                                                 break;
1156                                         }
1157                                 }
1158                                 break;
1159                         default:
1160                                 CALL_ENG_DEBUG(ENG_DEBUG, "Invalid Sat Event Type");
1161                                 break;
1162                         }
1163                 }
1164                 break;
1165         default:
1166                 CALL_ENG_DEBUG(ENG_DEBUG, "Invalid SAT Event");
1167                 return FALSE;
1168         }
1169         return TRUE;
1170 }
1171
1172 static gboolean __call_vc_incoming_idle_cb(gpointer puser_data)
1173 {
1174         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)puser_data;
1175         call_vc_call_objectinfo_t callobject_info;
1176
1177         CALL_ENG_DEBUG(ENG_DEBUG, "Handling Incoming call in Idle Callback");
1178
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");
1181                 return FALSE;
1182         }
1183
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);
1187         }
1188
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);
1192
1193         /* Reset Incoming Call Details */
1194         gincoming_call_handle = VC_TAPI_INVALID_CALLHANDLE;
1195         memset(&gincoming_call_info, 0, sizeof(TelCallIncomingCallInfo_t));
1196
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);
1201                 return FALSE;
1202         }
1203
1204         /*Always Return FALSE from this g_idle callback, so it will not be called again */
1205         return FALSE;
1206 }
1207
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)
1210 {
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;
1214
1215         CALL_ENG_DEBUG(ENG_DEBUG, "Rejecting the [Call:%d] in IDLE CB", gincoming_call_handle);
1216
1217         if (gincoming_call_handle != -1) {
1218                 _vc_core_cm_get_call_object(&pcall_agent->call_manager, gincoming_call_handle, &call_object);
1219
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);
1225                         }
1226
1227                         gincoming_call_handle = -1;
1228                 }
1229         }
1230         return FALSE;
1231 }
1232
1233 /*Always reject the call, if the reject call handle is valid*/
1234 static gboolean __call_vc_reject_call_idle_cb(gpointer puser_data)
1235 {
1236         call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)puser_data;
1237         TapiResult_t tapi_err = TAPI_API_SUCCESS;
1238
1239         CALL_ENG_DEBUG(ENG_DEBUG, "Rejecting the [Call Handle :%d] in IDLE CB", gincoming_call_handle);
1240
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);
1246                 }
1247                 gphone_rejected_call = -1;
1248         }
1249         return FALSE;
1250 }
1251
1252 static gboolean __call_vc_sat_idle_cb(gpointer puser_data)
1253 {
1254         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)puser_data;
1255
1256         TelSatSetupCallIndCallData_t temp_data = { 0, };
1257
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);
1264
1265         __call_vc_handle_sat_engine_events(pagent, VC_ACTION_SAT_REQUEST, gsat_event_type, gtype, gpresult);
1266
1267         /*Free the result after copying the data */
1268         /*g_free(gpresult);*/
1269         gpresult = NULL;
1270         /*Always Return FALSE from this g_idle callback, so it will not be called again */
1271         return FALSE;
1272 }
1273
1274 void _vc_core_engine_handle_incoming_tapi_events(void *mt_data, void *userdata)
1275 {
1276         char *data = mt_data;
1277
1278         call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
1279
1280         VOICECALL_RETURN_IF_FAIL(pagent != NULL);
1281
1282         int current_mt_call_handle = -1;
1283         CALL_ENG_DEBUG(ENG_DEBUG, "event_type == TAPI_EVENT_CALL_INCOM_IND...");
1284
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);
1288
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 *************************");
1294
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 *************************");
1300                 return;
1301         }
1302
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;
1306
1307         CALL_ENG_DEBUG(ENG_DEBUG, "CallHandle = %d,  Number = %s", gincoming_call_info.CallHandle, gincoming_call_info.szCallingPartyNumber);
1308
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");
1312
1313                 gphone_rejected_call = gincoming_call_handle;
1314
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);
1317
1318                 return;
1319         }
1320
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 */
1328                 {
1329                         call_vc_call_objectinfo_t objectInfo;
1330
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);
1335
1336                         /* add new member info */
1337                         _vc_core_cm_add_call_object(&pagent->call_manager, &objectInfo);
1338
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);
1341
1342                         return;
1343                 }
1344                 break;
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:
1351                 {
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);
1355
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);
1358                 }
1359         default:
1360                 break;
1361         }
1362
1363         /*If Incoming End event is still pending, First Process the incoming end indication before processing the new
1364            Incoming Call */
1365         if (VC_INOUT_STATE_INCOME_END == pagent->io_state) {
1366                 int mt_call_handle = -1;
1367
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);
1372                 }
1373         }
1374
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);
1379         }
1380
1381         CALL_ENG_DEBUG(ENG_DEBUG, "MT CALL event processed done.");
1382         return;
1383
1384 }
1385
1386 static void __call_vc_handle_tapi_events(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
1387 {
1388
1389         call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
1390
1391         VOICECALL_RETURN_IF_FAIL(pagent != NULL);
1392
1393         CALL_ENG_DEBUG(ENG_WARN, "event_type:[%s]", noti_id);
1394
1395         /* Process TAPI events */
1396         if (strcmp(noti_id, TAPI_NOTI_VOICE_CALL_STATUS_IDLE) == 0) {
1397                 /* End IND */
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;
1404
1405                 CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_NOTI_VOICE_CALL_STATUS_IDLE..");
1406
1407                 /* tapicallback data =  TelCallStatusIdleNoti_t */
1408                 if (data != NULL) {
1409                         memset(&callIdleInfo, 0, sizeof(TelCallStatusIdleNoti_t));
1410                         memcpy(&callIdleInfo, data, sizeof(TelCallStatusIdleNoti_t));
1411
1412                         call_handle = callIdleInfo.id;
1413                         tapi_cause = callIdleInfo.cause;
1414                 }
1415
1416                 CALL_ENG_DEBUG(ENG_DEBUG, "Call Handle = %d,end cause:%d", call_handle, tapi_cause);
1417
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");
1421
1422                         gphone_rejected_call = VC_TAPI_INVALID_CALLHANDLE;
1423
1424                         /*If no more calls available, End the Application */
1425                         __vc_core_check_engine_active_task(pagent);
1426                         return;
1427                 }
1428
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);
1431
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:
1437                         {
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);
1441                                 return;
1442                         }
1443                         break;
1444                 case VC_CALL_STATE_REJECTED:
1445                         {
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");
1450
1451                                         /*If no more calls available, End the Application */
1452                                         __vc_core_check_engine_active_task(pagent);
1453                                         return;
1454                                 }
1455                         }
1456                         break;
1457                 default:
1458                         break;
1459                 }
1460
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);
1464
1465                         /*Change the In Out state to None*/
1466                         _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_NONE);
1467
1468                         /*Notify Client about rejected Event*/
1469                         _vc_core_ca_send_event_to_client(pagent, VC_CALL_REJECTED_END, call_handle, 0, NULL);
1470
1471                         return;
1472                 }
1473
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);
1481                         return;
1482                 }
1483
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);
1487                         return;
1488                 }
1489
1490                 /*End of Normal Connected Call */
1491                 _vc_core_tapi_event_handle_call_end_event(pagent, noti_id, call_handle, tapi_cause);
1492
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);
1497
1498                         /*
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.
1502                          */
1503                         {
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);
1507                         }
1508                 } else {
1509                         _vc_core_ca_send_event_to_client(pagent, VC_CALL_NORMAL_END, objectInfo.call_handle, objectInfo.end_cause_type, NULL);
1510                 }
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;
1515
1516                 if (data != NULL) {
1517                         memset(&callActiveInfo, 0, sizeof(TelCallStatusActiveNoti_t));
1518                         memcpy(&callActiveInfo, data, sizeof(TelCallStatusActiveNoti_t));
1519                         call_handle = callActiveInfo.id;
1520                 }
1521                 CALL_ENG_DEBUG(ENG_DEBUG, "IO State: %d", pagent->io_state);
1522                 CALL_ENG_DEBUG(ENG_DEBUG, "Connected Call Handle = %d", call_handle);
1523
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...");
1528                 } else {
1529                         CALL_ENG_DEBUG(ENG_ERR, "invalid connected event Call Handle = %d", call_handle);
1530
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);
1534
1535                                 assert(0);
1536                         } else {
1537                                 CALL_ENG_DEBUG(ENG_ERR, "No pending calls to connect, ignoreing connect event for call handle= %d", call_handle);
1538                                 return;
1539                         }
1540                         return;
1541                 }
1542
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) {
1547                 /*Dialing IND*/
1548                 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1549                 TelCallStatusDialingNoti_t callDialingInfo;
1550                 call_vc_call_objectinfo_t objectInfo;
1551
1552                 CALL_ENG_DEBUG(ENG_DEBUG, "Data Received for DIALING_IND is %p", data);
1553
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);
1556                 } else {
1557                         CALL_ENG_DEBUG(ENG_ERR, "EXCEPTION:Outgoing call Info Missing..");
1558                 }
1559
1560
1561                 /* tapicallback data =  TelCallStatusHeldNoti_t */
1562                 if (data != NULL) {
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);
1567                 }
1568
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);
1571                         return;
1572                 }
1573
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");
1577                         return;
1578                 }
1579
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);
1583
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;
1590
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);
1596                         return;
1597                 }
1598
1599                 if (data != NULL) {
1600                         memset(&callAlertInfo, 0, sizeof(TelCallStatusAlertNoti_t));
1601                         memcpy(&callAlertInfo, data, sizeof(TelCallStatusAlertNoti_t));
1602                         call_handle = callAlertInfo.id;
1603                 }
1604
1605                 CALL_ENG_DEBUG(ENG_DEBUG, "Alert Call Handle = %d", call_handle);
1606
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);
1609
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");
1613                         return;
1614                 }
1615
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;
1659
1660                 if (data != NULL) {
1661                         memset(&wbamrInfo, 0, sizeof(TelCallSoundWbamrNoti_t));
1662                         memcpy(&wbamrInfo, data, sizeof(TelCallSoundWbamrNoti_t));
1663                 }
1664
1665                 CALL_ENG_DEBUG(ENG_DEBUG, "WBAMR is %d", wbamrInfo);
1666                 if (wbamrInfo == TAPI_CALL_SOUND_WBAMR_STATUS_ON) {
1667                         wbamr_status = TRUE;
1668                 }
1669
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");
1673         } else {
1674                 CALL_ENG_DEBUG(ENG_DEBUG, "ERROR!! Noti is not defined");
1675         }
1676
1677         CALL_ENG_DEBUG(ENG_DEBUG, "tapi noti(%s) processed done.", noti_id);
1678
1679         return;
1680 }
1681
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)
1683 {
1684         call_vc_call_objectinfo_t objectInfo;
1685         voice_call_end_cause_type_t endcause_type = 0;
1686
1687         VOICECALL_RETURN_FALSE_IF_FAIL(pagent != NULL);
1688
1689         _vc_core_cm_clear_call_object(&objectInfo);
1690         _vc_core_cm_get_call_object(&pagent->call_manager, call_handle, &objectInfo);
1691
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);
1696
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 */
1703
1704                         call_vc_satsetup_info_t *pcall_vc_satcall_info = NULL;
1705
1706                         pcall_vc_satcall_info = (call_vc_satsetup_info_t *) &(pagent->call_manager.setupcall_info.satcall_setup_info);
1707
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);
1711                         }
1712                 }
1713
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;
1718                 }
1719         }
1720
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);
1725
1726                 if (FALSE == bActiveCall) {
1727                         if (TRUE == bHoldCall) {
1728                                 CALL_ENG_DEBUG(ENG_DEBUG, "Continue SS Action");
1729
1730                                 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_NONE);
1731
1732                                 if (_vc_core_tapi_rqst_retrieve_call(pagent) == TRUE) {
1733                                         _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_UNHOLD);
1734                                 } else {
1735                                         _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
1736                                 }
1737                         } else {
1738                                 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
1739                         }
1740                 } else {
1741                         CALL_ENG_DEBUG(ENG_DEBUG, "active call must not exist!");
1742                         _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
1743                 }
1744         }
1745
1746         return TRUE;
1747 }
1748
1749 static gboolean __call_vc_incoming_call_end_idle_cb(gpointer puser_data)
1750 {
1751         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)puser_data;
1752         call_vc_handle call_handle = -1;
1753
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);
1760                 }
1761         }
1762         return FALSE;
1763 }
1764
1765 static gboolean __call_vc_incomingcall_endhandle(call_vc_callagent_state_t *pagent, call_vc_handle call_handle)
1766 {
1767         CALL_ENG_DEBUG(ENG_DEBUG, "");
1768
1769         CALL_VC_DUMP_CALLDETAILS(&pagent->call_manager);
1770
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");
1773
1774                 /*Remove Call Object Once the Incoming Call Got Ended*/
1775                 _vc_core_cm_remove_call_object(&pagent->call_manager, call_handle);
1776
1777                 CALL_VC_DUMP_CALLDETAILS(&pagent->call_manager);
1778
1779                 /*Finally Move the IO State None*/
1780                 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_NONE);
1781         }
1782         return TRUE;
1783 }
1784
1785 static gboolean __call_vc_is_callagent_waitstate(call_vc_callagent_state_t *pagent)
1786 {
1787
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:
1803                 {
1804                         return TRUE;
1805                 }
1806                 break;
1807         default:
1808                 return FALSE;
1809         }
1810 }
1811
1812 /**
1813  * This function checks whether dtmf is possible
1814  *
1815  * @return              This function returns TRUE if dtmf is possible or else FALSE
1816  * @param[in]           pcall_agent                     Pointer to the call agent structure
1817  */
1818 static gboolean __vc_core_is_dtmf_possible(call_vc_callagent_state_t *pcall_agent)
1819 {
1820         VOICECALL_RETURN_FALSE_IF_FAIL(pcall_agent != NULL);
1821         CALL_ENG_DEBUG(ENG_DEBUG, "");
1822
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");
1825                 return FALSE;
1826         }
1827
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");
1830                 return FALSE;
1831         }
1832
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");
1835                 return FALSE;
1836         }
1837
1838         CALL_ENG_DEBUG(ENG_DEBUG, "DTMF Possible");
1839         return TRUE;
1840 }
1841
1842 /**
1843  * This function checks the voicecall engine's idle status and send VC_ACTION_NO_ACTIVE_TASK to client if engine is idle
1844  *
1845  * @return              void
1846  * @param[in]           pcall_agent     Pointer to the call agent structure
1847  */
1848 void __vc_core_check_engine_active_task(call_vc_callagent_state_t *pcall_agent)
1849 {
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);
1854         }
1855 }
1856
1857 /**
1858 * This function ends only the connected call corresponding to the given call handle
1859 *
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
1868 */
1869 voicecall_error_t _vc_core_engine_end_call_byhandle(voicecall_engine_t *pvoicecall_agent, int call_handle)
1870 {
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);
1874
1875         return (TRUE == _vc_core_tapi_rqst_end_call_by_callhandle(pagent, call_handle)) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
1876 }
1877
1878 /**
1879 * This function ends a call corresponding to the given call ID
1880 *
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
1890 */
1891 voicecall_error_t _vc_core_engine_end_call_bycallId(voicecall_engine_t *pvoicecall_agent, int call_id)
1892 {
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;
1896
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);
1899
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;
1903         }
1904
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) {
1907
1908                 if (-1 == _vc_core_cm_get_active_group_index(&pagent->call_manager)) {
1909                         return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
1910                 }
1911
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;
1915                 }
1916         } else if (CALL_VC_GROUP_STATE_HOLD == call_group_state) {
1917                 int held_group_member_num = 0;
1918                 int held_group_index = -1;
1919
1920                 held_group_index = _vc_core_cm_get_held_group_index(&pagent->call_manager);
1921                 if (-1 == held_group_index) {
1922                         return FALSE;
1923                 }
1924
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;
1929                 }
1930
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;
1934                 }
1935         }
1936
1937         return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
1938 }
1939
1940 /**
1941 * This function ends the call according to the given end call type
1942 *
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
1951 *                               .
1952 */
1953 voicecall_error_t _vc_core_engine_end_call(voicecall_engine_t *pvoicecall_agent, _vc_core_engine_end_call_type_t end_call_type)
1954 {
1955         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
1956         gboolean bret_val = FALSE;
1957
1958         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
1959
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;
1963         }
1964
1965         CALL_ENG_DEBUG(ENG_DEBUG, "end_call_type = %d", end_call_type);
1966
1967         switch (end_call_type) {
1968         case VC_END_OUTGOING_CALL:
1969                 {
1970                         bret_val = _vc_core_tapi_rqst_release_outgoing_call(pagent);
1971                 }
1972                 break;
1973         case VC_END_INCOMING_CALL:
1974                 {
1975                         bret_val = _vc_core_tapi_rqst_release_incoming_call(pagent);
1976                 }
1977                 break;
1978         case VC_END_ACTIVE_OR_HELD_CALLS:
1979                 {
1980                         bret_val = _vc_core_tapi_rqst_end_call(pagent);
1981                 }
1982                 break;
1983         case VC_END_ALL_ACTIVE_CALLS:
1984                 {
1985                         bret_val = _vc_core_ca_end_active_calls(pagent);
1986                 }
1987                 break;
1988         case VC_END_ALL_HELD_CALLS:
1989                 {
1990                         bret_val = _vc_core_ca_end_held_calls(pagent);
1991                 }
1992                 break;
1993         case VC_END_ALL_CALLS:
1994                 {
1995                         bret_val = _vc_core_ca_end_all_calls(pagent);
1996                 }
1997                 break;
1998         default:
1999                 return ERROR_VOICECALL_INVALID_CALL_TYPE;
2000         }
2001
2002         return (TRUE == bret_val) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_INCOMPLETE;
2003 }
2004
2005 /**
2006 * This function does the explicit call transfer
2007 *
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
2011 */
2012 voicecall_error_t _vc_core_engine_transfer_calls(voicecall_engine_t *pvoicecall_agent)
2013 {
2014         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2015
2016         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2017
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;
2022         } else {
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;
2026                 }
2027         }
2028
2029         return ERROR_VOICECALL_TRANSFER_FAILED;
2030 }
2031
2032 /**
2033 * This function swaps the active and held calls if any available
2034 *
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
2041 *
2042 */
2043 voicecall_error_t _vc_core_engine_swap_calls(voicecall_engine_t *pvoicecall_agent)
2044 {
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);
2047
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;
2051         }
2052
2053         if (TRUE == _vc_core_tapi_rqst_swap_calls(pagent)) {
2054 #ifdef SWAP_SUPPORT
2055                 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_SWAP_HOLD_OR_ACTIVATE);
2056 #else
2057                 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_SWAP);
2058 #endif
2059                 return ERROR_VOICECALL_NONE;
2060         }
2061
2062         return ERROR_VOICECALL_SWAP_FAILED;
2063 }
2064
2065 /**
2066 * This function puts the active call if any on hold
2067 *
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
2072 */
2073 voicecall_error_t _vc_core_engine_hold_call(voicecall_engine_t *pvoicecall_agent)
2074 {
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);
2077
2078         if (TRUE == __call_vc_is_callagent_waitstate(pagent)) {
2079                 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
2080         }
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;
2086                 }
2087         } else {
2088                 return ERROR_VOICECALL_HOLD_NOT_SUPPORTED;
2089         }
2090 #else
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;
2094         }
2095 #endif
2096         return ERROR_VOICECALL_HOLD_FAILED;
2097 }
2098
2099 /**
2100 * This function retrieves/activates the held call
2101 *
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
2106 */
2107 voicecall_error_t _vc_core_engine_retrieve_call(voicecall_engine_t *pvoicecall_agent)
2108 {
2109         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2110
2111         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2112
2113         if (TRUE == __call_vc_is_callagent_waitstate(pagent)) {
2114                 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
2115         }
2116
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;
2120         }
2121         return ERROR_VOICECALL_RETREIVE_FAILED;
2122 }
2123
2124 /**
2125 * This function sets up a conference beween the currently available active and held calls
2126 *
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
2133 *
2134 */
2135 voicecall_error_t _vc_core_engine_setup_conference(voicecall_engine_t *pvoicecall_agent)
2136 {
2137         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2138
2139         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2140
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;
2146         } else {
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;
2150                 }
2151         }
2152         return ERROR_VOICECALL_SETUP_CONF_FAILED;
2153 }
2154
2155 /**
2156 * This function makes a private call to the call member corressponding to the given call id.
2157 *
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
2165 *
2166 */
2167 voicecall_error_t _vc_core_engine_private_call_by_callid(voicecall_engine_t *pvoicecall_agent, int call_id)
2168 {
2169         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2170
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);
2173
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;
2178         } else {
2179                 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
2180
2181                 call_handle = _vc_core_cm_get_call_handle_ingroup_bycallId(&pagent->call_manager, call_id);
2182
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;
2185                 }
2186         }
2187
2188         return ERROR_VOICECALL_INVALID_CALLID;
2189 }
2190
2191 /**
2192 * This function makes a private call to the given call member from the currently available active conference call
2193 *
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
2201 *
2202 */
2203 voicecall_error_t _vc_core_engine_private_call(voicecall_engine_t *pvoicecall_agent, int call_handle)
2204 {
2205         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2206
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);
2209
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;
2214         }
2215
2216         return (TRUE == _vc_core_tapi_rqst_private_call(pagent, call_handle)) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_REQUEST_FAILED;
2217 }
2218
2219 /**
2220 * This function rejects the incoming call if any
2221 *
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
2228 */
2229 voicecall_error_t _vc_core_engine_reject_call(voicecall_engine_t *pvoicecall_agent, gboolean budub)
2230 {
2231         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2232         int error_code = -1;
2233         gboolean ret = FALSE;
2234
2235         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2236
2237         ret = _vc_core_tapi_rqst_reject_mt_call(pagent, budub, &error_code);
2238
2239         return (TRUE == ret) ? ERROR_VOICECALL_NONE : error_code;
2240 }
2241
2242 /**
2243 * This function answers a call according to the given answer type
2244 *
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
2250 */
2251 voicecall_error_t _vc_core_engine_answer_call(voicecall_engine_t *pvoicecall_agent, voicecall_answer_type_t answer_type)
2252 {
2253         call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
2254         int error_code = 0;
2255         gboolean ret = FALSE;
2256
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);
2260 #else
2261         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(answer_type, VC_ANSWER_NORMAL, VC_ANSWER_RELEASE_HOLD_AND_ACCEPT, ERROR_VOICECALL_INVALID_ARGUMENTS);
2262 #endif
2263         ret = _vc_core_tapi_rqst_answer_call(pcall_agent, answer_type, &error_code);
2264
2265         return (TRUE == ret) ? ERROR_VOICECALL_NONE : error_code;
2266 }
2267
2268 /**
2269 * This function sends the given dtmf digits
2270 *
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,*,#)
2276 *
2277 */
2278 voicecall_error_t _vc_core_engine_send_dtmf(voicecall_engine_t *pvoicecall_agent, char *pdtmf_string)
2279 {
2280         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2281
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);
2284
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;
2288         }
2289
2290         return (TRUE == _vc_core_tapi_rqst_start_dtmf(pagent, pdtmf_string)) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_DTMF_FAILED;
2291 }
2292
2293 /**
2294 * This function sends response to sat based on the given sat response type
2295 *
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
2300 */
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)
2302 {
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);
2307
2308         return (TRUE == _vc_core_ca_send_sat_response(pagent, sat_rqst_resp_type, sat_response_type)) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_REQUEST_FAILED;
2309 }
2310
2311 /**
2312 * This function finalizes the voiecall engine and removes all allocated resources
2313 *
2314 * @return               nothing
2315 * @param[in]            pvoicecall_agent        Handle to Voicecall Engine
2316 * @remarks              pvoicecall_agent cannot be NULL
2317 */
2318 void _vc_core_engine_engine_finish(voicecall_engine_t *pvoicecall_agent)
2319 {
2320         call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
2321         VOICECALL_RETURN_IF_FAIL(pvoicecall_agent != NULL);
2322
2323         /*Unsubscribe Events */
2324         CALL_ENG_DEBUG(ENG_DEBUG, "Unsubscribing Events");
2325
2326         tel_deinit(pcall_agent->tapi_handle);
2327
2328         VOICECALL_RETURN_IF_FAIL(pcall_agent != NULL);
2329         _vc_core_ca_finish_agent(pcall_agent);
2330 }
2331
2332 #ifdef _SAT_MENU_
2333 /**
2334 * This function requests SAT Engine to setup SIM services Menu
2335 *
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.
2339 */
2340 voicecall_error_t voicecall_request_sat_menu(voicecall_engine_t *pvoicecall_agent)
2341 {
2342         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2343         TelSatSetupMenuInfo_t sim_menu; /*LiMo SAT*/
2344
2345         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2346
2347         CALL_ENG_DEBUG(ENG_DEBUG, "");
2348         memset(&sim_menu, 0, sizeof(TelSatSetupMenuInfo_t));
2349         /*LiMo SAT*/
2350         if (FALSE == TelTapiSatGetMainMenuList(&sim_menu)) {
2351                 CALL_ENG_DEBUG(ENG_DEBUG, "TelTapiSatGetMainMenuList failed");
2352                 return ERROR_VOICECALL_REQUEST_FAILED;
2353         }
2354
2355         return ERROR_VOICECALL_NONE;
2356 }
2357
2358 /**
2359 * This function retreives the SIM Menu Title from the SAT Engine
2360 *
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
2364 */
2365 voicecall_error_t voicecall_request_sat_menu_title(voicecall_engine_t *pvoicecall_agent, char *title)
2366 {
2367         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2368         TelSatMainMenuTitleInfo_t sat_menu_title;       /*LiMo SAT*/
2369
2370         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2371         VOICECALL_RETURN_VALUE_IF_FAIL(title != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2372
2373         CALL_ENG_DEBUG(ENG_DEBUG, "");
2374
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;
2380                 }
2381         }
2382
2383         return ERROR_VOICECALL_REQUEST_FAILED;
2384 }
2385 #endif
2386
2387 /**
2388 * This function prepares the engine for the redial call. It preserves the previsouly made call object to used for the next make call
2389 *
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
2395 */
2396 voicecall_error_t _vc_core_engine_prepare_redial(voicecall_engine_t *pvoicecall_agent, int call_handle)
2397 {
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;
2401
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);
2404
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;
2409         }
2410
2411         if (FALSE == _vc_core_cm_get_call_object(&pagent->call_manager, call_handle, &call_object)) {
2412                 return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
2413         }
2414
2415         /*Set the callobject status */
2416         call_object.state = VC_CALL_STATE_REDIAL;
2417
2418         /*Reintialize Call ID */
2419         call_object.call_id = 0;
2420         _vc_core_cm_set_call_object(&pagent->call_manager, &call_object);
2421
2422         /*Set Engine IO State */
2423         _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_OUTGOING_SHOW_REDIALCAUSE);
2424
2425         /*todo Set SAT Redial Data */
2426
2427         return ERROR_VOICECALL_NONE;
2428 }
2429
2430 #ifdef _OLD_SAT_
2431 /**
2432 * This function checks whether SAT redial duration is valid
2433 *
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
2438 */
2439 voicecall_error_t voicecall_get_sat_redial_duration_status(voicecall_engine_t *pvoicecall_agent, gboolean *bredial_duration)
2440 {
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;
2443
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);
2446
2447         pcall_vc_satcall_info = (call_vc_satsetup_info_t *) &(pagent->call_manager.setupcall_info.satcall_setup_info);
2448
2449         CALL_ENG_DEBUG(ENG_DEBUG, "SAT Redial Duration Status= %d", pcall_vc_satcall_info->bduration);
2450
2451         *bredial_duration = pcall_vc_satcall_info->bduration;
2452         return ERROR_VOICECALL_NONE;
2453 }
2454
2455 /**
2456 * This function sets the current duration and retrieves the modified remaining SAT redial duration
2457 *
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
2462 */
2463 voicecall_error_t voicecall_get_set_sat_remaining_duration(voicecall_engine_t *pvoicecall_agent, long *remaining_duration)
2464 {
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;
2467
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);
2470
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);
2474
2475         return ERROR_VOICECALL_NONE;
2476 }
2477 #endif
2478
2479 voicecall_error_t _vc_core_engine_get_sat_dtmf_hidden_mode(voicecall_engine_t *pvoicecall_agent, gboolean *bhidden_mode)
2480 {
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;
2483
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);
2486
2487         pcall_vc_satcall_info = (call_vc_satsetup_info_t *) &(pagent->call_manager.setupcall_info.satcall_setup_info);
2488
2489         CALL_ENG_DEBUG(ENG_DEBUG, "SAT Hidden Mode= %d", pcall_vc_satcall_info->satengine_dtmf_data.bIsHiddenMode);
2490
2491         *bhidden_mode = pcall_vc_satcall_info->satengine_dtmf_data.bIsHiddenMode;
2492         return ERROR_VOICECALL_NONE;
2493 }
2494
2495 /**
2496 * This function changes the voice audio path
2497 *
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
2502 */
2503 voicecall_error_t _vc_core_engine_change_audio_path(voicecall_engine_t *pvoicecall_agent, voicecall_audio_path_t audio_path, gboolean bextra_volume)
2504 {
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;
2509
2510         VOICECALL_RETURN_VALUE_IF_FAIL(pcall_agent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2511
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;
2515         }
2516
2517         switch (audio_path) {
2518         case VC_AUDIO_PATH_HANDSET:
2519                 {
2520                         tapi_sound_path.path = TAPI_SOUND_PATH_HANDSET;
2521                 }
2522                 break;
2523         case VC_AUDIO_PATH_HEADSET:
2524                 {
2525                         tapi_sound_path.path = TAPI_SOUND_PATH_HEADSET;
2526                 }
2527                 break;
2528         case VC_AUDIO_PATH_HANDSFREE:
2529                 {
2530                         tapi_sound_path.path = TAPI_SOUND_PATH_HANDSFREE;
2531                 }
2532                 break;
2533         case VC_AUDIO_PATH_BLUETOOTH:
2534                 {
2535                         tapi_sound_path.path = TAPI_SOUND_PATH_BLUETOOTH;
2536                 }
2537                 break;
2538         case VC_AUDIO_PATH_STEREO_BLUETOOTH:
2539                 {
2540                         tapi_sound_path.path = TAPI_SOUND_PATH_STEREO_BLUETOOTH;
2541                 }
2542                 break;
2543         case VC_AUDIO_PATH_SPK_PHONE:
2544                 {
2545                         tapi_sound_path.path = TAPI_SOUND_PATH_SPK_PHONE;
2546                 }
2547                 break;
2548         case VC_AUDIO_PATH_HEADSET_3_5PI:
2549                 {
2550                         tapi_sound_path.path = TAPI_SOUND_PATH_HEADSET_3_5PI;
2551                 }
2552                 break;
2553         default:
2554                 {
2555                         CALL_ENG_DEBUG(ENG_DEBUG, "Invalid audio path");
2556                         return ERROR_VOICECALL_INVALID_ARGUMENTS;
2557                 }
2558                 break;
2559         }
2560
2561         CALL_ENG_DEBUG(ENG_DEBUG, "tapi_audio_path: %d(extra voluem: %d)", tapi_sound_path, bextra_volume);
2562         if ((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;
2566         } else {
2567                 tapi_sound_path.ex_volume = TAPI_SOUND_EX_VOLUME_OFF;
2568         }
2569
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;
2574         }
2575
2576         return ERROR_VOICECALL_NONE;
2577 }
2578
2579 voicecall_error_t _vc_core_engine_set_audio_mute(voicecall_engine_t *pvoicecall_agent, gboolean bmute_audio)
2580 {
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; 
2584
2585         micmute_set = (TRUE == bmute_audio) ? TAPI_SOUND_MUTE_STATUS_ON : TAPI_SOUND_MUTE_STATUS_OFF;
2586
2587         error = tel_set_call_mute_status(pcall_agent->tapi_handle, micmute_set, _vc_core_engine_set_mute_status_resp_cb, NULL);
2588
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;
2592         }
2593
2594         CALL_ENG_DEBUG(ENG_DEBUG, "End");
2595         return ERROR_VOICECALL_NONE;
2596 }
2597
2598 /**
2599 * This function sets the voice call audio volume for the given audio path type
2600 *
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
2606 */
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)
2608 {
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;
2613
2614         CALL_ENG_DEBUG(ENG_DEBUG, "Start! path(%d), volume(%d)", audio_path_type, vol_level);
2615
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);
2619
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;
2624         }
2625
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;
2631                 break;
2632         case VC_AUDIO_PATH_BLUETOOTH:
2633         case VC_AUDIO_PATH_STEREO_BLUETOOTH:
2634                 vol_info.device = TAPI_SOUND_DEVICE_BLUETOOTH;
2635                 break;
2636         case VC_AUDIO_PATH_SPK_PHONE:
2637                 vol_info.device = TAPI_SOUND_DEVICE_SPEAKER_PHONE;
2638                 break;
2639         default:
2640                 vol_info.device = TAPI_SOUND_DEVICE_RECEIVER;
2641                 break;
2642         }
2643
2644         error = tel_set_call_volume_info(pcall_agent->tapi_handle, &vol_info, _vc_core_engine_set_volume_resp_cb, NULL);
2645
2646         if (error != TAPI_API_SUCCESS) {
2647                 CALL_ENG_DEBUG(ENG_DEBUG, "Tapi API Error: %d", error);
2648                 return ERROR_VOICECALL_TAPI_ERROR;
2649         }
2650
2651         CALL_ENG_DEBUG(ENG_DEBUG, "End");
2652         return ERROR_VOICECALL_NONE;
2653 }
2654
2655 /**
2656 * This function retreives the voice call audio volume for the given audio path type
2657 *
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
2666 *                               param3   - NULL
2667 */
2668 voicecall_error_t _vc_core_engine_get_audio_volume(voicecall_engine_t *pvoicecall_agent, voicecall_audio_path_t audio_path_type)
2669 {
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;
2673
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);
2676
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;
2680         }
2681
2682         switch (audio_path_type) {
2683         case VC_AUDIO_PATH_HEADSET:
2684                 volume_type = TAPI_SOUND_DEVICE_HEADSET;
2685                 break;
2686         case VC_AUDIO_PATH_BLUETOOTH:
2687         case VC_AUDIO_PATH_STEREO_BLUETOOTH:
2688                 volume_type = TAPI_SOUND_DEVICE_BLUETOOTH;
2689                 break;
2690         case VC_AUDIO_PATH_SPK_PHONE:
2691                 volume_type = TAPI_SOUND_DEVICE_SPEAKER_PHONE;
2692                 break;
2693         default:
2694                 volume_type = TAPI_SOUND_DEVICE_RECEIVER;
2695                 break;
2696         }
2697
2698         CALL_ENG_DEBUG(ENG_DEBUG, "volume_type = %d", volume_type);
2699
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);
2702
2703         if (error != TAPI_API_SUCCESS) {
2704                 CALL_ENG_DEBUG(ENG_DEBUG, "Tapi API Error: %d", error);
2705                 return ERROR_VOICECALL_TAPI_ERROR;
2706         }
2707
2708         return ERROR_VOICECALL_NONE;
2709 }
2710
2711 /**
2712 * This function changes the inout state of the engine to the given state
2713 *
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
2719 */
2720 voicecall_error_t _vc_core_engine_change_engine_iostate(voicecall_engine_t *pvoicecall_agent, int io_state)
2721 {
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);
2725
2726         if (TRUE == _vc_core_ca_change_inout_state(pagent, (voicecall_inout_state_t) io_state)) {
2727                 return ERROR_VOICECALL_NONE;
2728         }
2729
2730         return ERROR_VOICECALL_INVALID_ARGUMENTS;
2731 }
2732
2733 voicecall_error_t _vc_core_engine_extract_phone_number(const char *source_tel_number, char *phone_number, const int buf_size)
2734 {
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);
2737
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);
2740         }
2741
2742         return ERROR_VOICECALL_NONE;
2743 }
2744
2745 voicecall_error_t _vc_core_engine_set_to_default_values(voicecall_engine_t *pvoicecall_agent)
2746 {
2747         call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
2748
2749         CALL_ENG_DEBUG(ENG_DEBUG, "Start");
2750         /*Initialize Call Manager */
2751         _vc_core_call_manager_init(&pcall_agent->call_manager);
2752
2753         /* Initialize Call Agent Flags */
2754         _vc_core_ca_init_data(pcall_agent);
2755
2756 #ifdef _CCBS_DEFINED_
2757         /* Init CCBS Info */
2758         _vc_core_init_ccbs_info(pcall_agent);
2759 #endif
2760
2761         /* Init CPHS Info */
2762 #ifdef _CPHS_DEFINED_
2763         _vc_core_svcall_init_cphs_info(pcall_agent);
2764 #endif
2765
2766         CALL_VC_DUMP_CALLDETAILS(&pcall_agent->call_manager);
2767         CALL_ENG_DEBUG(ENG_DEBUG, "End");
2768
2769         return ERROR_VOICECALL_NONE;
2770 }
2771
2772 void _vc_core_engine_dial_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
2773 {
2774         CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_dial_call_resp_cb");
2775
2776         call_vc_call_objectinfo_t objectInfo;
2777         call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
2778
2779         if (TAPI_CAUSE_SUCCESS != result) {
2780                 CALL_ENG_DEBUG(ENG_DEBUG, "MO Call Dial call Failed with error cause: %d", result);
2781
2782                 _vc_core_cm_clear_call_object(&objectInfo);
2783
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... */
2786         }
2787 }
2788
2789 void _vc_core_engine_answer_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
2790 {
2791         CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_answer_call_resp_cb");
2792
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;
2798
2799                         mt_call_handle = _vc_core_cm_get_incoming_call_handle(&pagent->call_manager);
2800
2801                         if (mt_call_handle != -1) {
2802                                 CALL_ENG_DEBUG(ENG_DEBUG, "mt_call_handle = %d", mt_call_handle);
2803
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);
2808                                 }
2809
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);
2813                         }
2814                 }
2815         } else {
2816                 _vc_core_ca_send_event_to_client(pagent, VC_CALL_ANSWER_CNF, 0, 0, NULL);
2817         }
2818 }
2819
2820 void _vc_core_engine_end_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
2821 {
2822         CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_end_call_resp_cb..");
2823
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;
2828
2829         memset(&callEndInfo, 0, sizeof(TelCallEndCnf_t));
2830         memcpy(&callEndInfo, tapi_data, sizeof(TelCallEndCnf_t));
2831
2832         call_handle = callEndInfo.id;
2833         call_end_type = callEndInfo.type;
2834
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");
2838         } else {
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;
2844
2845                 CALL_ENG_DEBUG(ENG_DEBUG, "Call Handle = %d,end cause:%d", call_handle, tapi_cause);
2846
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");
2850
2851                         gphone_rejected_call = VC_TAPI_INVALID_CALLHANDLE;
2852
2853                         /*If no more calls available, End the Application */
2854                         __vc_core_check_engine_active_task(pagent);
2855                         return;
2856                 }
2857
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);
2860
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:
2866                         {
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);
2870                                 return;
2871                         }
2872                         break;
2873                 case VC_CALL_STATE_REJECTED:
2874                         {
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");
2879
2880                                         /*If no more calls available, End the Application */
2881                                         __vc_core_check_engine_active_task(pagent);
2882                                         return;
2883                                 }
2884                         }
2885                         break;
2886                 default:
2887                         break;
2888                 }
2889
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);
2893
2894                         /*Change the In Out state to None*/
2895                         _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_NONE);
2896
2897                         /*Notify Client about rejected Event*/
2898                         _vc_core_ca_send_event_to_client(pagent, VC_CALL_REJECTED_END, call_handle, 0, NULL);
2899
2900                         return;
2901                 }
2902
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);
2910                         return;
2911                 }
2912
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);
2916                         return;
2917                 }
2918
2919                 /*End of Normal Connected Call */
2920                 _vc_core_tapi_event_handle_call_end_event(pagent, "", call_handle, tapi_cause);
2921
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);
2926
2927                         /* jspark
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.
2931                          */
2932                         {
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);
2936                         }
2937                 } else {
2938                         _vc_core_ca_send_event_to_client(pagent, VC_CALL_NORMAL_END, objectInfo.call_handle, objectInfo.end_cause_type, NULL);
2939                 }
2940         }
2941         return;
2942 }
2943
2944 void _vc_core_engine_hold_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
2945 {
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;
2949
2950         if (TAPI_CAUSE_SUCCESS == result) {
2951                 memcpy(&call_handle, tapi_data, sizeof(call_vc_handle));
2952         } else {
2953                 _vc_core_cm_get_first_active_call_handle(&pagent->call_manager, &call_handle);
2954         }
2955
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);
2958         } else {
2959                 /*
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
2963                  */
2964                 _vc_core_cm_clear_endcall_member(&pagent->call_manager);
2965         }
2966 }
2967
2968 void _vc_core_engine_active_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
2969 {
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;
2974
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;
2979         } else {
2980                 _vc_core_cm_get_first_held_call_handle(&pagent->call_manager, &call_handle);
2981         }
2982
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);
2985         } else {
2986                 /*
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
2990                  */
2991                 _vc_core_cm_clear_endcall_member(&pagent->call_manager);
2992         }
2993 }
2994
2995 void _vc_core_engine_swap_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
2996 {
2997         CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_swap_call_resp_cb : %d", result);
2998 }
2999
3000 void _vc_core_engine_join_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3001 {
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;
3005
3006         CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_join_call_resp_cb...");
3007
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;
3012         } else {
3013                 call_handle = 0;
3014         }
3015
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);
3018 }
3019
3020 void _vc_core_engine_split_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3021 {
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;
3025
3026         CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_split_call_resp_cb");
3027
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;
3032         }
3033
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);
3036 }
3037
3038 void _vc_core_engine_transfer_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3039 {
3040         call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
3041
3042         CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_transfer_call_resp_cb");
3043
3044         _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
3045         _vc_core_tapi_event_handle_call_transfer_event(pagent, result);
3046 }
3047
3048 void _vc_core_engine_dtmf_call_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3049 {
3050         call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
3051
3052         CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_dtmf_call_resp_cb");
3053
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);
3058         } else {
3059                 /*Forward the events to client */
3060                 _vc_core_ca_send_event_to_client(pagent, VC_CALL_DTMF_ACK, TRUE, 0, NULL);
3061         }
3062 }
3063
3064 void _vc_core_engine_set_volume_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3065 {
3066         CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_set_volume_resp_cb : %d", result);
3067 }
3068
3069 void _vc_core_engine_get_volume_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3070 {
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;
3075
3076         memset(&snd_resp_data, 0, sizeof(TelCallGetVolumeInfoResp_t));
3077         memcpy(&snd_resp_data, tapi_data, sizeof(TelCallGetVolumeInfoResp_t));
3078
3079         int i = 0;
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;
3084                         break;
3085                 }
3086         }
3087         CALL_ENG_DEBUG(ENG_DEBUG, "Changed Vol Type = %d, Vol Level = %d", tapi_sound_path, volume_level);
3088
3089         _vc_core_ca_send_event_to_client(pagent, VC_CALL_GET_VOLUME_RESP, tapi_sound_path, volume_level, NULL);
3090 }
3091
3092 void _vc_core_engine_set_sound_path_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3093 {
3094         CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_set_sound_path_resp_cb : %d", result);
3095 }
3096
3097 void _vc_core_engine_set_mute_status_resp_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3098 {
3099         CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_set_mute_status_resp_cb : %d", result);
3100 }
3101
3102 void _vc_core_engine_get_aoc_info_cb(TapiHandle *handle, int result, void *tapi_data, void *user_data)
3103 {
3104         CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_engine_get_aoc_info_cb : %d", result);
3105 }