2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.tizenopensource.org/license
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "vc-core-callagent.h"
18 #include "vc-core-engine.h"
19 #include "vc-core-ccbs.h"
20 #include "vc-core-tapi-rqst.h"
21 #include "vc-core-tapi-evnt.h"
22 #include "vc-core-svcall.h"
25 /* For Debug Information, Inout state name string constant */
26 char *gszcall_vc_inout_state[VC_INOUT_STATE_MAX_NUM] = {
31 "OUTGOING_WAIT_ALERT",
32 "OUTGOING_WAIT_CONNECTED",
33 "OUTGOING_WAIT_RELEASE",
35 "OUTGOING_SHOW_REDIALCAUSE",
36 "OUTGOING_WAIT_REDIAL",
37 "OUTGOING_SHOW_RETRY_CALLBOX",
39 "INCOME_SELFEVENT_WAIT",
42 "INCOME_WAIT_REDIRECTCNF",
43 "INCOME_WAIT_REDIRECT_END",
44 "INCOME_WAIT_CONNECTED",
45 "INCOME_WAIT_HOLD_CONNECTED",
46 "INCOME_WAIT_RELEASE_ACTIVE_CONNECTED",
48 "INCOME_WAIT_RELEASE_ACTIVECALL",
49 "INCOME_WAIT_RELEASE_HOLDCALL",
50 "INCOME_WAIT_RELEASE",
54 /* For Debug Information, Call Agent State name string constant */
55 char *gszcall_vc_ca_state[CALL_VC_CA_STATE_MAX_NUM] = {
57 "CA_STATE_SPLIT_CALLBOX",
58 "CA_STATE_WAIT_SPLIT",
59 "CA_STATE_DROP_CALLBOX",
62 "CA_STATE_WAIT_SWAP_HOLD_OR_ACTIVATE",
63 "CA_STATE_WAIT_SWAP_HOLD",
64 "CA_STATE_WAIT_SWAP_ACTIVATE",
68 "CA_STATE_WAIT_UNHOLD",
70 "CA_STATE_WAIT_TRANSFER_CNF",
71 "CA_STATE_WAIT_TRANSFER_CALLEND",
72 "CA_STATE_WAIT_RELEASE_ALL_ACTIVECALL",
73 "CA_STATE_WAIT_RELEASE_ALL_HOLDCALL",
74 "CA_STATE_SENDMSG_CALLBOX",
75 "CA_STATE_VIEW_CONTACT_DETAIL_CALLBOX",
76 "CA_STATE_SAVE_TO_CONTACT_CALLBOX",
77 "CA_STATE_SS_WAIT_RELEASE_ALL_ACTIVECALL",
78 "CA_STATE_WAIT_RELEASE_ALL_CALLS",
79 "CA_STATE_WAIT_RELEASE_ALL_CALLS_TO_SETUP",
80 "CA_STATE_WAIT_RELEASE_ALL_CALLS_TO_SWITCH_TO_VIDEO_CALL"
84 * This function intializes the call agent
86 * @return Pointer to call agent state.
88 call_vc_callagent_state_t *_vc_core_ca_init_agent()
90 call_vc_callagent_state_t *pcall_agent = NULL;
91 pcall_agent = (call_vc_callagent_state_t *)calloc(1, sizeof(call_vc_callagent_state_t));
92 if (NULL == pcall_agent) {
93 CALL_ENG_DEBUG(ENG_DEBUG, "Voicecall Engine Initialization Failed: MEM ALLOC Failure");
97 /*Initialize Call Manager */
98 _vc_core_call_manager_init(&pcall_agent->call_manager);
100 /* Initialize Call Agent Flags */
101 _vc_core_ca_init_data(pcall_agent);
103 #ifdef _CCBS_DEFINED_
105 _vc_core_init_ccbs_info(pcall_agent);
109 #ifdef _CPHS_DEFINED_
110 _vc_core_svcall_init_cphs_info(pcall_agent);
116 * This function intializes the callagent data
119 * @param[in] pagent Pointer to the call agent structure
121 void _vc_core_ca_init_data(call_vc_callagent_state_t *pagent)
123 VOICECALL_RETURN_IF_FAIL(pagent != NULL);
124 pagent->bonly_sos_call = FALSE;
125 pagent->callagent_state = CALL_VC_CA_STATE_NORMAL;
126 pagent->io_state = VC_INOUT_STATE_NONE;
127 pagent->bis_no_sim = FALSE;
128 pagent->aoc_ppm = VC_INVALID_PPM;
132 * This function finalizes the call agent
134 * @return Returns void
135 * @param[in] pcall_agent Pointer to the call agent structure
137 void _vc_core_ca_finish_agent(call_vc_callagent_state_t *pcall_agent)
139 if (NULL != pcall_agent) {
146 * This function changes the in out state of the call agent
148 * @return This function returns TRUE on success and FALSE on failure
149 * @param[in] pagent Pointer to the call agent structure
150 * @param[in] new_state The new i/o state that should be set
151 * @see _vc_core_ca_change_agent_state
153 gboolean _vc_core_ca_change_inout_state(call_vc_callagent_state_t *pagent, voicecall_inout_state_t new_state)
155 VOICECALL_RETURN_FALSE_IF_FAIL(pagent != NULL);
157 CALL_ENG_DEBUG(ENG_ERR, "%s(%d) --> %s(%d)", gszcall_vc_inout_state[pagent->io_state], pagent->io_state, gszcall_vc_inout_state[new_state], new_state);
158 pagent->io_state = new_state;
163 * This function changes the in call agent state
165 * @return This function returns TRUE on success and FALSE on failure
166 * @param[in] pAgent Pointer to the call agent structure
167 * @param[in] new_state The new call agent state that should be set
168 * @see _vc_core_ca_change_inout_state
170 gboolean _vc_core_ca_change_agent_state(call_vc_callagent_state_t *pAgent, call_vc_ca_state_t new_state)
172 VOICECALL_RETURN_FALSE_IF_FAIL((new_state >= CALL_VC_CA_STATE_NORMAL && new_state < CALL_VC_CA_STATE_MAX_NUM));
173 CALL_ENG_DEBUG(ENG_DEBUG, "%s(%d) --> %s(%d)", gszcall_vc_ca_state[pAgent->callagent_state], pAgent->callagent_state, gszcall_vc_ca_state[new_state], new_state);
174 pAgent->callagent_state = new_state;
179 * This function checks if all the call members have terminated or not
181 * @return Returns TRUE if no call members exist, FALSE otherwise
182 * @param[in] pAgent Pointer to the call agent structure
184 gboolean _vc_core_ca_check_end(call_vc_callagent_state_t *pAgent)
186 gboolean result = FALSE;
187 VOICECALL_RETURN_FALSE_IF_FAIL(pAgent != NULL);
188 if ((_vc_core_cm_get_call_member_count(&pAgent->call_manager) == 0) && (pAgent->io_state == VC_INOUT_STATE_NONE)) {
189 CALL_ENG_DEBUG(ENG_DEBUG, "TRUE");
194 CALL_ENG_DEBUG(ENG_DEBUG, "FALSE");
202 * This function sends the response to the SAT engine
204 * @return This function returns TRUE on success and FALSE on failure
205 * @param[in] pagent Pointer to the call agent structure
206 * @param[in] sat_rqst_resp_type sat rquest/response type used by the client
207 * @param[in] sat_response_type response to be sent to sat
209 gboolean _vc_core_ca_send_sat_response(call_vc_callagent_state_t *pagent, voicecall_engine_sat_rqst_resp_type sat_rqst_resp_type, call_vc_sat_reponse_type_t sat_response_type)
211 call_vc_satsetup_info_t *pcall_vc_satcall_info = (call_vc_satsetup_info_t *) &(pagent->call_manager.setupcall_info.satcall_setup_info);
212 TelSatAppsRetInfo_t call_vc_sat_response = {0,};
213 TapiResult_t error_code;
214 CALL_ENG_DEBUG(ENG_DEBUG, "sat_rqst_resp_type: %d, sat_response_type: %d", sat_rqst_resp_type, sat_response_type);
215 switch (sat_rqst_resp_type) {
216 case SAT_RQST_SETUP_CALL:
218 TelSatCallRetInfo_t sat_engine_ret_call = {0,};
219 switch (sat_response_type) {
220 case CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND:
221 sat_engine_ret_call.resp = TAPI_SAT_R_ME_UNABLE_TO_PROCESS_COMMAND;
222 sat_engine_ret_call.bIsTapiCauseExist = FALSE;
223 sat_engine_ret_call.tapiCause = TAPI_CAUSE_UNKNOWN;
224 sat_engine_ret_call.meProblem = TAPI_SAT_ME_PROBLEM_ME_BUSY_ON_CALL;
225 sat_engine_ret_call.bIsOtherInfoExist = FALSE;
226 sat_engine_ret_call.permanentCallCtrlProblem = TAPI_SAT_CC_PROBLEM_NO_SPECIFIC_CAUSE;
228 case CALL_VC_NETWORK_UNABLE_TO_PROCESS_COMMAND:
229 sat_engine_ret_call.resp = TAPI_SAT_R_NETWORK_UNABLE_TO_PROCESS_COMMAND;
230 sat_engine_ret_call.bIsTapiCauseExist = TRUE;
231 sat_engine_ret_call.tapiCause = TAPI_CAUSE_BUSY;
232 sat_engine_ret_call.meProblem = TAPI_SAT_ME_PROBLEM_NO_SERVICE;
233 sat_engine_ret_call.bIsOtherInfoExist = FALSE;
234 sat_engine_ret_call.permanentCallCtrlProblem = TAPI_SAT_CC_PROBLEM_NO_SPECIFIC_CAUSE;
236 case CALL_VC_NETWORK_UNABLE_TO_PROCESS_COMMAND_WITHOUT_CAUSE:
237 sat_engine_ret_call.resp = TAPI_SAT_R_NETWORK_UNABLE_TO_PROCESS_COMMAND;
238 sat_engine_ret_call.bIsTapiCauseExist = FALSE;
239 sat_engine_ret_call.tapiCause = TAPI_CAUSE_UNKNOWN;
240 sat_engine_ret_call.meProblem = TAPI_SAT_ME_PROBLEM_NO_SPECIFIC_CAUSE;
241 sat_engine_ret_call.bIsOtherInfoExist = FALSE;
242 sat_engine_ret_call.permanentCallCtrlProblem = TAPI_SAT_CC_PROBLEM_NO_SPECIFIC_CAUSE;
244 case CALL_VC_ME_CONTROL_PERMANENT_PROBLEM:
245 sat_engine_ret_call.resp = TAPI_SAT_R_INTRCTN_WITH_CC_OR_SMS_CTRL_PRMNT_PRBLM;
246 sat_engine_ret_call.bIsTapiCauseExist = FALSE;
247 sat_engine_ret_call.tapiCause = TAPI_CAUSE_UNKNOWN;
248 sat_engine_ret_call.meProblem = TAPI_SAT_ME_PROBLEM_ACCESS_CONTROL_CLASS_BAR;
249 sat_engine_ret_call.bIsOtherInfoExist = FALSE;
250 sat_engine_ret_call.permanentCallCtrlProblem = TAPI_SAT_CC_PROBLEM_ACTION_NOT_ALLOWED;
252 case CALL_VC_ME_CLEAR_DOWN_BEFORE_CONN:
253 sat_engine_ret_call.resp = TAPI_SAT_R_USER_CLEAR_DOWN_CALL_BEFORE_CONN;
254 sat_engine_ret_call.bIsTapiCauseExist = FALSE;
255 sat_engine_ret_call.tapiCause = TAPI_CAUSE_UNKNOWN;
256 sat_engine_ret_call.meProblem = TAPI_SAT_ME_PROBLEM_ME_BUSY_ON_CALL;
257 sat_engine_ret_call.bIsOtherInfoExist = FALSE;
258 sat_engine_ret_call.permanentCallCtrlProblem = TAPI_SAT_CC_PROBLEM_NO_SPECIFIC_CAUSE;
260 case CALL_VC_ME_RET_SUCCESS:
261 sat_engine_ret_call.resp = TAPI_SAT_R_SUCCESS;
262 sat_engine_ret_call.bIsTapiCauseExist = TRUE;
263 sat_engine_ret_call.tapiCause = TAPI_CAUSE_SUCCESS;
264 sat_engine_ret_call.meProblem = TAPI_SAT_ME_PROBLEM_NO_SPECIFIC_CAUSE;
265 sat_engine_ret_call.bIsOtherInfoExist = FALSE;
266 sat_engine_ret_call.permanentCallCtrlProblem = TAPI_SAT_CC_PROBLEM_NO_SPECIFIC_CAUSE;
272 call_vc_sat_response.commandType = TAPI_SAT_CMD_TYPE_SETUP_CALL;
273 call_vc_sat_response.commandId = pcall_vc_satcall_info->satengine_setupcall_data.commandId;
274 memset(&(call_vc_sat_response.appsRet.setupCall), 0, sizeof(call_vc_sat_response.appsRet.setupCall));
275 memcpy(&(call_vc_sat_response.appsRet.setupCall), &sat_engine_ret_call, sizeof(call_vc_sat_response.appsRet.setupCall));
278 case SAT_RQST_SEND_DTMF:
280 TelSatDtmfRetInfo_t sat_engine_ret_dtmf;
281 switch (sat_response_type) {
282 case CALL_VC_ME_UNABLE_TO_PROCESS_COMMAND:
283 sat_engine_ret_dtmf.resp = TAPI_SAT_R_ME_UNABLE_TO_PROCESS_COMMAND;
285 case CALL_VC_NETWORK_UNABLE_TO_PROCESS_COMMAND:
286 sat_engine_ret_dtmf.resp = TAPI_SAT_R_NETWORK_UNABLE_TO_PROCESS_COMMAND;
288 case CALL_VC_ME_CONTROL_PERMANENT_PROBLEM:
289 sat_engine_ret_dtmf.resp = TAPI_SAT_R_INTRCTN_WITH_CC_OR_SMS_CTRL_PRMNT_PRBLM;
291 case CALL_VC_ME_CLEAR_DOWN_BEFORE_CONN:
292 sat_engine_ret_dtmf.resp = TAPI_SAT_R_USER_CLEAR_DOWN_CALL_BEFORE_CONN;
294 case CALL_VC_ME_RET_SUCCESS:
295 sat_engine_ret_dtmf.resp = TAPI_SAT_R_SUCCESS;
301 call_vc_sat_response.commandType = TAPI_SAT_CMD_TYPE_SEND_DTMF;
302 call_vc_sat_response.commandId = pcall_vc_satcall_info->satengine_dtmf_data.commandId;
303 memset(&(call_vc_sat_response.appsRet.sendDtmf), 0, sizeof(call_vc_sat_response.appsRet.sendDtmf));
304 memcpy(&(call_vc_sat_response.appsRet.sendDtmf), &sat_engine_ret_dtmf, sizeof(call_vc_sat_response.appsRet.sendDtmf));
306 /*Reset SAT DATA after sending response */
307 pcall_vc_satcall_info->satengine_dtmf_data.bIsHiddenMode = FALSE;
308 CALL_ENG_DEBUG(ENG_ERR, "SAT Hidden mode has been reset");
312 CALL_ENG_DEBUG(ENG_DEBUG, "Invalid SAT Rquest Response Type");
315 error_code = tel_send_sat_app_exec_result(&call_vc_sat_response);
316 if (error_code != TAPI_API_SUCCESS) {
317 CALL_ENG_DEBUG(ENG_DEBUG, "Error tel_send_sat_app_exec_result():%#X", error_code);
322 CALL_ENG_DEBUG(ENG_DEBUG, "tel_send_sat_app_exec_result: Success");
328 * This function checks whether outgoing call is possible
330 * @return This function returns TRUE if outgoing call is possible or else FALSE
331 * @param[in] pagent Pointer to the call agent structure
332 * @param[in] bemergency_number TRUE - if outgoing call being made is emergency call or else FALSE
334 gboolean _vc_core_ca_is_mocall_possible(call_vc_callagent_state_t *pagent, gboolean bemergency_number)
336 gboolean bactive_call = FALSE;
337 gboolean bheld_call = FALSE;
339 VOICECALL_RETURN_FALSE_IF_FAIL(pagent != NULL);
340 bactive_call = _vc_core_cm_isexists_active_call(&pagent->call_manager);
341 bheld_call = _vc_core_cm_isexists_held_call(&pagent->call_manager);
342 if (pagent->io_state != VC_INOUT_STATE_NONE) {
343 CALL_ENG_DEBUG(ENG_DEBUG, "io_state=%d with FALSE ..", pagent->io_state);
347 /* If it is emergency number, the call can be made by disconnecting all calls */
348 if (bemergency_number) {
349 CALL_ENG_DEBUG(ENG_DEBUG, "Emergency number with TRUE..");
353 /* Mo is impossile when both active and hold call exist */
354 if (bactive_call && bheld_call) {
355 CALL_ENG_DEBUG(ENG_DEBUG, "ended with FALSE ..");
360 member_num = _vc_core_cm_get_call_member_count(&pagent->call_manager);
362 #ifdef _CPHS_DEFINED_
363 if (bactive_call && _vc_core_svcall_cphs_csp_get_status(VC_CPHS_CSP_HOLD) == FALSE) {
364 CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_svcall_cphs_csp_get_status : Hold is not possible");
368 /* Mo is impossile when member is more than max */
369 if (member_num >= (VC_MAX_CALL_GROUP_MEMBER + 1)) {
370 CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_ca_is_mocall_possible: ended with FALSE ..");
375 CALL_ENG_DEBUG(ENG_DEBUG, "_vc_core_ca_is_mocall_possible: ended with TRUE ..");
383 * This function ends all the active calls
385 * @return Returns TRUE on success and FALSE on failure
386 * @param[in] pagent Handle to voicecall engine
388 gboolean _vc_core_ca_end_active_calls(call_vc_callagent_state_t *pagent)
390 gboolean result = FALSE;
391 VOICECALL_RETURN_FALSE_IF_FAIL(pagent != NULL);
392 if (TRUE == _vc_core_cm_isexists_active_call(&pagent->call_manager)) {
393 result = _vc_core_tapi_rqst_release_active_calls(pagent);
394 if (TRUE == result) {
395 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_RELEASE_ALL_ACTIVECALL);
402 * This function ends all the calls
404 * @return Returns TRUE on success and FALSE on failure
405 * @param[in] pagent Handle to voicecall engine
407 gboolean _vc_core_ca_end_all_calls(call_vc_callagent_state_t *pagent)
409 gboolean result = FALSE;
410 VOICECALL_RETURN_FALSE_IF_FAIL(pagent != NULL);
411 result = _vc_core_tapi_rqst_release_all_calls(pagent);
412 if (TRUE == result) {
413 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_RELEASE_ALL_CALLS);
419 * This function ends all the held calls
421 * @return Returns TRUE on success and FALSE on failure
422 * @param[in] pagent Handle to voicecall engine
424 gboolean _vc_core_ca_end_held_calls(call_vc_callagent_state_t *pagent)
426 gboolean result = FALSE;
427 VOICECALL_RETURN_FALSE_IF_FAIL(pagent != NULL);
428 if (TRUE == _vc_core_cm_isexists_held_call(&pagent->call_manager)) {
429 result = _vc_core_tapi_rqst_release_held_calls(pagent);
430 if (TRUE == result) {
431 _vc_core_ca_change_agent_state(pagent, CALL_VC_CA_STATE_WAIT_RELEASE_ALL_HOLDCALL);
438 * This function checks whether private call is possible or not
440 * @return This function returns TRUE if private is possible or else FALSE
441 * @param[in] pcall_agent Pointer to the call agent structure
443 gboolean _vc_core_ca_is_private_call_possible(call_vc_callagent_state_t *pcall_agent)
445 gboolean active_calls = FALSE, held_calls = FALSE;
446 int active_call_member = 0;
447 _vc_core_cm_isexists_call_ingroup(&pcall_agent->call_manager, &active_calls, &held_calls);
448 active_call_member = _vc_core_cm_get_active_call_count(&pcall_agent->call_manager);
449 if (TRUE == active_calls && FALSE == held_calls) {
450 if (active_call_member > 1) {
458 * This function checks whether call transfer is possible
460 * @return This function returns TRUE if transfer is possible or else FALSE
461 * @param[in] pcall_agent Pointer to the call agent structure
463 gboolean _vc_core_ca_is_transfer_call_possible(call_vc_callagent_state_t *pcall_agent)
465 gboolean active_calls = FALSE;
466 gboolean held_calls = FALSE;
467 int total_call_member = 0;
469 #ifdef _CPHS_DEFINED_
470 if (FALSE == _vc_core_svcall_cphs_csp_get_status(pcall_agent, VC_CPHS_CSP_CT)) {
474 _vc_core_cm_isexists_call_ingroup(&pcall_agent->call_manager, &active_calls, &held_calls);
475 total_call_member = _vc_core_cm_get_call_member_count(&pcall_agent->call_manager);
477 /* The Explicit Call Transfer (ECT) function should be invoked in association with two existing calls which 1) one is answered and in the held state and 2) the other is answered and active or alerting. */
478 if (3 == total_call_member) {
479 if ((TRUE == active_calls) && (TRUE == held_calls) && (VC_INVALID_CALL_INDEX != pcall_agent->call_manager.mtcall_index)) {
480 CALL_ENG_DEBUG(ENG_DEBUG, "Transfer possible..1 active, 1 held, 1 waiting..");
485 else if (2 == total_call_member) {
486 if ((TRUE == active_calls) && (TRUE == held_calls) && (VC_INVALID_CALL_INDEX == pcall_agent->call_manager.mtcall_index)) {
490 else if ((FALSE == active_calls) && (TRUE == held_calls) && (VC_INVALID_CALL_INDEX != pcall_agent->call_manager.mtcall_index)) {
494 else if ((FALSE == active_calls) && (TRUE == held_calls) && (-1 != pcall_agent->call_manager.setupcall_info.mocall_index) /*Outgoing call exists */
495 && (VC_INOUT_STATE_OUTGOING_WAIT_CONNECTED == pcall_agent->io_state)) {
503 * This function checks whether conference call is possible
505 * @return This function returns TRUE if transfer is possible or else FALSE
506 * @param[in] pcall_agent Pointer to the call agent structure
508 gboolean _vc_core_ca_is_conf_call_possible(call_vc_callagent_state_t *pcall_agent)
510 gboolean active_calls = FALSE;
511 gboolean held_calls = FALSE;
512 int total_call_member = 0;
514 #ifdef _CPHS_DEFINED_
515 if (FALSE == _vc_core_svcall_cphs_csp_get_status(pcall_agent, VC_CPHS_CSP_MPTY)) {
519 _vc_core_cm_isexists_call_ingroup(&pcall_agent->call_manager, &active_calls, &held_calls);
520 total_call_member = _vc_core_cm_get_call_member_count(&pcall_agent->call_manager);
522 /* Joining call is impossile when active or hold call doesn't exist */
523 if ((FALSE == active_calls) || (FALSE == held_calls)) {
524 CALL_ENG_DEBUG(ENG_DEBUG, "Join Impossible...");
530 /*Joining call is impossile when member is more than max
531 * if ( total_call_member >= (CALL_VC_CALL_GROUP_MEMBER_MAX + 1)) : Max Number in Group + Another Call*/
532 if (total_call_member > VC_MAX_CALL_GROUP_MEMBER) { /*Logic Changed from above line for same condition */
533 CALL_ENG_DEBUG(ENG_DEBUG, "Ended with FALSE...");
538 CALL_ENG_DEBUG(ENG_DEBUG, "Ended with TRUE...");
546 * This function clears the data of a connected call givenits call handle
548 * @return Returns TRUE on success and FALSE on failure
549 * @param[in] pcall_agent Handle to voicecall engine
550 * @param[in] call_handle Call handle of the connected call to be cleared
552 gboolean _vc_core_ca_clear_connected_call(call_vc_callagent_state_t *pcall_agent, int call_handle)
554 call_vc_call_objectinfo_t call_object;
555 gboolean remove = FALSE;
556 int group_index = -1;
559 VOICECALL_RETURN_FALSE_IF_FAIL(pcall_agent != NULL);
560 VOICECALL_RETURN_FALSE_IF_FAIL(call_handle >= 0);
561 CALL_ENG_DEBUG(ENG_DEBUG, "..");
562 _vc_core_cm_get_call_object(&pcall_agent->call_manager, call_handle, &call_object);
563 group_index = _vc_core_cm_get_group_index(&pcall_agent->call_manager, (call_vc_handle) call_handle);
564 if (group_index == -1) {
565 CALL_ENG_DEBUG(ENG_DEBUG, "ERROR: Not exist");
568 grp_mem_num = _vc_core_cm_get_member_count_ingroup(&pcall_agent->call_manager, group_index);
569 for (i = 0; i < grp_mem_num; i++) {
570 if ((_vc_core_cm_get_call_state_ingroup_byposition(&pcall_agent->call_manager, group_index, i) != VC_CALL_STATE_ENDED) && (_vc_core_cm_get_call_state_ingroup_byposition(&pcall_agent->call_manager, group_index, i) != VC_CALL_STATE_ENDED_FINISH)) {
575 _vc_core_cm_remove_call_object(&pcall_agent->call_manager, call_handle);
579 gboolean clear_end_call = TRUE;
580 _vc_core_cm_change_call_state(&call_object, VC_CALL_STATE_ENDED_FINISH);
581 _vc_core_cm_set_call_object(&pcall_agent->call_manager, &call_object);
582 for (i = 0; i < grp_mem_num; i++) {
583 if (_vc_core_cm_get_call_state_ingroup_byposition(&pcall_agent->call_manager, group_index, i) != VC_CALL_STATE_ENDED_FINISH)
584 clear_end_call = FALSE;
586 if (clear_end_call) {
587 _vc_core_cm_clear_endcall_member(&pcall_agent->call_manager);