2 * bluetooth-ag-manager.c
4 * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * Chethan TN <chethan.tn@samsung.com>
8 * Chanyeol Park <chanyeol.park@samsung.com>
9 * Rakesh MK <rakesh.mk@samsung.com>
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
26 #include "bluetooth-ag-agent.h"
27 #include "bluetooth-ag-handler.h"
28 #include <dbus/dbus.h>
30 #define PHONEBOOK_AGENT_BUS_NAME "org.bluez.pb_agent"
31 #define PHONEBOOK_AGENT_PATH "/org/bluez/pb_agent"
32 #define PHONEBOOK_AGENT_INTERFACE "org.bluez.PbAgent.At"
34 struct telephony_call {
37 gboolean call_originating;
38 gboolean call_emergency;
39 gboolean call_on_hold;
40 gboolean call_conference;
47 #define HFP_AGENT_ACTIVITY_STATUS_READY 0
48 #define HFP_AGENT_ACTIVITY_STATUS_UNAVAILABLE 1
49 #define HFP_AGENT_ACTIVITY_STATUS_UNKNOWN 2
50 #define HFP_AGENT_ACTIVITY_STATUS_RINGING 3
51 #define HFP_AGENT_ACTIVITY_STATUS_CALL_IN_PROGRESS 4
53 #define HFP_AGENT_BATTERY_INDICATOR "battchg"
54 #define HFP_AGENT_CALL_INDICATOR "call"
55 #define HFP_AGENT_CALLHELD_INDICATOR "callheld"
56 #define HFP_AGENT_CALLSETUP_INDICATOR "callsetup"
57 #define HFP_AGENT_ROAMING_INDICATOR "roam"
58 #define HFP_AGENT_SERVICE_INDICATOR "service"
59 #define HFP_AGENT_SIGNAL_INDICATOR "signal"
61 #define HFP_AGENT_CALL_IDLE 0
62 #define HFP_AGENT_CALL_ACTIVE 1
64 #define HFP_INCOMING_CALLSETUP 1
65 #define HFP_OUTGOING_CALLSETUP 2
66 #define RESTRAIN_CALL_FLAG 0x01
67 #define ALLOW_CALL_FLAG 0x02
69 #define HFP_CALL_STATUS_IDLE 0
70 #define HFP_CALL_STATUS_CREATE 1
71 #define HFP_CALL_STATUS_COMING 2
72 #define HFP_CALL_STATUS_PROCEEDING 3
73 #define HFP_CALL_STATUS_MO_ALERTING 4
74 #define HFP_CALL_STATUS_MT_ALERTING 5
75 #define HFP_CALL_STATUS_WAITING 6
76 #define HFP_CALL_STATUS_ANSWERED 7
77 #define HFP_CALL_STATUS_ACTIVE 8
78 #define HFP_CALL_STATUS_MO_RELEASE 9
79 #define HFP_CALL_STATUS_MT_RELEASE 10
80 #define HFP_CALL_STATUS_HOLD_INITIATED 11
81 #define HFP_CALL_STATUS_HOLD 12
82 #define HFP_CALL_STATUS_RETRIEVE_INITIATED 13
83 #define HFP_CALL_STATUS_RECONNECT_PENDING 14
84 #define HFP_CALL_STATUS_TERMINATED 15
85 #define HFP_CALL_STATUS_SWAP_INITIATED 16
87 #define AGENT_MAX_PB_COUNT 1000
88 #define AGENT_PB_NAME_MAX_LENGTH 20
89 #define AGENT_PB_NUMBER_MAX_LENGTH 20
90 #define AGENT_MAX_CALLLOG_COUNT 30
91 #define ERR_NOT_FOUND -1
92 #define AG_MAX_LENGTH 16
94 static gboolean update_events = FALSE;
95 static int caller_id = 0;
97 static GSList *call_senders_paths = NULL;
98 static GSList *existing_call_list = NULL;
99 static GSList *agent_active_call_list = NULL;
100 static char *ag_subscriber_num = NULL;
102 static guint call_on_hold_timer = 0;
110 char *network_operator_name;
111 uint8_t network_status;
112 int32_t signal_strength;
114 .network_operator_name = NULL,
115 .network_status = BT_AGENT_NETWORK_REG_STATUS_UNKOWN,
116 .signal_strength = 0,
119 static const char *agent_pb_store_list[] = {
120 "\"ME\"", "\"DC\"", "\"MC\"", "\"RC\""
123 static const char *agent_supported_character_set[] = {
124 "\"UTF-8\"", "\"IRA\""
127 #if defined(TIZEN_PROFILE_WEARABLE) && defined(TIZEN_FEATURE_BT_HFP_AG)
128 static const char *ag_chld_str = "0,1,2";
130 static const char *ag_chld_str = "0,1,2,3";
133 #define AGENT_PB_STORE_LIST_SIZE (sizeof(agent_pb_store_list) \
134 /sizeof(const char *))
135 #define AGENT_SUPPORTED_CHARACTER_SET_SIZE ( \
136 sizeof(agent_supported_character_set)/sizeof(const char *))
138 static bt_ag_indicators_t hfp_ag_ind[] = {
139 { "call", "0,1", 0, TRUE, TRUE },
140 { "callsetup", "0-3", 0 , TRUE, TRUE },
141 { "battchg", "0-5", 5 , TRUE, TRUE },
142 { "callheld", "0-2", 0 , FALSE, TRUE },
143 { "roam", "0,1", 0 , TRUE, TRUE },
144 { "signal", "0-5", 0 , TRUE, TRUE },
145 { "service", "0,1", 0, TRUE, TRUE },
157 /* LCOV_EXCL_START */
158 static gboolean __bt_hfp_check_for_callpath(const char *call_path,
159 const char *call_sender)
161 GSList *sender_list = call_senders_paths;
162 sender_info_t *sender;
164 DBG("call path is = %s\n", call_path);
165 DBG("sender is = %s\n", call_sender);
167 if (call_path == NULL || call_sender == NULL) {
169 ERR("Invalid Parameters");
173 /*check if the call is already registered*/
174 DBG("Checking if the call is already registered");
175 while (sender_list != NULL) {
176 sender = sender_list->data;
181 if (g_strcmp0(sender->sender_path, call_path) == 0) {
182 DBG("sender path and call path match... so return true");
186 sender_list = sender_list->next;
189 ERR("Call path is not already registered");
193 static void __bt_hfp_clear_sender_path(sender_info_t *s_path)
198 g_free(s_path->sender_name);
199 g_free(s_path->sender_path);
202 if (g_slist_length(call_senders_paths) == 0) {
203 g_slist_free(call_senders_paths);
204 call_senders_paths = NULL;
208 static void __bt_hfp_free_call(struct telephony_call *t_call)
213 g_free(t_call->call_number);
214 g_free(t_call->call_path);
215 g_free(t_call->call_sender);
220 static void __bt_hfp_reset_indicators(void)
224 for (i = 0; hfp_ag_ind[i].indicator_desc != NULL; i++)
225 hfp_ag_ind[i].is_activated = TRUE;
228 void _bt_hfp_device_disconnected(void *t_device)
230 DBG("hfp_agent: device %p disconnected", t_device);
231 update_events = FALSE;
232 __bt_hfp_reset_indicators();
235 void _bt_hfp_initialize_telephony_manager(uint32_t ag_features)
241 /* Reset the indicator values */
242 for (index = 0; hfp_ag_ind[index].indicator_desc != NULL; index++) {
243 if (g_str_equal(hfp_ag_ind[index].indicator_desc, "battchg")) {
244 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
247 ERR("Get battery status failed : %d\n", ret);
249 /* Send battery status ranging from 0-5 */
251 hfp_ag_ind[index].hfp_value = 0;
252 else if (value >= 100)
253 hfp_ag_ind[index].hfp_value = 5;
255 hfp_ag_ind[index].hfp_value = value / 20 + 1;
257 } else if (g_str_equal(hfp_ag_ind[index].indicator_desc, "signal")) {
258 ret = vconf_get_int(VCONFKEY_TELEPHONY_RSSI, &value);
260 ERR("Get signal status failed err = %d\n", ret);
262 BT_CHECK_SIGNAL_STRENGTH(value);
263 hfp_ag_ind[index].hfp_value = value;
265 } else if (g_str_equal(hfp_ag_ind[index].indicator_desc, "roam")) {
266 ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &value);
268 ERR("Get roaming status failed err = %d\n", ret);
270 hfp_ag_ind[index].hfp_value = value;
271 } else if (g_str_equal(hfp_ag_ind[index].indicator_desc, "service")) {
272 ret = vconf_get_int(VCONFKEY_TELEPHONY_SVCTYPE, &value);
274 ERR("Get Service status failed : %d\n", ret);
277 case VCONFKEY_TELEPHONY_SVCTYPE_NONE:
278 case VCONFKEY_TELEPHONY_SVCTYPE_NOSVC:
279 case VCONFKEY_TELEPHONY_SVCTYPE_SEARCH:
280 hfp_ag_ind[index].hfp_value =
281 INDICATOR_EVENT_SERVICE_NONE;
284 hfp_ag_ind[index].hfp_value =
285 INDICATOR_EVENT_SERVICE_PRESENT;
290 hfp_ag_ind[index].hfp_value = 0;
294 /*Initializatoin of the indicators*/
295 _bt_hfp_set_ag_indicator(ag_features, hfp_ag_ind,
296 BT_RSP_HOLD_NOT_SUPPORTED,
300 void _bt_hfp_deinitialize_telephony_manager(void)
302 GSList *list = call_senders_paths;
304 g_free(ag_subscriber_num);
305 ag_subscriber_num = NULL;
307 g_free(network_info.network_operator_name);
308 network_info.network_operator_name = NULL;
310 network_info.network_status = BT_AGENT_NETWORK_REG_STATUS_UNKOWN;
311 network_info.signal_strength = 0;
313 g_slist_free(agent_active_call_list);
314 agent_active_call_list = NULL;
316 g_slist_foreach(existing_call_list, (GFunc) __bt_hfp_free_call, NULL);
317 g_slist_free(existing_call_list);
318 existing_call_list = NULL;
320 while (list != NULL) {
321 __bt_hfp_clear_sender_path(list->data);
325 g_slist_free(call_senders_paths);
326 call_senders_paths = NULL;
328 _bt_hfp_deinitialize();
331 /* LCOV_EXCL_START */
332 bt_hfp_agent_error_t _bt_hfp_register_telephony_agent(gboolean register_flag,
333 const char *path_to_register,
336 sender_info_t *sender_info;
338 if (sender == NULL || path_to_register == NULL)
339 return BT_HFP_AGENT_ERROR_INVALID_PARAM;
341 DBG(" register_flag = %d", register_flag);
342 DBG(" path_to_register = %s", path_to_register);
343 DBG(" sender = %s", sender);
346 if (__bt_hfp_check_for_callpath(path_to_register, sender))
347 return BT_HFP_AGENT_ERROR_ALREADY_EXSIST;
349 /* add call path to the senders list*/
350 DBG("Call path doesn't exist. Add path %s to global path",
352 sender_info = g_new0(sender_info_t, 1);
353 sender_info->sender_path = g_strdup(path_to_register);
354 sender_info->sender_name = g_strdup(sender);
355 call_senders_paths = g_slist_append(call_senders_paths,
358 return BT_HFP_AGENT_ERROR_NONE;
360 /*remove the call from senders list */
361 GSList *s_list = call_senders_paths;
363 while (s_list != NULL) {
364 sender_info = s_list->data;
366 if (sender_info == NULL)
367 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
369 if (g_strcmp0(sender_info->sender_path,
370 path_to_register) == 0) {
371 call_senders_paths = g_slist_remove(
374 __bt_hfp_clear_sender_path(sender_info);
375 return BT_HFP_AGENT_ERROR_NONE;
377 s_list = s_list->next;
380 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
384 static gboolean __bt_hfp_is_call_allowed(const char *call_path)
386 GSList *call_list = existing_call_list;
388 /*if prior call list doesn't exisit, allow the call as it can be a new-call*/
389 if (!existing_call_list) {
390 DBG(" This must be a new call... Allow it!");
394 while (call_list != NULL) {
396 struct telephony_call *t_call = call_list->data;
398 if (g_strcmp0(t_call->call_path, call_path) == 0)
401 call_list = call_list->next;
404 ERR("call is not allowed");
408 static struct telephony_call *__bt_hfp_create_new_call(
409 const char *incoming_path,
410 uint32_t incoming_call_id,
411 const char *incoming_number,
414 struct telephony_call *t_call = NULL;
415 GSList *call_list = existing_call_list;
417 while (call_list != NULL) {
418 t_call = call_list->data;
420 if (t_call->call_id == incoming_call_id)
425 call_list = call_list->next;
428 DBG("Create a new call");
430 if (t_call == NULL) {
431 t_call = g_new0(struct telephony_call, 1);
432 t_call->call_id = incoming_call_id;
433 t_call->call_path = g_strdup(incoming_path);
434 t_call->call_sender = g_strdup(sender);
435 t_call->call_number = g_strdup(incoming_number);
437 existing_call_list = g_slist_append(existing_call_list,
444 gboolean _bt_hfp_is_call_exist(void)
446 DBG("_bt_hfp_is_call_exist [%p]", existing_call_list);
447 if (existing_call_list)
453 static struct telephony_call *__bt_hfp_get_call_with_status(int call_status)
455 DBG("Get Call with status %d", call_status);
457 GSList *temp_list = existing_call_list;
459 if (existing_call_list != NULL) {
460 /* LCOV_EXCL_START */
461 while (temp_list != NULL) {
462 struct telephony_call *t_call = temp_list->data;
463 if (t_call->call_status == call_status)
465 temp_list = temp_list->next;
470 DBG("Existing call list is NULL. So return NULL");
474 /* LCOV_EXCL_START */
475 static bt_hfp_agent_error_t __bt_hfp_modify_indicator(
476 const char *indicator_name,
479 bt_ag_indicators_t *hf_ind = NULL;
481 #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE
482 if (g_strcmp0(indicator_name,
483 HFP_AGENT_CALLSETUP_INDICATOR) == 0)
484 _bt_ag_agent_check_transport_state();
486 for (i = 0; hfp_ag_ind[i].indicator_desc != NULL; i++) {
487 if (g_str_equal(hfp_ag_ind[i].indicator_desc,
489 hf_ind = &hfp_ag_ind[i];
495 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
497 if (hf_ind->hfp_value == update_value && hf_ind->ignore)
498 return BT_HFP_AGENT_ERROR_NONE;
500 if (hf_ind->is_activated == FALSE)
501 return BT_HFP_AGENT_ERROR_NONE;
503 hf_ind->hfp_value = update_value;
505 DBG("updating hfp event indicator [%s] with value [%d]",
506 indicator_name, hf_ind->hfp_value);
508 return _bt_hfp_event_indicator(i);
511 static int __bt_hfp_get_indicator_value(
512 const bt_ag_indicators_t *ag_indicators,
516 for (x = 0; ag_indicators[x].indicator_desc != NULL; x++) {
517 if (g_str_equal(ag_indicators[x].indicator_desc, hf_desc))
518 return ag_indicators[x].hfp_value;
521 return ERR_NOT_FOUND;
524 static void __bt_hfp_handle_call_conference(void)
527 struct telephony_call *t_active_call = NULL;
528 int t_active_call_count = 0;
530 struct telephony_call *t_held_call = NULL;
531 int t_held_call_count = 0;
533 for (t_call_list = existing_call_list; t_call_list != NULL;
534 t_call_list = t_call_list->next) {
536 struct telephony_call *t_call = t_call_list->data;
538 if (t_call == NULL) {
539 ERR("t_call is NULL");
543 if (t_call->call_status == HFP_CALL_STATUS_ACTIVE) {
544 if (t_active_call == NULL)
545 t_active_call = t_call;
547 t_active_call_count++;
549 if (t_active_call_count >= 2) {
550 if (t_active_call->call_conference == FALSE)
551 t_active_call->call_conference = TRUE;
552 t_call->call_conference = TRUE;
555 } else if (t_call->call_status == HFP_CALL_STATUS_HOLD) {
556 if (t_held_call == NULL)
557 t_held_call = t_call;
561 if (t_held_call_count >= 2) {
562 if (t_held_call->call_conference == FALSE)
563 t_held_call->call_conference = TRUE;
564 t_call->call_conference = TRUE;
569 if (t_held_call != NULL && t_held_call_count == 1)
570 t_held_call->call_conference = FALSE;
572 if (t_active_call != NULL && t_active_call_count == 1)
573 t_active_call->call_conference = FALSE;
576 static gboolean __bt_hfp_on_call_hold_timeout(gpointer t_data)
580 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD)) {
581 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE))
582 status = INDICATOR_EVENT_CALLHELD_MULTIPLE;
584 status = INDICATOR_EVENT_CALLHELD_ON_HOLD;
586 status = INDICATOR_EVENT_CALLHELD_NONE;
589 __bt_hfp_modify_indicator("callheld", status);
591 call_on_hold_timer = 0;
595 static void __bt_hfp_handle_call_on_hold_request(void)
597 DBG(" Starting the timer for call on hold");
598 if (call_on_hold_timer)
599 g_source_remove(call_on_hold_timer);
601 call_on_hold_timer = g_timeout_add(250, __bt_hfp_on_call_hold_timeout,
603 DBG(" returning from the timer call");
606 static void __bt_hfp_set_call_status(struct telephony_call *t_call,
610 int org_status = t_call->call_status;
612 call_held = __bt_hfp_get_indicator_value(hfp_ag_ind, "callheld");
614 if (org_status == call_status) {
615 DBG("Ignore the CSD Call state change to existing state");
619 t_call->call_status = call_status;
621 DBG(" call status is %d", call_status);
623 switch (call_status) {
624 case HFP_CALL_STATUS_IDLE:
625 if (t_call->call_setup) {
626 __bt_hfp_modify_indicator("callsetup",
627 INDICATOR_EVENT_CALLSETUP_INACTIVE);
628 if (!t_call->call_originating)
629 _bt_calling_stopped_indicator();
632 g_free(t_call->call_number);
633 t_call->call_number = NULL;
634 t_call->call_originating = FALSE;
635 t_call->call_emergency = FALSE;
636 t_call->call_on_hold = FALSE;
637 t_call->call_conference = FALSE;
638 t_call->call_setup = FALSE;
641 case HFP_CALL_STATUS_COMING:
642 t_call->call_originating = FALSE;
643 t_call->call_setup = TRUE;
644 __bt_hfp_modify_indicator("callsetup",
645 INDICATOR_EVENT_CALLSETUP_INCOMING);
648 case HFP_CALL_STATUS_CREATE:
649 t_call->call_originating = TRUE;
650 t_call->call_setup = TRUE;
653 case HFP_CALL_STATUS_MO_ALERTING:
654 __bt_hfp_modify_indicator("callsetup",
655 INDICATOR_EVENT_CALLSETUP_ALERTING);
658 case HFP_CALL_STATUS_MT_ALERTING: {
659 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
661 if (t_call->call_number == NULL) {
662 t_number = AGENT_NUMBER_TYPE_TELEPHONY;
664 if (t_call->call_number[0] == '+' ||
665 strncmp(t_call->call_number, "00", 2) == 0)
666 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
669 if (org_status == HFP_CALL_STATUS_WAITING)
670 _bt_incoming_call_indicator(t_call->call_number,
675 case HFP_CALL_STATUS_ACTIVE:
676 DBG(" This is an Active call");
677 if (t_call->call_on_hold) {
678 t_call->call_on_hold = FALSE;
679 __bt_hfp_handle_call_on_hold_request();
681 if (!g_slist_find(agent_active_call_list, t_call)) {
682 DBG(" This call is not in the active call list. So Add it to the list.\n");
683 agent_active_call_list =
684 g_slist_prepend(agent_active_call_list,
687 if (g_slist_length(agent_active_call_list) == 1) {
688 DBG(" Update indicator to show the call presence.\n");
689 __bt_hfp_modify_indicator("call",
690 INDICATOR_EVENT_CALL_ACTIVE);
693 __bt_hfp_modify_indicator("callsetup",
694 INDICATOR_EVENT_CALLSETUP_INACTIVE);
695 __bt_hfp_handle_call_on_hold_request();
697 if (!t_call->call_originating)
698 _bt_calling_stopped_indicator();
700 t_call->call_setup = FALSE;
704 case HFP_CALL_STATUS_MO_RELEASE:
705 case HFP_CALL_STATUS_MT_RELEASE:
706 agent_active_call_list = g_slist_remove(agent_active_call_list,
708 if (g_slist_length(agent_active_call_list) == 0)
709 __bt_hfp_modify_indicator("call",
710 INDICATOR_EVENT_CALL_INACTIVE);
712 if (org_status == HFP_CALL_STATUS_HOLD)
713 __bt_hfp_modify_indicator("callheld", INDICATOR_EVENT_CALLHELD_NONE);
715 if ((org_status == HFP_CALL_STATUS_MO_ALERTING) ||
716 (org_status == HFP_CALL_STATUS_COMING) ||
717 (org_status == HFP_CALL_STATUS_CREATE) ||
718 (org_status == HFP_CALL_STATUS_WAITING)) {
719 __bt_hfp_modify_indicator("callsetup",
720 INDICATOR_EVENT_CALLSETUP_INACTIVE);
723 if (org_status == HFP_CALL_STATUS_COMING) {
724 if (!t_call->call_originating)
725 _bt_calling_stopped_indicator();
727 existing_call_list = g_slist_remove(existing_call_list, t_call);
728 __bt_hfp_free_call(t_call);
731 case HFP_CALL_STATUS_HOLD:
732 t_call->call_on_hold = TRUE;
733 __bt_hfp_handle_call_on_hold_request();
736 case HFP_CALL_STATUS_TERMINATED:
737 if (t_call->call_on_hold &&
738 !__bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD)) {
739 __bt_hfp_modify_indicator("callheld",
740 INDICATOR_EVENT_CALLHELD_NONE);
744 if (call_held == INDICATOR_EVENT_CALLHELD_MULTIPLE &&
745 __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD) &&
746 !__bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE))
747 __bt_hfp_modify_indicator("callheld",
748 INDICATOR_EVENT_CALLHELD_ON_HOLD);
751 case HFP_CALL_STATUS_PROCEEDING:
752 case HFP_CALL_STATUS_SWAP_INITIATED:
753 case HFP_CALL_STATUS_RETRIEVE_INITIATED:
754 case HFP_CALL_STATUS_RECONNECT_PENDING:
755 case HFP_CALL_STATUS_HOLD_INITIATED:
756 case HFP_CALL_STATUS_WAITING:
757 case HFP_CALL_STATUS_ANSWERED:
764 /* Update the call conference status for each of the call */
765 __bt_hfp_handle_call_conference();
768 bt_hfp_agent_error_t _bt_hfp_incoming_call(const char *call_path,
769 const char *incoming_number,
770 uint32_t incoming_call_id,
773 struct telephony_call *t_call = NULL;
774 bt_hfp_agent_error_t hfp_err = BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
775 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
778 if (sender == NULL || call_path == NULL)
779 return BT_HFP_AGENT_ERROR_INVALID_PARAM;
781 if (!__bt_hfp_check_for_callpath(call_path, sender))
782 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
784 if (!__bt_hfp_is_call_allowed(call_path))
785 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
787 /* Its a new call, so create a list for it*/
788 t_call = __bt_hfp_create_new_call(call_path, incoming_call_id,
792 /*get the type of the incoming number*/
793 if (t_call->call_number == NULL) {
794 t_number = AGENT_NUMBER_TYPE_TELEPHONY;
795 ERR("call_number is NULL");
797 if (t_call->call_number[0] == '+' || strncmp(
798 t_call->call_number, "00", 2) == 0)
799 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
801 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE) ||
802 __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD)) {
803 error = _bt_call_waiting_indicator(t_call->call_number,
806 ERR(" Fail to update CCWA information");
809 hfp_err = __bt_hfp_modify_indicator(
810 HFP_AGENT_CALLSETUP_INDICATOR,
811 HFP_INCOMING_CALLSETUP);
812 if (hfp_err != BT_HFP_AGENT_ERROR_NONE)
813 ERR("Failed to update the indicators");
815 __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_WAITING);
817 DBG(" It is an incoming call");
820 hfp_err = __bt_hfp_modify_indicator(
821 HFP_AGENT_CALLSETUP_INDICATOR,
822 HFP_INCOMING_CALLSETUP);
823 if (hfp_err != BT_HFP_AGENT_ERROR_NONE)
824 ERR("Failed to update the indicators");
827 error = _bt_incoming_call_indicator(t_call->call_number,
830 __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_COMING);
832 if (error == -ENODEV)
833 return BT_HFP_AGENT_ERROR_NOT_CONNECTED;
834 else if (error == -EBUSY)
835 return BT_HFP_AGENT_ERROR_BUSY;
842 bt_hfp_agent_error_t _bt_hfp_outgoing_call(const char *call_path,
844 uint32_t call_id, const char *sender)
846 struct telephony_call *t_call = NULL;
847 bt_hfp_agent_error_t ret = BT_HFP_AGENT_ERROR_NONE;
848 gboolean err = FALSE;
851 err = __bt_hfp_check_for_callpath(call_path, sender);
853 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
855 /*check if the call_path exisits in the active call list, if not
856 don't allow as the call may be initated by some other application*/
858 err = __bt_hfp_is_call_allowed(call_path);
860 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
862 /* create a new call for the call_path */
863 t_call = __bt_hfp_create_new_call(call_path, call_id, number, sender);
865 __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_CREATE);
867 ret = __bt_hfp_modify_indicator(HFP_AGENT_CALLSETUP_INDICATOR,
868 HFP_OUTGOING_CALLSETUP);
869 if (ret != BT_HFP_AGENT_ERROR_NONE)
870 DBG("Error in updating indicator");
875 bt_hfp_agent_error_t _bt_hfp_change_call_status(const char *call_path,
876 const char *number, uint32_t call_status,
877 uint32_t call_id, const char *sender)
879 GSList *call_list = existing_call_list;
880 struct telephony_call *t_call = NULL;
881 gboolean ret = FALSE;
883 if (call_status > AG_MAX_LENGTH)
884 return BT_HFP_AGENT_ERROR_INVALID_PARAM;
886 ret = __bt_hfp_check_for_callpath(call_path, sender);
889 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
891 ret = __bt_hfp_is_call_allowed(call_path);
893 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
895 /* find call with the given call_id*/
896 DBG(" Find call with the given call Id from the list");
897 while (call_list != NULL) {
898 t_call = call_list->data;
900 if (t_call->call_id == call_id) {
901 DBG("Call Id Match");
907 call_list = call_list->next;
910 if (t_call == NULL) {
911 DBG("t_call is NULL. So create new call");
912 t_call = __bt_hfp_create_new_call(call_path,
913 call_id, number, sender);
916 __bt_hfp_set_call_status(t_call, call_status);
918 return BT_HFP_AGENT_ERROR_NONE;
921 static int __bt_hfp_update_battery_strength(int32_t battery_strength)
923 int bat_strength = 0;
926 DBG(" Battery strength is.... %d", battery_strength);
928 /* get the current battery level */
929 for (x = 0; hfp_ag_ind[x].indicator_desc != NULL; x++) {
930 if (g_str_equal(hfp_ag_ind[x].indicator_desc, "battchg"))
931 bat_strength = hfp_ag_ind[x].hfp_value;
934 /* We need to send battery status ranging from 0-5 */
935 if (battery_strength < 5)
937 else if (battery_strength >= 100)
940 change_value = battery_strength / 20 + 1;
942 if (bat_strength == change_value) {
943 DBG("no change in battery strength");
947 if (__bt_hfp_modify_indicator("battchg",
948 change_value) == BT_HFP_AGENT_ERROR_NONE)
954 static int __bt_hfp_update_signal_strength(int32_t signal_strength_bars)
956 if (signal_strength_bars < 0)
957 signal_strength_bars = 0;
958 else if (signal_strength_bars > 5)
959 signal_strength_bars = 5;
961 if (network_info.signal_strength == signal_strength_bars) {
962 DBG("no change in signal strength");
966 network_info.signal_strength = signal_strength_bars;
968 if (__bt_hfp_modify_indicator("signal",
969 signal_strength_bars) == BT_HFP_AGENT_ERROR_NONE)
975 static int __bt_hfp_update_registration_status(uint8_t register_status)
977 bt_hfp_agent_error_t reg_ret = BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
979 DBG("Updating registration status to.... %d", register_status);
981 if (network_info.network_status == register_status) {
982 DBG("No change in registration status");
986 if (register_status == BT_AGENT_NETWORK_REG_STATUS_ROAMING) {
987 reg_ret = __bt_hfp_modify_indicator("roam",
988 INDICATOR_EVENT_ROAM_ACTIVE);
990 if (network_info.network_status >
991 BT_AGENT_NETWORK_REG_STATUS_ROAMING)
992 reg_ret = __bt_hfp_modify_indicator("service",
993 INDICATOR_EVENT_SERVICE_PRESENT);
994 } else if (register_status == BT_AGENT_NETWORK_REG_STATUS_HOME) {
995 reg_ret = __bt_hfp_modify_indicator("roam",
996 INDICATOR_EVENT_ROAM_INACTIVE);
998 if (network_info.network_status >
999 BT_AGENT_NETWORK_REG_STATUS_ROAMING)
1000 reg_ret = __bt_hfp_modify_indicator("service",
1001 INDICATOR_EVENT_SERVICE_PRESENT);
1002 } else if (register_status == BT_AGENT_NETWORK_REG_STATUS_OFFLINE ||
1003 register_status == BT_AGENT_NETWORK_REG_STATUS_SEARCHING ||
1004 register_status == BT_AGENT_NETWORK_REG_STATUS_NO_SIM ||
1005 register_status == BT_AGENT_NETWORK_REG_STATUS_POWEROFF ||
1006 register_status == BT_AGENT_NETWORK_REG_STATUS_POWERSAFE ||
1007 register_status == BT_AGENT_NETWORK_REG_STATUS_NO_COVERAGE ||
1008 register_status == BT_AGENT_NETWORK_REG_STATUS_REJECTED ||
1009 register_status == BT_AGENT_NETWORK_REG_STATUS_UNKOWN) {
1010 if (network_info.network_status <
1011 BT_AGENT_NETWORK_REG_STATUS_OFFLINE)
1012 reg_ret = __bt_hfp_modify_indicator("service",
1013 INDICATOR_EVENT_SERVICE_NONE);
1016 network_info.network_status = register_status;
1017 if (reg_ret == BT_HFP_AGENT_ERROR_NONE)
1023 int _bt_hfp_set_property_value(const char *property, int value)
1027 DBG("Property is %s", property);
1029 if (g_str_equal("RegistrationChanged", property))
1030 ret = __bt_hfp_update_registration_status(value);
1032 else if (g_str_equal("SignalBarsChanged", property))
1033 ret = __bt_hfp_update_signal_strength(value);
1035 else if (g_str_equal("BatteryBarsChanged", property))
1036 ret = __bt_hfp_update_battery_strength(value);
1040 /* LCOV_EXCL_STOP */
1042 int _bt_hfp_set_property_name(const char *property, const char *operator_name)
1046 if (operator_name == NULL)
1049 if (g_str_equal("OperatorNameChanged", property)) {
1050 g_free(network_info.network_operator_name);
1051 network_info.network_operator_name =
1052 g_strndup(operator_name, 16);
1056 if (g_str_equal("SubscriberNumberChanged", property)) {
1057 g_free(ag_subscriber_num);
1058 ag_subscriber_num = g_strdup(operator_name);
1059 DBG("HFP: subscriber_number updated: %s", ag_subscriber_num);
1065 /* LCOV_EXCL_START */
1066 static int __bt_hfp_answer_call(struct telephony_call *t_call)
1068 if (t_call->call_id != 0 && t_call->call_path != NULL &&
1069 t_call->call_sender != NULL) {
1070 _bt_ag_agent_answer_call(t_call->call_id,
1072 t_call->call_sender);
1077 /* LCOV_EXCL_STOP */
1079 void _bt_hfp_answer_call_request(void *t_device)
1081 struct telephony_call *t_call;
1083 t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_COMING);
1086 t_call = __bt_hfp_get_call_with_status(
1087 HFP_CALL_STATUS_MT_ALERTING);
1090 t_call = __bt_hfp_get_call_with_status(
1091 HFP_CALL_STATUS_PROCEEDING);
1094 t_call = __bt_hfp_get_call_with_status(
1095 HFP_CALL_STATUS_WAITING);
1097 if (t_call == NULL) {
1098 _bt_answer_call_response(t_device,
1099 HFP_STATE_MNGR_ERR_NOT_ALLOWED);
1103 /* LCOV_EXCL_START */
1104 if (__bt_hfp_answer_call(t_call) < 0)
1105 _bt_answer_call_response(t_device,
1106 HFP_STATE_MNGR_ERR_AG_FAILURE);
1108 _bt_answer_call_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1109 /* LCOV_EXCL_STOP */
1113 void _bt_hfp_dial_number_request(const char *dial_number, void *t_device)
1115 int call_flag = caller_id;
1116 bt_hfp_agent_error_t error_code = 0;
1118 if (strncmp(dial_number, "#31#", 4) == 0) {
1119 dial_number = dial_number + 4;
1120 call_flag = ALLOW_CALL_FLAG;
1121 } else if (strncmp(dial_number, "*31#", 4) == 0) {
1122 dial_number = dial_number + 4;
1123 call_flag = RESTRAIN_CALL_FLAG;
1124 } else if (dial_number[0] == '>') {
1125 int dial_location = strtol(&dial_number[1], NULL, 0);
1127 error_code = _bt_ag_agent_dial_memory(dial_location);
1129 if (error_code == BT_HFP_AGENT_ERROR_NONE)
1130 _bt_dial_number_response(t_device,
1131 HFP_STATE_MNGR_ERR_NONE); /* LCOV_EXCL_LINE */
1133 _bt_dial_number_response(t_device,
1134 HFP_STATE_MNGR_ERR_AG_FAILURE);
1138 error_code = _bt_ag_agent_dial_num(dial_number, call_flag);
1140 if (error_code == BT_HFP_AGENT_ERROR_NONE) {
1141 _bt_dial_number_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1145 _bt_dial_number_response(t_device, HFP_STATE_MNGR_ERR_AG_FAILURE); /* LCOV_EXCL_LINE */
1149 void _bt_hfp_update_event_request(int indicator, void *t_device)
1152 update_events = TRUE;
1154 update_events = FALSE;
1156 _bt_event_reporting_response(t_device,
1157 HFP_STATE_MNGR_ERR_NONE);
1160 /* LCOV_EXCL_START */
1161 static int __bt_bt_hfp_reject_call(struct telephony_call *t_call)
1165 if (t_call != NULL) {
1166 DBG(" rejecting call from sender %s with call path %s and call id %d",
1167 t_call->call_sender,
1171 ret = _bt_ag_agent_reject_call(t_call->call_id,
1173 t_call->call_sender);
1181 static int __bt_hfp_release_call(struct telephony_call *t_call)
1183 gboolean ret = _bt_ag_agent_release_call(t_call->call_id,
1185 t_call->call_sender);
1192 static int __bt_hfp_release_conference(void)
1194 GSList *temp_list = existing_call_list;
1196 while (temp_list != NULL) {
1197 struct telephony_call *t_call = temp_list->data;
1199 if (t_call->call_conference)
1200 __bt_hfp_release_call(t_call);
1202 temp_list = temp_list->next;
1206 /* LCOV_EXCL_STOP */
1208 void _bt_hfp_terminate_call_request(void *t_device)
1210 struct telephony_call *t_call;
1211 struct telephony_call *t_alert = NULL;
1214 t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE);
1216 if (t_call == NULL) {
1217 DBG("Find non-idle call");
1218 GSList *temp_call_list = existing_call_list;
1219 while (temp_call_list != NULL) {
1220 /* LCOV_EXCL_START */
1221 t_call = temp_call_list->data;
1223 if (t_call->call_status == HFP_AGENT_CALL_IDLE)
1224 temp_call_list = temp_call_list->next;
1227 /* LCOV_EXCL_STOP */
1231 if (t_call == NULL) {
1232 DBG("Seems like there are no active calls. So do not allow the call");
1233 _bt_terminate_call_response(t_device,
1234 HFP_STATE_MNGR_ERR_NOT_ALLOWED);
1238 /* LCOV_EXCL_START */
1239 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_WAITING) != NULL) {
1241 t_error = _bt_ag_agent_threeway_call(value, t_call->call_path,
1242 t_call->call_sender);
1243 } else if ((t_alert = __bt_hfp_get_call_with_status(
1244 HFP_CALL_STATUS_CREATE))
1246 t_error = __bt_hfp_release_call(t_alert);
1247 } else if ((t_alert = __bt_hfp_get_call_with_status(
1248 HFP_CALL_STATUS_MO_ALERTING))
1250 t_error = __bt_hfp_release_call(t_alert);
1251 } else if ((t_alert = __bt_hfp_get_call_with_status(
1252 HFP_CALL_STATUS_COMING)) != NULL) {
1253 t_error = __bt_bt_hfp_reject_call(t_alert);
1254 } else if (t_call->call_conference)
1255 t_error = __bt_hfp_release_conference();
1257 t_error = __bt_hfp_release_call(t_call);
1260 _bt_terminate_call_response(t_device,
1261 HFP_STATE_MNGR_ERR_AG_FAILURE);
1263 _bt_terminate_call_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1264 /* LCOV_EXCL_STOP */
1267 void _bt_hfp_call_hold_request(const char *t_cmd, void *t_device)
1270 struct telephony_call *t_call = NULL;
1271 GSList *t_sender_list = call_senders_paths;
1272 sender_info_t *sender_info = NULL;
1273 uint32_t t_chld_value;
1275 t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE);
1276 if (t_call == NULL) {
1278 __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD))
1280 if ((t_call = __bt_hfp_get_call_with_status(
1281 HFP_CALL_STATUS_WAITING)) == NULL) {
1282 /* means there is no outgoing call*/
1283 _bt_call_hold_response(t_device,
1284 HFP_STATE_MNGR_ERR_AG_FAILURE);
1290 /* LCOV_EXCL_START */
1291 while (t_sender_list != NULL) {
1292 sender_info = t_sender_list->data;
1293 if (sender_info == NULL) {
1294 _bt_call_hold_response(t_device,
1295 HFP_STATE_MNGR_ERR_AG_FAILURE);
1298 if (g_strcmp0(t_call->call_path, sender_info->sender_path)
1302 t_sender_list = t_sender_list->next;
1305 t_chld_value = strtoul(&t_cmd[0], NULL, 0);
1306 gboolean ret = _bt_ag_agent_threeway_call(t_chld_value,
1308 t_call->call_sender);
1311 _bt_call_hold_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1313 _bt_call_hold_response(t_device, HFP_STATE_MNGR_ERR_AG_FAILURE);
1314 /* LCOV_EXCL_STOP */
1317 void _bt_hfp_key_press_request(const char *t_key_press, void *t_device)
1319 struct telephony_call *t_active_call;
1320 struct telephony_call *t_waiting_call;
1323 t_waiting_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_COMING);
1325 if (t_waiting_call == NULL)
1326 t_waiting_call = __bt_hfp_get_call_with_status(
1327 HFP_CALL_STATUS_MT_ALERTING);
1329 if (t_waiting_call == NULL)
1330 t_waiting_call = __bt_hfp_get_call_with_status(
1331 HFP_CALL_STATUS_PROCEEDING);
1333 t_active_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE);
1336 if (t_waiting_call != NULL)
1337 t_error = __bt_hfp_answer_call(t_waiting_call);
1338 else if (t_active_call != NULL)
1339 t_error = __bt_hfp_release_call(t_active_call);
1341 if (_bt_ag_agent_dial_last_num(t_device) !=
1342 BT_HFP_AGENT_ERROR_NONE)
1343 _bt_dial_number_response(t_device,
1344 HFP_STATE_MNGR_ERR_AG_FAILURE);
1346 _bt_dial_number_response(t_device,
1347 HFP_STATE_MNGR_ERR_NONE);
1352 _bt_key_press_response(t_device,
1353 HFP_STATE_MNGR_ERR_AG_FAILURE);
1355 _bt_key_press_response(t_device,
1356 HFP_STATE_MNGR_ERR_NONE);
1359 void _bt_hfp_last_dialed_number_request(void *t_device)
1361 bt_hfp_agent_error_t error = _bt_ag_agent_dial_last_num(t_device);
1363 if (error != BT_HFP_AGENT_ERROR_NONE)
1364 _bt_dial_number_response(t_device,
1365 HFP_STATE_MNGR_ERR_AG_FAILURE);
1367 _bt_dial_number_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1370 void _bt_hfp_channel_dtmf_request(char t_tone, void *t_device)
1372 char buf[2] = { t_tone, '\0' };
1373 char *tone_buffer = buf;
1375 struct telephony_call *t_call = __bt_hfp_get_call_with_status(
1376 HFP_CALL_STATUS_ACTIVE);
1377 if (t_call == NULL) {
1378 t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD);
1379 if (t_call == NULL) {
1380 t_call = __bt_hfp_get_call_with_status(
1381 HFP_CALL_STATUS_WAITING);
1382 if (t_call == NULL) {
1383 /* if this point is reached,
1384 it means there is no ongoing call */
1385 _bt_transmit_dtmf_response(t_device,
1386 HFP_STATE_MNGR_ERR_AG_FAILURE);
1392 /* LCOV_EXCL_START */
1393 if (_bt_ag_agent_send_dtmf(tone_buffer, t_call->call_path,
1394 t_call->call_sender) != BT_HFP_AGENT_ERROR_NONE) {
1395 _bt_transmit_dtmf_response(t_device,
1396 HFP_STATE_MNGR_ERR_AG_FAILURE);
1400 _bt_transmit_dtmf_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1401 /* LCOV_EXCL_STOP */
1404 void _bt_hfp_vendor_cmd_request(const char *cmd,
1407 GSList *t_sender_list = call_senders_paths;
1408 sender_info_t *sender_info = NULL;
1410 bt_hfp_agent_error_t error = BT_HFP_AGENT_ERROR_NONE;
1412 if (NULL != t_sender_list) {
1413 /* LCOV_EXCL_START */
1414 for (l = t_sender_list; l != NULL; l = l->next) {
1415 sender_info = l->data;
1416 error = _bt_ag_agent_vendor_cmd(cmd,
1417 sender_info->sender_path,
1418 sender_info->sender_name);
1419 if (error != BT_HFP_AGENT_ERROR_NONE)
1422 /* LCOV_EXCL_STOP */
1425 if (error != BT_HFP_AGENT_ERROR_NONE)
1426 _bt_vendor_cmd_response(t_device,
1427 HFP_STATE_MNGR_ERR_AG_FAILURE);
1429 _bt_vendor_cmd_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1432 void _bt_hfp_subscriber_number_request(void *t_device)
1434 if (ag_subscriber_num != NULL) {
1435 /* LCOV_EXCL_START */
1436 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
1438 if (ag_subscriber_num[0] == '+' || strncmp(
1439 ag_subscriber_num, "00", 2) == 0)
1440 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
1442 _bt_subscriber_number_indicator(ag_subscriber_num,
1443 t_number, AGENT_SUBSCRIBER_SERVICE_VOICE);
1444 /* LCOV_EXCL_STOP */
1447 _bt_subscriber_number_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1450 /* LCOV_EXCL_START */
1451 static int __bt_hfp_get_call_status(struct telephony_call *t_call)
1453 switch (t_call->call_status) {
1454 case HFP_CALL_STATUS_IDLE:
1455 case HFP_CALL_STATUS_MO_RELEASE:
1456 case HFP_CALL_STATUS_MT_RELEASE:
1457 case HFP_CALL_STATUS_TERMINATED:
1460 case HFP_CALL_STATUS_ANSWERED:
1461 case HFP_CALL_STATUS_ACTIVE:
1462 case HFP_CALL_STATUS_RECONNECT_PENDING:
1463 case HFP_CALL_STATUS_SWAP_INITIATED:
1464 case HFP_CALL_STATUS_HOLD_INITIATED:
1465 return AGENT_CALL_STATUS_ACTIVE;
1467 case HFP_CALL_STATUS_RETRIEVE_INITIATED:
1468 case HFP_CALL_STATUS_HOLD:
1469 return AGENT_CALL_STATUS_HELD;
1471 case HFP_CALL_STATUS_WAITING:
1472 return AGENT_CALL_STATUS_WAITING;
1474 case HFP_CALL_STATUS_CREATE:
1475 return AGENT_CALL_STATUS_DIALING;
1477 case HFP_CALL_STATUS_PROCEEDING:
1478 if (t_call->call_originating)
1479 return AGENT_CALL_STATUS_DIALING;
1480 if (g_slist_length(agent_active_call_list) > 0)
1481 return AGENT_CALL_STATUS_WAITING;
1483 return AGENT_CALL_STATUS_INCOMING;
1485 case HFP_CALL_STATUS_COMING:
1486 if (g_slist_length(agent_active_call_list) > 0)
1487 return AGENT_CALL_STATUS_WAITING;
1489 return AGENT_CALL_STATUS_INCOMING;
1491 case HFP_CALL_STATUS_MO_ALERTING:
1492 return AGENT_CALL_STATUS_ALERTING;
1494 case HFP_CALL_STATUS_MT_ALERTING:
1495 return AGENT_CALL_STATUS_INCOMING;
1501 /* LCOV_EXCL_STOP */
1503 void _bt_list_current_calls(void *t_device)
1505 GSList *t_call_list = existing_call_list;
1507 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
1508 int t_direction, t_call_conference;
1511 while (t_call_list != NULL) {
1512 /* LCOV_EXCL_START */
1513 struct telephony_call *t_call = t_call_list->data;
1514 t_status = __bt_hfp_get_call_status(t_call);
1515 if (t_status >= 0) {
1516 if (t_call->call_originating != TRUE)
1517 t_direction = AGENT_CALL_DIRECTION_INCOMING;
1519 t_direction = AGENT_CALL_DIRECTION_OUTGOING;
1521 if (t_call->call_conference != TRUE)
1522 t_call_conference = AGENT_CALL_MULTIPARTY_NO;
1524 t_call_conference = AGENT_CALL_MULTIPARTY_YES;
1526 if (t_call->call_number == NULL) {
1527 t_number = AGENT_NUMBER_TYPE_TELEPHONY;
1529 if (t_call->call_number[0] == '+' || strncmp(
1530 t_call->call_number, "00", 2) == 0)
1531 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
1534 index = t_call->call_id;
1535 _bt_list_current_call_indicator(t_device, index, t_direction,
1536 AGENT_CALL_MODE_VOICE,
1538 t_call->call_number,
1542 t_call_list = t_call_list->next;
1543 /* LCOV_EXCL_STOP */
1545 _bt_list_current_calls_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1548 void _bt_hfp_release_all_calls_by_sender(const char *sender)
1550 GSList *temp_list = existing_call_list;
1556 DBG("sender [%s]", sender);
1558 while (temp_list != NULL) {
1559 /* LCOV_EXCL_START */
1560 struct telephony_call *t_call = temp_list->data;
1562 if (g_strcmp0(t_call->call_sender, sender) == 0) {
1563 INFO("terminate call[%d]", t_call->call_id);
1564 next_list = temp_list->next;
1565 __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_MT_RELEASE);
1566 temp_list = next_list;
1568 temp_list = temp_list->next;
1569 /* LCOV_EXCL_STOP */
1573 void _bt_hfp_noise_red_and_echo_cancel_request(gboolean t_enable,
1576 if (_bt_hfp_agent_nrec_status(t_enable, t_device) == TRUE)
1577 _bt_nr_and_ec_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1579 _bt_nr_and_ec_response(t_device, HFP_STATE_MNGR_ERR_AG_FAILURE);
1584 void _bt_hfp_voice_dial_request(gboolean t_enable, void *t_device)
1586 gboolean ret = FALSE;
1589 if (vconf_get_int(VCONFKEY_CALL_STATE, &call_state) < 0)
1590 ERR("vconf_get_int is failed");
1592 if ((t_enable == TRUE && call_state == 0) || t_enable == FALSE)
1593 ret = _bt_ag_agent_voice_dial(t_enable);
1596 _bt_voice_dial_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1598 _bt_voice_dial_response(t_device,
1599 HFP_STATE_MNGR_ERR_AG_FAILURE);
1604 void _bt_hfp_set_indicators(const char *t_command, void *t_device)
1606 const char delims = ',';
1609 if (t_command == NULL)
1612 str = strchr(t_command, '=');
1613 while (hfp_ag_ind[i].indicator_desc != NULL && str != NULL) {
1616 /* LCOV_EXCL_START */
1617 if ((g_strcmp0(hfp_ag_ind[i].indicator_desc, "call") != 0) &&
1618 (g_strcmp0(hfp_ag_ind[i].indicator_desc, "callheld") != 0) &&
1619 (g_strcmp0(hfp_ag_ind[i].indicator_desc, "callsetup") != 0)) {
1622 hfp_ag_ind[i].is_activated = FALSE;
1623 } else if (*str == '1') {
1624 hfp_ag_ind[i].is_activated = TRUE;
1626 DBG(" no change in is_activated for[%s]\n",
1627 hfp_ag_ind[i].indicator_desc);
1630 str = strchr(str, delims);
1632 /* LCOV_EXCL_STOP */
1635 _bt_indicators_activation_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1639 _bt_indicators_activation_response(t_device,
1640 HFP_STATE_MNGR_ERR_INVALID_CHAR_IN_STRING);
1644 static int __bt_hfp_get_phonebook_count(const char *path, uint32_t *max_size,
1647 #ifndef TIZEN_PROFILE_WEARABLE
1648 GDBusConnection *g_conn;
1649 GDBusProxy *g_proxy;
1651 GVariant *ret = NULL;
1655 g_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1659 ERR("Unable to connect to gdbus: %s", err->message);
1660 g_clear_error(&err);
1665 g_proxy = g_dbus_proxy_new_sync(g_conn,
1666 G_DBUS_PROXY_FLAGS_NONE, NULL,
1667 PHONEBOOK_AGENT_BUS_NAME, PHONEBOOK_AGENT_PATH,
1668 PHONEBOOK_AGENT_INTERFACE, NULL, &err);
1672 ERR("Unable to connect to gdbus: %s", err->message);
1673 g_clear_error(&err);
1678 /* LCOV_EXCL_START */
1679 ret = g_dbus_proxy_call_sync(g_proxy, "GetPhonebookSizeAt",
1680 g_variant_new("(s)",
1682 G_DBUS_CALL_FLAGS_NONE, -1,
1686 ERR("dbus call failed");
1688 ERR("D-Bus API failure: errCode[%x], message[%s]",
1689 err->code, err->message);
1691 g_clear_error(&err);
1695 g_variant_get(ret, "(u)", &size);
1696 g_variant_unref(ret);
1698 DBG("Size returned %d", size);
1699 if ((g_strcmp0(path, "\"SM\"") == 0) ||
1700 (g_strcmp0(path, "\"ME\"") == 0)) {
1701 max = AGENT_MAX_PB_COUNT;
1702 } else if ((g_strcmp0(path, "\"DC\"") == 0) ||
1703 (g_strcmp0(path, "\"MC\"") == 0) ||
1704 (g_strcmp0(path, "\"RC\"") == 0)) {
1705 max = AGENT_MAX_CALLLOG_COUNT;
1718 g_object_unref(g_conn);
1720 g_object_unref(g_proxy);
1721 /* LCOV_EXCL_STOP */
1726 void _bt_hfp_select_phonebook_memory_status(void *t_device)
1728 int32_t path_id = ag_pb_info.path_id;
1730 uint32_t max_size = 0;
1732 hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1734 if (path_id < 0 || path_id >= AGENT_PB_STORE_LIST_SIZE)
1737 if (__bt_hfp_get_phonebook_count(agent_pb_store_list[path_id],
1739 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1741 _bt_select_phonebook_memory_status_response(t_device,
1742 agent_pb_store_list[path_id],
1747 static char *__bt_hfp_get_supported_list(const char *char_list[],
1754 if (char_list == NULL || size == 0)
1757 strng = g_string_new("(");
1759 while (index < size) {
1761 g_string_append(strng, ",");
1763 g_string_append(strng, char_list[index]);
1767 g_string_append(strng, ")");
1769 return g_string_free(strng, FALSE);
1772 void _bt_hfp_select_phonebook_memory_list(void *t_device)
1776 str = __bt_hfp_get_supported_list(agent_pb_store_list,
1777 AGENT_PB_STORE_LIST_SIZE);
1779 _bt_select_phonebook_memory_list_response(t_device,
1780 str, HFP_STATE_MNGR_ERR_NONE);
1785 void _bt_hfp_select_phonebook_memory(void *t_device, const gchar *pb_path)
1788 hfp_state_manager_err_t err;
1790 while (i < AGENT_PB_STORE_LIST_SIZE) {
1791 if (strcmp(agent_pb_store_list[i], pb_path) == 0)
1796 if (i >= 0 && i < AGENT_PB_STORE_LIST_SIZE) {
1797 err = HFP_STATE_MNGR_ERR_NONE;
1798 ag_pb_info.path_id = i;
1800 err = HFP_STATE_MNGR_ERR_INVALID_CHAR_IN_STRING;
1802 _bt_select_phonebook_memory_response(t_device, err);
1805 void _bt_hfp_read_phonebook_entries_list(void *t_device)
1807 hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1809 int32_t path_id = ag_pb_info.path_id;
1812 if (path_id < 0 || path_id >= AGENT_PB_STORE_LIST_SIZE)
1813 err = HFP_STATE_MNGR_ERR_INVALID_INDEX;
1815 if (__bt_hfp_get_phonebook_count(agent_pb_store_list[path_id],
1816 NULL, &used) != 0) {
1817 err = HFP_STATE_MNGR_ERR_NOT_ALLOWED;
1821 _bt_read_phonebook_entries_list_response(t_device, used,
1822 AGENT_PB_NUMBER_MAX_LENGTH, AGENT_PB_NAME_MAX_LENGTH,
1826 static int __bt_hfp_get_phonebook_entries(int start_index, int end_index)
1828 #ifdef TIZEN_PROFILE_WEARABLE
1831 GDBusConnection *g_conn;
1832 GDBusProxy *g_proxy;
1834 GVariant *ret = NULL;
1836 GVariant *value = NULL;
1837 GVariant *tuple = NULL;
1838 const char *name = NULL;
1839 const char *number = NULL;
1844 uint32_t handle = 0;
1846 g_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1850 ERR("Unable to connect to gdbus: %s", err->message);
1851 g_clear_error(&err);
1856 g_proxy = g_dbus_proxy_new_sync(g_conn,
1857 G_DBUS_PROXY_FLAGS_NONE, NULL,
1858 PHONEBOOK_AGENT_BUS_NAME, PHONEBOOK_AGENT_PATH,
1859 PHONEBOOK_AGENT_INTERFACE, NULL, &err);
1862 ERR("Unable to connect to gdbus: %s", err->message);
1863 g_clear_error(&err);
1868 /* LCOV_EXCL_START */
1869 ret = g_dbus_proxy_call_sync(g_proxy, "GetPhonebookEntriesAt",
1870 g_variant_new("(sii)",
1871 agent_pb_store_list[ag_pb_info.path_id],
1872 start_index, end_index),
1873 G_DBUS_CALL_FLAGS_NONE, -1,
1877 ERR("Dbus call failed");
1879 ERR("D-Bus API failure: errCode[%x], message[%s]",
1880 err->code, err->message);
1882 g_clear_error(&err);
1884 ERR("error returned was NULL");
1888 tuple = g_variant_get_child_value(ret, 0);
1889 if (tuple != NULL) {
1890 int number_contacts = g_variant_n_children(tuple);
1891 DBG("number of contacts %d", number_contacts);
1892 while (count < number_contacts) {
1895 value = g_variant_get_child_value(tuple, count);
1897 g_variant_get(value, "(ssu)", &name, &number, &handle);
1899 uni_name = g_strndup(name, AGENT_PB_NAME_MAX_LENGTH);
1900 uni_number = g_strndup(number, AGENT_PB_NAME_MAX_LENGTH);
1902 _bt_read_phonebook_entries_indicator(uni_name,
1903 uni_number, handle);
1904 g_variant_unref(value);
1907 g_free((gpointer)name);
1908 g_free((gpointer)number);
1910 g_variant_unref(tuple);
1913 g_variant_unref(ret);
1915 g_object_unref(g_conn);
1917 g_object_unref(g_proxy);
1918 /* LCOV_EXCL_STOP */
1923 void _bt_hfp_read_phonebook_entries(void *t_device, const char *cmd)
1925 int start_index = 0;
1933 hfp_state_manager_err_t err;
1938 str = g_strdup(cmd);
1939 next = strchr(str, ',');
1945 end_index = strtol(next, NULL, 10);
1948 start_index = strtol(str, NULL, 10);
1952 count = __bt_hfp_get_phonebook_entries(start_index, end_index);
1955 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1956 else if (count == 0)
1957 err = HFP_STATE_MNGR_ERR_INVALID_INDEX;
1959 err = HFP_STATE_MNGR_ERR_NONE;
1961 _bt_read_phonebook_entries_response(t_device, err);
1964 void _bt_hfp_find_phonebook_entries_status(void *t_device)
1966 _bt_find_phonebook_entries_status_indicator(
1967 AGENT_PB_NUMBER_MAX_LENGTH,
1968 AGENT_PB_NAME_MAX_LENGTH);
1970 _bt_find_phonebook_entries_status_response(t_device,
1971 HFP_STATE_MNGR_ERR_NONE);
1974 static int __bt_hfp_find_pb_entries(const char *str)
1979 void _bt_hfp_find_phonebook_entries(void *t_device, const char *cmd)
1982 gchar *unquoted = NULL;
1984 hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1986 /* remove quote and compress */
1987 st = strchr(cmd, '"');
1989 unquoted = g_strdup(cmd);
1993 end = strrchr(cmd, '"');
1995 unquoted = g_strdup(cmd);
1997 unquoted = g_strndup(st + 1, end - st - 1);
2000 if (__bt_hfp_find_pb_entries(unquoted))
2001 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
2003 _bt_find_phonebook_entries_response(t_device, err);
2008 void _bt_hfp_get_character_set(void *t_device)
2010 _bt_supported_character_generic_response(t_device,
2011 (char *)agent_supported_character_set[ag_pb_info.charset_id],
2012 HFP_STATE_MNGR_ERR_NONE);
2015 void _bt_hfp_list_supported_character(void *t_device)
2019 str = __bt_hfp_get_supported_list(agent_supported_character_set,
2020 AGENT_SUPPORTED_CHARACTER_SET_SIZE);
2022 _bt_supported_character_generic_response(t_device,
2023 str, HFP_STATE_MNGR_ERR_NONE);
2028 void _bt_hfp_set_character_set(void *t_device, const char *cmd)
2032 while (index < AGENT_SUPPORTED_CHARACTER_SET_SIZE) {
2033 if (strcmp(agent_supported_character_set[index], cmd) == 0) {
2034 _bt_set_characterset_generic_response(t_device,
2035 HFP_STATE_MNGR_ERR_NONE);
2037 ag_pb_info.charset_id = index;
2043 _bt_set_characterset_generic_response(t_device,
2044 HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
2048 void _bt_hfp_signal_quality_reply(int32_t rssi, int32_t ber,
2051 DBG("signal_quality_reply");
2053 if (rssi == -1 && ber == -1) {
2054 _bt_signal_quality_response(t_device, rssi, ber,
2055 HFP_STATE_MNGR_ERR_AG_FAILURE);
2057 _bt_signal_quality_response(t_device, rssi, ber,
2058 HFP_STATE_MNGR_ERR_NONE);
2062 void _bt_hfp_battery_property_reply(void *data, int32_t bcs,
2065 if (bcs == -1 || bcl == -1) {
2066 _bt_battery_charge_status_response(data, bcs,
2067 bcl, HFP_STATE_MNGR_ERR_AG_FAILURE);
2069 _bt_battery_charge_status_response(data, bcs,
2070 bcl, HFP_STATE_MNGR_ERR_NONE);
2076 void _bt_hfp_get_battery_property(void *t_device)
2078 _bt_ag_agent_get_battery_status(t_device);
2081 void _bt_hfp_operator_reply(char *operator_name, void *t_device)
2083 if (operator_name == NULL)
2086 network_info.network_operator_name = g_strndup(operator_name, 16);
2088 _bt_operator_selection_indicator(AGENT_OPERATOR_MODE_AUTO,
2090 _bt_operator_selection_response(t_device, HFP_STATE_MNGR_ERR_NONE);
2094 _bt_operator_selection_indicator(AGENT_OPERATOR_MODE_AUTO, "UNKNOWN");
2095 _bt_operator_selection_response(t_device,
2096 HFP_STATE_MNGR_ERR_AG_FAILURE);
2099 void _bt_hfp_get_operator_selection_request(void *t_device)
2101 _bt_ag_agent_get_operator_name(t_device);
2104 void _bt_hfp_response_and_hold_request(void *t_device)
2106 _bt_response_and_hold_response(t_device,
2107 HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
2110 void _bt_get_activity_status(void *t_device)
2112 DBG("telephony-tizen: telephony_get_activity_status");
2114 if (NULL != (__bt_hfp_get_call_with_status(
2115 HFP_CALL_STATUS_MT_ALERTING)) ||
2116 NULL != (__bt_hfp_get_call_with_status(
2117 HFP_CALL_STATUS_MO_ALERTING)) ||
2118 NULL != (__bt_hfp_get_call_with_status(
2119 HFP_CALL_STATUS_COMING)) ||
2120 NULL != (__bt_hfp_get_call_with_status(
2121 HFP_CALL_STATUS_CREATE)))
2122 _bt_hfp_get_activity_status_rsp(t_device,
2123 HFP_AGENT_ACTIVITY_STATUS_RINGING,
2124 HFP_STATE_MNGR_ERR_NONE);
2125 else if (NULL != (__bt_hfp_get_call_with_status(
2126 HFP_CALL_STATUS_WAITING)) ||
2127 NULL != (__bt_hfp_get_call_with_status(
2128 HFP_CALL_STATUS_ACTIVE)))
2129 _bt_hfp_get_activity_status_rsp(t_device,
2130 HFP_AGENT_ACTIVITY_STATUS_CALL_IN_PROGRESS,
2131 HFP_STATE_MNGR_ERR_NONE);
2133 _bt_hfp_get_activity_status_rsp(t_device,
2134 HFP_AGENT_ACTIVITY_STATUS_READY,
2135 HFP_STATE_MNGR_ERR_NONE);
2138 void _bt_hfp_get_imei_number_reply(char *imei_number, void *t_device)
2140 _bt_hfp_get_equipment_identity_rsp(t_device, imei_number,
2141 HFP_STATE_MNGR_ERR_NONE);
2144 void _bt_hfp_get_imsi_reply(char *mcc, char *mnc, char *msin, void *t_device)
2146 if (mcc != NULL && mnc != NULL && msin != NULL)
2147 _bt_hfp_get_imsi_rsp(t_device, mcc, mnc, msin,
2148 HFP_STATE_MNGR_ERR_NONE);
2150 _bt_hfp_get_imsi_rsp(t_device, NULL, NULL, NULL,
2151 HFP_STATE_MNGR_ERR_NOT_ALLOWED);
2154 void _bt_hfp_get_creg_status_reply(int n, int status, void *t_device)
2156 _bt_hfp_get_creg_status_rsp(t_device, n, status,
2157 HFP_STATE_MNGR_ERR_NONE);
2160 void _bt_hfp_get_equipment_identity_req(void *t_device)
2162 _bt_ag_agent_get_imei_number(t_device);
2165 void _bt_hfp_get_model_info_reply(char *model, void *t_device)
2167 _bt_hfp_get_model_info_rsp(t_device, model,
2168 HFP_STATE_MNGR_ERR_NONE);
2171 void _bt_hfp_get_model_info_req(void *t_device)
2173 _bt_ag_agent_get_model_name(t_device);
2176 void _bt_hfp_get_device_manufacturer_reply(char *manufacturer, void *t_device)
2178 _bt_hfp_get_device_manufacturer_rsp(t_device, manufacturer,
2179 HFP_STATE_MNGR_ERR_NONE);
2182 void _bt_hfp_get_device_manufacturer_req(void *t_device)
2184 _bt_ag_agent_get_manufacturer_name(t_device);
2187 void _bt_hfp_get_imsi_req(void *t_device)
2189 _bt_ag_agent_get_imsi(t_device);
2192 void _bt_hfp_get_creg_status_req(void *t_device)
2194 _bt_ag_agent_get_creg_status(t_device);
2197 void _bt_hfp_get_revision_info_reply(char *revision, void *t_device)
2199 _bt_hfp_get_revision_info_rsp(t_device, revision,
2200 HFP_STATE_MNGR_ERR_NONE);
2203 void _bt_hfp_get_revision_info_req(void *t_device)
2205 _bt_ag_agent_get_revision_information(t_device);