cafbfd5a80f7608f7c7180da1caf008ec09e3676
[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
22 /* Call Module File Includes */
23 #include "vc-core-engine.h"
24 #include "vc-core-callagent.h"
25 #include "vc-core-callmanager.h"
26 #include "vc-core-util.h"
27 #include "vc-core-tapi-evnt.h"
28 #include "vc-core-tapi-rqst.h"
29 #include "vc-core-svcall.h"
30 #include "vc-core-engine-status.h"
31
32 /*Global Variable Declerations */
33
34 /*Incoming Call Details used for Self Event*/
35 static call_vc_handle gincoming_call_handle = VC_TAPI_INVALID_CALLHANDLE;
36 static TelCallIncomingCallInfo_t gincoming_call_info;
37
38 /*Initialization Global Variables*/
39 static gboolean gphone_init_finished = FALSE;
40 static call_vc_handle gphone_rejected_call = VC_TAPI_INVALID_CALLHANDLE;
41
42 static call_vc_callagent_state_t *gpcall_agent_for_callback = NULL;
43 /* SAT call detail used for self event */
44 static int gsat_event_type = 0;
45 static int gtype = 0;
46 static void *gpresult = NULL;
47 static TelSatSetupCallIndCallData_t gSatSetupCallInfo;
48 static TelSatSendDtmfIndDtmfData_t gSatSendDtmfInfo;
49
50 /*Local Function Declarations*/
51 /**
52  * This function handles the end event for outgoing call
53  *
54  * @internal
55  * @return              Returns TRUE on success and FALSE on failure
56  * @param[in]           pcall_agent             Handle to the call agent
57  * @param[in]           call_handle             call handle of the outgoing call
58  * @param[in]           type                            type of the tapi event
59  * @param[in]           tapi_cause              tapi cause
60  */
61 static gboolean __call_vc_outgoingcall_endhandle(call_vc_callagent_state_t *pcall_agent, call_vc_handle call_handle, int type, TelTapiEndCause_t tapi_cause);
62 /**
63  * This function handles the end event for incoming call
64  *
65  * @internal
66  * @return              Returns TRUE on success and FALSE on failure
67  * @param[in]           pcall_agent             Handle to the call agent
68  * @param[in]           call_handle             call handle of the outgoing call
69  */
70 static gboolean __call_vc_incomingcall_endhandle(call_vc_callagent_state_t *pcall_agent, call_vc_handle call_handle);
71 /**
72  * This function checks whether the call agent is in any of the wait state
73  *
74  * @internal
75  * @return              Returns TRUE on if call agent is in wait state or FALSE
76  * @param[in]           pcall_agent             Handle to the call agent
77  */
78 static gboolean __call_vc_is_callagent_waitstate(call_vc_callagent_state_t *pcall_agent);
79 /**
80  * This function creates call details for outgoign call with the given setup info
81  *
82  * @internal
83  * @return              Returns TRUE on if call agent is in wait state or FALSE
84  * @param[in]           pagent                  Handle to the call agent
85  * @param[in]           psetup_call_info        Setup info
86  * @param[out]  pcall_object            Call object containing call details
87  * @param[out]  error_code              Error Code
88  */
89 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);
90
91 /**
92  * This function handles all telephony events
93  *
94  * @internal
95  * @return              Returns TRUE on if call agent is in wait state or FALSE
96  * @param[in]           event                   tapi event data
97  * @param[in]           userdata                        user callback data
98  */
99
100 static void __call_vc_handle_tapi_events(TelTapiEvent_t *event, void *userdata);
101
102 /**
103 * This function handles sat engine notification
104 *
105 * @internal
106 * @return               Returns TRUE on success or FALSE on failure
107 * @param[in]            event                   tapi event data
108 * @param[in]            userdata                        user callback data
109 */
110 static void __call_vc_handle_sat_engine_events_cb(TelTapiEvent_t *event, void *userdata);
111
112 /**
113 * This function subscribes for all notifications required for voicecall engine
114 *
115 * @internal
116 * @return               Returns TRUE on success or FALSE on failure
117 * @param[in]            pcall_agent             handle to voicecall agent structure
118 */
119 static gboolean __call_vc_subscribe_call_events(call_vc_callagent_state_t *pcall_agent);
120
121 /**
122 * This function handles telephony initialized notifications
123 *
124 * @internal
125 * @return               Returns TRUE on success or FALSE on failure
126 * @param[in]            event                   tapi event data
127 * @param[in]            userdata                        user callback data
128 */
129 static void __call_vc_tapi_initialized_cb(TelTapiEvent_t *event, void *userdata);
130
131 /**
132 * This function subscribes for telephony call notifications
133 *
134 * @internal
135 * @return               Returns TRUE on success or FALSE on failure
136 * @param[in]            pcall_agent             handle to voicecall agent structure
137 */
138 static gboolean __call_vc_subscribe_tapi_event(call_vc_callagent_state_t *pcall_agent);
139
140 /**
141 * This function request the engine to setup a sat call
142 *
143 * @internal
144 * @return               Returns TRUE on success or FALSE on failure
145 * @param[in]            pagent          handle to voicecall agent structure
146 * @param[in]            mo_call_index           call index of the mo call prepared for sat call
147 * @param[in]            ret_code                Error code
148 * @exception            ERROR_VOICECALL_TAPI_CAUSE_CALL_FAILED
149 */
150 static gboolean __call_vc_request_sat_call(call_vc_callagent_state_t *pagent, int mo_call_index, int *ret_code);
151
152 /**
153 * This function hadles the events from the sat engine
154 *
155 * @internal
156 * @return               Returns TRUE on success or FALSE on failure
157 * @param[in]            pcall_agent             handle to voicecall agent structure
158 * @param[in]            sat_event               event type (sat request / sat response)
159 * @param[in]            sat_event_type  sat event sub type
160 * @param[in]            type                            event type received from sat
161 * @param[in]            result                  data received from sat
162 */
163 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);
164
165 /**
166 * This function request the engine to setup a normal voice call
167 *
168 * @internal
169 * @return               Returns TRUE on success or FALSE on failure
170 * @param[in]            pagent          handle to voicecall agent structure
171 * @param[in]            mo_call_index           call index of the mo call prepared for sat call
172 * @param[in]            ret_code                Error code
173 * @exception            ERROR_VOICECALL_TAPI_CAUSE_CALL_FAILED
174 */
175 static gboolean __call_vc_request_call(call_vc_callagent_state_t *pagent, int mo_call_index, int *ret_code);
176
177 /**
178 * This function serves as the callback function for the incoming call idle add function
179 *
180 * @return               Returns TRUE - if the callback has to be called again, FALSE otherwise
181 * @param[in]            puser_data      data set by the user
182 */
183 static gboolean __call_vc_incoming_idle_cb(gpointer puser_data);
184 static gboolean __call_vc_incoming_call_end_idle_cb(gpointer puser_data);
185 static gboolean __call_vc_reject_call_idle_cb(gpointer puser_data);
186 static gboolean __call_vc_reject_call_full_idle_cb(gpointer puser_data);
187
188 /**
189 * This function serves as the callback function for the SAT idle add function
190 *
191 * @return               Returns TRUE - if the callback has to be called again, FALSE otherwise
192 * @param[in]            puser_data      data set by the user
193 */
194 static gboolean __call_vc_sat_idle_cb(gpointer puser_data);
195
196 /**
197  * This function checks the voicecall engine's idle status and send VC_ACTION_NO_ACTIVE_TASK to client if engine is idle
198  *
199  * @return              void
200  * @param[in]           pcall_agent     Pointer to the call agent structure
201  */
202 static void __vc_core_check_engine_active_task(call_vc_callagent_state_t *pcall_agent);
203
204 /**
205 * This function initializes the voicecall engine
206 *
207 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
208 * @param[out]   pcall_agent_out Pointer to the address of call agent
209 * @param[in]    pcallback_func  Call back function
210 * @param[in]    puser_data              Data set by user
211 * @remarks              pcall_agent_out and pcallback_func cannot be NULL.
212 *                               Output Parameter pcall_agent_out should be initialized to NULL
213 */
214 voicecall_error_t _vc_core_engine_init(voicecall_engine_t **pcall_agent_out, voicecall_cb pcallback_func, void *puser_data)
215 {
216         call_vc_callagent_state_t *pcall_agent = NULL;
217
218         CALL_ENG_DEBUG(ENG_DEBUG, "Voicecall Engine");
219
220         VOICECALL_RETURN_VALUE_IF_FAIL(pcall_agent_out != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
221         VOICECALL_RETURN_VALUE_IF_FAIL(*pcall_agent_out == NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
222
223         /*Initialize Call Agent*/
224         pcall_agent = _vc_core_ca_init_agent();
225         if (NULL == pcall_agent) {
226                 return ERROR_VOICECALL_MEMALLOC_FAILURE;
227         }
228
229         if (FALSE == __call_vc_subscribe_call_events(pcall_agent)) {
230                 CALL_ENG_DEBUG(ENG_DEBUG, "Event Subscrition Failed");
231                 _vc_core_ca_finish_agent(pcall_agent);
232                 return ERROR_VOICECALL_NOTI_FAILED;
233         }
234         /*Store the Callback Pointer*/
235         pcall_agent->client_callback = pcallback_func;
236         pcall_agent->puser_data = puser_data;
237
238         /*Calls to Tapi Should not be made in the application initialization, because this code will be executed if application is launched during
239         an incoming call also. so DBus Lock up can happen.*/
240         gphone_init_finished = TRUE;
241
242         /*Init Success, Assign Output Parameters*/
243         *pcall_agent_out = (voicecall_engine_t *)pcall_agent;
244
245         return ERROR_VOICECALL_NONE;
246 }
247
248 void _vc_core_engine_handle_sat_events_cb(void *sat_setup_call_data, void *userdata)
249 {
250         char *data = sat_setup_call_data;
251
252         call_vc_callagent_state_t *pcall_agent = gpcall_agent_for_callback;
253
254         CALL_ENG_DEBUG(ENG_DEBUG, "sat event callback.");
255
256         memset(&gSatSetupCallInfo, 0, sizeof(TelSatSetupCallIndCallData_t));
257         memcpy(&gSatSetupCallInfo, data, sizeof(TelSatSetupCallIndCallData_t));
258
259         gsat_event_type = SAT_RQST_SETUP_CALL;
260         gtype = TAPI_EVENT_SAT_SETUP_CALL_IND;
261         gpresult = &gSatSetupCallInfo;
262         g_idle_add(__call_vc_sat_idle_cb, pcall_agent);
263
264         CALL_ENG_DEBUG(ENG_DEBUG, "Call back Ends and returning..");
265 }
266
267 static void __call_vc_handle_sat_engine_events_cb(TelTapiEvent_t *event, void *userdata)
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         int event_type = event->EventType;
274         /*int status = event->Status;*/
275         char *data = event->pData;
276
277         switch (event_type) {
278         case TAPI_EVENT_SAT_SETUP_CALL_IND:
279                 {
280                         /*it will be processed in _vc_core_engine_handle_sat_events_cb().*/
281                         return;
282                 }
283                 break;
284
285         case TAPI_EVENT_SAT_SEND_DTMF_IND:
286                 {
287                         memset(&gSatSendDtmfInfo, 0, sizeof(TelSatSendDtmfIndDtmfData_t));
288                         memcpy(&gSatSendDtmfInfo, data, sizeof(TelSatSendDtmfIndDtmfData_t));
289
290                         gsat_event_type = SAT_RQST_SEND_DTMF;
291                         gtype = event_type;
292                         gpresult = &gSatSendDtmfInfo;
293
294                         g_idle_add(__call_vc_sat_idle_cb, pcall_agent);
295                 }
296                 break;
297
298         case TAPI_EVENT_SAT_CALL_CONTROL_IND:
299                 {
300                         __call_vc_handle_sat_engine_events(pcall_agent, VC_ACTION_SAT_RESPONSE, SAT_RESP_SETUP_CALL, event_type, data);
301                 }
302                 break;
303
304         default:
305                 CALL_ENG_DEBUG(ENG_DEBUG, "Default: event_type = %d", event_type);
306                 break;
307         }
308
309         CALL_ENG_DEBUG(ENG_DEBUG, "Call back Ends and returning..");
310
311         /*Send Process Termintate Event to the Client */
312         if ((event_type == TAPI_EVENT_SAT_SETUP_CALL_IND) || (event_type == TAPI_EVENT_SAT_SEND_DTMF_IND)) {
313                 CALL_ENG_DEBUG(ENG_DEBUG, "Do not check an active task here");
314         } else {
315                 __vc_core_check_engine_active_task(pcall_agent);
316         }
317
318 }
319
320 /*Subscribe Noti Events*/
321 static gboolean __call_vc_subscribe_call_events(call_vc_callagent_state_t *pcall_agent)
322 {
323         clock_t start = 0;
324         clock_t end = 0;
325
326         start = GET_CURR_TIME();
327
328         CALL_ENG_KPI("__call_vc_subscribe_tapi_event start");
329         /* Subscribe Tapi Events */
330         if (FALSE == __call_vc_subscribe_tapi_event(pcall_agent)) {
331                 CALL_ENG_DEBUG(ENG_DEBUG, "Noti subscribe to Tapi Events failed");
332                 return FALSE;
333
334         }
335         CALL_ENG_KPI("__call_vc_subscribe_tapi_event done");
336
337         end = GET_CURR_TIME();
338         PRINT_DIFF_TIME(start, end, "Duration For tapi_call_subscription");
339
340         CALL_ENG_DEBUG(ENG_DEBUG, "Noti Subscription Sucess");
341         return TRUE;
342 }
343
344 /**
345  * This function sends response event to the registered client
346  *
347  * @return              This function returns TRUE on success and FALSE on failure
348  * @param[in]           pcall_agent     Pointer to the call agent structure
349  * @param[in]           event           response event type
350  * @param[in]           param1          param 1 to be passed to the client
351  * @param[in]           param2          param 2 to be passed to the client
352  * @param[in]           param3          param 3 to be passed to the client
353  */
354 gboolean _vc_core_ca_send_event_to_client(call_vc_callagent_state_t *pcall_agent, int event, int param1, int param2, void *param3)
355 {
356         CALL_ENG_DEBUG(ENG_DEBUG, "Sending Event to Client");
357         if (pcall_agent->client_callback != NULL) {
358                 return pcall_agent->client_callback(event, param1, param2, param3, pcall_agent->puser_data);
359         }
360         return FALSE;
361 }
362
363 static void __call_vc_tapi_initialized_cb(TelTapiEvent_t *event, void *userdata)
364 {
365         call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
366         TapiResult_t tapi_err = TAPI_API_SUCCESS;
367         TelSimCardStatus_t sim_status = 0;
368         TelSimCardType_t card_type = 0;
369         int sim_changed = 0;
370
371         CALL_ENG_DEBUG(ENG_DEBUG, "gphone_init_finished %d", gphone_init_finished);
372
373         if (gphone_init_finished != TRUE) {
374                 gphone_init_finished = TRUE;
375
376                 CALL_ENG_DEBUG(ENG_DEBUG, "Query Card Status ..");
377
378                 /*memset(&sim_status, 0, sizeof(sim_status));*/
379                 tapi_err = tel_get_sim_init_info(&sim_status, &sim_changed);
380
381                 if (TAPI_API_SUCCESS != tapi_err) {
382                         CALL_ENG_DEBUG(ENG_DEBUG, "tapi_sim_get_card_type failed.. tapi_err = %d", tapi_err);
383                         pagent->bis_no_sim = TRUE;
384                 } else {
385                         tel_get_sim_type(&card_type);
386                         pagent->card_type = card_type;
387
388                         CALL_ENG_DEBUG(ENG_DEBUG, "card_status = %d, card_type = %d", sim_status, pagent->card_type);
389                         switch (sim_status) {
390                         case TAPI_SIM_STATUS_CARD_NOT_PRESENT:  /* = 0x01, /**<  Card not present */
391                         case TAPI_SIM_STATUS_CARD_REMOVED:      /* =0x0b, /**<  Card removed **/
392                                 pagent->bis_no_sim = TRUE;
393                                 break;
394                         case TAPI_SIM_STATUS_CARD_ERROR:        /* = 0x00, /**< Bad card / On the fly SIM gone bad **/
395                         case TAPI_SIM_STATUS_SIM_INITIALIZING:  /* = 0x02, /**<  Sim is Initializing state **/
396                         case TAPI_SIM_STATUS_SIM_INIT_COMPLETED:        /* = 0x03, /**<  Sim Initialization ok **/
397                         case TAPI_SIM_STATUS_SIM_PIN_REQUIRED:  /* = 0x04, /**<  PIN  required state **/
398                         case TAPI_SIM_STATUS_SIM_PUK_REQUIRED:  /* = 0x05, /**<  PUK required state **/
399                         case TAPI_SIM_STATUS_CARD_BLOCKED:      /* = 0x06,              /**<  PIN/PUK blocked(permanently blocked- All the attempts for PIN/PUK failed) **/
400                         case TAPI_SIM_STATUS_SIM_NCK_REQUIRED:  /* = 0x07,              /**<  Network Control Key required state **/
401                         case TAPI_SIM_STATUS_SIM_NSCK_REQUIRED: /* = 0x08,              /**<  Network Subset Control Key required state **/
402                         case TAPI_SIM_STATUS_SIM_SPCK_REQUIRED: /* = 0x09,              /**<  Service Provider Control Key required state **/
403                         case TAPI_SIM_STATUS_SIM_CCK_REQUIRED:  /* = 0x0a,              /**<  Corporate Control Key required state **/
404                         case TAPI_SIM_STATUS_SIM_LOCK_REQUIRED:
405                                 pagent->bis_no_sim = FALSE;
406                                 break;
407                         default:
408                                 CALL_ENG_DEBUG(ENG_DEBUG, "Unknown Card_status = %d", sim_status);
409                                 pagent->bis_no_sim = TRUE;
410                                 break;
411                         }
412                 }
413         } else {
414                 CALL_ENG_DEBUG(ENG_DEBUG, "gphone_init_finished is TRUE.");
415         }
416
417         /*As a Backup, whenever this event is arrived, just update this variable*/
418         gphone_init_finished = TRUE;
419 }
420
421 static gboolean __call_vc_subscribe_tapi_event(call_vc_callagent_state_t *pcall_agent)
422 {
423         int index = 0;
424
425         TapiResult_t api_err = TAPI_API_SUCCESS;
426         int num_event = 0;
427
428         if (tel_init() == TAPI_API_SUCCESS) {
429                 CALL_ENG_DEBUG(ENG_DEBUG, "tel_init() success.");
430         } else {
431                 CALL_ENG_DEBUG(ENG_DEBUG, "tel_init() failed.");
432                 return FALSE;
433         }
434
435         int call_event_list[] = {
436                 TAPI_EVENT_CALL_SETUP_CNF,
437                 TAPI_EVENT_CALL_ALERT_IND,
438                 TAPI_EVENT_CALL_CONNECTED_IND,
439                 TAPI_EVENT_CALL_INCOM_IND,
440                 TAPI_EVENT_CALL_ANSWER_CNF,
441                 TAPI_EVENT_CALL_RETRIEVE_CNF,
442                 TAPI_EVENT_CALL_RETRIEVE_IND,
443                 TAPI_EVENT_CALL_HOLD_IND,
444                 TAPI_EVENT_CALL_HOLD_CNF,
445                 TAPI_EVENT_CALL_TRANSFER_CNF,
446                 TAPI_EVENT_CALL_TRANSFER_IND,
447                 TAPI_EVENT_CALL_SETUPCONFERENCE_CNF,
448                 TAPI_EVENT_CALL_SETUPCONFERENCE_IND,
449                 TAPI_EVENT_CALL_SPLITCONFERENCE_CNF,
450                 TAPI_EVENT_CALL_SEND_DTMF_CNF,
451                 TAPI_EVENT_CALL_WAITING_IND,
452                 TAPI_EVENT_CALL_FORWARD_IND,
453                 TAPI_EVENT_CALL_RELEASE_CNF,
454                 TAPI_EVENT_CALL_RELEASE_ALL_CNF,
455                 TAPI_EVENT_CALL_RELEASE_ALL_ACTIVE_CNF,
456                 TAPI_EVENT_CALL_RELEASE_ALL_HELD_CNF,
457                 TAPI_EVENT_CALL_END_IND,
458                 TAPI_EVENT_CALL_BARRING_IND,
459                 TAPI_EVENT_CALL_CUGINFO_IND,
460                 TAPI_EVENT_CALL_AOCINFO_IND,
461                 TAPI_EVENT_CALL_CALLINGNAMEINFO_IND,
462                 TAPI_EVENT_CALL_CONNECTEDNUMBERINFO_IND,
463                 TAPI_EVENT_CALL_CLISUPRESSIONREJ_IND,
464                 TAPI_EVENT_CALL_DEFLECTED_IND,
465                 TAPI_EVENT_CALL_UNCOND_FORWARDING_IND,
466                 TAPI_EVENT_CALL_COND_FORWARDING_IND,
467
468                 TAPI_EVENT_SS_AOC_RSP,
469
470                 TAPI_EVENT_SOUND_VOLUMECTRL_RSP,        /*CALL_VC_TAPI_CALL_EVENT_MAX_NUM : 33*/
471         };
472         num_event = sizeof(call_event_list) / sizeof(int);
473         for (index = 0; index < num_event; index++) {
474                 api_err = tel_register_event(call_event_list[index], &pcall_agent->subscription_id[index], (TelAppCallback) & __call_vc_handle_tapi_events, NULL);
475                 if (api_err != TAPI_API_SUCCESS) {
476                         CALL_ENG_DEBUG(ENG_DEBUG, "tel_register_event() failed.. event id:[%d], api_err:[%d]", call_event_list[index], api_err);
477                         return FALSE;
478                 }
479         }
480
481         int ready_event_list[] = {
482                 TAPI_EVENT_POWER_SERVICE_READY_IND,     /*CALL_VC_TAPI_READY_EVENT_NUM 1*/
483         };
484         num_event = sizeof(ready_event_list) / sizeof(int);
485         for (index = 0; index < num_event; index++) {
486                 api_err = tel_register_event(ready_event_list[index], &pcall_agent->subscription_id[index + CALL_VC_TAPI_CALL_EVENT_MAX_NUM], (TelAppCallback) & __call_vc_tapi_initialized_cb, NULL);
487                 if (api_err != TAPI_API_SUCCESS) {
488                         CALL_ENG_DEBUG(ENG_DEBUG, "tel_register_event() failed.. event id:[%d], api_err:[%d]", ready_event_list[index], api_err);
489                         return FALSE;
490                 }
491         }
492
493         int sat_event_list[] = {
494                 TAPI_EVENT_SAT_SETUP_CALL_IND,
495                 TAPI_EVENT_SAT_CALL_CONTROL_IND,
496                 TAPI_EVENT_SAT_SEND_DTMF_IND,   /*CALL_VC_SIMATK_EVENT_MAX_NUM : 3*/
497         };
498         num_event = sizeof(sat_event_list) / sizeof(int);
499         for (index = 0; index < num_event; index++) {
500                 api_err = tel_register_event(sat_event_list[index], &pcall_agent->subscription_id[index + CALL_VC_TAPI_CALL_EVENT_MAX_NUM + CALL_VC_TAPI_READY_EVENT_NUM], (TelAppCallback) & __call_vc_handle_sat_engine_events_cb, NULL);
501                 if (api_err != TAPI_API_SUCCESS) {
502                         CALL_ENG_DEBUG(ENG_DEBUG, "tel_register_event() failed.. event id:[%d], api_err:[%d]", sat_event_list[index], api_err);
503                         return FALSE;
504                 }
505         }
506
507         if (tel_register_app_name("org.tizen.voicecall") != TAPI_API_SUCCESS) {
508                 CALL_ENG_DEBUG(ENG_DEBUG, "tel_register_app_name() failed");
509         }
510
511         gpcall_agent_for_callback = pcall_agent;
512
513         CALL_ENG_DEBUG(ENG_DEBUG, "Subscribe to TAPI Success");
514
515         return TRUE;
516
517 }
518
519 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)
520 {
521         char call_number[VC_PHONE_NUMBER_LENGTH_MAX] = { 0, };
522
523         CALL_ENG_DEBUG(ENG_DEBUG, "call_type=%d", psetup_call_info->call_type);
524
525         _vc_core_cm_clear_call_object(pcall_object);
526
527         /*Initialize following Call Agents state to defaults.*/
528         pagent->bonly_sos_call = FALSE;
529
530         /*Update CallObjects state to Prepare Outgoing*/
531         pcall_object->state = VC_CALL_STATE_PREPARE_OUTGOING;
532
533         /*Update Call|Objects Call Type*/
534         pcall_object->call_type = psetup_call_info->call_type;
535
536         /*Update Call Objects Identity*/
537         pcall_object->identity_mode = psetup_call_info->identity_mode;
538
539         /*Differentiate the call by its source of origination*/
540         switch (pcall_object->call_type) {
541         case VC_CALL_ORIG_TYPE_EMERGENCY:
542                 {
543                         pagent->bonly_sos_call = TRUE;
544                         pcall_object->bemergency_number = TRUE;
545 /*PDIAL_SEND_DTMF*/
546                         _vc_core_util_strcpy(pcall_object->source_tel_number, sizeof(pcall_object->source_tel_number), psetup_call_info->source_tel_number);
547 /*PDIAL_SEND_DTMF*/
548                         _vc_core_util_strcpy(pcall_object->tel_number, sizeof(pcall_object->tel_number), psetup_call_info->tel_number);
549                         return TRUE;
550                 }
551                 break;
552         case VC_CALL_ORIG_TYPE_PINLOCK:
553                 {
554                         CALL_ENG_DEBUG(ENG_DEBUG, "PIN LOCK!!!!");
555                         pagent->bonly_sos_call = TRUE;
556 /*PDIAL_SEND_DTMF*/
557                         _vc_core_util_strcpy(pcall_object->source_tel_number, sizeof(pcall_object->source_tel_number), psetup_call_info->source_tel_number);
558 /*PDIAL_SEND_DTMF*/
559                         _vc_core_util_strcpy(pcall_object->tel_number, sizeof(pcall_object->tel_number), psetup_call_info->tel_number);
560                 }
561                 break;
562         case VC_CALL_ORIG_TYPE_NOSIM:   /*no sim (pagent->bis_no_sim == TRUE)*/
563                 {
564                         pagent->bonly_sos_call = TRUE;
565 /*PDIAL_SEND_DTMF*/
566                         _vc_core_util_strcpy(pcall_object->source_tel_number, sizeof(pcall_object->source_tel_number), psetup_call_info->source_tel_number);
567 /*PDIAL_SEND_DTMF*/
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_NORMAL:
572         case VC_CALL_ORIG_TYPE_SAT:
573                 {
574 /*PDIAL_SEND_DTMF*/
575                         _vc_core_util_strcpy(pcall_object->source_tel_number, sizeof(pcall_object->source_tel_number), psetup_call_info->source_tel_number);
576 /*PDIAL_SEND_DTMF*/
577                         _vc_core_util_strcpy(pcall_object->tel_number, sizeof(pcall_object->tel_number), psetup_call_info->tel_number);
578                 }
579                 break;
580         case VC_CALL_ORIG_TYPE_VOICEMAIL:
581                 {
582 /*PDIAL_SEND_DTMF*/
583                         _vc_core_util_strcpy(pcall_object->source_tel_number, sizeof(pcall_object->source_tel_number), psetup_call_info->source_tel_number);
584 /*PDIAL_SEND_DTMF*/
585                         _vc_core_util_strcpy(pcall_object->tel_number, sizeof(pcall_object->tel_number), psetup_call_info->tel_number);
586                 }
587                 break;
588         default:
589                 CALL_ENG_DEBUG(ENG_DEBUG, "Invalide Call Type: %d", pcall_object->call_type);
590                 *error_code = ERROR_VOICECALL_INVALID_CALL_TYPE;
591                 return FALSE;
592         }
593
594         /*Copy CUG Details */
595         memcpy(&pcall_object->cug_info, &psetup_call_info->cug_info, sizeof(voicecall_cug_info_t));
596
597         /*Check for Emergency Number */
598         _vc_core_util_extract_call_number(pcall_object->tel_number, call_number, sizeof(call_number));
599         pcall_object->bemergency_number = _vc_core_util_check_emergency_number(pagent->card_type, call_number, pagent->bis_no_sim, &pcall_object->ecc_category);
600
601         CALL_ENG_DEBUG(ENG_DEBUG, "no_sim=%d, emergency_number=%d", pagent->bis_no_sim, pcall_object->bemergency_number);
602
603         if (VC_CALL_ORIG_TYPE_PINLOCK == pcall_object->call_type && pcall_object->bemergency_number == FALSE) {
604                 CALL_ENG_DEBUG(ENG_DEBUG, "PIN/PUK Lock and number is no emergency number, call cannot be made");
605                 *error_code = ERROR_VOICECALL_EMERGENCY_CALLS_ONLY;
606                 return FALSE;
607         }
608
609         if (pagent->bis_no_sim == TRUE && pcall_object->bemergency_number == FALSE) {
610                 CALL_ENG_DEBUG(ENG_DEBUG, "Sim Not available and number is no emergency number, call cannot be made");
611                 *error_code = ERROR_VOICECALL_CALL_IMPOSSIBLE_NOSIM_NOEMERGNUM;
612                 return FALSE;
613         }
614
615         if (TRUE == pcall_object->bemergency_number) {
616                 CALL_ENG_DEBUG(ENG_DEBUG, "Number is Emergency Number, Change call type to emergency");
617                 psetup_call_info->call_type = pcall_object->call_type = VC_CALL_ORIG_TYPE_EMERGENCY;
618                 psetup_call_info->ecc_category = pcall_object->ecc_category;
619         }
620
621         return TRUE;
622 }
623
624 static gboolean __call_vc_request_sat_call(call_vc_callagent_state_t *pagent, int mo_call_index, int *ret_code)
625 {
626         call_vc_call_objectinfo_t callInfo;
627         TelSatCmdQualiSetupCall_t sat_request_type = 0;
628
629         CALL_ENG_DEBUG(ENG_DEBUG, "mo_call_index = %d", mo_call_index);
630
631         VOICECALL_RETURN_FALSE_IF_FAIL(pagent->call_manager.setupcall_info.mocall_index == mo_call_index);
632
633         if (FALSE == _vc_core_cm_get_outgoing_call_info(&pagent->call_manager, &callInfo)) {
634                 CALL_ENG_DEBUG(ENG_DEBUG, "Outgoing call info does not exist!");
635                 *ret_code = ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
636                 return FALSE;
637         }
638
639         sat_request_type = pagent->call_manager.setupcall_info.satcall_setup_info.satengine_setupcall_data.calltype;
640
641         CALL_ENG_DEBUG(ENG_DEBUG, " SAT_CALL sat_request_type=%d", sat_request_type);
642
643         switch (sat_request_type) {
644         case TAPI_SAT_SETUP_CALL_IF_ANOTHER_CALL_NOT_BUSY_WITH_REDIAL:
645                 {
646                         pagent->call_manager.setupcall_info.satcall_setup_info.redial = TRUE;
647                 }
648         case TAPI_SAT_SETUP_CALL_IF_ANOTHER_CALL_NOT_BUSY:      /*Fall Through*/
649                 {
650                         /* one is the call set up by SAT, so more than 1 means another call exists */
651                         if (_vc_core_cm_get_call_member_count(&pagent->call_manager) > 1) {
652                                 /* voice call agent is busy */
653                                 CALL_ENG_DEBUG(ENG_DEBUG, "Call Exists, SAT call connot be continued");
654                                 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND);
655                                 _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
656                                 *ret_code = ERROR_VOICECALL_CALL_NOT_ALLOWED;
657                                 return FALSE;
658                         }
659
660                         _vc_core_cm_set_outgoing_call_info(&pagent->call_manager, &callInfo);
661
662                         if (_vc_core_tapi_rqst_prepare_setup_call(pagent) == FALSE) {
663                                 CALL_ENG_DEBUG(ENG_DEBUG, "SAT_CALL fail to setup call");
664                                 _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
665                                 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND);
666                                 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_OUTGOING_ABORTED);
667                                 *ret_code = ERROR_VOICECALL_TAPI_CAUSE_CALL_FAILED;
668                                 return FALSE;
669                         } else {
670                                 CALL_ENG_DEBUG(ENG_DEBUG, "Prepare Setup Call Success");
671                         }
672                 }
673                 break;
674         case TAPI_SAT_SETUP_CALL_PUT_ALL_OTHER_CALLS_ON_HOLD_WITH_REDIAL:
675                 {
676                         pagent->call_manager.setupcall_info.satcall_setup_info.redial = TRUE;
677                 }
678         case TAPI_SAT_SETUP_CALL_PUT_ALL_OTHER_CALLS_ON_HOLD:   /*Fall Through*/
679                 {
680                         if (_vc_core_cm_isexists_active_call(&pagent->call_manager) && _vc_core_cm_isexists_held_call(&pagent->call_manager)) {
681                                 CALL_ENG_DEBUG(ENG_DEBUG, "Both Activee & Hld call exists, SAT Call cannot be continued");
682                                 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND);
683                                 _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
684                                 *ret_code = ERROR_VOICECALL_CALL_NOT_ALLOWED;
685                                 return FALSE;
686                         }
687                         if (_vc_core_cm_isexists_connected_call(&pagent->call_manager)) {
688                                 if (FALSE == _vc_core_tapi_rqst_prepare_setup_call(pagent)) {
689                                         CALL_ENG_DEBUG(ENG_DEBUG, "SAT_CALL hold fail");
690                                         _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND);
691                                         _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
692                                         _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_OUTGOING_ABORTED);
693                                         *ret_code = ERROR_VOICECALL_TAPI_CAUSE_CALL_FAILED;
694                                         return FALSE;
695                                 }
696                         } else {
697                                 /*If no other calls to hold, setup the call directly */
698                                 if (FALSE == _vc_core_tapi_rqst_setup_call(pagent)) {
699                                         CALL_ENG_DEBUG(ENG_DEBUG, "SAT_CALL fail to setup call");
700                                         _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
701                                         _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND);
702                                         _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_OUTGOING_ABORTED);
703                                         *ret_code = ERROR_VOICECALL_TAPI_CAUSE_CALL_FAILED;
704                                         return FALSE;
705                                 }
706                         }
707                 }
708                 break;
709         case TAPI_SAT_SETUP_CALL_DISCONN_ALL_OTHER_CALLS_WITH_REDIAL:
710                 {
711                         pagent->call_manager.setupcall_info.satcall_setup_info.redial = TRUE;
712                 }
713         case TAPI_SAT_SETUP_CALL_DISCONN_ALL_OTHER_CALLS:       /*Fall Through*/
714                 {
715                         if (_vc_core_cm_isexists_active_call(&pagent->call_manager) || _vc_core_cm_isexists_held_call(&pagent->call_manager)) {
716                                 /*Disconnect all calls and setup call */
717                                 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_RELEASE_ALL_CALLS_TO_SETUP);
718                                 _vc_core_tapi_rqst_release_all_calls(pagent);
719                         } else {
720                                 if (FALSE == _vc_core_tapi_rqst_prepare_setup_call(pagent)) {
721                                         CALL_ENG_DEBUG(ENG_DEBUG, "SAT_CALL fail to setup call");
722                                         _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
723                                         _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND);
724                                         _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_OUTGOING_ABORTED);
725                                         *ret_code = ERROR_VOICECALL_TAPI_CAUSE_CALL_FAILED;
726                                         return FALSE;
727                                 }
728                         }
729                 }
730                 break;
731         default:
732                 CALL_ENG_DEBUG(ENG_DEBUG, "Action not defined for this SAT Request Type");
733                 return FALSE;
734         }
735
736         return TRUE;
737 }
738
739 static gboolean __call_vc_request_call(call_vc_callagent_state_t *pagent, int mo_call_index, int *ret_code)
740 {
741         call_vc_call_objectinfo_t callInfo;
742
743         CALL_ENG_DEBUG(ENG_DEBUG, "");
744
745         VOICECALL_RETURN_FALSE_IF_FAIL(pagent->call_manager.setupcall_info.mocall_index == mo_call_index);
746
747         _vc_core_cm_clear_call_object(&callInfo);
748         if (_vc_core_cm_get_outgoing_call_info(&pagent->call_manager, &callInfo) == FALSE) {
749                 CALL_ENG_DEBUG(ENG_DEBUG, "Outgoing call info does not exist!");
750                 *ret_code = ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
751                 return FALSE;
752         }
753         /*Switch according to the CallType requested*/
754         switch (callInfo.call_type) {
755         case VC_CALL_ORIG_TYPE_NORMAL:
756         case VC_CALL_ORIG_TYPE_EMERGENCY:
757         case VC_CALL_ORIG_TYPE_NOSIM:
758         case VC_CALL_ORIG_TYPE_SAT:
759         case VC_CALL_ORIG_TYPE_PINLOCK:
760
761                 /*Set the updated Object Info to the Call Manager*/
762                 _vc_core_cm_set_outgoing_call_info(&pagent->call_manager, &callInfo);
763
764                 if (_vc_core_tapi_rqst_prepare_setup_call(pagent) == FALSE) {
765                         _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
766                         _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_OUTGOING_ABORTED);
767                         *ret_code = ERROR_VOICECALL_TAPI_CAUSE_CALL_FAILED;
768                         CALL_ENG_DEBUG(ENG_DEBUG, "Prepare Setup Call Failed");
769
770                         return FALSE;
771                 } else {
772                         CALL_ENG_DEBUG(ENG_DEBUG, "Prepare Setup Call Success");
773                 }
774
775                 break;
776         default:
777                 *ret_code = ERROR_VOICECALL_INVALID_CALL_TYPE;
778                 CALL_ENG_DEBUG(ENG_DEBUG, "Not defined call type=%d", pagent->call_manager.setupcall_info.call_type);
779                 return FALSE;
780                 break;
781         }
782
783         return TRUE;
784 }
785
786 /**
787 * This function prepares the call setup info structure for making call
788  *
789 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
790 * @param[in]    pvoicecall_agent    Handle to voicecall engine
791 * @param[in]    psetup_call_info        Pointer to the call setup info structure.
792 * @remarks              pvoicecall_agent and psetup_call_info cannot be NULL
793 *                               Only on successfull completion of this API, _vc_core_engine_make_call can be made
794 * @see                  See following API's also
795 *                               -_vc_core_engine_make_call
796 *                               -voicecall_clear_prepared_call
797 *
798  */
799 voicecall_error_t _vc_core_engine_prepare_call(voicecall_engine_t *pvoicecall_agent, voicecall_setup_info_t *psetup_call_info)
800 {
801         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
802         call_vc_call_objectinfo_t callobject_info;
803         TapiResult_t tapi_err = TAPI_API_SUCCESS;
804         TelSimCardStatus_t sim_status;
805         TelSimCardType_t card_type = 0;
806         int sim_changed = 0;
807         gboolean status = FALSE;
808         int nIndex = 0;
809         int error_code = 0;
810
811         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
812         VOICECALL_RETURN_VALUE_IF_FAIL(psetup_call_info != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
813
814         CALL_ENG_DEBUG(ENG_DEBUG, "");
815
816         if (FALSE == _vc_core_util_isvalid_telephone_number(psetup_call_info->tel_number)) {
817                 return ERROR_VOICECALL_INVALID_TELEPHONE_NUMBER;
818         }
819
820         CALL_ENG_KPI("tel_check_service_ready start");
821         tapi_err = tel_check_service_ready(&status);
822         CALL_ENG_KPI("tel_check_service_ready done");
823         if (TAPI_API_SUCCESS != tapi_err || FALSE == status) {
824                 CALL_ENG_DEBUG(ENG_DEBUG, "Tapi not initialized");
825                 return ERROR_VOICECALL_PHONE_NOT_INITIALIZED;
826         }
827         /*Check the Call Engines IO State*/
828         if (pagent->io_state != VC_INOUT_STATE_NONE && pagent->io_state != VC_INOUT_STATE_OUTGOING_SHOW_RETRY_CALLBOX) {
829                 CALL_ENG_DEBUG(ENG_DEBUG, "pagent->io_state != VC_INOUT_STATE_NONE..io_state=%d", pagent->io_state);
830                 return ERROR_VOICECALL_ENGINE_STATE_NOT_NONE;
831         }
832
833         CALL_ENG_DEBUG(ENG_DEBUG, "Checking for SIM Availablity");
834
835         /*memset(&sim_status, 0, sizeof(sim_status));*/
836         CALL_ENG_KPI("tel_get_sim_init_info start");
837         tapi_err = tel_get_sim_init_info(&sim_status, &sim_changed);
838         CALL_ENG_KPI("tel_get_sim_init_info done");
839
840         if (TAPI_API_SUCCESS != tapi_err) {
841                 CALL_ENG_DEBUG(ENG_DEBUG, "tel_get_sim_init_info failed.. tapi_err = %d", tapi_err);
842
843                 pagent->bis_no_sim = TRUE;
844                 psetup_call_info->call_type = VC_CALL_ORIG_TYPE_NOSIM;
845         } else {
846                 CALL_ENG_KPI("tel_get_sim_type start");
847                 tel_get_sim_type(&card_type);
848                 CALL_ENG_KPI("tel_get_sim_type done");
849                 pagent->card_type = card_type;
850
851                 CALL_ENG_DEBUG(ENG_DEBUG, "card_status = %d, card_type = %d", sim_status, pagent->card_type);
852                 switch (sim_status) {
853                 case TAPI_SIM_STATUS_CARD_NOT_PRESENT:  /* = 0x01, /**<  Card not present **/
854                 case TAPI_SIM_STATUS_CARD_REMOVED:      /* =0x0b, /**<  Card removed **/
855                         pagent->bis_no_sim = TRUE;
856                         break;
857                 case TAPI_SIM_STATUS_CARD_ERROR:        /* = 0x00, /**< Bad card / On the fly SIM gone bad **/
858                 case TAPI_SIM_STATUS_SIM_INITIALIZING:  /* = 0x02, /**<  Sim is Initializing state **/
859                 case TAPI_SIM_STATUS_SIM_INIT_COMPLETED:        /* = 0x03, /**<  Sim Initialization ok **/
860                 case TAPI_SIM_STATUS_SIM_PIN_REQUIRED:  /* = 0x04, /**<  PIN  required state **/
861                 case TAPI_SIM_STATUS_SIM_PUK_REQUIRED:  /* = 0x05, /**<  PUK required state **/
862                 case TAPI_SIM_STATUS_CARD_BLOCKED:      /* = 0x06,              /**<  PIN/PUK blocked(permanently blocked- All the attempts for PIN/PUK failed) **/
863                 case TAPI_SIM_STATUS_SIM_NCK_REQUIRED:  /* = 0x07,              /**<  Network Control Key required state **/
864                 case TAPI_SIM_STATUS_SIM_NSCK_REQUIRED: /* = 0x08,              /**<  Network Subset Control Key required state **/
865                 case TAPI_SIM_STATUS_SIM_SPCK_REQUIRED: /* = 0x09,              /**<  Service Provider Control Key required state **/
866                 case TAPI_SIM_STATUS_SIM_CCK_REQUIRED:  /* = 0x0a,              /**<  Corporate Control Key required state **/
867                 case TAPI_SIM_STATUS_SIM_LOCK_REQUIRED:
868                         pagent->bis_no_sim = FALSE;
869                         break;
870                 default:
871                         CALL_ENG_DEBUG(ENG_DEBUG, "Unknown Card_status = %d", sim_status);
872                         pagent->bis_no_sim = TRUE;
873                         break;
874                 }
875         }
876
877         /*Prepare Outgoing Call Info*/
878         _vc_core_cm_clear_call_object(&callobject_info);
879         if (__call_vc_create_outgoing_callinfo(pagent, psetup_call_info, &callobject_info, &error_code) == FALSE) {
880                 return error_code;
881         }
882
883         /* Check for MO Call Possiblity */
884         if (_vc_core_ca_is_mocall_possible(pagent, callobject_info.bemergency_number) == FALSE) {
885                 return ERROR_VOICECALL_CALL_NOT_ALLOWED;
886         }
887
888         /* Add the prepared call object to the CallManager */
889         nIndex = _vc_core_cm_add_call_object(&pagent->call_manager, &callobject_info);
890         if (nIndex != -1) {
891                 /*If there is a previously made MO Call, clear that before setting the new mo call */
892                 _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
893                 _vc_core_cm_set_outgoing_call(&pagent->call_manager, nIndex);
894                 psetup_call_info->mo_call_index = nIndex;
895         } else {
896                 return ERROR_VOICECALL_CALL_NOT_ALLOWED;
897         }
898
899         return ERROR_VOICECALL_NONE;
900 }
901
902 /**
903 * This function clears the data of the given call type.
904 *
905 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
906 * @param[in]    pvoicecall_agent        Handle to voicecall engine
907 * @param[in]    call_type               call type
908 * @param[in]    call_handle             Call handle of the connected call to be cleared
909 * @remarks              This will clear the call data only when the call data are currently not being used
910 *                               i,e) the data will be cleared only if the corresponding call is ended or the call data is not used at all.
911 *                               call_handle argument is required only in case of connected call, Engine ignores call_handle for other
912 *                               call types.
913 */
914 voicecall_error_t _vc_core_engine_finalize_call(voicecall_engine_t *pvoicecall_agent, voicecall_call_type_t call_type, int call_handle)
915 {
916         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
917         gboolean bret_val = FALSE;
918
919         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
920
921         CALL_ENG_DEBUG(ENG_DEBUG, "call_type = %d", call_type);
922
923         switch (call_type) {
924         case VC_OUTGOING_CALL:
925                 {
926                         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)) {
927                                 return ERROR_VOICECALL_CALL_IS_IN_PROGRESS;
928                         }
929
930                         bret_val = _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
931                 }
932                 break;
933         case VC_CONNECTED_CALL:
934                 {
935                         call_vc_call_objectinfo_t call_object;
936
937                         if (TRUE == _vc_core_cm_get_call_object(&pagent->call_manager, call_handle, &call_object)) {
938                                 if (VC_CALL_STATE_ENDED == call_object.state) {
939                                         bret_val = _vc_core_ca_clear_connected_call(pagent, call_handle);
940                                 } else {
941                                         return ERROR_VOICECALL_CALL_IS_IN_PROGRESS;
942                                 }
943                         }
944                 }
945                 break;
946         case VC_INCOMING_CALL:
947                 {
948                         return ERROR_VOICECALL_NOT_SUPPORTED;
949                 }
950                 break;
951         default:
952                 return ERROR_VOICECALL_INVALID_CALL_TYPE;
953         }
954
955         return (TRUE == bret_val) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
956 }
957
958 /**
959 * This function establishes an outgoing call with the details prepared using _vc_core_engine_prepare_call
960 *
961 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
962 * @param[in]    pvoicecall_agent    Handle to voicecall engine
963 * @param[in]    mo_call_index           Index of the prepare mo call
964 * @param[out]   pcall_handle            Handle of the MO Call Made
965 * @remarks              pvoicecall_agent and pcall_handle cannot be NULL
966 * @see                  _vc_core_engine_end_call
967 */
968 voicecall_error_t _vc_core_engine_make_call(voicecall_engine_t *pvoicecall_agent, int mo_call_index, int *pcall_handle)
969 {
970         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
971         gboolean ret_val = FALSE;
972         call_vc_call_objectinfo_t call_object;
973         int error_code = ERROR_VOICECALL_NONE;
974
975         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
976         VOICECALL_RETURN_VALUE_IF_FAIL(mo_call_index >= 0 && mo_call_index <= 7, ERROR_VOICECALL_INVALID_ARGUMENTS);
977         VOICECALL_RETURN_VALUE_IF_FAIL(pcall_handle != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
978
979         CALL_ENG_DEBUG(ENG_DEBUG, "...");
980
981         _vc_core_cm_clear_call_object(&call_object);
982         if (_vc_core_cm_get_outgoing_call_info(&pagent->call_manager, &call_object) == FALSE) {
983                 CALL_ENG_DEBUG(ENG_DEBUG, "Outgoing call info does not exist!");
984                 return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
985         }
986
987         if (VC_CALL_ORIG_TYPE_SAT == call_object.call_type) {
988                 ret_val = __call_vc_request_sat_call(pagent, mo_call_index, &error_code);
989         } else {
990                 ret_val = __call_vc_request_call(pagent, mo_call_index, &error_code);
991         }
992
993         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)) {
994                 *pcall_handle = _vc_core_cm_get_outgoing_call_handle(&pagent->call_manager);
995                 CALL_ENG_DEBUG(ENG_DEBUG, "Outgoing call Handle: %d", *pcall_handle);
996
997         }
998
999         return (TRUE == ret_val) ? ERROR_VOICECALL_NONE : error_code;
1000 }
1001
1002 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)
1003 {
1004         call_vc_callagent_state_t *pagent = pcall_agent;
1005         call_vc_satsetup_info_t *psatsetup_info = NULL;
1006         voicecall_sat_callinfo_t call_vc_sat_callinfo;
1007
1008         VOICECALL_RETURN_FALSE_IF_FAIL(pcall_agent != NULL);
1009
1010         CALL_ENG_DEBUG(ENG_DEBUG, "sat_event: %d, sat_event_type: %d, command_type: %d", sat_event, sat_event_type, type);
1011
1012         psatsetup_info = (call_vc_satsetup_info_t *) &(pagent->call_manager.setupcall_info.satcall_setup_info);
1013
1014         switch (sat_event) {
1015         case VC_ACTION_SAT_REQUEST:
1016                 {
1017                         switch (sat_event_type) {
1018                         case SAT_RQST_SETUP_CALL:
1019                                 {
1020                                         CALL_ENG_DEBUG(ENG_DEBUG, "SAT_RQST_SETUP_CALL SAT Event is recieved...");
1021
1022                                         if ((pagent->io_state != VC_INOUT_STATE_NONE) || (pagent->callagent_state != CALL_VC_CA_STATE_NORMAL)) {
1023                                                 CALL_ENG_DEBUG(ENG_DEBUG, "SAT_CALL unable to process command!");
1024                                                 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND);
1025                                                 return FALSE;
1026                                         }
1027
1028                                         /*Initialize Call Setup Data */
1029                                         psatsetup_info->psat_rgb_data = NULL;
1030                                         memset(&(psatsetup_info->satengine_setupcall_data), 0, sizeof(TelSatSetupCallIndCallData_t));
1031                                         memcpy(&(psatsetup_info->satengine_setupcall_data), result, sizeof(TelSatSetupCallIndCallData_t));
1032                                         psatsetup_info->satengine_event_type = type;
1033                                         memset(&call_vc_sat_callinfo, 0, sizeof(voicecall_sat_callinfo_t));
1034
1035                                         _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);
1036                                         _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);
1037                                         call_vc_sat_callinfo.duration = psatsetup_info->satengine_setupcall_data.duration;
1038                                         if (call_vc_sat_callinfo.duration > 0) {
1039                                                 psatsetup_info->bduration = TRUE;
1040
1041                                                 /*Store the duration, this remaining duration will be reduced in subsequent redial attempts */
1042                                                 psatsetup_info->remaining_duration = call_vc_sat_callinfo.duration;
1043                                         }
1044                                         CALL_ENG_DEBUG(ENG_DEBUG, "Voice call set up request sent to voice call application psatsetup_info->bduration = %d", psatsetup_info->bduration);
1045                                         CALL_ENG_DEBUG(ENG_DEBUG, "psatsetup_info->remaining_duration = %lu", psatsetup_info->remaining_duration);
1046                                         CALL_ENG_DEBUG(ENG_DEBUG, "sat call type = %d", psatsetup_info->satengine_setupcall_data.calltype);
1047
1048                                         _vc_core_ca_send_event_to_client(pagent, VC_ACTION_SAT_REQUEST, SAT_RQST_SETUP_CALL, 0, &call_vc_sat_callinfo);
1049                                 }
1050                                 break;
1051                         case SAT_RQST_SEND_DTMF:
1052                                 {
1053                                         memset(&(psatsetup_info->satengine_dtmf_data), 0, sizeof(TelSatSendDtmfIndDtmfData_t));
1054                                         memcpy(&(psatsetup_info->satengine_dtmf_data), result, sizeof(TelSatSendDtmfIndDtmfData_t));
1055                                         psatsetup_info->satengine_event_type = type;
1056
1057                                         if (FALSE == __vc_core_is_dtmf_possible(pagent)) {
1058                                                 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SEND_DTMF, CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND);
1059                                         } else {
1060                                                 memset(&call_vc_sat_callinfo, 0, sizeof(voicecall_sat_callinfo_t));
1061
1062                                                 _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);
1063                                                 call_vc_sat_callinfo.bsat_hidden = psatsetup_info->satengine_dtmf_data.bIsHiddenMode;
1064                                                 _vc_core_ca_send_event_to_client(pagent, VC_ACTION_SAT_REQUEST, SAT_RQST_SEND_DTMF, 0, &call_vc_sat_callinfo);
1065                                         }
1066                                 }
1067                                 break;
1068                         }
1069                 }
1070                 break;
1071         case VC_ACTION_SAT_RESPONSE:
1072                 {
1073                         call_vc_call_objectinfo_t objectInfo;
1074                         switch (sat_event_type) {
1075                         case SAT_RESP_SETUP_CALL:
1076                                 {
1077                                         if (_vc_core_cm_get_outgoing_call_info(&pagent->call_manager, &objectInfo) == FALSE) {
1078                                                 CALL_ENG_DEBUG(ENG_DEBUG, "SAT_CALL_CONTROL Outgoing call info does not exist..");
1079                                                 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_NONE);
1080                                                 break;
1081                                         }
1082                                         memset(&(psatsetup_info->satengine_callctrl_data), 0, sizeof(psatsetup_info->satengine_callctrl_data));
1083                                         memcpy(&(psatsetup_info->satengine_callctrl_data), result, sizeof(psatsetup_info->satengine_callctrl_data));
1084
1085                                         switch (psatsetup_info->satengine_callctrl_data.callCtrlResult) {
1086                                         case TAPI_SAT_CALL_CTRL_R_ALLOWED_NO_MOD:
1087                                                 {
1088                                                         CALL_ENG_DEBUG(ENG_DEBUG, "ret=TAPI_SAT_CALL_CTRL_R_ALLOWED_NO_MOD");
1089                                                         pagent->call_manager.setupcall_info.call_control_type = CALL_VC_SAT_CC_ALLOWED;
1090                                                 }
1091                                                 break;
1092                                         case TAPI_SAT_CALL_CTRL_R_NOT_ALLOWED:
1093                                                 {
1094                                                         CALL_ENG_DEBUG(ENG_DEBUG, "ret=TAPI_SAT_CALL_CTRL_R_NOT_ALLOWED");
1095                                                         pagent->call_manager.setupcall_info.call_control_type = CALL_VC_SAT_CC_NOT_ALLOWED;
1096                                                         _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_NONE);
1097
1098                                                         if (objectInfo.call_type == VC_CALL_ORIG_TYPE_SAT) {
1099                                                                 _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
1100                                                                 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_CONTROL_PERMANENT_PROBLEM);
1101                                                         } else {
1102                                                                 _vc_core_cm_clear_outgoing_call(&pagent->call_manager);
1103                                                         }
1104
1105                                                         memset(&call_vc_sat_callinfo, 0, sizeof(voicecall_sat_callinfo_t));
1106                                                         call_vc_sat_callinfo.sat_mo_call_ctrl_res = CALL_NOT_ALLOWED;
1107                                                         _vc_core_ca_send_event_to_client(pagent, VC_ACTION_SAT_RESPONSE, SAT_RESP_SETUP_CALL, 0, &call_vc_sat_callinfo);
1108                                                 }
1109                                                 break;
1110                                         case TAPI_SAT_CALL_CTRL_R_ALLOWED_WITH_MOD:
1111                                                 {
1112                                                         gboolean bsscode = FALSE;
1113
1114                                                         CALL_ENG_DEBUG(ENG_DEBUG, "ret=TAPI_SAT_CALL_CTRL_R_ALLOWED_WITH_MOD");
1115                                                         pagent->call_manager.setupcall_info.call_control_type = CALL_VC_SAT_CC_ALLOWED_WITH_MODIFIED;
1116
1117                                                         memset(objectInfo.connected_telnumber, 0, sizeof(objectInfo.connected_telnumber));
1118                                                         memset(objectInfo.connected_name, 0, sizeof(objectInfo.connected_name));
1119
1120                                                         _vc_core_util_strcpy(objectInfo.connected_telnumber, sizeof(objectInfo.connected_telnumber), (char *)psatsetup_info->satengine_callctrl_data.u.callCtrlCnfCallData.address.string);
1121                                                         _vc_core_util_strcpy(objectInfo.connected_name, sizeof(objectInfo.connected_name), (char *)psatsetup_info->satengine_callctrl_data.dispData.string);
1122
1123                                                         /*Prepare the data to be sent to the client */
1124                                                         memset(&call_vc_sat_callinfo, 0, sizeof(voicecall_sat_callinfo_t));
1125                                                         _vc_core_util_strcpy(call_vc_sat_callinfo.call_number, sizeof(call_vc_sat_callinfo.call_number), objectInfo.connected_telnumber);
1126                                                         _vc_core_util_strcpy(call_vc_sat_callinfo.disp_text, sizeof(call_vc_sat_callinfo.disp_text), objectInfo.connected_name);
1127
1128                                                         /* when call number is changed as SS string */
1129                                                         _vc_core_engine_status_isvalid_ss_code((voicecall_engine_t *)pcall_agent, objectInfo.connected_telnumber, &bsscode);
1130                                                         if (TRUE == bsscode) {
1131                                                                 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_NONE);
1132
1133                                                                 call_vc_sat_callinfo.sat_mo_call_ctrl_res = CALL_CHANGED_TO_SS;
1134                                                                 CALL_ENG_DEBUG(ENG_DEBUG, "VC Call Control Response Event: %d", call_vc_sat_callinfo.sat_mo_call_ctrl_res);
1135                                                         } else {
1136                                                                 objectInfo.bemergency_number = _vc_core_util_check_emergency_number(pagent->card_type, objectInfo.connected_telnumber, pagent->bis_no_sim, &objectInfo.ecc_category);
1137                                                                 _vc_core_cm_set_outgoing_call_info(&pagent->call_manager, &objectInfo);
1138
1139                                                                 call_vc_sat_callinfo.duration = psatsetup_info->satengine_setupcall_data.duration;
1140                                                                 call_vc_sat_callinfo.sat_mo_call_ctrl_res = CALL_ALLOWED_WITH_MOD;
1141                                                                 CALL_ENG_DEBUG(ENG_DEBUG, "VC Call Control Response Event: %d", call_vc_sat_callinfo.sat_mo_call_ctrl_res);
1142                                                         }
1143
1144                                                         /*Send the Call Control response event to the client */
1145                                                         _vc_core_ca_send_event_to_client(pagent, VC_ACTION_SAT_RESPONSE, SAT_RESP_SETUP_CALL, 0, &call_vc_sat_callinfo);
1146                                                 }
1147                                                 break;
1148                                         default:
1149                                                 CALL_ENG_DEBUG(ENG_DEBUG, "SAT_CALL_CONTROL - not defined return code");
1150                                                 break;
1151                                         }
1152                                 }
1153                                 break;
1154                         default:
1155                                 CALL_ENG_DEBUG(ENG_DEBUG, "Invalid Sat Event Type");
1156                                 break;
1157                         }
1158                 }
1159                 break;
1160         default:
1161                 CALL_ENG_DEBUG(ENG_DEBUG, "Invalid SAT Event");
1162                 return FALSE;
1163         }
1164         return TRUE;
1165 }
1166
1167 static gboolean __call_vc_incoming_idle_cb(gpointer puser_data)
1168 {
1169         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)puser_data;
1170         call_vc_call_objectinfo_t callobject_info;
1171
1172         CALL_ENG_DEBUG(ENG_DEBUG, "Handling Incoming call in Idle Callback");
1173
1174         if (FALSE == _vc_core_cm_get_incoming_call_info(&pagent->call_manager, &callobject_info)) {
1175                 CALL_ENG_DEBUG(ENG_ERR, "Incoming Call Info not available");
1176                 return FALSE;
1177         }
1178
1179         /*If the Incoming End event arrived before processing the Incoming request, then donot change the state to Incombox */
1180         if (pagent->io_state != VC_INOUT_STATE_INCOME_END) {
1181                 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_INCOME_BOX);
1182         }
1183
1184         /* Send Incoming Call Event to Client */
1185         /*_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);*/
1186         _vc_core_ca_send_event_to_client(pagent, VC_CALL_INCOM, callobject_info.call_handle, 0, callobject_info.tel_number);
1187
1188         /* Reset Incoming Call Details */
1189         gincoming_call_handle = VC_TAPI_INVALID_CALLHANDLE;
1190         memset(&gincoming_call_info, 0, sizeof(TelCallIncomingCallInfo_t));
1191
1192         /*Check whether the incoming call is accepted or rejected by
1193            cheking the Incoming callobjects status */
1194         if (_vc_core_cm_get_call_state(&pagent->call_manager, callobject_info.call_handle) != VC_CALL_STATE_INCOME) {
1195                 CALL_ENG_DEBUG(ENG_DEBUG, "[Call :%d] not in VC_CALL_STATE_INCOME state", callobject_info.call_handle);
1196                 return FALSE;
1197         }
1198
1199         /*Always Return FALSE from this g_idle callback, so it will not be called again */
1200         return FALSE;
1201 }
1202
1203 /*Rejects the call, only if the call state is in rejected state*/
1204 static gboolean __call_vc_reject_call_full_idle_cb(gpointer puser_data)
1205 {
1206         call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)puser_data;
1207         TapiResult_t tapi_err = TAPI_API_SUCCESS;
1208         int pReqId = VC_RQSTID_DEFAULT;
1209         call_vc_call_objectinfo_t call_object;
1210
1211         CALL_ENG_DEBUG(ENG_DEBUG, "Rejecting the [Call:%d] in IDLE CB", gincoming_call_handle);
1212
1213         if (gincoming_call_handle != -1) {
1214                 _vc_core_cm_get_call_object(&pcall_agent->call_manager, gincoming_call_handle, &call_object);
1215
1216                 if (VC_CALL_STATE_REJECTED == call_object.state) {
1217                         /*Answer the incoming call by accepting or rejecting the call */
1218                         tapi_err = tel_answer_call(gincoming_call_handle, TAPI_CALL_ANSWER_REJECT, &pReqId);
1219                         if (TAPI_API_SUCCESS != tapi_err) {
1220                                 CALL_ENG_DEBUG(ENG_ERR, "tel_answer_call failed, Error: %d", tapi_err);
1221                         }
1222
1223                         gincoming_call_handle = -1;
1224                 }
1225         }
1226         return FALSE;
1227 }
1228
1229 /*Always reject the call, if the reject call handle is valid*/
1230 static gboolean __call_vc_reject_call_idle_cb(gpointer puser_data)
1231 {
1232         TapiResult_t tapi_err = TAPI_API_SUCCESS;
1233         int pReqId = VC_RQSTID_DEFAULT;
1234
1235         CALL_ENG_DEBUG(ENG_DEBUG, "Rejecting the [Call Handle :%d] in IDLE CB", gincoming_call_handle);
1236
1237         if (gphone_rejected_call != -1) {
1238                 /*Answer the incoming call by accepting or rejecting the call */
1239                 tapi_err = tel_answer_call(gphone_rejected_call, TAPI_CALL_ANSWER_REJECT, &pReqId);
1240                 if (TAPI_API_SUCCESS != tapi_err) {
1241                         CALL_ENG_DEBUG(ENG_ERR, "tel_answer_call failed, Error: %d", tapi_err);
1242                 }
1243                 gphone_rejected_call = -1;
1244         }
1245         return FALSE;
1246 }
1247
1248 static gboolean __call_vc_sat_idle_cb(gpointer puser_data)
1249 {
1250         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)puser_data;
1251
1252         TelSatSetupCallIndCallData_t temp_data = { 0, };
1253
1254         memset(&temp_data, 0, sizeof(TelSatSetupCallIndCallData_t));
1255         memcpy(&temp_data, gpresult, sizeof(TelSatSetupCallIndCallData_t));
1256         CALL_ENG_DEBUG(ENG_DEBUG, "[SAT] call_data->calltype = 0x%x", temp_data.calltype);
1257         CALL_ENG_DEBUG(ENG_DEBUG, "[SAT] call_data->dispText.string = %s", temp_data.dispText.string);
1258         CALL_ENG_DEBUG(ENG_DEBUG, "[SAT] call_data->callNumber.string = %s", temp_data.callNumber.string);
1259         CALL_ENG_DEBUG(ENG_DEBUG, "[SAT] call_data->duration = %d", (int)temp_data.duration);
1260
1261         __call_vc_handle_sat_engine_events(pagent, VC_ACTION_SAT_REQUEST, gsat_event_type, gtype, gpresult);
1262
1263         /*Free the result after copying the data */
1264         /*g_free(gpresult);*/
1265         gpresult = NULL;
1266         /*Always Return FALSE from this g_idle callback, so it will not be called again */
1267         return FALSE;
1268 }
1269
1270 void _vc_core_engine_handle_incoming_tapi_events(void *mt_data, void *userdata)
1271 {
1272         char *data = mt_data;
1273
1274         call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
1275
1276         VOICECALL_RETURN_IF_FAIL(pagent != NULL);
1277
1278         int current_mt_call_handle = -1;
1279         CALL_ENG_DEBUG(ENG_DEBUG, "event_type == TAPI_EVENT_CALL_INCOM_IND...");
1280
1281         /*Safety Check to avoid the mutiple incoming noti for the same call */
1282         current_mt_call_handle = _vc_core_cm_get_incoming_call_handle(&pagent->call_manager);
1283         CALL_ENG_DEBUG(ENG_ERR, "current_mt_call_handle = %d", current_mt_call_handle);
1284
1285         if (current_mt_call_handle != VC_TAPI_INVALID_CALLHANDLE) {
1286                 TelCallIncomingCallInfo_t mt_call_info;
1287                 CALL_ENG_DEBUG(ENG_ERR, "Already an Incoming Call exits ,Problem in accpeting the incoming call, Current Call Details");
1288                 CALL_VC_DUMP_CALLDETAILS(&pagent->call_manager);
1289                 CALL_ENG_DEBUG(ENG_ERR, "****************Currently received call details *************************");
1290
1291                 memset(&mt_call_info, 0, sizeof(TelCallIncomingCallInfo_t));
1292                 memcpy(&mt_call_info, data, sizeof(TelCallIncomingCallInfo_t));
1293                 CALL_ENG_DEBUG(ENG_ERR, "****************call handle = [%d] *************************", mt_call_info.CallHandle);
1294                 CALL_ENG_DEBUG(ENG_ERR, "****************call Number = [%s] *************************", mt_call_info.szCallingPartyNumber);
1295                 CALL_ENG_DEBUG(ENG_ERR, "**************** Ignoring this incoming notification *************************");
1296                 return;
1297         }
1298
1299         memset(&gincoming_call_info, 0, sizeof(TelCallIncomingCallInfo_t));
1300         memcpy(&gincoming_call_info, data, sizeof(TelCallIncomingCallInfo_t));
1301         gincoming_call_handle = gincoming_call_info.CallHandle;
1302
1303         CALL_ENG_DEBUG(ENG_DEBUG, "CallHandle = %d,  Number = %s", gincoming_call_info.CallHandle, gincoming_call_info.szCallingPartyNumber);
1304
1305         /* Reject the Incoming call */
1306         if (FALSE == gphone_init_finished) {
1307                 CALL_ENG_DEBUG(ENG_ERR, "Phone is not initialized, So reject the Call");
1308
1309                 gphone_rejected_call = gincoming_call_handle;
1310
1311                 /*Reject the Call in the Idle Callback */
1312                 g_idle_add_full(G_PRIORITY_HIGH_IDLE, __call_vc_reject_call_idle_cb, pagent, NULL);
1313
1314                 return;
1315         }
1316
1317         /* Check the IO State before accepting the call */
1318         switch (pagent->io_state) {
1319         case VC_INOUT_STATE_OUTGOING_WAIT_HOLD:
1320         case VC_INOUT_STATE_OUTGOING_WAIT_ALERT:
1321         case VC_INOUT_STATE_OUTGOING_WAIT_ORIG:
1322         case VC_INOUT_STATE_OUTGOING_WAIT_CONNECTED:
1323         case VC_INOUT_STATE_INCOME_END: /*If the Previous End event is still not prcocessed then reject the call */
1324                 {
1325                         call_vc_call_objectinfo_t objectInfo;
1326
1327                         /* setting the new member info */
1328                         _vc_core_cm_clear_call_object(&objectInfo);
1329                         objectInfo.call_handle = gincoming_call_handle;
1330                         _vc_core_cm_change_call_state(&objectInfo, VC_CALL_STATE_REJECTED);
1331
1332                         /* add new member info */
1333                         _vc_core_cm_add_call_object(&pagent->call_manager, &objectInfo);
1334
1335                         /*Reject the Call in the Idle Callback */
1336                         g_idle_add_full(G_PRIORITY_HIGH_IDLE, __call_vc_reject_call_full_idle_cb, pagent, NULL);
1337
1338                         return;
1339                 }
1340                 break;
1341                 /*If Outgoing call is in any of the following wait state during an Incoming Event Cancel the Outgoing Call */
1342         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 */
1343         case VC_INOUT_STATE_OUTGOING_ABORTED:
1344         case VC_INOUT_STATE_OUTGOING_SHOW_REDIALCAUSE:
1345         case VC_INOUT_STATE_OUTGOING_WAIT_REDIAL:
1346         case VC_INOUT_STATE_OUTGOING_SHOW_RETRY_CALLBOX:
1347                 {
1348                         int mo_call_handle = -1;
1349                         mo_call_handle = _vc_core_cm_get_outgoing_call_handle(&pagent->call_manager);
1350                         _vc_core_cm_remove_call_object(&pagent->call_manager, mo_call_handle);
1351
1352                         /* Inform the Client that waiting outgoing call are cleaned up to accept the incoming call , */
1353                         _vc_core_ca_send_event_to_client(pagent, VC_ACTION_INCOM_FORCE, mo_call_handle, 0, NULL);
1354                 }
1355         default:
1356                 break;
1357         }
1358
1359         /*If Incoming End event is still pending, First Process the incoming end indication before processing the new
1360            Incoming Call */
1361         if (VC_INOUT_STATE_INCOME_END == pagent->io_state) {
1362                 int mt_call_handle = -1;
1363
1364                 CALL_ENG_DEBUG(ENG_ERR, "Previous Incoming End Call Not processed, Processing Here");
1365                 mt_call_handle = _vc_core_cm_get_incoming_call_handle(&pagent->call_manager);
1366                 if (mt_call_handle != -1) {
1367                         __call_vc_incomingcall_endhandle(pagent, mt_call_handle);
1368                 }
1369         }
1370
1371         /* Handle Incoming Call */
1372         if (TRUE == _vc_core_tapi_event_handle_incoming_event(pagent, gincoming_call_handle, &gincoming_call_info)) {
1373                 CALL_ENG_DEBUG(ENG_DEBUG, "Using Idle Add Full with G_PRIORITY_HIGH_IDLE for processing Incoming Call");
1374                 g_idle_add_full(G_PRIORITY_HIGH_IDLE, __call_vc_incoming_idle_cb, pagent, NULL);
1375         }
1376
1377         CALL_ENG_DEBUG(ENG_DEBUG, "MT CALL event processed done.");
1378         return;
1379
1380 }
1381
1382 static void __call_vc_handle_tapi_events(TelTapiEvent_t *event, void *userdata)
1383 {
1384         int event_type = event->EventType;
1385         int status = event->Status;
1386         char *data = event->pData;
1387
1388         call_vc_callagent_state_t *pagent = gpcall_agent_for_callback;
1389
1390         VOICECALL_RETURN_IF_FAIL(pagent != NULL);
1391
1392         CALL_ENG_DEBUG(ENG_WARN, "event_type:[0x%x], status= %d", event_type, status);
1393
1394         /* Process TAPI events */
1395         switch (event_type) {
1396 #ifdef _INCOM_END_
1397         case TAPI_EVENT_CALL_INCOM_IND:
1398                 {
1399                         int current_mt_call_handle = -1;
1400                         CALL_ENG_DEBUG(ENG_DEBUG, "event_type == TAPI_EVENT_CALL_INCOM_IND...");
1401
1402                         /*Safety Check to avoid the mutiple incoming noti for the same call */
1403                         current_mt_call_handle = _vc_core_cm_get_incoming_call_handle(&pagent->call_manager);
1404                         CALL_ENG_DEBUG(ENG_ERR, "current_mt_call_handle = %d", current_mt_call_handle);
1405
1406                         if (current_mt_call_handle != VC_TAPI_INVALID_CALLHANDLE) {
1407                                 TelCallIncomingCallInfo_t mt_call_info;
1408                                 CALL_ENG_DEBUG(ENG_ERR, "Already an Incoming Call exits ,Problem in accpeting the incoming call, Current Call Details");
1409                                 CALL_VC_DUMP_CALLDETAILS(&pagent->call_manager);
1410                                 CALL_ENG_DEBUG(ENG_ERR, "****************Currently received call details *************************");
1411
1412                                 memset(&mt_call_info, 0, sizeof(TelCallIncomingCallInfo_t));
1413                                 memcpy(&mt_call_info, data, sizeof(TelCallIncomingCallInfo_t));
1414                                 CALL_ENG_DEBUG(ENG_ERR, "****************call handle = [%d] *************************", mt_call_info.CallHandle);
1415                                 CALL_ENG_DEBUG(ENG_ERR, "****************call Number = [%s] *************************", mt_call_info.szCallingPartyNumber);
1416                                 CALL_ENG_DEBUG(ENG_ERR, "**************** Ignoring this incoming notification *************************");
1417                                 return;
1418                         }
1419
1420                         memset(&gincoming_call_info, 0, sizeof(TelCallIncomingCallInfo_t));
1421                         memcpy(&gincoming_call_info, data, sizeof(TelCallIncomingCallInfo_t));
1422                         gincoming_call_handle = gincoming_call_info.CallHandle;
1423
1424                         CALL_ENG_DEBUG(ENG_DEBUG, "CallHandle = %d,  Number = %s", gincoming_call_info.CallHandle, gincoming_call_info.szCallingPartyNumber);
1425
1426                         /* Reject the Incoming call */
1427                         if (FALSE == gphone_init_finished) {
1428                                 CALL_ENG_DEBUG(ENG_ERR, "Phone is not initialized, So reject the Call");
1429
1430                                 gphone_rejected_call = gincoming_call_handle;
1431
1432                                 /*Reject the Call in the Idle Callback */
1433                                 g_idle_add_full(G_PRIORITY_HIGH_IDLE, __call_vc_reject_call_idle_cb, pagent, NULL);
1434
1435                                 return;
1436                         }
1437
1438                         /* Check the IO State before accepting the call */
1439                         switch (pagent->io_state) {
1440                         case VC_INOUT_STATE_OUTGOING_WAIT_HOLD:
1441                         case VC_INOUT_STATE_OUTGOING_WAIT_ALERT:
1442                         case VC_INOUT_STATE_OUTGOING_WAIT_ORIG:
1443                         case VC_INOUT_STATE_OUTGOING_WAIT_CONNECTED:
1444                         case VC_INOUT_STATE_INCOME_END: /*If the Previous End event is still not prcocessed then reject the call */
1445                                 {
1446                                         call_vc_call_objectinfo_t objectInfo;
1447
1448                                         /* setting the new member info */
1449                                         _vc_core_cm_clear_call_object(&objectInfo);
1450                                         objectInfo.call_handle = gincoming_call_handle;
1451                                         _vc_core_cm_change_call_state(&objectInfo, VC_CALL_STATE_REJECTED);
1452
1453                                         /* add new member info */
1454                                         _vc_core_cm_add_call_object(&pagent->call_manager, &objectInfo);
1455
1456                                         /*Reject the Call in the Idle Callback */
1457                                         g_idle_add_full(G_PRIORITY_HIGH_IDLE, __call_vc_reject_call_full_idle_cb, pagent, NULL);
1458
1459                                         return;
1460                                 }
1461                                 break;
1462                                 /*If Outgoing call is in any of the following wait state during an Incoming Event Cancel the Outgoing Call */
1463                         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 */
1464                         case VC_INOUT_STATE_OUTGOING_ABORTED:
1465                         case VC_INOUT_STATE_OUTGOING_SHOW_REDIALCAUSE:
1466                         case VC_INOUT_STATE_OUTGOING_WAIT_REDIAL:
1467                         case VC_INOUT_STATE_OUTGOING_SHOW_RETRY_CALLBOX:
1468                                 {
1469                                         int mo_call_handle = -1;
1470                                         mo_call_handle = _vc_core_cm_get_outgoing_call_handle(&pagent->call_manager);
1471                                         _vc_core_cm_remove_call_object(&pagent->call_manager, mo_call_handle);
1472
1473                                         /* Inform the Client that waiting outgoing call are cleaned up to accept the incoming call , */
1474                                         _vc_core_ca_send_event_to_client(pagent, VC_ACTION_INCOM_FORCE, mo_call_handle, 0, NULL);
1475                                 }
1476                         default:
1477                                 break;
1478                         }
1479
1480                         /*If Incoming End event is still pending, First Process the incoming end indication before processing the new
1481                            Incoming Call */
1482                         if (VC_INOUT_STATE_INCOME_END == pagent->io_state) {
1483                                 int mt_call_handle = -1;
1484
1485                                 CALL_ENG_DEBUG(ENG_ERR, "Previous Incoming End Call Not processed, Processing Here");
1486                                 mt_call_handle = _vc_core_cm_get_incoming_call_handle(&pagent->call_manager);
1487                                 if (mt_call_handle != -1) {
1488                                         __call_vc_incomingcall_endhandle(pagent, mt_call_handle);
1489                                 }
1490                         }
1491
1492                         /* Handle Incoming Call */
1493                         if (TRUE == _vc_core_tapi_event_handle_incoming_event(pagent, gincoming_call_handle, &gincoming_call_info)) {
1494                                 CALL_ENG_DEBUG(ENG_DEBUG, "Using Idle Add Full with G_PRIORITY_HIGH_IDLE for processing Incoming Call");
1495                                 g_idle_add_full(G_PRIORITY_HIGH_IDLE, __call_vc_incoming_idle_cb, pagent, NULL);
1496                         }
1497
1498                         return;
1499                 }
1500                 break;
1501 #endif
1502         case TAPI_EVENT_CALL_RELEASE_CNF:
1503                 {
1504                         CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_EVENT_CALL_RELEASE_CNF..");
1505
1506                         if (TAPI_CAUSE_SUCCESS == status) {
1507                                 /*Ignore this event as endication will be received from TAPI for the call release request */
1508                                 CALL_ENG_DEBUG(ENG_DEBUG, "Success response for Call Release request");
1509                                 break;
1510                         } else {
1511                                 /*Call Release request failed, handle the call end process in this event itself as the end indication may not be released */
1512                                 CALL_ENG_DEBUG(ENG_ERR, "Call Release request failed, proceeding with Call end process");
1513                         }
1514                 }
1515         case TAPI_EVENT_CALL_END_IND:   /*Fall Through */
1516                 {
1517                         call_vc_call_objectinfo_t objectInfo;
1518                         voicecall_call_state_t present_call_state = VC_CALL_STATE_NONE;
1519                         call_vc_handle incoming_call_handle = VC_TAPI_INVALID_CALLHANDLE;
1520                         TelTapiEndCause_t tapi_cause = TAPI_CALL_END_NO_CAUSE;
1521                         call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1522                         TelCallEndInfo_t callEndInfo;
1523
1524                         CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_EVENT_CALL_END_IND..");
1525
1526                         if (TAPI_EVENT_CALL_RELEASE_CNF == event_type) {
1527                                 /* tapicallback data =  Call Handle */
1528                                 memset(&call_handle, 0, sizeof(call_vc_handle));
1529                                 memcpy(&call_handle, data, sizeof(call_vc_handle));
1530
1531                                 /*Tapi doesn't send cause for TAPI_EVENT_CALL_RELEASE_CNF */
1532                                 tapi_cause = TAPI_CALL_END_NO_CAUSE;
1533                         } else {
1534                                 /* tapicallback data =  CallEndInfo */
1535                                 memset(&callEndInfo, 0, sizeof(TelCallEndInfo_t));
1536                                 memcpy(&callEndInfo, data, sizeof(TelCallEndInfo_t));
1537
1538                                 call_handle = callEndInfo.pCallHandle;
1539                                 tapi_cause = callEndInfo.CallEndCause;
1540                         }
1541
1542                         CALL_ENG_DEBUG(ENG_DEBUG, "Call Handle = %d,end cause:%d", call_handle, tapi_cause);
1543
1544                         /*the end of incoming call rejected by callagent, because the call had come before the phone is initialized */
1545                         if (call_handle == gphone_rejected_call) {
1546                                 CALL_ENG_DEBUG(ENG_DEBUG, "Rejected call..phone not initialized");
1547
1548                                 gphone_rejected_call = VC_TAPI_INVALID_CALLHANDLE;
1549
1550                                 /*If no more calls available, End the Application */
1551                                 __vc_core_check_engine_active_task(pagent);
1552                                 return;
1553                         }
1554
1555                         incoming_call_handle = _vc_core_cm_get_incoming_call_handle(&pagent->call_manager);
1556                         present_call_state = _vc_core_cm_get_call_state(&pagent->call_manager, call_handle);
1557
1558                         CALL_ENG_DEBUG(ENG_DEBUG, "New Call Handle = %d, Already registered MT call handle : %d", call_handle, incoming_call_handle);
1559                         switch (present_call_state) {
1560                         case VC_CALL_STATE_NONE:
1561                         case VC_CALL_STATE_ENDED:
1562                         case VC_CALL_STATE_ENDED_FINISH:
1563                                 {
1564                                         CALL_ENG_DEBUG(ENG_DEBUG, "Call Handle = %d state is %d", call_handle, present_call_state);
1565                                         /*If no more calls available, End the Application */
1566                                         __vc_core_check_engine_active_task(pagent);
1567                                         return;
1568                                 }
1569                                 break;
1570                         case VC_CALL_STATE_REJECTED:
1571                                 {
1572                                         /*End of incoming call (not registered as incoming call in CallAgent) rejected by callagent */
1573                                         if (incoming_call_handle != call_handle) {
1574                                                 _vc_core_cm_remove_call_object(&pagent->call_manager, call_handle);
1575                                                 CALL_ENG_DEBUG(ENG_DEBUG, "end of call rejected by callagent");
1576
1577                                                 /*If no more calls available, End the Application */
1578                                                 __vc_core_check_engine_active_task(pagent);
1579                                                 return;
1580                                         }
1581                                 }
1582                                 break;
1583                         default:
1584                                 break;
1585                         }
1586
1587                         /*End of the call rejected by user or by callagent (when hold is failed) */
1588                         if ((VC_INOUT_STATE_INCOME_WAIT_RELEASE == pagent->io_state) && (incoming_call_handle == call_handle)) {
1589                                 _vc_core_cm_remove_call_object(&pagent->call_manager, call_handle);
1590
1591                                 /*Change the In Out state to None*/
1592                                 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_NONE);
1593
1594                                 /*Notify Client about rejected Event*/
1595                                 _vc_core_ca_send_event_to_client(pagent, VC_CALL_REJECTED_END, call_handle, 0, NULL);
1596
1597                                 return;
1598                         }
1599
1600                         /*End of Incoming Call */
1601                         if (incoming_call_handle == call_handle) {
1602                                 CALL_ENG_DEBUG(ENG_DEBUG, "Adding Incoming End Event to Idle Callback");
1603                                 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_INCOME_END);
1604                                 /*Make sure that the End Indication is processed always after the Incoming Indication , as both are
1605                                    processed in Idle Add Callbacks */
1606                                 g_idle_add(__call_vc_incoming_call_end_idle_cb, pagent);
1607                                 return;
1608                         }
1609
1610                         /*End of Outgoing Call */
1611                         if (_vc_core_cm_get_outgoing_call_handle(&pagent->call_manager) == call_handle) {
1612                                 __call_vc_outgoingcall_endhandle(pagent, call_handle, TAPI_EVENT_CALL_END_IND, tapi_cause);
1613                                 return;
1614                         }
1615
1616                         /*End of Normal Connected Call */
1617                         _vc_core_tapi_event_handle_call_end_event(pagent, event_type, call_handle, tapi_cause);
1618
1619                         CALL_VC_DUMP_CALLDETAILS(&pagent->call_manager);
1620                         _vc_core_cm_clear_call_object(&objectInfo);
1621                         if (FALSE == _vc_core_cm_get_call_object(&pagent->call_manager, call_handle, &objectInfo)) {
1622                                 CALL_ENG_DEBUG(ENG_DEBUG, "Call Already Cleared for Call Handle = %d", call_handle);
1623
1624                                 /*
1625                                  * Because of _vc_core_tapi_rqst_answer_call( .., VC_ANSWER_HOLD_ACTIVE_AND_ACCEPT,.. ) inside _vc_core_tapi_event_handle_call_end_event(),
1626                                  * pagent->call_manager is cleared. so, we didn't send VC_CALL_NORMAL_END to call-ui.
1627                                  * so we should send this event to call-ui.
1628                                  */
1629                                 {
1630                                         voice_call_end_cause_type_t end_cause_type;
1631                                         _vc_core_tapi_event_get_end_cause_type(event_type, tapi_cause, &end_cause_type);
1632                                         _vc_core_ca_send_event_to_client(pagent, VC_CALL_NORMAL_END, call_handle, end_cause_type, NULL);
1633                                 }
1634                         } else {
1635                                 _vc_core_ca_send_event_to_client(pagent, VC_CALL_NORMAL_END, objectInfo.call_handle, objectInfo.end_cause_type, NULL);
1636                         }
1637                 }
1638                 break;
1639         case TAPI_EVENT_CALL_RELEASE_ALL_CNF:
1640                 {
1641                         CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_EVENT_CALL_RELEASE_ALL_CNF");
1642                 }
1643                 break;
1644         case TAPI_EVENT_CALL_RELEASE_ALL_ACTIVE_CNF:
1645                 {
1646                         CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_EVENT_CALL_RELEASE_ALL_ACTIVE_CNF");
1647                 }
1648                 break;
1649         case TAPI_EVENT_CALL_RELEASE_ALL_HELD_CNF:
1650                 {
1651                         CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_EVENT_CALL_RELEASE_ALL_HELD_CNF");
1652                 }
1653                 break;
1654         case TAPI_EVENT_CALL_ALERT_IND:
1655                 {
1656                         call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1657                         call_vc_handle mo_call_handle = VC_TAPI_INVALID_CALLHANDLE;
1658
1659                         CALL_ENG_KPI("TAPI_EVENT_CALL_ALERT_IND START");
1660                         /*There are possiblities, that TAPI issued the Alert Notification and it is pending in the gmain loop, but meanwhile, the call
1661                            is released by the user - so ignore the event if it doesn't match with the IN OUT Wait state */
1662                         if (VC_INOUT_STATE_OUTGOING_WAIT_ALERT != pagent->io_state) {
1663                                 CALL_ENG_DEBUG(ENG_DEBUG, "Io State not in WAIT_ORIG, current io state is : %d", pagent->io_state);
1664                                 return;
1665                         }
1666                         /*tapi_data = (call_handle)*/
1667                         memcpy(&call_handle, data, sizeof(call_vc_handle));
1668                         CALL_ENG_DEBUG(ENG_DEBUG, "Alert Call Handle = %d", call_handle);
1669
1670                         mo_call_handle = _vc_core_cm_get_outgoing_call_handle(&pagent->call_manager);
1671                         CALL_ENG_DEBUG(ENG_DEBUG, "MO Call Handle = %d", mo_call_handle);
1672
1673                         /*Get the outgoing call handle from CallManger and check*/
1674                         if ((VC_TAPI_INVALID_CALLHANDLE == call_handle) || (mo_call_handle != call_handle)) {
1675                                 CALL_ENG_DEBUG(ENG_DEBUG, "Outgoing call does not exist or call_handle doesn't match");
1676                                 break;
1677                         }
1678
1679                         _vc_core_tapi_event_handle_alert_event(pagent, call_handle);
1680                         CALL_ENG_KPI("TAPI_EVENT_CALL_ALERT_IND done");
1681                 }
1682                 break;
1683         case TAPI_EVENT_CALL_SETUP_CNF:
1684                 {
1685                         call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1686                         call_vc_call_objectinfo_t objectInfo;
1687
1688                         CALL_ENG_DEBUG(ENG_DEBUG, "Data Received for Setup CNF is %p", data);
1689                         CALL_ENG_KPI("Set Up CNF start");
1690
1691                         if (TRUE == _vc_core_cm_get_outgoing_call_info(&pagent->call_manager, &objectInfo)) {
1692                                 CALL_ENG_DEBUG(ENG_DEBUG, "MO call index (%d)",objectInfo.call_id);
1693                         } else {
1694                                 CALL_ENG_DEBUG(ENG_ERR, "EXCEPTION:Outgoing call Info Missing..");
1695                         }
1696
1697                         /*Copy Telephony Data */
1698                         /* tapi_data = (call_handle) */
1699                         if (data != NULL) {
1700                                 memcpy(&call_handle, data, sizeof(call_vc_handle));
1701                                 CALL_ENG_DEBUG(ENG_DEBUG, "Received Call Handle = %d", call_handle);
1702                         }
1703
1704                         if (VC_INOUT_STATE_OUTGOING_WAIT_ORIG != pagent->io_state) {
1705                                 CALL_ENG_DEBUG(ENG_DEBUG, "Io State not in WAIT_ORIG, current io state is : %d", pagent->io_state);
1706                                 return;
1707                         }
1708
1709                         if (TAPI_CAUSE_SUCCESS == status) {
1710                                 /* Get the outgoing call handle from CallManger and check */
1711                                 if ((VC_TAPI_INVALID_CALLHANDLE == call_handle)) {
1712                                         CALL_ENG_DEBUG(ENG_DEBUG, "Outgoing call does not exist or call_handle doesn't match");
1713                                         break;
1714                                 }
1715
1716                                 /* Set the Call Handle to the CallbObject for future reference */
1717                                 objectInfo.call_handle = call_handle;
1718                                 _vc_core_cm_set_outgoing_call_info(&pagent->call_manager, &objectInfo);
1719
1720                                 _vc_core_tapi_event_handle_originated_event(pagent, call_handle);
1721                         } else {
1722                                 CALL_ENG_DEBUG(ENG_DEBUG, "MO Call SetupCNF Failed with error cause: %d", status);
1723
1724                                 _vc_core_cm_clear_call_object(&objectInfo);
1725
1726                                 __call_vc_outgoingcall_endhandle(pagent, objectInfo.call_handle, TAPI_EVENT_CALL_END_IND, TAPI_CC_CAUSE_FACILITY_REJECTED);
1727                         }
1728                         CALL_ENG_KPI("Set Up CNF done");
1729                 }
1730                 break;
1731         case TAPI_EVENT_CALL_ANSWER_CNF:
1732                 {
1733                         CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_EVENT_CALL_ANSWER_CNF");
1734
1735                         if (status != TAPI_CAUSE_SUCCESS) {
1736                                 /*If IO State is waiting for Answer Response */
1737                                 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)) {
1738                                         int mt_call_handle = -1;
1739
1740                                         mt_call_handle = _vc_core_cm_get_incoming_call_handle(&pagent->call_manager);
1741
1742                                         if (mt_call_handle != -1) {
1743                                                 CALL_ENG_DEBUG(ENG_DEBUG, "mt_call_handle = %d", mt_call_handle);
1744
1745                                                 /*Send Hold Failed Notification to client UI */
1746                                                 if (pagent->callagent_state == CALL_VC_CA_STATE_WAIT_HOLD) {
1747                                                         _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
1748                                                         _vc_core_ca_send_event_to_client(pagent, VC_ERROR_OCCURED, ERROR_VOICECALL_HOLD_FAILED, 0, NULL);
1749                                                 }
1750
1751                                                 /*Send Incoming call MT End Indication to Client UI */
1752                                                 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_INCOME_END);
1753                                                 g_idle_add(__call_vc_incoming_call_end_idle_cb, pagent);
1754                                         }
1755                                 }
1756                         }else {
1757                                 _vc_core_ca_send_event_to_client(pagent, VC_CALL_ANSWER_CNF, 0, 0, NULL);
1758                         }
1759                 }
1760                 break;
1761         case TAPI_EVENT_CALL_CONNECTED_IND:
1762                 {
1763                         call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1764
1765                         CALL_ENG_DEBUG(ENG_DEBUG, "event_type == TAPI_EVENT_CALL_CONNECTED_IND...");
1766                         CALL_ENG_KPI("TAPI_EVENT_CALL_CONNECTED_IND start");
1767
1768                         /*tapi callback data = (call_handle)*/
1769                         memcpy(&call_handle, data, sizeof(int));
1770                         CALL_ENG_DEBUG(ENG_DEBUG, "IO State: %d", pagent->io_state);
1771                         CALL_ENG_DEBUG(ENG_DEBUG, "Connected Call Handle = %d", call_handle);
1772
1773                         if (call_handle == _vc_core_cm_get_incoming_call_handle(&pagent->call_manager)) {
1774                                 CALL_ENG_DEBUG(ENG_DEBUG, "Incoming call is being connected...");
1775                         } else if (call_handle == _vc_core_cm_get_outgoing_call_handle(&pagent->call_manager)) {
1776                                 CALL_ENG_DEBUG(ENG_DEBUG, "Outgoing call is being connected...");
1777                         } else {
1778                                 CALL_ENG_DEBUG(ENG_ERR, "invalid connected event Call Handle = %d", call_handle);
1779
1780                                 if ((VC_INVALID_CALL_INDEX != pagent->call_manager.mtcall_index) || (VC_INVALID_CALL_INDEX != pagent->call_manager.setupcall_info.mocall_index)) {
1781                                         CALL_ENG_DEBUG(ENG_DEBUG, "incoming/outgoin calls call exits, invalid call handle [PROBLEM]");
1782                                         CALL_VC_DUMP_CALLDETAILS(&pagent->call_manager);
1783
1784                                         assert(0);
1785                                 } else {
1786                                         CALL_ENG_DEBUG(ENG_ERR, "No pending calls to connect, ignoreing connect event for call handle= %d", call_handle);
1787                                         return;
1788                                 }
1789                                 break;
1790                         }
1791
1792                         /*Handle Connected Call Event */
1793                         _vc_core_tapi_event_handle_call_connect_event(pagent, call_handle);
1794                         CALL_ENG_KPI("TAPI_EVENT_CALL_CONNECTED_IND done");
1795                 }
1796                 break;
1797         case TAPI_EVENT_CALL_HOLD_CNF:
1798                 {
1799                         call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1800
1801                         CALL_ENG_DEBUG(ENG_DEBUG, "event_type == TAPI_EVENT_CALL_HOLD_CNF...");
1802                         if (TAPI_CAUSE_SUCCESS == status) {
1803                                 /*tapicallback data = call_handle*/
1804                                 memcpy(&call_handle, data, sizeof(call_vc_handle));
1805                         } else {
1806                                 _vc_core_cm_get_first_active_call_handle(&pagent->call_manager, &call_handle);
1807                         }
1808
1809                         if (_vc_core_tapi_event_handle_call_held_event(pagent, call_handle, status) == FALSE) {
1810                                 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
1811                         } else {
1812                                 /*
1813                                    Be carefull in clearing the end call member, because _vc_core_engine_status_is_any_call_ending
1814                                    function depends on the end call object status. If it is cleared often, the check by
1815                                    _vc_core_engine_status_is_any_call_ending becomes invalid
1816                                  */
1817                                 _vc_core_cm_clear_endcall_member(&pagent->call_manager);
1818                         }
1819                 }
1820                 break;
1821         case TAPI_EVENT_CALL_RETRIEVE_CNF:
1822                 {
1823                         call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1824
1825                         CALL_ENG_DEBUG(ENG_DEBUG, "event_type == TAPI_EVENT_CALL_RETRIEVE_CNF...");
1826
1827                         if (TAPI_CAUSE_SUCCESS == status) {
1828                                 /*tapicallback data = call_handle*/
1829                                 memcpy(&call_handle, data, sizeof(call_vc_handle));
1830                         } else {
1831                                 _vc_core_cm_get_first_held_call_handle(&pagent->call_manager, &call_handle);
1832                         }
1833
1834                         if (_vc_core_tapi_event_handle_call_retrieve_event(pagent, call_handle, status) == FALSE) {
1835                                 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
1836                         } else {
1837                                 /*
1838                                    Be carefull in clearing the end call member, because _vc_core_engine_status_is_any_call_ending
1839                                    function depends on the end call object status. If it is cleared often, the check by
1840                                    _vc_core_engine_status_is_any_call_ending becomes invalid
1841                                  */
1842                                 _vc_core_cm_clear_endcall_member(&pagent->call_manager);
1843                         }
1844
1845                 }
1846                 break;
1847         case TAPI_EVENT_CALL_SETUPCONFERENCE_CNF:
1848                 {
1849                         call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1850
1851                         CALL_ENG_DEBUG(ENG_DEBUG, "event_type == TAPI_EVENT_CALL_SETUPCONFERENCE_CNF...");
1852
1853                         if (TAPI_CAUSE_SUCCESS == status) {
1854                                 /*tapicallback data = call_handle*/
1855                                 memcpy(&call_handle, data, sizeof(call_vc_handle));
1856                         } else {
1857                                 call_handle = 0;
1858                         }
1859
1860                         _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
1861                         _vc_core_tapi_event_handle_call_join_event(pagent, call_handle, status);
1862                 }
1863                 break;
1864         case TAPI_EVENT_CALL_SPLITCONFERENCE_CNF:
1865                 {
1866                         call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1867
1868                         CALL_ENG_DEBUG(ENG_DEBUG, "event_type == TAPI_EVENT_CALL_SPLITCONFERENCE_CNF...");
1869
1870                         if (TAPI_CAUSE_SUCCESS == status) {
1871                                 /*tapicallback data = call_handle*/
1872                                 memcpy(&call_handle, data, sizeof(call_vc_handle));
1873                         }
1874
1875                         _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
1876                         _vc_core_tapi_event_handle_call_split_event(pagent, call_handle, status);
1877                 }
1878                 break;
1879         case TAPI_EVENT_CALL_TRANSFER_CNF:
1880                 {
1881                         CALL_ENG_DEBUG(ENG_DEBUG, "event_type == TAPI_EVENT_CALL_TRANSFER_CNF");
1882
1883                         _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
1884                         _vc_core_tapi_event_handle_call_transfer_event(pagent, status);
1885                 }
1886                 break;
1887         case TAPI_EVENT_CALL_RETRIEVE_IND:
1888         case TAPI_EVENT_CALL_HOLD_IND:
1889         case TAPI_EVENT_CALL_TRANSFER_IND:
1890         case TAPI_EVENT_CALL_SETUPCONFERENCE_IND:
1891         case TAPI_EVENT_CALL_BARRING_IND:
1892         case TAPI_EVENT_CALL_WAITING_IND:
1893         case TAPI_EVENT_CALL_COND_FORWARDING_IND:
1894         case TAPI_EVENT_CALL_UNCOND_FORWARDING_IND:
1895                 {
1896                         CALL_ENG_DEBUG(ENG_DEBUG, "Received Indication %d", event_type);
1897                         if (TRUE == __call_vc_is_callagent_waitstate(pagent)) {
1898                                 CALL_ENG_DEBUG(ENG_DEBUG, "[Now tapi requesting...callagent_state=%d, not display network ind]", pagent->callagent_state);
1899                                 return;
1900
1901                         } else {
1902                                 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1903
1904                                 /*tapicallback data = call_handle + cause*/
1905                                 memcpy(&call_handle, data, sizeof(call_vc_handle));
1906
1907                                 CALL_ENG_DEBUG(ENG_DEBUG, "Call Handle = %d", call_handle);
1908
1909                                 _vc_core_tapi_event_handle_notification(pagent, event_type, 0);
1910                         }
1911                 }
1912                 break;
1913         case TAPI_EVENT_CALL_CUGINFO_IND:
1914                 {
1915                         CALL_ENG_DEBUG(ENG_DEBUG, "Received TAPI_EVENT_CALL_CUGINFO_IND");
1916
1917                         if (TRUE == __call_vc_is_callagent_waitstate(pagent)) {
1918                                 CALL_ENG_DEBUG(ENG_DEBUG, "[Now tapi requesting...callagent_state=%d, not display network ind]", pagent->callagent_state);
1919                                 return;
1920
1921                         } else {
1922                                 int cugIndex = 0;
1923                                 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1924
1925                                 /*tapicallback data = call_handle + cause*/
1926                                 memcpy(&call_handle, data, sizeof(call_vc_handle));
1927                                 memcpy(&cugIndex, data + sizeof(call_vc_handle), sizeof(int));
1928
1929                                 /*cugindex is not used inside this function*/
1930                                 /*It may be used in the future*/
1931                                 _vc_core_tapi_event_handle_notification(pagent, event_type, cugIndex);
1932                         }
1933                 }
1934                 break;
1935         case TAPI_EVENT_CALL_CALLINGNAMEINFO_IND:
1936                 {
1937                         CALL_ENG_DEBUG(ENG_DEBUG, "Received TAPI_EVENT_CALL_CALLINGNAMEINFO_IND");
1938                         CALL_ENG_DEBUG(ENG_DEBUG, "Event Not Handled, Feature Not Implemented");
1939
1940 #ifdef _CALLING_NAME_INFO_
1941                         if (TRUE == __call_vc_is_callagent_waitstate(pagent)) {
1942                                 CALL_ENG_DEBUG(ENG_DEBUG, "[Now tapi requesting...callagent_state=%d, not display network ind]", pagent->callagent_state);
1943                                 return;
1944
1945                         } else {
1946                                 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1947                                 /*Structure for calling name information */
1948                                 TelCallingNameInfo_t calling_nameinfo;
1949                                 memset(&calling_nameinfo, 0, sizeof(TelCallingNameInfo_t));
1950
1951                                 /*TapiCallingNameInfo is padded as second parameneter
1952                                 tapicallback data = call_handle + cause*/
1953                                 memcpy(&call_handle, data, sizeof(call_vc_handle));
1954                                 memcpy(&calling_nameinfo, data + sizeof(call_vc_handle), sizeof(TelCallingNameInfo_t));
1955
1956                                 /*calling_info is not used in this function, so not passed.
1957                                 It may be used in the future*/
1958                                 _vc_core_tapi_event_handle_notification(pagent, event_type, 0);
1959                         }
1960 #endif
1961                 }
1962                 break;
1963 #ifdef _OLD_TAPI_
1964         case TAPI_EVENT_CALL_SSNOTIFY_IND:
1965                 {
1966                         CALL_ENG_DEBUG(ENG_DEBUG, "Received TAPI_EVENT_CALL_SSNOTIFY_IND");
1967                         CALL_ENG_DEBUG(ENG_DEBUG, "Event Not Handled, Feature Not Implemented");
1968
1969                         if (TRUE == __call_vc_is_callagent_waitstate(pagent)) {
1970                                 CALL_ENG_DEBUG(ENG_DEBUG, "[Now tapi requesting...callagent_state=%d, not display network ind]", pagent->callagent_state);
1971                                 return TRUE;
1972
1973                         } else {
1974                                 tapi_call_ss_codes_t ss_code;
1975
1976                                 /*ss_code is padded as first parameter in the data
1977                                 data = ss_code*/
1978                                 memcpy(&ss_code, data, sizeof(tapi_call_ss_codes_t));
1979                                 _vc_core_tapi_event_handle_notification(pagent, event_type, ss_code);
1980
1981                         }
1982                 }
1983                 break;
1984
1985         case TAPI_EVENT_CALL_REDIRECT_CNF:
1986                 {
1987                         CALL_ENG_DEBUG(ENG_DEBUG, "Received TAPI_EVENT_CALL_REDIRECT_CNF");
1988                         CALL_ENG_DEBUG(ENG_DEBUG, "Event Not Handled, Feature Not Implemented");
1989
1990                         /*TODO abthul, not used currently */
1991                         return;
1992
1993                         if (TRUE == __call_vc_is_callagent_waitstate(pagent)) {
1994                                 CALL_ENG_DEBUG(ENG_DEBUG, "[Now tapi requesting...callagent_state=%d, not display network ind]", pagent->callagent_state);
1995                                 return;
1996                         } else {
1997                                 gboolean bValue;
1998
1999                                 /*bValue is padded as first parameter in data from TAPI
2000                                 data = bValue*/
2001                                 memcpy(&bValue, data, sizeof(gboolean));
2002                                 _vc_core_tapi_event_handle_notification(pagent, event_type, bValue);
2003                         }
2004                 }
2005 #endif
2006                 break;
2007         case TAPI_EVENT_CALL_FORWARD_IND:
2008                 {
2009                         CALL_ENG_DEBUG(ENG_DEBUG, "Received TAPI_EVENT_CALL_FORWARD_IND");
2010
2011                         if (TRUE == __call_vc_is_callagent_waitstate(pagent)) {
2012                                 CALL_ENG_DEBUG(ENG_DEBUG, "[Now tapi requesting...callagent_state=%d, not display network ind]", pagent->callagent_state);
2013                                 return;
2014
2015                         } else {
2016                                 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
2017                                 TelCallForwardType_t forwardind_type = -1;
2018
2019                                 /*tapicallback data = call_handle + forwardind_type*/
2020                                 memcpy(&call_handle, data, sizeof(call_vc_handle));
2021                                 memcpy(&forwardind_type, data + sizeof(call_vc_handle), sizeof(TelCallForwardType_t));
2022
2023                                 _vc_core_tapi_event_handle_notification(pagent, event_type, forwardind_type);
2024                         }
2025                 }
2026                 break;
2027         case TAPI_EVENT_CALL_AOCINFO_IND:
2028                 {
2029                         TelCallAocInfo_t aoc_info;
2030                         call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
2031                         memset(&aoc_info, 0, sizeof(TelCallAocInfo_t));
2032
2033                         CALL_ENG_DEBUG(ENG_DEBUG, "Recived TAPI_EVENT_CALL_AOCINFO_IND...");
2034
2035                         /*data = call_handle + tapi_call_aoc_info_t */
2036                         memcpy(&call_handle, data, sizeof(int));
2037                         memcpy(&aoc_info, (data + sizeof(int)), sizeof(TelCallAocInfo_t));
2038
2039                         CALL_ENG_DEBUG(ENG_DEBUG, "Call Handle = %d", call_handle);
2040                         _vc_core_tapi_event_handle_aoc(pagent, call_handle, &aoc_info);
2041                 }
2042                 break;
2043         case TAPI_EVENT_SS_AOC_RSP:
2044                 {
2045                         TelCallAocInfo_t aoc_info;
2046
2047                         CALL_ENG_DEBUG(ENG_DEBUG, "Recived TAPI_EVENT_SS_AOC_RSP");
2048
2049                         if (TAPI_CAUSE_SUCCESS == status) {
2050                                 memset(&aoc_info, 0, sizeof(TelCallAocInfo_t));
2051                                 memcpy(&aoc_info, data, sizeof(TelCallAocInfo_t));
2052
2053                                 switch (aoc_info.AocType) {
2054                                 case TAPI_SS_AOC_TYPE_PUC:
2055                                         CALL_ENG_DEBUG(ENG_DEBUG, "Recived aoc_ppm = %f", aoc_info.PPM);
2056                                         pagent->aoc_ppm = aoc_info.PPM;
2057                                         break;
2058                                 default:
2059                                         CALL_ENG_DEBUG(ENG_DEBUG, "Action not defined for AOC Type : %d", aoc_info.AocType);
2060                                 }
2061                         }
2062                 }
2063                 break;
2064         case TAPI_EVENT_CALL_CONNECTEDNUMBERINFO_IND:
2065                 {
2066                         TelCallConnectedNumberInfo_t connected_number_info;
2067                         call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
2068                         memset(&connected_number_info, 0, sizeof(TelCallConnectedNumberInfo_t));
2069
2070                         CALL_ENG_DEBUG(ENG_DEBUG, "TAPI_EVENT_CALL_CONNECTEDNUMBERINFO_IND");
2071
2072                         /*data = callhandle + 0(dwParam)*/
2073                         memcpy(&call_handle, data, sizeof(call_vc_handle));
2074                         memcpy(&connected_number_info, (data + sizeof(call_vc_handle)), sizeof(TelCallConnectedNumberInfo_t));
2075
2076                         CALL_ENG_DEBUG(ENG_DEBUG, "Call Handle = %d", call_handle);
2077
2078                         /*Abthul:todo , Check the usage of connected number info*/
2079                         _vc_core_tapi_event_connected_line_ind_handle(pagent, call_handle, &connected_number_info);
2080                 }
2081                 break;
2082         case TAPI_EVENT_CALL_SEND_DTMF_CNF:
2083                 {
2084                         CALL_ENG_DEBUG(ENG_DEBUG, "event_type == TAPI_EVENT_CALL_SEND_DTMF_CNF");
2085
2086                         if (TAPI_CAUSE_SUCCESS != status) {
2087                                 CALL_ENG_DEBUG(ENG_DEBUG, "Tapi Error Code %d", status);
2088                                 /*Forward the events to client */
2089                                 _vc_core_ca_send_event_to_client(pagent, VC_CALL_DTMF_ACK, FALSE, 0, NULL);
2090                         } else {
2091                                 /*Forward the events to client */
2092                                 _vc_core_ca_send_event_to_client(pagent, VC_CALL_DTMF_ACK, TRUE, 0, NULL);
2093                         }
2094                 }
2095                 break;
2096         case TAPI_EVENT_SOUND_VOLUMECTRL_RSP:
2097                 {
2098                         int tapi_sound_path = 0;
2099                         int volume_level = 0;
2100                         tapi_sound_volumn_ctrl_res snd_resp_data;
2101
2102                         memset(&snd_resp_data, 0, sizeof(tapi_sound_volumn_ctrl_res));
2103                         memcpy(&snd_resp_data, data, sizeof(tapi_sound_volumn_ctrl_res));
2104
2105                         int i = 0;
2106                         tapi_sound_path = pagent->curr_tapi_path;
2107                         for (i = 0; i < snd_resp_data.num_record; i++) {
2108                                 if (tapi_sound_path == snd_resp_data.pinfo[i].type) {
2109                                         volume_level = snd_resp_data.pinfo[i].level;
2110                                         break;
2111                                 }
2112                         }
2113                         CALL_ENG_DEBUG(ENG_DEBUG, "Changed Vol Type = %d, Vol Level = %d", tapi_sound_path, volume_level);
2114
2115                         _vc_core_ca_send_event_to_client(pagent, VC_CALL_GET_VOLUME_RESP, tapi_sound_path, volume_level, NULL);
2116                 }
2117                 break;
2118         default:
2119                 CALL_ENG_DEBUG(ENG_DEBUG, "Default: event_type = %d", event_type);
2120                 break;
2121         }
2122         CALL_ENG_DEBUG(ENG_DEBUG, "tapi event(%d) processed done.", event_type);
2123
2124         return;
2125 }
2126
2127 static gboolean __call_vc_outgoingcall_endhandle(call_vc_callagent_state_t *pagent, call_vc_handle call_handle, int type, TelTapiEndCause_t tapi_cause)
2128 {
2129         call_vc_call_objectinfo_t objectInfo;
2130         voice_call_end_cause_type_t endcause_type = 0;
2131
2132         VOICECALL_RETURN_FALSE_IF_FAIL(pagent != NULL);
2133
2134         _vc_core_cm_clear_call_object(&objectInfo);
2135         _vc_core_cm_get_call_object(&pagent->call_manager, call_handle, &objectInfo);
2136
2137         /*Inform Client App about MO Call Disconnect */
2138         _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_OUTGOING_ABORTED);
2139         _vc_core_tapi_event_get_end_cause_type(type, tapi_cause, &endcause_type);
2140         _vc_core_ca_send_event_to_client(pagent, VC_CALL_OUTGOING_END, call_handle, (int)endcause_type, NULL);
2141
2142         /* Response call setup result to SAT if this is SAT call */
2143         if (VC_CALL_ORIG_TYPE_SAT == objectInfo.call_type) {
2144                 /*Cancelled by user */
2145                 if (VC_CALL_STATE_CANCELLED == objectInfo.state) {
2146                         _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_ME_CLEAR_DOWN_BEFORE_CONN);
2147                 } else {        /* Disconnected by Network */
2148
2149                         call_vc_satsetup_info_t *pcall_vc_satcall_info = NULL;
2150
2151                         pcall_vc_satcall_info = (call_vc_satsetup_info_t *) &(pagent->call_manager.setupcall_info.satcall_setup_info);
2152
2153                         if (FALSE == pcall_vc_satcall_info->redial) {
2154                                 /*Send only if SAT redial is not enabled */
2155                                 _vc_core_ca_send_sat_response(pagent, SAT_RQST_SETUP_CALL, CALL_VC_NETWORK_UNABLE_TO_PROCESS_COMMAND);
2156                         }
2157                 }
2158
2159                 /*Free SAT Icon data if available */
2160                 if (pagent->call_manager.setupcall_info.satcall_setup_info.psat_rgb_data != NULL) {
2161                         free(pagent->call_manager.setupcall_info.satcall_setup_info.psat_rgb_data);
2162                         pagent->call_manager.setupcall_info.satcall_setup_info.psat_rgb_data = NULL;
2163                 }
2164         }
2165
2166         /* SS: 1 send, while outgoing is CONNECTING state... */
2167         if (CALL_VC_CA_STATE_SS_WAIT_RELEASE_ALL_ACTIVECALL == pagent->callagent_state) {
2168                 gboolean bActiveCall = _vc_core_cm_isexists_active_call(&pagent->call_manager);
2169                 gboolean bHoldCall = _vc_core_cm_isexists_held_call(&pagent->call_manager);
2170
2171                 if (FALSE == bActiveCall) {
2172                         if (TRUE == bHoldCall) {
2173                                 CALL_ENG_DEBUG(ENG_DEBUG, "Continue SS Action");
2174
2175                                 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_NONE);
2176
2177                                 if (_vc_core_tapi_rqst_retrieve_call(pagent) == TRUE) {
2178                                         _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_UNHOLD);
2179                                 } else {
2180                                         _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
2181                                 }
2182                         } else {
2183                                 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
2184                         }
2185                 } else {
2186                         CALL_ENG_DEBUG(ENG_DEBUG, "active call must not exist!");
2187                         _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_NORMAL);
2188                 }
2189         }
2190
2191         return TRUE;
2192 }
2193
2194 static gboolean __call_vc_incoming_call_end_idle_cb(gpointer puser_data)
2195 {
2196         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)puser_data;
2197         call_vc_handle call_handle = -1;
2198
2199         CALL_ENG_DEBUG(ENG_DEBUG, "Ending the Incoming Call in Idle Callback");
2200         /*Send the Incoming end indication to the client, only if the io state is in VC_INOUT_STATE_INCOME_END */
2201         if (VC_INOUT_STATE_INCOME_END == pagent->io_state) {
2202                 call_handle = _vc_core_cm_get_incoming_call_handle(&pagent->call_manager);
2203                 if (-1 != call_handle) {
2204                         __call_vc_incomingcall_endhandle(pagent, call_handle);
2205                 }
2206         }
2207         return FALSE;
2208 }
2209
2210 static gboolean __call_vc_incomingcall_endhandle(call_vc_callagent_state_t *pagent, call_vc_handle call_handle)
2211 {
2212         CALL_ENG_DEBUG(ENG_DEBUG, "");
2213
2214         CALL_VC_DUMP_CALLDETAILS(&pagent->call_manager);
2215
2216         if (TRUE == _vc_core_ca_send_event_to_client(pagent, VC_CALL_INCOM_END, call_handle, 0, NULL)) {
2217                 CALL_ENG_DEBUG(ENG_DEBUG, "client call back returned TRUE Removing Inomcing call Object");
2218
2219                 /*Remove Call Object Once the Incoming Call Got Ended*/
2220                 _vc_core_cm_remove_call_object(&pagent->call_manager, call_handle);
2221
2222                 CALL_VC_DUMP_CALLDETAILS(&pagent->call_manager);
2223
2224                 /*Finally Move the IO State None*/
2225                 _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_NONE);
2226         }
2227         return TRUE;
2228 }
2229
2230 static gboolean __call_vc_is_callagent_waitstate(call_vc_callagent_state_t *pagent)
2231 {
2232
2233         switch (pagent->callagent_state) {
2234         case CALL_VC_CA_STATE_WAIT_SPLIT:
2235         case CALL_VC_CA_STATE_WAIT_DROP:
2236         case CALL_VC_CA_STATE_WAIT_SWAP:
2237         case CALL_VC_CA_STATE_WAIT_HOLD:
2238         case CALL_VC_CA_STATE_WAIT_UNHOLD:
2239         case CALL_VC_CA_STATE_WAIT_JOIN:
2240         case CALL_VC_CA_STATE_WAIT_TRANSFER_CNF:
2241         case CALL_VC_CA_STATE_WAIT_TRANSFER_CALLEND:
2242         case CALL_VC_CA_STATE_WAIT_RELEASE_ALL_ACTIVECALL:
2243         case CALL_VC_CA_STATE_WAIT_RELEASE_ALL_HOLDCALL:
2244         case CALL_VC_CA_STATE_SS_WAIT_RELEASE_ALL_ACTIVECALL:
2245         case CALL_VC_CA_STATE_WAIT_RELEASE_ALL_CALLS:
2246         case CALL_VC_CA_STATE_WAIT_RELEASE_ALL_CALLS_TO_SETUP:
2247         case CALL_VC_CA_STATE_WAIT_RELEASE_ALL_CALLS_TO_SWITCH_TO_VIDEO_CALL:
2248                 {
2249                         return TRUE;
2250                 }
2251                 break;
2252         default:
2253                 return FALSE;
2254         }
2255 }
2256
2257 /**
2258  * This function checks whether dtmf is possible
2259  *
2260  * @return              This function returns TRUE if dtmf is possible or else FALSE
2261  * @param[in]           pcall_agent                     Pointer to the call agent structure
2262  */
2263 gboolean __vc_core_is_dtmf_possible(call_vc_callagent_state_t *pcall_agent)
2264 {
2265         VOICECALL_RETURN_FALSE_IF_FAIL(pcall_agent != NULL);
2266         CALL_ENG_DEBUG(ENG_DEBUG, "");
2267
2268         if (VC_INOUT_STATE_NONE != pcall_agent->io_state) {
2269                 CALL_ENG_DEBUG(ENG_DEBUG, "__vc_core_is_dtmf_possible, io_state not idle");
2270                 return FALSE;
2271         }
2272
2273         if (CALL_VC_CA_STATE_NORMAL != pcall_agent->callagent_state) {
2274                 CALL_ENG_DEBUG(ENG_DEBUG, "__vc_core_is_dtmf_possible, callagent_state not idle");
2275                 return FALSE;
2276         }
2277
2278         if (FALSE == _vc_core_cm_isexists_active_call(&pcall_agent->call_manager)) {
2279                 CALL_ENG_DEBUG(ENG_DEBUG, "NO Active Calls available to send DTMF");
2280                 return FALSE;
2281         }
2282
2283         CALL_ENG_DEBUG(ENG_DEBUG, "DTMF Possible");
2284         return TRUE;
2285 }
2286
2287 /**
2288  * This function checks the voicecall engine's idle status and send VC_ACTION_NO_ACTIVE_TASK to client if engine is idle
2289  *
2290  * @return              void
2291  * @param[in]           pcall_agent     Pointer to the call agent structure
2292  */
2293 void __vc_core_check_engine_active_task(call_vc_callagent_state_t *pcall_agent)
2294 {
2295         VOICECALL_RETURN_IF_FAIL(pcall_agent != NULL);
2296         if (_vc_core_ca_check_end(pcall_agent)) {
2297                 CALL_ENG_DEBUG(ENG_DEBUG, "Engine is Idle, Informing the Client");
2298                 _vc_core_ca_send_event_to_client(pcall_agent, VC_ACTION_NO_ACTIVE_TASK, 0, 0, NULL);
2299         }
2300 }
2301
2302 /**
2303 * This function ends only the connected call corresponding to the given call handle
2304 *
2305 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2306 * @param[in]    pvoicecall_agent        Handle to voicecall engine
2307 * @param[in]    call_handle             Call handle of the call to be ended
2308 * @remarks              pvoicecall_agent cannot be NULL
2309 * @see                  See also following functions
2310 *                               - _vc_core_engine_make_call
2311 *                               - _vc_core_engine_end_call
2312 *                               - _vc_core_engine_end_call_bycallId
2313 */
2314 voicecall_error_t _vc_core_engine_end_call_byhandle(voicecall_engine_t *pvoicecall_agent, int call_handle)
2315 {
2316         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2317         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2318         VOICECALL_RETURN_VALUE_IF_FAIL(call_handle >= 0, ERROR_VOICECALL_INVALID_ARGUMENTS);
2319
2320         return (TRUE == _vc_core_tapi_rqst_end_call_by_callhandle(pagent, call_handle)) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
2321 }
2322
2323 /**
2324 * This function ends a call corresponding to the given call ID
2325 *
2326 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2327 * @param[in]    pvoicecall_agent        Handle to voicecall engine
2328 * @param[in]    call_id                 call id of the call to be ended
2329 * @remarks              pvoicecall_agent cannot be NULL
2330 *                               call_id shall take only values between 1 to 7
2331 * @see                  See also following functions
2332 *                               - _vc_core_engine_make_call
2333 *                               - _vc_core_engine_end_call
2334 *                               - _vc_core_engine_end_call_byhandle
2335 */
2336 voicecall_error_t _vc_core_engine_end_call_bycallId(voicecall_engine_t *pvoicecall_agent, int call_id)
2337 {
2338         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2339         call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
2340         call_vc_groupstate_t call_group_state = CALL_VC_GROUP_STATE_NONE;
2341
2342         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2343         VOICECALL_RETURN_VALUE_IF_FAIL((call_id >= 1 && call_id <= 7), ERROR_VOICECALL_INVALID_ARGUMENTS);
2344
2345         call_handle = _vc_core_cm_get_call_handle_ingroup_bycallId(&pagent->call_manager, call_id);
2346         if (VC_TAPI_INVALID_CALLHANDLE == call_handle) {
2347                 return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
2348         }
2349
2350         call_group_state = _vc_core_cm_get_group_state_callid(&pagent->call_manager, call_id);
2351         if (CALL_VC_GROUP_STATE_ACTIVE == call_group_state) {
2352
2353                 if (-1 == _vc_core_cm_get_active_group_index(&pagent->call_manager)) {
2354                         return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
2355                 }
2356
2357                 if (TRUE == _vc_core_tapi_rqst_end_call_by_callhandle(pagent, call_handle)) {
2358                         _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_DROP);
2359                         return ERROR_VOICECALL_NONE;
2360                 }
2361         } else if (CALL_VC_GROUP_STATE_HOLD == call_group_state) {
2362                 int held_group_member_num = 0;
2363                 int held_group_index = -1;
2364
2365                 held_group_index = _vc_core_cm_get_held_group_index(&pagent->call_manager);
2366                 if (-1 == held_group_index) {
2367                         return FALSE;
2368                 }
2369
2370                 held_group_member_num = _vc_core_cm_get_member_count_ingroup(&pagent->call_manager, held_group_index);
2371                 if (held_group_member_num > 1) {
2372                         /*Individual calls cannot be ended when the conf call in held state */
2373                         return ERROR_VOICECALL_OPERATION_NOT_ALLOWED;
2374                 }
2375
2376                 if (TRUE == _vc_core_tapi_rqst_end_call_by_callhandle(pagent, call_handle)) {
2377                         _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_DROP);
2378                         return ERROR_VOICECALL_NONE;
2379                 }
2380         }
2381
2382         return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
2383 }
2384
2385 /**
2386 * This function ends the call according to the given end call type
2387 *
2388 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2389 * @param[in]    pvoicecall_agent        Handle to voicecall engine
2390 * @param[in]    end_call_type           End Call Type
2391 * @remarks              pvoicecall_agent cannot be NULL
2392 * @see                  See also following functions
2393 *                               - _vc_core_engine_make_call
2394 *                               - _vc_core_engine_end_call_byhandle
2395 *                               - _vc_core_engine_end_call_bycallId
2396 *                               .
2397 */
2398 voicecall_error_t _vc_core_engine_end_call(voicecall_engine_t *pvoicecall_agent, _vc_core_engine_end_call_type_t end_call_type)
2399 {
2400         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2401         gboolean bret_val = FALSE;
2402
2403         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2404
2405         /*If Call Agent is waiting for any of the release event then ignore the end call request */
2406         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)) {
2407                 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
2408         }
2409
2410         CALL_ENG_DEBUG(ENG_DEBUG, "end_call_type = %d", end_call_type);
2411
2412         switch (end_call_type) {
2413         case VC_END_OUTGOING_CALL:
2414                 {
2415                         bret_val = _vc_core_tapi_rqst_release_outgoing_call(pagent);
2416                 }
2417                 break;
2418         case VC_END_INCOMING_CALL:
2419                 {
2420                         bret_val = _vc_core_tapi_rqst_release_incoming_call(pagent);
2421                 }
2422                 break;
2423         case VC_END_ACTIVE_OR_HELD_CALLS:
2424                 {
2425                         bret_val = _vc_core_tapi_rqst_end_call(pagent);
2426                 }
2427                 break;
2428         case VC_END_ALL_ACTIVE_CALLS:
2429                 {
2430                         bret_val = _vc_core_ca_end_active_calls(pagent);
2431                 }
2432                 break;
2433         case VC_END_ALL_HELD_CALLS:
2434                 {
2435                         bret_val = _vc_core_ca_end_held_calls(pagent);
2436                 }
2437                 break;
2438         case VC_END_ALL_CALLS:
2439                 {
2440                         bret_val = _vc_core_ca_end_all_calls(pagent);
2441                 }
2442                 break;
2443         default:
2444                 return ERROR_VOICECALL_INVALID_CALL_TYPE;
2445         }
2446
2447         return (TRUE == bret_val) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_INCOMPLETE;
2448 }
2449
2450 /**
2451 * This function does the explicit call transfer
2452 *
2453 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2454 * @param[in]    pvoicecall_agent        Handle to voicecall engine
2455 * @remarks              pvoicecall_agent cannot be NULL
2456 */
2457 voicecall_error_t _vc_core_engine_transfer_calls(voicecall_engine_t *pvoicecall_agent)
2458 {
2459         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2460
2461         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2462
2463         if (CALL_VC_CA_STATE_WAIT_TRANSFER_CNF == pagent->callagent_state) {
2464                 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
2465         } else if (FALSE == _vc_core_ca_is_transfer_call_possible(pagent)) {
2466                 return ERROR_VOICECALL_TRANSFER_CALL_NOT_POSSIBLE;
2467         } else {
2468                 if (TRUE == _vc_core_tapi_rqst_transfer_call(pagent)) {
2469                         _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_TRANSFER_CNF);
2470                         return ERROR_VOICECALL_NONE;
2471                 }
2472         }
2473
2474         return ERROR_VOICECALL_TRANSFER_FAILED;
2475 }
2476
2477 /**
2478 * This function swaps the active and held calls if any available
2479 *
2480 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2481 * @param[in]    pvoicecall_agent        Handle to voicecall engine
2482 * @remarks              pvoicecall_agent cannot be NULL
2483 * @see                  See also the following APIs
2484 *                               - _vc_core_engine_hold_call
2485 *                               - _vc_core_engine_retrieve_call
2486 *
2487 */
2488 voicecall_error_t _vc_core_engine_swap_calls(voicecall_engine_t *pvoicecall_agent)
2489 {
2490         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2491         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2492
2493         /*If call agent is in any of the wait states, then ignore the request */
2494         if (TRUE == __call_vc_is_callagent_waitstate(pagent)) {
2495                 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
2496         }
2497
2498         if (TRUE == _vc_core_tapi_rqst_swap_calls(pagent)) {
2499 #ifdef SWAP_SUPPORT
2500                 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_SWAP_HOLD_OR_ACTIVATE);
2501 #else
2502                 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_SWAP);
2503 #endif
2504                 return ERROR_VOICECALL_NONE;
2505         }
2506
2507         return ERROR_VOICECALL_SWAP_FAILED;
2508 }
2509
2510 /**
2511 * This function puts the active call if any on hold
2512 *
2513 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2514 * @param[in]    pvoicecall_agent                Handle to voicecall engine
2515 * @remarks              pvoicecall_agent cannot be NULL
2516 * @see                  voicecall_retreive_call
2517 */
2518 voicecall_error_t _vc_core_engine_hold_call(voicecall_engine_t *pvoicecall_agent)
2519 {
2520         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2521         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2522
2523         if (TRUE == __call_vc_is_callagent_waitstate(pagent)) {
2524                 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
2525         }
2526 #ifdef _CPHS_DEFINED_
2527         if (TRUE == _vc_core_svcall_cphs_csp_get_status(pagent, VC_CPHS_CSP_HOLD)) {
2528                 if (TRUE == _vc_core_tapi_rqst_hold_call(pagent)) {
2529                         _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_HOLD);
2530                         return ERROR_VOICECALL_NONE;
2531                 }
2532         } else {
2533                 return ERROR_VOICECALL_HOLD_NOT_SUPPORTED;
2534         }
2535 #else
2536         if (TRUE == _vc_core_tapi_rqst_hold_call(pagent)) {
2537                 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_HOLD);
2538                 return ERROR_VOICECALL_NONE;
2539         }
2540 #endif
2541         return ERROR_VOICECALL_HOLD_FAILED;
2542 }
2543
2544 /**
2545 * This function retrieves/activates the held call
2546 *
2547 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2548 * @param[in]    pvoicecall_agent        Handle to voicecall engine
2549 * @remarks              pvoicecall_agent cannot be NULL
2550 * @see                  _vc_core_engine_hold_call
2551 */
2552 voicecall_error_t _vc_core_engine_retrieve_call(voicecall_engine_t *pvoicecall_agent)
2553 {
2554         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2555
2556         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2557
2558         if (TRUE == __call_vc_is_callagent_waitstate(pagent)) {
2559                 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
2560         }
2561
2562         if (TRUE == _vc_core_tapi_rqst_retrieve_call(pagent)) {
2563                 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_UNHOLD);
2564                 return ERROR_VOICECALL_NONE;
2565         }
2566         return ERROR_VOICECALL_RETREIVE_FAILED;
2567 }
2568
2569 /**
2570 * This function sets up a conference beween the currently available active and held calls
2571 *
2572 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2573 * @param[in]    pvoicecall_agent                Handle to voicecall engine
2574 * @remarks              pvoicecall_agent cannot be NULL
2575 * @see                  See also the following APIs
2576 *                               - _vc_core_engine_private_call
2577 *                               - _vc_core_engine_private_call_by_callid
2578 *
2579 */
2580 voicecall_error_t _vc_core_engine_setup_conference(voicecall_engine_t *pvoicecall_agent)
2581 {
2582         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2583
2584         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2585
2586         /*If call agent is in any of the wait states, then ignore the request */
2587         if (CALL_VC_CA_STATE_WAIT_JOIN == pagent->callagent_state) {
2588                 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
2589         } else if (FALSE == _vc_core_ca_is_conf_call_possible(pagent)) {
2590                 return ERROR_VOICECALL_CONF_NOT_POSSIBLE;
2591         } else {
2592                 if (TRUE == _vc_core_tapi_rqst_join_calls(pagent)) {
2593                         _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_JOIN);
2594                         return ERROR_VOICECALL_NONE;
2595                 }
2596         }
2597         return ERROR_VOICECALL_SETUP_CONF_FAILED;
2598 }
2599
2600 /**
2601 * This function makes a private call to the call member corressponding to the given call id.
2602 *
2603 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2604 * @param[in]    pvoicecall_agent        Handle to voicecall engine
2605 * @param[in]    call_id                 Call ID of the call to be made private
2606 * @remarks              pvoicecall_agent cannot be NULL
2607 * @see                  See also the following APIs
2608 *                               - _vc_core_engine_setup_conference
2609 *                               - _vc_core_engine_private_call
2610 *
2611 */
2612 voicecall_error_t _vc_core_engine_private_call_by_callid(voicecall_engine_t *pvoicecall_agent, int call_id)
2613 {
2614         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2615
2616         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2617         VOICECALL_RETURN_VALUE_IF_FAIL((call_id >= 1 && call_id <= 7), ERROR_VOICECALL_INVALID_ARGUMENTS);
2618
2619         if (CALL_VC_CA_STATE_WAIT_SPLIT == pagent->callagent_state) {
2620                 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
2621         } else if (FALSE == _vc_core_ca_is_private_call_possible(pagent)) {
2622                 return ERROR__vc_core_engine_private_call_NOT_POSSIBLE;
2623         } else {
2624                 call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
2625
2626                 call_handle = _vc_core_cm_get_call_handle_ingroup_bycallId(&pagent->call_manager, call_id);
2627
2628                 if (VC_TAPI_INVALID_CALLHANDLE != call_handle) {
2629                         return (TRUE == _vc_core_tapi_rqst_private_call(pagent, call_handle)) ? ERROR_VOICECALL_NONE : ERROR__vc_core_engine_private_call_FAILED;
2630                 }
2631         }
2632
2633         return ERROR_VOICECALL_INVALID_CALLID;
2634 }
2635
2636 /**
2637 * This function makes a private call to the given call member from the currently available active conference call
2638 *
2639 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2640 * @param[in]    pvoicecall_agent        Handle to voicecall engine
2641 * @param[in]    call_handle             call handle of the call to be made private
2642 * @remarks              pvoicecall_agent cannot be NULL
2643 * @see                  See also the following APIs
2644 *                               - _vc_core_engine_setup_conference
2645 *                               - _vc_core_engine_private_call_by_callid
2646 *
2647 */
2648 voicecall_error_t _vc_core_engine_private_call(voicecall_engine_t *pvoicecall_agent, int call_handle)
2649 {
2650         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2651
2652         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2653         VOICECALL_RETURN_VALUE_IF_FAIL(call_handle >= 0, ERROR_VOICECALL_INVALID_ARGUMENTS);
2654
2655         if (CALL_VC_CA_STATE_WAIT_SPLIT == pagent->callagent_state) {
2656                 return ERROR_VOICECALL_PREVIOUS_REQUEST_IN_PROGRESS;
2657         } else if (FALSE == _vc_core_ca_is_private_call_possible(pagent)) {
2658                 return ERROR__vc_core_engine_private_call_NOT_POSSIBLE;
2659         }
2660
2661         return (TRUE == _vc_core_tapi_rqst_private_call(pagent, call_handle)) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_REQUEST_FAILED;
2662 }
2663
2664 /**
2665 * This function rejects the incoming call if any
2666 *
2667 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2668 * @param[in]    pvoicecall_agent        Handle to voicecall engine
2669 * @param[in]    budub                   User Determined User Busy - TRUE, Else - FALSE
2670 * @exception            In case of exceptions return value contains appropriate error code.
2671 * @remarks              pvoicecall_agent cannot be NULL
2672 * @see                  _vc_core_engine_answer_call
2673 */
2674 voicecall_error_t _vc_core_engine_reject_call(voicecall_engine_t *pvoicecall_agent, gboolean budub)
2675 {
2676         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2677         int error_code = -1;
2678         gboolean ret = FALSE;
2679
2680         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2681
2682         ret = _vc_core_tapi_rqst_reject_mt_call(pagent, budub, &error_code);
2683
2684         return (TRUE == ret) ? ERROR_VOICECALL_NONE : error_code;
2685 }
2686
2687 /**
2688 * This function answers a call according to the given answer type
2689 *
2690 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2691 * @param[in]    pvoicecall_agent        Handle to voicecall engine
2692 * @param[in]    answer_type             The answer type to be used
2693 * @remarks              pvoicecall_agent and pcall_handle cannot be NULL
2694 * @see                  _vc_core_engine_reject_call
2695 */
2696 voicecall_error_t _vc_core_engine_answer_call(voicecall_engine_t *pvoicecall_agent, voicecall_answer_type_t answer_type)
2697 {
2698         call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
2699         int error_code = 0;
2700         gboolean ret = FALSE;
2701
2702         VOICECALL_RETURN_VALUE_IF_FAIL(pcall_agent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2703 #ifdef RELEASE_ALL_AND_ACCEPT_SUPPORT
2704         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(answer_type, VC_ANSWER_NORMAL, VC_ANSWER_RELEASE_ALL_AND_ACCEPT, ERROR_VOICECALL_INVALID_ARGUMENTS);
2705 #else
2706         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(answer_type, VC_ANSWER_NORMAL, VC_ANSWER_RELEASE_HOLD_AND_ACCEPT, ERROR_VOICECALL_INVALID_ARGUMENTS);
2707 #endif
2708         ret = _vc_core_tapi_rqst_answer_call(pcall_agent, answer_type, &error_code);
2709
2710         return (TRUE == ret) ? ERROR_VOICECALL_NONE : error_code;
2711 }
2712
2713 /**
2714 * This function sends the given dtmf digits
2715 *
2716 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2717 * @param[in]    pvoicecall_agent        Handle to voicecall engine
2718 * @param[in]    pdtmf_string            dtmf digits to be sent
2719 * @remarks              pvoicecall_agent and pdtmf_string cannot be NULL
2720 *                               pdtmf_string shall only accept strings containing the digit value (0-9,A,B,C,D,*,#)
2721 *
2722 */
2723 voicecall_error_t _vc_core_engine_send_dtmf(voicecall_engine_t *pvoicecall_agent, char *pdtmf_string)
2724 {
2725         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2726
2727         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2728         VOICECALL_RETURN_VALUE_IF_FAIL(pdtmf_string != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2729
2730         if (FALSE == _vc_core_util_isvalid_dtmf_number(pdtmf_string)) {
2731                 _vc_core_ca_send_event_to_client(pagent, VC_ERROR_OCCURED, ERROR_VOICECALL_INVALID_DTMF_CHAR, -1, NULL);
2732                 return ERROR_VOICECALL_INVALID_DTMF_CHAR;
2733         }
2734
2735         return (TRUE == _vc_core_tapi_rqst_start_dtmf(pagent, pdtmf_string)) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_DTMF_FAILED;
2736 }
2737
2738 /**
2739 * This function sends response to sat based on the given sat response type
2740 *
2741 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2742 * @param[in]    pvoicecall_agent                Handle to voicecall engine
2743 * @param[in]    sat_rqst_resp_type  sat rqst/response type sent by client
2744 * @param[in]    sat_response_type  sat response type to be sent to SAT
2745 */
2746 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)
2747 {
2748         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2749         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2750         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(sat_rqst_resp_type, SAT_RQST_SETUP_CALL, SAT_RESP_SETUP_CALL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2751         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);
2752
2753         return (TRUE == _vc_core_ca_send_sat_response(pagent, sat_rqst_resp_type, sat_response_type)) ? ERROR_VOICECALL_NONE : ERROR_VOICECALL_REQUEST_FAILED;
2754 }
2755
2756 /**
2757 * This function finalizes the voiecall engine and removes all allocated resources
2758 *
2759 * @return               nothing
2760 * @param[in]            pvoicecall_agent        Handle to Voicecall Engine
2761 * @remarks              pvoicecall_agent cannot be NULL
2762 */
2763 void _vc_core_engine_engine_finish(voicecall_engine_t *pvoicecall_agent)
2764 {
2765         call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
2766         int error_code = 0;
2767         int index = 0;
2768
2769         VOICECALL_RETURN_IF_FAIL(pvoicecall_agent != NULL);
2770
2771         /*Unsubscribe Events */
2772         CALL_ENG_DEBUG(ENG_DEBUG, "Unsubscribing Events");
2773         for (index = 0; index < CALL_VC_TAPI_SUBSCRIPTION_MAX; index++) {
2774                 error_code = tel_deregister_event(pcall_agent->subscription_id[index]);
2775                 if (error_code != TAPI_API_SUCCESS) {
2776                         CALL_ENG_DEBUG(ENG_DEBUG, "tel_deregister_event failed. sub id is %d error_code is %d", pcall_agent->subscription_id[index], error_code);
2777                         break;
2778                 }
2779         }
2780
2781         tel_deinit();
2782
2783         VOICECALL_RETURN_IF_FAIL(pcall_agent != NULL);
2784         _vc_core_ca_finish_agent(pcall_agent);
2785 }
2786
2787 #ifdef _SAT_MENU_
2788 /**
2789 * This function requests SAT Engine to setup SIM services Menu
2790 *
2791 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2792 * @param[in]            pvoicecall_agent                Handle to Voicecall Engine
2793 * @remarks              Voicecall Engine only requests the SAT engine to display the menu.
2794 */
2795 voicecall_error_t voicecall_request_sat_menu(voicecall_engine_t *pvoicecall_agent)
2796 {
2797         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2798         TelSatSetupMenuInfo_t sim_menu;
2799         
2800         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2801
2802         CALL_ENG_DEBUG(ENG_DEBUG, "");
2803         memset(&sim_menu, 0, sizeof(TelSatSetupMenuInfo_t));
2804
2805         if (FALSE == TelTapiSatGetMainMenuList(&sim_menu)) {
2806                 CALL_ENG_DEBUG(ENG_DEBUG, "TelTapiSatGetMainMenuList failed");
2807                 return ERROR_VOICECALL_REQUEST_FAILED;
2808         }
2809
2810         return ERROR_VOICECALL_NONE;
2811 }
2812
2813 /**
2814 * This function retreives the SIM Menu Title from the SAT Engine
2815 *
2816 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2817 * @param[in]            pvoicecall_agent                Handle to Voicecall Engine
2818 * @param[out]   title                                   contains the sat menu title on sucess
2819 */
2820 voicecall_error_t voicecall_request_sat_menu_title(voicecall_engine_t *pvoicecall_agent, char *title)
2821 {
2822         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2823         TelSatMainMenuTitleInfo_t sat_menu_title;
2824
2825         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2826         VOICECALL_RETURN_VALUE_IF_FAIL(title != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2827
2828         CALL_ENG_DEBUG(ENG_DEBUG, "");
2829
2830         memset(&sat_menu_title, 0, sizeof(TelSatMainMenuTitleInfo_t));
2831
2832         if (TRUE == TelTapiSatGetMainMenuTitle(&sat_menu_title)) {
2833                 if (TRUE == sat_menu_title.bIsMainMenuPresent) {
2834                         strcpy(title, (char *)sat_menu_title.mainMenuTitle.string);
2835                         return ERROR_VOICECALL_NONE;
2836                 }
2837         }
2838
2839         return ERROR_VOICECALL_REQUEST_FAILED;
2840 }
2841 #endif
2842
2843 /**
2844 * This function prepares the engine for the redial call. It preserves the previsouly made call object to used for the next make call
2845 *
2846 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2847 * @param[in]            pvoicecall_agent        Handle to Voicecall Engine
2848 * @param[in]            call_handle             call handle
2849 * @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
2850 *                               be used for the redialling. Application has to just use _vc_core_engine_make_call API to redial the call
2851 */
2852 voicecall_error_t _vc_core_engine_prepare_redial(voicecall_engine_t *pvoicecall_agent, int call_handle)
2853 {
2854         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2855         call_vc_call_objectinfo_t call_object;
2856         int mo_call_handle = -1;
2857
2858         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2859         VOICECALL_RETURN_VALUE_IF_FAIL(call_handle >= 0, ERROR_VOICECALL_INVALID_ARGUMENTS);
2860
2861         /*Check the validity of the call handle */
2862         mo_call_handle = _vc_core_cm_get_outgoing_call_handle(&pagent->call_manager);
2863         if ((mo_call_handle == -1) || (mo_call_handle != call_handle)) {
2864                 return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
2865         }
2866
2867         if (FALSE == _vc_core_cm_get_call_object(&pagent->call_manager, call_handle, &call_object)) {
2868                 return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
2869         }
2870
2871         /*Set the callobject status */
2872         call_object.state = VC_CALL_STATE_REDIAL;
2873
2874         /*Reintialize Call ID */
2875         call_object.call_id = 0;
2876         _vc_core_cm_set_call_object(&pagent->call_manager, &call_object);
2877
2878         /*Set Engine IO State */
2879         _vc_core_ca_change_inout_state(pagent, VC_INOUT_STATE_OUTGOING_SHOW_REDIALCAUSE);
2880
2881         /*Abthul:todo Set SAT Redial Data */
2882
2883         return ERROR_VOICECALL_NONE;
2884 }
2885
2886 #ifdef _OLD_SAT_
2887 /**
2888 * This function checks whether SAT redial duration is valid
2889 *
2890 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2891 * @param[in]            pvoicecall_agent        Handle to Voicecall Engine
2892 * @param[out]   bredial_duration        Contains TRUE if SAT redial duration is enabled, FALSE otherwise
2893 * @remarks              pvoicecall_agent and bredial_duration cannot be NULL
2894 */
2895 voicecall_error_t voicecall_get_sat_redial_duration_status(voicecall_engine_t *pvoicecall_agent, gboolean * bredial_duration)
2896 {
2897         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2898         call_vc_satsetup_info_t *pcall_vc_satcall_info = NULL;
2899
2900         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2901         VOICECALL_RETURN_VALUE_IF_FAIL(bredial_duration != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2902
2903         pcall_vc_satcall_info = (call_vc_satsetup_info_t *) &(pagent->call_manager.setupcall_info.satcall_setup_info);
2904
2905         CALL_ENG_DEBUG(ENG_DEBUG, "SAT Redial Duration Status= %d", pcall_vc_satcall_info->bduration);
2906
2907         *bredial_duration = pcall_vc_satcall_info->bduration;
2908         return ERROR_VOICECALL_NONE;
2909 }
2910
2911 /**
2912 * This function sets the current duration and retrieves the modified remaining SAT redial duration
2913 *
2914 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2915 * @param[in]    pvoicecall_agent                Handle to Voicecall Engine
2916 * @param[out]   remaining_duration              remaining sat duration
2917 * @remarks              pvoicecall_agent and remaining_duration cannot be NULL
2918 */
2919 voicecall_error_t voicecall_get_set_sat_remaining_duration(voicecall_engine_t *pvoicecall_agent, long *remaining_duration)
2920 {
2921         call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
2922         call_vc_satsetup_info_t *pcall_vc_satcall_info = NULL;
2923
2924         VOICECALL_RETURN_VALUE_IF_FAIL(pcall_agent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2925         VOICECALL_RETURN_VALUE_IF_FAIL(remaining_duration != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2926
2927         pcall_vc_satcall_info = (call_vc_satsetup_info_t *) &(pcall_agent->call_manager.setupcall_info.satcall_setup_info);
2928         *remaining_duration = pcall_vc_satcall_info->remaining_duration;
2929         CALL_ENG_DEBUG(ENG_DEBUG, "Remaining Duration: %ld", *remaining_duration);
2930
2931         return ERROR_VOICECALL_NONE;
2932 }
2933 #endif
2934
2935 voicecall_error_t _vc_core_engine_get_sat_dtmf_hidden_mode(voicecall_engine_t *pvoicecall_agent, gboolean *bhidden_mode)
2936 {
2937         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
2938         call_vc_satsetup_info_t *pcall_vc_satcall_info = NULL;
2939
2940         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2941         VOICECALL_RETURN_VALUE_IF_FAIL(bhidden_mode != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2942
2943         pcall_vc_satcall_info = (call_vc_satsetup_info_t *) &(pagent->call_manager.setupcall_info.satcall_setup_info);
2944
2945         CALL_ENG_DEBUG(ENG_DEBUG, "SAT Hidden Mode= %d", pcall_vc_satcall_info->satengine_dtmf_data.bIsHiddenMode);
2946
2947         *bhidden_mode = pcall_vc_satcall_info->satengine_dtmf_data.bIsHiddenMode;
2948         return ERROR_VOICECALL_NONE;
2949 }
2950
2951 /**
2952 * This function changes the voice audio path
2953 *
2954 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
2955 * @param[in]            pvoicecall_agent                Handle to Voicecall Engine
2956 * @param[in]            audio_path              audio path to be changed
2957 * @remarks              pvoicecall_agent cannot be NULL
2958 */
2959 voicecall_error_t _vc_core_engine_change_audio_path(voicecall_engine_t *pvoicecall_agent, voicecall_audio_path_t audio_path)
2960 {
2961         call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
2962         tapi_sound_audio_path_t tapi_audio_path = TAPI_SOUND_HANDSET;
2963         /*Enum for encapsulating errors from TAPI Lib */
2964         TapiResult_t tapi_error = TAPI_API_SUCCESS;
2965         int ReqId = VC_RQSTID_DEFAULT;
2966
2967         VOICECALL_RETURN_VALUE_IF_FAIL(pcall_agent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
2968
2969         /*Voicecall Path Should not be modified if calls are not available */
2970         if (_vc_core_cm_get_call_member_count(&pcall_agent->call_manager) <= 0) {
2971                 return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
2972         }
2973
2974         switch (audio_path) {
2975         case VC_AUDIO_PATH_HANDSET:
2976                 {
2977                         tapi_audio_path = TAPI_SOUND_HANDSET;
2978                 }
2979                 break;
2980         case VC_AUDIO_PATH_HEADSET:
2981                 {
2982                         tapi_audio_path = TAPI_SOUND_HEADSET;
2983                 }
2984                 break;
2985         case VC_AUDIO_PATH_HANDSFREE:
2986                 {
2987                         tapi_audio_path = TAPI_SOUND_HANDSFREE;
2988                 }
2989                 break;
2990         case VC_AUDIO_PATH_BLUETOOTH:
2991                 {
2992                         tapi_audio_path = TAPI_SOUND_BLUETOOTH;
2993                 }
2994                 break;
2995         case VC_AUDIO_PATH_STEREO_BLUETOOTH:
2996                 {
2997                         tapi_audio_path = TAPI_SOUND_STEREO_BLUETOOTH;
2998                 }
2999                 break;
3000         case VC_AUDIO_PATH_SPK_PHONE:
3001                 {
3002                         tapi_audio_path = TAPI_SOUND_SPK_PHONE;
3003                 }
3004                 break;
3005         case VC_AUDIO_PATH_HEADSET_3_5PI:
3006                 {
3007                         tapi_audio_path = TAPI_SOUND_HEADSET_3_5PI;
3008                 }
3009                 break;
3010         default:
3011                 {
3012                         CALL_ENG_DEBUG(ENG_DEBUG, "Invalid audio path");
3013                         return ERROR_VOICECALL_INVALID_ARGUMENTS;
3014                 }
3015                 break;
3016         }
3017
3018         CALL_ENG_DEBUG(ENG_DEBUG, "tapi_audio_path: %d", tapi_audio_path);
3019         tapi_error = tel_set_sound_path(tapi_audio_path, &ReqId);
3020
3021         if (tapi_error != TAPI_API_SUCCESS) {
3022                 CALL_ENG_DEBUG(ENG_DEBUG, "tel_set_sound_path error: %d", tapi_error);
3023                 return ERROR_VOICECALL_TAPI_ERROR;
3024         }
3025
3026         return ERROR_VOICECALL_NONE;
3027 }
3028
3029 voicecall_error_t _vc_core_engine_set_audio_mute(voicecall_engine_t *pvoicecall_agent, gboolean bmute_audio)
3030 {
3031         TapiResult_t error = TAPI_API_SUCCESS;
3032         tapi_sound_mic_mute_t micmute_set = TAPI_SOUND_MIC_UNMUTE;
3033         int req_id = VC_RQSTID_DEFAULT;
3034
3035         micmute_set = (TRUE == bmute_audio) ? TAPI_SOUND_MIC_MUTE : TAPI_SOUND_MIC_UNMUTE;
3036
3037         error = tel_set_sound_mute_status(micmute_set, &req_id);
3038
3039         if (error != TAPI_API_SUCCESS) {
3040                 CALL_ENG_DEBUG(ENG_DEBUG, "tel_set_sound_mute_status Error: %d", error);
3041                 return ERROR_VOICECALL_TAPI_ERROR;
3042         }
3043
3044         CALL_ENG_DEBUG(ENG_DEBUG, "End");
3045         return ERROR_VOICECALL_NONE;
3046 }
3047
3048 /**
3049 * This function sets the voice call audio volume for the given audio path type
3050 *
3051 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
3052 * @param[in]            pvoicecall_agent                Handle to Voicecall Engine
3053 * @param[in]            audio_path_type         audio path for the volume to be set
3054 * @param[in]            vol_level                       volume level
3055 * @remarks              pvoicecall_agent cannot be NULL
3056 */
3057 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)
3058 {
3059         call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
3060         /*Enum for encapsulating errors from TAPI Lib */
3061         TapiResult_t error = TAPI_API_SUCCESS;
3062         tapi_sound_volume_control_t vol_control;
3063         int ReqId = VC_RQSTID_DEFAULT;
3064
3065         CALL_ENG_DEBUG(ENG_DEBUG, "Start! path(%d), volume(%d)", audio_path_type, vol_level);
3066
3067         VOICECALL_RETURN_VALUE_IF_FAIL(pcall_agent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
3068         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(audio_path_type, VC_AUDIO_PATH_HANDSET, VC_AUDIO_PATH_HEADSET_3_5PI, ERROR_VOICECALL_INVALID_ARGUMENTS);
3069         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(vol_level, VC_AUDIO_VOLUME_LEVEL_0, VC_AUDIO_VOLUME_LEVEL_9, ERROR_VOICECALL_INVALID_ARGUMENTS);
3070
3071         /*Ignore the request if calls are not available */
3072         if (_vc_core_cm_get_call_member_count(&pcall_agent->call_manager) <= 0) {
3073                 CALL_ENG_DEBUG(ENG_DEBUG, "End");
3074                 return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
3075         }
3076
3077         vol_control.volume = vol_level;
3078         switch (audio_path_type) {
3079         case VC_AUDIO_PATH_HEADSET:
3080                 vol_control.vol_type = TAPI_SOUND_VOL_HEADSET_VOICE;
3081                 break;
3082         case VC_AUDIO_PATH_BLUETOOTH:
3083         case VC_AUDIO_PATH_STEREO_BLUETOOTH:
3084                 vol_control.vol_type = TAPI_SOUND_VOL_BT_VOICE;
3085                 break;
3086         case VC_AUDIO_PATH_SPK_PHONE:
3087                 vol_control.vol_type = TAPI_SOUND_VOL_SPK_PHONE;
3088                 break;
3089         default:
3090                 vol_control.vol_type = TAPI_SOUND_VOL_VOICE;
3091                 break;
3092         }
3093
3094         error = tel_set_sound_volume_info(vol_control, &ReqId);
3095
3096         if (error != TAPI_API_SUCCESS) {
3097                 CALL_ENG_DEBUG(ENG_DEBUG, "Tapi API Error: %d", error);
3098                 return ERROR_VOICECALL_TAPI_ERROR;
3099         }
3100
3101         CALL_ENG_DEBUG(ENG_DEBUG, "End");
3102         return ERROR_VOICECALL_NONE;
3103 }
3104
3105 /**
3106 * This function retreives the voice call audio volume for the given audio path type
3107 *
3108 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
3109 * @param[in]            pvoicecall_agent                Handle to Voicecall Engine
3110 * @param[in]            audio_path_type         audio path for the volume to be retreived
3111 * @remarks              pvoicecall_agent cannot be NULL
3112 *                               The audio volume level will be send as a response with the below details
3113 *                               event   - VC_CALL_GET_VOLUME_RESP
3114 *                               param1  - audio_path_type
3115 *                               param2   - volume level
3116 *                               param3   - NULL
3117 */
3118 voicecall_error_t _vc_core_engine_get_audio_volume(voicecall_engine_t *pvoicecall_agent, voicecall_audio_path_t audio_path_type)
3119 {
3120         call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
3121         TapiResult_t error = TAPI_API_SUCCESS;
3122         tapi_sound_volume_type_t volume_type = TAPI_SOUND_VOL_VOICE;
3123         int ReqId = VC_RQSTID_DEFAULT;
3124
3125         VOICECALL_RETURN_VALUE_IF_FAIL(pcall_agent != NULL, ERROR_VOICECALL_INVALID_ARGUMENTS);
3126         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(audio_path_type, VC_AUDIO_PATH_HANDSET, VC_AUDIO_PATH_HEADSET_3_5PI, ERROR_VOICECALL_INVALID_ARGUMENTS);
3127
3128         /*Ignore the request if calls are not available */
3129         if (_vc_core_cm_get_call_member_count(&pcall_agent->call_manager) <= 0) {
3130                 return ERROR_VOICECALL_CALL_INFO_NOT_AVAILABLE;
3131         }
3132
3133         switch (audio_path_type) {
3134         case VC_AUDIO_PATH_HEADSET:
3135                 volume_type = TAPI_SOUND_VOL_HEADSET_VOICE;
3136                 break;
3137         case VC_AUDIO_PATH_BLUETOOTH:
3138         case VC_AUDIO_PATH_STEREO_BLUETOOTH:
3139                 volume_type = TAPI_SOUND_VOL_BT_VOICE;
3140                 break;
3141         case VC_AUDIO_PATH_SPK_PHONE:
3142                 volume_type = TAPI_SOUND_VOL_SPK_PHONE;
3143                 break;
3144         default:
3145                 volume_type = TAPI_SOUND_VOL_VOICE;
3146                 break;
3147         }
3148
3149         CALL_ENG_DEBUG(ENG_DEBUG, "volume_type = %d", volume_type);
3150
3151         pcall_agent->curr_tapi_path = volume_type;
3152         error = tel_get_sound_volume_info(volume_type, &ReqId);
3153
3154         if (error != TAPI_API_SUCCESS) {
3155                 CALL_ENG_DEBUG(ENG_DEBUG, "Tapi API Error: %d", error);
3156                 return ERROR_VOICECALL_TAPI_ERROR;
3157         }
3158
3159         return ERROR_VOICECALL_NONE;
3160 }
3161
3162 /**
3163 * This function changes the inout state of the engine to the given state
3164 *
3165 * @return               ERROR_VOICECALL_NONE on success or return value contains appropriate error code on failure
3166 * @param[in]    pvoicecall_agent        Handle to voicecall engine
3167 * @param[in]    io_state                        Inout state to be set
3168 * @remarks              pvoicecall_agent cannot be NULL
3169 * @see                  _vc_core_engine_status_get_engine_iostate
3170 */
3171 voicecall_error_t _vc_core_engine_change_engine_iostate(voicecall_engine_t *pvoicecall_agent, int io_state)
3172 {
3173         call_vc_callagent_state_t *pagent = (call_vc_callagent_state_t *)pvoicecall_agent;
3174         VOICECALL_RETURN_VALUE_IF_FAIL(pagent != NULL, ERROR_VOICECALL_INVALID_CALL_HANDLE);
3175         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(io_state, VC_INOUT_STATE_NONE, VC_INOUT_STATE_INCOME_END, ERROR_VOICECALL_INVALID_CALL_HANDLE);
3176
3177         if (TRUE == _vc_core_ca_change_inout_state(pagent, (voicecall_inout_state_t) io_state)) {
3178                 return ERROR_VOICECALL_NONE;
3179         }
3180
3181         return ERROR_VOICECALL_INVALID_ARGUMENTS;
3182 }
3183
3184 voicecall_error_t _vc_core_engine_extract_phone_number(const char *source_tel_number, char *phone_number, const int buf_size)
3185 {
3186         VOICECALL_RETURN_VALUE_IF_FAIL(source_tel_number != NULL, ERROR_VOICECALL_INVALID_CALL_HANDLE);
3187         VOICECALL_RETURN_VALUE_IF_FAIL(phone_number != NULL, ERROR_VOICECALL_INVALID_CALL_HANDLE);
3188
3189         if (FALSE == _vc_core_util_extract_call_number(source_tel_number, phone_number, buf_size)) {
3190                 _vc_core_util_strcpy(phone_number, buf_size, source_tel_number);
3191         }
3192
3193         return ERROR_VOICECALL_NONE;
3194 }
3195
3196 voicecall_error_t _vc_core_engine_set_to_default_values(voicecall_engine_t *pvoicecall_agent)
3197 {
3198         call_vc_callagent_state_t *pcall_agent = (call_vc_callagent_state_t *)pvoicecall_agent;
3199
3200         CALL_ENG_DEBUG(ENG_DEBUG, "Start");
3201         /*Initialize Call Manager */
3202         _vc_core_call_manager_init(&pcall_agent->call_manager);
3203
3204         /* Initialize Call Agent Flags */
3205         _vc_core_ca_init_data(pcall_agent);
3206
3207 #ifdef _CCBS_DEFINED_
3208         /* Init CCBS Info */
3209         _vc_core_init_ccbs_info(pcall_agent);
3210 #endif
3211
3212         /* Init CPHS Info */
3213 #ifdef _CPHS_DEFINED_
3214         _vc_core_svcall_init_cphs_info(pcall_agent);
3215 #endif
3216
3217         CALL_VC_DUMP_CALLDETAILS(&pcall_agent->call_manager);
3218         CALL_ENG_DEBUG(ENG_DEBUG, "End");
3219
3220         return ERROR_VOICECALL_NONE;
3221 }