2 * bluetooth-ag-handler.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.
25 #include <bundle_internal.h>
26 #include <bluetooth.h>
27 #include <bluetooth_internal.h>
28 #include "bluetooth-ag-agent.h"
29 #include "bluetooth-ag-handler.h"
31 #include "vconf-keys.h"
32 #include <syspopup_caller.h>
34 extern bt_ag_status_t ag;
35 extern GSList *active_devices;
36 extern GDBusConnection *ag_dbus_conn;
37 extern gchar *remote_dev_path;
39 /* AT+CSQ : Returns received signal strength indication.
40 Command response: +CSQ: <rssi>,<ber>
41 <ber> is not supported and has a constant value of 99, included for compatibility reasons.
43 #define BT_SIGNAL_QUALITY_BER 99
45 wbs_options wbs_opts = {
50 .pcm_interface_rate = 0x00,
53 /* AT+BRSF response */
54 int _bt_hfp_supported_features(bt_ag_info_t *hs, const char *buf)
56 bt_ag_slconn_t *slconn = hs->slc;
58 // bt_hfp_agent_error_t ret = BT_HFP_AGENT_ERROR_NONE;
64 slconn->hs_features = strtoul(&buf[8], NULL, 10);
65 #if 0 /* SCO is crashed if below is called when SCO is opened by hf-agent */
66 if (slconn->hs_features & BT_HF_FEATURE_CODEC_NEGOTIATION) {
67 ret = _bt_ag_set_codec(hs, "SetWbsParameters");
68 if (ret != BT_HFP_AGENT_ERROR_NONE)
69 ERR("Unable to set the default WBC codec");
71 /* Default codec is NB */
72 ret = _bt_ag_set_codec(hs, "SetNbParameters");
73 if (ret != BT_HFP_AGENT_ERROR_NONE)
74 ERR("Unable to set the default NBC codec");
77 err = _bt_ag_send_at(hs, "\r\n+BRSF: %u\r\n", ag.features);
81 return _bt_ag_send_at(hs, "\r\nOK\r\n");
84 static char *__bt_get_indicator_ranges(const bt_ag_indicators_t *indicators)
89 DBG("__bt_get_indicator_ranges");
90 gstr = g_string_new("\r\n+CIND: ");
92 for (i = 0; indicators[i].indicator_desc != NULL; i++) {
94 g_string_append_printf(gstr, "(\"%s\",(%s))",
95 indicators[i].indicator_desc,
96 indicators[i].indicator_range);
98 g_string_append_printf(gstr, ",(\"%s\",(%s))",
99 indicators[i].indicator_desc,
100 indicators[i].indicator_range);
102 g_string_append(gstr, "\r\n");
103 return g_string_free(gstr, FALSE);
106 static char *__bt_get_indicator_values(const bt_ag_indicators_t *indicators)
111 gstr = g_string_new("\r\n+CIND: ");
112 DBG("__bt_get_indicator_values");
113 for (i = 0; indicators[i].indicator_range != NULL; i++) {
115 g_string_append_printf(gstr, "%d",
116 indicators[i].hfp_value);
118 g_string_append_printf(gstr, ",%d",
119 indicators[i].hfp_value);
121 g_string_append(gstr, "\r\n");
123 return g_string_free(gstr, FALSE);
126 static int __bt_check_hdset(bt_ag_info_t *hdset)
128 bt_ag_slconn_t *slconn = hdset->slc;
130 if (!hdset->hfp_active)
133 if (slconn->is_client_active)
139 static int __bt_hfp_cmp(bt_ag_info_t *hs)
147 static int __bt_cwa_cmp(bt_ag_info_t *hs)
152 if (hs->slc->is_cwa_enabled)
158 gboolean __bt_ring_timer_cb(gpointer data)
160 _bt_ag_send_foreach_headset(active_devices, NULL, "\r\nRING\r\n");
163 _bt_ag_send_foreach_headset(active_devices, __bt_check_hdset,
164 "\r\n+CLIP: \"%s\",%d\r\n",
165 ag.number, ag.number_type);
170 int _bt_incoming_call_indicator(const char *number, int type)
173 bt_ag_slconn_t *slconn;
178 /* Get the updated list of connected devices */
179 hs = active_devices->data;
183 DBG("incoming_call_indicator: already calling....");
187 /*If inband ring supported then no need to send RING alert to HF */
188 if (!hs->hfp_active && slconn->is_inband_ring) {
189 DBG("Inband ring tone supported");
193 DBG("Inband ring tone not supported.. so send a RING to HF");
195 ag.number = g_strdup(number);
196 ag.number_type = type;
198 if (slconn->is_inband_ring &&
199 hs->state != HEADSET_STATE_ON_CALL) {
200 slconn->is_pending_ring = TRUE;
204 __bt_ring_timer_cb(NULL);
205 ag.ring_timer = g_timeout_add(AG_RING_INTERVAL, __bt_ring_timer_cb, NULL);
210 int _bt_calling_stopped_indicator(void)
215 g_source_remove(ag.ring_timer);
222 /* In case SCO is in intermediate state to connect */
223 dev = active_devices->data;
225 if (!dev->slc->is_pending_ring && !ag.ring_timer)
228 dev->slc->is_pending_ring = FALSE;
233 void _bt_hfp_set_ag_indicator(uint32_t ag_features,
234 const bt_ag_indicators_t *ag_indicators, int rh,
237 DBG("Set Ag Features");
238 ag.telephony_ready = TRUE;
239 ag.features = ag_features;
240 ag.indicators = ag_indicators;
245 void _bt_hfp_deinitialize(void)
248 memset(&ag, 0, sizeof(ag));
249 ag.rh = BT_RSP_HOLD_NOT_SUPPORTED;
253 /* Send event indication call from Statemanager module */
254 bt_hfp_agent_error_t _bt_hfp_event_indicator(int index)
256 if (!active_devices) {
257 DBG("No Active devices present");
258 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
262 DBG("Indicate event called but event reporting is disabled");
263 return BT_HFP_AGENT_ERROR_INTERNAL;
266 DBG("Sending event notification to hf....");
268 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
269 "\r\n+CIEV: %d,%d\r\n", index + 1,
270 ag.indicators[index].hfp_value);
272 return BT_HFP_AGENT_ERROR_NONE;
275 /* AT+CIND response */
276 int _bt_hfp_report_indicators(bt_ag_info_t *hs, const char *buf)
285 str = __bt_get_indicator_ranges(ag.indicators);
287 str = __bt_get_indicator_values(ag.indicators);
289 err = _bt_ag_send_at(hs, "%s", str);
296 return _bt_ag_send_at(hs, "\r\nOK\r\n");
299 /* AT+CMER response */
300 int _bt_event_reporting_response(void *t_device,
301 bt_hfp_agent_error_t err)
303 bt_ag_info_t *hdset = t_device;
304 bt_ag_slconn_t *slconn = hdset->slc;
307 if (err != (bt_hfp_agent_error_t) HFP_STATE_MNGR_ERR_NONE)
308 return _bt_ag_send_response(t_device, err);
310 ret_val = _bt_ag_send_at(hdset, "\r\nOK\r\n");
314 if (hdset->state != HEADSET_STATE_CONNECTING)
317 if (slconn->hs_features & HANDSFREE_FEATURE_CALL_WAITING_AND_3WAY &&
318 ag.features & BT_AG_FEATURE_THREE_WAY_CALL)
321 _bt_ag_slconn_complete(hdset);
326 int _bt_hfp_enable_indicators(bt_ag_info_t *hdset, const char *buffer)
328 if (strlen(buffer) < 13)
331 /* tokenks can be <mode>,<keyp>,<disp>,<ind>,<bfr>*/
332 char **ind_tokens = g_strsplit(&buffer[8], ",", 5);
334 if (g_strv_length(ind_tokens) < 4) {
335 g_strfreev(ind_tokens);
339 ag.er_mode = atoi(ind_tokens[0]);
340 ag.er_ind = atoi(ind_tokens[3]);
342 DBG("hfp_enable_indicators (CMER): indicator=%d, mode=%d",
343 ag.er_ind, ag.er_mode);
345 g_strfreev(ind_tokens);
351 _bt_hfp_update_event_request(ag.er_ind, hdset);
359 /* AT+CHLD response */
360 int _bt_hfp_call_hold(bt_ag_info_t *hs, const char *buf)
368 _bt_hfp_call_hold_request(&buf[8], hs);
372 err = _bt_ag_send_at(hs, "\r\n+CHLD: (%s)\r\n", ag.chld);
376 err = _bt_ag_send_at(hs, "\r\nOK\r\n");
380 _bt_ag_slconn_complete(hs);
385 int _bt_key_press_response(void *t_device, bt_hfp_agent_error_t err)
387 return _bt_ag_send_response(t_device, err);
390 int _bt_hfp_key_press(bt_ag_info_t *hs, const char *buf)
396 g_source_remove(ag.ring_timer);
400 _bt_hfp_key_press_request(&buf[8], hs);
405 int _bt_answer_call_response(void *hs, bt_hfp_agent_error_t err)
407 return _bt_ag_send_response(hs, err);
410 int _bt_hfp_answer_call(bt_ag_info_t *hs, const char *buf)
413 g_source_remove(ag.ring_timer);
423 g_free(remote_dev_path);
425 remote_dev_path = g_strdup(hs->path);
427 _bt_hfp_answer_call_request(hs);
431 int _bt_terminate_call_response(void *t_device,
432 hfp_state_manager_err_t err)
434 bt_ag_info_t *hs = t_device;
436 if (err != HFP_STATE_MNGR_ERR_NONE)
437 return _bt_ag_send_response(hs, err);
439 return _bt_ag_send_at(hs, "\r\nOK\r\n");
442 int _bt_hfp_terminate_call(bt_ag_info_t *hs, const char *buf)
450 g_source_remove(ag.ring_timer);
454 _bt_hfp_terminate_call_request(hs);
459 int _bt_hfp_cli_notification(bt_ag_info_t *hs, const char *buf)
461 bt_ag_slconn_t *slconn = hs->slc;
466 slconn->is_client_active = buf[8] == '1' ? TRUE : FALSE;
468 return _bt_ag_send_at(hs, "\r\nOK\r\n");
471 int _bt_response_and_hold_response(void *t_device,
472 bt_hfp_agent_error_t err)
474 return _bt_ag_send_response(t_device, err);
477 int _bt_hfp_response_and_hold(bt_ag_info_t *hs, const char *buf)
483 if (ag.rh == BT_RSP_HOLD_NOT_SUPPORTED)
484 return _bt_ag_send_response(hs,
485 HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
488 _bt_hfp_response_and_hold_request(hs);
493 _bt_ag_send_at(hs, "\r\n+BTRH: %d\r\n", ag.rh);
495 return _bt_ag_send_at(hs, "\r\nOK\r\n");
498 int _bt_hfp_last_dialed_number(bt_ag_info_t *hs, const char *buf)
501 g_free(remote_dev_path);
503 remote_dev_path = g_strdup(hs->path);
504 _bt_hfp_last_dialed_number_request(hs);
509 int _bt_dial_number_response(void *t_device, bt_hfp_agent_error_t err)
511 return _bt_ag_send_response(t_device, err);
514 int _bt_hfp_dial_number(bt_ag_info_t *hs, const char *buf)
516 char number[MAX_BUFFER_SIZE];
519 buf_len = strlen(buf);
521 if (buf[buf_len - 1] != ';') {
522 DBG("Reject the non-voice call dial number request");
526 memset(number, 0, sizeof(number));
527 strncpy(number, &buf[3], buf_len - 4);
530 g_free(remote_dev_path);
532 remote_dev_path = g_strdup(hs->path);
534 _bt_hfp_dial_number_request(number, hs);
539 static int __bt_headset_set_gain(bt_ag_info_t *hs, uint16_t gain, char type)
541 bt_ag_slconn_t *slconn = hs->slc;
542 const char *property;
545 DBG("Invalid gain value: %u", gain);
550 case BT_HFP_SPEAKER_GAIN:
551 if (slconn->speaker_gain == gain) {
552 DBG("Ignoring no-change in speaker gain");
555 property = "SpeakerGain";
556 slconn->speaker_gain = gain;
557 _bt_ag_agent_set_last_speaker_gain(gain);
559 case BT_HFP_MICROPHONE_GAIN:
560 if (slconn->microphone_gain == gain) {
561 DBG("Ignoring no-change in microphone gain");
564 property = "MicrophoneGain";
565 slconn->microphone_gain = gain;
568 DBG("Unknown gain setting\n");
572 _bt_ag_agent_emit_property_changed(ag_dbus_conn, hs->path,
573 BT_HEADSET_INTERFACE, property,
574 g_variant_new("q", gain));
578 int _bt_hfp_signal_gain_setting(bt_ag_info_t *hs, const char *buf)
583 if (strlen(buf) < 8) {
584 DBG("very short string to use for Gain setting\n");
588 gain = (uint16_t) strtol(&buf[7], NULL, 10);
590 err = __bt_headset_set_gain(hs, gain, buf[5]);
591 if (err < 0 && err != -EALREADY)
594 return _bt_ag_send_at(hs, "\r\nOK\r\n");
597 int _bt_transmit_dtmf_response(void *t_device,
598 bt_hfp_agent_error_t err)
600 return _bt_ag_send_response(t_device, err);
603 int _bt_hfp_dtmf_tone(bt_ag_info_t *hs, const char *buf)
607 if (strlen(buf) < 8) {
608 printf("Too short string for DTMF tone");
613 if (tone >= '#' && tone <= 'D')
614 _bt_hfp_channel_dtmf_request(tone, hs);
621 int _bt_hfp_set_speaker_gain(bt_ag_info_t *hs,
625 char type = BT_HFP_SPEAKER_GAIN;
627 err = __bt_headset_set_gain(hs, gain_value, type);
629 return BT_HFP_AGENT_ERROR_INTERNAL;
631 if (hs->state == HEADSET_STATE_ON_CALL) {
632 err = _bt_ag_send_at(hs, "\r\n+VG%c=%u\r\n", type,
635 return BT_HFP_AGENT_ERROR_INTERNAL;
637 return BT_HFP_AGENT_ERROR_NONE;
640 int _bt_hfp_set_microphone_gain(bt_ag_info_t *hs,
644 char type = BT_HFP_MICROPHONE_GAIN;
648 return BT_HFP_AGENT_ERROR_INVALID_PARAM;
651 err = __bt_headset_set_gain(hs, gain_value, type);
653 return BT_HFP_AGENT_ERROR_INTERNAL;
655 if (hs->state == HEADSET_STATE_ON_CALL) {
656 err = _bt_ag_send_at(hs, "\r\n+VG%c=%u\r\n", type,
659 return BT_HFP_AGENT_ERROR_INTERNAL;
661 return BT_HFP_AGENT_ERROR_NONE;
665 int _bt_hfp_set_voice_dial(bt_ag_info_t *hs,
668 DBG("_bt_hfp_set_voice_dial = %d", enable);
670 if (_bt_ag_send_at(hs, "\r\n+BVRA: %d\r\n", enable) < 0)
671 return BT_HFP_AGENT_ERROR_INTERNAL;
673 return BT_HFP_AGENT_ERROR_NONE;
676 int _bt_hfp_send_vendor_cmd(bt_ag_info_t *hs,
679 DBG("_bt_hfp_send_vendor_cmd = %d", cmd);
681 if (_bt_ag_send_at(hs, "\r\n%s\r\n", cmd) < 0)
682 return BT_HFP_AGENT_ERROR_INTERNAL;
684 return BT_HFP_AGENT_ERROR_NONE;
687 int _bt_vendor_cmd_response(void *t_device,
688 bt_hfp_agent_error_t err)
690 return _bt_ag_send_response(t_device, err);
693 int _bt_hfp_vendor_cmd(bt_ag_info_t *hs, const char *buf)
695 DBG("XSAT vendor command");
697 _bt_hfp_vendor_cmd_request(buf, hs);
702 int _bt_list_current_call_indicator(bt_ag_info_t *hs, int index, int direction,
703 int mode, int status, const char *call_num, int conference, int t_num)
705 if (call_num && strlen(call_num) > 0) {
707 "\r\n+CLCC: %d,%d,%d,%d,%d,\"%s\",%d\r\n",
708 index, direction, status, mode, conference,
712 "\r\n+CLCC: %d,%d,%d,%d,%d\r\n",
713 index, direction, status, mode, conference);
718 int _bt_subscriber_number_indicator(const char *call_num, int type, int service)
723 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
724 "\r\n+CNUM: ,%s,%d,,%d\r\n",
725 call_num, type, service);
729 int _bt_subscriber_number_response(void *t_device,
730 bt_hfp_agent_error_t err)
732 return _bt_ag_send_response(t_device, err);
735 int _bt_hfp_subscriber_number(bt_ag_info_t *hs, const char *buf)
737 _bt_hfp_subscriber_number_request(hs);
742 int _bt_call_waiting_indicator(const char *number, int type)
747 DBG("Call waiting indicator to hf");
748 _bt_ag_send_foreach_headset(active_devices, __bt_cwa_cmp,
749 "\r\n+CCWA: \"%s\",%d\r\n",
754 int _bt_list_current_calls_response(void *t_device,
755 bt_hfp_agent_error_t err)
757 return _bt_ag_send_response(t_device, err);
760 int _bt_hfp_list_current_calls(bt_ag_info_t *hs, const char *buf)
762 _bt_list_current_calls(hs);
767 int _bt_hfp_extended_errors(bt_ag_info_t *hs, const char *buf)
769 bt_ag_slconn_t *slconn = hs->slc;
775 slconn->is_cme_enabled = TRUE;
776 DBG("CME errors enabled for headset %p", hs);
778 slconn->is_cme_enabled = FALSE;
779 DBG("CME errors disabled for headset %p", hs);
782 return _bt_ag_send_at(hs, "\r\nOK\r\n");
785 int _bt_hfp_call_waiting_notify(bt_ag_info_t *hs, const char *buf)
787 bt_ag_slconn_t *slconn = hs->slc;
793 slconn->is_cwa_enabled = TRUE;
794 DBG("Call waiting notification enabled for headset %p", hs);
796 slconn->is_cwa_enabled = FALSE;
797 DBG("Call waiting notification disabled for headset %p", hs);
800 return _bt_ag_send_at(hs, "\r\nOK\r\n");
803 int _bt_operator_selection_response(void *t_device,
804 bt_hfp_agent_error_t err)
806 return _bt_ag_send_response(t_device, err);
809 int _bt_call_hold_response(void *t_device, bt_hfp_agent_error_t err)
811 return _bt_ag_send_response(t_device, err);
814 int _bt_nr_and_ec_response(void *t_device, bt_hfp_agent_error_t err)
816 bt_ag_info_t *hs = t_device;
817 bt_ag_slconn_t *slconn = hs->slc;
819 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
822 for (l = hs->nrec_cbs; l; l = l->next) {
823 struct hs_nrec_callback *nrec_cb = l->data;
825 nrec_cb->cb(hs, slconn->is_nrec_req,
829 slconn->is_nrec = hs->slc->is_nrec_req;
832 return _bt_ag_send_response(t_device, err);
835 int _bt_voice_dial_response(void *t_device, bt_hfp_agent_error_t err)
837 return _bt_ag_send_response(t_device, err);
840 int _bt_operator_selection_indicator(int mode, const char *oper)
845 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
846 "\r\n+COPS: %d,0,\"%s\"\r\n",
851 int _bt_hfp_operator_selection(bt_ag_info_t *hs, const char *buf)
858 _bt_hfp_get_operator_selection_request(hs);
862 return _bt_ag_send_at(hs, "\r\n+CME ERROR: %d\r\n",
863 HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
865 return _bt_ag_send_at(hs, "\r\nOK\r\n");
874 int _bt_hfp_nr_and_ec(bt_ag_info_t *hs, const char *buf)
876 bt_ag_slconn_t *slconn = hs->slc;
882 slconn->is_nrec_req = FALSE;
884 slconn->is_nrec_req = TRUE;
886 _bt_hfp_noise_red_and_echo_cancel_request(slconn->is_nrec_req, hs);
891 int _bt_hfp_voice_dial(bt_ag_info_t *hs, const char *buf)
893 bt_ag_slconn_t *slconn = hs->slc;
905 g_free(remote_dev_path);
907 remote_dev_path = g_strdup(hs->path);
909 _bt_hfp_voice_dial_request(enable, hs);
911 slconn->is_voice_recognition_running = enable;
916 int _bt_hfp_indicators_activation(bt_ag_info_t *hs, const char *buf)
918 if (strlen(buf) < 7) {
919 ERR("Invalid indicator activation request\n");
923 _bt_hfp_set_indicators(&buf[6], hs);
927 int _bt_indicators_activation_response(void *t_device,
928 bt_hfp_agent_error_t err)
930 return _bt_ag_send_response(t_device, err);
933 int _bt_select_phonebook_memory_status_response(void *t_device,
935 uint32_t total, uint32_t used,
936 bt_hfp_agent_error_t err)
938 bt_ag_info_t *hs = t_device;
939 bt_ag_slconn_t *slconn = hs->slc;
941 if (err != (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
942 if (slconn->is_cme_enabled)
943 return _bt_ag_send_at(hs,
944 "\r\n+CME ERROR: %d\r\n", err);
946 return _bt_ag_send_at(hs, "\r\nERROR\r\n");
952 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
953 "\r\n+CPBS: %s,%d,%d\r\n",
956 return _bt_ag_send_at(hs, "\r\nOK\r\n");
959 int _bt_select_phonebook_memory_list_response(void *t_device,
961 bt_hfp_agent_error_t err)
963 bt_ag_info_t *hs = t_device;
964 bt_ag_slconn_t *slconn = hs->slc;
966 if ((err != (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) ||
968 if (slconn->is_cme_enabled)
969 return _bt_ag_send_at(hs,
970 "\r\n+CME ERROR: %d\r\n", err);
972 return _bt_ag_send_at(hs, "\r\nERROR\r\n");
979 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
980 "\r\n+CPBS: %s\r\n", buf);
983 return _bt_ag_send_at(hs, "\r\nOK\r\n");
986 int _bt_select_phonebook_memory_response(void *t_device,
987 bt_hfp_agent_error_t err)
989 return _bt_ag_send_response(t_device, err);
992 static char *__bt_get_remote_device_name(const char *device_path)
996 GVariant *result = NULL;
998 GDBusProxy *device_proxy;
999 GDBusConnection *conn;
1001 if (device_path == NULL)
1004 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
1006 INFO_SECURE("Device_path %s", device_path);
1007 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1010 BT_PROPERTIES_INTERFACE,
1013 result = g_dbus_proxy_call_sync(device_proxy, "GetAll",
1014 g_variant_new("(s)", "org.bluez.Device1"),
1015 G_DBUS_CALL_FLAGS_NONE,
1019 ERR("DBus Error : %s", err->message);
1020 g_clear_error(&err);
1023 if (result == NULL) {
1024 ERR("g_dbus_proxy_call_sync function return NULL");
1027 g_variant_get(result, "(@a{sv})", &value);
1030 GVariant *temp_value = g_variant_lookup_value(value, "Alias",
1031 G_VARIANT_TYPE_STRING);
1032 g_variant_get(temp_value, "(s)", &name);
1034 g_variant_unref(temp_value);
1037 INFO_SECURE("Alias Name [%s]", name);
1039 temp_value = g_variant_lookup_value(value, "Name", G_VARIANT_TYPE_STRING);
1040 g_variant_get(temp_value, "s", &name);
1042 g_variant_unref(temp_value);
1043 INFO_SECURE("Name = %s", name);
1046 g_variant_unref(result);
1047 g_object_unref(device_proxy);
1051 int _bt_launch_pbap_popup(const char *device_name,
1052 const char *agent_path)
1056 char event_str[50 + 1];
1058 b = bundle_create();
1060 ERR("Launching system popup failed");
1064 bundle_add(b, "device-name", device_name);
1065 bundle_add(b, "agent-path", agent_path);
1067 g_strlcpy(event_str, "phonebook-request", sizeof(event_str));
1069 bundle_add(b, "event-type", event_str);
1071 ret = syspopup_launch("bt-syspopup", b);
1073 ERR("Popup launch failed... %d", ret);
1078 INFO("_bt_agent_launch_system_popup");
1082 int _bt_hfp_select_phonebook_memory_status_reply(bt_ag_info_t *hs)
1084 const char *buf = hs->at_pbap_buf;
1085 if (hs->pbap_trusted == BT_AG_FEATURE_PBAP_BLOCKED
1086 || hs->pbap_trusted == BT_AG_FEATURE_PBAP_CANCEL) {
1087 INFO("Doesnot have Access reply with error");
1088 _bt_select_phonebook_memory_response(hs,
1089 HFP_STATE_MNGR_ERR_NOT_ALLOWED);
1093 if (buf[7] == '?') {
1094 _bt_hfp_select_phonebook_memory_status(hs);
1098 if (buf[7] == '=') {
1099 if (buf[8] == '?') {
1100 _bt_hfp_select_phonebook_memory_list(hs);
1103 _bt_hfp_select_phonebook_memory(hs, &buf[8]);
1109 int _bt_hfp_select_pb_memory(bt_ag_info_t *hs, const char *buf)
1111 if (strlen(buf) < 8)
1113 INFO("Pbap_trusted %d", hs->pbap_trusted);
1114 if (hs->pbap_trusted == BT_AG_FEATURE_PBAP_SHOW_AUTHORIZATION
1115 || hs->pbap_trusted == BT_AG_FEATURE_PBAP_CANCEL) {
1116 strncpy(hs->at_pbap_buf, buf, sizeof(hs->at_pbap_buf) - 1);
1117 /* Adding Popup here */
1120 int err = bt_device_get_profile_trusted(hs->remote_addr, 1, &trust);
1121 if (err != TIZEN_ERROR_NONE) {
1122 INFO("Show authorization popup %d Error %d", trust, err);
1123 char *name = __bt_get_remote_device_name(hs->path);
1124 INFO_SECURE("remote device name %s", name);
1125 _bt_launch_pbap_popup(name,
1126 BT_AG_AGENT_OBJECT_PATH);
1130 INFO("This device has been marked as blocked");
1131 hs->pbap_trusted = BT_AG_FEATURE_PBAP_BLOCKED;
1134 hs->pbap_trusted = BT_AG_FEATURE_PBAP_ALLOWED;
1136 if (hs->pbap_trusted == BT_AG_FEATURE_PBAP_ALLOWED) {
1137 INFO("Authorized from PBAP");
1138 if (buf[7] == '?') {
1139 _bt_hfp_select_phonebook_memory_status(hs);
1143 if (buf[7] == '=') {
1144 if (buf[8] == '?') {
1145 _bt_hfp_select_phonebook_memory_list(hs);
1148 _bt_hfp_select_phonebook_memory(hs, &buf[8]);
1151 } else if (hs->pbap_trusted == BT_AG_FEATURE_PBAP_BLOCKED) {
1152 INFO("Device is blocked");
1153 /* Reply with Error */
1160 int _bt_read_phonebook_entries_list_response(void *t_device,
1162 uint32_t number_length,
1163 uint32_t name_length,
1164 bt_hfp_agent_error_t err)
1166 bt_ag_info_t *hs = t_device;
1167 bt_ag_slconn_t *slconn = hs->slc;
1172 if (err != (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
1173 if (slconn->is_cme_enabled)
1174 return _bt_ag_send_at(hs,
1175 "\r\n+CME ERROR: %d\r\n", err);
1177 return _bt_ag_send_at(hs, "\r\nERROR\r\n");
1183 send_err = _bt_ag_send_at(hs, "\r\n+CPBR: (%d-%d),%d,%d\r\n",
1184 index, used, number_length, name_length);
1188 return _bt_ag_send_at(hs, "\r\nOK\r\n");
1191 int _bt_read_phonebook_entries_response(void *t_device,
1192 bt_hfp_agent_error_t err)
1194 return _bt_ag_send_response(t_device, err);
1197 int _bt_read_phonebook_entries_indicator(const char *name, const char *number,
1201 const char *pos = NULL;
1204 while (*pos == ' ' || *pos == '\t')
1207 /* 145 means international access code, otherwise 129 is used */
1211 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1212 "\r\n+CPBR: %d,\"%s\",%d,\"%s\"\r\n",
1213 handle, number, type, name);
1217 int _bt_read_phonebook_entries_indicator_by_name(const char *name,
1218 const char *number, uint32_t handle)
1221 const char *pos = NULL;
1224 while (*pos == ' ' || *pos == '\t')
1227 /* 145 means international access code, otherwise 129 is used */
1231 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1232 "\r\n+CPBF: %d,\"%s\",%d,\"%s\"\r\n",
1233 handle, number, type, name);
1237 int _bt_hfp_read_pb_entries(bt_ag_info_t *hs, const char *buf)
1239 if (hs->pbap_trusted != BT_AG_FEATURE_PBAP_ALLOWED)
1242 if (strlen(buf) < 8)
1249 _bt_hfp_read_phonebook_entries_list(hs);
1251 _bt_hfp_read_phonebook_entries(hs, &buf[8]);
1256 int _bt_find_phonebook_entries_status_response(void *t_device,
1257 bt_hfp_agent_error_t err)
1259 return _bt_ag_send_response(t_device, err);
1262 int _bt_find_phonebook_entries_response(void *t_device,
1263 bt_hfp_agent_error_t err)
1265 return _bt_ag_send_response(t_device, err);
1268 int _bt_find_phonebook_entries_status_indicator(uint32_t number_length,
1269 uint32_t name_length)
1271 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1272 "\r\n+CPBF: %d,%d\r\n",
1273 number_length, name_length);
1278 int _bt_hfp_find_pb_entires(bt_ag_info_t *hs, const char *buf)
1280 /* Check if Contact access is permitted or not */
1281 if (hs->pbap_trusted != BT_AG_FEATURE_PBAP_ALLOWED)
1284 if (strlen(buf) < 8)
1291 _bt_hfp_find_phonebook_entries_status(hs);
1293 _bt_hfp_find_phonebook_entries(hs, &buf[8]);
1298 int _bt_supported_character_generic_response(void *t_device,
1299 char *character_set_list,
1300 bt_hfp_agent_error_t err)
1302 bt_ag_info_t *hs = t_device;
1303 bt_ag_slconn_t *slconn = hs->slc;
1305 if (err != (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
1306 if (slconn->is_cme_enabled)
1307 return _bt_ag_send_at(hs,
1308 "\r\n+CME ERROR: %d\r\n", err);
1310 return _bt_ag_send_at(hs, "\r\nERROR\r\n");
1313 if (NULL != character_set_list) {
1314 if (!active_devices)
1317 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1318 "\r\n+CSCS: %s\r\n", character_set_list);
1320 return _bt_ag_send_at(hs, "\r\nOK\r\n");
1323 int _bt_set_characterset_generic_response(void *t_device,
1324 bt_hfp_agent_error_t err)
1326 return _bt_ag_send_response(t_device, err);
1329 int _bt_hfp_select_character_set(bt_ag_info_t *hs, const char *buf)
1332 if (strlen(buf) < 7)
1335 if (buf[7] == '?') {
1336 _bt_hfp_get_character_set(hs);
1340 if (buf[7] == '=') {
1342 _bt_hfp_list_supported_character(hs);
1344 _bt_hfp_set_character_set(hs, &buf[8]);
1351 int _bt_battery_charge_status_response(void *t_device,
1354 bt_hfp_agent_error_t err)
1356 bt_ag_info_t *hs = t_device;
1358 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
1359 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1360 "\r\n+CBC: %d,%d\r\n", bcs, bcl);
1363 return _bt_ag_send_response(hs, err);
1366 int _bt_hfp_get_battery_charge_status(bt_ag_info_t *hs, const char *buf)
1368 if (strlen(buf) < 6)
1372 return _bt_ag_send_response(hs, HFP_STATE_MNGR_ERR_NONE);
1374 _bt_hfp_get_battery_property(hs);
1378 int _bt_hfp_apl_command(bt_ag_info_t *hs, const char *buf)
1380 DBG("Got Apple command: %s", buf);
1382 /*we don't support XAPL commands*/
1383 return _bt_ag_send_response(hs, HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
1386 /* convert signal strength to a RSSI level */
1387 static int __bt_telephony_convert_signal_to_rssi(int signal)
1389 /* input : BT signal strength (0~5) */
1390 /* output : RSSI strength (0~31) */
1406 int _bt_signal_quality_response(void *t_device,
1409 bt_hfp_agent_error_t err)
1411 bt_ag_info_t *hs = t_device;
1413 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
1414 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1415 "\r\n+CSQ: %d,%d\r\n",
1416 __bt_telephony_convert_signal_to_rssi(rssi), ber);
1418 return _bt_ag_send_response(hs, err);
1421 int _bt_telephony_signal_quality_list_supported_response(void *t_device,
1422 bt_hfp_agent_error_t err)
1424 bt_ag_info_t *device = t_device;
1426 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
1427 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1428 "\r\n+CSQ: (0-31,99),(99)\r\n");
1430 return _bt_ag_send_response(device, err);
1433 int _bt_hfp_get_signal_quality(bt_ag_info_t *hs, const char *buf)
1435 if (strlen(buf) < 6)
1439 _bt_telephony_signal_quality_list_supported_response(hs,
1440 HFP_STATE_MNGR_ERR_NONE);
1442 _bt_ag_agent_get_signal_quality(hs);
1447 int _bt_hfp_get_activity_status_rsp(void *t_device,
1449 bt_hfp_agent_error_t err)
1451 bt_ag_info_t *device = t_device;
1453 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
1454 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1455 "\r\n+CPAS: %d\r\n", status);
1458 return _bt_ag_send_response(device, err);
1461 int _bt_hfp_get_activity_status(bt_ag_info_t *device, const char *buf)
1463 if (strlen(buf) < 7)
1466 if (buf[7] == '?') {
1467 return _bt_ag_send_response(device,
1468 HFP_STATE_MNGR_ERR_AG_FAILURE);
1469 } else if (buf[7] == '=') {
1470 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1471 "\r\n+CPAS: (0-4)\r\n");
1472 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1475 _bt_get_activity_status(device);
1479 int _bt_hfp_get_equipment_identity_rsp(void *t_device,
1480 char *identity, bt_hfp_agent_error_t err)
1483 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1484 "\r\n+CGSN: %s\r\n", identity);
1485 return _bt_ag_send_response(t_device, err);
1488 int _bt_hfp_get_imsi_rsp(void *t_device,
1489 char *mcc, char *mnc, char *msin, bt_hfp_agent_error_t err)
1491 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE)
1492 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1493 "\r\n%s%s%s\r\n", mcc, mnc, msin);
1494 return _bt_ag_send_response(t_device, err);
1497 int _bt_hfp_get_creg_status_rsp(void *t_device,
1498 int n, int status, bt_hfp_agent_error_t err)
1500 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE)
1501 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1502 "\r\n+CREG: %d,%d\r\n", n, status);
1503 return _bt_ag_send_response(t_device, err);
1506 int _bt_hfp_get_equipment_identity(bt_ag_info_t *device, const char *buf)
1508 int len = strlen(buf);
1510 if (len == 9 && buf[7] == '=' && buf[8] == '?') /* AT+CGSN=? */
1511 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1516 _bt_hfp_get_equipment_identity_req(device); /* AT+CGSN */
1520 int _bt_hfp_get_model_info_rsp(void *t_device, char *model,
1521 bt_hfp_agent_error_t err)
1524 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1525 "\r\n+CGMM: %s\r\n", model);
1526 return _bt_ag_send_response(t_device, err);
1529 int _bt_hfp_get_model_information(bt_ag_info_t *device, const char *buf)
1531 int len = strlen(buf);
1533 if (len == 9 && buf[7] == '=' && buf[8] == '?') /* AT+CGMM=? */
1534 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1539 _bt_hfp_get_model_info_req(device);/* AT+CGMM */
1543 int _bt_hfp_get_device_manufacturer_rsp(void *t_device,
1544 char *manufacturer, bt_hfp_agent_error_t err)
1547 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1548 "\r\n+CGMI: %s\r\n", manufacturer);
1549 return _bt_ag_send_response(t_device, err);
1552 int _bt_hfp_get_device_manufacturer(bt_ag_info_t *device, const char *buf)
1554 int len = strlen(buf);
1556 if (len == 9 && buf[7] == '=' && buf[8] == '?') /* AT+CGMI=? */
1557 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1562 _bt_hfp_get_device_manufacturer_req(device);
1566 int _bt_hfp_get_imsi(bt_ag_info_t *device, const char *buf)
1568 int len = strlen(buf);
1569 DBG_SECURE("Buf %s", buf);
1572 _bt_hfp_get_imsi_req(device);
1574 _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_INVALID_INDEX);
1579 int _bt_hfp_get_creg_status(bt_ag_info_t *device, const char *buf)
1581 int len = strlen(buf);
1582 DBG_SECURE("buf %s", buf);
1583 if (len < 7 || len > 9)
1586 _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_INVALID_INDEX);
1587 else if (buf[7] == '=')
1588 _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_INVALID_INDEX);
1589 else if (buf[7] == '?')
1590 _bt_hfp_get_creg_status_req(device);
1594 int _bt_hfp_get_revision_info_rsp(void *t_device, char *revision,
1595 bt_hfp_agent_error_t err)
1598 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1599 "\r\n+CGMR: %s\r\n", revision);
1600 return _bt_ag_send_response(t_device, err);
1603 int _bt_hfp_get_revision_information(bt_ag_info_t *device, const char *buf)
1605 int len = strlen(buf);
1607 if (len == 9 && buf[7] == '=' && buf[8] == '?') /* AT+CGMR=? */
1608 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1613 _bt_hfp_get_revision_info_req(device);