806899e6a563e962081390d3941536915e89a092
[apps/home/call.git] / call-engine / core / vc-core-callmanager.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 <stdio.h>
21 #include <stdbool.h>
22 #include <glib.h>
23 #include "vc-core-util.h"
24 #include "vc-core-callmanager.h"
25 #include "vc-core-callagent.h"
26
27 char *gaszCallStateName[VC_CALL_STATE_MAX_NUM] = {
28         "CALL_NONE",
29         "CALL_INCOME",
30         "CALL_REJECTED",
31         "CALL_PREPARE_OUTGOING",
32         "CALL_OUTGOING",
33         "CALL_OUTGOING_ORIG",
34         "CALL_OUTGOING_ALERT",
35         "CALL_CANCELLED",
36         "CALL_CONNECTED",
37         "CALL_RELEASE_WAIT",
38         "CALL_ENDED",
39         "CALL_REDIAL",
40         "CALL_ENDED_FINISH",
41 };
42
43 /*Local Function Declarations*/
44 /**
45 * This function handles sat engine notification
46 *
47 * @internal
48 * @return               Returns TRUE on success or FALSE on failure
49 * @param[in]            callStatusInfo  Handle to call manager
50 * @param[in]            call_handle     telephony call handle
51 * @param[out]   pGroup          group to which the call_handle belongs
52 * @param[in]            pPos                    positoin in the pGroup in which the call details of call handle is maintained
53 */
54 static gboolean __call_vc_cm_gp_get_groupcall_pos(call_vc_manager_t *callStatusInfo, call_vc_handle call_handle, int *pGroup, int *pPos);
55
56 /**
57  * This function removes a call member to a group
58  *
59  * @return              This function returns TRUE on success and FALSE on failure
60  * @param[in]           pMng            Pointer to the call manager structure
61  * @param[in]           call_handle     The call handle to be removed
62  * @see                 _vc_core_cm_add_call_member_togroup
63  */
64 static gboolean __vc_core_cm_remove_call_member_fromgroup(call_vc_manager_t *pMng, call_vc_handle call_handle);
65
66 /*Function Definitions*/
67 /**
68  * This function initializes the call manager
69  *
70  * @return              void
71  * @param[out]  pMng            Pointer to the call manager structure
72  */
73 void _vc_core_call_manager_init(call_vc_manager_t *pMng)
74 {
75         VOICECALL_RETURN_IF_FAIL(pMng != NULL);
76         int index = 0;
77
78         memset(pMng, 0, sizeof(call_vc_manager_t));
79
80         /* init call handle */
81         for (index = 0; index < VC_MAX_CALL_MEMBER; index++) {
82                 /*CALL_ENG_DEBUG(ENG_DEBUG, "%d",index);*/
83                 pMng->callobject_info[index].call_handle = VC_TAPI_INVALID_CALLHANDLE;
84                 pMng->callobject_info[index].aoc_ccm = VC_INVALID_CALL_COST;
85                 pMng->callobject_info[index].call_id = VC_INVALID_CALL_ID;
86                 pMng->callobject_info[index].call_type = VC_CALL_ORIG_TYPE_NORMAL;
87         }
88
89         pMng->setupcall_info.mocall_index = VC_INVALID_CALL_INDEX;
90         pMng->setupcall_info.call_control_type = CALL_VC_SAT_CC_NONE;
91         pMng->mtcall_index = VC_INVALID_CALL_INDEX;
92
93         CALL_ENG_DEBUG(ENG_DEBUG, "[pMng->callobject_info initialized]");
94
95 }
96
97 /**
98  * This function clears the information of a given call state
99  *
100  * @return              void
101  * @param[in]   pcall_object    Pointer to the call object which has to be cleared
102  */
103 void _vc_core_cm_clear_call_object(call_vc_call_objectinfo_t *pcall_object)
104 {
105         VOICECALL_RETURN_IF_FAIL(pcall_object != NULL);
106         memset(pcall_object, 0, sizeof(call_vc_call_objectinfo_t));
107
108         pcall_object->state = VC_CALL_STATE_NONE;
109         pcall_object->call_handle = VC_TAPI_INVALID_CALLHANDLE;
110         pcall_object->aoc_ccm = VC_INVALID_CALL_COST;
111         pcall_object->call_id = VC_INVALID_CALL_ID;
112         pcall_object->call_type = VC_CALL_ORIG_TYPE_NORMAL;
113
114 #ifdef _CPHS_DEFINED_
115         pcall_object->alsLine = VC_CALL_CPHS_ALS_NONE;
116 #endif
117
118         pcall_object->bccbs_call = FALSE;
119
120 }
121
122 /**
123 * This function clears the information of the callobject available in the given index
124  *
125 * @return               TRUE, if the object cleared, otherwise FALSE
126 * @param[in]    pMng            Pointer to the call manager structure
127 * @param[in]    index           Index of the call object to be cleared
128  */
129 gboolean _vc_core_cm_clear_call_object_byindex(call_vc_manager_t *pMng, int index)
130 {
131         call_vc_call_objectinfo_t call_object;
132         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
133         VOICECALL_RETURN_FALSE_IF_FAIL(index >= 0 && index <= 7);
134
135         if (TRUE == _vc_core_cm_get_call_object_byindex(pMng, index, &call_object)) {
136                 _vc_core_cm_clear_call_object(&call_object);
137                 return TRUE;
138         }
139
140         return FALSE;
141 }
142
143 /**
144  * This function adds the given call object info to a free slot.
145  *
146  * @return              This function returns the call object index on success and -1 on failure
147  * @param[in]           pMng            Pointer to the call manager structure
148  * @param[in]           pcall_object    Pointer to the call object info structure that need to be added
149  * @see                 _vc_core_cm_set_call_object, _vc_core_cm_remove_call_object
150  */
151 int _vc_core_cm_add_call_object(call_vc_manager_t *pMng, call_vc_call_objectinfo_t *pcall_object)
152 {
153         int index = 0;
154
155         VOICECALL_RETURN_INVALID_IF_FAIL(pMng != NULL);
156         VOICECALL_RETURN_INVALID_IF_FAIL(pcall_object != NULL);
157
158         for (index = 0; index < VC_MAX_CALL_MEMBER; index++) {
159                 if (pMng->callobject_info[index].state == VC_CALL_STATE_NONE) {
160                         memcpy(&pMng->callobject_info[index], pcall_object, sizeof(call_vc_call_objectinfo_t));
161                         return index;
162                 }
163         }
164
165         CALL_ENG_DEBUG(ENG_DEBUG, "Insufficient buffer i = %d..", index);
166
167         return VC_TAPI_INVALID_CALLHANDLE;
168 }
169
170 /**
171  * This function removes the specified call object info of a given call handle
172  *
173  * @return              This function returns TRUE on success and FALSE on failure
174  * @param[in]           pMng            Pointer to the call manager structure
175  * @param[in]           call_handle     Handle of the call object to be removed
176  * @see                 _vc_core_cm_add_call_object, _vc_core_cm_set_call_object
177  */
178 gboolean _vc_core_cm_remove_call_object(call_vc_manager_t *pMng, call_vc_handle call_handle)
179 {
180         int i = 0;
181         int groupIndex = -1;
182
183         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
184         VOICECALL_RETURN_FALSE_IF_FAIL(call_handle != VC_TAPI_INVALID_CALLHANDLE);
185
186         CALL_ENG_DEBUG(ENG_DEBUG, "[Call Handle = %d]", call_handle);
187
188         for (i = 0; i < VC_MAX_CALL_MEMBER; i++) {
189                 if (pMng->callobject_info[i].call_handle == call_handle) {
190                         if (pMng->setupcall_info.mocall_index == i) {
191                                 CALL_ENG_DEBUG(ENG_DEBUG, "Removing MO Call Info >> i=%d", i);
192                                 pMng->setupcall_info.mocall_index = VC_INVALID_CALL_INDEX;
193                                 pMng->setupcall_info.no_service_state = FALSE;
194                         } else if (pMng->mtcall_index == i) {
195                                 CALL_ENG_DEBUG(ENG_DEBUG, "Removing MT Call Info >> i=%d", i);
196                                 pMng->mtcall_index = VC_INVALID_CALL_INDEX;
197                         } else {
198                                 groupIndex = _vc_core_cm_get_group_index(pMng, call_handle);
199                                 __vc_core_cm_remove_call_member_fromgroup(pMng, call_handle);
200                         }
201                         _vc_core_cm_clear_call_object(&(pMng->callobject_info[i]));
202                         break;
203                 }
204
205         }
206
207         return TRUE;
208 }
209
210 /**
211  * This function retrieves the given call object info
212  *
213  * @return              This function returns TRUE on success and FALSE on failure
214  * @param[in]           pMng            Pointer to the call manager structure
215  * @param[in]           call_handle     Call handle of the object info to be retrieved
216  * @param[out]  pcall_object    Pointer to the call object info structure that should be retrieved
217  * @see                 _vc_core_cm_add_call_object, _vc_core_cm_remove_call_object, _vc_core_cm_set_call_object
218  */
219 gboolean _vc_core_cm_get_call_object(call_vc_manager_t *pMng, call_vc_handle call_handle, call_vc_call_objectinfo_t *pcall_object)
220 {
221         int i = 0;
222
223         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
224         VOICECALL_RETURN_FALSE_IF_FAIL(call_handle != VC_TAPI_INVALID_CALLHANDLE);
225         VOICECALL_RETURN_FALSE_IF_FAIL(pcall_object != NULL);
226
227         for (i = 0; i < VC_MAX_CALL_MEMBER; i++) {
228                 if (pMng->callobject_info[i].call_handle == call_handle) {
229                         memcpy(pcall_object, &pMng->callobject_info[i], sizeof(call_vc_call_objectinfo_t));
230                         return TRUE;
231                 }
232         }
233
234         return FALSE;
235 }
236
237 /**
238  * This function retrieves the given call object info
239  *
240  * @return              This function returns TRUE on success and FALSE on failure
241  * @param[in]           pMng            Pointer to the call manager structure
242  * @param[in]           index           index of the object info to be retrieved
243  * @param[out]  pcall_object    Pointer to the call object info structure that should be retrieved
244  * @see                 _vc_core_cm_add_call_object, _vc_core_cm_remove_call_object, _vc_core_cm_set_call_object
245  */
246 gboolean _vc_core_cm_get_call_object_byindex(call_vc_manager_t *pMng, int index, call_vc_call_objectinfo_t *pcall_object)
247 {
248         int i = 0;
249
250         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
251         VOICECALL_RETURN_FALSE_IF_FAIL(index >= 0 && index <= 7);
252         VOICECALL_RETURN_FALSE_IF_FAIL(pcall_object != NULL);
253
254         for (i = 0; i < VC_MAX_CALL_MEMBER; i++) {
255                 if (i == index) {
256                         memcpy(pcall_object, &pMng->callobject_info[i], sizeof(call_vc_call_objectinfo_t));
257                         return TRUE;
258                 }
259         }
260
261         return FALSE;
262 }
263
264 /**
265  * This function retrieves the call state of a given call handle
266  *
267  * @return              This function returns the call state
268  * @param[in]           pMng            Pointer to the call manager structure
269  * @param[in]           call_handle     Call handle for which the state has to be retrieved
270  */
271 voicecall_call_state_t _vc_core_cm_get_call_state(call_vc_manager_t *pMng, call_vc_handle call_handle)
272 {
273         int i = 0;
274
275         VOICECALL_RETURN_VALUE_IF_FAIL(pMng != NULL, VC_CALL_STATE_NONE);
276         VOICECALL_RETURN_VALUE_IF_FAIL(call_handle != VC_TAPI_INVALID_CALLHANDLE, VC_CALL_STATE_NONE);
277
278         for (i = 0; i < VC_MAX_CALL_MEMBER; i++) {
279                 if (pMng->callobject_info[i].call_handle == call_handle) {
280                         return pMng->callobject_info[i].state;
281                 }
282         }
283
284         return VC_CALL_STATE_NONE;
285 }
286
287  /**
288  * This function retrieves the number of call members in various states of a call
289  *
290  * @return              Number of call members available
291  * @param[in]           pMng            Pointer to the call manager structure
292  */
293 int _vc_core_cm_get_call_member_count(call_vc_manager_t *pMng)
294 {
295         int i = 0;
296         int nCount = 0;
297
298         VOICECALL_RETURN_ZERO_IF_FAIL(pMng != NULL);
299
300         for (i = 0; i < VC_MAX_CALL_MEMBER; i++) {
301                 if (pMng->callobject_info[i].state != VC_CALL_STATE_NONE)
302                         nCount++;
303         }
304
305         CALL_ENG_DEBUG(ENG_DEBUG, "%d", nCount);
306
307         return nCount;
308 }
309
310 /**
311  * This function sets the given call object info to the given slot
312  *
313  * @return              This function returns the call object index on success and -1 on failure
314  * @param[in]           pMng            Pointer to the call manager structure
315  * @param[in]           pcall_object    Pointer to the call object info structure that need to be modified
316  * @see                 _vc_core_cm_add_call_object, _vc_core_cm_remove_call_object, _vc_core_cm_get_call_object
317  */
318 int _vc_core_cm_set_call_object(call_vc_manager_t *pMng, call_vc_call_objectinfo_t *pcall_object)
319 {
320         int i = 0;
321
322         VOICECALL_RETURN_INVALID_IF_FAIL(pMng != NULL);
323         VOICECALL_RETURN_INVALID_IF_FAIL(pcall_object != NULL);
324
325         for (i = 0; i < VC_MAX_CALL_MEMBER; i++) {
326                 if (pMng->callobject_info[i].call_handle == pcall_object->call_handle) {
327                         CALL_ENG_DEBUG(ENG_DEBUG, "[Call Handle = %d]", pcall_object->call_handle);
328                         memcpy(&pMng->callobject_info[i], pcall_object, sizeof(call_vc_call_objectinfo_t));
329                         return i;
330                 }
331         }
332
333         return VC_TAPI_INVALID_CALLHANDLE;
334 }
335
336 /**
337  * This function returns the number of calls in a given call state
338  *
339  * @return              This function returns the number of calls in the given state
340  * @param[in]           pMng            Pointer to the call manager structure
341  * @param[in]           state           The call state the number of which has to be retrieved
342  */
343 int _vc_core_cm_get_call_state_num(call_vc_manager_t *pMng, voicecall_call_state_t state)
344 {
345         int i = 0;
346         int count = 0;
347
348         VOICECALL_RETURN_ZERO_IF_FAIL(pMng != NULL);
349
350         for (i = 0; i < VC_MAX_CALL_MEMBER; i++) {
351                 if (pMng->callobject_info[i].state == state) {
352                         count++;
353                 }
354         }
355         return count;
356 }
357
358 static gboolean __call_vc_cm_gp_get_groupcall_pos(call_vc_manager_t *callStatusInfo, call_vc_handle call_handle, int *pGroup, int *pPos)
359 {
360         int group = 0;
361         int pos = 0;
362         gboolean bFound = FALSE;
363         call_vc_groupinfo_t *pcall_group_info = NULL;
364         call_vc_call_objectinfo_t *pcall_object_info = NULL;
365
366         VOICECALL_RETURN_FALSE_IF_FAIL(callStatusInfo != NULL);
367         VOICECALL_RETURN_FALSE_IF_FAIL(call_handle != VC_TAPI_INVALID_CALLHANDLE);
368         VOICECALL_RETURN_FALSE_IF_FAIL(pGroup != NULL);
369         VOICECALL_RETURN_FALSE_IF_FAIL(pPos != NULL);
370
371         /*Optimization: Avoiding Long dereferencing inside loops */
372         pcall_group_info = callStatusInfo->callgroup_info;
373         pcall_object_info = callStatusInfo->callobject_info;
374         for (group = 0; group < CALL_VC_CALL_GROUP_MAX; group++) {
375                 CALL_ENG_DEBUG(ENG_DEBUG, "callStatusInfo->callgroup_info[%d].num:%d", group, callStatusInfo->callgroup_info[group].num);
376                 for (pos = 0; pos < pcall_group_info[group].num; pos++) {
377                         int v = pcall_group_info[group].callobject_index[pos];
378                         if (pcall_object_info[v].call_handle == call_handle) {
379                                 bFound = TRUE;
380                                 break;
381                         }
382                 }
383                 if (bFound)
384                         break;
385         }
386
387         if (bFound == FALSE) {
388                 CALL_ENG_DEBUG(ENG_DEBUG, "fail to get");
389                 return FALSE;
390         }
391
392         *pGroup = group;
393         *pPos = pos;
394
395         return TRUE;
396
397 }
398
399 /**
400  * This function adds a call member to a group
401  *
402  * @return              This function returns TRUE on success and FALSE on failure
403  * @param[in]           pMng            Pointer to the call manager structure
404  * @param[in]           callobject_index        The object index of the call object to be added
405  * @see                 __vc_core_cm_remove_call_member_fromgroup
406  */
407 gboolean _vc_core_cm_add_call_member_togroup(call_vc_manager_t *pMng, int callobject_index)
408 {
409         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
410         VOICECALL_RETURN_FALSE_IF_FAIL(pMng->callgroup_info[CALL_VC_CALL_GROUP_1].state == CALL_VC_GROUP_STATE_NONE);
411
412         CALL_ENG_DEBUG(ENG_DEBUG, "member index=%d", callobject_index);
413
414         /* Every Member should be added to a new group when added for the first time. First check whether Group 0 has any members.
415            If Group 0 has any previous members then move all members in the Group 0 to  Group 1 and Group 0 must be in held state
416            as the current call is going to be active in the new group. Then add this new call to the Group 0 and Group 0 becomes active group */
417         if (pMng->callgroup_info[CALL_VC_CALL_GROUP_0].state != CALL_VC_GROUP_STATE_NONE) {
418                 CALL_ENG_DEBUG(ENG_DEBUG, "Copying Group 0 data to Group 1");
419                 VOICECALL_RETURN_FALSE_IF_FAIL(pMng->callgroup_info[CALL_VC_CALL_GROUP_0].state == CALL_VC_GROUP_STATE_HOLD);
420                 memcpy(&(pMng->callgroup_info[CALL_VC_CALL_GROUP_1]), &(pMng->callgroup_info[CALL_VC_CALL_GROUP_0]), sizeof(call_vc_groupinfo_t));
421         }
422
423         pMng->callgroup_info[CALL_VC_CALL_GROUP_0].num = 1;
424         pMng->callgroup_info[CALL_VC_CALL_GROUP_0].callobject_index[0] = callobject_index;
425         pMng->callgroup_info[CALL_VC_CALL_GROUP_0].state = CALL_VC_GROUP_STATE_ACTIVE;
426
427         /*If the currently added call is Incoming or Outgoing call then make the Incoming/Outgoing status
428            invalid since the call has been connected and added to call group */
429         if (callobject_index == pMng->setupcall_info.mocall_index) {
430                 pMng->setupcall_info.mocall_index = VC_INVALID_CALL_INDEX;
431                 pMng->setupcall_info.no_service_state = FALSE;
432         } else if (callobject_index == pMng->mtcall_index) {
433                 pMng->mtcall_index = VC_INVALID_CALL_INDEX;
434         } else {
435                 return FALSE;
436         }
437
438         return TRUE;
439
440 }
441
442 /**
443  * This function removes a call member to a group
444  *
445  * @return              This function returns TRUE on success and FALSE on failure
446  * @param[in]           pMng            Pointer to the call manager structure
447  * @param[in]           call_handle     The call handle to be removed
448  * @see                 _vc_core_cm_add_call_member_togroup
449  */
450 gboolean __vc_core_cm_remove_call_member_fromgroup(call_vc_manager_t *pMng, call_vc_handle call_handle)
451 {
452         int group = 0;
453         int pos = 0;
454         int i = 0;
455         call_vc_groupinfo_t *pcall_group_info = NULL;
456
457         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
458         VOICECALL_RETURN_FALSE_IF_FAIL(call_handle != VC_TAPI_INVALID_CALLHANDLE);
459
460         CALL_ENG_DEBUG(ENG_DEBUG, "Call Handle = %d", call_handle);
461
462         /*Findout the Index Group number and the index posistion in the group for the given call handle */
463         if (__call_vc_cm_gp_get_groupcall_pos(pMng, call_handle, &group, &pos) == FALSE) {
464                 CALL_ENG_DEBUG(ENG_DEBUG, "fail to remove");
465                 return FALSE;
466         }
467
468         /*Optimization: Avoiding Long dereferencing inside loops */
469         pcall_group_info = pMng->callgroup_info;
470         for (i = pos + 1; i < pMng->callgroup_info[group].num; i++) {
471                 pcall_group_info[group].callobject_index[i - 1] = pcall_group_info[group].callobject_index[i];
472         }
473
474         pcall_group_info[group].num--;
475
476         /*If the number of members in the group become 0, then make the group status to none */
477         if (pcall_group_info[group].num == 0) {
478                 pcall_group_info[group].state = CALL_VC_GROUP_STATE_NONE;
479
480                 /*If Group 0 becomes none and Group 1 has any  members , then move the Group 1 members to Group 0
481                    Always the Group 0 is prefered group by default, this logic is to simplify all other search mehods. */
482                 if ((group == 0) && (pcall_group_info[CALL_VC_CALL_GROUP_1].num > 0)) {
483                         memcpy(&(pcall_group_info[0]), &(pcall_group_info[1]), sizeof(call_vc_groupinfo_t));
484                         memset(&(pcall_group_info[1]), 0, sizeof(call_vc_groupinfo_t));
485                 }
486         }
487
488         return TRUE;
489
490 }
491
492 /**
493  * This function clears the call object information of the ended and finished calls
494  *
495  * @return              This function returns TRUE on success and FALSE on failure
496  * @param[in]           pMng            Pointer to the call manager structure
497  */
498 gboolean _vc_core_cm_clear_endcall_member(call_vc_manager_t *pMng)
499 {
500         int i = 0;
501         call_vc_call_objectinfo_t *pcall_object_info = NULL;
502
503         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
504
505         CALL_ENG_DEBUG(ENG_DEBUG, "...");
506
507         /*Optimization: Avoiding Long dereferencing inside loops */
508         pcall_object_info = pMng->callobject_info;
509         for (i = 0; i < VC_MAX_CALL_MEMBER; i++) {
510                 if ((pcall_object_info[i].state == VC_CALL_STATE_ENDED) || (pcall_object_info[i].state == VC_CALL_STATE_ENDED_FINISH)) {
511                         __vc_core_cm_remove_call_member_fromgroup(pMng, pcall_object_info[i].call_handle);
512
513                         _vc_core_cm_clear_call_object(&pcall_object_info[i]);
514                 }
515         }
516         return TRUE;
517 }
518
519 /**
520  * This function sets the state of a given group
521  *
522  * @return              void
523  * @param[in]           pMng            Pointer to the call manager structure
524  * @param[in]           nGroup          The call group for which the state needs to be changed
525  * @param[in]           state           The state to be set
526  * @see                 _vc_core_cm_swap_group_state, _vc_core_cm_get_call_pos_ingroup
527  */
528 void _vc_core_cm_set_group_state(call_vc_manager_t *pMng, int nGroup, call_vc_groupstate_t state)
529 {
530         CALL_ENG_DEBUG(ENG_DEBUG, "group=%d, state=%d", nGroup, state);
531
532         VOICECALL_RETURN_IF_FAIL(pMng != NULL);
533         /*Only Group 0 and Group 1 are possible */
534         VOICECALL_RETURN_IF_FAIL((nGroup >= CALL_VC_CALL_GROUP_0 && nGroup < CALL_VC_CALL_GROUP_MAX));
535         
536         pMng->callgroup_info[nGroup].state = state;
537 }
538
539 /**
540  * This function retrieves the index of the group given the call handle
541  *
542  * @return              Returns group index on success and -1 on failure
543  * @param[in]           pMng            Pointer to the call manager structure
544  * @param[in]           call_handle     The for which the group index has to be retrieved
545  * @see                 _vc_core_cm_set_group_state, _vc_core_cm_get_call_pos_ingroup
546  */
547 int _vc_core_cm_get_group_index(call_vc_manager_t *pMng, call_vc_handle call_handle)
548 {
549         int group = 0;
550         int index = 0;
551
552         VOICECALL_RETURN_INVALID_IF_FAIL(pMng != NULL);
553         VOICECALL_RETURN_INVALID_IF_FAIL(call_handle != VC_TAPI_INVALID_CALLHANDLE);
554
555         if (__call_vc_cm_gp_get_groupcall_pos(pMng, call_handle, &group, &index) == FALSE) {
556                 CALL_ENG_DEBUG(ENG_DEBUG, "fail");
557                 return VC_TAPI_INVALID_CALLHANDLE;
558         }
559
560         return group;
561 }
562
563 /**
564  * This function retrieves the index/position of the call info in the object info table for a given call handle
565  *
566  * @return              Returns index on success and -1 on failure
567  * @param[in]           pMng            Pointer to the call manager structure
568  * @param[in]           nGroup          Group ID
569  * @param[in]           call_handle     The call handle for which the call index has to be retrieved
570  * @see                 _vc_core_cm_get_group_index
571  */
572 int _vc_core_cm_get_call_pos_ingroup(call_vc_manager_t *pMng, int nGroup, call_vc_handle call_handle)
573 {
574         int i = 0;
575         int idx = 0;
576
577         VOICECALL_RETURN_INVALID_IF_FAIL(pMng != NULL);
578         VOICECALL_RETURN_INVALID_IF_FAIL((nGroup >= CALL_VC_CALL_GROUP_0 && nGroup < CALL_VC_CALL_GROUP_MAX));
579         VOICECALL_RETURN_INVALID_IF_FAIL(call_handle != VC_TAPI_INVALID_CALLHANDLE);
580
581         for (i = 0; i < pMng->callgroup_info[nGroup].num; i++) {
582                 idx = pMng->callgroup_info[nGroup].callobject_index[i];
583                 if (pMng->callobject_info[idx].call_handle == call_handle)
584                         return i;
585         }
586         return VC_TAPI_INVALID_CALLHANDLE;
587 }
588
589 /**
590  * This function swaps the state of the groups
591  *
592  * @return              Returns TRUE on success and FALSE on failure
593  * @param[in]           pMng            Pointer to the call manager structure
594  * @see                 _vc_core_cm_set_group_state
595  */
596 gboolean _vc_core_cm_swap_group_state(call_vc_manager_t *pMng)
597 {
598         int i = 0;
599
600         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
601
602         for (i = 0; i < CALL_VC_CALL_GROUP_MAX; i++) {
603                 if (pMng->callgroup_info[i].state == CALL_VC_GROUP_STATE_HOLD)
604                         pMng->callgroup_info[i].state = CALL_VC_GROUP_STATE_ACTIVE;
605                 else if (pMng->callgroup_info[i].state == CALL_VC_GROUP_STATE_ACTIVE)
606                         pMng->callgroup_info[i].state = CALL_VC_GROUP_STATE_HOLD;
607         }
608         return TRUE;
609 }
610
611 /**
612  * This function joins the groups
613  *
614  * @return              Returns TRUE on success and FALSE on failure
615  * @param[in]           pMng            Pointer to the call manager structure
616  * @see                 _vc_core_cm_split_group
617  */
618 gboolean _vc_core_cm_join_group(call_vc_manager_t *pMng)
619 {
620         int callIndex[VC_MAX_CALL_MEMBER];
621         int i = 0;
622         int j = 0;
623         int nCount = 0;
624         int totalMember = 0;
625
626         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
627
628         CALL_ENG_DEBUG(ENG_DEBUG, "");
629
630         totalMember = _vc_core_cm_get_total_members_ingroup(pMng);
631
632         CALL_ENG_DEBUG(ENG_DEBUG, "Total Members: %d", totalMember);
633
634         for (i = CALL_VC_CALL_GROUP_MAX - 1; i >= 0; i--) {
635                 for (j = 0; j < pMng->callgroup_info[i].num; j++) {
636                         callIndex[nCount] = pMng->callgroup_info[i].callobject_index[j];
637                         nCount++;
638                 }
639         }
640
641         VOICECALL_RETURN_FALSE_IF_FAIL(nCount <= VC_MAX_CALL_GROUP_MEMBER);
642
643         for (i = 0; i < nCount; i++) {
644                 pMng->callgroup_info[CALL_VC_CALL_GROUP_0].callobject_index[i] = callIndex[i];
645         }
646
647         pMng->callgroup_info[CALL_VC_CALL_GROUP_0].num = nCount;
648         if (nCount == 0)
649                 pMng->callgroup_info[CALL_VC_CALL_GROUP_0].state = CALL_VC_GROUP_STATE_NONE;
650         else
651                 pMng->callgroup_info[CALL_VC_CALL_GROUP_0].state = CALL_VC_GROUP_STATE_ACTIVE;
652
653         pMng->callgroup_info[CALL_VC_CALL_GROUP_1].num = 0;
654         pMng->callgroup_info[CALL_VC_CALL_GROUP_1].state = CALL_VC_GROUP_STATE_NONE;
655
656         return TRUE;
657
658 }
659
660 /**
661  * This function splits the group given a call handle
662  *
663  * @return              Returns TRUE on success and FALSE on failure
664  * @param[in]           pMng            Pointer to the call manager structure
665  * @param[in]           call_handle     Call handle
666  * @see                 _vc_core_cm_join_group
667  */
668 gboolean _vc_core_cm_split_group(call_vc_manager_t *pMng, call_vc_handle call_handle)
669 {
670         int group = 0;
671         int pos = 0;
672         int i = 0;
673         int count = 0;
674
675         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
676         VOICECALL_RETURN_FALSE_IF_FAIL(call_handle != VC_TAPI_INVALID_CALLHANDLE);
677
678         if (__call_vc_cm_gp_get_groupcall_pos(pMng, call_handle, &group, &pos) == FALSE) {
679                 CALL_ENG_DEBUG(ENG_DEBUG, "fail");
680                 return FALSE;
681         }
682
683         VOICECALL_RETURN_FALSE_IF_FAIL(group == 0);
684         VOICECALL_RETURN_FALSE_IF_FAIL(pMng->callgroup_info[CALL_VC_CALL_GROUP_1].state == CALL_VC_GROUP_STATE_NONE);
685
686         CALL_ENG_DEBUG(ENG_DEBUG, "group=%d, pos=%d, Call Handle = %d, title=%s", group, pos, call_handle, pMng->callobject_info[pMng->callgroup_info[group].callobject_index[pos]].tel_number);
687
688         for (i = 0; i < pMng->callgroup_info[0].num; i++) {
689                 if (i != pos) {
690                         pMng->callgroup_info[CALL_VC_CALL_GROUP_1].callobject_index[count] = pMng->callgroup_info[CALL_VC_CALL_GROUP_0].callobject_index[i];
691                         count++;
692                 }
693         }
694
695         pMng->callgroup_info[CALL_VC_CALL_GROUP_1].num = count;
696
697         if (count == 0)
698                 pMng->callgroup_info[CALL_VC_CALL_GROUP_1].state = CALL_VC_GROUP_STATE_NONE;
699         else
700                 pMng->callgroup_info[CALL_VC_CALL_GROUP_1].state = CALL_VC_GROUP_STATE_HOLD;
701
702         pMng->callgroup_info[CALL_VC_CALL_GROUP_0].num = 1;
703         pMng->callgroup_info[CALL_VC_CALL_GROUP_0].state = CALL_VC_GROUP_STATE_ACTIVE;
704         pMng->callgroup_info[CALL_VC_CALL_GROUP_0].callobject_index[0] = pMng->callgroup_info[CALL_VC_CALL_GROUP_0].callobject_index[pos];
705
706         return TRUE;
707
708 }
709
710 /**
711  * This function retreives the group state for the given group index
712  *
713  * @return              This function returns the group state
714  * @param[in]           pMng            Pointer to the call manager structure
715  * @param[in]           nGroup          group index
716  */
717 call_vc_groupstate_t _vc_core_cm_get_group_state(call_vc_manager_t *pMng, int nGroup)
718 {
719         VOICECALL_RETURN_VALUE_IF_FAIL(pMng != NULL, CALL_VC_GROUP_STATE_NONE);
720         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(nGroup, 0, 1, CALL_VC_GROUP_STATE_NONE);
721
722         return pMng->callgroup_info[nGroup].state;
723 }
724
725 /**
726  * This function retrieves the number of members in a group
727  *
728  * @return              Returns number of members in the group
729  * @param[in]           pMng            Pointer to the call manager structure
730  * @param[in]           nGroup          Group index
731  */
732 int _vc_core_cm_get_member_count_ingroup(call_vc_manager_t *pMng, int nGroup)
733 {
734         VOICECALL_RETURN_ZERO_IF_FAIL(pMng != NULL);
735         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(nGroup, 0, 1, CALL_VC_GROUP_STATE_NONE);
736
737         return pMng->callgroup_info[nGroup].num;
738 }
739
740 /**
741  * This function retrieves the total number of members in all the groups
742  *
743  * @return              Returns the total number of members
744  * @param[in]           pMng            Pointer to the call manager structure
745  */
746 int _vc_core_cm_get_total_members_ingroup(call_vc_manager_t *pMng)
747 {
748         VOICECALL_RETURN_ZERO_IF_FAIL(pMng != NULL);
749
750         CALL_ENG_DEBUG(ENG_DEBUG, "Members in Group 0: %d, Members in Group 1: %d", pMng->callgroup_info[CALL_VC_CALL_GROUP_0].num, pMng->callgroup_info[CALL_VC_CALL_GROUP_1].num);
751         return (pMng->callgroup_info[CALL_VC_CALL_GROUP_0].num + pMng->callgroup_info[CALL_VC_CALL_GROUP_1].num);
752 }
753
754 /**
755  * This function retrieves the number of connected members in a group
756  *
757  * @return              Returns number of connected members in the group
758  * @param[in]           pMng            Pointer to the call manager structure
759  * @param[in]           nGroup          Group index
760  */
761 int _vc_core_cm_get_connected_member_count_ingroup(call_vc_manager_t *pMng, int nGroup)
762 {
763         int i = 0;
764         int callIndex = 0;
765         int count = 0;
766
767         VOICECALL_RETURN_ZERO_IF_FAIL(pMng != NULL);
768         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(nGroup, 0, 1, CALL_VC_GROUP_STATE_NONE);
769
770         for (i = 0; i < pMng->callgroup_info[nGroup].num; i++) {
771                 callIndex = pMng->callgroup_info[nGroup].callobject_index[i];
772                 if ((pMng->callobject_info[callIndex].call_handle != VC_TAPI_INVALID_CALLHANDLE) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED_FINISH)) {
773                         count++;
774                 }
775         }
776         return count;
777
778 }
779
780 /**
781  * This function retrieves the total number of groups
782  *
783  * @return              Returns the total number of groups
784  * @param[in]           pMng            Pointer to the call manager structure
785  */
786 int _vc_core_cm_get_group_count(call_vc_manager_t *pMng)
787 {
788         int num = 0;
789         int i = 0;
790
791         VOICECALL_RETURN_ZERO_IF_FAIL(pMng != NULL);
792
793         for (i = 0; i < CALL_VC_CALL_GROUP_MAX; i++) {
794                 CALL_ENG_DEBUG(ENG_DEBUG, "pMng->callgroup_info[%d].num = %d", i, pMng->callgroup_info[i].num);
795
796                 if (pMng->callgroup_info[i].num != 0)
797                         num++;
798         }
799         return num;
800 }
801
802 /**
803  * This function retrieves the call state of a given group and object position
804  *
805  * @return              Returns call state of the object
806  * @param[in]           pMng            Pointer to the call manager structure
807  * @param[in]           nGroup          Group index
808  * @param[in]           nPos                    Call object index
809  */
810 voicecall_call_state_t _vc_core_cm_get_call_state_ingroup_byposition(call_vc_manager_t *pMng, int nGroup, int nPos)
811 {
812         int memIndex = 0;
813
814         VOICECALL_RETURN_VALUE_IF_FAIL(pMng != NULL, VC_CALL_STATE_NONE);
815         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(nGroup, 0, 1, VC_CALL_STATE_NONE);
816         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(nPos, 0, 4, VC_CALL_STATE_NONE);
817
818         if (pMng->callgroup_info[nGroup].state == CALL_VC_GROUP_STATE_NONE) {
819                 return VC_CALL_STATE_NONE;
820         }
821
822         if (nPos >= pMng->callgroup_info[nGroup].num) {
823                 return VC_CALL_STATE_NONE;
824         }
825
826         memIndex = pMng->callgroup_info[nGroup].callobject_index[nPos];
827
828         return pMng->callobject_info[memIndex].state;
829 }
830
831 /**
832  * This function retrieves the call object info of a given group and object position
833  *
834  * @return              Returns TRUE on success and FALSE on failure
835  * @param[in]           pMng            Pointer to the call manager structure
836  * @param[in]           nGroup          Group index
837  * @param[in]           nPos                    Call object index
838  * @param[out]  pcall_object    Pointer to the call object info structure
839  */
840 gboolean _vc_core_cm_get_call_info_ingroup_byposition(call_vc_manager_t *pMng, int nGroup, int nPos, call_vc_call_objectinfo_t *pcall_object)
841 {
842         int memIndex = 0;
843
844         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
845         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(nGroup, 0, 1, FALSE);
846         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(nPos, 0, 4, FALSE);
847
848         if (pMng->callgroup_info[nGroup].state == CALL_VC_GROUP_STATE_NONE)
849                 return FALSE;
850         if (nPos >= pMng->callgroup_info[nGroup].num)
851                 return FALSE;
852
853         memIndex = pMng->callgroup_info[nGroup].callobject_index[nPos];
854
855         memcpy(pcall_object, &pMng->callobject_info[memIndex], sizeof(call_vc_call_objectinfo_t));
856
857         return TRUE;
858 }
859
860 /**
861  * This function checks if connected call exists
862  *
863  * @return              Returns TRUE if call exist FALSE otherwise
864  * @param[in]           pMng            Pointer to the call manager structure
865  * @see                 _vc_core_cm_isexits_outgoing_call, _vc_core_cm_isexists_incoming_call
866  */
867 gboolean _vc_core_cm_isexists_connected_call(call_vc_manager_t *pMng)
868 {
869         int i = 0;
870         int group = 0;
871         int callIndex = 0;
872
873         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
874
875         for (group = 0; group < CALL_VC_CALL_GROUP_MAX; group++) {
876                 for (i = 0; i < pMng->callgroup_info[group].num; i++) {
877                         callIndex = pMng->callgroup_info[group].callobject_index[i];
878                         if ((pMng->callobject_info[callIndex].call_handle != VC_TAPI_INVALID_CALLHANDLE) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED_FINISH)) {
879                                 return TRUE;
880                         }
881                 }
882         }
883         return FALSE;
884
885 }
886
887 /**
888  * This function retrieves the group state for a given call ID of an
889  *
890  * @return              This function returns the group state
891  * @param[in]           pMng            Pointer to the call manager structure
892  * @param[in]           callID          The call ID of the object
893  */
894 call_vc_groupstate_t _vc_core_cm_get_group_state_callid(call_vc_manager_t *pMng, int callID)
895 {
896         int i = 0;
897         int nGroup = 0;
898         int callIndex = 0;
899
900         VOICECALL_RETURN_VALUE_IF_FAIL(pMng != NULL, CALL_VC_GROUP_STATE_NONE);
901         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(callID, 1, 7, FALSE);
902
903         for (nGroup = 0; nGroup < CALL_VC_CALL_GROUP_MAX; nGroup++) {
904                 if (pMng->callgroup_info[nGroup].state == CALL_VC_GROUP_STATE_NONE)
905                         continue;
906
907                 for (i = 0; i < pMng->callgroup_info[nGroup].num; i++) {
908                         callIndex = pMng->callgroup_info[nGroup].callobject_index[i];
909                         if (pMng->callobject_info[callIndex].call_id == callID) {
910                                 return pMng->callgroup_info[nGroup].state;
911                         }
912                 }
913         }
914
915         return CALL_VC_GROUP_STATE_NONE;
916
917 }
918
919 /**
920  * This function clears the outgoing call information
921  *
922  * @return              Returns TRUE on success and FALSE on failure
923  * @param[in]           pMng            Pointer to the call manager structure
924  * @see                 _vc_core_cm_set_outgoing_call
925  */
926 gboolean _vc_core_cm_clear_outgoing_call(call_vc_manager_t *pMng)
927 {
928
929         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
930
931         if (pMng->setupcall_info.mocall_index != VC_INVALID_CALL_INDEX) {
932                 _vc_core_cm_clear_call_object(&(pMng->callobject_info[pMng->setupcall_info.mocall_index]));
933                 pMng->setupcall_info.mocall_index = VC_INVALID_CALL_INDEX;
934                 pMng->setupcall_info.no_service_state = FALSE;
935                 pMng->setupcall_info.call_control_type = CALL_VC_SAT_CC_NONE;
936
937                 CALL_ENG_DEBUG(ENG_DEBUG, "remove outgoing call info");
938                 return TRUE;
939         }
940         return FALSE;
941 }
942
943 /**
944  * This function sets the out going call index
945  *
946  * @return              Returns TRUE on success and FALSE on failure
947  * @param[in]           pMng            Pointer to the call manager structure
948  * @param[in]           callIndex               Call index that needs to be set
949  * @see                 _vc_core_cm_clear_outgoing_call
950  */
951 gboolean _vc_core_cm_set_outgoing_call(call_vc_manager_t *pMng, int callIndex)
952 {
953         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
954
955         if (pMng->setupcall_info.mocall_index != VC_INVALID_CALL_INDEX) {
956                 CALL_ENG_DEBUG(ENG_DEBUG, "previous mo call not cleard!");
957                 return FALSE;
958         }
959         CALL_ENG_DEBUG(ENG_DEBUG, "index=%d", callIndex);
960
961         pMng->setupcall_info.mocall_index = callIndex;
962
963         return TRUE;
964 }
965
966 /**
967  * This function retrieves the outgoing call handle
968  *
969  * @return              Returns out going call handle on success and TAPI_INVALID_CALLHANDLE on failure
970  * @param[in]           pMng            Pointer to the call manager structure
971  */
972 call_vc_handle _vc_core_cm_get_outgoing_call_handle(call_vc_manager_t *pMng)
973 {
974         VOICECALL_RETURN_INVALID_IF_FAIL(pMng != NULL);
975
976         if (pMng->setupcall_info.mocall_index == VC_INVALID_CALL_INDEX) {
977                 return VC_TAPI_INVALID_CALLHANDLE;
978         }
979
980         return pMng->callobject_info[pMng->setupcall_info.mocall_index].call_handle;
981 }
982
983 /**
984  * This function retrieves the outgoing call information
985  *
986  * @return              Returns TRUE on success and FALSE on failure
987  * @param[in]           pMng            Pointer to the call manager structure
988  * @param[out]  pcall_object    Pointer to the call object info structure
989  * @see                 _vc_core_cm_set_outgoing_call_info
990  */
991 gboolean _vc_core_cm_get_outgoing_call_info(call_vc_manager_t *pMng, call_vc_call_objectinfo_t *pcall_object)
992 {
993         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
994
995         if (pMng->setupcall_info.mocall_index == VC_INVALID_CALL_INDEX)
996                 return FALSE;
997         memcpy(pcall_object, &pMng->callobject_info[pMng->setupcall_info.mocall_index], sizeof(call_vc_call_objectinfo_t));
998
999         return TRUE;
1000 }
1001
1002 /**
1003  * This function sets the given outgoing call information
1004  *
1005  * @return              Returns TRUE on success and FALSE on failure
1006  * @param[in]           pMng            Pointer to the call manager structure
1007  * @param[in]           pcall_object    Pointer to the call object info structure
1008  * @see                 _vc_core_cm_get_outgoing_call_info
1009  */
1010 gboolean _vc_core_cm_set_outgoing_call_info(call_vc_manager_t *pMng, call_vc_call_objectinfo_t *pcall_object)
1011 {
1012         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
1013
1014         if (pMng->setupcall_info.mocall_index == VC_INVALID_CALL_INDEX)
1015                 return FALSE;
1016         memcpy(&pMng->callobject_info[pMng->setupcall_info.mocall_index], pcall_object, sizeof(call_vc_call_objectinfo_t));
1017
1018         return TRUE;
1019 }
1020
1021 /**
1022  * This function checks if outgoing call exists
1023  *
1024  * @return              Returns TRUE if outgoing call exist FALSE otherwise
1025  * @param[in]           pMng            Pointer to the call manager structure
1026  * @see                 _vc_core_cm_isexists_incoming_call, _vc_core_cm_isexists_connected_call
1027  */
1028 gboolean _vc_core_cm_isexits_outgoing_call(call_vc_manager_t *pMng)
1029 {
1030         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
1031
1032         if (pMng->setupcall_info.mocall_index == VC_INVALID_CALL_INDEX)
1033                 return FALSE;
1034         else
1035                 return TRUE;
1036 }
1037
1038 /**
1039  * This function sets the incoming call index
1040  *
1041  * @return              Returns TRUE on success and FALSE on failure
1042  * @param[in]           pMng            Pointer to the call manager structure
1043  * @param[in]           callIndex               Call index of the incoming call
1044  */
1045 gboolean _vc_core_cm_set_incoming_call(call_vc_manager_t *pMng, int callIndex)
1046 {
1047         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
1048
1049         if (pMng->mtcall_index != VC_INVALID_CALL_INDEX) {
1050                 CALL_ENG_DEBUG(ENG_DEBUG, "previous mo call not cleard!");
1051                 return FALSE;
1052         }
1053         CALL_ENG_DEBUG(ENG_DEBUG, "index=%d", callIndex);
1054         pMng->mtcall_index = callIndex;
1055
1056         return TRUE;
1057 }
1058
1059 /**
1060 * This function retrieves the call handle of the incoming call
1061 *
1062 * @return               Returns the call handle if success, TAPI_INVALID_CALLHANDLE on failure
1063 * @param[in]            pMng            Pointer to the call manager structure
1064 * @see                  _vc_core_cm_get_incoming_call_info
1065 */
1066 call_vc_handle _vc_core_cm_get_incoming_call_handle(call_vc_manager_t *pMng)
1067 {
1068         VOICECALL_RETURN_INVALID_IF_FAIL(pMng != NULL);
1069
1070         if (pMng->mtcall_index == VC_INVALID_CALL_INDEX) {
1071                 return VC_TAPI_INVALID_CALLHANDLE;
1072         }
1073
1074         return pMng->callobject_info[pMng->mtcall_index].call_handle;
1075 }
1076
1077 /**
1078  * This function retrieves the call information of the incoming call
1079  *
1080  * @return              Returns TRUE on success and FALSE on failure
1081  * @param[in]           pMng            Pointer to the call manager structure
1082  * @param[out]  pcall_object    Pointer to the call object info structure
1083  * @see                 _vc_core_cm_get_incoming_call_info, __vc_core_cm_set_incoming_call_info
1084  */
1085 gboolean _vc_core_cm_get_incoming_call_info(call_vc_manager_t *pMng, call_vc_call_objectinfo_t *pcall_object)
1086 {
1087         call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1088         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
1089         VOICECALL_RETURN_FALSE_IF_FAIL(pcall_object != NULL);
1090
1091         call_handle = _vc_core_cm_get_incoming_call_handle(pMng);
1092         if (VC_TAPI_INVALID_CALLHANDLE == call_handle) {
1093                 return FALSE;
1094         }
1095         return _vc_core_cm_get_call_object(pMng, call_handle, pcall_object);
1096 }
1097
1098 /**
1099  * This function sets the call information of the incoming call
1100  *
1101  * @return              Returns TRUE on success and FALSE on failure
1102  * @param[in]           pMng            Pointer to the call manager structure
1103  * @param[in]           pcall_object    Pointer to the call object info structure
1104  * @see                 _vc_core_cm_get_incoming_call_info
1105  */
1106 gboolean __vc_core_cm_set_incoming_call_info(call_vc_manager_t *pMng, call_vc_call_objectinfo_t *pcall_object)
1107 {
1108         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
1109         VOICECALL_RETURN_FALSE_IF_FAIL(pcall_object != NULL);
1110
1111         if (VC_INVALID_CALL_INDEX == pMng->mtcall_index) {
1112                 return FALSE;
1113         }
1114         memcpy(&pMng->callobject_info[pMng->mtcall_index], pcall_object, sizeof(call_vc_call_objectinfo_t));
1115
1116         return TRUE;
1117 }
1118
1119 /**
1120  * This function checks if incoming call exists
1121  *
1122  * @return              Returns TRUE if call exist FALSE otherwise
1123  * @param[in]           pMng            Pointer to the call manager structure
1124  * @see                 _vc_core_cm_isexits_outgoing_call, _vc_core_cm_isexists_connected_call
1125  */
1126 gboolean _vc_core_cm_isexists_incoming_call(call_vc_manager_t *pMng)
1127 {
1128         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
1129         CALL_ENG_DEBUG(ENG_DEBUG, "[pMng=0x%x]", pMng);
1130
1131         CALL_ENG_DEBUG(ENG_DEBUG, "[pMng->mtcall_index=%d]", pMng->mtcall_index);
1132
1133         if (pMng->mtcall_index == VC_INVALID_CALL_INDEX)
1134                 return FALSE;
1135         else
1136                 return TRUE;
1137 }
1138
1139 /**
1140  * This function retrieves the call handle of a given group and object position
1141  *
1142  * @return              Returns call handle of the object
1143  * @param[in]           pMng            Pointer to the call manager structure
1144  * @param[in]           nGroup          Group index
1145  * @param[in]           nPos                    Call object index
1146  */
1147 call_vc_handle _vc_core_cm_get_call_handle_ingroup_byposition(call_vc_manager_t *pMng, int nGroup, int nPos)
1148 {
1149         int callIndex = 0;
1150
1151         VOICECALL_RETURN_INVALID_IF_FAIL(pMng != NULL);
1152         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(nGroup, 0, 1, VC_TAPI_INVALID_CALLHANDLE);
1153         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(nPos, 0, 4, VC_TAPI_INVALID_CALLHANDLE);
1154         VOICECALL_RETURN_INVALID_IF_FAIL(pMng->callgroup_info[nGroup].state != CALL_VC_GROUP_STATE_NONE);
1155         VOICECALL_RETURN_INVALID_IF_FAIL(nPos <= pMng->callgroup_info[nGroup].num);
1156
1157         callIndex = pMng->callgroup_info[nGroup].callobject_index[nPos];
1158
1159         return pMng->callobject_info[callIndex].call_handle;
1160 }
1161
1162 /**
1163  * This function retrieves the call handle of a given call ID
1164  *
1165  * @return              Returns call handle of the object
1166  * @param[in]           pMng            Pointer to the call manager structure
1167  * @param[in]           callID          Call ID for a given call object
1168  */
1169 call_vc_handle _vc_core_cm_get_call_handle_ingroup_bycallId(call_vc_manager_t *pMng, int callID)
1170 {
1171         int i = 0;
1172         call_vc_handle call_handle = VC_TAPI_INVALID_CALLHANDLE;
1173
1174         VOICECALL_RETURN_INVALID_IF_FAIL(pMng != NULL);
1175         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(callID, 1, 7, VC_TAPI_INVALID_CALLHANDLE);
1176
1177         for (i = 0; i < VC_MAX_CALL_MEMBER; i++) {
1178                 if (pMng->callobject_info[i].call_id == callID) {
1179                         return pMng->callobject_info[i].call_handle;
1180                 }
1181         }
1182
1183         CALL_ENG_DEBUG(ENG_DEBUG, "return VC_TAPI_INVALID_CALLHANDLE");
1184
1185         return call_handle;
1186
1187 }
1188
1189 /**
1190  * This function retrieves the call handle of a given telephone number
1191  *
1192  * @return              Returns call handle of the object
1193  * @param[in]           pMng            Pointer to the call manager structure
1194  * @param[in]           tel_number      Telephone number of a call object
1195  */
1196 call_vc_handle __vc_core_cm_get_call_handle_ingroup_bynumber(call_vc_manager_t *pMng, char *tel_number)
1197 {
1198         int group = 0;
1199         int i = 0;
1200         int callIndex = 0;
1201
1202         VOICECALL_RETURN_INVALID_IF_FAIL(pMng != NULL);
1203         VOICECALL_RETURN_INVALID_IF_FAIL(tel_number != NULL);
1204
1205         if (strlen(tel_number) == 0) {
1206                 return VC_TAPI_INVALID_CALLHANDLE;
1207         }
1208
1209         for (group = 0; group < CALL_VC_CALL_GROUP_MAX; group++) {
1210                 for (i = 0; i < pMng->callgroup_info[group].num; i++) {
1211                         callIndex = pMng->callgroup_info[group].callobject_index[i];
1212                         if (strcmp(pMng->callobject_info[callIndex].tel_number, tel_number) == 0) {
1213                                 return pMng->callobject_info[callIndex].call_handle;
1214                         }
1215                 }
1216         }
1217
1218         return VC_TAPI_INVALID_CALLHANDLE;
1219
1220 }
1221
1222 /**
1223  * This function retrieves the call handle of the first active call
1224  *
1225  * @return              Returns the call handle on sucess, -1 on failure
1226  * @param[in]           pMng            Pointer to the call manager structure
1227  * @param[in]           pCall           Pointer to the call handle where the retrieved call handle need to be stored
1228  * @see                 _vc_core_cm_get_next_active_call_handle
1229  */
1230 int _vc_core_cm_get_first_active_call_handle(call_vc_manager_t *pMng, call_vc_handle *pCall)
1231 {
1232         VOICECALL_RETURN_INVALID_IF_FAIL(pMng != NULL);
1233         VOICECALL_RETURN_INVALID_IF_FAIL(pCall != NULL);
1234
1235         if (_vc_core_cm_get_total_members_ingroup(pMng) == 0 && _vc_core_cm_isexits_outgoing_call(pMng)) {
1236                 *pCall = _vc_core_cm_get_outgoing_call_handle(pMng);
1237                 return VC_TAPI_INVALID_CALLHANDLE;
1238
1239         }
1240
1241         return _vc_core_cm_get_next_active_call_handle(pMng, pCall, 0);
1242 }
1243
1244 /**
1245  * This function retrieves the call handle of the first held call
1246  *
1247  * @return              Returns the call handle on sucess, -1 on failure
1248  * @param[in]           pMng            Pointer to the call manager structure
1249  * @param[in]           pCall           Pointer to the call handle where the retrieved call handle need to be stored
1250  * @see                 _vc_core_cm_get_next_held_call_handle
1251  */
1252 int _vc_core_cm_get_first_held_call_handle(call_vc_manager_t *pMng, call_vc_handle *pCall)
1253 {
1254         VOICECALL_RETURN_INVALID_IF_FAIL(pMng != NULL);
1255         VOICECALL_RETURN_INVALID_IF_FAIL(pCall != NULL);
1256
1257         return _vc_core_cm_get_next_held_call_handle(pMng, pCall, 0);
1258 }
1259
1260 /**
1261  * This function retrieves the next active call handle
1262  *
1263  * @return              Returns the call handle on sucess, -1 on failure
1264  * @param[in]           pMng            Pointer to the call manager structure
1265  * @param[in]           pCall           Pointer to the call handle where the retrieved call handle need to be stored
1266  * @param[in]           nPos                    Current position of the call object index
1267  * @see                 _vc_core_cm_get_first_active_call_handle
1268  */
1269 int _vc_core_cm_get_next_active_call_handle(call_vc_manager_t *pMng, call_vc_handle *pCall, int nPos)
1270 {
1271         int i = 0;
1272         int k = 0;
1273         int callIndex = 0;
1274
1275         VOICECALL_RETURN_INVALID_IF_FAIL(pMng != NULL);
1276         VOICECALL_RETURN_INVALID_IF_FAIL(pCall != NULL);
1277
1278         for (i = 0; i < CALL_VC_CALL_GROUP_MAX; i++) {
1279                 if (pMng->callgroup_info[i].state == CALL_VC_GROUP_STATE_ACTIVE)
1280                         break;
1281         }
1282         if (i == CALL_VC_CALL_GROUP_MAX) {
1283                 *pCall = VC_TAPI_INVALID_CALLHANDLE;
1284                 return VC_TAPI_INVALID_CALLHANDLE;
1285         }
1286
1287         for (k = nPos; k < pMng->callgroup_info[i].num; k++) {
1288                 callIndex = pMng->callgroup_info[i].callobject_index[k];
1289                 if ((pMng->callobject_info[callIndex].call_handle != VC_TAPI_INVALID_CALLHANDLE) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED_FINISH)) {
1290                         *pCall = pMng->callobject_info[callIndex].call_handle;
1291                         return k + 1;
1292                 }
1293         }
1294
1295         *pCall = VC_TAPI_INVALID_CALLHANDLE;
1296
1297         return VC_TAPI_INVALID_CALLHANDLE;
1298
1299 }
1300
1301 /**
1302  * This function retrieves the next held call handle
1303  *
1304  * @return              Returns the call handle on sucess, -1 on failure
1305  * @param[in]           pMng            Pointer to the call manager structure
1306  * @param[in]           pCall           Pointer to the call handle where the retrieved call handle need to be stored
1307  * @param[in]           nPos                    Current position of the call object index
1308  * @see                 _vc_core_cm_get_first_held_call_handle
1309  */
1310 int _vc_core_cm_get_next_held_call_handle(call_vc_manager_t *pMng, call_vc_handle *pCall, int nPos)
1311 {
1312         int i = 0;
1313         int k = 0;
1314         int callIndex = 0;
1315
1316         VOICECALL_RETURN_INVALID_IF_FAIL(pMng != NULL);
1317         VOICECALL_RETURN_INVALID_IF_FAIL(pCall != NULL);
1318
1319         for (i = 0; i < CALL_VC_CALL_GROUP_MAX; i++) {
1320                 if (pMng->callgroup_info[i].state == CALL_VC_GROUP_STATE_HOLD)
1321                         break;
1322         }
1323         if (i == CALL_VC_CALL_GROUP_MAX) {
1324                 *pCall = VC_TAPI_INVALID_CALLHANDLE;
1325                 return VC_TAPI_INVALID_CALLHANDLE;
1326         }
1327
1328         for (k = nPos; k < pMng->callgroup_info[i].num; k++) {
1329                 callIndex = pMng->callgroup_info[i].callobject_index[k];
1330                 if ((pMng->callobject_info[callIndex].call_handle != VC_TAPI_INVALID_CALLHANDLE) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED_FINISH)) {
1331                         *pCall = pMng->callobject_info[callIndex].call_handle;
1332                         return k + 1;
1333                 }
1334         }
1335
1336         *pCall = VC_TAPI_INVALID_CALLHANDLE;
1337
1338         return VC_TAPI_INVALID_CALLHANDLE;
1339
1340 }
1341
1342 /**
1343  * This function checks if active call exists
1344  *
1345  * @return              Returns TRUE if call exist FALSE otherwise
1346  * @param[in]           pMng            Pointer to the call manager structure
1347  * @see                 _vc_core_cm_isexists_held_call
1348  */
1349 gboolean _vc_core_cm_isexists_active_call(call_vc_manager_t *pMng)
1350 {
1351         int i = 0;
1352         int k = 0;
1353         int callIndex = 0;
1354
1355         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
1356
1357         for (i = 0; i < CALL_VC_CALL_GROUP_MAX; i++) {
1358                 if (pMng->callgroup_info[i].state == CALL_VC_GROUP_STATE_ACTIVE)
1359                         break;
1360         }
1361         if (i == CALL_VC_CALL_GROUP_MAX) {
1362                 return FALSE;
1363         }
1364
1365         for (k = 0; k < pMng->callgroup_info[i].num; k++) {
1366                 callIndex = pMng->callgroup_info[i].callobject_index[k];
1367                 if ((pMng->callobject_info[callIndex].call_handle != VC_TAPI_INVALID_CALLHANDLE) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED_FINISH)) {
1368                         CALL_ENG_DEBUG(ENG_DEBUG, "returns TRUE");
1369                         return TRUE;
1370                 }
1371         }
1372
1373         CALL_ENG_DEBUG(ENG_DEBUG, "returns FALSE");
1374
1375         return FALSE;
1376
1377 }
1378
1379 /**
1380  * This function checks if held call exists
1381  *
1382  * @return              Returns TRUE if call exist FALSE otherwise
1383  * @param[in]           pMng            Pointer to the call manager structure
1384  * @see                 _vc_core_cm_isexists_active_call
1385  */
1386 gboolean _vc_core_cm_isexists_held_call(call_vc_manager_t *pMng)
1387 {
1388         int i = 0;
1389         int k = 0;
1390         int callIndex = 0;
1391
1392         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
1393
1394         for (i = 0; i < CALL_VC_CALL_GROUP_MAX; i++) {
1395                 if (pMng->callgroup_info[i].state == CALL_VC_GROUP_STATE_HOLD)
1396                         break;
1397         }
1398         if (i == CALL_VC_CALL_GROUP_MAX) {
1399                 return FALSE;
1400         }
1401
1402         for (k = 0; k < pMng->callgroup_info[i].num; k++) {
1403                 callIndex = pMng->callgroup_info[i].callobject_index[k];
1404                 if ((pMng->callobject_info[callIndex].call_handle != VC_TAPI_INVALID_CALLHANDLE) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED_FINISH)) {
1405                         CALL_ENG_DEBUG(ENG_DEBUG, "returns TRUE");
1406
1407                         return TRUE;
1408                 }
1409         }
1410         CALL_ENG_DEBUG(ENG_DEBUG, "returns FALSE");
1411         return FALSE;
1412 }
1413
1414 /**
1415  * This function retrieves the number of active calls
1416  *
1417  * @return              Returns number of active calls
1418  * @param[in]           pMng            Pointer to the call manager structure
1419  * @see                 _vc_core_cm_get_held_call_count
1420  */
1421 int _vc_core_cm_get_active_call_count(call_vc_manager_t *pMng)
1422 {
1423         int i = 0;
1424         int k = 0;
1425         int callIndex = 0;
1426         int count = 0;
1427
1428         VOICECALL_RETURN_ZERO_IF_FAIL(pMng != NULL);
1429
1430         for (i = 0; i < CALL_VC_CALL_GROUP_MAX; i++) {
1431                 if (pMng->callgroup_info[i].state == CALL_VC_GROUP_STATE_ACTIVE)
1432                         break;
1433         }
1434         if (i == CALL_VC_CALL_GROUP_MAX) {
1435                 return 0;
1436         }
1437
1438         count = 0;
1439         for (k = 0; k < pMng->callgroup_info[i].num; k++) {
1440                 callIndex = pMng->callgroup_info[i].callobject_index[k];
1441                 if ((pMng->callobject_info[callIndex].call_handle != VC_TAPI_INVALID_CALLHANDLE) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED_FINISH)) {
1442                         count++;
1443                 }
1444         }
1445         return count;
1446 }
1447
1448 /**
1449  * This function retrieves the number of held calls
1450  *
1451  * @return              Returns number of held calls
1452  * @param[in]           pMng            Pointer to the call manager structure
1453  * @see                 _vc_core_cm_get_held_call_count
1454  */
1455 int _vc_core_cm_get_held_call_count(call_vc_manager_t *pMng)
1456 {
1457         int i = 0;
1458         int k = 0;
1459         int callIndex = 0;
1460         int count = 0;
1461
1462         VOICECALL_RETURN_ZERO_IF_FAIL(pMng != NULL);
1463
1464         for (i = 0; i < CALL_VC_CALL_GROUP_MAX; i++) {
1465                 if (pMng->callgroup_info[i].state == CALL_VC_GROUP_STATE_HOLD)
1466                         break;
1467         }
1468         if (i == CALL_VC_CALL_GROUP_MAX) {
1469                 return 0;
1470         }
1471
1472         count = 0;
1473         for (k = 0; k < pMng->callgroup_info[i].num; k++) {
1474                 callIndex = pMng->callgroup_info[i].callobject_index[k];
1475                 if ((pMng->callobject_info[callIndex].call_handle != VC_TAPI_INVALID_CALLHANDLE) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED_FINISH)) {
1476                         count++;
1477                 }
1478         }
1479         return count;
1480 }
1481
1482 /**
1483  * This function retrieves the group index of active calls
1484  *
1485  * @return              Returns the group index
1486  * @param[in]           pMng            Pointer to the call manager structure
1487  * @see                 _vc_core_cm_get_held_group_index
1488  */
1489 int _vc_core_cm_get_active_group_index(call_vc_manager_t *pMng)
1490 {
1491         int i = 0;
1492
1493         VOICECALL_RETURN_INVALID_IF_FAIL(pMng != NULL);
1494
1495         for (i = 0; i < CALL_VC_CALL_GROUP_MAX; i++) {
1496                 if (_vc_core_cm_get_group_state(pMng, i) == CALL_VC_GROUP_STATE_ACTIVE)
1497                         return i;
1498         }
1499         return VC_TAPI_INVALID_CALLHANDLE;
1500 }
1501
1502 /**
1503  * This function retrieves the group index of held calls
1504  *
1505  * @return              Returns the group index
1506  * @param[in]           pMng            Pointer to the call manager structure
1507  * @see                 _vc_core_cm_get_active_group_index
1508  */
1509 int _vc_core_cm_get_held_group_index(call_vc_manager_t *pMng)
1510 {
1511         int i = 0;
1512
1513         VOICECALL_RETURN_INVALID_IF_FAIL(pMng != NULL);
1514
1515         for (i = 0; i < CALL_VC_CALL_GROUP_MAX; i++) {
1516                 if (_vc_core_cm_get_group_state(pMng, i) == CALL_VC_GROUP_STATE_HOLD)
1517                         return i;
1518         }
1519         return VC_TAPI_INVALID_CALLHANDLE;
1520
1521 }
1522
1523  /**
1524  * This function changes the state of the given onject info
1525  *
1526  * @return              void
1527  * @param[in]           info                    Pointer to the call object into structure for which the state has to be changed
1528  * @param[in]           callState               State that needs to be set
1529  */
1530 void inline _vc_core_cm_change_call_state(call_vc_call_objectinfo_t *info, voicecall_call_state_t callState)
1531 {
1532         VOICECALL_RETURN_IF_FAIL(info != NULL);
1533         CALL_ENG_DEBUG(ENG_DEBUG, "Call Handle = %d..%s(%d)-->%s(%d))", info->call_handle, gaszCallStateName[info->state], info->state, gaszCallStateName[callState], callState);
1534         info->state = callState;
1535 }
1536
1537 /**
1538  * This function dumps the complete information in the call manager
1539  *
1540  * @return              void
1541  * @param[in]           info            Pointer to the call manager structure
1542  */
1543 void _vc_core_cm_test_dump(call_vc_manager_t *info)
1544 {
1545         int i = 0;
1546         int j = 0;
1547         int count = 0;
1548         char szBuffer[320];
1549
1550         VOICECALL_RETURN_IF_FAIL(info != NULL);
1551         CALL_ENG_DEBUG(ENG_ERR, "************START*****************CALL_DETAILS_DUMP************START*****************");
1552
1553         for (i = 0; i < CALL_VC_CALL_GROUP_MAX; i++) {
1554                 char szTemp[10];
1555                 memset(szTemp, 0, sizeof(szTemp));
1556                 if (info->callgroup_info[i].state == CALL_VC_GROUP_STATE_NONE) {
1557                         snprintf(szTemp, 5, "%s", "NONE");
1558                 } else if (info->callgroup_info[i].state == CALL_VC_GROUP_STATE_ACTIVE) {
1559                         snprintf(szTemp, 7, "%s", "ACTIVE");
1560                 } else if (info->callgroup_info[i].state == CALL_VC_GROUP_STATE_HOLD) {
1561                         snprintf(szTemp, 5, "%s", "HOLD");
1562                 }
1563
1564                 snprintf(szBuffer, (27 + sizeof(i) + sizeof(int) + sizeof(szTemp)), "__________ group=%d(num=%d) %s", i, info->callgroup_info[i].num, szTemp);
1565                 CALL_ENG_DEBUG(ENG_ERR, "%s", szBuffer);
1566                 for (j = 0; j < info->callgroup_info[i].num; j++) {
1567                         snprintf(szBuffer, (50 + sizeof(j) + sizeof(int) + sizeof(int) + VC_PHONE_NUMBER_LENGTH_MAX),
1568                                  "             __pos=%d, bufindex=%d, Call Handle = %d, [%s], state:[%d]",
1569                                  j, info->callgroup_info[i].callobject_index[j],
1570                                  info->callobject_info[info->callgroup_info[i].callobject_index[j]].call_handle,
1571                                  info->callobject_info[info->callgroup_info[i].callobject_index[j]].tel_number, info->callobject_info[info->callgroup_info[i].callobject_index[j]].state);
1572                         CALL_ENG_DEBUG(ENG_ERR, "%s", szBuffer);
1573                 }
1574         }
1575         if (info->setupcall_info.mocall_index == VC_INVALID_CALL_INDEX) {
1576                 CALL_ENG_DEBUG(ENG_ERR, "_______ MO call not exist");
1577         } else {
1578                 CALL_ENG_DEBUG(ENG_ERR, "_______ MO callIndex=%d, Call Handle = %d, %s",
1579                                info->setupcall_info.mocall_index, info->callobject_info[info->setupcall_info.mocall_index].call_handle, info->callobject_info[info->setupcall_info.mocall_index].tel_number);
1580         }
1581         if (info->mtcall_index == VC_INVALID_CALL_INDEX) {
1582                 CALL_ENG_DEBUG(ENG_ERR, "_______ MT call not exist");
1583         } else {
1584                 CALL_ENG_DEBUG(ENG_ERR, "_______ MT callIndex=%d, Call Handle = %d, [%s], state:[%d]",
1585                                info->mtcall_index, info->callobject_info[info->mtcall_index].call_handle, info->callobject_info[info->mtcall_index].tel_number, info->callobject_info[info->mtcall_index].state);
1586         }
1587         count = 0;
1588         for (i = 0; i < VC_MAX_CALL_MEMBER; i++) {
1589                 if (info->callobject_info[i].call_handle != VC_TAPI_INVALID_CALLHANDLE) {
1590                         count++;
1591                 }
1592         }
1593         CALL_ENG_DEBUG(ENG_ERR, "____Call Handle Num=%d", count);
1594         CALL_ENG_DEBUG(ENG_ERR, "**************END*****************CALL_DETAILS_DUMP**************END*****************");
1595 }
1596
1597 #ifdef UNUSED_APIS
1598 unsigned long call_vc_cm_search_oldcall(call_vc_manager_t *pMng, gboolean activegroup)
1599 {
1600         int index = 0;
1601         int totalmember = 0;
1602         int k = 0;
1603         int min = 0;
1604         unsigned long mintmconnected = 0;
1605
1606         VOICECALL_RETURN_VALUE_IF_FAIL(pMng != NULL, 0);
1607         if (activegroup == TRUE) {
1608                 index = _vc_core_cm_get_active_group_index(pMng);
1609         } else if (activegroup == FALSE) {
1610                 index = _vc_core_cm_get_held_group_index(pMng);
1611         }
1612
1613         totalmember = pMng->callgroup_info[index].num;
1614
1615         if (totalmember > 1) {
1616                 for (k = 1; k < totalmember; k++) {
1617                         if (pMng->callobject_info[pMng->callgroup_info[index].callobject_index[k]].connected_time < pMng->callobject_info[pMng->callgroup_info[index].callobject_index[min]].connected_time) {
1618                                 min = k;
1619                         }
1620                 }
1621                 mintmconnected = pMng->callobject_info[pMng->callgroup_info[index].callobject_index[min]].connected_time;
1622         } else if (totalmember == 1)
1623                 mintmconnected = pMng->callobject_info[pMng->callgroup_info[index].callobject_index[0]].connected_time;
1624
1625         CALL_ENG_DEBUG(ENG_DEBUG, "index = %d", index);
1626         CALL_ENG_DEBUG(ENG_DEBUG, "totalmember = %d", totalmember);
1627         CALL_ENG_DEBUG(ENG_DEBUG, "min = %d", min);
1628         CALL_ENG_DEBUG(ENG_DEBUG, "min tmconnected = %d", mintmconnected);
1629
1630         return mintmconnected;
1631
1632 }
1633
1634 unsigned long call_vc_cm_search_next_oldcall(call_vc_manager_t *pMng, gboolean activegroup, call_vc_handle call_handle)
1635 {
1636         int index = 0;
1637         int totalmember = 0;
1638         int i = 0;
1639         int k = 0;
1640         int min = 0;
1641         int j = 0;
1642         int searchinfonum = 0;
1643         unsigned long mintmconnected = 0xFFFF;
1644         unsigned long searchInfo[VC_MAX_CALL_GROUP_MEMBER];
1645
1646         VOICECALL_RETURN_VALUE_IF_FAIL(pMng != NULL, 0);
1647         CALL_ENG_DEBUG(ENG_DEBUG, "ended call_handle = %d", call_handle);
1648
1649         if (activegroup == TRUE) {
1650                 index = _vc_core_cm_get_active_group_index(pMng);
1651         } else if (activegroup == FALSE) {
1652                 index = _vc_core_cm_get_held_group_index(pMng);
1653         }
1654
1655         totalmember = pMng->callgroup_info[index].num;
1656
1657         CALL_ENG_DEBUG(ENG_DEBUG, "totalmember = %d", totalmember);
1658
1659         for (i = 0; i < totalmember; i++) {
1660                 if (pMng->callobject_info[pMng->callgroup_info[index].callobject_index[i]].call_handle != call_handle) {
1661                         searchInfo[j] = pMng->callobject_info[pMng->callgroup_info[index].callobject_index[i]].connected_time;
1662                         CALL_ENG_DEBUG(ENG_DEBUG, "searchInfo[%d] = %d", j, searchInfo[j]);
1663                         j = j + 1;
1664                 }
1665         }
1666
1667         searchinfonum = j;
1668
1669         CALL_ENG_DEBUG(ENG_DEBUG, "searchinfonum = %d", searchinfonum);
1670
1671         if (searchinfonum > 1) {
1672                 for (k = 1; k < searchinfonum; k++) {
1673                         if (searchInfo[k] < searchInfo[min]) {
1674                                 min = k;
1675                         }
1676                 }
1677                 mintmconnected = searchInfo[min];
1678         } else if (searchinfonum == 1)
1679                 mintmconnected = searchInfo[0];
1680
1681         CALL_ENG_DEBUG(ENG_DEBUG, "index = %d", index);
1682         CALL_ENG_DEBUG(ENG_DEBUG, "min = %d", min);
1683         CALL_ENG_DEBUG(ENG_DEBUG, "min tmconnected = %d", mintmconnected);
1684
1685         return mintmconnected;
1686
1687 }
1688
1689 unsigned long call_vc_cm_gp_get_calltm_connected(call_vc_manager_t *pMng, int nGroup, int nPos)
1690 {
1691         int callIndex = 0;
1692         VOICECALL_RETURN_VALUE_IF_FAIL(pMng != NULL, 0);
1693         VOICECALL_RETURN_VALUE_IF_FAIL((nGroup >= CALL_VC_CALL_GROUP_0 && nGroup < CALL_VC_CALL_GROUP_MAX), 0);
1694         VOICECALL_RETURN_VALUE_IF_NOT_IN_RANGE(nPos, 0, 4, 0);
1695
1696         callIndex = pMng->callgroup_info[nGroup].callobject_index[nPos];
1697         return pMng->callobject_info[callIndex].connected_time;
1698 }
1699
1700 gboolean call_vc_cm_search_activecall(call_vc_manager_t *pMng, call_vc_handle call_handle)
1701 {
1702         int i = 0;
1703         int k = 0;
1704         int callIndex = 0;
1705
1706         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
1707
1708         for (i = 0; i < CALL_VC_CALL_GROUP_MAX; i++) {
1709                 if (pMng->callgroup_info[i].state == CALL_VC_GROUP_STATE_ACTIVE)
1710                         break;
1711         }
1712         if (i == CALL_VC_CALL_GROUP_MAX) {
1713                 return FALSE;
1714         }
1715         for (k = 0; k < pMng->callgroup_info[i].num; k++) {
1716                 callIndex = pMng->callgroup_info[i].callobject_index[k];
1717                 if ((pMng->callobject_info[callIndex].call_handle != VC_TAPI_INVALID_CALLHANDLE) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED_FINISH)) {
1718                         if (call_handle == pMng->callobject_info[callIndex].call_handle)
1719                                 return TRUE;
1720                 }
1721         }
1722         return FALSE;
1723
1724 }
1725
1726 gboolean call_vc_cm_search_activecall_ctinfo(call_vc_manager_t *pMng, call_vc_handle call_handle)
1727 {
1728         int i = 0;
1729         int k = 0;
1730         int callIndex = 0;
1731         gboolean bctinfo_found = FALSE;
1732         gboolean bctinfo_atleast_one_found = FALSE;
1733
1734         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
1735
1736         for (i = 0; i < CALL_VC_CALL_GROUP_MAX; i++) {
1737                 if (pMng->callgroup_info[i].state == CALL_VC_GROUP_STATE_ACTIVE)
1738                         break;
1739         }
1740         if (i == CALL_VC_CALL_GROUP_MAX) {
1741                 return FALSE;
1742         }
1743         for (k = 0; k < pMng->callgroup_info[i].num; k++) {
1744                 callIndex = pMng->callgroup_info[i].callobject_index[k];
1745                 if ((pMng->callobject_info[callIndex].call_handle != VC_TAPI_INVALID_CALLHANDLE) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED_FINISH)) {
1746                         bctinfo_found = pMng->callobject_info[callIndex].bctinfo_found;
1747                         CALL_ENG_DEBUG(ENG_DEBUG, "pMng->callobject_info[%d].bctinfo_found (%d).", callIndex, pMng->callobject_info[callIndex].bctinfo_found);
1748                 }
1749
1750                 bctinfo_atleast_one_found = bctinfo_found || bctinfo_atleast_one_found;
1751
1752         }
1753
1754         return bctinfo_atleast_one_found;
1755
1756 }
1757
1758 gboolean call_vc_cm_search_holdcall(call_vc_manager_t *pMng, call_vc_handle call_handle)
1759 {
1760         int i = 0;
1761         int k = 0;
1762         int callIndex = 0;
1763
1764         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
1765
1766         for (i = 0; i < CALL_VC_CALL_GROUP_MAX; i++) {
1767                 if (pMng->callgroup_info[i].state == CALL_VC_GROUP_STATE_HOLD)
1768                         break;
1769         }
1770         if (i == CALL_VC_CALL_GROUP_MAX) {
1771                 return FALSE;
1772         }
1773         for (k = 0; k < pMng->callgroup_info[i].num; k++) {
1774                 callIndex = pMng->callgroup_info[i].callobject_index[k];
1775                 if ((pMng->callobject_info[callIndex].call_handle != VC_TAPI_INVALID_CALLHANDLE) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED_FINISH)) {
1776                         if (call_handle == pMng->callobject_info[callIndex].call_handle)
1777                                 return TRUE;
1778                 }
1779         }
1780         return FALSE;
1781 }
1782
1783 gboolean call_vc_cm_search_holdcall_ctinfo(call_vc_manager_t *pMng, call_vc_handle call_handle)
1784 {
1785         int i = 0;
1786         int k = 0 callIndex;
1787         gboolean bctinfo_found = FALSE;
1788         gboolean bCtInfoAtLeastOnde = FALSE;
1789
1790         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
1791
1792         for (i = 0; i < CALL_VC_CALL_GROUP_MAX; i++) {
1793                 if (pMng->callgroup_info[i].state == CALL_VC_GROUP_STATE_HOLD)
1794                         break;
1795         }
1796         if (i == CALL_VC_CALL_GROUP_MAX) {
1797                 return FALSE;
1798         }
1799         for (k = 0; k < pMng->callgroup_info[i].num; k++) {
1800                 callIndex = pMng->callgroup_info[i].callobject_index[k];
1801                 if ((pMng->callobject_info[callIndex].call_handle != VC_TAPI_INVALID_CALLHANDLE) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED) && (pMng->callobject_info[callIndex].state != VC_CALL_STATE_ENDED_FINISH)) {
1802                         bctinfo_found = pMng->callobject_info[callIndex].bctinfo_found;
1803                         CALL_ENG_DEBUG(ENG_DEBUG, "pMng->callobject_info[%d].bctinfo_found (%d).", callIndex, pMng->callobject_info[callIndex].bctinfo_found);
1804                 }
1805
1806                 bCtInfoAtLeastOnde = bctinfo_found || bCtInfoAtLeastOnde;
1807         }
1808         return bCtInfoAtLeastOnde;
1809 }
1810 #endif
1811
1812 /**
1813  * This function retrieves an available call ID
1814  *
1815  * @return              Call ID on success, -1 on failure
1816  * @param[in]           pMng            Pointer to the call manager structure
1817  */
1818 int _vc_core_cm_get_new_callId(call_vc_manager_t *pMng)
1819 {
1820         gboolean bCheck[VC_MAX_CALL_ID];
1821         int i = 0;
1822
1823         VOICECALL_RETURN_VALUE_IF_FAIL(pMng != NULL, VC_TAPI_INVALID_CALLHANDLE);
1824         
1825         memset(bCheck, 0, sizeof(bCheck));
1826         for (i = 0; i < VC_MAX_CALL_MEMBER; i++) {
1827                 if ((pMng->callobject_info[i].state != VC_CALL_STATE_ENDED) && (pMng->callobject_info[i].state != VC_CALL_STATE_ENDED_FINISH)) {
1828                         VOICECALL_RETURN_INVALID_IF_FAIL(((pMng->callobject_info[i].call_id >= 0) && (pMng->callobject_info[i].call_id <= VC_MAX_CALL_ID)));
1829                         if (pMng->callobject_info[i].call_id != 0) {
1830                                 bCheck[pMng->callobject_info[i].call_id - 1] = TRUE;
1831                         }
1832                 }
1833         }
1834
1835         for (i = 0; i < VC_MAX_CALL_ID; i++) {
1836                 if (bCheck[i] == FALSE) {
1837                         CALL_ENG_DEBUG(ENG_DEBUG, "CallID=%d", i + 1);
1838                         return i + 1;
1839                 }
1840         }
1841         CALL_ENG_DEBUG(ENG_DEBUG, "fail to get id!");
1842         return VC_TAPI_INVALID_CALLHANDLE;
1843 }
1844
1845 /**
1846  * This function checks if active/ held exists
1847  *
1848  * @return              Returns TRUE if success else FALSE
1849  * @param[in]           pMng            Pointer to the call manager structure
1850  * @param[out]  active_calls    TRUE if active call exists, FALSE if held call exists
1851  * @param[out]  held_calls      TRUE if held call exists, FALSE if held call exists
1852  * @see                 _vc_core_cm_isexits_outgoing_call, _vc_core_cm_isexists_connected_call
1853  */
1854 gboolean _vc_core_cm_isexists_call_ingroup(call_vc_manager_t *pMng, int *active_calls, int *held_calls)
1855 {
1856         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
1857         VOICECALL_RETURN_FALSE_IF_FAIL(active_calls != NULL);
1858         VOICECALL_RETURN_FALSE_IF_FAIL(held_calls != NULL);
1859
1860         *active_calls = _vc_core_cm_isexists_active_call(pMng);
1861         *held_calls = _vc_core_cm_isexists_held_call(pMng);
1862
1863         CALL_ENG_DEBUG(ENG_DEBUG, "act_calls :%d", *active_calls);
1864         CALL_ENG_DEBUG(ENG_DEBUG, "hld_calls :%d", *held_calls);
1865
1866         return TRUE;
1867 }
1868
1869 /**
1870  * This function changes the call state of the call object corresponds to the given call handle
1871  *
1872  * @return              Returns TRUE if success else FALSE
1873  * @param[in]           pMng            Pointer to the call manager structure
1874  * @param[out]  call_handle     Call Handle of the Callobject to be modified
1875  * @param[out]  callState               New call state to be set
1876  */
1877 gboolean _vc_core_cm_change_call_object_state(call_vc_manager_t *pMng, call_vc_handle call_handle, voicecall_call_state_t callState)
1878 {
1879         call_vc_call_objectinfo_t callobject_info;
1880         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
1881
1882         if (VC_TAPI_INVALID_CALLHANDLE == call_handle)
1883                 return FALSE;
1884
1885         _vc_core_cm_clear_call_object(&callobject_info);
1886
1887         if (!_vc_core_cm_get_call_object(pMng, call_handle, &callobject_info))
1888                 return FALSE;
1889
1890         _vc_core_cm_change_call_state(&callobject_info, callState);
1891
1892         _vc_core_cm_set_call_object(pMng, &callobject_info);
1893
1894         return TRUE;
1895
1896 }
1897
1898 gboolean _vc_core_cm_get_ending_call_info(call_vc_manager_t *pMng)
1899 {
1900         int i = 0;
1901         gboolean bcall_ending = FALSE;
1902         VOICECALL_RETURN_FALSE_IF_FAIL(pMng != NULL);
1903
1904         for (i = 0; i < VC_MAX_CALL_MEMBER; i++) {
1905                 if ((pMng->callobject_info[i].state == VC_CALL_STATE_ENDED) || (pMng->callobject_info[i].state == VC_CALL_STATE_ENDED_FINISH)) {
1906
1907                         CALL_ENG_DEBUG(ENG_DEBUG, "Tel(%s) is ending!!", pMng->callobject_info[i].tel_number);
1908                         bcall_ending = TRUE;
1909                         break;
1910                 }
1911         }
1912         return bcall_ending;
1913 }