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->call_status == HFP_CALL_STATUS_ACTIVE) {
532 if (t_active_call == NULL)
533 t_active_call = t_call;
535 t_active_call_count++;
537 if (t_active_call_count >= 2) {
538 if (t_active_call->call_conference == FALSE)
539 t_active_call->call_conference = TRUE;
540 t_call->call_conference = TRUE;
543 } else if (t_call->call_status == HFP_CALL_STATUS_HOLD) {
544 if (t_held_call == NULL)
545 t_held_call = t_call;
549 if (t_held_call_count >= 2) {
550 if (t_held_call->call_conference == FALSE)
551 t_held_call->call_conference = TRUE;
552 t_call->call_conference = TRUE;
557 if (t_held_call_count == 1)
558 t_held_call->call_conference = FALSE;
560 if (t_active_call_count == 1)
561 t_active_call->call_conference = FALSE;
564 static gboolean __bt_hfp_on_call_hold_timeout(gpointer t_data)
568 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD)) {
569 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE))
570 status = INDICATOR_EVENT_CALLHELD_MULTIPLE;
572 status = INDICATOR_EVENT_CALLHELD_ON_HOLD;
574 status = INDICATOR_EVENT_CALLHELD_NONE;
577 __bt_hfp_modify_indicator("callheld", status);
579 call_on_hold_timer = 0;
583 static void __bt_hfp_handle_call_on_hold_request(void)
585 DBG(" Starting the timer for call on hold");
586 if (call_on_hold_timer)
587 g_source_remove(call_on_hold_timer);
589 call_on_hold_timer = g_timeout_add(250, __bt_hfp_on_call_hold_timeout,
591 DBG(" returning from the timer call");
594 static void __bt_hfp_set_call_status(struct telephony_call *t_call,
598 int org_status = t_call->call_status;
600 call_held = __bt_hfp_get_indicator_value(hfp_ag_ind, "callheld");
602 if (org_status == call_status) {
603 DBG("Ignore the CSD Call state change to existing state");
607 t_call->call_status = call_status;
609 DBG(" call status is %d", call_status);
611 switch (call_status) {
612 case HFP_CALL_STATUS_IDLE:
613 if (t_call->call_setup) {
614 __bt_hfp_modify_indicator("callsetup",
615 INDICATOR_EVENT_CALLSETUP_INACTIVE);
616 if (!t_call->call_originating)
617 _bt_calling_stopped_indicator();
620 g_free(t_call->call_number);
621 t_call->call_number = NULL;
622 t_call->call_originating = FALSE;
623 t_call->call_emergency = FALSE;
624 t_call->call_on_hold = FALSE;
625 t_call->call_conference = FALSE;
626 t_call->call_setup = FALSE;
629 case HFP_CALL_STATUS_COMING:
630 t_call->call_originating = FALSE;
631 t_call->call_setup = TRUE;
632 __bt_hfp_modify_indicator("callsetup",
633 INDICATOR_EVENT_CALLSETUP_INCOMING);
636 case HFP_CALL_STATUS_CREATE:
637 t_call->call_originating = TRUE;
638 t_call->call_setup = TRUE;
641 case HFP_CALL_STATUS_MO_ALERTING:
642 __bt_hfp_modify_indicator("callsetup",
643 INDICATOR_EVENT_CALLSETUP_ALERTING);
646 case HFP_CALL_STATUS_MT_ALERTING: {
647 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
649 if (t_call->call_number == NULL) {
650 t_number = AGENT_NUMBER_TYPE_TELEPHONY;
652 if (t_call->call_number[0] == '+' ||
653 strncmp(t_call->call_number, "00", 2) == 0)
654 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
657 if (org_status == HFP_CALL_STATUS_WAITING)
658 _bt_incoming_call_indicator(t_call->call_number,
663 case HFP_CALL_STATUS_ACTIVE:
664 DBG(" This is an Active call");
665 if (t_call->call_on_hold) {
666 t_call->call_on_hold = FALSE;
667 __bt_hfp_handle_call_on_hold_request();
669 if (!g_slist_find(agent_active_call_list, t_call)) {
670 DBG(" This call is not in the active call list. So Add it to the list.\n");
671 agent_active_call_list =
672 g_slist_prepend(agent_active_call_list,
675 if (g_slist_length(agent_active_call_list) == 1) {
676 DBG(" Update indicator to show the call presence.\n");
677 __bt_hfp_modify_indicator("call",
678 INDICATOR_EVENT_CALL_ACTIVE);
681 __bt_hfp_modify_indicator("callsetup",
682 INDICATOR_EVENT_CALLSETUP_INACTIVE);
683 __bt_hfp_handle_call_on_hold_request();
685 if (!t_call->call_originating)
686 _bt_calling_stopped_indicator();
688 t_call->call_setup = FALSE;
692 case HFP_CALL_STATUS_MO_RELEASE:
693 case HFP_CALL_STATUS_MT_RELEASE:
694 agent_active_call_list = g_slist_remove(agent_active_call_list,
696 if (g_slist_length(agent_active_call_list) == 0)
697 __bt_hfp_modify_indicator("call",
698 INDICATOR_EVENT_CALL_INACTIVE);
700 if (org_status == HFP_CALL_STATUS_HOLD) {
701 __bt_hfp_modify_indicator("callheld", INDICATOR_EVENT_CALLHELD_NONE);
704 if ((org_status == HFP_CALL_STATUS_MO_ALERTING) ||
705 (org_status == HFP_CALL_STATUS_COMING) ||
706 (org_status == HFP_CALL_STATUS_CREATE) ||
707 (org_status == HFP_CALL_STATUS_WAITING)) {
708 __bt_hfp_modify_indicator("callsetup",
709 INDICATOR_EVENT_CALLSETUP_INACTIVE);
712 if (org_status == HFP_CALL_STATUS_COMING) {
713 if (!t_call->call_originating)
714 _bt_calling_stopped_indicator();
716 existing_call_list = g_slist_remove(existing_call_list, t_call);
717 __bt_hfp_free_call(t_call);
720 case HFP_CALL_STATUS_HOLD:
721 t_call->call_on_hold = TRUE;
722 __bt_hfp_handle_call_on_hold_request();
725 case HFP_CALL_STATUS_TERMINATED:
726 if (t_call->call_on_hold &&
727 !__bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD)) {
728 __bt_hfp_modify_indicator("callheld",
729 INDICATOR_EVENT_CALLHELD_NONE);
733 if (call_held == INDICATOR_EVENT_CALLHELD_MULTIPLE &&
734 __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD) &&
735 !__bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE))
736 __bt_hfp_modify_indicator("callheld",
737 INDICATOR_EVENT_CALLHELD_ON_HOLD);
740 case HFP_CALL_STATUS_PROCEEDING:
741 case HFP_CALL_STATUS_SWAP_INITIATED:
742 case HFP_CALL_STATUS_RETRIEVE_INITIATED:
743 case HFP_CALL_STATUS_RECONNECT_PENDING:
744 case HFP_CALL_STATUS_HOLD_INITIATED:
745 case HFP_CALL_STATUS_WAITING:
746 case HFP_CALL_STATUS_ANSWERED:
753 /* Update the call conference status for each of the call */
754 __bt_hfp_handle_call_conference();
757 bt_hfp_agent_error_t _bt_hfp_incoming_call(const char *call_path,
758 const char *incoming_number,
759 uint32_t incoming_call_id,
762 struct telephony_call *t_call = NULL;
763 bt_hfp_agent_error_t hfp_err = BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
764 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
767 if (sender == NULL || call_path == NULL)
768 return BT_HFP_AGENT_ERROR_INVALID_PARAM;
770 if (!__bt_hfp_check_for_callpath(call_path, sender))
771 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
773 if (!__bt_hfp_is_call_allowed(call_path))
774 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
776 /* Its a new call, so create a list for it*/
777 t_call = __bt_hfp_create_new_call(call_path, incoming_call_id,
781 /*get the type of the incoming number*/
782 if (t_call->call_number == NULL) {
783 t_number = AGENT_NUMBER_TYPE_TELEPHONY;
784 ERR("call_number is NULL");
786 if (t_call->call_number[0] == '+' || strncmp(
787 t_call->call_number, "00", 2) == 0)
788 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
790 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE) ||
791 __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD)) {
792 error = _bt_call_waiting_indicator(t_call->call_number,
795 ERR(" Fail to update CCWA information");
798 hfp_err = __bt_hfp_modify_indicator(
799 HFP_AGENT_CALLSETUP_INDICATOR,
800 HFP_INCOMING_CALLSETUP);
801 if (hfp_err != BT_HFP_AGENT_ERROR_NONE)
802 ERR("Failed to update the indicators");
804 __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_WAITING);
806 DBG(" It is an incoming call");
809 hfp_err = __bt_hfp_modify_indicator(
810 HFP_AGENT_CALLSETUP_INDICATOR,
811 HFP_INCOMING_CALLSETUP);
812 if (hfp_err != BT_HFP_AGENT_ERROR_NONE)
813 ERR("Failed to update the indicators");
816 error = _bt_incoming_call_indicator(t_call->call_number,
819 __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_COMING);
821 if (error == -ENODEV)
822 return BT_HFP_AGENT_ERROR_NOT_CONNECTED;
823 else if (error == -EBUSY)
824 return BT_HFP_AGENT_ERROR_BUSY;
831 bt_hfp_agent_error_t _bt_hfp_outgoing_call(const char *call_path,
833 uint32_t call_id, const char *sender)
835 struct telephony_call *t_call = NULL;
836 bt_hfp_agent_error_t ret = BT_HFP_AGENT_ERROR_NONE;
837 gboolean err = FALSE;
840 err = __bt_hfp_check_for_callpath(call_path, sender);
842 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
844 /*check if the call_path exisits in the active call list, if not
845 don't allow as the call may be initated by some other application*/
847 err = __bt_hfp_is_call_allowed(call_path);
849 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
851 /* create a new call for the call_path */
852 t_call = __bt_hfp_create_new_call(call_path, call_id, number, sender);
854 __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_CREATE);
856 ret = __bt_hfp_modify_indicator(HFP_AGENT_CALLSETUP_INDICATOR,
857 HFP_OUTGOING_CALLSETUP);
858 if (ret != BT_HFP_AGENT_ERROR_NONE)
859 DBG("Error in updating indicator");
864 bt_hfp_agent_error_t _bt_hfp_change_call_status(const char *call_path,
865 const char *number, uint32_t call_status,
866 uint32_t call_id, const char *sender)
868 GSList *call_list = existing_call_list;
869 struct telephony_call *t_call = NULL;
870 gboolean ret = FALSE;
872 if (call_status > AG_MAX_LENGTH)
873 return BT_HFP_AGENT_ERROR_INVALID_PARAM;
875 ret = __bt_hfp_check_for_callpath(call_path, sender);
878 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
880 ret = __bt_hfp_is_call_allowed(call_path);
882 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
884 /* find call with the given call_id*/
885 DBG(" Find call with the given call Id from the list");
886 while (call_list != NULL) {
887 t_call = call_list->data;
889 if (t_call->call_id == call_id) {
890 DBG("Call Id Match");
896 call_list = call_list->next;
899 if (t_call == NULL) {
900 DBG("t_call is NULL. So create new call");
901 t_call = __bt_hfp_create_new_call(call_path,
902 call_id, number, sender);
905 __bt_hfp_set_call_status(t_call, call_status);
907 return BT_HFP_AGENT_ERROR_NONE;
910 static int __bt_hfp_update_battery_strength(int32_t battery_strength)
912 int bat_strength = 0;
915 DBG(" Battery strength is.... %d", battery_strength);
917 /* get the current battery level */
918 for (x = 0; hfp_ag_ind[x].indicator_desc != NULL; x++) {
919 if (g_str_equal(hfp_ag_ind[x].indicator_desc, "battchg"))
920 bat_strength = hfp_ag_ind[x].hfp_value;
923 /* We need to send battery status ranging from 0-5 */
924 if (battery_strength < 5)
926 else if (battery_strength >= 100)
929 change_value = battery_strength / 20 + 1;
931 if (bat_strength == change_value) {
932 DBG("no change in battery strength");
936 if (__bt_hfp_modify_indicator("battchg",
937 change_value) == BT_HFP_AGENT_ERROR_NONE)
943 static int __bt_hfp_update_signal_strength(int32_t signal_strength_bars)
945 if (signal_strength_bars < 0)
946 signal_strength_bars = 0;
947 else if (signal_strength_bars > 5)
948 signal_strength_bars = 5;
950 if (network_info.signal_strength == signal_strength_bars) {
951 DBG("no change in signal strength");
955 network_info.signal_strength = signal_strength_bars;
957 if (__bt_hfp_modify_indicator("signal",
958 signal_strength_bars) == BT_HFP_AGENT_ERROR_NONE)
964 static int __bt_hfp_update_registration_status(uint8_t register_status)
966 bt_hfp_agent_error_t reg_ret = BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
968 DBG("Updating registration status to.... %d", register_status);
970 if (network_info.network_status == register_status) {
971 DBG("No change in registration status");
975 if (register_status == BT_AGENT_NETWORK_REG_STATUS_ROAMING) {
976 reg_ret = __bt_hfp_modify_indicator("roam",
977 INDICATOR_EVENT_ROAM_ACTIVE);
979 if (network_info.network_status >
980 BT_AGENT_NETWORK_REG_STATUS_ROAMING)
981 reg_ret = __bt_hfp_modify_indicator("service",
982 INDICATOR_EVENT_SERVICE_PRESENT);
983 } else if (register_status == BT_AGENT_NETWORK_REG_STATUS_HOME) {
984 reg_ret = __bt_hfp_modify_indicator("roam",
985 INDICATOR_EVENT_ROAM_INACTIVE);
987 if (network_info.network_status >
988 BT_AGENT_NETWORK_REG_STATUS_ROAMING)
989 reg_ret = __bt_hfp_modify_indicator("service",
990 INDICATOR_EVENT_SERVICE_PRESENT);
991 } else if (register_status == BT_AGENT_NETWORK_REG_STATUS_OFFLINE ||
992 register_status == BT_AGENT_NETWORK_REG_STATUS_SEARCHING ||
993 register_status == BT_AGENT_NETWORK_REG_STATUS_NO_SIM ||
994 register_status == BT_AGENT_NETWORK_REG_STATUS_POWEROFF ||
995 register_status == BT_AGENT_NETWORK_REG_STATUS_POWERSAFE ||
996 register_status == BT_AGENT_NETWORK_REG_STATUS_NO_COVERAGE ||
997 register_status == BT_AGENT_NETWORK_REG_STATUS_REJECTED ||
998 register_status == BT_AGENT_NETWORK_REG_STATUS_UNKOWN) {
999 if (network_info.network_status <
1000 BT_AGENT_NETWORK_REG_STATUS_OFFLINE)
1001 reg_ret = __bt_hfp_modify_indicator("service",
1002 INDICATOR_EVENT_SERVICE_NONE);
1005 network_info.network_status = register_status;
1006 if (reg_ret == BT_HFP_AGENT_ERROR_NONE)
1012 int _bt_hfp_set_property_value(const char *property, int value)
1016 DBG("Property is %s", property);
1018 if (g_str_equal("RegistrationChanged", property))
1019 ret = __bt_hfp_update_registration_status(value);
1021 else if (g_str_equal("SignalBarsChanged", property))
1022 ret = __bt_hfp_update_signal_strength(value);
1024 else if (g_str_equal("BatteryBarsChanged", property))
1025 ret = __bt_hfp_update_battery_strength(value);
1030 int _bt_hfp_set_property_name(const char *property, const char *operator_name)
1034 if (operator_name == NULL)
1037 if (g_str_equal("OperatorNameChanged", property)) {
1038 g_free(network_info.network_operator_name);
1039 network_info.network_operator_name =
1040 g_strndup(operator_name, 16);
1044 if (g_str_equal("SubscriberNumberChanged", property)) {
1045 g_free(ag_subscriber_num);
1046 ag_subscriber_num = g_strdup(operator_name);
1047 DBG("HFP: subscriber_number updated: %s", ag_subscriber_num);
1053 static int __bt_hfp_answer_call(struct telephony_call *t_call)
1055 if (t_call->call_id != 0 && t_call->call_path != NULL &&
1056 t_call->call_sender != NULL) {
1057 _bt_ag_agent_answer_call(t_call->call_id,
1059 t_call->call_sender);
1065 void _bt_hfp_answer_call_request(void *t_device)
1067 struct telephony_call *t_call;
1069 t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_COMING);
1072 t_call = __bt_hfp_get_call_with_status(
1073 HFP_CALL_STATUS_MT_ALERTING);
1076 t_call = __bt_hfp_get_call_with_status(
1077 HFP_CALL_STATUS_PROCEEDING);
1080 t_call = __bt_hfp_get_call_with_status(
1081 HFP_CALL_STATUS_WAITING);
1083 if (t_call == NULL) {
1084 _bt_answer_call_response(t_device,
1085 HFP_STATE_MNGR_ERR_NOT_ALLOWED);
1089 if (__bt_hfp_answer_call(t_call) < 0)
1090 _bt_answer_call_response(t_device,
1091 HFP_STATE_MNGR_ERR_AG_FAILURE);
1093 _bt_answer_call_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1097 void _bt_hfp_dial_number_request(const char *dial_number, void *t_device)
1099 int call_flag = caller_id;
1100 bt_hfp_agent_error_t error_code = 0;
1102 if (strncmp(dial_number, "#31#", 4) == 0) {
1103 dial_number = dial_number + 4;
1104 call_flag = ALLOW_CALL_FLAG;
1105 } else if (strncmp(dial_number, "*31#", 4) == 0) {
1106 dial_number = dial_number + 4;
1107 call_flag = RESTRAIN_CALL_FLAG;
1108 } else if (dial_number[0] == '>') {
1109 int dial_location = strtol(&dial_number[1], NULL, 0);
1111 error_code = _bt_ag_agent_dial_memory(dial_location);
1113 if (error_code == BT_HFP_AGENT_ERROR_NONE)
1114 _bt_dial_number_response(t_device,
1115 HFP_STATE_MNGR_ERR_NONE);
1117 _bt_dial_number_response(t_device,
1118 HFP_STATE_MNGR_ERR_AG_FAILURE);
1122 error_code = _bt_ag_agent_dial_num(dial_number, call_flag);
1124 if (error_code == BT_HFP_AGENT_ERROR_NONE) {
1125 _bt_dial_number_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1129 _bt_dial_number_response(t_device, HFP_STATE_MNGR_ERR_AG_FAILURE);
1133 void _bt_hfp_update_event_request(int indicator, void *t_device)
1136 update_events = TRUE;
1138 update_events = FALSE;
1140 _bt_event_reporting_response(t_device,
1141 HFP_STATE_MNGR_ERR_NONE);
1144 static int __bt_bt_hfp_reject_call(struct telephony_call *t_call)
1148 if (t_call != NULL) {
1149 DBG(" rejecting call from sender %s with call path %s and call id %d",
1150 t_call->call_sender,
1154 ret = _bt_ag_agent_reject_call(t_call->call_id,
1156 t_call->call_sender);
1164 static int __bt_hfp_release_call(struct telephony_call *t_call)
1166 gboolean ret = _bt_ag_agent_release_call(t_call->call_id,
1168 t_call->call_sender);
1175 static int __bt_hfp_release_conference(void)
1177 GSList *temp_list = existing_call_list;
1179 while (temp_list != NULL) {
1180 struct telephony_call *t_call = temp_list->data;
1182 if (t_call->call_conference)
1183 __bt_hfp_release_call(t_call);
1185 temp_list = temp_list->next;
1190 void _bt_hfp_terminate_call_request(void *t_device)
1192 struct telephony_call *t_call;
1193 struct telephony_call *t_alert = NULL;
1196 t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE);
1198 if (t_call == NULL) {
1199 DBG("Find non-idle call");
1200 GSList *temp_call_list = existing_call_list;
1201 while (temp_call_list != NULL) {
1202 t_call = temp_call_list->data;
1204 if (t_call->call_status == HFP_AGENT_CALL_IDLE)
1205 temp_call_list = temp_call_list->next;
1211 if (t_call == NULL) {
1212 DBG("Seems like there are no active calls. So do not allow the call");
1213 _bt_terminate_call_response(t_device,
1214 HFP_STATE_MNGR_ERR_NOT_ALLOWED);
1218 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_WAITING) != NULL) {
1220 t_error = _bt_ag_agent_threeway_call(value, t_call->call_path,
1221 t_call->call_sender);
1222 } else if ((t_alert = __bt_hfp_get_call_with_status(
1223 HFP_CALL_STATUS_CREATE))
1225 t_error = __bt_bt_hfp_reject_call(t_alert);
1226 } else if ((t_alert = __bt_hfp_get_call_with_status(
1227 HFP_CALL_STATUS_MO_ALERTING))
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_COMING)) != NULL) {
1232 t_error = __bt_bt_hfp_reject_call(t_alert);
1233 } else if (t_call->call_conference)
1234 t_error = __bt_hfp_release_conference();
1236 t_error = __bt_hfp_release_call(t_call);
1239 _bt_terminate_call_response(t_device,
1240 HFP_STATE_MNGR_ERR_AG_FAILURE);
1242 _bt_terminate_call_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1245 void _bt_hfp_call_hold_request(const char *t_cmd, void *t_device)
1248 struct telephony_call *t_call = NULL;
1249 GSList *t_sender_list = call_senders_paths;
1250 sender_info_t *sender_info = NULL;
1251 uint32_t t_chld_value;
1253 t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE);
1254 if (t_call == NULL) {
1256 __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD))
1258 if ((t_call = __bt_hfp_get_call_with_status(
1259 HFP_CALL_STATUS_WAITING)) == NULL) {
1260 /* means there is no outgoing call*/
1261 _bt_call_hold_response(t_device,
1262 HFP_STATE_MNGR_ERR_AG_FAILURE);
1268 while (t_sender_list != NULL) {
1269 sender_info = t_sender_list->data;
1270 if (sender_info == NULL) {
1271 _bt_call_hold_response(t_device,
1272 HFP_STATE_MNGR_ERR_AG_FAILURE);
1275 if (g_strcmp0(t_call->call_path, sender_info->sender_path)
1279 t_sender_list = t_sender_list->next;
1282 t_chld_value = strtoul(&t_cmd[0], NULL, 0);
1283 gboolean ret = _bt_ag_agent_threeway_call(t_chld_value,
1285 t_call->call_sender);
1288 _bt_call_hold_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1290 _bt_call_hold_response(t_device, HFP_STATE_MNGR_ERR_AG_FAILURE);
1294 void _bt_hfp_key_press_request(const char *t_key_press, void *t_device)
1296 struct telephony_call *t_active_call;
1297 struct telephony_call *t_waiting_call;
1300 t_waiting_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_COMING);
1302 if (t_waiting_call == NULL)
1303 t_waiting_call = __bt_hfp_get_call_with_status(
1304 HFP_CALL_STATUS_MT_ALERTING);
1306 if (t_waiting_call == NULL)
1307 t_waiting_call = __bt_hfp_get_call_with_status(
1308 HFP_CALL_STATUS_PROCEEDING);
1310 t_active_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE);
1313 if (t_waiting_call != NULL)
1314 t_error = __bt_hfp_answer_call(t_waiting_call);
1315 else if (t_active_call != NULL)
1316 t_error = __bt_hfp_release_call(t_active_call);
1318 if (_bt_ag_agent_dial_last_num(t_device) !=
1319 BT_HFP_AGENT_ERROR_NONE)
1320 _bt_dial_number_response(t_device,
1321 HFP_STATE_MNGR_ERR_AG_FAILURE);
1323 _bt_dial_number_response(t_device,
1324 HFP_STATE_MNGR_ERR_NONE);
1329 _bt_key_press_response(t_device,
1330 HFP_STATE_MNGR_ERR_AG_FAILURE);
1332 _bt_key_press_response(t_device,
1333 HFP_STATE_MNGR_ERR_NONE);
1336 void _bt_hfp_last_dialed_number_request(void *t_device)
1338 bt_hfp_agent_error_t error = _bt_ag_agent_dial_last_num(t_device);
1340 if (error != BT_HFP_AGENT_ERROR_NONE)
1341 _bt_dial_number_response(t_device,
1342 HFP_STATE_MNGR_ERR_AG_FAILURE);
1344 _bt_dial_number_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1347 void _bt_hfp_channel_dtmf_request(char t_tone, void *t_device)
1349 char buf[2] = { t_tone, '\0' };
1350 char *tone_buffer = buf;
1352 struct telephony_call *t_call = __bt_hfp_get_call_with_status(
1353 HFP_CALL_STATUS_ACTIVE);
1354 if (t_call == NULL) {
1355 t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD);
1356 if (t_call == NULL) {
1357 t_call = __bt_hfp_get_call_with_status(
1358 HFP_CALL_STATUS_WAITING);
1359 if (t_call == NULL) {
1360 /* if this point is reached,
1361 it means there is no ongoing call */
1362 _bt_transmit_dtmf_response(t_device,
1363 HFP_STATE_MNGR_ERR_AG_FAILURE);
1369 if (_bt_ag_agent_send_dtmf(tone_buffer, t_call->call_path,
1370 t_call->call_sender) != BT_HFP_AGENT_ERROR_NONE) {
1371 _bt_transmit_dtmf_response(t_device,
1372 HFP_STATE_MNGR_ERR_AG_FAILURE);
1376 _bt_transmit_dtmf_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1379 void _bt_hfp_vendor_cmd_request(const char *cmd,
1382 GSList *t_sender_list = call_senders_paths;
1383 sender_info_t *sender_info = NULL;
1385 bt_hfp_agent_error_t error = BT_HFP_AGENT_ERROR_NONE;
1387 if (NULL != t_sender_list) {
1388 for (l = t_sender_list; l != NULL; l = l->next) {
1389 sender_info = l->data;
1390 error = _bt_ag_agent_vendor_cmd(cmd,
1391 sender_info->sender_path,
1392 sender_info->sender_name);
1393 if (error != BT_HFP_AGENT_ERROR_NONE)
1398 if (error != BT_HFP_AGENT_ERROR_NONE)
1399 _bt_vendor_cmd_response(t_device,
1400 HFP_STATE_MNGR_ERR_AG_FAILURE);
1402 _bt_vendor_cmd_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1405 void _bt_hfp_subscriber_number_request(void *t_device)
1407 if (ag_subscriber_num != NULL) {
1409 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
1411 if (ag_subscriber_num[0] == '+' || strncmp(
1412 ag_subscriber_num, "00", 2) == 0)
1413 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
1415 _bt_subscriber_number_indicator(ag_subscriber_num,
1416 t_number, AGENT_SUBSCRIBER_SERVICE_VOICE);
1419 _bt_subscriber_number_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1422 static int __bt_hfp_get_call_status(struct telephony_call *t_call)
1424 switch (t_call->call_status) {
1425 case HFP_CALL_STATUS_IDLE:
1426 case HFP_CALL_STATUS_MO_RELEASE:
1427 case HFP_CALL_STATUS_MT_RELEASE:
1428 case HFP_CALL_STATUS_TERMINATED:
1431 case HFP_CALL_STATUS_ANSWERED:
1432 case HFP_CALL_STATUS_ACTIVE:
1433 case HFP_CALL_STATUS_RECONNECT_PENDING:
1434 case HFP_CALL_STATUS_SWAP_INITIATED:
1435 case HFP_CALL_STATUS_HOLD_INITIATED:
1436 return AGENT_CALL_STATUS_ACTIVE;
1438 case HFP_CALL_STATUS_RETRIEVE_INITIATED:
1439 case HFP_CALL_STATUS_HOLD:
1440 return AGENT_CALL_STATUS_HELD;
1442 case HFP_CALL_STATUS_WAITING:
1443 return AGENT_CALL_STATUS_WAITING;
1445 case HFP_CALL_STATUS_CREATE:
1446 return AGENT_CALL_STATUS_DIALING;
1448 case HFP_CALL_STATUS_PROCEEDING:
1449 if (t_call->call_originating)
1450 return AGENT_CALL_STATUS_DIALING;
1451 if (g_slist_length(agent_active_call_list) > 0)
1452 return AGENT_CALL_STATUS_WAITING;
1454 return AGENT_CALL_STATUS_INCOMING;
1456 case HFP_CALL_STATUS_COMING:
1457 if (g_slist_length(agent_active_call_list) > 0)
1458 return AGENT_CALL_STATUS_WAITING;
1460 return AGENT_CALL_STATUS_INCOMING;
1462 case HFP_CALL_STATUS_MO_ALERTING:
1463 return AGENT_CALL_STATUS_ALERTING;
1465 case HFP_CALL_STATUS_MT_ALERTING:
1466 return AGENT_CALL_STATUS_INCOMING;
1473 void _bt_list_current_calls(void *t_device)
1475 GSList *t_call_list = existing_call_list;
1477 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
1478 int t_direction, t_call_conference;
1481 while (t_call_list != NULL) {
1482 struct telephony_call *t_call = t_call_list->data;
1483 t_status = __bt_hfp_get_call_status(t_call);
1484 if (t_status >= 0) {
1485 if (t_call->call_originating != TRUE)
1486 t_direction = AGENT_CALL_DIRECTION_INCOMING;
1488 t_direction = AGENT_CALL_DIRECTION_OUTGOING;
1490 if (t_call->call_conference != TRUE)
1491 t_call_conference = AGENT_CALL_MULTIPARTY_NO;
1493 t_call_conference = AGENT_CALL_MULTIPARTY_YES;
1495 if (t_call->call_number == NULL) {
1496 t_number = AGENT_NUMBER_TYPE_TELEPHONY;
1498 if (t_call->call_number[0] == '+' || strncmp(
1499 t_call->call_number, "00", 2) == 0)
1500 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
1503 index = t_call->call_id;
1504 _bt_list_current_call_indicator(t_device, index, t_direction,
1505 AGENT_CALL_MODE_VOICE,
1507 t_call->call_number,
1511 t_call_list = t_call_list->next;
1513 _bt_list_current_calls_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1516 void _bt_hfp_release_all_calls_by_sender(const char *sender)
1518 GSList *temp_list = existing_call_list;
1524 DBG("sender [%s]", sender);
1526 while (temp_list != NULL) {
1527 struct telephony_call *t_call = temp_list->data;
1529 if (g_strcmp0(t_call->call_sender, sender) == 0) {
1530 INFO("terminate call[%d]", t_call->call_id);
1531 next_list = temp_list->next;
1532 __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_MT_RELEASE);
1533 temp_list = next_list;
1535 temp_list = temp_list->next;
1539 void _bt_hfp_noise_red_and_echo_cancel_request(gboolean t_enable,
1542 if (_bt_hfp_agent_nrec_status(t_enable, t_device) == TRUE)
1543 _bt_nr_and_ec_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1545 _bt_nr_and_ec_response(t_device, HFP_STATE_MNGR_ERR_AG_FAILURE);
1550 void _bt_hfp_voice_dial_request(gboolean t_enable, void *t_device)
1552 gboolean ret = FALSE;
1555 if (vconf_get_int(VCONFKEY_CALL_STATE, &call_state) < 0)
1556 ERR("vconf_get_int is failed");
1558 if ((t_enable == TRUE && call_state == 0) || t_enable == FALSE)
1559 ret = _bt_ag_agent_voice_dial(t_enable);
1562 _bt_voice_dial_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1564 _bt_voice_dial_response(t_device,
1565 HFP_STATE_MNGR_ERR_AG_FAILURE);
1570 void _bt_hfp_set_indicators(const char *t_command, void *t_device)
1572 const char delims = ',';
1575 if (t_command == NULL)
1578 str = strchr(t_command, '=');
1579 while (hfp_ag_ind[i].indicator_desc != NULL && str != NULL) {
1582 if ((g_strcmp0(hfp_ag_ind[i].indicator_desc, "call") != 0) &&
1583 (g_strcmp0(hfp_ag_ind[i].indicator_desc, "callheld") != 0) &&
1584 (g_strcmp0(hfp_ag_ind[i].indicator_desc, "callsetup") != 0)) {
1587 hfp_ag_ind[i].is_activated = FALSE;
1588 } else if (*str == '1') {
1589 hfp_ag_ind[i].is_activated = TRUE;
1591 DBG(" no change in is_activated for[%s]\n",
1592 hfp_ag_ind[i].indicator_desc);
1595 str = strchr(str, delims);
1599 _bt_indicators_activation_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1603 _bt_indicators_activation_response(t_device,
1604 HFP_STATE_MNGR_ERR_INVALID_CHAR_IN_STRING);
1608 static int __bt_hfp_get_phonebook_count(const char *path, uint32_t *max_size,
1611 #ifndef TIZEN_PROFILE_WEARABLE
1612 GDBusConnection *g_conn;
1613 GDBusProxy *g_proxy;
1615 GVariant *ret = NULL;
1619 g_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1623 ERR("Unable to connect to gdbus: %s", err->message);
1624 g_clear_error(&err);
1629 g_proxy = g_dbus_proxy_new_sync(g_conn,
1630 G_DBUS_PROXY_FLAGS_NONE, NULL,
1631 PHONEBOOK_AGENT_BUS_NAME, PHONEBOOK_AGENT_PATH,
1632 PHONEBOOK_AGENT_INTERFACE, NULL, &err);
1636 ERR("Unable to connect to gdbus: %s", err->message);
1637 g_clear_error(&err);
1642 ret = g_dbus_proxy_call_sync(g_proxy, "GetPhonebookSizeAt",
1643 g_variant_new("(s)",
1645 G_DBUS_CALL_FLAGS_NONE, -1,
1649 ERR("dbus call failed");
1651 ERR("D-Bus API failure: errCode[%x], message[%s]",
1652 err->code, err->message);
1654 g_clear_error(&err);
1658 g_variant_get(ret, "(u)", &size);
1659 g_variant_unref(ret);
1661 DBG("Size returned %d", size);
1662 if ((g_strcmp0(path, "\"SM\"") == 0) ||
1663 (g_strcmp0(path, "\"ME\"") == 0)) {
1664 max = AGENT_MAX_PB_COUNT;
1665 } else if ((g_strcmp0(path, "\"DC\"") == 0) ||
1666 (g_strcmp0(path, "\"MC\"") == 0) ||
1667 (g_strcmp0(path, "\"RC\"") == 0)) {
1668 max = AGENT_MAX_CALLLOG_COUNT;
1681 g_object_unref(g_conn);
1683 g_object_unref(g_proxy);
1688 void _bt_hfp_select_phonebook_memory_status(void *t_device)
1690 int32_t path_id = ag_pb_info.path_id;
1692 uint32_t max_size = 0;
1694 hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1696 if (path_id < 0 || path_id >= AGENT_PB_STORE_LIST_SIZE)
1699 if (__bt_hfp_get_phonebook_count(agent_pb_store_list[path_id],
1701 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1703 _bt_select_phonebook_memory_status_response(t_device,
1704 agent_pb_store_list[path_id],
1709 static char *__bt_hfp_get_supported_list(const char *char_list[],
1716 if (char_list == NULL || size == 0)
1719 strng = g_string_new("(");
1721 while (index < size) {
1723 g_string_append(strng, ",");
1725 g_string_append(strng, char_list[index]);
1729 g_string_append(strng, ")");
1731 return g_string_free(strng, FALSE);
1734 void _bt_hfp_select_phonebook_memory_list(void *t_device)
1738 str = __bt_hfp_get_supported_list(agent_pb_store_list,
1739 AGENT_PB_STORE_LIST_SIZE);
1741 _bt_select_phonebook_memory_list_response(t_device,
1742 str, HFP_STATE_MNGR_ERR_NONE);
1747 void _bt_hfp_select_phonebook_memory(void *t_device, const gchar *pb_path)
1750 hfp_state_manager_err_t err;
1752 while (i < AGENT_PB_STORE_LIST_SIZE) {
1753 if (strcmp(agent_pb_store_list[i], pb_path) == 0)
1758 if (i >= 0 && i < AGENT_PB_STORE_LIST_SIZE) {
1759 err = HFP_STATE_MNGR_ERR_NONE;
1760 ag_pb_info.path_id = i;
1762 err = HFP_STATE_MNGR_ERR_INVALID_CHAR_IN_STRING;
1764 _bt_select_phonebook_memory_response(t_device, err);
1767 void _bt_hfp_read_phonebook_entries_list(void *t_device)
1769 hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1771 int32_t path_id = ag_pb_info.path_id;
1774 if (path_id < 0 || path_id >= AGENT_PB_STORE_LIST_SIZE)
1775 err = HFP_STATE_MNGR_ERR_INVALID_INDEX;
1777 if (__bt_hfp_get_phonebook_count(agent_pb_store_list[path_id],
1778 NULL, &used) != 0) {
1779 err = HFP_STATE_MNGR_ERR_NOT_ALLOWED;
1783 _bt_read_phonebook_entries_list_response(t_device, used,
1784 AGENT_PB_NUMBER_MAX_LENGTH, AGENT_PB_NAME_MAX_LENGTH,
1788 static int __bt_hfp_get_phonebook_entries(int start_index, int end_index)
1790 #ifdef TIZEN_PROFILE_WEARABLE
1793 GDBusConnection *g_conn;
1794 GDBusProxy *g_proxy;
1796 GVariant *ret = NULL;
1798 GVariant *value = NULL;
1799 GVariant *tuple = NULL;
1800 const char *name = NULL;
1801 const char *number = NULL;
1806 uint32_t handle = 0;
1808 g_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1812 ERR("Unable to connect to gdbus: %s", err->message);
1813 g_clear_error(&err);
1818 g_proxy = g_dbus_proxy_new_sync(g_conn,
1819 G_DBUS_PROXY_FLAGS_NONE, NULL,
1820 PHONEBOOK_AGENT_BUS_NAME, PHONEBOOK_AGENT_PATH,
1821 PHONEBOOK_AGENT_INTERFACE, NULL, &err);
1824 ERR("Unable to connect to gdbus: %s", err->message);
1825 g_clear_error(&err);
1830 ret = g_dbus_proxy_call_sync(g_proxy, "GetPhonebookEntriesAt",
1831 g_variant_new("(sii)",
1832 agent_pb_store_list[ag_pb_info.path_id],
1833 start_index, end_index),
1834 G_DBUS_CALL_FLAGS_NONE, -1,
1838 ERR("Dbus call failed");
1840 ERR("D-Bus API failure: errCode[%x], message[%s]",
1841 err->code, err->message);
1843 g_clear_error(&err);
1845 ERR("error returned was NULL");
1849 tuple = g_variant_get_child_value(ret, 0);
1850 if (tuple != NULL) {
1851 int number_contacts = g_variant_n_children(tuple);
1852 DBG("number of contacts %d", number_contacts);
1853 while (count < number_contacts) {
1856 value = g_variant_get_child_value(tuple, count);
1858 g_variant_get(value, "(ssu)", &name, &number, &handle);
1860 uni_name = g_strndup(name, AGENT_PB_NAME_MAX_LENGTH);
1861 uni_number = g_strndup(number, AGENT_PB_NAME_MAX_LENGTH);
1863 _bt_read_phonebook_entries_indicator(uni_name,
1864 uni_number, handle);
1865 g_variant_unref(value);
1868 g_free((gpointer)name);
1869 g_free((gpointer)number);
1871 g_variant_unref(tuple);
1874 g_variant_unref(ret);
1876 g_object_unref(g_conn);
1878 g_object_unref(g_proxy);
1883 void _bt_hfp_read_phonebook_entries(void *t_device, const char *cmd)
1885 int start_index = 0;
1893 hfp_state_manager_err_t err;
1898 str = g_strdup(cmd);
1899 next = strchr(str, ',');
1905 end_index = strtol(next, NULL, 10);
1908 start_index = strtol(str, NULL, 10);
1912 count = __bt_hfp_get_phonebook_entries(start_index, end_index);
1915 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1916 else if (count == 0)
1917 err = HFP_STATE_MNGR_ERR_INVALID_INDEX;
1919 err = HFP_STATE_MNGR_ERR_NONE;
1921 _bt_read_phonebook_entries_response(t_device, err);
1924 void _bt_hfp_find_phonebook_entries_status(void *t_device)
1926 _bt_find_phonebook_entries_status_indicator(
1927 AGENT_PB_NUMBER_MAX_LENGTH,
1928 AGENT_PB_NAME_MAX_LENGTH);
1930 _bt_find_phonebook_entries_status_response(t_device,
1931 HFP_STATE_MNGR_ERR_NONE);
1934 static int __bt_hfp_find_pb_entries(const char *str)
1939 void _bt_hfp_find_phonebook_entries(void *t_device, const char *cmd)
1942 gchar *unquoted = NULL;
1944 hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1946 /* remove quote and compress */
1947 st = strchr(cmd, '"');
1949 unquoted = g_strdup(cmd);
1953 end = strrchr(cmd, '"');
1955 unquoted = g_strdup(cmd);
1957 unquoted = g_strndup(st + 1, end - st - 1);
1960 if (__bt_hfp_find_pb_entries(unquoted))
1961 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1963 _bt_find_phonebook_entries_response(t_device, err);
1968 void _bt_hfp_get_character_set(void *t_device)
1970 _bt_supported_character_generic_response(t_device,
1971 (char *)agent_supported_character_set[ag_pb_info.charset_id],
1972 HFP_STATE_MNGR_ERR_NONE);
1975 void _bt_hfp_list_supported_character(void *t_device)
1979 str = __bt_hfp_get_supported_list(agent_supported_character_set,
1980 AGENT_SUPPORTED_CHARACTER_SET_SIZE);
1982 _bt_supported_character_generic_response(t_device,
1983 str, HFP_STATE_MNGR_ERR_NONE);
1988 void _bt_hfp_set_character_set(void *t_device, const char *cmd)
1992 while (index < AGENT_SUPPORTED_CHARACTER_SET_SIZE) {
1993 if (strcmp(agent_supported_character_set[index], cmd) == 0) {
1994 _bt_set_characterset_generic_response(t_device,
1995 HFP_STATE_MNGR_ERR_NONE);
1997 ag_pb_info.charset_id = index;
2003 _bt_set_characterset_generic_response(t_device,
2004 HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
2008 void _bt_hfp_signal_quality_reply(int32_t rssi, int32_t ber,
2011 DBG("signal_quality_reply");
2013 if (rssi == -1 && ber == -1) {
2014 _bt_signal_quality_response(t_device, rssi, ber,
2015 HFP_STATE_MNGR_ERR_AG_FAILURE);
2017 _bt_signal_quality_response(t_device, rssi, ber,
2018 HFP_STATE_MNGR_ERR_NONE);
2022 void _bt_hfp_battery_property_reply(void *data, int32_t bcs,
2025 if (bcs == -1 || bcl == -1) {
2026 _bt_battery_charge_status_response(data, bcs,
2027 bcl, HFP_STATE_MNGR_ERR_AG_FAILURE);
2029 _bt_battery_charge_status_response(data, bcs,
2030 bcl, HFP_STATE_MNGR_ERR_NONE);
2036 void _bt_hfp_get_battery_property(void *t_device)
2038 _bt_ag_agent_get_battery_status(t_device);
2041 void _bt_hfp_operator_reply(char *operator_name, void *t_device)
2043 if (operator_name == NULL)
2046 network_info.network_operator_name = g_strndup(operator_name, 16);
2048 _bt_operator_selection_indicator(AGENT_OPERATOR_MODE_AUTO,
2050 _bt_operator_selection_response(t_device, HFP_STATE_MNGR_ERR_NONE);
2054 _bt_operator_selection_indicator(AGENT_OPERATOR_MODE_AUTO, "UNKNOWN");
2055 _bt_operator_selection_response(t_device,
2056 HFP_STATE_MNGR_ERR_AG_FAILURE);
2059 void _bt_hfp_get_operator_selection_request(void *t_device)
2061 _bt_ag_agent_get_operator_name(t_device);
2064 void _bt_hfp_response_and_hold_request(void *t_device)
2066 _bt_response_and_hold_response(t_device,
2067 HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
2070 void _bt_get_activity_status(void *t_device)
2072 DBG("telephony-tizen: telephony_get_activity_status");
2074 if (NULL != (__bt_hfp_get_call_with_status(
2075 HFP_CALL_STATUS_MT_ALERTING)) ||
2076 NULL != (__bt_hfp_get_call_with_status(
2077 HFP_CALL_STATUS_MO_ALERTING)) ||
2078 NULL != (__bt_hfp_get_call_with_status(
2079 HFP_CALL_STATUS_COMING)) ||
2080 NULL != (__bt_hfp_get_call_with_status(
2081 HFP_CALL_STATUS_CREATE)))
2082 _bt_hfp_get_activity_status_rsp(t_device,
2083 HFP_AGENT_ACTIVITY_STATUS_RINGING,
2084 HFP_STATE_MNGR_ERR_NONE);
2085 else if (NULL != (__bt_hfp_get_call_with_status(
2086 HFP_CALL_STATUS_WAITING)) ||
2087 NULL != (__bt_hfp_get_call_with_status(
2088 HFP_CALL_STATUS_ACTIVE)))
2089 _bt_hfp_get_activity_status_rsp(t_device,
2090 HFP_AGENT_ACTIVITY_STATUS_CALL_IN_PROGRESS,
2091 HFP_STATE_MNGR_ERR_NONE);
2093 _bt_hfp_get_activity_status_rsp(t_device,
2094 HFP_AGENT_ACTIVITY_STATUS_READY,
2095 HFP_STATE_MNGR_ERR_NONE);
2098 void _bt_hfp_get_imei_number_reply(char *imei_number, void *t_device)
2100 _bt_hfp_get_equipment_identity_rsp(t_device, imei_number,
2101 HFP_STATE_MNGR_ERR_NONE);
2104 void _bt_hfp_get_imsi_reply(char *mcc, char *mnc, char *msin, void *t_device)
2106 if (mcc != NULL && mnc != NULL && msin != NULL)
2107 _bt_hfp_get_imsi_rsp(t_device, mcc, mnc, msin,
2108 HFP_STATE_MNGR_ERR_NONE);
2110 _bt_hfp_get_imsi_rsp(t_device, NULL, NULL, NULL,
2111 HFP_STATE_MNGR_ERR_NOT_ALLOWED);
2114 void _bt_hfp_get_creg_status_reply(int n, int status, void *t_device)
2116 _bt_hfp_get_creg_status_rsp(t_device, n, status,
2117 HFP_STATE_MNGR_ERR_NONE);
2120 void _bt_hfp_get_equipment_identity_req(void *t_device)
2122 _bt_ag_agent_get_imei_number(t_device);
2125 void _bt_hfp_get_model_info_reply(char *model, void *t_device)
2127 _bt_hfp_get_model_info_rsp(t_device, model,
2128 HFP_STATE_MNGR_ERR_NONE);
2131 void _bt_hfp_get_model_info_req(void *t_device)
2133 _bt_ag_agent_get_model_name(t_device);
2136 void _bt_hfp_get_device_manufacturer_reply(char *manufacturer, void *t_device)
2138 _bt_hfp_get_device_manufacturer_rsp(t_device, manufacturer,
2139 HFP_STATE_MNGR_ERR_NONE);
2142 void _bt_hfp_get_device_manufacturer_req(void *t_device)
2144 _bt_ag_agent_get_manufacturer_name(t_device);
2147 void _bt_hfp_get_imsi_req(void *t_device)
2149 _bt_ag_agent_get_imsi(t_device);
2152 void _bt_hfp_get_creg_status_req(void *t_device)
2154 _bt_ag_agent_get_creg_status(t_device);
2157 void _bt_hfp_get_revision_info_reply(char *revision, void *t_device)
2159 _bt_hfp_get_revision_info_rsp(t_device, revision,
2160 HFP_STATE_MNGR_ERR_NONE);
2163 void _bt_hfp_get_revision_info_req(void *t_device)
2165 _bt_ag_agent_get_revision_information(t_device);