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.
18 #include "vc-core-util.h"
19 #include "vc-core-engine-status.h"
20 #include "vc-core-engine-group.h"
21 #include "voice-call-core.h"
22 #include "voice-call-sound.h"
23 #include "voice-call-bt.h"
25 #include "vconf-keys.h"
26 #include "voice-call-dbus.h"
27 #include "voice-call-engine-msg.h"
29 /* For Debug Information, name string constant */
31 static char *gszbt_res_event[BT_AG_RES_CALL_SWAPPED + 1] = {
32 "BT_AG_RES_CALL_ORIG",
33 "BT_AG_RES_CALL_INCOM",
34 "BT_AG_RES_CALL_CONNECT",
36 "BT_AG_RES_CALL_HOLD",
37 "BT_AG_RES_CALL_RETRIEVE",
38 "BT_AG_RES_CALL_JOINED",
41 "BT_AG_RES_CALL_REMOTE_RINGING",
42 "BT_AG_RES_SWITCH_TO_HEADSET",
43 "BT_AG_RES_SWITCH_TO_PHONE",
44 "BT_AG_RES_CALL_STATUS",
45 "BT_AG_RES_HEADSET_VOL",
46 "BT_AG_RES_CALL_SWAPPED"
50 static char *gszbt_req_event[BT_AG_REQ_CALL_STATUS + 1] = {
52 "BT_AG_REQ_CONNECT_ERROR",
53 "BT_AG_REQ_DISCONNECT",
56 "BT_AG_REQ_CALL_ACCEPTED",
57 "BT_AG_REQ_CALL_REJECT",
59 "BT_AG_REQ_CALL_HOLD",
60 "BT_AG_REQ_CALL_RETRIEVE",
61 "BT_AG_REQ_BUTTON_PRESSED",
62 "BT_AG_REQ_CALL_REDIAL",
63 "BT_AG_REQ_CALL_2_SEND",
64 "BT_AG_REQ_CALL_3_SEND",
65 "BT_AG_REQ_CALL_0_SEND",
66 "BT_AG_REQ_CALL_1_SEND",
67 "BT_AG_REQ_HEADSET_VOL",
68 "BT_AG_REQ_SWITCH_TO_HEADSET",
69 "BT_AG_REQ_SWITCH_TO_PHONE",
71 "BT_AG_REQ_CALL_STATUS"
74 static gboolean b_user_rqst_path_change = FALSE;
75 static int __vc_bt_converted_bt_vol_to_voice_vol(int bt_vol_level);
76 static void __vc_bt_handle_connectivity_event(call_vc_core_state_t *pcall_core, gboolean bt_headset_connect_status);
78 static int __vc_bt_converted_bt_vol_to_voice_vol(int bt_vol_level)
80 int converted_vol_level = -1;
82 if (bt_vol_level <= 0) {
83 converted_vol_level = 1;
84 } else if (bt_vol_level > 15) {
85 converted_vol_level = 15;
87 converted_vol_level = bt_vol_level;
89 return converted_vol_level;
92 static void __vc_bt_handle_connectivity_event(call_vc_core_state_t *pcall_core, gboolean bt_headset_connect_status)
94 VOICECALL_RETURN_IF_FAIL(pcall_core != NULL);
96 voicecall_engine_t *pcall_engine = pcall_core->pcall_engine;
98 CALL_ENG_DEBUG(ENG_DEBUG, "bt_headset_connect_status = %d", bt_headset_connect_status);
99 if (FALSE == bt_headset_connect_status) {
100 voicecall_core_set_status(pcall_core, CALL_VC_CORE_FLAG_BT_EVENT_WAITING, FALSE);
103 if (bt_headset_connect_status == pcall_core->bt_connected) {
104 CALL_ENG_DEBUG(ENG_DEBUG, "No change in state, Ignoring Event");
105 CALL_ENG_DEBUG(ENG_DEBUG, "bt_headset_connect_status = %d", bt_headset_connect_status);
108 pcall_core->bt_connected = bt_headset_connect_status;
110 if (TRUE == pcall_core->bt_connected) {
111 /*Check the Call Status and Send Response event to the Bluetooth */
112 int call_handle = -1;
114 CALL_ENG_DEBUG(ENG_DEBUG, "BT connected, Not changing the sound status");
115 /* Headset is connected, Set the Sound Status to Headset
116 and change the path only incase of mocall and connected call */
118 _vc_core_engine_status_get_call_handle_bytype(pcall_engine, VC_INCOMING_CALL, &call_handle);
119 if (call_handle != -1) {
120 call_vc_call_objectinfo_t callobject_info;
122 CALL_ENG_DEBUG(ENG_DEBUG, "Incoming Call Exists, call handle = %d", call_handle);
124 voicecall_core_get_call_object(pcall_engine, call_handle, &callobject_info);
126 /*Incoming Call Exists */
127 _vc_bt_send_response_to_bt(pcall_core, BT_AG_RES_CALL_INCOM, call_handle, callobject_info.tel_number);
131 _vc_core_engine_status_get_call_handle_bytype(pcall_engine, VC_OUTGOING_CALL, &call_handle);
132 if (call_handle != -1) {
133 int io_state = VC_INOUT_STATE_NONE;
135 CALL_ENG_DEBUG(ENG_DEBUG, "Outgoing Call Exists, call handle = %d", call_handle);
136 _vc_core_engine_status_get_engine_iostate(pcall_engine, &io_state);
139 case VC_INOUT_STATE_OUTGOING_WAIT_ORIG:
140 case VC_INOUT_STATE_OUTGOING_WAIT_ALERT: /*Fall Through */
142 call_vc_call_objectinfo_t callobject_info;
144 voicecall_core_get_call_object(pcall_engine, call_handle, &callobject_info);
146 _vc_bt_send_response_to_bt(pcall_core, BT_AG_RES_CALL_ORIG, call_handle, callobject_info.tel_number);
149 case VC_INOUT_STATE_OUTGOING_WAIT_CONNECTED:
151 _vc_bt_send_response_to_bt(pcall_core, BT_AG_RES_CALL_REMOTE_RINGING, call_handle, NULL);
152 voicecall_snd_set_path_status(pcall_core->papp_snd, VOICE_CALL_SND_PATH_BT);
153 _vc_bt_request_switch_headset_path(pcall_core, TRUE);
158 CALL_ENG_DEBUG(ENG_DEBUG, "Engine not in desired IO State, Current IO State: %d", io_state);
167 _vc_core_engine_status_get_call_handle_bytype(pcall_engine, VC_CONNECTED_CALL, &call_handle);
168 if (call_handle != -1) {
169 CALL_ENG_DEBUG(ENG_DEBUG, "Connected Call Exists, call handle = %d", call_handle);
171 CALL_ENG_DEBUG(ENG_DEBUG, "BT connected, Not changing the path in bt connect event");
173 _vc_bt_send_response_to_bt(pcall_core, BT_AG_RES_CALL_CONNECT, call_handle, NULL);
177 vc_engine_headset_status_type event_data;
179 if (voicecall_snd_get_path_status(pcall_core->papp_snd) == VOICE_CALL_SND_PATH_BT) {
180 voicecall_snd_set_path_status(pcall_core->papp_snd, VOICE_CALL_SND_PATH_RECEIVER_EARJACK);
182 /* Headset is disconnected, so voice sound path should be changed to phone. */
183 voicecall_snd_set_status(pcall_core->papp_snd, VOICE_CALL_AUDIO_HEADSET, FALSE);
184 if (voicecall_core_is_incoming_call_exists(pcall_engine)) {
185 sound_manager_call_session_set_mode(pcall_core->papp_snd->psnd_session, SOUND_CALL_SESSION_MODE_RINGTONE);
187 if (voicecall_core_is_outgoing_call_exists(pcall_engine) || (voicecall_core_is_connected_call_exist(pcall_engine))) {
188 voicecall_snd_change_path(pcall_core->papp_snd);
190 CALL_ENG_DEBUG(ENG_ERR, "No valid calls, not changing the path");
194 CALL_ENG_DEBUG(ENG_ERR, "BT disconnected when path is not on BT. Do NOT change path. only update UI");
197 memset(&event_data, 0, sizeof(event_data));
198 event_data.bstatus = FALSE;
199 vcall_engine_send_event_to_client(VC_ENGINE_MSG_HEADSET_STATUS_TO_UI, (void *)&event_data);
204 gboolean _vc_bt_switch_headset_path(call_vc_core_state_t *pcall_core, gboolean bheadset, gboolean bsend_bt_response)
206 VOICECALL_RETURN_FALSE_IF_FAIL(pcall_core != NULL);
208 connectivity_bt_ag_res_t bt_event = BT_AG_RES_SWITCH_TO_PHONE;
209 voicecall_snd_mgr_t *papp_snd = pcall_core->papp_snd;
210 voicecall_engine_t *pcall_engine = pcall_core->pcall_engine;
212 CALL_ENG_DEBUG(ENG_DEBUG, "bheadset = %d,bsend_bt_response = %d", bheadset, bsend_bt_response);
214 CALL_ENG_DEBUG(ENG_DEBUG, "b_user_rqst_path_change(%d)", b_user_rqst_path_change);
215 if (b_user_rqst_path_change == FALSE) {
216 if (TRUE == bheadset) {
217 voicecall_snd_set_path_status(pcall_core->papp_snd, VOICE_CALL_SND_PATH_BT);
219 voicecall_snd_set_path_status(pcall_core->papp_snd, VOICE_CALL_SND_PATH_RECEIVER_EARJACK);
222 CALL_ENG_DEBUG(ENG_DEBUG, "Don't set path_status.. rqst from User. Already setted.");
225 /*Donot change the path for MT Call. Change the Audio Path only for MO and Connected calls */
226 if ((TRUE == voicecall_core_is_connected_call_exist(pcall_engine)) || (TRUE == voicecall_core_is_outgoing_call_exists(pcall_engine))) {
227 CALL_ENG_DEBUG(ENG_DEBUG, "Changing the Path on BT Request");
228 voicecall_snd_change_path_real(papp_snd);
230 /*Send Response to BT only if the path is changed */
231 if (TRUE == bsend_bt_response) {
232 bt_event = (TRUE == bheadset) ? BT_AG_RES_SWITCH_TO_HEADSET : BT_AG_RES_SWITCH_TO_PHONE;
233 CALL_ENG_DEBUG(ENG_DEBUG, "Sending BT Response bt_event: %d", bt_event);
234 _vc_bt_send_response_to_bt(pcall_core, bt_event, -1, NULL);
243 * This function sends event to BT for switch to Headset/Phone
246 * @param[in] pcall_core Handle to voicecall core
247 * @param[in] bheadset TRUE if sound type is Audio Headset, FALSE otherwise
249 void _vc_bt_request_switch_headset_path(call_vc_core_state_t *pcall_core, gboolean bheadset)
251 VOICECALL_RETURN_IF_FAIL(pcall_core != NULL);
253 connectivity_bt_ag_res_t bt_event = BT_AG_RES_SWITCH_TO_PHONE;
254 voicecall_engine_t *pcall_engine = pcall_core->pcall_engine;
256 CALL_ENG_DEBUG(ENG_DEBUG, "..");
258 /*Donot change the path for MT Call. Change the Audio Path only for MO and Connected calls */
259 if ((TRUE == voicecall_core_is_connected_call_exist(pcall_engine)) || (TRUE == voicecall_core_is_outgoing_call_exists(pcall_engine))) {
260 bt_event = (TRUE == bheadset) ? BT_AG_RES_SWITCH_TO_HEADSET : BT_AG_RES_SWITCH_TO_PHONE;
261 CALL_ENG_DEBUG(ENG_DEBUG, "Sending BT Response bt_event: %d", bt_event);
262 voicecall_core_set_status(pcall_core, CALL_VC_CORE_FLAG_BT_EVENT_WAITING, TRUE);
264 _vc_bt_send_response_to_bt(pcall_core, bt_event, -1, NULL);
266 CALL_ENG_DEBUG(ENG_ERR, "No Valid calls to switch path");
271 * This function handles the bluetooth notifications sent by blue tooth application
273 * @return TRUE -if event is handled, FALSE otherwise
274 * @param[in] pcall_core Handle to voicecall core
275 * @param[in] pbt_info bt notification details
277 gboolean _vc_bt_handle_bt_events(call_vc_core_state_t *pcall_core, connectivity_bt_ag_param_info_t * pbt_info)
279 VOICECALL_RETURN_FALSE_IF_FAIL(pcall_core != NULL);
280 VOICECALL_RETURN_FALSE_IF_FAIL(pbt_info != NULL);
282 CALL_ENG_DEBUG(ENG_DEBUG, "Event: %s(%d)", gszbt_req_event[pbt_info->param1], pbt_info->param1);
284 /*HS Connection not required for sending response to BT_AG_REQ_CALL_STATUS */
285 if ((FALSE == pcall_core->bt_connected) && (BT_AG_REQ_CALL_STATUS != pbt_info->param1)) {
286 CALL_ENG_DEBUG(ENG_ERR, "BT not connected, Ignoring BT Events, BT Event= %d", pbt_info->param1);
290 switch (pbt_info->param1) {
291 case BT_AG_REQ_CALL_STATUS:
293 /*Send the Current Call status to BT */
294 _vc_bt_send_response_to_bt(pcall_core, BT_AG_RES_CALL_STATUS, -1, NULL);
298 case BT_AG_REQ_SPK_GAIN:
300 int bt_vol_level = pbt_info->param2;
301 int converted_vol_level;
302 vc_engine_vol_set_from_bt_type event_data;
304 CALL_ENG_DEBUG(ENG_DEBUG, "Speaker Gain Value : %d", bt_vol_level);
306 if (voicecall_snd_get_path_status(pcall_core->papp_snd) != VOICE_CALL_SND_PATH_BT) {
307 CALL_ENG_DEBUG(ENG_DEBUG, "Headset not switched on, Ignoring Speaker Gain Event");
310 voicecall_core_set_status(pcall_core, CALL_VC_CORE_FLAG_VOL_CHNGD_BYBT, TRUE);
312 converted_vol_level = __vc_bt_converted_bt_vol_to_voice_vol(bt_vol_level);
314 CALL_ENG_DEBUG(ENG_DEBUG, "converted Speaker Gain Value : %d", converted_vol_level);
316 memset(&event_data, 0, sizeof(event_data));
317 event_data.vol_level = converted_vol_level;
318 vcall_engine_send_event_to_client(VC_ENGINE_MSG_SET_VOLUME_FROM_BT_TO_UI, (void *)&event_data);
321 case BT_AG_REQ_CALL_ACCEPTED:
323 if (voicecall_core_is_incoming_call_exists(pcall_core->pcall_engine)) {
324 CALL_ENG_DEBUG(ENG_DEBUG, "Incoming call Accept by BT");
325 voicecall_core_set_status(pcall_core, CALL_VC_CORE_FLAG_ACCEPT_BY_BT, TRUE);
326 if (_vc_core_util_phonelock_status() == FALSE)
327 vconf_set_int(VCONFKEY_IDLE_LOCK_STATE, VCONFKEY_IDLE_UNLOCK);
328 voicecall_snd_set_path_status(pcall_core->papp_snd, VOICE_CALL_SND_PATH_BT);
329 if (TRUE == voicecall_core_answer_call(pcall_core, FALSE)) {
330 CALL_ENG_DEBUG(ENG_DEBUG, "voicecall_core_answer_call success");
333 CALL_ENG_DEBUG(ENG_ERR, "No Incoming call, skipping BT request");
337 case BT_AG_REQ_CALL_REJECT:
339 if (TRUE == voicecall_core_is_incoming_call_exists(pcall_core->pcall_engine)) {
340 if (FALSE == voicecall_core_reject_mt(pcall_core, TRUE)) {
341 CALL_ENG_DEBUG(ENG_ERR, "voicecall_core_reject_mt returned FALSE!");
343 /*Call rejected, reset the accept by flag */
344 voicecall_core_set_status(pcall_core, CALL_VC_CORE_FLAG_ACCEPT_BY_BT, FALSE);
345 } else if (TRUE == voicecall_core_is_outgoing_call_exists(pcall_core->pcall_engine)) {
346 /*To retrieve the held call automatically once the mo call is ended, if held is call is available */
347 _vc_core_engine_status_set_end_flag(pcall_core->pcall_engine, VC_RETREIVE_CALL_ON_MOCALL_END);
349 voicecall_core_end_mo_call(pcall_core->pcall_engine);
351 CALL_ENG_DEBUG(ENG_ERR, "No Incoming/Outgoing calls, skipping BT request");
355 case BT_AG_REQ_BUTTON_PRESSED:
357 if (voicecall_core_is_connected_call_exist(pcall_core->pcall_engine)) {
358 return voicecall_core_process_hold_call(pcall_core);
360 CALL_ENG_DEBUG(ENG_ERR, "No connected calls, skipping BT request");
365 case BT_AG_REQ_CALL_END:
367 voicecall_core_end_call(pcall_core);
370 case BT_AG_REQ_CONNECT_ERROR:
372 /*To change path , reset flags and to update UI, if this is conisdered as Bt disconnect */
373 __vc_bt_handle_connectivity_event(pcall_core, FALSE);
376 case BT_AG_REQ_CALL_0_SEND:
378 if (TRUE == voicecall_core_is_any_call_exists(pcall_core->pcall_engine)) {
379 voicecall_core_start_incall_ss(pcall_core, CALL_VC_CORE_SS_0);
383 case BT_AG_REQ_CALL_1_SEND:
385 if (TRUE == voicecall_core_is_any_call_exists(pcall_core->pcall_engine)) {
386 if (TRUE == voicecall_core_is_incoming_call_exists(pcall_core->pcall_engine)) {
387 CALL_ENG_DEBUG(ENG_DEBUG, "Incoming call Accept by BT");
388 voicecall_core_set_status(pcall_core, CALL_VC_CORE_FLAG_ACCEPT_BY_BT, TRUE);
390 voicecall_core_start_incall_ss(pcall_core, CALL_VC_CORE_SS_1);
394 case BT_AG_REQ_CALL_2_SEND:
396 if (TRUE == voicecall_core_is_any_call_exists(pcall_core->pcall_engine)) {
397 gboolean bactive_calls = FALSE;
398 gboolean bheld_calls = FALSE;
400 if (TRUE == voicecall_core_is_incoming_call_exists(pcall_core->pcall_engine)) {
401 voicecall_core_is_call_exists(pcall_core->pcall_engine, &bactive_calls, &bheld_calls);
402 if (!((TRUE == bactive_calls) && (TRUE == bheld_calls))) {
403 CALL_ENG_DEBUG(ENG_DEBUG, "Incoming call Accept by BT");
404 voicecall_core_set_status(pcall_core, CALL_VC_CORE_FLAG_ACCEPT_BY_BT, TRUE);
407 voicecall_core_start_incall_ss(pcall_core, CALL_VC_CORE_SS_2);
411 case BT_AG_REQ_CALL_3_SEND:
413 if (TRUE == voicecall_core_is_any_call_exists(pcall_core->pcall_engine)) {
414 voicecall_core_start_incall_ss(pcall_core, CALL_VC_CORE_SS_3);
418 case BT_AG_REQ_HEADSET_VOL:
420 int bt_vol_level = pbt_info->param2;
421 int converted_vol_level;
423 CALL_ENG_DEBUG(ENG_DEBUG, "BT volume Level: %d", bt_vol_level);
425 if (voicecall_core_is_any_call_exists(pcall_core->pcall_engine)) {
426 vc_engine_vol_resp_type event_data;
428 converted_vol_level = __vc_bt_converted_bt_vol_to_voice_vol(bt_vol_level);
430 memset(&event_data, 0, sizeof(event_data));
431 event_data.vol_alert_type = VOICE_CALL_VOL_TYPE_HEADSET;
432 event_data.vol_level = converted_vol_level;
433 vcall_engine_send_event_to_client(VC_ENGINE_MSG_GET_VOLUME_RESP_TO_UI, (void *)&event_data);
435 CALL_ENG_DEBUG(ENG_ERR, "NO Calls, Skipping BT Response");
439 case BT_AG_REQ_SWITCH_TO_HEADSET:
440 case BT_AG_REQ_SWITCH_TO_PHONE:
442 gboolean bswitch_to_headset = FALSE;
443 int bt_error = pbt_info->param2;
445 if (voicecall_core_get_status(pcall_core, CALL_VC_CORE_FLAG_BT_EVENT_WAITING) == TRUE) {
446 b_user_rqst_path_change = TRUE;
448 b_user_rqst_path_change = FALSE;
451 voicecall_core_set_status(pcall_core, CALL_VC_CORE_FLAG_BT_EVENT_WAITING, FALSE);
453 /*Switch to response is received from BT, BT decision is fina, so reset the accept by BT */
454 voicecall_core_set_status(pcall_core, CALL_VC_CORE_FLAG_ACCEPT_BY_BT, FALSE);
456 CALL_ENG_DEBUG(ENG_DEBUG, "BT Error :%d", bt_error);
458 /*Audio Connection/Disconnection Success case */
459 bswitch_to_headset = (BT_AG_REQ_SWITCH_TO_HEADSET == pbt_info->param1) ? TRUE : FALSE;
461 /*Audio Connection/Disconnection Error Case */
462 if (BT_AG_RES_AUDIO_CONNECTION_ERROR == bt_error) {
463 /*Connection Error, switch to phone */
464 bswitch_to_headset = FALSE;
465 } else if (BT_AG_RES_AUDIO_DISCONNECTION_ERROR == bt_error) {
466 /*Disconnection Error, switch to headset */
467 bswitch_to_headset = TRUE;
469 CALL_ENG_DEBUG(ENG_ERR, "Invalid BT Error: %d", bt_error);
474 CALL_ENG_DEBUG(ENG_DEBUG, "bswitch_to_headset = %d", bswitch_to_headset);
476 if ((TRUE == voicecall_core_is_connected_call_exist(pcall_core->pcall_engine)) || (TRUE == voicecall_core_is_outgoing_call_exists(pcall_core->pcall_engine))) {
477 gboolean bupdate = FALSE;
480 /*Connection/Diconnection is sucess, don't send response to BT */
481 bupdate = _vc_bt_switch_headset_path(pcall_core, bswitch_to_headset, FALSE);
482 CALL_ENG_DEBUG(ENG_DEBUG, "bupdate = %d, bswitch_to_headset = %d", bupdate, bswitch_to_headset);
484 vc_engine_headset_status_type event_data;
485 memset(&event_data, 0, sizeof(event_data));
486 event_data.bstatus = bswitch_to_headset;
487 vcall_engine_send_event_to_client(VC_ENGINE_MSG_HEADSET_STATUS_TO_UI, (void *)&event_data);
489 /*Connection/Diconnection is NOT sucess, change path and send response to BT */
490 bupdate = _vc_bt_switch_headset_path(pcall_core, bswitch_to_headset, TRUE);
494 CALL_ENG_DEBUG(ENG_ERR, "No connected/outgoing calls, Skipping BT Request");
500 gboolean active_calls = FALSE;
501 gboolean held_calls = FALSE;
503 CALL_ENG_DEBUG(ENG_DEBUG, "Send DTMF(%s)", pbt_info->param4);
504 if ((voicecall_core_is_call_exists(pcall_core->pcall_engine, &active_calls, &held_calls)) && (TRUE == active_calls)) {
505 voicecall_core_send_dtmf(pcall_core, pbt_info->param4);
510 case BT_AG_REQ_CALL_REDIAL:
512 CALL_ENG_DEBUG(ENG_DEBUG, "Action not defined for bt event: %d", pbt_info->param1);
522 * This function sends response back to the bt application
525 * @param[in] pcall_core Handle to voicecall core
526 * @param[in] bt_event bluetooth event type
527 * @param[in] param1 user param1
528 * @param[in] param2 user param2
530 void _vc_bt_send_response_to_bt(call_vc_core_state_t *pcall_core, int bt_event, int param1, gpointer param2)
532 VOICECALL_RETURN_IF_FAIL(pcall_core != NULL);
534 connectivity_bt_ag_param_info_t bt_response_info;
535 CALL_ENG_DEBUG(ENG_DEBUG, "Event: %s(%d), param1=[%d]", gszbt_res_event[bt_event], bt_event, param1);
537 /*Skip events, if Bluetooth is not connected */
538 /* if((FALSE == pcall_core->bt_connected) && (BT_AG_RES_CALL_STATUS != bt_event))
540 CALL_ENG_DEBUG(ENG_DEBUG,"Bluetooth not connected , Not sending any responses to BT");
544 /*Make BT Response Info */
545 memset(&bt_response_info, 0, sizeof(connectivity_bt_ag_param_info_t));
547 bt_response_info.param1 = bt_event;
550 case BT_AG_RES_CALL_STATUS:
551 case BT_AG_RES_CALL_SWAPPED:
553 connectivity_bt_ag_call_status_info_t call_status_info[10];
554 int mt_call_handle = -1;
555 int mo_call_handle = -1;
556 int connected_call_handle = -1;
557 int active_group_member_num = 0;
558 int held_group_member_num = 0;
561 char temp_str[10] = { 0, };
562 char result_str[256] = { 0, };
565 _vc_core_engine_status_get_call_handle_bytype(pcall_core->pcall_engine, VC_INCOMING_CALL, &mt_call_handle);
566 if (mt_call_handle != -1) {
567 CALL_ENG_DEBUG(ENG_DEBUG, "Incoming Call Exists, call handle = %d", mt_call_handle);
569 call_status_info[index].call_id = mt_call_handle;
570 call_status_info[index].call_status = BT_AG_CALL_STATUS_INCOMING;
572 CALL_ENG_DEBUG(ENG_DEBUG, "total_call_member after mt= %d", index);
576 _vc_core_engine_status_get_call_handle_bytype(pcall_core->pcall_engine, VC_OUTGOING_CALL, &mo_call_handle);
577 if (mo_call_handle != -1) {
578 voicecall_call_state_t call_state;
579 gboolean bvalid_call = TRUE;
581 _vc_core_engine_status_get_call_state_byhandle(pcall_core->pcall_engine, mo_call_handle, &call_state);
582 CALL_ENG_DEBUG(ENG_DEBUG, "call state: %d", call_state);
584 switch (call_state) {
585 case VC_CALL_STATE_OUTGOING_ALERT:
587 call_status_info[index].call_status = BT_AG_CALL_STATUS_ALERTING;
590 case VC_CALL_STATE_PREPARE_OUTGOING:
591 case VC_CALL_STATE_OUTGOING:
592 case VC_CALL_STATE_OUTGOING_ORIG:
594 call_status_info[index].call_status = BT_AG_CALL_STATUS_DIALLING;
597 default: /*All Other states , donot consider for mocall */
598 CALL_ENG_DEBUG(ENG_DEBUG, "mo call state: %d", call_state);
602 if (TRUE == bvalid_call) {
603 call_status_info[index].call_id = mo_call_handle;
605 CALL_ENG_DEBUG(ENG_DEBUG, "total_call_member after mo= %d", index);
611 int act_grp_index = -1;
612 int held_grp_index = -1;
614 _vc_core_engine_group_get_group_indices(pcall_core->pcall_engine, &act_grp_index, &held_grp_index);
616 CALL_ENG_DEBUG(ENG_DEBUG, "act_grp_index = %d, held_grp_index = %d", act_grp_index, held_grp_index);
617 /*Active Connected Call */
618 if (act_grp_index != -1) {
619 _vc_core_engine_group_get_connected_member_count(pcall_core->pcall_engine, act_grp_index, &active_group_member_num);
620 CALL_ENG_DEBUG(ENG_DEBUG, "active_group_connected_member_num = %d", active_group_member_num);
621 for (i = 0; i < active_group_member_num; i++) {
622 _vc_core_engine_group_get_call_handle_byposition(pcall_core->pcall_engine, act_grp_index, i, &connected_call_handle);
623 if (connected_call_handle != -1) {
624 call_status_info[index].call_id = connected_call_handle;
625 call_status_info[index].call_status = BT_AG_CALL_STATUS_CONNECTED;
629 CALL_ENG_DEBUG(ENG_DEBUG, "total_call_member after active calls= %d", index);
632 /*Held Connected Call */
633 if (held_grp_index != -1) {
634 _vc_core_engine_group_get_connected_member_count(pcall_core->pcall_engine, held_grp_index, &held_group_member_num);
636 CALL_ENG_DEBUG(ENG_DEBUG, "held_group_member_num = %d", held_group_member_num);
637 for (i = 0; i < held_group_member_num; i++) {
638 _vc_core_engine_group_get_call_handle_byposition(pcall_core->pcall_engine, held_grp_index, i, &connected_call_handle);
639 CALL_ENG_DEBUG(ENG_DEBUG, "Call Handle[%d] = %d", i, connected_call_handle);
640 if (connected_call_handle != -1) {
641 call_status_info[index].call_id = connected_call_handle;
642 call_status_info[index].call_status = BT_AG_CALL_STATUS_HELD;
646 CALL_ENG_DEBUG(ENG_DEBUG, "total_call_member after held calls= %d", index);
649 CALL_ENG_DEBUG(ENG_DEBUG, "Total Calls = %d", index);
650 bt_response_info.param2 = index;
652 memset(result_str, 0x00, sizeof(result_str));
653 for (i = 0; i < index; i++) {
654 memset(temp_str, 0x00, sizeof(temp_str));
655 snprintf(temp_str, sizeof(temp_str), "%d.%d/", call_status_info[i].call_id, call_status_info[i].call_status);
656 strncat(result_str, temp_str, sizeof(temp_str) - 1);
658 CALL_ENG_DEBUG(ENG_DEBUG, "The resultant string is %s", result_str);
660 _vc_core_util_strcpy(bt_response_info.param4, sizeof(bt_response_info.param4), result_str);
662 CALL_ENG_DEBUG(ENG_DEBUG, "Actual Data Passed is %s", bt_response_info.param4);
663 CALL_ENG_DEBUG(ENG_DEBUG, "Actual Data Passed to BT");
664 for (i = 0; i < index; i++) {
665 CALL_ENG_DEBUG(ENG_DEBUG, "call id = %d", call_status_info[i].call_id);
666 CALL_ENG_DEBUG(ENG_DEBUG, "call status= %d", call_status_info[i].call_status);
669 CALL_ENG_DEBUG(ENG_DEBUG, "Verification of BT data being sent");
673 case BT_AG_RES_CALL_INCOM:
675 /*Length of Incoming Call Number */
676 if (NULL != param2) {
677 CALL_ENG_DEBUG(ENG_DEBUG, "phone number=%s", (char *)param2);
678 bt_response_info.param2 = strlen(param2);
679 bt_response_info.param3 = param1;
680 _vc_core_util_strcpy(bt_response_info.param4, VC_PHONE_NUMBER_LENGTH_MAX, param2);
684 case BT_AG_RES_CALL_ORIG:
686 if (NULL != param2) {
687 CALL_ENG_DEBUG(ENG_DEBUG, "phone number=%s", (char *)param2);
688 switch (voicecall_snd_get_path_status(pcall_core->papp_snd)) {
689 case VOICE_CALL_SND_PATH_RECEIVER_EARJACK:
690 case VOICE_CALL_SND_PATH_SPEAKER:
691 bt_response_info.param2 = FALSE;
693 case VOICE_CALL_SND_PATH_BT:
694 bt_response_info.param2 = TRUE;
699 bt_response_info.param3 = param1;
700 _vc_core_util_strcpy(bt_response_info.param4, VC_PHONE_NUMBER_LENGTH_MAX, param2);
704 case BT_AG_RES_CALL_REMOTE_RINGING:
706 /*Assign Call Handle */
707 bt_response_info.param3 = param1;
710 case BT_AG_RES_CALL_CONNECT:
711 case BT_AG_RES_CALL_END:
713 switch (voicecall_snd_get_path_status(pcall_core->papp_snd)) {
714 case VOICE_CALL_SND_PATH_RECEIVER_EARJACK:
715 case VOICE_CALL_SND_PATH_SPEAKER:
716 bt_response_info.param2 = FALSE;
718 case VOICE_CALL_SND_PATH_BT:
719 bt_response_info.param2 = TRUE;
724 /*Assign Call Handle */
725 bt_response_info.param3 = param1;
728 case BT_AG_RES_SPK_GAIN:
730 bt_response_info.param2 = param1;
732 case BT_AG_RES_HEADSET_VOL: /*Request For Current BT Volume Level */
734 CALL_ENG_DEBUG(ENG_DEBUG, "Requesting for Current BT Volume Level");
737 case BT_AG_RES_SWITCH_TO_HEADSET:
738 case BT_AG_RES_SWITCH_TO_PHONE:
740 case BT_AG_RES_CALL_HOLD:
741 case BT_AG_RES_CALL_RETRIEVE: /*Fall Through */
742 bt_response_info.param3 = param1;
744 case BT_AG_RES_CALL_JOINED: /*Fall Through */
749 vc_engine_on_dbus_send_response_to_bt(bt_response_info);
751 CALL_ENG_DEBUG(ENG_DEBUG, "bt response ended.");
756 * This function register bt callback.
758 * @return TRUE if bt status is registered, FALSE otherwise
761 gboolean _vc_bt_status_init(call_vc_core_state_t *pcall_core)
763 VOICECALL_RETURN_FALSE_IF_FAIL(pcall_core != NULL);
765 gboolean ret = FALSE;
768 bstatus = _vc_bt_get_bt_status();
769 CALL_ENG_DEBUG(ENG_DEBUG, "bt_connected:[%d]", bstatus);
770 __vc_bt_handle_connectivity_event(pcall_core, bstatus);
772 ret = vconf_notify_key_changed(VCONFKEY_BT_DEVICE, (void *)_vc_bt_handle_phonestatus_bt_events, pcall_core);
774 CALL_ENG_DEBUG(ENG_ERR, "vconf_notify_key_changed failed..[%d]", ret);
781 * This function gets the blue tooth active status from the phone status server
783 * @return TRUE - if BT is enabled, FALSE otherwise
786 gboolean _vc_bt_get_bt_status(void)
788 int bt_status = VCONFKEY_BT_DEVICE_NONE;
789 gboolean ret = FALSE;
791 ret = vconf_get_int(VCONFKEY_BT_DEVICE, &bt_status);
793 CALL_ENG_DEBUG(ENG_DEBUG, "bt_status = [0x%x]", bt_status);
795 CALL_ENG_DEBUG(ENG_ERR, "vconf_get_int failed..[%d]", ret);
798 return (VCONFKEY_BT_DEVICE_HEADSET_CONNECTED == (bt_status & VCONFKEY_BT_DEVICE_HEADSET_CONNECTED)) ? TRUE : FALSE;
802 * This function gets the BT inband ringtone activate settings
804 * @return TRUE - if BT inband ringtone activate settings is ON, FALSE otherwise
807 gboolean _vc_bt_get_inband_ringtone_active(void)
809 /* InBand_Ringtone_Active for vconf.. */
814 * This function handles the notifications sent by phone status server
816 * @return TRUE -if notification is handled, FALSE otherwise
817 * @param[in] pcall_core Handle to voicecall core
818 * @param[in] bt_status Blue tooth status
820 gboolean _vc_bt_handle_phonestatus_bt_events(keynode_t *node, call_vc_core_state_t *pcall_core)
822 VOICECALL_RETURN_FALSE_IF_FAIL(node != NULL);
823 VOICECALL_RETURN_FALSE_IF_FAIL(pcall_core != NULL);
825 gboolean bt_conn_status = FALSE;
826 int bt_status = vconf_keynode_get_int(node);
828 CALL_ENG_DEBUG(ENG_DEBUG, "bt_status = [0x%x]", bt_status);
830 /*set the sound status */
831 bt_conn_status = (VCONFKEY_BT_DEVICE_HEADSET_CONNECTED == (bt_status & VCONFKEY_BT_DEVICE_HEADSET_CONNECTED)) ? TRUE : FALSE;
832 CALL_ENG_DEBUG(ENG_DEBUG, "bt_conn_status = %d", bt_conn_status);
834 __vc_bt_handle_connectivity_event(pcall_core, bt_conn_status);
839 * This function retreives volume level of headset
842 * @param[in] pcall_core Handle to voicecall core
844 void _vc_bt_get_headset_volume(call_vc_core_state_t *pcall_core)
846 VOICECALL_RETURN_IF_FAIL(pcall_core != NULL);
848 _vc_bt_send_response_to_bt(pcall_core, BT_AG_RES_HEADSET_VOL, 0, NULL);
852 * This function returns the BT connection status
854 * @return TRUE if bt is connected, FALSE otherwise
855 * @param[in] pcall_core Handle to voicecall core
857 gboolean _vc_bt_is_bt_connected(call_vc_core_state_t *pcall_core)
859 VOICECALL_RETURN_FALSE_IF_FAIL(pcall_core != NULL);
861 return pcall_core->bt_connected;
865 * This function returns the BT SCO status.(Synchronized Connection Oriented link)
867 * @return TRUE if bt is connected, FALSE otherwise
870 gboolean _vc_bt_get_bt_sco_status(void)
872 gboolean sco_status = FALSE;
873 gboolean ret = FALSE;
875 ret = vconf_get_bool(VCONFKEY_BT_HEADSET_SCO, &sco_status);
877 CALL_ENG_DEBUG(ENG_DEBUG, "sco_status = [%d]", sco_status);
879 CALL_ENG_DEBUG(ENG_ERR, "vconf_get_int failed..[%d]", ret);
886 * This function processed bt handset event
888 * @return TRUE if bt is connected, FALSE otherwise
889 * @param[in] pcall_core Handle to voicecall core
890 * @param[in] bheadset headset status
892 gboolean _vc_bt_process_bt_handset(call_vc_core_state_t *pcall_core, int bheadset)
894 VOICECALL_RETURN_FALSE_IF_FAIL(pcall_core != NULL);
896 CALL_ENG_DEBUG(ENG_DEBUG, "bheadset:[%d]", bheadset);
898 if (FALSE == _vc_bt_get_bt_status()) {
899 vc_engine_on_dbus_send_connect_to_bt();
901 CALL_ENG_DEBUG(ENG_DEBUG, "BT is ON.. switch path to BT");
902 _vc_bt_switch_headset_path(pcall_core, bheadset, TRUE);
905 _vc_bt_switch_headset_path(pcall_core, bheadset, TRUE);