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 "bluetooth-agent-profile.h"
31 #include "bluetooth-ag-phonebook.h"
33 #include <TapiUtility.h>
36 #include <device/battery.h>
37 #include <device-error.h>
39 #define PHONEBOOK_AGENT_BUS_NAME "org.bluez.pb_agent"
40 #define PHONEBOOK_AGENT_PATH "/org/bluez/pb_agent"
41 #define PHONEBOOK_AGENT_INTERFACE "org.bluez.PbAgent.At"
43 struct telephony_call {
46 gboolean call_originating;
47 gboolean call_emergency;
48 gboolean call_on_hold;
49 gboolean call_conference;
56 #define HFP_AGENT_ACTIVITY_STATUS_READY 0
57 #define HFP_AGENT_ACTIVITY_STATUS_UNAVAILABLE 1
58 #define HFP_AGENT_ACTIVITY_STATUS_UNKNOWN 2
59 #define HFP_AGENT_ACTIVITY_STATUS_RINGING 3
60 #define HFP_AGENT_ACTIVITY_STATUS_CALL_IN_PROGRESS 4
62 #define HFP_AGENT_BATTERY_INDICATOR "battchg"
63 #define HFP_AGENT_CALL_INDICATOR "call"
64 #define HFP_AGENT_CALLHELD_INDICATOR "callheld"
65 #define HFP_AGENT_CALLSETUP_INDICATOR "callsetup"
66 #define HFP_AGENT_ROAMING_INDICATOR "roam"
67 #define HFP_AGENT_SERVICE_INDICATOR "service"
68 #define HFP_AGENT_SIGNAL_INDICATOR "signal"
70 #define HFP_AGENT_CALL_IDLE 0
71 #define HFP_AGENT_CALL_ACTIVE 1
73 #define HFP_INCOMING_CALLSETUP 1
74 #define HFP_OUTGOING_CALLSETUP 2
75 #define RESTRAIN_CALL_FLAG 0x01
76 #define ALLOW_CALL_FLAG 0x02
78 #define HFP_CALL_STATUS_IDLE 0
79 #define HFP_CALL_STATUS_CREATE 1
80 #define HFP_CALL_STATUS_COMING 2
81 #define HFP_CALL_STATUS_PROCEEDING 3
82 #define HFP_CALL_STATUS_MO_ALERTING 4
83 #define HFP_CALL_STATUS_MT_ALERTING 5
84 #define HFP_CALL_STATUS_WAITING 6
85 #define HFP_CALL_STATUS_ANSWERED 7
86 #define HFP_CALL_STATUS_ACTIVE 8
87 #define HFP_CALL_STATUS_MO_RELEASE 9
88 #define HFP_CALL_STATUS_MT_RELEASE 10
89 #define HFP_CALL_STATUS_HOLD_INITIATED 11
90 #define HFP_CALL_STATUS_HOLD 12
91 #define HFP_CALL_STATUS_RETRIEVE_INITIATED 13
92 #define HFP_CALL_STATUS_RECONNECT_PENDING 14
93 #define HFP_CALL_STATUS_TERMINATED 15
94 #define HFP_CALL_STATUS_SWAP_INITIATED 16
96 #define AGENT_MAX_PB_COUNT 1000
97 #define AGENT_PB_NAME_MAX_LENGTH 20
98 #define AGENT_PB_NUMBER_MAX_LENGTH 20
99 #define AGENT_MAX_CALLLOG_COUNT 30
100 #define ERR_NOT_FOUND -1
101 #define AG_MAX_LENGTH 16
103 static gboolean update_events = FALSE;
104 static int caller_id = 0;
106 static GSList *call_senders_paths = NULL;
107 static GSList *existing_call_list = NULL;
108 static GSList *agent_active_call_list = NULL;
109 static char *ag_subscriber_num = NULL;
111 static guint call_on_hold_timer = 0;
119 char *network_operator_name;
120 uint8_t network_status;
121 int32_t signal_strength;
123 .network_operator_name = NULL,
124 .network_status = BT_AGENT_NETWORK_REG_STATUS_UNKOWN,
125 .signal_strength = 0,
128 #ifdef TIZEN_FEATURE_BT_PBAP_SIM
129 static const char *agent_pb_store_list[] = {
130 "\"ME\"", "\"DC\"", "\"MC\"", "\"SM\"", "\"RC\""
133 static const char *agent_pb_store_list[] = {
134 "\"ME\"", "\"DC\"", "\"MC\"", "\"RC\""
138 static const char *agent_supported_character_set[] = {
139 "\"UTF-8\"", "\"IRA\""
142 #define AGENT_PB_STORE_LIST_SIZE (sizeof(agent_pb_store_list) \
143 /sizeof(const char *))
144 #define AGENT_SUPPORTED_CHARACTER_SET_SIZE ( \
145 sizeof(agent_supported_character_set)/sizeof(const char *))
147 static bt_ag_indicators_t hfp_ag_ind[] = {
148 { "call", "0,1", 0, TRUE, TRUE },
149 { "callsetup", "0-3", 0 , TRUE, TRUE },
150 { "battchg", "0-5", 5 , TRUE, TRUE },
151 { "callheld", "0-2", 0 , FALSE, TRUE },
152 { "roam", "0,1", 0 , TRUE, TRUE },
153 { "signal", "0-5", 0 , TRUE, TRUE },
154 { "service", "0,1", 0, TRUE, TRUE },
166 void __bt_hfp_print_callpath(const char *call_path, const char *call_sender)
168 GSList *sender_list = call_senders_paths;
169 sender_info_t *sender;
171 INFO("=============================");
172 INFO("call path is = %s\n", call_path);
173 INFO("sender is = %s\n", call_sender);
175 if (call_path == NULL || call_sender == NULL) {
176 ERR("Invalid Parameters");
180 while (sender_list != NULL) {
181 sender = sender_list->data;
186 INFO("sender->sender_path [%s] ", sender->sender_path);
187 sender_list = sender_list->next;
189 INFO("=============================");
193 static gboolean __bt_hfp_check_for_callpath(const char *call_path,
194 const char *call_sender)
196 GSList *sender_list = call_senders_paths;
197 sender_info_t *sender;
199 DBG("call path is = %s\n", call_path);
200 DBG("sender is = %s\n", call_sender);
202 if (call_path == NULL || call_sender == NULL) {
204 ERR("Invalid Parameters");
208 /*check if the call is already registered*/
209 DBG("Checking if the call is already registered");
210 while (sender_list != NULL) {
211 sender = sender_list->data;
216 if (g_strcmp0(sender->sender_path, call_path) == 0) {
217 DBG("sender path and call path match... so return true");
221 sender_list = sender_list->next;
224 ERR("Call path [%s] is not registered", call_path);
228 static void __bt_hfp_clear_sender_path(sender_info_t *s_path)
233 g_free(s_path->sender_name);
234 g_free(s_path->sender_path);
237 if (g_slist_length(call_senders_paths) == 0) {
238 g_slist_free(call_senders_paths);
239 call_senders_paths = NULL;
243 static void __bt_hfp_free_call(struct telephony_call *t_call)
248 g_free(t_call->call_number);
249 g_free(t_call->call_path);
250 g_free(t_call->call_sender);
254 static void __bt_hfp_reset_indicators(void)
258 for (i = 0; hfp_ag_ind[i].indicator_desc != NULL; i++)
259 hfp_ag_ind[i].is_activated = TRUE;
262 void _bt_hfp_device_disconnected(void *t_device)
264 DBG("hfp_agent: device %p disconnected", t_device);
265 update_events = FALSE;
266 __bt_hfp_reset_indicators();
269 void _bt_hfp_initialize_telephony_manager(uint32_t ag_features, TapiHandle *handler)
276 if (TIZEN_PROFILE_WEARABLE)
277 ag_chld_str = "0,1,2";
279 ag_chld_str = "0,1,2,3";
281 /* Reset the indicator values */
282 for (index = 0; hfp_ag_ind[index].indicator_desc != NULL; index++) {
283 if (g_str_equal(hfp_ag_ind[index].indicator_desc, "battchg")) {
284 ret = device_battery_get_percent(&value);
285 if (ret != DEVICE_ERROR_NONE) {
286 ERR("Get battery status failed. Err = %d\n", ret);
288 /* Send battery status ranging from 0-5 */
290 hfp_ag_ind[index].hfp_value = 0;
291 else if (value >= 100)
292 hfp_ag_ind[index].hfp_value = 5;
294 hfp_ag_ind[index].hfp_value = value / 20 + 1;
296 } else if (g_str_equal(hfp_ag_ind[index].indicator_desc, "signal")) {
297 ret = tel_get_property_int(handler, TAPI_PROP_NETWORK_SIGNALSTRENGTH_LEVEL, &value);
298 if (ret != TAPI_API_SUCCESS) {
299 ERR("Get signal status failed err = %d\n", ret);
301 BT_CHECK_SIGNAL_STRENGTH(value);
302 hfp_ag_ind[index].hfp_value = value;
304 } else if (g_str_equal(hfp_ag_ind[index].indicator_desc, "roam")) {
305 ret = tel_get_property_int(handler, TAPI_PROP_NETWORK_ROAMING_STATUS, &value);
306 if (ret != TAPI_API_SUCCESS)
307 ERR("Get roaming status failed err = %d\n", ret);
309 hfp_ag_ind[index].hfp_value = value;
310 } else if (g_str_equal(hfp_ag_ind[index].indicator_desc, "service")) {
311 ret = tel_get_property_int(handler, TAPI_PROP_NETWORK_SERVICE_TYPE, &value);
312 if (ret != TAPI_API_SUCCESS) {
313 ERR("Get Service status failed : %d\n", ret);
316 case TAPI_NETWORK_SERVICE_TYPE_UNKNOWN:
317 case TAPI_NETWORK_SERVICE_TYPE_NO_SERVICE:
318 case TAPI_NETWORK_SERVICE_TYPE_SEARCH:
319 hfp_ag_ind[index].hfp_value =
320 INDICATOR_EVENT_SERVICE_NONE;
323 hfp_ag_ind[index].hfp_value =
324 INDICATOR_EVENT_SERVICE_PRESENT;
329 hfp_ag_ind[index].hfp_value = 0;
333 /*Initializatoin of the indicators*/
334 _bt_hfp_set_ag_indicator(ag_features, hfp_ag_ind,
335 BT_RSP_HOLD_NOT_SUPPORTED,
339 void _bt_hfp_deinitialize_telephony_manager(void)
341 GSList *list = call_senders_paths;
343 g_free(ag_subscriber_num);
344 ag_subscriber_num = NULL;
346 g_free(network_info.network_operator_name);
347 network_info.network_operator_name = NULL;
349 network_info.network_status = BT_AGENT_NETWORK_REG_STATUS_UNKOWN;
350 network_info.signal_strength = 0;
352 g_slist_free(agent_active_call_list);
353 agent_active_call_list = NULL;
355 g_slist_foreach(existing_call_list, (GFunc) __bt_hfp_free_call, NULL);
356 g_slist_free(existing_call_list);
357 existing_call_list = NULL;
359 while (list != NULL) {
360 __bt_hfp_clear_sender_path(list->data);
364 g_slist_free(call_senders_paths);
365 call_senders_paths = NULL;
367 _bt_hfp_deinitialize();
370 bt_hfp_agent_error_t _bt_hfp_register_telephony_agent(gboolean register_flag,
371 const char *path_to_register,
374 sender_info_t *sender_info;
376 if (sender == NULL || path_to_register == NULL)
377 return BT_HFP_AGENT_ERROR_INVALID_PARAM;
379 INFO(" register_flag = %d", register_flag);
380 INFO(" path_to_register = %s", path_to_register);
381 INFO(" sender = %s", sender);
384 if (__bt_hfp_check_for_callpath(path_to_register, sender))
385 return BT_HFP_AGENT_ERROR_ALREADY_EXSIST;
387 /* add call path to the senders list*/
388 INFO("Call path doesn't exist. Add path %s to global path",
390 sender_info = g_new0(sender_info_t, 1);
391 sender_info->sender_path = g_strdup(path_to_register);
392 sender_info->sender_name = g_strdup(sender);
393 call_senders_paths = g_slist_append(call_senders_paths, sender_info);
395 return BT_HFP_AGENT_ERROR_NONE;
397 /*remove the call from senders list */
398 GSList *s_list = call_senders_paths;
400 while (s_list != NULL) {
401 sender_info = s_list->data;
403 if (sender_info == NULL)
404 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
406 if (g_strcmp0(sender_info->sender_path,
407 path_to_register) == 0) {
408 INFO("Remove path [%s]", path_to_register);
409 call_senders_paths = g_slist_remove(
412 __bt_hfp_clear_sender_path(sender_info);
414 return BT_HFP_AGENT_ERROR_NONE;
416 s_list = s_list->next;
419 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
423 static gboolean __bt_hfp_is_call_allowed(const char *call_path)
425 GSList *call_list = existing_call_list;
427 /*if prior call list doesn't exisit, allow the call as it can be a new-call*/
428 if (!existing_call_list) {
429 DBG(" This must be a new call... Allow it!");
433 while (call_list != NULL) {
435 struct telephony_call *t_call = call_list->data;
437 if (g_strcmp0(t_call->call_path, call_path) == 0)
440 call_list = call_list->next;
443 ERR("call is not allowed");
447 static struct telephony_call *__bt_hfp_create_new_call(
448 const char *incoming_path,
449 uint32_t incoming_call_id,
450 const char *incoming_number,
453 struct telephony_call *t_call = NULL;
454 GSList *call_list = existing_call_list;
456 while (call_list != NULL) {
457 t_call = call_list->data;
459 if (t_call->call_id == incoming_call_id)
464 call_list = call_list->next;
467 DBG("Create a new call");
469 if (t_call == NULL) {
470 t_call = g_new0(struct telephony_call, 1);
471 t_call->call_id = incoming_call_id;
472 t_call->call_path = g_strdup(incoming_path);
473 t_call->call_sender = g_strdup(sender);
474 t_call->call_number = g_strdup(incoming_number);
476 existing_call_list = g_slist_append(existing_call_list,
482 gboolean _bt_hfp_is_call_exist(void)
484 DBG("_bt_hfp_is_call_exist [%x]", existing_call_list);
485 if (existing_call_list)
491 static struct telephony_call *__bt_hfp_get_call_with_status(int call_status)
493 DBG("Get Call with status %d", call_status);
495 GSList *temp_list = existing_call_list;
497 if (existing_call_list != NULL) {
498 while (temp_list != NULL) {
499 struct telephony_call *t_call = temp_list->data;
500 if (t_call->call_status == call_status)
502 temp_list = temp_list->next;
506 DBG("Existing call list is NULL. So return NULL");
510 static bt_hfp_agent_error_t __bt_hfp_modify_indicator(
511 const char *indicator_name,
514 bt_ag_indicators_t *hf_ind = NULL;
516 #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE
517 if (g_strcmp0(indicator_name,
518 HFP_AGENT_CALLSETUP_INDICATOR) == 0)
519 _bt_ag_agent_check_transport_state();
521 for (i = 0; hfp_ag_ind[i].indicator_desc != NULL; i++) {
522 if (g_str_equal(hfp_ag_ind[i].indicator_desc,
524 hf_ind = &hfp_ag_ind[i];
530 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
532 if (hf_ind->hfp_value == update_value && hf_ind->ignore)
533 return BT_HFP_AGENT_ERROR_NONE;
535 if (hf_ind->is_activated == FALSE)
536 return BT_HFP_AGENT_ERROR_NONE;
538 hf_ind->hfp_value = update_value;
540 DBG("updating hfp event indicator [%s] with value [%d]",
541 indicator_name, hf_ind->hfp_value);
543 return _bt_hfp_event_indicator(i);
546 static int __bt_hfp_get_indicator_value(
547 const bt_ag_indicators_t *ag_indicators,
551 for (x = 0; ag_indicators[x].indicator_desc != NULL; x++) {
552 if (g_str_equal(ag_indicators[x].indicator_desc, hf_desc))
553 return ag_indicators[x].hfp_value;
556 return ERR_NOT_FOUND;
559 static void __bt_hfp_handle_call_conference(void)
562 struct telephony_call *t_active_call = NULL;
563 int t_active_call_count = 0;
565 struct telephony_call *t_held_call = NULL;
566 int t_held_call_count = 0;
568 for (t_call_list = existing_call_list; t_call_list != NULL;
569 t_call_list = t_call_list->next) {
571 struct telephony_call *t_call = t_call_list->data;
573 if (t_call == NULL) {
574 ERR("t_call is NULL");
578 if (t_call->call_status == HFP_CALL_STATUS_ACTIVE) {
579 if (t_active_call == NULL)
580 t_active_call = t_call;
582 t_active_call_count++;
584 if (t_active_call_count >= 2) {
585 if (t_active_call->call_conference == FALSE)
586 t_active_call->call_conference = TRUE;
587 t_call->call_conference = TRUE;
590 } else if (t_call->call_status == HFP_CALL_STATUS_HOLD) {
591 if (t_held_call == NULL)
592 t_held_call = t_call;
596 if (t_held_call_count >= 2) {
597 if (t_held_call->call_conference == FALSE)
598 t_held_call->call_conference = TRUE;
599 t_call->call_conference = TRUE;
604 if (t_held_call != NULL && t_held_call_count == 1)
605 t_held_call->call_conference = FALSE;
607 if (t_active_call != NULL && t_active_call_count == 1)
608 t_active_call->call_conference = FALSE;
611 static gboolean __bt_hfp_on_call_hold_timeout(gpointer t_data)
615 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD)) {
616 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE))
617 status = INDICATOR_EVENT_CALLHELD_MULTIPLE;
619 status = INDICATOR_EVENT_CALLHELD_ON_HOLD;
621 status = INDICATOR_EVENT_CALLHELD_NONE;
624 __bt_hfp_modify_indicator("callheld", status);
626 call_on_hold_timer = 0;
630 static void __bt_hfp_handle_call_on_hold_request(void)
632 DBG(" Starting the timer for call on hold");
633 if (call_on_hold_timer)
634 g_source_remove(call_on_hold_timer);
636 call_on_hold_timer = g_timeout_add(250, __bt_hfp_on_call_hold_timeout,
638 DBG(" returning from the timer call");
641 static void __bt_hfp_set_call_status(struct telephony_call *t_call,
645 int org_status = t_call->call_status;
647 call_held = __bt_hfp_get_indicator_value(hfp_ag_ind, "callheld");
649 if (org_status == call_status) {
650 DBG("Ignore the CSD Call state change to existing state");
654 t_call->call_status = call_status;
656 DBG(" call status is %d", call_status);
658 switch (call_status) {
659 case HFP_CALL_STATUS_IDLE:
660 if (t_call->call_setup) {
661 __bt_hfp_modify_indicator("callsetup",
662 INDICATOR_EVENT_CALLSETUP_INACTIVE);
663 if (!t_call->call_originating)
664 _bt_calling_stopped_indicator();
667 g_free(t_call->call_number);
668 t_call->call_number = NULL;
669 t_call->call_originating = FALSE;
670 t_call->call_emergency = FALSE;
671 t_call->call_on_hold = FALSE;
672 t_call->call_conference = FALSE;
673 t_call->call_setup = FALSE;
676 case HFP_CALL_STATUS_COMING:
677 t_call->call_originating = FALSE;
678 t_call->call_setup = TRUE;
679 __bt_hfp_modify_indicator("callsetup",
680 INDICATOR_EVENT_CALLSETUP_INCOMING);
683 case HFP_CALL_STATUS_CREATE:
684 t_call->call_originating = TRUE;
685 t_call->call_setup = TRUE;
688 case HFP_CALL_STATUS_MO_ALERTING:
689 __bt_hfp_modify_indicator("callsetup",
690 INDICATOR_EVENT_CALLSETUP_ALERTING);
693 case HFP_CALL_STATUS_MT_ALERTING: {
694 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
696 if (t_call->call_number == NULL) {
697 t_number = AGENT_NUMBER_TYPE_TELEPHONY;
699 if (t_call->call_number[0] == '+' ||
700 strncmp(t_call->call_number, "00", 2) == 0)
701 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
704 if (org_status == HFP_CALL_STATUS_WAITING)
705 _bt_incoming_call_indicator(t_call->call_number,
710 case HFP_CALL_STATUS_ACTIVE:
711 DBG(" This is an Active call");
712 if (t_call->call_on_hold) {
713 t_call->call_on_hold = FALSE;
714 __bt_hfp_handle_call_on_hold_request();
716 if (!g_slist_find(agent_active_call_list, t_call)) {
717 DBG(" This call is not in the active call list. So Add it to the list.\n");
718 agent_active_call_list =
719 g_slist_prepend(agent_active_call_list,
722 if (g_slist_length(agent_active_call_list) == 1) {
723 DBG(" Update indicator to show the call presence.\n");
724 __bt_hfp_modify_indicator("call",
725 INDICATOR_EVENT_CALL_ACTIVE);
728 __bt_hfp_modify_indicator("callsetup",
729 INDICATOR_EVENT_CALLSETUP_INACTIVE);
730 __bt_hfp_handle_call_on_hold_request();
732 if (!t_call->call_originating)
733 _bt_calling_stopped_indicator();
735 t_call->call_setup = FALSE;
739 case HFP_CALL_STATUS_MO_RELEASE:
740 case HFP_CALL_STATUS_MT_RELEASE:
741 agent_active_call_list = g_slist_remove(agent_active_call_list,
743 if (g_slist_length(agent_active_call_list) == 0)
744 __bt_hfp_modify_indicator("call",
745 INDICATOR_EVENT_CALL_INACTIVE);
747 if (org_status == HFP_CALL_STATUS_HOLD)
748 __bt_hfp_modify_indicator("callheld", INDICATOR_EVENT_CALLHELD_NONE);
750 if ((org_status == HFP_CALL_STATUS_MO_ALERTING) ||
751 (org_status == HFP_CALL_STATUS_COMING) ||
752 (org_status == HFP_CALL_STATUS_CREATE) ||
753 (org_status == HFP_CALL_STATUS_WAITING)) {
754 __bt_hfp_modify_indicator("callsetup",
755 INDICATOR_EVENT_CALLSETUP_INACTIVE);
758 if (org_status == HFP_CALL_STATUS_COMING) {
759 if (!t_call->call_originating)
760 _bt_calling_stopped_indicator();
762 existing_call_list = g_slist_remove(existing_call_list, t_call);
763 __bt_hfp_free_call(t_call);
766 case HFP_CALL_STATUS_HOLD:
767 t_call->call_on_hold = TRUE;
768 __bt_hfp_handle_call_on_hold_request();
771 case HFP_CALL_STATUS_TERMINATED:
772 if (t_call->call_on_hold &&
773 !__bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD)) {
774 __bt_hfp_modify_indicator("callheld",
775 INDICATOR_EVENT_CALLHELD_NONE);
779 if (call_held == INDICATOR_EVENT_CALLHELD_MULTIPLE &&
780 __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD) &&
781 !__bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE))
782 __bt_hfp_modify_indicator("callheld",
783 INDICATOR_EVENT_CALLHELD_ON_HOLD);
786 case HFP_CALL_STATUS_PROCEEDING:
787 case HFP_CALL_STATUS_SWAP_INITIATED:
788 case HFP_CALL_STATUS_RETRIEVE_INITIATED:
789 case HFP_CALL_STATUS_RECONNECT_PENDING:
790 case HFP_CALL_STATUS_HOLD_INITIATED:
791 case HFP_CALL_STATUS_WAITING:
792 case HFP_CALL_STATUS_ANSWERED:
799 /* Update the call conference status for each of the call */
800 __bt_hfp_handle_call_conference();
803 bt_hfp_agent_error_t _bt_hfp_incoming_call(const char *call_path,
804 const char *incoming_number,
805 uint32_t incoming_call_id,
808 struct telephony_call *t_call = NULL;
809 bt_hfp_agent_error_t hfp_err = BT_HFP_AGENT_ERROR_NONE;
810 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
813 if (sender == NULL || call_path == NULL)
814 return BT_HFP_AGENT_ERROR_INVALID_PARAM;
816 if (!__bt_hfp_check_for_callpath(call_path, sender)) {
817 __bt_hfp_print_callpath(call_path, sender);
818 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
821 if (!__bt_hfp_is_call_allowed(call_path))
822 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
824 /* Its a new call, so create a list for it*/
825 t_call = __bt_hfp_create_new_call(call_path, incoming_call_id,
829 /*get the type of the incoming number*/
830 if (t_call->call_number == NULL) {
831 t_number = AGENT_NUMBER_TYPE_TELEPHONY;
832 ERR("call_number is NULL");
834 if (t_call->call_number[0] == '+' || strncmp(
835 t_call->call_number, "00", 2) == 0)
836 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
838 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE) ||
839 __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD)) {
840 error = _bt_call_waiting_indicator(t_call->call_number,
843 ERR(" Fail to update CCWA information");
846 hfp_err = __bt_hfp_modify_indicator(
847 HFP_AGENT_CALLSETUP_INDICATOR,
848 HFP_INCOMING_CALLSETUP);
849 if (hfp_err != BT_HFP_AGENT_ERROR_NONE)
850 ERR("Failed to update the indicators");
852 __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_WAITING);
854 DBG(" It is an incoming call");
857 hfp_err = __bt_hfp_modify_indicator(
858 HFP_AGENT_CALLSETUP_INDICATOR,
859 HFP_INCOMING_CALLSETUP);
860 if (hfp_err != BT_HFP_AGENT_ERROR_NONE)
861 ERR("Failed to update the indicators");
864 error = _bt_incoming_call_indicator(t_call->call_number,
867 __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_COMING);
869 if (error == -ENODEV)
870 return BT_HFP_AGENT_ERROR_NOT_CONNECTED;
871 else if (error == -EBUSY)
872 return BT_HFP_AGENT_ERROR_BUSY;
879 bt_hfp_agent_error_t _bt_hfp_outgoing_call(const char *call_path,
881 uint32_t call_id, const char *sender)
883 struct telephony_call *t_call = NULL;
884 bt_hfp_agent_error_t ret = BT_HFP_AGENT_ERROR_NONE;
885 gboolean err = FALSE;
887 err = __bt_hfp_check_for_callpath(call_path, sender);
889 __bt_hfp_print_callpath(call_path, sender);
890 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
892 /*check if the call_path exisits in the active call list, if not
893 don't allow as the call may be initated by some other application*/
895 err = __bt_hfp_is_call_allowed(call_path);
897 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
899 /* create a new call for the call_path */
900 t_call = __bt_hfp_create_new_call(call_path, call_id, number, sender);
902 __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_CREATE);
904 ret = __bt_hfp_modify_indicator(HFP_AGENT_CALLSETUP_INDICATOR,
905 HFP_OUTGOING_CALLSETUP);
906 if (ret != BT_HFP_AGENT_ERROR_NONE)
907 DBG("Error in updating indicator");
912 bt_hfp_agent_error_t _bt_hfp_change_call_status(const char *call_path,
913 const char *number, uint32_t call_status,
914 uint32_t call_id, const char *sender)
916 GSList *call_list = existing_call_list;
917 struct telephony_call *t_call = NULL;
918 gboolean ret = FALSE;
920 if (call_status > AG_MAX_LENGTH)
921 return BT_HFP_AGENT_ERROR_INVALID_PARAM;
923 ret = __bt_hfp_check_for_callpath(call_path, sender);
926 __bt_hfp_print_callpath(call_path, sender);
927 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
930 ret = __bt_hfp_is_call_allowed(call_path);
932 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
934 /* find call with the given call_id*/
935 DBG(" Find call with the given call Id from the list");
936 while (call_list != NULL) {
937 t_call = call_list->data;
939 if (t_call->call_id == call_id) {
940 DBG("Call Id Match");
946 call_list = call_list->next;
949 if (t_call == NULL) {
950 DBG("t_call is NULL. So create new call");
951 t_call = __bt_hfp_create_new_call(call_path,
952 call_id, number, sender);
955 __bt_hfp_set_call_status(t_call, call_status);
957 return BT_HFP_AGENT_ERROR_NONE;
960 static int __bt_hfp_update_battery_strength(int32_t battery_strength)
962 int bat_strength = 0;
965 DBG(" Battery strength is.... %d", battery_strength);
967 /* get the current battery level */
968 for (x = 0; hfp_ag_ind[x].indicator_desc != NULL; x++) {
969 if (g_str_equal(hfp_ag_ind[x].indicator_desc, "battchg"))
970 bat_strength = hfp_ag_ind[x].hfp_value;
973 /* We need to send battery status ranging from 0-5 */
974 if (battery_strength < 5)
976 else if (battery_strength >= 100)
979 change_value = battery_strength / 20 + 1;
981 if (bat_strength == change_value) {
982 DBG("no change in battery strength");
986 if (__bt_hfp_modify_indicator("battchg",
987 change_value) == BT_HFP_AGENT_ERROR_NONE)
993 static int __bt_hfp_update_signal_strength(int32_t signal_strength_bars)
995 if (signal_strength_bars < 0)
996 signal_strength_bars = 0;
997 else if (signal_strength_bars > 5)
998 signal_strength_bars = 5;
1000 if (network_info.signal_strength == signal_strength_bars) {
1001 DBG("no change in signal strength");
1005 network_info.signal_strength = signal_strength_bars;
1007 if (__bt_hfp_modify_indicator("signal",
1008 signal_strength_bars) == BT_HFP_AGENT_ERROR_NONE)
1014 static int __bt_hfp_update_registration_status(uint8_t register_status)
1016 bt_hfp_agent_error_t reg_ret = BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
1018 DBG("Updating registration status to.... %d", register_status);
1020 if (network_info.network_status == register_status) {
1021 DBG("No change in registration status");
1025 if (register_status == BT_AGENT_NETWORK_REG_STATUS_ROAMING) {
1026 reg_ret = __bt_hfp_modify_indicator("roam",
1027 INDICATOR_EVENT_ROAM_ACTIVE);
1029 if (network_info.network_status >
1030 BT_AGENT_NETWORK_REG_STATUS_ROAMING)
1031 reg_ret = __bt_hfp_modify_indicator("service",
1032 INDICATOR_EVENT_SERVICE_PRESENT);
1033 } else if (register_status == BT_AGENT_NETWORK_REG_STATUS_HOME) {
1034 reg_ret = __bt_hfp_modify_indicator("roam",
1035 INDICATOR_EVENT_ROAM_INACTIVE);
1037 if (network_info.network_status >
1038 BT_AGENT_NETWORK_REG_STATUS_ROAMING)
1039 reg_ret = __bt_hfp_modify_indicator("service",
1040 INDICATOR_EVENT_SERVICE_PRESENT);
1041 } else if (register_status == BT_AGENT_NETWORK_REG_STATUS_OFFLINE ||
1042 register_status == BT_AGENT_NETWORK_REG_STATUS_SEARCHING ||
1043 register_status == BT_AGENT_NETWORK_REG_STATUS_NO_SIM ||
1044 register_status == BT_AGENT_NETWORK_REG_STATUS_POWEROFF ||
1045 register_status == BT_AGENT_NETWORK_REG_STATUS_POWERSAFE ||
1046 register_status == BT_AGENT_NETWORK_REG_STATUS_NO_COVERAGE ||
1047 register_status == BT_AGENT_NETWORK_REG_STATUS_REJECTED ||
1048 register_status == BT_AGENT_NETWORK_REG_STATUS_UNKOWN) {
1049 if (network_info.network_status <
1050 BT_AGENT_NETWORK_REG_STATUS_OFFLINE)
1051 reg_ret = __bt_hfp_modify_indicator("service",
1052 INDICATOR_EVENT_SERVICE_NONE);
1055 network_info.network_status = register_status;
1056 if (reg_ret == BT_HFP_AGENT_ERROR_NONE)
1062 int _bt_hfp_set_property_value(const char *property, int value)
1066 DBG("Property is %s", property);
1068 if (g_str_equal("RegistrationChanged", property))
1069 ret = __bt_hfp_update_registration_status(value);
1071 else if (g_str_equal("SignalBarsChanged", property))
1072 ret = __bt_hfp_update_signal_strength(value);
1074 else if (g_str_equal("BatteryBarsChanged", property))
1075 ret = __bt_hfp_update_battery_strength(value);
1080 int _bt_hfp_set_property_name(const char *property, const char *operator_name)
1084 if (operator_name == NULL)
1087 if (g_str_equal("OperatorNameChanged", property)) {
1088 g_free(network_info.network_operator_name);
1089 network_info.network_operator_name =
1090 g_strndup(operator_name, 16);
1094 if (g_str_equal("SubscriberNumberChanged", property)) {
1095 g_free(ag_subscriber_num);
1096 ag_subscriber_num = g_strdup(operator_name);
1097 DBG_SECURE("HFP: subscriber_number updated: %s", ag_subscriber_num);
1103 static int __bt_hfp_answer_call(struct telephony_call *t_call)
1105 if (t_call->call_id != 0 && t_call->call_path != NULL &&
1106 t_call->call_sender != NULL) {
1107 _bt_ag_agent_answer_call(t_call->call_id,
1109 t_call->call_sender);
1115 void _bt_hfp_answer_call_request(void *t_device)
1117 struct telephony_call *t_call;
1119 t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_COMING);
1122 t_call = __bt_hfp_get_call_with_status(
1123 HFP_CALL_STATUS_MT_ALERTING);
1126 t_call = __bt_hfp_get_call_with_status(
1127 HFP_CALL_STATUS_PROCEEDING);
1130 t_call = __bt_hfp_get_call_with_status(
1131 HFP_CALL_STATUS_WAITING);
1133 if (t_call == NULL) {
1134 _bt_answer_call_response(t_device,
1135 HFP_STATE_MNGR_ERR_NOT_ALLOWED);
1139 if (__bt_hfp_answer_call(t_call) < 0)
1140 _bt_answer_call_response(t_device,
1141 HFP_STATE_MNGR_ERR_AG_FAILURE);
1143 _bt_answer_call_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1147 void _bt_hfp_dial_number_request(const char *dial_number, void *t_device)
1149 int call_flag = caller_id;
1150 bt_hfp_agent_error_t error_code = 0;
1152 if (strncmp(dial_number, "#31#", 4) == 0) {
1153 dial_number = dial_number + 4;
1154 call_flag = ALLOW_CALL_FLAG;
1155 } else if (strncmp(dial_number, "*31#", 4) == 0) {
1156 dial_number = dial_number + 4;
1157 call_flag = RESTRAIN_CALL_FLAG;
1158 } else if (dial_number[0] == '>') {
1159 int dial_location = strtol(&dial_number[1], NULL, 0);
1161 error_code = _bt_ag_agent_dial_memory(dial_location);
1163 if (error_code == BT_HFP_AGENT_ERROR_NONE)
1164 _bt_dial_number_response(t_device,
1165 HFP_STATE_MNGR_ERR_NONE);
1167 _bt_dial_number_response(t_device,
1168 HFP_STATE_MNGR_ERR_AG_FAILURE);
1172 error_code = _bt_ag_agent_dial_num(dial_number, call_flag);
1174 if (error_code == BT_HFP_AGENT_ERROR_NONE) {
1175 _bt_dial_number_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1179 _bt_dial_number_response(t_device, HFP_STATE_MNGR_ERR_AG_FAILURE);
1183 void _bt_hfp_update_event_request(int indicator, void *t_device)
1186 update_events = TRUE;
1188 update_events = FALSE;
1190 _bt_event_reporting_response(t_device,
1191 HFP_STATE_MNGR_ERR_NONE);
1194 static int __bt_bt_hfp_reject_call(struct telephony_call *t_call)
1198 if (t_call != NULL) {
1199 DBG(" rejecting call from sender %s with call path %s and call id %d",
1200 t_call->call_sender,
1204 ret = _bt_ag_agent_reject_call(t_call->call_id,
1206 t_call->call_sender);
1214 static int __bt_hfp_release_call(struct telephony_call *t_call)
1216 gboolean ret = _bt_ag_agent_release_call(t_call->call_id,
1218 t_call->call_sender);
1225 static int __bt_hfp_release_conference(void)
1227 GSList *temp_list = existing_call_list;
1230 while (temp_list != NULL) {
1231 struct telephony_call *t_call = temp_list->data;
1233 if (t_call->call_conference) {
1234 ret = __bt_hfp_release_call(t_call);
1236 ERR("Seems like there are no active calls.");
1239 temp_list = temp_list->next;
1244 void _bt_hfp_terminate_call_request(void *t_device)
1246 struct telephony_call *t_call;
1247 struct telephony_call *t_alert = NULL;
1250 t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE);
1252 if (t_call == NULL) {
1253 DBG("Find non-idle call");
1254 GSList *temp_call_list = existing_call_list;
1255 while (temp_call_list != NULL) {
1256 t_call = temp_call_list->data;
1258 if (t_call->call_status == HFP_AGENT_CALL_IDLE)
1259 temp_call_list = temp_call_list->next;
1265 if (t_call == NULL) {
1266 DBG("Seems like there are no active calls. So do not allow the call");
1267 _bt_terminate_call_response(t_device,
1268 HFP_STATE_MNGR_ERR_NOT_ALLOWED);
1272 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_WAITING) != NULL) {
1274 t_error = _bt_ag_agent_threeway_call(value, t_call->call_path,
1275 t_call->call_sender);
1276 } else if ((t_alert = __bt_hfp_get_call_with_status(
1277 HFP_CALL_STATUS_CREATE))
1279 t_error = __bt_hfp_release_call(t_alert);
1280 } else if ((t_alert = __bt_hfp_get_call_with_status(
1281 HFP_CALL_STATUS_MO_ALERTING))
1283 t_error = __bt_hfp_release_call(t_alert);
1284 } else if ((t_alert = __bt_hfp_get_call_with_status(
1285 HFP_CALL_STATUS_COMING)) != NULL) {
1286 t_error = __bt_bt_hfp_reject_call(t_alert);
1287 } else if (t_call->call_conference)
1288 t_error = __bt_hfp_release_conference();
1290 t_error = __bt_hfp_release_call(t_call);
1293 _bt_terminate_call_response(t_device,
1294 HFP_STATE_MNGR_ERR_AG_FAILURE);
1296 _bt_terminate_call_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1299 void _bt_hfp_call_hold_request(const char *t_cmd, void *t_device)
1302 struct telephony_call *t_call = NULL;
1303 GSList *t_sender_list = call_senders_paths;
1304 sender_info_t *sender_info = NULL;
1305 uint32_t t_chld_value;
1307 t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE);
1308 if (t_call == NULL) {
1310 __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD))
1312 if ((t_call = __bt_hfp_get_call_with_status(
1313 HFP_CALL_STATUS_WAITING)) == NULL) {
1314 /* means there is no outgoing call*/
1315 _bt_call_hold_response(t_device,
1316 HFP_STATE_MNGR_ERR_AG_FAILURE);
1322 while (t_sender_list != NULL) {
1323 sender_info = t_sender_list->data;
1324 if (sender_info == NULL) {
1325 _bt_call_hold_response(t_device,
1326 HFP_STATE_MNGR_ERR_AG_FAILURE);
1329 if (g_strcmp0(t_call->call_path, sender_info->sender_path)
1333 t_sender_list = t_sender_list->next;
1336 t_chld_value = strtoul(&t_cmd[0], NULL, 0);
1337 gboolean ret = _bt_ag_agent_threeway_call(t_chld_value,
1339 t_call->call_sender);
1342 _bt_call_hold_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1344 _bt_call_hold_response(t_device, HFP_STATE_MNGR_ERR_AG_FAILURE);
1347 void _bt_hfp_key_press_request(const char *t_key_press, void *t_device)
1349 struct telephony_call *t_active_call;
1350 struct telephony_call *t_waiting_call;
1353 t_waiting_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_COMING);
1355 if (t_waiting_call == NULL)
1356 t_waiting_call = __bt_hfp_get_call_with_status(
1357 HFP_CALL_STATUS_MT_ALERTING);
1359 if (t_waiting_call == NULL)
1360 t_waiting_call = __bt_hfp_get_call_with_status(
1361 HFP_CALL_STATUS_PROCEEDING);
1363 t_active_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE);
1366 if (t_waiting_call != NULL)
1367 t_error = __bt_hfp_answer_call(t_waiting_call);
1368 else if (t_active_call != NULL)
1369 t_error = __bt_hfp_release_call(t_active_call);
1371 if (_bt_ag_agent_dial_last_num(t_device) !=
1372 BT_HFP_AGENT_ERROR_NONE)
1373 _bt_dial_number_response(t_device,
1374 HFP_STATE_MNGR_ERR_AG_FAILURE);
1376 _bt_dial_number_response(t_device,
1377 HFP_STATE_MNGR_ERR_NONE);
1382 _bt_key_press_response(t_device,
1383 HFP_STATE_MNGR_ERR_AG_FAILURE);
1385 _bt_key_press_response(t_device,
1386 HFP_STATE_MNGR_ERR_NONE);
1389 void _bt_hfp_last_dialed_number_request(void *t_device)
1391 bt_hfp_agent_error_t error = _bt_ag_agent_dial_last_num(t_device);
1393 if (error != BT_HFP_AGENT_ERROR_NONE)
1394 _bt_dial_number_response(t_device,
1395 HFP_STATE_MNGR_ERR_AG_FAILURE);
1397 _bt_dial_number_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1400 void _bt_hfp_channel_dtmf_request(char t_tone, void *t_device)
1402 char buf[2] = { t_tone, '\0' };
1403 char *tone_buffer = buf;
1405 struct telephony_call *t_call = __bt_hfp_get_call_with_status(
1406 HFP_CALL_STATUS_ACTIVE);
1407 if (t_call == NULL) {
1408 t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD);
1409 if (t_call == NULL) {
1410 t_call = __bt_hfp_get_call_with_status(
1411 HFP_CALL_STATUS_WAITING);
1412 if (t_call == NULL) {
1413 /* if this point is reached,
1414 it means there is no ongoing call */
1415 _bt_transmit_dtmf_response(t_device,
1416 HFP_STATE_MNGR_ERR_AG_FAILURE);
1422 if (_bt_ag_agent_send_dtmf(tone_buffer, t_call->call_path,
1423 t_call->call_sender) != BT_HFP_AGENT_ERROR_NONE) {
1424 _bt_transmit_dtmf_response(t_device,
1425 HFP_STATE_MNGR_ERR_AG_FAILURE);
1429 _bt_transmit_dtmf_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1432 void _bt_hfp_vendor_cmd_request(const char *cmd,
1435 GSList *t_sender_list = call_senders_paths;
1436 sender_info_t *sender_info = NULL;
1438 bt_hfp_agent_error_t error = BT_HFP_AGENT_ERROR_NONE;
1440 if (NULL != t_sender_list) {
1441 for (l = t_sender_list; l != NULL; l = l->next) {
1442 sender_info = l->data;
1443 error = _bt_ag_agent_vendor_cmd(cmd,
1444 sender_info->sender_path,
1445 sender_info->sender_name);
1446 if (error != BT_HFP_AGENT_ERROR_NONE)
1451 if (error != BT_HFP_AGENT_ERROR_NONE)
1452 _bt_vendor_cmd_response(t_device,
1453 HFP_STATE_MNGR_ERR_AG_FAILURE);
1455 _bt_vendor_cmd_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1458 void _bt_hfp_subscriber_number_request(void *t_device)
1460 if (ag_subscriber_num != NULL) {
1462 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
1464 if (ag_subscriber_num[0] == '+' || strncmp(
1465 ag_subscriber_num, "00", 2) == 0)
1466 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
1468 _bt_subscriber_number_indicator(ag_subscriber_num,
1469 t_number, AGENT_SUBSCRIBER_SERVICE_VOICE);
1472 _bt_subscriber_number_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1475 static int __bt_hfp_get_call_status(struct telephony_call *t_call)
1477 switch (t_call->call_status) {
1478 case HFP_CALL_STATUS_IDLE:
1479 case HFP_CALL_STATUS_MO_RELEASE:
1480 case HFP_CALL_STATUS_MT_RELEASE:
1481 case HFP_CALL_STATUS_TERMINATED:
1484 case HFP_CALL_STATUS_ANSWERED:
1485 case HFP_CALL_STATUS_ACTIVE:
1486 case HFP_CALL_STATUS_RECONNECT_PENDING:
1487 case HFP_CALL_STATUS_SWAP_INITIATED:
1488 case HFP_CALL_STATUS_HOLD_INITIATED:
1489 return AGENT_CALL_STATUS_ACTIVE;
1491 case HFP_CALL_STATUS_RETRIEVE_INITIATED:
1492 case HFP_CALL_STATUS_HOLD:
1493 return AGENT_CALL_STATUS_HELD;
1495 case HFP_CALL_STATUS_WAITING:
1496 return AGENT_CALL_STATUS_WAITING;
1498 case HFP_CALL_STATUS_CREATE:
1499 return AGENT_CALL_STATUS_DIALING;
1501 case HFP_CALL_STATUS_PROCEEDING:
1502 if (t_call->call_originating)
1503 return AGENT_CALL_STATUS_DIALING;
1504 if (g_slist_length(agent_active_call_list) > 0)
1505 return AGENT_CALL_STATUS_WAITING;
1507 return AGENT_CALL_STATUS_INCOMING;
1509 case HFP_CALL_STATUS_COMING:
1510 if (g_slist_length(agent_active_call_list) > 0)
1511 return AGENT_CALL_STATUS_WAITING;
1513 return AGENT_CALL_STATUS_INCOMING;
1515 case HFP_CALL_STATUS_MO_ALERTING:
1516 return AGENT_CALL_STATUS_ALERTING;
1518 case HFP_CALL_STATUS_MT_ALERTING:
1519 return AGENT_CALL_STATUS_INCOMING;
1526 void _bt_list_current_calls(void *t_device)
1528 GSList *t_call_list = existing_call_list;
1530 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
1531 int t_direction, t_call_conference;
1534 while (t_call_list != NULL) {
1535 struct telephony_call *t_call = t_call_list->data;
1536 t_status = __bt_hfp_get_call_status(t_call);
1537 if (t_status >= 0) {
1538 if (t_call->call_originating != TRUE)
1539 t_direction = AGENT_CALL_DIRECTION_INCOMING;
1541 t_direction = AGENT_CALL_DIRECTION_OUTGOING;
1543 if (t_call->call_conference != TRUE)
1544 t_call_conference = AGENT_CALL_MULTIPARTY_NO;
1546 t_call_conference = AGENT_CALL_MULTIPARTY_YES;
1548 if (t_call->call_number == NULL) {
1549 t_number = AGENT_NUMBER_TYPE_TELEPHONY;
1551 if (t_call->call_number[0] == '+' || strncmp(
1552 t_call->call_number, "00", 2) == 0)
1553 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
1556 index = t_call->call_id;
1557 _bt_list_current_call_indicator(t_device, index, t_direction,
1558 AGENT_CALL_MODE_VOICE,
1560 t_call->call_number,
1564 t_call_list = t_call_list->next;
1566 _bt_list_current_calls_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1569 void _bt_hfp_release_all_calls_by_sender(const char *sender)
1571 GSList *temp_list = existing_call_list;
1577 while (temp_list != NULL) {
1578 struct telephony_call *t_call = temp_list->data;
1580 if (g_strcmp0(t_call->call_sender, sender) == 0) {
1581 INFO("terminate call[%d]", t_call->call_id);
1582 next_list = temp_list->next;
1583 __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_MT_RELEASE);
1584 temp_list = next_list;
1586 temp_list = temp_list->next;
1590 void _bt_hfp_noise_red_and_echo_cancel_request(gboolean t_enable,
1593 if (_bt_hfp_agent_nrec_status(t_enable, t_device) == TRUE)
1594 _bt_nr_and_ec_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1596 _bt_nr_and_ec_response(t_device, HFP_STATE_MNGR_ERR_AG_FAILURE);
1601 void _bt_hfp_voice_dial_request(gboolean t_enable, void *t_device)
1603 gboolean ret = FALSE;
1606 if (vconf_get_int(VCONFKEY_CALL_STATE, &call_state) < 0)
1607 ERR("vconf_get_int is failed");
1609 if ((t_enable == TRUE && call_state == 0) || t_enable == FALSE)
1610 ret = _bt_ag_agent_voice_dial(t_enable);
1613 _bt_voice_dial_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1615 _bt_voice_dial_response(t_device,
1616 HFP_STATE_MNGR_ERR_AG_FAILURE);
1621 void _bt_hfp_set_indicators(const char *t_command, void *t_device)
1623 const char delims = ',';
1626 if (t_command == NULL)
1629 str = strchr(t_command, '=');
1630 while (hfp_ag_ind[i].indicator_desc != NULL && str != NULL) {
1633 if ((g_strcmp0(hfp_ag_ind[i].indicator_desc, "call") != 0) &&
1634 (g_strcmp0(hfp_ag_ind[i].indicator_desc, "callheld") != 0) &&
1635 (g_strcmp0(hfp_ag_ind[i].indicator_desc, "callsetup") != 0)) {
1638 hfp_ag_ind[i].is_activated = FALSE;
1639 } else if (*str == '1') {
1640 hfp_ag_ind[i].is_activated = TRUE;
1642 DBG(" no change in is_activated for[%s]\n",
1643 hfp_ag_ind[i].indicator_desc);
1646 str = strchr(str, delims);
1650 _bt_indicators_activation_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1654 _bt_indicators_activation_response(t_device,
1655 HFP_STATE_MNGR_ERR_INVALID_CHAR_IN_STRING);
1659 static int __bt_hfp_get_phonebook_count(const char *path, uint32_t *max_size,
1663 PhoneBookType pb_type = TELECOM_NONE;
1667 INFO("name: %s\n", path);
1668 if (contacts_connect() != CONTACTS_ERROR_NONE) {
1669 ERR("Can not connect contacts server\n");
1673 pb_type = __bluetooth_pb_get_storage_pb_type(path);
1675 if (__bluetooth_pb_get_count(pb_type, &count) == FALSE) {
1676 ERR("unable to get count");
1677 if (contacts_disconnect() != CONTACTS_ERROR_NONE)
1678 ERR("contacts_disconnect failed");
1682 DBG("Size returned %d", count);
1683 if ((g_strcmp0(path, "\"SM\"") == 0) ||
1684 (g_strcmp0(path, "\"ME\"") == 0)) {
1685 max = AGENT_MAX_PB_COUNT;
1686 } else if ((g_strcmp0(path, "\"DC\"") == 0) ||
1687 (g_strcmp0(path, "\"MC\"") == 0) ||
1688 (g_strcmp0(path, "\"RC\"") == 0)) {
1689 max = AGENT_MAX_CALLLOG_COUNT;
1700 if (contacts_disconnect() != CONTACTS_ERROR_NONE)
1701 ERR("contacts_disconnect failed");
1706 void _bt_hfp_select_phonebook_memory_status(void *t_device)
1708 int32_t path_id = ag_pb_info.path_id;
1710 uint32_t max_size = 0;
1712 hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1714 if (path_id < 0 || path_id >= AGENT_PB_STORE_LIST_SIZE)
1717 if (__bt_hfp_get_phonebook_count(agent_pb_store_list[path_id],
1719 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1721 _bt_select_phonebook_memory_status_response(t_device,
1722 agent_pb_store_list[path_id],
1727 static char *__bt_hfp_get_supported_list(const char *char_list[],
1734 if (char_list == NULL || size == 0)
1737 strng = g_string_new("(");
1739 while (index < size) {
1741 g_string_append(strng, ",");
1743 g_string_append(strng, char_list[index]);
1747 g_string_append(strng, ")");
1749 return g_string_free(strng, FALSE);
1752 void _bt_hfp_select_phonebook_memory_list(void *t_device)
1756 str = __bt_hfp_get_supported_list(agent_pb_store_list,
1757 AGENT_PB_STORE_LIST_SIZE);
1759 _bt_select_phonebook_memory_list_response(t_device,
1760 str, HFP_STATE_MNGR_ERR_NONE);
1765 void _bt_hfp_select_phonebook_memory(void *t_device, const gchar *pb_path)
1768 hfp_state_manager_err_t err;
1770 while (i < AGENT_PB_STORE_LIST_SIZE) {
1771 if (strcmp(agent_pb_store_list[i], pb_path) == 0)
1776 if (i >= 0 && i < AGENT_PB_STORE_LIST_SIZE) {
1777 err = HFP_STATE_MNGR_ERR_NONE;
1778 ag_pb_info.path_id = i;
1780 err = HFP_STATE_MNGR_ERR_INVALID_CHAR_IN_STRING;
1782 _bt_select_phonebook_memory_response(t_device, err);
1785 void _bt_hfp_read_phonebook_entries_list(void *t_device)
1787 hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1789 int32_t path_id = ag_pb_info.path_id;
1792 if (path_id < 0 || path_id >= AGENT_PB_STORE_LIST_SIZE)
1793 err = HFP_STATE_MNGR_ERR_INVALID_INDEX;
1795 if (__bt_hfp_get_phonebook_count(agent_pb_store_list[path_id],
1796 NULL, &used) != 0) {
1797 err = HFP_STATE_MNGR_ERR_NOT_ALLOWED;
1801 _bt_read_phonebook_entries_list_response(t_device, used,
1802 AGENT_PB_NUMBER_MAX_LENGTH, AGENT_PB_NAME_MAX_LENGTH,
1806 static int __bt_hfp_get_phonebook_entries(int start_index, int end_index)
1810 PhoneBookType pb_type = TELECOM_NONE;
1812 DBG("command: %s, start_index: %d, end_index: %d\n",
1813 agent_pb_store_list[ag_pb_info.path_id], start_index, end_index);
1815 if (contacts_connect() != CONTACTS_ERROR_NONE) {
1816 ERR("Can not connect contacts server");
1820 pb_type = __bluetooth_pb_get_storage_pb_type(
1821 agent_pb_store_list[ag_pb_info.path_id]);
1823 if (pb_type == TELECOM_NONE || pb_type == TELECOM_CCH) {
1824 if (contacts_disconnect() != CONTACTS_ERROR_NONE)
1825 ERR("contacts_disconnect failed");
1829 __bluetooth_pb_get_list_number(pb_type,
1830 start_index, end_index, &count);
1832 if (contacts_disconnect() != CONTACTS_ERROR_NONE)
1833 ERR("contacts_disconnect failed");
1838 void _bt_hfp_read_phonebook_entries(void *t_device, const char *cmd)
1840 int start_index = 0;
1848 hfp_state_manager_err_t err;
1853 str = g_strdup(cmd);
1854 next = strchr(str, ',');
1860 end_index = strtol(next, NULL, 10);
1863 start_index = strtol(str, NULL, 10);
1867 count = __bt_hfp_get_phonebook_entries(start_index, end_index);
1870 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1871 else if (count == 0)
1872 err = HFP_STATE_MNGR_ERR_INVALID_INDEX;
1874 err = HFP_STATE_MNGR_ERR_NONE;
1876 _bt_read_phonebook_entries_response(t_device, err);
1879 void _bt_hfp_find_phonebook_entries_status(void *t_device)
1881 _bt_find_phonebook_entries_status_indicator(
1882 AGENT_PB_NUMBER_MAX_LENGTH,
1883 AGENT_PB_NAME_MAX_LENGTH);
1885 _bt_find_phonebook_entries_status_response(t_device,
1886 HFP_STATE_MNGR_ERR_NONE);
1889 static int __bt_hfp_get_phonebook_entries_by_name(int start_index,
1895 PhoneBookType pb_type = TELECOM_NONE;
1897 DBG("command: %s, start_index: %d, end_index: %d\n",
1898 agent_pb_store_list[ag_pb_info.path_id], start_index, end_index);
1900 if (contacts_connect() != CONTACTS_ERROR_NONE) {
1901 ERR("Can not connect contacts server");
1905 pb_type = __bluetooth_pb_get_storage_pb_type(
1906 agent_pb_store_list[ag_pb_info.path_id]);
1908 if (pb_type == TELECOM_NONE || pb_type == TELECOM_CCH) {
1909 if (contacts_disconnect() != CONTACTS_ERROR_NONE)
1910 ERR("contacts_disconnect failed");
1914 __bluetooth_pb_get_list_entries_by_name(pb_type,
1915 start_index, end_index, str, &count);
1917 if (contacts_disconnect() != CONTACTS_ERROR_NONE)
1918 ERR("contacts_disconnect failed");
1923 static int __bt_hfp_find_pb_entries(const char *str)
1925 char *search = g_ascii_strup(str, strlen(str));
1927 /* No limit on number of searched item and need to search complete list*/
1928 __bt_hfp_get_phonebook_entries_by_name(0, 0, search);
1933 void _bt_hfp_find_phonebook_entries(void *t_device, const char *cmd)
1936 gchar *unquoted = NULL;
1938 hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1940 /* remove quote and compress */
1941 st = strchr(cmd, '"');
1943 unquoted = g_strdup(cmd);
1947 end = strrchr(cmd, '"');
1949 unquoted = g_strdup(cmd);
1951 unquoted = g_strndup(st + 1, end - st - 1);
1954 if (__bt_hfp_find_pb_entries(unquoted))
1955 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1957 _bt_find_phonebook_entries_response(t_device, err);
1962 void _bt_hfp_get_character_set(void *t_device)
1964 _bt_supported_character_generic_response(t_device,
1965 (char *)agent_supported_character_set[ag_pb_info.charset_id],
1966 HFP_STATE_MNGR_ERR_NONE);
1969 void _bt_hfp_list_supported_character(void *t_device)
1973 str = __bt_hfp_get_supported_list(agent_supported_character_set,
1974 AGENT_SUPPORTED_CHARACTER_SET_SIZE);
1976 _bt_supported_character_generic_response(t_device,
1977 str, HFP_STATE_MNGR_ERR_NONE);
1982 void _bt_hfp_set_character_set(void *t_device, const char *cmd)
1986 while (index < AGENT_SUPPORTED_CHARACTER_SET_SIZE) {
1987 if (strcmp(agent_supported_character_set[index], cmd) == 0) {
1988 _bt_set_characterset_generic_response(t_device,
1989 HFP_STATE_MNGR_ERR_NONE);
1991 ag_pb_info.charset_id = index;
1997 _bt_set_characterset_generic_response(t_device,
1998 HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
2002 void _bt_hfp_signal_quality_reply(int32_t rssi, int32_t ber,
2005 DBG("signal_quality_reply");
2007 if (rssi == -1 && ber == -1) {
2008 _bt_signal_quality_response(t_device, rssi, ber,
2009 HFP_STATE_MNGR_ERR_AG_FAILURE);
2011 _bt_signal_quality_response(t_device, rssi, ber,
2012 HFP_STATE_MNGR_ERR_NONE);
2016 void _bt_hfp_battery_property_reply(void *data, int32_t bcs,
2019 if (bcs == -1 || bcl == -1) {
2020 _bt_battery_charge_status_response(data, bcs,
2021 bcl, HFP_STATE_MNGR_ERR_AG_FAILURE);
2023 _bt_battery_charge_status_response(data, bcs,
2024 bcl, HFP_STATE_MNGR_ERR_NONE);
2030 void _bt_hfp_get_battery_property(void *t_device)
2032 _bt_ag_agent_get_battery_status(t_device);
2035 void _bt_hfp_operator_reply(char *operator_name, void *t_device)
2037 if (operator_name == NULL)
2040 network_info.network_operator_name = g_strndup(operator_name, 16);
2042 _bt_operator_selection_indicator(AGENT_OPERATOR_MODE_AUTO,
2044 _bt_operator_selection_response(t_device, HFP_STATE_MNGR_ERR_NONE);
2048 _bt_operator_selection_indicator(AGENT_OPERATOR_MODE_AUTO, "UNKNOWN");
2049 _bt_operator_selection_response(t_device,
2050 HFP_STATE_MNGR_ERR_AG_FAILURE);
2053 void _bt_hfp_get_operator_selection_request(void *t_device)
2055 _bt_ag_agent_get_operator_name(t_device);
2058 void _bt_hfp_response_and_hold_request(void *t_device)
2060 _bt_response_and_hold_response(t_device,
2061 HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
2064 void _bt_get_activity_status(void *t_device)
2066 DBG("telephony-tizen: telephony_get_activity_status");
2068 if (NULL != (__bt_hfp_get_call_with_status(
2069 HFP_CALL_STATUS_MT_ALERTING)) ||
2070 NULL != (__bt_hfp_get_call_with_status(
2071 HFP_CALL_STATUS_MO_ALERTING)) ||
2072 NULL != (__bt_hfp_get_call_with_status(
2073 HFP_CALL_STATUS_COMING)) ||
2074 NULL != (__bt_hfp_get_call_with_status(
2075 HFP_CALL_STATUS_CREATE)))
2076 _bt_hfp_get_activity_status_rsp(t_device,
2077 HFP_AGENT_ACTIVITY_STATUS_RINGING,
2078 HFP_STATE_MNGR_ERR_NONE);
2079 else if (NULL != (__bt_hfp_get_call_with_status(
2080 HFP_CALL_STATUS_WAITING)) ||
2081 NULL != (__bt_hfp_get_call_with_status(
2082 HFP_CALL_STATUS_ACTIVE)))
2083 _bt_hfp_get_activity_status_rsp(t_device,
2084 HFP_AGENT_ACTIVITY_STATUS_CALL_IN_PROGRESS,
2085 HFP_STATE_MNGR_ERR_NONE);
2087 _bt_hfp_get_activity_status_rsp(t_device,
2088 HFP_AGENT_ACTIVITY_STATUS_READY,
2089 HFP_STATE_MNGR_ERR_NONE);
2092 void _bt_hfp_get_imei_number_reply(char *imei_number, void *t_device)
2094 _bt_hfp_get_equipment_identity_rsp(t_device, imei_number,
2095 HFP_STATE_MNGR_ERR_NONE);
2098 void _bt_hfp_get_imsi_reply(char *mcc, char *mnc, char *msin, void *t_device)
2100 if (mcc != NULL && mnc != NULL && msin != NULL)
2101 _bt_hfp_get_imsi_rsp(t_device, mcc, mnc, msin,
2102 HFP_STATE_MNGR_ERR_NONE);
2104 _bt_hfp_get_imsi_rsp(t_device, NULL, NULL, NULL,
2105 HFP_STATE_MNGR_ERR_NOT_ALLOWED);
2108 void _bt_hfp_get_creg_status_reply(int n, int status, void *t_device)
2110 _bt_hfp_get_creg_status_rsp(t_device, n, status,
2111 HFP_STATE_MNGR_ERR_NONE);
2114 void _bt_hfp_get_equipment_identity_req(void *t_device)
2116 _bt_ag_agent_get_imei_number(t_device);
2119 void _bt_hfp_get_model_info_reply(char *model, void *t_device)
2121 _bt_hfp_get_model_info_rsp(t_device, model,
2122 HFP_STATE_MNGR_ERR_NONE);
2125 void _bt_hfp_get_model_info_req(void *t_device)
2127 _bt_ag_agent_get_model_name(t_device);
2130 void _bt_hfp_get_device_manufacturer_reply(char *manufacturer, void *t_device)
2132 _bt_hfp_get_device_manufacturer_rsp(t_device, manufacturer,
2133 HFP_STATE_MNGR_ERR_NONE);
2136 void _bt_hfp_get_device_manufacturer_req(void *t_device)
2138 _bt_ag_agent_get_manufacturer_name(t_device);
2141 void _bt_hfp_get_imsi_req(void *t_device)
2143 _bt_ag_agent_get_imsi(t_device);
2146 void _bt_hfp_get_creg_status_req(void *t_device)
2148 _bt_ag_agent_get_creg_status(t_device);
2151 void _bt_hfp_get_revision_info_reply(char *revision, void *t_device)
2153 _bt_hfp_get_revision_info_rsp(t_device, revision,
2154 HFP_STATE_MNGR_ERR_NONE);
2157 void _bt_hfp_get_revision_info_req(void *t_device)
2159 _bt_ag_agent_get_revision_information(t_device);