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.
24 #include "bluetooth-ag-agent.h"
25 #include "bluetooth-ag-handler.h"
27 #include "vconf-keys.h"
29 extern bt_ag_status_t ag;
30 extern GSList *active_devices;
31 extern GDBusConnection *ag_dbus_conn;
32 extern gchar *remote_dev_path;
34 /* AT+CSQ : Returns received signal strength indication.
35 Command response: +CSQ: <rssi>,<ber>
36 <ber> is not supported and has a constant value of 99, included for compatibility reasons.
38 #define BT_SIGNAL_QUALITY_BER 99
40 wbs_options wbs_opts = {
45 .pcm_interface_rate = 0x00,
49 /* AT+BRSF response */
50 int _bt_hfp_supported_features(bt_ag_info_t *hs, const char *buf)
52 bt_ag_slconn_t *slconn = hs->slc;
54 // bt_hfp_agent_error_t ret = BT_HFP_AGENT_ERROR_NONE;
60 slconn->hs_features = strtoul(&buf[8], NULL, 10);
61 #if 0 /* SCO is crashed if below is called when SCO is opened by hf-agent */
62 if (slconn->hs_features & BT_HF_FEATURE_CODEC_NEGOTIATION) {
63 ret = _bt_ag_set_codec(hs, "SetWbsParameters");
64 if (ret != BT_HFP_AGENT_ERROR_NONE)
65 ERR("Unable to set the default WBC codec");
67 /* Default codec is NB */
68 ret = _bt_ag_set_codec(hs, "SetNbParameters");
69 if (ret != BT_HFP_AGENT_ERROR_NONE)
70 ERR("Unable to set the default NBC codec");
73 err = _bt_ag_send_at(hs, "\r\n+BRSF: %u\r\n", ag.features);
77 return _bt_ag_send_at(hs, "\r\nOK\r\n");
80 static char *__bt_get_indicator_ranges(const bt_ag_indicators_t *indicators)
85 DBG("__bt_get_indicator_ranges");
86 gstr = g_string_new("\r\n+CIND: ");
88 for (i = 0; indicators[i].indicator_desc != NULL; i++) {
90 g_string_append_printf(gstr, "(\"%s\",(%s))",
91 indicators[i].indicator_desc,
92 indicators[i].indicator_range);
94 g_string_append_printf(gstr, ",(\"%s\",(%s))",
95 indicators[i].indicator_desc,
96 indicators[i].indicator_range);
98 g_string_append(gstr, "\r\n");
99 return g_string_free(gstr, FALSE);
102 static char *__bt_get_indicator_values(const bt_ag_indicators_t *indicators)
107 gstr = g_string_new("\r\n+CIND: ");
108 DBG("__bt_get_indicator_values");
109 for (i = 0; indicators[i].indicator_range != NULL; i++) {
111 g_string_append_printf(gstr, "%d",
112 indicators[i].hfp_value);
114 g_string_append_printf(gstr, ",%d",
115 indicators[i].hfp_value);
117 g_string_append(gstr, "\r\n");
119 return g_string_free(gstr, FALSE);
122 static int __bt_check_hdset(bt_ag_info_t *hdset)
124 bt_ag_slconn_t *slconn = hdset->slc;
126 if (!hdset->hfp_active)
129 if (slconn->is_client_active)
136 static int __bt_hfp_cmp(bt_ag_info_t *hs)
144 /* LCOV_EXCL_START */
145 static int __bt_cwa_cmp(bt_ag_info_t *hs)
150 if (hs->slc->is_cwa_enabled)
156 gboolean __bt_ring_timer_cb(gpointer data)
158 _bt_ag_send_foreach_headset(active_devices, NULL, "\r\nRING\r\n");
161 _bt_ag_send_foreach_headset(active_devices, __bt_check_hdset,
162 "\r\n+CLIP: \"%s\",%d\r\n",
163 ag.number, ag.number_type);
168 int _bt_incoming_call_indicator(const char *number, int type)
171 bt_ag_slconn_t *slconn;
176 /* Get the updated list of connected devices */
177 hs = active_devices->data;
181 DBG("incoming_call_indicator: already calling....");
185 /*If inband ring supported then no need to send RING alert to HF */
186 if (!hs->hfp_active && slconn->is_inband_ring) {
187 DBG("Inband ring tone supported");
191 DBG("Inband ring tone not supported.. so send a RING to HF");
193 ag.number = g_strdup(number);
194 ag.number_type = type;
196 if (slconn->is_inband_ring &&
197 hs->state != HEADSET_STATE_ON_CALL) {
198 slconn->is_pending_ring = TRUE;
202 __bt_ring_timer_cb(NULL);
203 ag.ring_timer = g_timeout_add(AG_RING_INTERVAL, __bt_ring_timer_cb, NULL);
208 int _bt_calling_stopped_indicator(void)
213 g_source_remove(ag.ring_timer);
220 /* In case SCO is in intermediate state to connect */
221 dev = active_devices->data;
223 if (!dev->slc->is_pending_ring && !ag.ring_timer)
226 dev->slc->is_pending_ring = FALSE;
232 void _bt_hfp_set_ag_indicator(uint32_t ag_features,
233 const bt_ag_indicators_t *ag_indicators, int rh,
236 DBG("Set Ag Features");
237 ag.telephony_ready = TRUE;
238 ag.features = ag_features;
239 ag.indicators = ag_indicators;
244 void _bt_hfp_deinitialize(void)
247 memset(&ag, 0, sizeof(ag));
248 ag.rh = BT_RSP_HOLD_NOT_SUPPORTED;
252 /* LCOV_EXCL_START */
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;
558 case BT_HFP_MICROPHONE_GAIN:
559 if (slconn->microphone_gain == gain) {
560 DBG("Ignoring no-change in microphone gain");
563 property = "MicrophoneGain";
564 slconn->microphone_gain = gain;
567 DBG("Unknown gain setting\n");
571 _bt_ag_agent_emit_property_changed(ag_dbus_conn, hs->path,
572 BT_HEADSET_INTERFACE, property,
573 g_variant_new("q", gain));
577 int _bt_hfp_signal_gain_setting(bt_ag_info_t *hs, const char *buf)
582 if (strlen(buf) < 8) {
583 DBG("very short string to use for Gain setting\n");
587 gain = (uint16_t) strtol(&buf[7], NULL, 10);
589 err = __bt_headset_set_gain(hs, gain, buf[5]);
590 if (err < 0 && err != -EALREADY)
593 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 /* LCOV_EXCL_START */
604 int _bt_hfp_dtmf_tone(bt_ag_info_t *hs, const char *buf)
608 if (strlen(buf) < 8) {
609 printf("Too short string for DTMF tone");
614 if (tone >= '#' && tone <= 'D')
615 _bt_hfp_channel_dtmf_request(tone, hs);
622 int _bt_hfp_set_speaker_gain(bt_ag_info_t *hs,
626 char type = BT_HFP_SPEAKER_GAIN;
628 err = __bt_headset_set_gain(hs, gain_value, type);
630 return BT_HFP_AGENT_ERROR_INTERNAL;
632 if (hs->state == HEADSET_STATE_ON_CALL) {
633 err = _bt_ag_send_at(hs, "\r\n+VG%c=%u\r\n", type,
636 return BT_HFP_AGENT_ERROR_INTERNAL;
638 return BT_HFP_AGENT_ERROR_NONE;
641 int _bt_hfp_set_microphone_gain(bt_ag_info_t *hs,
645 char type = BT_HFP_MICROPHONE_GAIN;
649 return BT_HFP_AGENT_ERROR_INVALID_PARAM;
652 err = __bt_headset_set_gain(hs, gain_value, type);
654 return BT_HFP_AGENT_ERROR_INTERNAL;
656 if (hs->state == HEADSET_STATE_ON_CALL) {
657 err = _bt_ag_send_at(hs, "\r\n+VG%c=%u\r\n", type,
660 return BT_HFP_AGENT_ERROR_INTERNAL;
662 return BT_HFP_AGENT_ERROR_NONE;
666 int _bt_hfp_set_voice_dial(bt_ag_info_t *hs,
669 DBG("_bt_hfp_set_voice_dial = %d", enable);
671 if (_bt_ag_send_at(hs, "\r\n+BVRA: %d\r\n", enable) < 0)
672 return BT_HFP_AGENT_ERROR_INTERNAL;
674 return BT_HFP_AGENT_ERROR_NONE;
677 int _bt_hfp_send_vendor_cmd(bt_ag_info_t *hs,
680 DBG("_bt_hfp_send_vendor_cmd = %s", cmd);
682 if (_bt_ag_send_at(hs, "\r\n%s\r\n", cmd) < 0)
683 return BT_HFP_AGENT_ERROR_INTERNAL;
685 return BT_HFP_AGENT_ERROR_NONE;
689 int _bt_vendor_cmd_response(void *t_device,
690 bt_hfp_agent_error_t err)
692 return _bt_ag_send_response(t_device, err);
695 /* LCOV_EXCL_START */
696 int _bt_hfp_vendor_cmd(bt_ag_info_t *hs, const char *buf)
698 DBG("XSAT vendor command");
700 _bt_hfp_vendor_cmd_request(buf, hs);
705 int _bt_list_current_call_indicator(bt_ag_info_t *hs, int index, int direction,
706 int mode, int status, const char *call_num, int conference, int t_num)
708 if (call_num && strlen(call_num) > 0) {
710 "\r\n+CLCC: %d,%d,%d,%d,%d,\"%s\",%d\r\n",
711 index, direction, status, mode, conference,
715 "\r\n+CLCC: %d,%d,%d,%d,%d\r\n",
716 index, direction, status, mode, conference);
721 int _bt_subscriber_number_indicator(const char *call_num, int type, int service)
726 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
727 "\r\n+CNUM: ,%s,%d,,%d\r\n",
728 call_num, type, service);
733 int _bt_subscriber_number_response(void *t_device,
734 bt_hfp_agent_error_t err)
736 return _bt_ag_send_response(t_device, err);
739 /* LCOV_EXCL_START */
740 int _bt_hfp_subscriber_number(bt_ag_info_t *hs, const char *buf)
742 _bt_hfp_subscriber_number_request(hs);
747 int _bt_call_waiting_indicator(const char *number, int type)
752 DBG("Call waiting indicator to hf");
753 _bt_ag_send_foreach_headset(active_devices, __bt_cwa_cmp,
754 "\r\n+CCWA: \"%s\",%d\r\n",
760 int _bt_list_current_calls_response(void *t_device,
761 bt_hfp_agent_error_t err)
763 return _bt_ag_send_response(t_device, err);
766 /* LCOV_EXCL_START */
767 int _bt_hfp_list_current_calls(bt_ag_info_t *hs, const char *buf)
769 _bt_list_current_calls(hs);
774 int _bt_hfp_extended_errors(bt_ag_info_t *hs, const char *buf)
776 bt_ag_slconn_t *slconn = hs->slc;
782 slconn->is_cme_enabled = TRUE;
783 DBG("CME errors enabled for headset %p", hs);
785 slconn->is_cme_enabled = FALSE;
786 DBG("CME errors disabled for headset %p", hs);
789 return _bt_ag_send_at(hs, "\r\nOK\r\n");
792 int _bt_hfp_call_waiting_notify(bt_ag_info_t *hs, const char *buf)
794 bt_ag_slconn_t *slconn = hs->slc;
800 slconn->is_cwa_enabled = TRUE;
801 DBG("Call waiting notification enabled for headset %p", hs);
803 slconn->is_cwa_enabled = FALSE;
804 DBG("Call waiting notification disabled for headset %p", hs);
807 return _bt_ag_send_at(hs, "\r\nOK\r\n");
811 int _bt_operator_selection_response(void *t_device,
812 bt_hfp_agent_error_t err)
814 return _bt_ag_send_response(t_device, err);
817 int _bt_call_hold_response(void *t_device, bt_hfp_agent_error_t err)
819 return _bt_ag_send_response(t_device, err);
822 int _bt_nr_and_ec_response(void *t_device, bt_hfp_agent_error_t err)
824 bt_ag_info_t *hs = t_device;
825 bt_ag_slconn_t *slconn = hs->slc;
827 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
830 for (l = hs->nrec_cbs; l; l = l->next) {
831 struct hs_nrec_callback *nrec_cb = l->data;
833 nrec_cb->cb(hs, slconn->is_nrec_req,
837 slconn->is_nrec = hs->slc->is_nrec_req;
840 return _bt_ag_send_response(t_device, err);
843 int _bt_voice_dial_response(void *t_device, bt_hfp_agent_error_t err)
845 return _bt_ag_send_response(t_device, err);
848 int _bt_operator_selection_indicator(int mode, const char *oper)
853 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
854 "\r\n+COPS: %d,0,\"%s\"\r\n",
859 /* LCOV_EXCL_START */
860 int _bt_hfp_operator_selection(bt_ag_info_t *hs, const char *buf)
867 _bt_hfp_get_operator_selection_request(hs);
871 return _bt_ag_send_at(hs, "\r\n+CME ERROR: %d\r\n",
872 HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
874 return _bt_ag_send_at(hs, "\r\nOK\r\n");
883 int _bt_hfp_nr_and_ec(bt_ag_info_t *hs, const char *buf)
885 bt_ag_slconn_t *slconn = hs->slc;
891 slconn->is_nrec_req = FALSE;
893 slconn->is_nrec_req = TRUE;
895 _bt_hfp_noise_red_and_echo_cancel_request(slconn->is_nrec_req, hs);
900 int _bt_hfp_voice_dial(bt_ag_info_t *hs, const char *buf)
902 bt_ag_slconn_t *slconn = hs->slc;
913 _bt_hfp_voice_dial_request(enable, hs);
915 slconn->is_voice_recognition_running = enable;
920 int _bt_hfp_indicators_activation(bt_ag_info_t *hs, const char *buf)
922 if (strlen(buf) < 7) {
923 printf("Invalid indicator activation request\n");
927 _bt_hfp_set_indicators(&buf[6], hs);
932 int _bt_indicators_activation_response(void *t_device,
933 bt_hfp_agent_error_t err)
935 return _bt_ag_send_response(t_device, err);
938 int _bt_select_phonebook_memory_status_response(void *t_device,
940 uint32_t total, uint32_t used,
941 bt_hfp_agent_error_t err)
943 bt_ag_info_t *hs = t_device;
944 bt_ag_slconn_t *slconn = hs->slc;
946 if (err != (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
947 if (slconn->is_cme_enabled)
948 return _bt_ag_send_at(hs,
949 "\r\n+CME ERROR: %d\r\n", err);
951 return _bt_ag_send_at(hs, "\r\nERROR\r\n");
957 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
958 "\r\n+CPBS: %s,%d,%d\r\n",
961 return _bt_ag_send_at(hs, "\r\nOK\r\n");
964 int _bt_select_phonebook_memory_list_response(void *t_device,
966 bt_hfp_agent_error_t err)
968 bt_ag_info_t *hs = t_device;
969 bt_ag_slconn_t *slconn = hs->slc;
971 if ((err != (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) ||
973 if (slconn->is_cme_enabled)
974 return _bt_ag_send_at(hs,
975 "\r\n+CME ERROR: %d\r\n", err);
977 return _bt_ag_send_at(hs, "\r\nERROR\r\n");
984 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
985 "\r\n+CPBS: %s\r\n", buf);
988 return _bt_ag_send_at(hs, "\r\nOK\r\n");
991 int _bt_select_phonebook_memory_response(void *t_device,
992 bt_hfp_agent_error_t err)
994 return _bt_ag_send_response(t_device, err);
997 /* LCOV_EXCL_START */
998 int _bt_hfp_select_pb_memory(bt_ag_info_t *hs, const char *buf)
1000 if (strlen(buf) < 8)
1003 if (buf[7] == '?') {
1004 _bt_hfp_select_phonebook_memory_status(hs);
1008 if (buf[7] == '=') {
1009 if (buf[8] == '?') {
1010 _bt_hfp_select_phonebook_memory_list(hs);
1013 _bt_hfp_select_phonebook_memory(hs, &buf[8]);
1019 /* LCOV_EXCL_STOP */
1021 int _bt_read_phonebook_entries_list_response(void *t_device,
1023 uint32_t number_length,
1024 uint32_t name_length,
1025 bt_hfp_agent_error_t err)
1027 bt_ag_info_t *hs = t_device;
1028 bt_ag_slconn_t *slconn = hs->slc;
1033 if (err != (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
1034 if (slconn->is_cme_enabled)
1035 return _bt_ag_send_at(hs,
1036 "\r\n+CME ERROR: %d\r\n", err);
1038 return _bt_ag_send_at(hs, "\r\nERROR\r\n");
1044 send_err = _bt_ag_send_at(hs, "\r\n+CPBR: (%d-%d),%d,%d\r\n",
1045 index, used, number_length, name_length);
1049 return _bt_ag_send_at(hs, "\r\nOK\r\n");
1052 int _bt_read_phonebook_entries_response(void *t_device,
1053 bt_hfp_agent_error_t err)
1055 return _bt_ag_send_response(t_device, err);
1058 /* LCOV_EXCL_START */
1059 int _bt_read_phonebook_entries_indicator(const char *name, const char *number,
1063 const char *pos = NULL;
1066 while (*pos == ' ' || *pos == '\t')
1069 /* 145 means international access code, otherwise 129 is used */
1073 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1074 "\r\n+CPBR: %d,\"%s\",%d,\"%s\"\r\n",
1075 handle, number, type, name);
1079 int _bt_hfp_read_pb_entries(bt_ag_info_t *hs, const char *buf)
1081 if (strlen(buf) < 8)
1088 _bt_hfp_read_phonebook_entries_list(hs);
1090 _bt_hfp_read_phonebook_entries(hs, &buf[8]);
1094 /* LCOV_EXCL_STOP */
1096 int _bt_find_phonebook_entries_status_response(void *t_device,
1097 bt_hfp_agent_error_t err)
1099 return _bt_ag_send_response(t_device, err);
1102 int _bt_find_phonebook_entries_response(void *t_device,
1103 bt_hfp_agent_error_t err)
1105 return _bt_ag_send_response(t_device, err);
1108 int _bt_find_phonebook_entries_status_indicator(uint32_t number_length,
1109 uint32_t name_length)
1111 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1112 "\r\n+CPBF: %d,%d\r\n",
1113 number_length, name_length);
1118 /* LCOV_EXCL_START */
1119 int _bt_hfp_find_pb_entires(bt_ag_info_t *hs, const char *buf)
1121 if (strlen(buf) < 8)
1128 _bt_hfp_find_phonebook_entries_status(hs);
1130 _bt_hfp_find_phonebook_entries(hs, &buf[8]);
1134 /* LCOV_EXCL_STOP */
1136 int _bt_supported_character_generic_response(void *t_device,
1137 char *character_set_list,
1138 bt_hfp_agent_error_t err)
1140 bt_ag_info_t *hs = t_device;
1141 bt_ag_slconn_t *slconn = hs->slc;
1143 if (err != (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
1144 if (slconn->is_cme_enabled)
1145 return _bt_ag_send_at(hs,
1146 "\r\n+CME ERROR: %d\r\n", err);
1148 return _bt_ag_send_at(hs, "\r\nERROR\r\n");
1151 if (NULL != character_set_list) {
1152 if (!active_devices)
1155 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1156 "\r\n+CSCS: %s\r\n", character_set_list);
1158 return _bt_ag_send_at(hs, "\r\nOK\r\n");
1161 int _bt_set_characterset_generic_response(void *t_device,
1162 bt_hfp_agent_error_t err)
1164 return _bt_ag_send_response(t_device, err);
1167 /* LCOV_EXCL_START */
1168 int _bt_hfp_select_character_set(bt_ag_info_t *hs, const char *buf)
1171 if (strlen(buf) < 7)
1174 if (buf[7] == '?') {
1175 _bt_hfp_get_character_set(hs);
1179 if (buf[7] == '=') {
1181 _bt_hfp_list_supported_character(hs);
1183 _bt_hfp_set_character_set(hs, &buf[8]);
1189 /* LCOV_EXCL_STOP */
1191 int _bt_battery_charge_status_response(void *t_device,
1194 bt_hfp_agent_error_t err)
1196 bt_ag_info_t *hs = t_device;
1198 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
1199 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1200 "\r\n+CBC: %d,%d\r\n", bcs, bcl);
1203 return _bt_ag_send_response(hs, err);
1206 /* LCOV_EXCL_START */
1207 int _bt_hfp_get_battery_charge_status(bt_ag_info_t *hs, const char *buf)
1209 if (strlen(buf) < 6)
1213 return _bt_ag_send_response(hs, HFP_STATE_MNGR_ERR_NONE);
1215 _bt_hfp_get_battery_property(hs);
1219 int _bt_hfp_apl_command(bt_ag_info_t *hs, const char *buf)
1221 DBG("Got Apple command: %s", buf);
1223 return _bt_ag_send_response(hs, HFP_STATE_MNGR_ERR_NONE);
1225 /* LCOV_EXCL_STOP */
1227 /* convert signal strength to a RSSI level */
1228 static int __bt_telephony_convert_signal_to_rssi(int signal)
1230 /* input : BT signal strength (0~5) */
1231 /* output : RSSI strength (0~31) */
1247 int _bt_signal_quality_response(void *t_device,
1250 bt_hfp_agent_error_t err)
1252 bt_ag_info_t *hs = t_device;
1254 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
1255 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1256 "\r\n+CSQ: %d,%d\r\n",
1257 __bt_telephony_convert_signal_to_rssi(rssi), ber);
1259 return _bt_ag_send_response(hs, err);
1262 /* LCOV_EXCL_START */
1263 int _bt_telephony_signal_quality_list_supported_response(void *t_device,
1264 bt_hfp_agent_error_t err)
1266 bt_ag_info_t *device = t_device;
1268 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
1269 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1270 "\r\n+CSQ: (0-31,99),(99)\r\n");
1272 return _bt_ag_send_response(device, err);
1275 int _bt_hfp_get_signal_quality(bt_ag_info_t *hs, const char *buf)
1277 if (strlen(buf) < 6)
1281 _bt_telephony_signal_quality_list_supported_response(hs,
1282 HFP_STATE_MNGR_ERR_NONE);
1284 _bt_ag_agent_get_signal_quality(hs);
1288 /* LCOV_EXCL_STOP */
1290 int _bt_hfp_get_activity_status_rsp(void *t_device,
1292 bt_hfp_agent_error_t err)
1294 bt_ag_info_t *device = t_device;
1296 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
1297 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1298 "\r\n+CPAS: %d\r\n", status);
1301 return _bt_ag_send_response(device, err);
1304 /* LCOV_EXCL_START */
1305 int _bt_hfp_get_activity_status(bt_ag_info_t *device, const char *buf)
1307 if (strlen(buf) < 7)
1310 if (buf[7] == '?') {
1311 return _bt_ag_send_response(device,
1312 HFP_STATE_MNGR_ERR_AG_FAILURE);
1313 } else if (buf[7] == '=') {
1314 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1315 "\r\n+CPAS: (0-4)\r\n");
1316 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1319 _bt_get_activity_status(device);
1322 /* LCOV_EXCL_STOP */
1324 int _bt_hfp_get_equipment_identity_rsp(void *t_device,
1325 char *identity, bt_hfp_agent_error_t err)
1328 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1329 "\r\n+CGSN: %s\r\n", identity);
1330 return _bt_ag_send_response(t_device, err);
1333 int _bt_hfp_get_imsi_rsp(void *t_device,
1334 char *mcc, char *mnc, char *msin, bt_hfp_agent_error_t err)
1336 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE)
1337 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1338 "\r\n%s%s%s\r\n", mcc, mnc, msin);
1339 return _bt_ag_send_response(t_device, err);
1342 int _bt_hfp_get_creg_status_rsp(void *t_device,
1343 int n, int status, bt_hfp_agent_error_t err)
1345 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE)
1346 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1347 "\r\n+CREG: %d,%d\r\n", n, status);
1348 return _bt_ag_send_response(t_device, err);
1351 int _bt_hfp_get_equipment_identity(bt_ag_info_t *device, const char *buf)
1353 int len = strlen(buf);
1355 if (len == 9 && buf[7] == '=' && buf[8] == '?') /* AT+CGSN=? */
1356 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1361 _bt_hfp_get_equipment_identity_req(device); /* AT+CGSN */
1365 int _bt_hfp_get_model_info_rsp(void *t_device, char *model,
1366 bt_hfp_agent_error_t err)
1369 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1370 "\r\n+CGMM: %s\r\n", model);
1371 return _bt_ag_send_response(t_device, err);
1374 int _bt_hfp_get_model_information(bt_ag_info_t *device, const char *buf)
1376 int len = strlen(buf);
1378 if (len == 9 && buf[7] == '=' && buf[8] == '?') /* AT+CGMM=? */
1379 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1384 _bt_hfp_get_model_info_req(device);/* AT+CGMM */
1388 int _bt_hfp_get_device_manufacturer_rsp(void *t_device,
1389 char *manufacturer, bt_hfp_agent_error_t err)
1392 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1393 "\r\n+CGMI: %s\r\n", manufacturer);
1394 return _bt_ag_send_response(t_device, err);
1397 int _bt_hfp_get_device_manufacturer(bt_ag_info_t *device, const char *buf)
1399 int len = strlen(buf);
1401 if (len == 9 && buf[7] == '=' && buf[8] == '?') /* AT+CGMI=? */
1402 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1407 _bt_hfp_get_device_manufacturer_req(device);
1411 int _bt_hfp_get_imsi(bt_ag_info_t *device, const char *buf)
1413 int len = strlen(buf);
1414 DBG_SECURE("Buf %s", buf);
1417 _bt_hfp_get_imsi_req(device);
1419 _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_INVALID_INDEX);
1424 int _bt_hfp_get_creg_status(bt_ag_info_t *device, const char *buf)
1426 int len = strlen(buf);
1427 DBG_SECURE("buf %s", buf);
1428 if (len < 7 || len > 9)
1431 _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_INVALID_INDEX);
1432 else if (buf[7] == '=')
1433 _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_INVALID_INDEX);
1434 else if (buf[7] == '?')
1435 _bt_hfp_get_creg_status_req(device);
1439 int _bt_hfp_get_revision_info_rsp(void *t_device, char *revision,
1440 bt_hfp_agent_error_t err)
1443 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1444 "\r\n+CGMR: %s\r\n", revision);
1445 return _bt_ag_send_response(t_device, err);
1448 int _bt_hfp_get_revision_information(bt_ag_info_t *device, const char *buf)
1450 int len = strlen(buf);
1452 if (len == 9 && buf[7] == '=' && buf[8] == '?') /* AT+CGMR=? */
1453 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1458 _bt_hfp_get_revision_info_req(device);