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 static gboolean __bt_hfp_check_for_callpath(const char *call_path,
158 const char *call_sender)
160 GSList *sender_list = call_senders_paths;
161 sender_info_t *sender;
163 DBG("call path is = %s\n", call_path);
164 DBG("sender is = %s\n", call_sender);
166 if (call_path == NULL || call_sender == NULL) {
168 ERR("Invalid Parameters");
172 /*check if the call is already registered*/
173 DBG("Checking if the call is already registered");
174 while (sender_list != NULL) {
175 sender = sender_list->data;
180 if (g_strcmp0(sender->sender_path, call_path) == 0) {
181 DBG("sender path and call path match... so return true");
185 sender_list = sender_list->next;
188 ERR("Call path is not already registered");
192 static void __bt_hfp_clear_sender_path(sender_info_t *s_path)
197 g_free(s_path->sender_name);
198 g_free(s_path->sender_path);
201 if (g_slist_length(call_senders_paths) == 0) {
202 g_slist_free(call_senders_paths);
203 call_senders_paths = NULL;
207 static void __bt_hfp_free_call(struct telephony_call *t_call)
212 g_free(t_call->call_number);
213 g_free(t_call->call_path);
214 g_free(t_call->call_sender);
218 static void __bt_hfp_reset_indicators(void)
222 for (i = 0; hfp_ag_ind[i].indicator_desc != NULL; i++)
223 hfp_ag_ind[i].is_activated = TRUE;
226 void _bt_hfp_device_disconnected(void *t_device)
228 DBG("hfp_agent: device %p disconnected", t_device);
229 update_events = FALSE;
230 __bt_hfp_reset_indicators();
233 void _bt_hfp_initialize_telephony_manager(uint32_t ag_features)
239 /* Reset the indicator values */
240 for (index = 0; hfp_ag_ind[index].indicator_desc != NULL; index++) {
241 if (g_str_equal(hfp_ag_ind[index].indicator_desc, "battchg")) {
242 ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
245 ERR("Get battery status failed : %d\n", ret);
247 /* Send battery status ranging from 0-5 */
249 hfp_ag_ind[index].hfp_value = 0;
250 else if (value >= 100)
251 hfp_ag_ind[index].hfp_value = 5;
253 hfp_ag_ind[index].hfp_value = value / 20 + 1;
255 } else if (g_str_equal(hfp_ag_ind[index].indicator_desc, "signal")) {
256 ret = vconf_get_int(VCONFKEY_TELEPHONY_RSSI, &value);
258 ERR("Get signal status failed err = %d\n", ret);
260 BT_CHECK_SIGNAL_STRENGTH(value);
261 hfp_ag_ind[index].hfp_value = value;
263 } else if (g_str_equal(hfp_ag_ind[index].indicator_desc, "roam")) {
264 ret = vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &value);
266 ERR("Get roaming status failed err = %d\n", ret);
268 hfp_ag_ind[index].hfp_value = value;
269 } else if (g_str_equal(hfp_ag_ind[index].indicator_desc, "service")) {
270 ret = vconf_get_int(VCONFKEY_TELEPHONY_SVCTYPE, &value);
272 ERR("Get Service status failed : %d\n", ret);
275 case VCONFKEY_TELEPHONY_SVCTYPE_NONE:
276 case VCONFKEY_TELEPHONY_SVCTYPE_NOSVC:
277 case VCONFKEY_TELEPHONY_SVCTYPE_SEARCH:
278 hfp_ag_ind[index].hfp_value =
279 INDICATOR_EVENT_SERVICE_NONE;
282 hfp_ag_ind[index].hfp_value =
283 INDICATOR_EVENT_SERVICE_PRESENT;
288 hfp_ag_ind[index].hfp_value = 0;
292 /*Initializatoin of the indicators*/
293 _bt_hfp_set_ag_indicator(ag_features, hfp_ag_ind,
294 BT_RSP_HOLD_NOT_SUPPORTED,
298 void _bt_hfp_deinitialize_telephony_manager(void)
300 GSList *list = call_senders_paths;
302 g_free(ag_subscriber_num);
303 ag_subscriber_num = NULL;
305 g_free(network_info.network_operator_name);
306 network_info.network_operator_name = NULL;
308 network_info.network_status = BT_AGENT_NETWORK_REG_STATUS_UNKOWN;
309 network_info.signal_strength = 0;
311 g_slist_free(agent_active_call_list);
312 agent_active_call_list = NULL;
314 g_slist_foreach(existing_call_list, (GFunc) __bt_hfp_free_call, NULL);
315 g_slist_free(existing_call_list);
316 existing_call_list = NULL;
318 while (list != NULL) {
319 __bt_hfp_clear_sender_path(list->data);
323 g_slist_free(call_senders_paths);
324 call_senders_paths = NULL;
326 _bt_hfp_deinitialize();
329 bt_hfp_agent_error_t _bt_hfp_register_telephony_agent(gboolean register_flag,
330 const char *path_to_register,
333 sender_info_t *sender_info;
335 if (sender == NULL || path_to_register == NULL)
336 return BT_HFP_AGENT_ERROR_INVALID_PARAM;
338 DBG(" register_flag = %d", register_flag);
339 DBG(" path_to_register = %s", path_to_register);
340 DBG(" sender = %s", sender);
343 if (__bt_hfp_check_for_callpath(path_to_register, sender))
344 return BT_HFP_AGENT_ERROR_ALREADY_EXSIST;
346 /* add call path to the senders list*/
347 DBG("Call path doesn't exist. Add path %s to global path",
349 sender_info = g_new0(sender_info_t, 1);
350 sender_info->sender_path = g_strdup(path_to_register);
351 sender_info->sender_name = g_strdup(sender);
352 call_senders_paths = g_slist_append(call_senders_paths,
355 return BT_HFP_AGENT_ERROR_NONE;
357 /*remove the call from senders list */
358 GSList *s_list = call_senders_paths;
360 while (s_list != NULL) {
361 sender_info = s_list->data;
363 if (sender_info == NULL)
364 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
366 if (g_strcmp0(sender_info->sender_path,
367 path_to_register) == 0) {
368 call_senders_paths = g_slist_remove(
371 __bt_hfp_clear_sender_path(sender_info);
372 return BT_HFP_AGENT_ERROR_NONE;
374 s_list = s_list->next;
377 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
381 static gboolean __bt_hfp_is_call_allowed(const char *call_path)
383 GSList *call_list = existing_call_list;
385 /*if prior call list doesn't exisit, allow the call as it can be a new-call*/
386 if (!existing_call_list) {
387 DBG(" This must be a new call... Allow it!");
391 while (call_list != NULL) {
393 struct telephony_call *t_call = call_list->data;
395 if (g_strcmp0(t_call->call_path, call_path) == 0)
398 call_list = call_list->next;
401 ERR("call is not allowed");
405 static struct telephony_call *__bt_hfp_create_new_call(
406 const char *incoming_path,
407 uint32_t incoming_call_id,
408 const char *incoming_number,
411 struct telephony_call *t_call = NULL;
412 GSList *call_list = existing_call_list;
414 while (call_list != NULL) {
415 t_call = call_list->data;
417 if (t_call->call_id == incoming_call_id)
422 call_list = call_list->next;
425 DBG("Create a new call");
427 if (t_call == NULL) {
428 t_call = g_new0(struct telephony_call, 1);
429 t_call->call_id = incoming_call_id;
430 t_call->call_path = g_strdup(incoming_path);
431 t_call->call_sender = g_strdup(sender);
432 t_call->call_number = g_strdup(incoming_number);
434 existing_call_list = g_slist_append(existing_call_list,
440 gboolean _bt_hfp_is_call_exist(void)
442 DBG("_bt_hfp_is_call_exist [%x]", existing_call_list);
443 if (existing_call_list)
449 static struct telephony_call *__bt_hfp_get_call_with_status(int call_status)
451 DBG("Get Call with status %d", call_status);
453 GSList *temp_list = existing_call_list;
455 if (existing_call_list != NULL) {
456 while (temp_list != NULL) {
457 struct telephony_call *t_call = temp_list->data;
458 if (t_call->call_status == call_status)
460 temp_list = temp_list->next;
464 DBG("Existing call list is NULL. So return NULL");
468 static bt_hfp_agent_error_t __bt_hfp_modify_indicator(
469 const char *indicator_name,
472 bt_ag_indicators_t *hf_ind = NULL;
474 #ifdef TIZEN_FEATURE_BT_MEDIA_ENHANCE
475 if (g_strcmp0(indicator_name,
476 HFP_AGENT_CALLSETUP_INDICATOR) == 0)
477 _bt_ag_agent_check_transport_state();
479 for (i = 0; hfp_ag_ind[i].indicator_desc != NULL; i++) {
480 if (g_str_equal(hfp_ag_ind[i].indicator_desc,
482 hf_ind = &hfp_ag_ind[i];
488 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
490 if (hf_ind->hfp_value == update_value && hf_ind->ignore)
491 return BT_HFP_AGENT_ERROR_NONE;
493 if (hf_ind->is_activated == FALSE)
494 return BT_HFP_AGENT_ERROR_NONE;
496 hf_ind->hfp_value = update_value;
498 DBG("updating hfp event indicator [%s] with value [%d]",
499 indicator_name, hf_ind->hfp_value);
501 return _bt_hfp_event_indicator(i);
504 static int __bt_hfp_get_indicator_value(
505 const bt_ag_indicators_t *ag_indicators,
509 for (x = 0; ag_indicators[x].indicator_desc != NULL; x++) {
510 if (g_str_equal(ag_indicators[x].indicator_desc, hf_desc))
511 return ag_indicators[x].hfp_value;
514 return ERR_NOT_FOUND;
517 static void __bt_hfp_handle_call_conference(void)
520 struct telephony_call *t_active_call = NULL;
521 int t_active_call_count = 0;
523 struct telephony_call *t_held_call = NULL;
524 int t_held_call_count = 0;
526 for (t_call_list = existing_call_list; t_call_list != NULL;
527 t_call_list = t_call_list->next) {
529 struct telephony_call *t_call = t_call_list->data;
531 if (t_call == NULL) {
532 ERR("t_call is NULL");
536 if (t_call->call_status == HFP_CALL_STATUS_ACTIVE) {
537 if (t_active_call == NULL)
538 t_active_call = t_call;
540 t_active_call_count++;
542 if (t_active_call_count >= 2) {
543 if (t_active_call->call_conference == FALSE)
544 t_active_call->call_conference = TRUE;
545 t_call->call_conference = TRUE;
548 } else if (t_call->call_status == HFP_CALL_STATUS_HOLD) {
549 if (t_held_call == NULL)
550 t_held_call = t_call;
554 if (t_held_call_count >= 2) {
555 if (t_held_call->call_conference == FALSE)
556 t_held_call->call_conference = TRUE;
557 t_call->call_conference = TRUE;
562 if (t_held_call != NULL && t_held_call_count == 1)
563 t_held_call->call_conference = FALSE;
565 if (t_active_call != NULL && t_active_call_count == 1)
566 t_active_call->call_conference = FALSE;
569 static gboolean __bt_hfp_on_call_hold_timeout(gpointer t_data)
573 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD)) {
574 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE))
575 status = INDICATOR_EVENT_CALLHELD_MULTIPLE;
577 status = INDICATOR_EVENT_CALLHELD_ON_HOLD;
579 status = INDICATOR_EVENT_CALLHELD_NONE;
582 __bt_hfp_modify_indicator("callheld", status);
584 call_on_hold_timer = 0;
588 static void __bt_hfp_handle_call_on_hold_request(void)
590 DBG(" Starting the timer for call on hold");
591 if (call_on_hold_timer)
592 g_source_remove(call_on_hold_timer);
594 call_on_hold_timer = g_timeout_add(250, __bt_hfp_on_call_hold_timeout,
596 DBG(" returning from the timer call");
599 static void __bt_hfp_set_call_status(struct telephony_call *t_call,
603 int org_status = t_call->call_status;
605 call_held = __bt_hfp_get_indicator_value(hfp_ag_ind, "callheld");
607 if (org_status == call_status) {
608 DBG("Ignore the CSD Call state change to existing state");
612 t_call->call_status = call_status;
614 DBG(" call status is %d", call_status);
616 switch (call_status) {
617 case HFP_CALL_STATUS_IDLE:
618 if (t_call->call_setup) {
619 __bt_hfp_modify_indicator("callsetup",
620 INDICATOR_EVENT_CALLSETUP_INACTIVE);
621 if (!t_call->call_originating)
622 _bt_calling_stopped_indicator();
625 g_free(t_call->call_number);
626 t_call->call_number = NULL;
627 t_call->call_originating = FALSE;
628 t_call->call_emergency = FALSE;
629 t_call->call_on_hold = FALSE;
630 t_call->call_conference = FALSE;
631 t_call->call_setup = FALSE;
634 case HFP_CALL_STATUS_COMING:
635 t_call->call_originating = FALSE;
636 t_call->call_setup = TRUE;
637 __bt_hfp_modify_indicator("callsetup",
638 INDICATOR_EVENT_CALLSETUP_INCOMING);
641 case HFP_CALL_STATUS_CREATE:
642 t_call->call_originating = TRUE;
643 t_call->call_setup = TRUE;
646 case HFP_CALL_STATUS_MO_ALERTING:
647 __bt_hfp_modify_indicator("callsetup",
648 INDICATOR_EVENT_CALLSETUP_ALERTING);
651 case HFP_CALL_STATUS_MT_ALERTING: {
652 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
654 if (t_call->call_number == NULL) {
655 t_number = AGENT_NUMBER_TYPE_TELEPHONY;
657 if (t_call->call_number[0] == '+' ||
658 strncmp(t_call->call_number, "00", 2) == 0)
659 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
662 if (org_status == HFP_CALL_STATUS_WAITING)
663 _bt_incoming_call_indicator(t_call->call_number,
668 case HFP_CALL_STATUS_ACTIVE:
669 DBG(" This is an Active call");
670 if (t_call->call_on_hold) {
671 t_call->call_on_hold = FALSE;
672 __bt_hfp_handle_call_on_hold_request();
674 if (!g_slist_find(agent_active_call_list, t_call)) {
675 DBG(" This call is not in the active call list. So Add it to the list.\n");
676 agent_active_call_list =
677 g_slist_prepend(agent_active_call_list,
680 if (g_slist_length(agent_active_call_list) == 1) {
681 DBG(" Update indicator to show the call presence.\n");
682 __bt_hfp_modify_indicator("call",
683 INDICATOR_EVENT_CALL_ACTIVE);
686 __bt_hfp_modify_indicator("callsetup",
687 INDICATOR_EVENT_CALLSETUP_INACTIVE);
688 __bt_hfp_handle_call_on_hold_request();
690 if (!t_call->call_originating)
691 _bt_calling_stopped_indicator();
693 t_call->call_setup = FALSE;
697 case HFP_CALL_STATUS_MO_RELEASE:
698 case HFP_CALL_STATUS_MT_RELEASE:
699 agent_active_call_list = g_slist_remove(agent_active_call_list,
701 if (g_slist_length(agent_active_call_list) == 0)
702 __bt_hfp_modify_indicator("call",
703 INDICATOR_EVENT_CALL_INACTIVE);
705 if (org_status == HFP_CALL_STATUS_HOLD)
706 __bt_hfp_modify_indicator("callheld", INDICATOR_EVENT_CALLHELD_NONE);
708 if ((org_status == HFP_CALL_STATUS_MO_ALERTING) ||
709 (org_status == HFP_CALL_STATUS_COMING) ||
710 (org_status == HFP_CALL_STATUS_CREATE) ||
711 (org_status == HFP_CALL_STATUS_WAITING)) {
712 __bt_hfp_modify_indicator("callsetup",
713 INDICATOR_EVENT_CALLSETUP_INACTIVE);
716 if (org_status == HFP_CALL_STATUS_COMING) {
717 if (!t_call->call_originating)
718 _bt_calling_stopped_indicator();
720 existing_call_list = g_slist_remove(existing_call_list, t_call);
721 __bt_hfp_free_call(t_call);
724 case HFP_CALL_STATUS_HOLD:
725 t_call->call_on_hold = TRUE;
726 __bt_hfp_handle_call_on_hold_request();
729 case HFP_CALL_STATUS_TERMINATED:
730 if (t_call->call_on_hold &&
731 !__bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD)) {
732 __bt_hfp_modify_indicator("callheld",
733 INDICATOR_EVENT_CALLHELD_NONE);
737 if (call_held == INDICATOR_EVENT_CALLHELD_MULTIPLE &&
738 __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD) &&
739 !__bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE))
740 __bt_hfp_modify_indicator("callheld",
741 INDICATOR_EVENT_CALLHELD_ON_HOLD);
744 case HFP_CALL_STATUS_PROCEEDING:
745 case HFP_CALL_STATUS_SWAP_INITIATED:
746 case HFP_CALL_STATUS_RETRIEVE_INITIATED:
747 case HFP_CALL_STATUS_RECONNECT_PENDING:
748 case HFP_CALL_STATUS_HOLD_INITIATED:
749 case HFP_CALL_STATUS_WAITING:
750 case HFP_CALL_STATUS_ANSWERED:
757 /* Update the call conference status for each of the call */
758 __bt_hfp_handle_call_conference();
761 bt_hfp_agent_error_t _bt_hfp_incoming_call(const char *call_path,
762 const char *incoming_number,
763 uint32_t incoming_call_id,
766 struct telephony_call *t_call = NULL;
767 bt_hfp_agent_error_t hfp_err = BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
768 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
771 if (sender == NULL || call_path == NULL)
772 return BT_HFP_AGENT_ERROR_INVALID_PARAM;
774 if (!__bt_hfp_check_for_callpath(call_path, sender))
775 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
777 if (!__bt_hfp_is_call_allowed(call_path))
778 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
780 /* Its a new call, so create a list for it*/
781 t_call = __bt_hfp_create_new_call(call_path, incoming_call_id,
785 /*get the type of the incoming number*/
786 if (t_call->call_number == NULL) {
787 t_number = AGENT_NUMBER_TYPE_TELEPHONY;
788 ERR("call_number is NULL");
790 if (t_call->call_number[0] == '+' || strncmp(
791 t_call->call_number, "00", 2) == 0)
792 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
794 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE) ||
795 __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD)) {
796 error = _bt_call_waiting_indicator(t_call->call_number,
799 ERR(" Fail to update CCWA information");
802 hfp_err = __bt_hfp_modify_indicator(
803 HFP_AGENT_CALLSETUP_INDICATOR,
804 HFP_INCOMING_CALLSETUP);
805 if (hfp_err != BT_HFP_AGENT_ERROR_NONE)
806 ERR("Failed to update the indicators");
808 __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_WAITING);
810 DBG(" It is an incoming call");
813 hfp_err = __bt_hfp_modify_indicator(
814 HFP_AGENT_CALLSETUP_INDICATOR,
815 HFP_INCOMING_CALLSETUP);
816 if (hfp_err != BT_HFP_AGENT_ERROR_NONE)
817 ERR("Failed to update the indicators");
820 error = _bt_incoming_call_indicator(t_call->call_number,
823 __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_COMING);
825 if (error == -ENODEV)
826 return BT_HFP_AGENT_ERROR_NOT_CONNECTED;
827 else if (error == -EBUSY)
828 return BT_HFP_AGENT_ERROR_BUSY;
835 bt_hfp_agent_error_t _bt_hfp_outgoing_call(const char *call_path,
837 uint32_t call_id, const char *sender)
839 struct telephony_call *t_call = NULL;
840 bt_hfp_agent_error_t ret = BT_HFP_AGENT_ERROR_NONE;
841 gboolean err = FALSE;
844 err = __bt_hfp_check_for_callpath(call_path, sender);
846 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
848 /*check if the call_path exisits in the active call list, if not
849 don't allow as the call may be initated by some other application*/
851 err = __bt_hfp_is_call_allowed(call_path);
853 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
855 /* create a new call for the call_path */
856 t_call = __bt_hfp_create_new_call(call_path, call_id, number, sender);
858 __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_CREATE);
860 ret = __bt_hfp_modify_indicator(HFP_AGENT_CALLSETUP_INDICATOR,
861 HFP_OUTGOING_CALLSETUP);
862 if (ret != BT_HFP_AGENT_ERROR_NONE)
863 DBG("Error in updating indicator");
868 bt_hfp_agent_error_t _bt_hfp_change_call_status(const char *call_path,
869 const char *number, uint32_t call_status,
870 uint32_t call_id, const char *sender)
872 GSList *call_list = existing_call_list;
873 struct telephony_call *t_call = NULL;
874 gboolean ret = FALSE;
876 if (call_status > AG_MAX_LENGTH)
877 return BT_HFP_AGENT_ERROR_INVALID_PARAM;
879 ret = __bt_hfp_check_for_callpath(call_path, sender);
882 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
884 ret = __bt_hfp_is_call_allowed(call_path);
886 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
888 /* find call with the given call_id*/
889 DBG(" Find call with the given call Id from the list");
890 while (call_list != NULL) {
891 t_call = call_list->data;
893 if (t_call->call_id == call_id) {
894 DBG("Call Id Match");
900 call_list = call_list->next;
903 if (t_call == NULL) {
904 DBG("t_call is NULL. So create new call");
905 t_call = __bt_hfp_create_new_call(call_path,
906 call_id, number, sender);
909 __bt_hfp_set_call_status(t_call, call_status);
911 return BT_HFP_AGENT_ERROR_NONE;
914 static int __bt_hfp_update_battery_strength(int32_t battery_strength)
916 int bat_strength = 0;
919 DBG(" Battery strength is.... %d", battery_strength);
921 /* get the current battery level */
922 for (x = 0; hfp_ag_ind[x].indicator_desc != NULL; x++) {
923 if (g_str_equal(hfp_ag_ind[x].indicator_desc, "battchg"))
924 bat_strength = hfp_ag_ind[x].hfp_value;
927 /* We need to send battery status ranging from 0-5 */
928 if (battery_strength < 5)
930 else if (battery_strength >= 100)
933 change_value = battery_strength / 20 + 1;
935 if (bat_strength == change_value) {
936 DBG("no change in battery strength");
940 if (__bt_hfp_modify_indicator("battchg",
941 change_value) == BT_HFP_AGENT_ERROR_NONE)
947 static int __bt_hfp_update_signal_strength(int32_t signal_strength_bars)
949 if (signal_strength_bars < 0)
950 signal_strength_bars = 0;
951 else if (signal_strength_bars > 5)
952 signal_strength_bars = 5;
954 if (network_info.signal_strength == signal_strength_bars) {
955 DBG("no change in signal strength");
959 network_info.signal_strength = signal_strength_bars;
961 if (__bt_hfp_modify_indicator("signal",
962 signal_strength_bars) == BT_HFP_AGENT_ERROR_NONE)
968 static int __bt_hfp_update_registration_status(uint8_t register_status)
970 bt_hfp_agent_error_t reg_ret = BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
972 DBG("Updating registration status to.... %d", register_status);
974 if (network_info.network_status == register_status) {
975 DBG("No change in registration status");
979 if (register_status == BT_AGENT_NETWORK_REG_STATUS_ROAMING) {
980 reg_ret = __bt_hfp_modify_indicator("roam",
981 INDICATOR_EVENT_ROAM_ACTIVE);
983 if (network_info.network_status >
984 BT_AGENT_NETWORK_REG_STATUS_ROAMING)
985 reg_ret = __bt_hfp_modify_indicator("service",
986 INDICATOR_EVENT_SERVICE_PRESENT);
987 } else if (register_status == BT_AGENT_NETWORK_REG_STATUS_HOME) {
988 reg_ret = __bt_hfp_modify_indicator("roam",
989 INDICATOR_EVENT_ROAM_INACTIVE);
991 if (network_info.network_status >
992 BT_AGENT_NETWORK_REG_STATUS_ROAMING)
993 reg_ret = __bt_hfp_modify_indicator("service",
994 INDICATOR_EVENT_SERVICE_PRESENT);
995 } else if (register_status == BT_AGENT_NETWORK_REG_STATUS_OFFLINE ||
996 register_status == BT_AGENT_NETWORK_REG_STATUS_SEARCHING ||
997 register_status == BT_AGENT_NETWORK_REG_STATUS_NO_SIM ||
998 register_status == BT_AGENT_NETWORK_REG_STATUS_POWEROFF ||
999 register_status == BT_AGENT_NETWORK_REG_STATUS_POWERSAFE ||
1000 register_status == BT_AGENT_NETWORK_REG_STATUS_NO_COVERAGE ||
1001 register_status == BT_AGENT_NETWORK_REG_STATUS_REJECTED ||
1002 register_status == BT_AGENT_NETWORK_REG_STATUS_UNKOWN) {
1003 if (network_info.network_status <
1004 BT_AGENT_NETWORK_REG_STATUS_OFFLINE)
1005 reg_ret = __bt_hfp_modify_indicator("service",
1006 INDICATOR_EVENT_SERVICE_NONE);
1009 network_info.network_status = register_status;
1010 if (reg_ret == BT_HFP_AGENT_ERROR_NONE)
1016 int _bt_hfp_set_property_value(const char *property, int value)
1020 DBG("Property is %s", property);
1022 if (g_str_equal("RegistrationChanged", property))
1023 ret = __bt_hfp_update_registration_status(value);
1025 else if (g_str_equal("SignalBarsChanged", property))
1026 ret = __bt_hfp_update_signal_strength(value);
1028 else if (g_str_equal("BatteryBarsChanged", property))
1029 ret = __bt_hfp_update_battery_strength(value);
1034 int _bt_hfp_set_property_name(const char *property, const char *operator_name)
1038 if (operator_name == NULL)
1041 if (g_str_equal("OperatorNameChanged", property)) {
1042 g_free(network_info.network_operator_name);
1043 network_info.network_operator_name =
1044 g_strndup(operator_name, 16);
1048 if (g_str_equal("SubscriberNumberChanged", property)) {
1049 g_free(ag_subscriber_num);
1050 ag_subscriber_num = g_strdup(operator_name);
1051 DBG("HFP: subscriber_number updated: %s", ag_subscriber_num);
1057 static int __bt_hfp_answer_call(struct telephony_call *t_call)
1059 if (t_call->call_id != 0 && t_call->call_path != NULL &&
1060 t_call->call_sender != NULL) {
1061 _bt_ag_agent_answer_call(t_call->call_id,
1063 t_call->call_sender);
1069 void _bt_hfp_answer_call_request(void *t_device)
1071 struct telephony_call *t_call;
1073 t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_COMING);
1076 t_call = __bt_hfp_get_call_with_status(
1077 HFP_CALL_STATUS_MT_ALERTING);
1080 t_call = __bt_hfp_get_call_with_status(
1081 HFP_CALL_STATUS_PROCEEDING);
1084 t_call = __bt_hfp_get_call_with_status(
1085 HFP_CALL_STATUS_WAITING);
1087 if (t_call == NULL) {
1088 _bt_answer_call_response(t_device,
1089 HFP_STATE_MNGR_ERR_NOT_ALLOWED);
1093 if (__bt_hfp_answer_call(t_call) < 0)
1094 _bt_answer_call_response(t_device,
1095 HFP_STATE_MNGR_ERR_AG_FAILURE);
1097 _bt_answer_call_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1101 void _bt_hfp_dial_number_request(const char *dial_number, void *t_device)
1103 int call_flag = caller_id;
1104 bt_hfp_agent_error_t error_code = 0;
1106 if (strncmp(dial_number, "#31#", 4) == 0) {
1107 dial_number = dial_number + 4;
1108 call_flag = ALLOW_CALL_FLAG;
1109 } else if (strncmp(dial_number, "*31#", 4) == 0) {
1110 dial_number = dial_number + 4;
1111 call_flag = RESTRAIN_CALL_FLAG;
1112 } else if (dial_number[0] == '>') {
1113 int dial_location = strtol(&dial_number[1], NULL, 0);
1115 error_code = _bt_ag_agent_dial_memory(dial_location);
1117 if (error_code == BT_HFP_AGENT_ERROR_NONE)
1118 _bt_dial_number_response(t_device,
1119 HFP_STATE_MNGR_ERR_NONE);
1121 _bt_dial_number_response(t_device,
1122 HFP_STATE_MNGR_ERR_AG_FAILURE);
1126 error_code = _bt_ag_agent_dial_num(dial_number, call_flag);
1128 if (error_code == BT_HFP_AGENT_ERROR_NONE) {
1129 _bt_dial_number_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1133 _bt_dial_number_response(t_device, HFP_STATE_MNGR_ERR_AG_FAILURE);
1137 void _bt_hfp_update_event_request(int indicator, void *t_device)
1140 update_events = TRUE;
1142 update_events = FALSE;
1144 _bt_event_reporting_response(t_device,
1145 HFP_STATE_MNGR_ERR_NONE);
1148 static int __bt_bt_hfp_reject_call(struct telephony_call *t_call)
1152 if (t_call != NULL) {
1153 DBG(" rejecting call from sender %s with call path %s and call id %d",
1154 t_call->call_sender,
1158 ret = _bt_ag_agent_reject_call(t_call->call_id,
1160 t_call->call_sender);
1168 static int __bt_hfp_release_call(struct telephony_call *t_call)
1170 gboolean ret = _bt_ag_agent_release_call(t_call->call_id,
1172 t_call->call_sender);
1179 static int __bt_hfp_release_conference(void)
1181 GSList *temp_list = existing_call_list;
1183 while (temp_list != NULL) {
1184 struct telephony_call *t_call = temp_list->data;
1186 if (t_call->call_conference)
1187 __bt_hfp_release_call(t_call);
1189 temp_list = temp_list->next;
1194 void _bt_hfp_terminate_call_request(void *t_device)
1196 struct telephony_call *t_call;
1197 struct telephony_call *t_alert = NULL;
1200 t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE);
1202 if (t_call == NULL) {
1203 DBG("Find non-idle call");
1204 GSList *temp_call_list = existing_call_list;
1205 while (temp_call_list != NULL) {
1206 t_call = temp_call_list->data;
1208 if (t_call->call_status == HFP_AGENT_CALL_IDLE)
1209 temp_call_list = temp_call_list->next;
1215 if (t_call == NULL) {
1216 DBG("Seems like there are no active calls. So do not allow the call");
1217 _bt_terminate_call_response(t_device,
1218 HFP_STATE_MNGR_ERR_NOT_ALLOWED);
1222 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_WAITING) != NULL) {
1224 t_error = _bt_ag_agent_threeway_call(value, t_call->call_path,
1225 t_call->call_sender);
1226 } else if ((t_alert = __bt_hfp_get_call_with_status(
1227 HFP_CALL_STATUS_CREATE))
1229 t_error = __bt_bt_hfp_reject_call(t_alert);
1230 } else if ((t_alert = __bt_hfp_get_call_with_status(
1231 HFP_CALL_STATUS_MO_ALERTING))
1233 t_error = __bt_bt_hfp_reject_call(t_alert);
1234 } else if ((t_alert = __bt_hfp_get_call_with_status(
1235 HFP_CALL_STATUS_COMING)) != NULL) {
1236 t_error = __bt_bt_hfp_reject_call(t_alert);
1237 } else if (t_call->call_conference)
1238 t_error = __bt_hfp_release_conference();
1240 t_error = __bt_hfp_release_call(t_call);
1243 _bt_terminate_call_response(t_device,
1244 HFP_STATE_MNGR_ERR_AG_FAILURE);
1246 _bt_terminate_call_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1249 void _bt_hfp_call_hold_request(const char *t_cmd, void *t_device)
1252 struct telephony_call *t_call = NULL;
1253 GSList *t_sender_list = call_senders_paths;
1254 sender_info_t *sender_info = NULL;
1255 uint32_t t_chld_value;
1257 t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE);
1258 if (t_call == NULL) {
1260 __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD))
1262 if ((t_call = __bt_hfp_get_call_with_status(
1263 HFP_CALL_STATUS_WAITING)) == NULL) {
1264 /* means there is no outgoing call*/
1265 _bt_call_hold_response(t_device,
1266 HFP_STATE_MNGR_ERR_AG_FAILURE);
1272 while (t_sender_list != NULL) {
1273 sender_info = t_sender_list->data;
1274 if (sender_info == NULL) {
1275 _bt_call_hold_response(t_device,
1276 HFP_STATE_MNGR_ERR_AG_FAILURE);
1279 if (g_strcmp0(t_call->call_path, sender_info->sender_path)
1283 t_sender_list = t_sender_list->next;
1286 t_chld_value = strtoul(&t_cmd[0], NULL, 0);
1287 gboolean ret = _bt_ag_agent_threeway_call(t_chld_value,
1289 t_call->call_sender);
1292 _bt_call_hold_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1294 _bt_call_hold_response(t_device, HFP_STATE_MNGR_ERR_AG_FAILURE);
1297 void _bt_hfp_key_press_request(const char *t_key_press, void *t_device)
1299 struct telephony_call *t_active_call;
1300 struct telephony_call *t_waiting_call;
1303 t_waiting_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_COMING);
1305 if (t_waiting_call == NULL)
1306 t_waiting_call = __bt_hfp_get_call_with_status(
1307 HFP_CALL_STATUS_MT_ALERTING);
1309 if (t_waiting_call == NULL)
1310 t_waiting_call = __bt_hfp_get_call_with_status(
1311 HFP_CALL_STATUS_PROCEEDING);
1313 t_active_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE);
1316 if (t_waiting_call != NULL)
1317 t_error = __bt_hfp_answer_call(t_waiting_call);
1318 else if (t_active_call != NULL)
1319 t_error = __bt_hfp_release_call(t_active_call);
1321 if (_bt_ag_agent_dial_last_num(t_device) !=
1322 BT_HFP_AGENT_ERROR_NONE)
1323 _bt_dial_number_response(t_device,
1324 HFP_STATE_MNGR_ERR_AG_FAILURE);
1326 _bt_dial_number_response(t_device,
1327 HFP_STATE_MNGR_ERR_NONE);
1332 _bt_key_press_response(t_device,
1333 HFP_STATE_MNGR_ERR_AG_FAILURE);
1335 _bt_key_press_response(t_device,
1336 HFP_STATE_MNGR_ERR_NONE);
1339 void _bt_hfp_last_dialed_number_request(void *t_device)
1341 bt_hfp_agent_error_t error = _bt_ag_agent_dial_last_num(t_device);
1343 if (error != BT_HFP_AGENT_ERROR_NONE)
1344 _bt_dial_number_response(t_device,
1345 HFP_STATE_MNGR_ERR_AG_FAILURE);
1347 _bt_dial_number_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1350 void _bt_hfp_channel_dtmf_request(char t_tone, void *t_device)
1352 char buf[2] = { t_tone, '\0' };
1353 char *tone_buffer = buf;
1355 struct telephony_call *t_call = __bt_hfp_get_call_with_status(
1356 HFP_CALL_STATUS_ACTIVE);
1357 if (t_call == NULL) {
1358 t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD);
1359 if (t_call == NULL) {
1360 t_call = __bt_hfp_get_call_with_status(
1361 HFP_CALL_STATUS_WAITING);
1362 if (t_call == NULL) {
1363 /* if this point is reached,
1364 it means there is no ongoing call */
1365 _bt_transmit_dtmf_response(t_device,
1366 HFP_STATE_MNGR_ERR_AG_FAILURE);
1372 if (_bt_ag_agent_send_dtmf(tone_buffer, t_call->call_path,
1373 t_call->call_sender) != BT_HFP_AGENT_ERROR_NONE) {
1374 _bt_transmit_dtmf_response(t_device,
1375 HFP_STATE_MNGR_ERR_AG_FAILURE);
1379 _bt_transmit_dtmf_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1382 void _bt_hfp_vendor_cmd_request(const char *cmd,
1385 GSList *t_sender_list = call_senders_paths;
1386 sender_info_t *sender_info = NULL;
1388 bt_hfp_agent_error_t error = BT_HFP_AGENT_ERROR_NONE;
1390 if (NULL != t_sender_list) {
1391 for (l = t_sender_list; l != NULL; l = l->next) {
1392 sender_info = l->data;
1393 error = _bt_ag_agent_vendor_cmd(cmd,
1394 sender_info->sender_path,
1395 sender_info->sender_name);
1396 if (error != BT_HFP_AGENT_ERROR_NONE)
1401 if (error != BT_HFP_AGENT_ERROR_NONE)
1402 _bt_vendor_cmd_response(t_device,
1403 HFP_STATE_MNGR_ERR_AG_FAILURE);
1405 _bt_vendor_cmd_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1408 void _bt_hfp_subscriber_number_request(void *t_device)
1410 if (ag_subscriber_num != NULL) {
1412 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
1414 if (ag_subscriber_num[0] == '+' || strncmp(
1415 ag_subscriber_num, "00", 2) == 0)
1416 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
1418 _bt_subscriber_number_indicator(ag_subscriber_num,
1419 t_number, AGENT_SUBSCRIBER_SERVICE_VOICE);
1422 _bt_subscriber_number_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1425 static int __bt_hfp_get_call_status(struct telephony_call *t_call)
1427 switch (t_call->call_status) {
1428 case HFP_CALL_STATUS_IDLE:
1429 case HFP_CALL_STATUS_MO_RELEASE:
1430 case HFP_CALL_STATUS_MT_RELEASE:
1431 case HFP_CALL_STATUS_TERMINATED:
1434 case HFP_CALL_STATUS_ANSWERED:
1435 case HFP_CALL_STATUS_ACTIVE:
1436 case HFP_CALL_STATUS_RECONNECT_PENDING:
1437 case HFP_CALL_STATUS_SWAP_INITIATED:
1438 case HFP_CALL_STATUS_HOLD_INITIATED:
1439 return AGENT_CALL_STATUS_ACTIVE;
1441 case HFP_CALL_STATUS_RETRIEVE_INITIATED:
1442 case HFP_CALL_STATUS_HOLD:
1443 return AGENT_CALL_STATUS_HELD;
1445 case HFP_CALL_STATUS_WAITING:
1446 return AGENT_CALL_STATUS_WAITING;
1448 case HFP_CALL_STATUS_CREATE:
1449 return AGENT_CALL_STATUS_DIALING;
1451 case HFP_CALL_STATUS_PROCEEDING:
1452 if (t_call->call_originating)
1453 return AGENT_CALL_STATUS_DIALING;
1454 if (g_slist_length(agent_active_call_list) > 0)
1455 return AGENT_CALL_STATUS_WAITING;
1457 return AGENT_CALL_STATUS_INCOMING;
1459 case HFP_CALL_STATUS_COMING:
1460 if (g_slist_length(agent_active_call_list) > 0)
1461 return AGENT_CALL_STATUS_WAITING;
1463 return AGENT_CALL_STATUS_INCOMING;
1465 case HFP_CALL_STATUS_MO_ALERTING:
1466 return AGENT_CALL_STATUS_ALERTING;
1468 case HFP_CALL_STATUS_MT_ALERTING:
1469 return AGENT_CALL_STATUS_INCOMING;
1476 void _bt_list_current_calls(void *t_device)
1478 GSList *t_call_list = existing_call_list;
1480 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
1481 int t_direction, t_call_conference;
1484 while (t_call_list != NULL) {
1485 struct telephony_call *t_call = t_call_list->data;
1486 t_status = __bt_hfp_get_call_status(t_call);
1487 if (t_status >= 0) {
1488 if (t_call->call_originating != TRUE)
1489 t_direction = AGENT_CALL_DIRECTION_INCOMING;
1491 t_direction = AGENT_CALL_DIRECTION_OUTGOING;
1493 if (t_call->call_conference != TRUE)
1494 t_call_conference = AGENT_CALL_MULTIPARTY_NO;
1496 t_call_conference = AGENT_CALL_MULTIPARTY_YES;
1498 if (t_call->call_number == NULL) {
1499 t_number = AGENT_NUMBER_TYPE_TELEPHONY;
1501 if (t_call->call_number[0] == '+' || strncmp(
1502 t_call->call_number, "00", 2) == 0)
1503 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
1506 index = t_call->call_id;
1507 _bt_list_current_call_indicator(t_device, index, t_direction,
1508 AGENT_CALL_MODE_VOICE,
1510 t_call->call_number,
1514 t_call_list = t_call_list->next;
1516 _bt_list_current_calls_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1519 void _bt_hfp_release_all_calls_by_sender(const char *sender)
1521 GSList *temp_list = existing_call_list;
1527 DBG("sender [%s]", sender);
1529 while (temp_list != NULL) {
1530 struct telephony_call *t_call = temp_list->data;
1532 if (g_strcmp0(t_call->call_sender, sender) == 0) {
1533 INFO("terminate call[%d]", t_call->call_id);
1534 next_list = temp_list->next;
1535 __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_MT_RELEASE);
1536 temp_list = next_list;
1538 temp_list = temp_list->next;
1542 void _bt_hfp_noise_red_and_echo_cancel_request(gboolean t_enable,
1545 if (_bt_hfp_agent_nrec_status(t_enable, t_device) == TRUE)
1546 _bt_nr_and_ec_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1548 _bt_nr_and_ec_response(t_device, HFP_STATE_MNGR_ERR_AG_FAILURE);
1553 void _bt_hfp_voice_dial_request(gboolean t_enable, void *t_device)
1555 gboolean ret = FALSE;
1558 if (vconf_get_int(VCONFKEY_CALL_STATE, &call_state) < 0)
1559 ERR("vconf_get_int is failed");
1561 if ((t_enable == TRUE && call_state == 0) || t_enable == FALSE)
1562 ret = _bt_ag_agent_voice_dial(t_enable);
1565 _bt_voice_dial_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1567 _bt_voice_dial_response(t_device,
1568 HFP_STATE_MNGR_ERR_AG_FAILURE);
1573 void _bt_hfp_set_indicators(const char *t_command, void *t_device)
1575 const char delims = ',';
1578 if (t_command == NULL)
1581 str = strchr(t_command, '=');
1582 while (hfp_ag_ind[i].indicator_desc != NULL && str != NULL) {
1585 if ((g_strcmp0(hfp_ag_ind[i].indicator_desc, "call") != 0) &&
1586 (g_strcmp0(hfp_ag_ind[i].indicator_desc, "callheld") != 0) &&
1587 (g_strcmp0(hfp_ag_ind[i].indicator_desc, "callsetup") != 0)) {
1590 hfp_ag_ind[i].is_activated = FALSE;
1591 } else if (*str == '1') {
1592 hfp_ag_ind[i].is_activated = TRUE;
1594 DBG(" no change in is_activated for[%s]\n",
1595 hfp_ag_ind[i].indicator_desc);
1598 str = strchr(str, delims);
1602 _bt_indicators_activation_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1606 _bt_indicators_activation_response(t_device,
1607 HFP_STATE_MNGR_ERR_INVALID_CHAR_IN_STRING);
1611 static int __bt_hfp_get_phonebook_count(const char *path, uint32_t *max_size,
1614 #ifndef TIZEN_PROFILE_WEARABLE
1615 GDBusConnection *g_conn;
1616 GDBusProxy *g_proxy;
1618 GVariant *ret = NULL;
1622 g_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1626 ERR("Unable to connect to gdbus: %s", err->message);
1627 g_clear_error(&err);
1632 g_proxy = g_dbus_proxy_new_sync(g_conn,
1633 G_DBUS_PROXY_FLAGS_NONE, NULL,
1634 PHONEBOOK_AGENT_BUS_NAME, PHONEBOOK_AGENT_PATH,
1635 PHONEBOOK_AGENT_INTERFACE, NULL, &err);
1639 ERR("Unable to connect to gdbus: %s", err->message);
1640 g_clear_error(&err);
1645 ret = g_dbus_proxy_call_sync(g_proxy, "GetPhonebookSizeAt",
1646 g_variant_new("(s)",
1648 G_DBUS_CALL_FLAGS_NONE, -1,
1652 ERR("dbus call failed");
1654 ERR("D-Bus API failure: errCode[%x], message[%s]",
1655 err->code, err->message);
1657 g_clear_error(&err);
1661 g_variant_get(ret, "(u)", &size);
1662 g_variant_unref(ret);
1664 DBG("Size returned %d", size);
1665 if ((g_strcmp0(path, "\"SM\"") == 0) ||
1666 (g_strcmp0(path, "\"ME\"") == 0)) {
1667 max = AGENT_MAX_PB_COUNT;
1668 } else if ((g_strcmp0(path, "\"DC\"") == 0) ||
1669 (g_strcmp0(path, "\"MC\"") == 0) ||
1670 (g_strcmp0(path, "\"RC\"") == 0)) {
1671 max = AGENT_MAX_CALLLOG_COUNT;
1684 g_object_unref(g_conn);
1686 g_object_unref(g_proxy);
1691 void _bt_hfp_select_phonebook_memory_status(void *t_device)
1693 int32_t path_id = ag_pb_info.path_id;
1695 uint32_t max_size = 0;
1697 hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1699 if (path_id < 0 || path_id >= AGENT_PB_STORE_LIST_SIZE)
1702 if (__bt_hfp_get_phonebook_count(agent_pb_store_list[path_id],
1704 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1706 _bt_select_phonebook_memory_status_response(t_device,
1707 agent_pb_store_list[path_id],
1712 static char *__bt_hfp_get_supported_list(const char *char_list[],
1719 if (char_list == NULL || size == 0)
1722 strng = g_string_new("(");
1724 while (index < size) {
1726 g_string_append(strng, ",");
1728 g_string_append(strng, char_list[index]);
1732 g_string_append(strng, ")");
1734 return g_string_free(strng, FALSE);
1737 void _bt_hfp_select_phonebook_memory_list(void *t_device)
1741 str = __bt_hfp_get_supported_list(agent_pb_store_list,
1742 AGENT_PB_STORE_LIST_SIZE);
1744 _bt_select_phonebook_memory_list_response(t_device,
1745 str, HFP_STATE_MNGR_ERR_NONE);
1750 void _bt_hfp_select_phonebook_memory(void *t_device, const gchar *pb_path)
1753 hfp_state_manager_err_t err;
1755 while (i < AGENT_PB_STORE_LIST_SIZE) {
1756 if (strcmp(agent_pb_store_list[i], pb_path) == 0)
1761 if (i >= 0 && i < AGENT_PB_STORE_LIST_SIZE) {
1762 err = HFP_STATE_MNGR_ERR_NONE;
1763 ag_pb_info.path_id = i;
1765 err = HFP_STATE_MNGR_ERR_INVALID_CHAR_IN_STRING;
1767 _bt_select_phonebook_memory_response(t_device, err);
1770 void _bt_hfp_read_phonebook_entries_list(void *t_device)
1772 hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1774 int32_t path_id = ag_pb_info.path_id;
1777 if (path_id < 0 || path_id >= AGENT_PB_STORE_LIST_SIZE)
1778 err = HFP_STATE_MNGR_ERR_INVALID_INDEX;
1780 if (__bt_hfp_get_phonebook_count(agent_pb_store_list[path_id],
1781 NULL, &used) != 0) {
1782 err = HFP_STATE_MNGR_ERR_NOT_ALLOWED;
1786 _bt_read_phonebook_entries_list_response(t_device, used,
1787 AGENT_PB_NUMBER_MAX_LENGTH, AGENT_PB_NAME_MAX_LENGTH,
1791 static int __bt_hfp_get_phonebook_entries(int start_index, int end_index)
1793 #ifdef TIZEN_PROFILE_WEARABLE
1796 GDBusConnection *g_conn;
1797 GDBusProxy *g_proxy;
1799 GVariant *ret = NULL;
1801 GVariant *value = NULL;
1802 GVariant *tuple = NULL;
1803 const char *name = NULL;
1804 const char *number = NULL;
1809 uint32_t handle = 0;
1811 g_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1815 ERR("Unable to connect to gdbus: %s", err->message);
1816 g_clear_error(&err);
1821 g_proxy = g_dbus_proxy_new_sync(g_conn,
1822 G_DBUS_PROXY_FLAGS_NONE, NULL,
1823 PHONEBOOK_AGENT_BUS_NAME, PHONEBOOK_AGENT_PATH,
1824 PHONEBOOK_AGENT_INTERFACE, NULL, &err);
1827 ERR("Unable to connect to gdbus: %s", err->message);
1828 g_clear_error(&err);
1833 ret = g_dbus_proxy_call_sync(g_proxy, "GetPhonebookEntriesAt",
1834 g_variant_new("(sii)",
1835 agent_pb_store_list[ag_pb_info.path_id],
1836 start_index, end_index),
1837 G_DBUS_CALL_FLAGS_NONE, -1,
1841 ERR("Dbus call failed");
1843 ERR("D-Bus API failure: errCode[%x], message[%s]",
1844 err->code, err->message);
1846 g_clear_error(&err);
1848 ERR("error returned was NULL");
1852 tuple = g_variant_get_child_value(ret, 0);
1853 if (tuple != NULL) {
1854 int number_contacts = g_variant_n_children(tuple);
1855 DBG("number of contacts %d", number_contacts);
1856 while (count < number_contacts) {
1859 value = g_variant_get_child_value(tuple, count);
1861 g_variant_get(value, "(ssu)", &name, &number, &handle);
1863 uni_name = g_strndup(name, AGENT_PB_NAME_MAX_LENGTH);
1864 uni_number = g_strndup(number, AGENT_PB_NAME_MAX_LENGTH);
1866 _bt_read_phonebook_entries_indicator(uni_name,
1867 uni_number, handle);
1868 g_variant_unref(value);
1871 g_free((gpointer)name);
1872 g_free((gpointer)number);
1874 g_variant_unref(tuple);
1877 g_variant_unref(ret);
1879 g_object_unref(g_conn);
1881 g_object_unref(g_proxy);
1886 void _bt_hfp_read_phonebook_entries(void *t_device, const char *cmd)
1888 int start_index = 0;
1896 hfp_state_manager_err_t err;
1901 str = g_strdup(cmd);
1902 next = strchr(str, ',');
1908 end_index = strtol(next, NULL, 10);
1911 start_index = strtol(str, NULL, 10);
1915 count = __bt_hfp_get_phonebook_entries(start_index, end_index);
1918 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1919 else if (count == 0)
1920 err = HFP_STATE_MNGR_ERR_INVALID_INDEX;
1922 err = HFP_STATE_MNGR_ERR_NONE;
1924 _bt_read_phonebook_entries_response(t_device, err);
1927 void _bt_hfp_find_phonebook_entries_status(void *t_device)
1929 _bt_find_phonebook_entries_status_indicator(
1930 AGENT_PB_NUMBER_MAX_LENGTH,
1931 AGENT_PB_NAME_MAX_LENGTH);
1933 _bt_find_phonebook_entries_status_response(t_device,
1934 HFP_STATE_MNGR_ERR_NONE);
1937 static int __bt_hfp_find_pb_entries(const char *str)
1942 void _bt_hfp_find_phonebook_entries(void *t_device, const char *cmd)
1945 gchar *unquoted = NULL;
1947 hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1949 /* remove quote and compress */
1950 st = strchr(cmd, '"');
1952 unquoted = g_strdup(cmd);
1956 end = strrchr(cmd, '"');
1958 unquoted = g_strdup(cmd);
1960 unquoted = g_strndup(st + 1, end - st - 1);
1963 if (__bt_hfp_find_pb_entries(unquoted))
1964 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1966 _bt_find_phonebook_entries_response(t_device, err);
1971 void _bt_hfp_get_character_set(void *t_device)
1973 _bt_supported_character_generic_response(t_device,
1974 (char *)agent_supported_character_set[ag_pb_info.charset_id],
1975 HFP_STATE_MNGR_ERR_NONE);
1978 void _bt_hfp_list_supported_character(void *t_device)
1982 str = __bt_hfp_get_supported_list(agent_supported_character_set,
1983 AGENT_SUPPORTED_CHARACTER_SET_SIZE);
1985 _bt_supported_character_generic_response(t_device,
1986 str, HFP_STATE_MNGR_ERR_NONE);
1991 void _bt_hfp_set_character_set(void *t_device, const char *cmd)
1995 while (index < AGENT_SUPPORTED_CHARACTER_SET_SIZE) {
1996 if (strcmp(agent_supported_character_set[index], cmd) == 0) {
1997 _bt_set_characterset_generic_response(t_device,
1998 HFP_STATE_MNGR_ERR_NONE);
2000 ag_pb_info.charset_id = index;
2006 _bt_set_characterset_generic_response(t_device,
2007 HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
2011 void _bt_hfp_signal_quality_reply(int32_t rssi, int32_t ber,
2014 DBG("signal_quality_reply");
2016 if (rssi == -1 && ber == -1) {
2017 _bt_signal_quality_response(t_device, rssi, ber,
2018 HFP_STATE_MNGR_ERR_AG_FAILURE);
2020 _bt_signal_quality_response(t_device, rssi, ber,
2021 HFP_STATE_MNGR_ERR_NONE);
2025 void _bt_hfp_battery_property_reply(void *data, int32_t bcs,
2028 if (bcs == -1 || bcl == -1) {
2029 _bt_battery_charge_status_response(data, bcs,
2030 bcl, HFP_STATE_MNGR_ERR_AG_FAILURE);
2032 _bt_battery_charge_status_response(data, bcs,
2033 bcl, HFP_STATE_MNGR_ERR_NONE);
2039 void _bt_hfp_get_battery_property(void *t_device)
2041 _bt_ag_agent_get_battery_status(t_device);
2044 void _bt_hfp_operator_reply(char *operator_name, void *t_device)
2046 if (operator_name == NULL)
2049 network_info.network_operator_name = g_strndup(operator_name, 16);
2051 _bt_operator_selection_indicator(AGENT_OPERATOR_MODE_AUTO,
2053 _bt_operator_selection_response(t_device, HFP_STATE_MNGR_ERR_NONE);
2057 _bt_operator_selection_indicator(AGENT_OPERATOR_MODE_AUTO, "UNKNOWN");
2058 _bt_operator_selection_response(t_device,
2059 HFP_STATE_MNGR_ERR_AG_FAILURE);
2062 void _bt_hfp_get_operator_selection_request(void *t_device)
2064 _bt_ag_agent_get_operator_name(t_device);
2067 void _bt_hfp_response_and_hold_request(void *t_device)
2069 _bt_response_and_hold_response(t_device,
2070 HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
2073 void _bt_get_activity_status(void *t_device)
2075 DBG("telephony-tizen: telephony_get_activity_status");
2077 if (NULL != (__bt_hfp_get_call_with_status(
2078 HFP_CALL_STATUS_MT_ALERTING)) ||
2079 NULL != (__bt_hfp_get_call_with_status(
2080 HFP_CALL_STATUS_MO_ALERTING)) ||
2081 NULL != (__bt_hfp_get_call_with_status(
2082 HFP_CALL_STATUS_COMING)) ||
2083 NULL != (__bt_hfp_get_call_with_status(
2084 HFP_CALL_STATUS_CREATE)))
2085 _bt_hfp_get_activity_status_rsp(t_device,
2086 HFP_AGENT_ACTIVITY_STATUS_RINGING,
2087 HFP_STATE_MNGR_ERR_NONE);
2088 else if (NULL != (__bt_hfp_get_call_with_status(
2089 HFP_CALL_STATUS_WAITING)) ||
2090 NULL != (__bt_hfp_get_call_with_status(
2091 HFP_CALL_STATUS_ACTIVE)))
2092 _bt_hfp_get_activity_status_rsp(t_device,
2093 HFP_AGENT_ACTIVITY_STATUS_CALL_IN_PROGRESS,
2094 HFP_STATE_MNGR_ERR_NONE);
2096 _bt_hfp_get_activity_status_rsp(t_device,
2097 HFP_AGENT_ACTIVITY_STATUS_READY,
2098 HFP_STATE_MNGR_ERR_NONE);
2101 void _bt_hfp_get_imei_number_reply(char *imei_number, void *t_device)
2103 _bt_hfp_get_equipment_identity_rsp(t_device, imei_number,
2104 HFP_STATE_MNGR_ERR_NONE);
2107 void _bt_hfp_get_imsi_reply(char *mcc, char *mnc, char *msin, void *t_device)
2109 if (mcc != NULL && mnc != NULL && msin != NULL)
2110 _bt_hfp_get_imsi_rsp(t_device, mcc, mnc, msin,
2111 HFP_STATE_MNGR_ERR_NONE);
2113 _bt_hfp_get_imsi_rsp(t_device, NULL, NULL, NULL,
2114 HFP_STATE_MNGR_ERR_NOT_ALLOWED);
2117 void _bt_hfp_get_creg_status_reply(int n, int status, void *t_device)
2119 _bt_hfp_get_creg_status_rsp(t_device, n, status,
2120 HFP_STATE_MNGR_ERR_NONE);
2123 void _bt_hfp_get_equipment_identity_req(void *t_device)
2125 _bt_ag_agent_get_imei_number(t_device);
2128 void _bt_hfp_get_model_info_reply(char *model, void *t_device)
2130 _bt_hfp_get_model_info_rsp(t_device, model,
2131 HFP_STATE_MNGR_ERR_NONE);
2134 void _bt_hfp_get_model_info_req(void *t_device)
2136 _bt_ag_agent_get_model_name(t_device);
2139 void _bt_hfp_get_device_manufacturer_reply(char *manufacturer, void *t_device)
2141 _bt_hfp_get_device_manufacturer_rsp(t_device, manufacturer,
2142 HFP_STATE_MNGR_ERR_NONE);
2145 void _bt_hfp_get_device_manufacturer_req(void *t_device)
2147 _bt_ag_agent_get_manufacturer_name(t_device);
2150 void _bt_hfp_get_imsi_req(void *t_device)
2152 _bt_ag_agent_get_imsi(t_device);
2155 void _bt_hfp_get_creg_status_req(void *t_device)
2157 _bt_ag_agent_get_creg_status(t_device);
2160 void _bt_hfp_get_revision_info_reply(char *revision, void *t_device)
2162 _bt_hfp_get_revision_info_rsp(t_device, revision,
2163 HFP_STATE_MNGR_ERR_NONE);
2166 void _bt_hfp_get_revision_info_req(void *t_device)
2168 _bt_ag_agent_get_revision_information(t_device);