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)
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)
551 t_held_call->call_conference = TRUE;
552 t_call->call_conference = TRUE;
557 if (t_held_call_count == 1) {
558 if (t_held_call->call_conference)
559 t_held_call->call_conference = FALSE;
562 if (t_active_call_count == 1) {
563 if (t_active_call->call_conference)
564 t_active_call->call_conference = FALSE;
568 static gboolean __bt_hfp_on_call_hold_timeout(gpointer t_data)
572 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD)) {
573 if (__bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE))
574 status = INDICATOR_EVENT_CALLHELD_MULTIPLE;
576 status = INDICATOR_EVENT_CALLHELD_ON_HOLD;
578 status = INDICATOR_EVENT_CALLHELD_NONE;
581 __bt_hfp_modify_indicator("callheld", status);
583 call_on_hold_timer = 0;
587 static void __bt_hfp_handle_call_on_hold_request(void)
589 DBG(" Starting the timer for call on hold");
590 if (call_on_hold_timer)
591 g_source_remove(call_on_hold_timer);
593 call_on_hold_timer = g_timeout_add(250, __bt_hfp_on_call_hold_timeout,
595 DBG(" returning from the timer call");
598 static void __bt_hfp_set_call_status(struct telephony_call *t_call,
602 int org_status = t_call->call_status;
604 call_held = __bt_hfp_get_indicator_value(hfp_ag_ind, "callheld");
606 if (org_status == call_status) {
607 DBG("Ignore the CSD Call state change to existing state");
611 t_call->call_status = call_status;
613 DBG(" call status is %d", call_status);
615 switch (call_status) {
616 case HFP_CALL_STATUS_IDLE:
617 if (t_call->call_setup) {
618 __bt_hfp_modify_indicator("callsetup",
619 INDICATOR_EVENT_CALLSETUP_INACTIVE);
620 if (!t_call->call_originating)
621 _bt_calling_stopped_indicator();
624 g_free(t_call->call_number);
625 t_call->call_number = NULL;
626 t_call->call_originating = FALSE;
627 t_call->call_emergency = FALSE;
628 t_call->call_on_hold = FALSE;
629 t_call->call_conference = FALSE;
630 t_call->call_setup = FALSE;
633 case HFP_CALL_STATUS_COMING:
634 t_call->call_originating = FALSE;
635 t_call->call_setup = TRUE;
636 __bt_hfp_modify_indicator("callsetup",
637 INDICATOR_EVENT_CALLSETUP_INCOMING);
640 case HFP_CALL_STATUS_CREATE:
641 t_call->call_originating = TRUE;
642 t_call->call_setup = TRUE;
645 case HFP_CALL_STATUS_MO_ALERTING:
646 __bt_hfp_modify_indicator("callsetup",
647 INDICATOR_EVENT_CALLSETUP_ALERTING);
650 case HFP_CALL_STATUS_MT_ALERTING: {
651 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
653 if (t_call->call_number == NULL) {
654 t_number = AGENT_NUMBER_TYPE_TELEPHONY;
656 if (t_call->call_number[0] == '+' ||
657 strncmp(t_call->call_number, "00", 2) == 0)
658 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
661 if (org_status == HFP_CALL_STATUS_WAITING)
662 _bt_incoming_call_indicator(t_call->call_number,
667 case HFP_CALL_STATUS_ACTIVE:
668 DBG(" This is an Active call");
669 if (t_call->call_on_hold) {
670 t_call->call_on_hold = FALSE;
671 __bt_hfp_handle_call_on_hold_request();
673 if (!g_slist_find(agent_active_call_list, t_call)) {
674 DBG(" This call is not in the active call list. So Add it to the list.\n");
675 agent_active_call_list =
676 g_slist_prepend(agent_active_call_list,
679 if (g_slist_length(agent_active_call_list) == 1) {
680 DBG(" Update indicator to show the call presence.\n");
681 __bt_hfp_modify_indicator("call",
682 INDICATOR_EVENT_CALL_ACTIVE);
685 __bt_hfp_modify_indicator("callsetup",
686 INDICATOR_EVENT_CALLSETUP_INACTIVE);
687 __bt_hfp_handle_call_on_hold_request();
689 if (!t_call->call_originating)
690 _bt_calling_stopped_indicator();
692 t_call->call_setup = FALSE;
696 case HFP_CALL_STATUS_MO_RELEASE:
697 case HFP_CALL_STATUS_MT_RELEASE:
698 agent_active_call_list = g_slist_remove(agent_active_call_list,
700 if (g_slist_length(agent_active_call_list) == 0)
701 __bt_hfp_modify_indicator("call",
702 INDICATOR_EVENT_CALL_INACTIVE);
704 if (org_status == HFP_CALL_STATUS_HOLD) {
705 __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);
1298 void _bt_hfp_key_press_request(const char *t_key_press, void *t_device)
1300 struct telephony_call *t_active_call;
1301 struct telephony_call *t_waiting_call;
1304 t_waiting_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_COMING);
1306 if (t_waiting_call == NULL)
1307 t_waiting_call = __bt_hfp_get_call_with_status(
1308 HFP_CALL_STATUS_MT_ALERTING);
1310 if (t_waiting_call == NULL)
1311 t_waiting_call = __bt_hfp_get_call_with_status(
1312 HFP_CALL_STATUS_PROCEEDING);
1314 t_active_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_ACTIVE);
1317 if (t_waiting_call != NULL)
1318 t_error = __bt_hfp_answer_call(t_waiting_call);
1319 else if (t_active_call != NULL)
1320 t_error = __bt_hfp_release_call(t_active_call);
1322 if (_bt_ag_agent_dial_last_num(t_device) !=
1323 BT_HFP_AGENT_ERROR_NONE)
1324 _bt_dial_number_response(t_device,
1325 HFP_STATE_MNGR_ERR_AG_FAILURE);
1327 _bt_dial_number_response(t_device,
1328 HFP_STATE_MNGR_ERR_NONE);
1333 _bt_key_press_response(t_device,
1334 HFP_STATE_MNGR_ERR_AG_FAILURE);
1336 _bt_key_press_response(t_device,
1337 HFP_STATE_MNGR_ERR_NONE);
1340 void _bt_hfp_last_dialed_number_request(void *t_device)
1342 bt_hfp_agent_error_t error = _bt_ag_agent_dial_last_num(t_device);
1344 if (error != BT_HFP_AGENT_ERROR_NONE)
1345 _bt_dial_number_response(t_device,
1346 HFP_STATE_MNGR_ERR_AG_FAILURE);
1348 _bt_dial_number_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1351 void _bt_hfp_channel_dtmf_request(char t_tone, void *t_device)
1353 char buf[2] = { t_tone, '\0' };
1354 char *tone_buffer = buf;
1356 struct telephony_call *t_call = __bt_hfp_get_call_with_status(
1357 HFP_CALL_STATUS_ACTIVE);
1358 if (t_call == NULL) {
1359 t_call = __bt_hfp_get_call_with_status(HFP_CALL_STATUS_HOLD);
1360 if (t_call == NULL) {
1361 t_call = __bt_hfp_get_call_with_status(
1362 HFP_CALL_STATUS_WAITING);
1363 if (t_call == NULL) {
1364 /* if this point is reached,
1365 it means there is no ongoing call */
1366 _bt_transmit_dtmf_response(t_device,
1367 HFP_STATE_MNGR_ERR_AG_FAILURE);
1373 if (_bt_ag_agent_send_dtmf(tone_buffer, t_call->call_path,
1374 t_call->call_sender) != BT_HFP_AGENT_ERROR_NONE) {
1375 _bt_transmit_dtmf_response(t_device,
1376 HFP_STATE_MNGR_ERR_AG_FAILURE);
1380 _bt_transmit_dtmf_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1383 void _bt_hfp_vendor_cmd_request(const char *cmd,
1386 GSList *t_sender_list = call_senders_paths;
1387 sender_info_t *sender_info = NULL;
1389 bt_hfp_agent_error_t error = BT_HFP_AGENT_ERROR_NONE;
1391 if (NULL != t_sender_list) {
1392 for (l = t_sender_list; l != NULL; l = l->next) {
1393 sender_info = l->data;
1394 error = _bt_ag_agent_vendor_cmd(cmd,
1395 sender_info->sender_path,
1396 sender_info->sender_name);
1397 if (error != BT_HFP_AGENT_ERROR_NONE)
1402 if (error != BT_HFP_AGENT_ERROR_NONE)
1403 _bt_vendor_cmd_response(t_device,
1404 HFP_STATE_MNGR_ERR_AG_FAILURE);
1406 _bt_vendor_cmd_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1409 void _bt_hfp_subscriber_number_request(void *t_device)
1411 if (ag_subscriber_num != NULL) {
1413 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
1415 if (ag_subscriber_num[0] == '+' || strncmp(
1416 ag_subscriber_num, "00", 2) == 0)
1417 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
1419 _bt_subscriber_number_indicator(ag_subscriber_num,
1420 t_number, AGENT_SUBSCRIBER_SERVICE_VOICE);
1423 _bt_subscriber_number_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1426 static int __bt_hfp_get_call_status(struct telephony_call *t_call)
1428 switch (t_call->call_status) {
1429 case HFP_CALL_STATUS_IDLE:
1430 case HFP_CALL_STATUS_MO_RELEASE:
1431 case HFP_CALL_STATUS_MT_RELEASE:
1432 case HFP_CALL_STATUS_TERMINATED:
1435 case HFP_CALL_STATUS_ANSWERED:
1436 case HFP_CALL_STATUS_ACTIVE:
1437 case HFP_CALL_STATUS_RECONNECT_PENDING:
1438 case HFP_CALL_STATUS_SWAP_INITIATED:
1439 case HFP_CALL_STATUS_HOLD_INITIATED:
1440 return AGENT_CALL_STATUS_ACTIVE;
1442 case HFP_CALL_STATUS_RETRIEVE_INITIATED:
1443 case HFP_CALL_STATUS_HOLD:
1444 return AGENT_CALL_STATUS_HELD;
1446 case HFP_CALL_STATUS_WAITING:
1447 return AGENT_CALL_STATUS_WAITING;
1449 case HFP_CALL_STATUS_CREATE:
1450 return AGENT_CALL_STATUS_DIALING;
1452 case HFP_CALL_STATUS_PROCEEDING:
1453 if (t_call->call_originating)
1454 return AGENT_CALL_STATUS_DIALING;
1455 if (g_slist_length(agent_active_call_list) > 0)
1456 return AGENT_CALL_STATUS_WAITING;
1458 return AGENT_CALL_STATUS_INCOMING;
1460 case HFP_CALL_STATUS_COMING:
1461 if (g_slist_length(agent_active_call_list) > 0)
1462 return AGENT_CALL_STATUS_WAITING;
1464 return AGENT_CALL_STATUS_INCOMING;
1466 case HFP_CALL_STATUS_MO_ALERTING:
1467 return AGENT_CALL_STATUS_ALERTING;
1469 case HFP_CALL_STATUS_MT_ALERTING:
1470 return AGENT_CALL_STATUS_INCOMING;
1477 void _bt_list_current_calls(void *t_device)
1479 GSList *t_call_list = existing_call_list;
1481 int t_number = AGENT_NUMBER_TYPE_TELEPHONY;
1482 int t_direction, t_call_conference;
1485 while (t_call_list != NULL) {
1486 struct telephony_call *t_call = t_call_list->data;
1487 t_status = __bt_hfp_get_call_status(t_call);
1488 if (t_status >= 0) {
1489 if (t_call->call_originating != TRUE)
1490 t_direction = AGENT_CALL_DIRECTION_INCOMING;
1492 t_direction = AGENT_CALL_DIRECTION_OUTGOING;
1494 if (t_call->call_conference != TRUE)
1495 t_call_conference = AGENT_CALL_MULTIPARTY_NO;
1497 t_call_conference = AGENT_CALL_MULTIPARTY_YES;
1499 if (t_call->call_number == NULL) {
1500 t_number = AGENT_NUMBER_TYPE_TELEPHONY;
1502 if (t_call->call_number[0] == '+' || strncmp(
1503 t_call->call_number, "00", 2) == 0)
1504 t_number = AGENT_NUMBER_TYPE_INTERNATIONAL;
1507 index = t_call->call_id;
1508 _bt_list_current_call_indicator(t_device, index, t_direction,
1509 AGENT_CALL_MODE_VOICE,
1511 t_call->call_number,
1515 t_call_list = t_call_list->next;
1517 _bt_list_current_calls_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1520 void _bt_hfp_release_all_calls_by_sender(const char *sender)
1522 GSList *temp_list = existing_call_list;
1528 DBG("sender [%s]", sender);
1530 while (temp_list != NULL) {
1531 struct telephony_call *t_call = temp_list->data;
1533 if (g_strcmp0(t_call->call_sender, sender) == 0) {
1534 INFO("terminate call[%d]", t_call->call_id);
1535 next_list = temp_list->next;
1536 __bt_hfp_set_call_status(t_call, HFP_CALL_STATUS_MT_RELEASE);
1537 temp_list = next_list;
1539 temp_list = temp_list->next;
1543 void _bt_hfp_noise_red_and_echo_cancel_request(gboolean t_enable,
1546 if (_bt_hfp_agent_nrec_status(t_enable, t_device) == TRUE)
1547 _bt_nr_and_ec_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1549 _bt_nr_and_ec_response(t_device, HFP_STATE_MNGR_ERR_AG_FAILURE);
1554 void _bt_hfp_voice_dial_request(gboolean t_enable, void *t_device)
1556 gboolean ret = FALSE;
1559 if (vconf_get_int(VCONFKEY_CALL_STATE, &call_state) < 0)
1560 ERR("vconf_get_int is failed");
1562 if ((t_enable == TRUE && call_state == 0) || t_enable == FALSE)
1563 ret = _bt_ag_agent_voice_dial(t_enable);
1566 _bt_voice_dial_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1568 _bt_voice_dial_response(t_device,
1569 HFP_STATE_MNGR_ERR_AG_FAILURE);
1574 void _bt_hfp_set_indicators(const char *t_command, void *t_device)
1576 const char delims = ',';
1579 if (t_command == NULL)
1582 str = strchr(t_command, '=');
1583 while (hfp_ag_ind[i].indicator_desc != NULL && str != NULL) {
1586 if ((g_strcmp0(hfp_ag_ind[i].indicator_desc, "call") != 0) &&
1587 (g_strcmp0(hfp_ag_ind[i].indicator_desc, "callheld") != 0) &&
1588 (g_strcmp0(hfp_ag_ind[i].indicator_desc, "callsetup") != 0)) {
1591 hfp_ag_ind[i].is_activated = FALSE;
1592 } else if (*str == '1') {
1593 hfp_ag_ind[i].is_activated = TRUE;
1595 DBG(" no change in is_activated for[%s]\n",
1596 hfp_ag_ind[i].indicator_desc);
1599 str = strchr(str, delims);
1603 _bt_indicators_activation_response(t_device, HFP_STATE_MNGR_ERR_NONE);
1607 _bt_indicators_activation_response(t_device,
1608 HFP_STATE_MNGR_ERR_INVALID_CHAR_IN_STRING);
1612 static int __bt_hfp_get_phonebook_count(const char *path, uint32_t *max_size,
1615 #ifndef TIZEN_PROFILE_WEARABLE
1616 GDBusConnection *g_conn;
1617 GDBusProxy *g_proxy;
1619 GVariant *ret = NULL;
1623 g_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1627 ERR("Unable to connect to gdbus: %s", err->message);
1628 g_clear_error(&err);
1633 g_proxy = g_dbus_proxy_new_sync(g_conn,
1634 G_DBUS_PROXY_FLAGS_NONE, NULL,
1635 PHONEBOOK_AGENT_BUS_NAME, PHONEBOOK_AGENT_PATH,
1636 PHONEBOOK_AGENT_INTERFACE, NULL, &err);
1640 ERR("Unable to connect to gdbus: %s", err->message);
1641 g_clear_error(&err);
1646 ret = g_dbus_proxy_call_sync(g_proxy, "GetPhonebookSizeAt",
1647 g_variant_new("(s)",
1649 G_DBUS_CALL_FLAGS_NONE, -1,
1653 ERR("dbus call failed");
1655 ERR("D-Bus API failure: errCode[%x], message[%s]",
1656 err->code, err->message);
1658 g_clear_error(&err);
1662 g_variant_get(ret, "(u)", &size);
1663 g_variant_unref(ret);
1665 DBG("Size returned %d", size);
1666 if ((g_strcmp0(path, "\"SM\"") == 0) ||
1667 (g_strcmp0(path, "\"ME\"") == 0)) {
1668 max = AGENT_MAX_PB_COUNT;
1669 } else if ((g_strcmp0(path, "\"DC\"") == 0) ||
1670 (g_strcmp0(path, "\"MC\"") == 0) ||
1671 (g_strcmp0(path, "\"RC\"") == 0)) {
1672 max = AGENT_MAX_CALLLOG_COUNT;
1685 g_object_unref(g_conn);
1687 g_object_unref(g_proxy);
1692 void _bt_hfp_select_phonebook_memory_status(void *t_device)
1694 int32_t path_id = ag_pb_info.path_id;
1696 uint32_t max_size = 0;
1698 hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1700 if (path_id < 0 || path_id >= AGENT_PB_STORE_LIST_SIZE)
1703 if (__bt_hfp_get_phonebook_count(agent_pb_store_list[path_id],
1705 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1707 _bt_select_phonebook_memory_status_response(t_device,
1708 agent_pb_store_list[path_id],
1713 static char *__bt_hfp_get_supported_list(const char *char_list[],
1720 if (char_list == NULL || size == 0)
1723 strng = g_string_new("(");
1725 while (index < size) {
1727 g_string_append(strng, ",");
1729 g_string_append(strng, char_list[index]);
1733 g_string_append(strng, ")");
1735 return g_string_free(strng, FALSE);
1738 void _bt_hfp_select_phonebook_memory_list(void *t_device)
1742 str = __bt_hfp_get_supported_list(agent_pb_store_list,
1743 AGENT_PB_STORE_LIST_SIZE);
1745 _bt_select_phonebook_memory_list_response(t_device,
1746 str, HFP_STATE_MNGR_ERR_NONE);
1751 void _bt_hfp_select_phonebook_memory(void *t_device, const gchar *pb_path)
1754 hfp_state_manager_err_t err;
1756 while (i < AGENT_PB_STORE_LIST_SIZE) {
1757 if (strcmp(agent_pb_store_list[i], pb_path) == 0)
1762 if (i >= 0 && i < AGENT_PB_STORE_LIST_SIZE) {
1763 err = HFP_STATE_MNGR_ERR_NONE;
1764 ag_pb_info.path_id = i;
1766 err = HFP_STATE_MNGR_ERR_INVALID_CHAR_IN_STRING;
1768 _bt_select_phonebook_memory_response(t_device, err);
1771 void _bt_hfp_read_phonebook_entries_list(void *t_device)
1773 hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1775 int32_t path_id = ag_pb_info.path_id;
1778 if (path_id < 0 || path_id >= AGENT_PB_STORE_LIST_SIZE)
1779 err = HFP_STATE_MNGR_ERR_INVALID_INDEX;
1781 if (__bt_hfp_get_phonebook_count(agent_pb_store_list[path_id],
1782 NULL, &used) != 0) {
1783 err = HFP_STATE_MNGR_ERR_NOT_ALLOWED;
1787 _bt_read_phonebook_entries_list_response(t_device, used,
1788 AGENT_PB_NUMBER_MAX_LENGTH, AGENT_PB_NAME_MAX_LENGTH,
1792 static int __bt_hfp_get_phonebook_entries(int start_index, int end_index)
1794 #ifdef TIZEN_PROFILE_WEARABLE
1797 GDBusConnection *g_conn;
1798 GDBusProxy *g_proxy;
1800 GVariant *ret = NULL;
1802 GVariant *value = NULL;
1803 GVariant *tuple = NULL;
1804 const char *name = NULL;
1805 const char *number = NULL;
1810 uint32_t handle = 0;
1812 g_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
1816 ERR("Unable to connect to gdbus: %s", err->message);
1817 g_clear_error(&err);
1822 g_proxy = g_dbus_proxy_new_sync(g_conn,
1823 G_DBUS_PROXY_FLAGS_NONE, NULL,
1824 PHONEBOOK_AGENT_BUS_NAME, PHONEBOOK_AGENT_PATH,
1825 PHONEBOOK_AGENT_INTERFACE, NULL, &err);
1828 ERR("Unable to connect to gdbus: %s", err->message);
1829 g_clear_error(&err);
1834 ret = g_dbus_proxy_call_sync(g_proxy, "GetPhonebookEntriesAt",
1835 g_variant_new("(sii)",
1836 agent_pb_store_list[ag_pb_info.path_id],
1837 start_index, end_index),
1838 G_DBUS_CALL_FLAGS_NONE, -1,
1842 ERR("Dbus call failed");
1844 ERR("D-Bus API failure: errCode[%x], message[%s]",
1845 err->code, err->message);
1847 g_clear_error(&err);
1849 ERR("error returned was NULL");
1853 tuple = g_variant_get_child_value(ret, 0);
1854 if (tuple != NULL) {
1855 int number_contacts = g_variant_n_children(tuple);
1856 DBG("number of contacts %d", number_contacts);
1857 while (count < number_contacts) {
1860 value = g_variant_get_child_value(tuple, count);
1862 g_variant_get(value, "(ssu)", &name, &number, &handle);
1864 uni_name = g_strndup(name, AGENT_PB_NAME_MAX_LENGTH);
1865 uni_number = g_strndup(number, AGENT_PB_NAME_MAX_LENGTH);
1867 _bt_read_phonebook_entries_indicator(uni_name,
1868 uni_number, handle);
1869 g_variant_unref(value);
1872 g_free((gpointer)name);
1873 g_free((gpointer)number);
1875 g_variant_unref(tuple);
1878 g_variant_unref(ret);
1880 g_object_unref(g_conn);
1882 g_object_unref(g_proxy);
1887 void _bt_hfp_read_phonebook_entries(void *t_device, const char *cmd)
1889 int start_index = 0;
1897 hfp_state_manager_err_t err;
1902 str = g_strdup(cmd);
1903 next = strchr(str, ',');
1909 end_index = strtol(next, NULL, 10);
1912 start_index = strtol(str, NULL, 10);
1916 count = __bt_hfp_get_phonebook_entries(start_index, end_index);
1919 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1920 else if (count == 0)
1921 err = HFP_STATE_MNGR_ERR_INVALID_INDEX;
1923 err = HFP_STATE_MNGR_ERR_NONE;
1925 _bt_read_phonebook_entries_response(t_device, err);
1928 void _bt_hfp_find_phonebook_entries_status(void *t_device)
1930 _bt_find_phonebook_entries_status_indicator(
1931 AGENT_PB_NUMBER_MAX_LENGTH,
1932 AGENT_PB_NAME_MAX_LENGTH);
1934 _bt_find_phonebook_entries_status_response(t_device,
1935 HFP_STATE_MNGR_ERR_NONE);
1938 static int __bt_hfp_find_pb_entries(const char *str)
1943 void _bt_hfp_find_phonebook_entries(void *t_device, const char *cmd)
1946 gchar *unquoted = NULL;
1948 hfp_state_manager_err_t err = HFP_STATE_MNGR_ERR_NONE;
1950 /* remove quote and compress */
1951 st = strchr(cmd, '"');
1953 unquoted = g_strdup(cmd);
1957 end = strrchr(cmd, '"');
1959 unquoted = g_strdup(cmd);
1961 unquoted = g_strndup(st + 1, end - st - 1);
1964 if (__bt_hfp_find_pb_entries(unquoted))
1965 err = HFP_STATE_MNGR_ERR_AG_FAILURE;
1967 _bt_find_phonebook_entries_response(t_device, err);
1972 void _bt_hfp_get_character_set(void *t_device)
1974 _bt_supported_character_generic_response(t_device,
1975 (char *)agent_supported_character_set[ag_pb_info.charset_id],
1976 HFP_STATE_MNGR_ERR_NONE);
1979 void _bt_hfp_list_supported_character(void *t_device)
1983 str = __bt_hfp_get_supported_list(agent_supported_character_set,
1984 AGENT_SUPPORTED_CHARACTER_SET_SIZE);
1986 _bt_supported_character_generic_response(t_device,
1987 str, HFP_STATE_MNGR_ERR_NONE);
1992 void _bt_hfp_set_character_set(void *t_device, const char *cmd)
1996 while (index < AGENT_SUPPORTED_CHARACTER_SET_SIZE) {
1997 if (strcmp(agent_supported_character_set[index], cmd) == 0) {
1998 _bt_set_characterset_generic_response(t_device,
1999 HFP_STATE_MNGR_ERR_NONE);
2001 ag_pb_info.charset_id = index;
2007 _bt_set_characterset_generic_response(t_device,
2008 HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
2012 void _bt_hfp_signal_quality_reply(int32_t rssi, int32_t ber,
2015 DBG("signal_quality_reply");
2017 if (rssi == -1 && ber == -1) {
2018 _bt_signal_quality_response(t_device, rssi, ber,
2019 HFP_STATE_MNGR_ERR_AG_FAILURE);
2021 _bt_signal_quality_response(t_device, rssi, ber,
2022 HFP_STATE_MNGR_ERR_NONE);
2026 void _bt_hfp_battery_property_reply(void *data, int32_t bcs,
2029 if (bcs == -1 || bcl == -1) {
2030 _bt_battery_charge_status_response(data, bcs,
2031 bcl, HFP_STATE_MNGR_ERR_AG_FAILURE);
2033 _bt_battery_charge_status_response(data, bcs,
2034 bcl, HFP_STATE_MNGR_ERR_NONE);
2040 void _bt_hfp_get_battery_property(void *t_device)
2042 _bt_ag_agent_get_battery_status(t_device);
2045 void _bt_hfp_operator_reply(char *operator_name, void *t_device)
2047 if (operator_name == NULL)
2050 network_info.network_operator_name = g_strndup(operator_name, 16);
2052 _bt_operator_selection_indicator(AGENT_OPERATOR_MODE_AUTO,
2054 _bt_operator_selection_response(t_device, HFP_STATE_MNGR_ERR_NONE);
2058 _bt_operator_selection_indicator(AGENT_OPERATOR_MODE_AUTO, "UNKNOWN");
2059 _bt_operator_selection_response(t_device,
2060 HFP_STATE_MNGR_ERR_AG_FAILURE);
2063 void _bt_hfp_get_operator_selection_request(void *t_device)
2065 _bt_ag_agent_get_operator_name(t_device);
2068 void _bt_hfp_response_and_hold_request(void *t_device)
2070 _bt_response_and_hold_response(t_device,
2071 HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
2074 void _bt_get_activity_status(void *t_device)
2076 DBG("telephony-tizen: telephony_get_activity_status");
2078 if (NULL != (__bt_hfp_get_call_with_status(
2079 HFP_CALL_STATUS_MT_ALERTING)) ||
2080 NULL != (__bt_hfp_get_call_with_status(
2081 HFP_CALL_STATUS_MO_ALERTING)) ||
2082 NULL != (__bt_hfp_get_call_with_status(
2083 HFP_CALL_STATUS_COMING)) ||
2084 NULL != (__bt_hfp_get_call_with_status(
2085 HFP_CALL_STATUS_CREATE)))
2086 _bt_hfp_get_activity_status_rsp(t_device,
2087 HFP_AGENT_ACTIVITY_STATUS_RINGING,
2088 HFP_STATE_MNGR_ERR_NONE);
2089 else if (NULL != (__bt_hfp_get_call_with_status(
2090 HFP_CALL_STATUS_WAITING)) ||
2091 NULL != (__bt_hfp_get_call_with_status(
2092 HFP_CALL_STATUS_ACTIVE)))
2093 _bt_hfp_get_activity_status_rsp(t_device,
2094 HFP_AGENT_ACTIVITY_STATUS_CALL_IN_PROGRESS,
2095 HFP_STATE_MNGR_ERR_NONE);
2097 _bt_hfp_get_activity_status_rsp(t_device,
2098 HFP_AGENT_ACTIVITY_STATUS_READY,
2099 HFP_STATE_MNGR_ERR_NONE);
2102 void _bt_hfp_get_imei_number_reply(char *imei_number, void *t_device)
2104 _bt_hfp_get_equipment_identity_rsp(t_device, imei_number,
2105 HFP_STATE_MNGR_ERR_NONE);
2108 void _bt_hfp_get_imsi_reply(char *mcc, char *mnc, char *msin, void *t_device)
2110 if (mcc != NULL && mnc != NULL && msin != NULL)
2111 _bt_hfp_get_imsi_rsp(t_device, mcc, mnc, msin,
2112 HFP_STATE_MNGR_ERR_NONE);
2114 _bt_hfp_get_imsi_rsp(t_device, NULL, NULL, NULL,
2115 HFP_STATE_MNGR_ERR_NOT_ALLOWED);
2118 void _bt_hfp_get_creg_status_reply(int n, int status, void *t_device)
2120 _bt_hfp_get_creg_status_rsp(t_device, n, status,
2121 HFP_STATE_MNGR_ERR_NONE);
2124 void _bt_hfp_get_equipment_identity_req(void *t_device)
2126 _bt_ag_agent_get_imei_number(t_device);
2129 void _bt_hfp_get_model_info_reply(char *model, void *t_device)
2131 _bt_hfp_get_model_info_rsp(t_device, model,
2132 HFP_STATE_MNGR_ERR_NONE);
2135 void _bt_hfp_get_model_info_req(void *t_device)
2137 _bt_ag_agent_get_model_name(t_device);
2140 void _bt_hfp_get_device_manufacturer_reply(char *manufacturer, void *t_device)
2142 _bt_hfp_get_device_manufacturer_rsp(t_device, manufacturer,
2143 HFP_STATE_MNGR_ERR_NONE);
2146 void _bt_hfp_get_device_manufacturer_req(void *t_device)
2148 _bt_ag_agent_get_manufacturer_name(t_device);
2151 void _bt_hfp_get_imsi_req(void *t_device)
2153 _bt_ag_agent_get_imsi(t_device);
2156 void _bt_hfp_get_creg_status_req(void *t_device)
2158 _bt_ag_agent_get_creg_status(t_device);
2161 void _bt_hfp_get_revision_info_reply(char *revision, void *t_device)
2163 _bt_hfp_get_revision_info_rsp(t_device, revision,
2164 HFP_STATE_MNGR_ERR_NONE);
2167 void _bt_hfp_get_revision_info_req(void *t_device)
2169 _bt_ag_agent_get_revision_information(t_device);