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,
48 /* AT+BRSF response */
49 int _bt_hfp_supported_features(bt_ag_info_t *hs, const char *buf)
51 bt_ag_slconn_t *slconn = hs->slc;
53 // bt_hfp_agent_error_t ret = BT_HFP_AGENT_ERROR_NONE;
59 slconn->hs_features = strtoul(&buf[8], NULL, 10);
60 #if 0 /* SCO is crashed if below is called when SCO is opened by hf-agent */
61 if (slconn->hs_features & BT_HF_FEATURE_CODEC_NEGOTIATION) {
62 ret = _bt_ag_set_codec(hs, "SetWbsParameters");
63 if (ret != BT_HFP_AGENT_ERROR_NONE)
64 ERR("Unable to set the default WBC codec");
66 /* Default codec is NB */
67 ret = _bt_ag_set_codec(hs, "SetNbParameters");
68 if (ret != BT_HFP_AGENT_ERROR_NONE)
69 ERR("Unable to set the default NBC codec");
72 err = _bt_ag_send_at(hs, "\r\n+BRSF: %u\r\n", ag.features);
76 return _bt_ag_send_at(hs, "\r\nOK\r\n");
79 static char *__bt_get_indicator_ranges(const bt_ag_indicators_t *indicators)
84 DBG("__bt_get_indicator_ranges");
85 gstr = g_string_new("\r\n+CIND: ");
87 for (i = 0; indicators[i].indicator_desc != NULL; i++) {
89 g_string_append_printf(gstr, "(\"%s\",(%s))",
90 indicators[i].indicator_desc,
91 indicators[i].indicator_range);
93 g_string_append_printf(gstr, ",(\"%s\",(%s))",
94 indicators[i].indicator_desc,
95 indicators[i].indicator_range);
97 g_string_append(gstr, "\r\n");
98 return g_string_free(gstr, FALSE);
101 static char *__bt_get_indicator_values(const bt_ag_indicators_t *indicators)
106 gstr = g_string_new("\r\n+CIND: ");
107 DBG("__bt_get_indicator_values");
108 for (i = 0; indicators[i].indicator_range != NULL; i++) {
110 g_string_append_printf(gstr, "%d",
111 indicators[i].hfp_value);
113 g_string_append_printf(gstr, ",%d",
114 indicators[i].hfp_value);
116 g_string_append(gstr, "\r\n");
118 return g_string_free(gstr, FALSE);
121 static int __bt_check_hdset(bt_ag_info_t *hdset)
123 bt_ag_slconn_t *slconn = hdset->slc;
125 if (!hdset->hfp_active)
128 if (slconn->is_client_active)
134 static int __bt_hfp_cmp(bt_ag_info_t *hs)
142 static int __bt_cwa_cmp(bt_ag_info_t *hs)
147 if (hs->slc->is_cwa_enabled)
153 gboolean __bt_ring_timer_cb(gpointer data)
155 _bt_ag_send_foreach_headset(active_devices, NULL, "\r\nRING\r\n");
158 _bt_ag_send_foreach_headset(active_devices, __bt_check_hdset,
159 "\r\n+CLIP: \"%s\",%d\r\n",
160 ag.number, ag.number_type);
165 int _bt_incoming_call_indicator(const char *number, int type)
168 bt_ag_slconn_t *slconn;
173 /* Get the updated list of connected devices */
174 hs = active_devices->data;
178 DBG("incoming_call_indicator: already calling....");
182 /*If inband ring supported then no need to send RING alert to HF */
183 if (!hs->hfp_active && slconn->is_inband_ring) {
184 DBG("Inband ring tone supported");
188 DBG("Inband ring tone not supported.. so send a RING to HF");
190 ag.number = g_strdup(number);
191 ag.number_type = type;
193 if (slconn->is_inband_ring &&
194 hs->state != HEADSET_STATE_ON_CALL) {
195 slconn->is_pending_ring = TRUE;
199 __bt_ring_timer_cb(NULL);
200 ag.ring_timer = g_timeout_add(AG_RING_INTERVAL, __bt_ring_timer_cb, NULL);
205 int _bt_calling_stopped_indicator(void)
210 g_source_remove(ag.ring_timer);
217 /* In case SCO is in intermediate state to connect */
218 dev = active_devices->data;
220 if (!dev->slc->is_pending_ring && !ag.ring_timer)
223 dev->slc->is_pending_ring = FALSE;
228 void _bt_hfp_set_ag_indicator(uint32_t ag_features,
229 const bt_ag_indicators_t *ag_indicators, int rh,
232 DBG("Set Ag Features");
233 ag.telephony_ready = TRUE;
234 ag.features = ag_features;
235 ag.indicators = ag_indicators;
240 void _bt_hfp_deinitialize(void)
243 memset(&ag, 0, sizeof(ag));
244 ag.rh = BT_RSP_HOLD_NOT_SUPPORTED;
248 /* Send event indication call from Statemanager module */
249 bt_hfp_agent_error_t _bt_hfp_event_indicator(int index)
251 if (!active_devices) {
252 DBG("No Active devices present");
253 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
257 DBG("Indicate event called but event reporting is disabled");
258 return BT_HFP_AGENT_ERROR_INTERNAL;
261 DBG("Sending event notification to hf....");
263 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
264 "\r\n+CIEV: %d,%d\r\n", index + 1,
265 ag.indicators[index].hfp_value);
267 return BT_HFP_AGENT_ERROR_NONE;
270 /* AT+CIND response */
271 int _bt_hfp_report_indicators(bt_ag_info_t *hs, const char *buf)
280 str = __bt_get_indicator_ranges(ag.indicators);
282 str = __bt_get_indicator_values(ag.indicators);
284 err = _bt_ag_send_at(hs, "%s", str);
291 return _bt_ag_send_at(hs, "\r\nOK\r\n");
294 /* AT+CMER response */
295 int _bt_event_reporting_response(void *t_device,
296 bt_hfp_agent_error_t err)
298 bt_ag_info_t *hdset = t_device;
299 bt_ag_slconn_t *slconn = hdset->slc;
302 if (err != (bt_hfp_agent_error_t) HFP_STATE_MNGR_ERR_NONE)
303 return _bt_ag_send_response(t_device, err);
305 ret_val = _bt_ag_send_at(hdset, "\r\nOK\r\n");
309 if (hdset->state != HEADSET_STATE_CONNECTING)
312 if (slconn->hs_features & HANDSFREE_FEATURE_CALL_WAITING_AND_3WAY &&
313 ag.features & BT_AG_FEATURE_THREE_WAY_CALL)
316 _bt_ag_slconn_complete(hdset);
321 int _bt_hfp_enable_indicators(bt_ag_info_t *hdset, const char *buffer)
323 if (strlen(buffer) < 13)
326 /* tokenks can be <mode>,<keyp>,<disp>,<ind>,<bfr>*/
327 char **ind_tokens = g_strsplit(&buffer[8], ",", 5);
329 if (g_strv_length(ind_tokens) < 4) {
330 g_strfreev(ind_tokens);
334 ag.er_mode = atoi(ind_tokens[0]);
335 ag.er_ind = atoi(ind_tokens[3]);
337 DBG("hfp_enable_indicators (CMER): indicator=%d, mode=%d",
338 ag.er_ind, ag.er_mode);
340 g_strfreev(ind_tokens);
346 _bt_hfp_update_event_request(ag.er_ind, hdset);
354 /* AT+CHLD response */
355 int _bt_hfp_call_hold(bt_ag_info_t *hs, const char *buf)
363 _bt_hfp_call_hold_request(&buf[8], hs);
367 err = _bt_ag_send_at(hs, "\r\n+CHLD: (%s)\r\n", ag.chld);
371 err = _bt_ag_send_at(hs, "\r\nOK\r\n");
375 _bt_ag_slconn_complete(hs);
380 int _bt_key_press_response(void *t_device, bt_hfp_agent_error_t err)
382 return _bt_ag_send_response(t_device, err);
385 int _bt_hfp_key_press(bt_ag_info_t *hs, const char *buf)
391 g_source_remove(ag.ring_timer);
395 _bt_hfp_key_press_request(&buf[8], hs);
400 int _bt_answer_call_response(void *hs, bt_hfp_agent_error_t err)
402 return _bt_ag_send_response(hs, err);
405 int _bt_hfp_answer_call(bt_ag_info_t *hs, const char *buf)
408 g_source_remove(ag.ring_timer);
418 g_free(remote_dev_path);
420 remote_dev_path = g_strdup(hs->path);
422 _bt_hfp_answer_call_request(hs);
426 int _bt_terminate_call_response(void *t_device,
427 hfp_state_manager_err_t err)
429 bt_ag_info_t *hs = t_device;
431 if (err != HFP_STATE_MNGR_ERR_NONE)
432 return _bt_ag_send_response(hs, err);
434 return _bt_ag_send_at(hs, "\r\nOK\r\n");
437 int _bt_hfp_terminate_call(bt_ag_info_t *hs, const char *buf)
445 g_source_remove(ag.ring_timer);
449 _bt_hfp_terminate_call_request(hs);
454 int _bt_hfp_cli_notification(bt_ag_info_t *hs, const char *buf)
456 bt_ag_slconn_t *slconn = hs->slc;
461 slconn->is_client_active = buf[8] == '1' ? TRUE : FALSE;
463 return _bt_ag_send_at(hs, "\r\nOK\r\n");
466 int _bt_response_and_hold_response(void *t_device,
467 bt_hfp_agent_error_t err)
469 return _bt_ag_send_response(t_device, err);
472 int _bt_hfp_response_and_hold(bt_ag_info_t *hs, const char *buf)
478 if (ag.rh == BT_RSP_HOLD_NOT_SUPPORTED)
479 return _bt_ag_send_response(hs,
480 HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
483 _bt_hfp_response_and_hold_request(hs);
488 _bt_ag_send_at(hs, "\r\n+BTRH: %d\r\n", ag.rh);
490 return _bt_ag_send_at(hs, "\r\nOK\r\n");
493 int _bt_hfp_last_dialed_number(bt_ag_info_t *hs, const char *buf)
496 g_free(remote_dev_path);
498 remote_dev_path = g_strdup(hs->path);
499 _bt_hfp_last_dialed_number_request(hs);
504 int _bt_dial_number_response(void *t_device, bt_hfp_agent_error_t err)
506 return _bt_ag_send_response(t_device, err);
509 int _bt_hfp_dial_number(bt_ag_info_t *hs, const char *buf)
511 char number[MAX_BUFFER_SIZE];
514 buf_len = strlen(buf);
516 if (buf[buf_len - 1] != ';') {
517 DBG("Reject the non-voice call dial number request");
521 memset(number, 0, sizeof(number));
522 strncpy(number, &buf[3], buf_len - 4);
525 g_free(remote_dev_path);
527 remote_dev_path = g_strdup(hs->path);
529 _bt_hfp_dial_number_request(number, hs);
534 static int __bt_headset_set_gain(bt_ag_info_t *hs, uint16_t gain, char type)
536 bt_ag_slconn_t *slconn = hs->slc;
537 const char *property;
540 DBG("Invalid gain value: %u", gain);
545 case BT_HFP_SPEAKER_GAIN:
546 if (slconn->speaker_gain == gain) {
547 DBG("Ignoring no-change in speaker gain");
550 property = "SpeakerGain";
551 slconn->speaker_gain = gain;
553 case BT_HFP_MICROPHONE_GAIN:
554 if (slconn->microphone_gain == gain) {
555 DBG("Ignoring no-change in microphone gain");
558 property = "MicrophoneGain";
559 slconn->microphone_gain = gain;
562 DBG("Unknown gain setting\n");
566 _bt_ag_agent_emit_property_changed(ag_dbus_conn, hs->path,
567 BT_HEADSET_INTERFACE, property,
568 g_variant_new("q", gain));
572 int _bt_hfp_signal_gain_setting(bt_ag_info_t *hs, const char *buf)
577 if (strlen(buf) < 8) {
578 DBG("very short string to use for Gain setting\n");
582 gain = (uint16_t) strtol(&buf[7], NULL, 10);
584 err = __bt_headset_set_gain(hs, gain, buf[5]);
585 if (err < 0 && err != -EALREADY)
588 return _bt_ag_send_at(hs, "\r\nOK\r\n");
591 int _bt_transmit_dtmf_response(void *t_device,
592 bt_hfp_agent_error_t err)
594 return _bt_ag_send_response(t_device, err);
597 int _bt_hfp_dtmf_tone(bt_ag_info_t *hs, const char *buf)
601 if (strlen(buf) < 8) {
602 printf("Too short string for DTMF tone");
607 if (tone >= '#' && tone <= 'D')
608 _bt_hfp_channel_dtmf_request(tone, hs);
615 int _bt_hfp_set_speaker_gain(bt_ag_info_t *hs,
619 char type = BT_HFP_SPEAKER_GAIN;
621 err = __bt_headset_set_gain(hs, gain_value, type);
623 return BT_HFP_AGENT_ERROR_INTERNAL;
625 if (hs->state == HEADSET_STATE_ON_CALL) {
626 err = _bt_ag_send_at(hs, "\r\n+VG%c=%u\r\n", type,
629 return BT_HFP_AGENT_ERROR_INTERNAL;
631 return BT_HFP_AGENT_ERROR_NONE;
634 int _bt_hfp_set_microphone_gain(bt_ag_info_t *hs,
638 char type = BT_HFP_MICROPHONE_GAIN;
642 return BT_HFP_AGENT_ERROR_INVALID_PARAM;
645 err = __bt_headset_set_gain(hs, gain_value, type);
647 return BT_HFP_AGENT_ERROR_INTERNAL;
649 if (hs->state == HEADSET_STATE_ON_CALL) {
650 err = _bt_ag_send_at(hs, "\r\n+VG%c=%u\r\n", type,
653 return BT_HFP_AGENT_ERROR_INTERNAL;
655 return BT_HFP_AGENT_ERROR_NONE;
659 int _bt_hfp_set_voice_dial(bt_ag_info_t *hs,
662 DBG("_bt_hfp_set_voice_dial = %d", enable);
664 if (_bt_ag_send_at(hs, "\r\n+BVRA: %d\r\n", enable) < 0)
665 return BT_HFP_AGENT_ERROR_INTERNAL;
667 return BT_HFP_AGENT_ERROR_NONE;
670 int _bt_hfp_send_vendor_cmd(bt_ag_info_t *hs,
673 DBG("_bt_hfp_send_vendor_cmd = %d", cmd);
675 if (_bt_ag_send_at(hs, "\r\n%s\r\n", cmd) < 0)
676 return BT_HFP_AGENT_ERROR_INTERNAL;
678 return BT_HFP_AGENT_ERROR_NONE;
681 int _bt_vendor_cmd_response(void *t_device,
682 bt_hfp_agent_error_t err)
684 return _bt_ag_send_response(t_device, err);
687 int _bt_hfp_vendor_cmd(bt_ag_info_t *hs, const char *buf)
689 DBG("XSAT vendor command");
691 _bt_hfp_vendor_cmd_request(buf, hs);
696 int _bt_list_current_call_indicator(bt_ag_info_t *hs, int index, int direction,
697 int mode, int status, const char *call_num, int conference, int t_num)
699 if (call_num && strlen(call_num) > 0) {
701 "\r\n+CLCC: %d,%d,%d,%d,%d,\"%s\",%d\r\n",
702 index, direction, status, mode, conference,
706 "\r\n+CLCC: %d,%d,%d,%d,%d\r\n",
707 index, direction, status, mode, conference);
712 int _bt_subscriber_number_indicator(const char *call_num, int type, int service)
717 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
718 "\r\n+CNUM: ,%s,%d,,%d\r\n",
719 call_num, type, service);
723 int _bt_subscriber_number_response(void *t_device,
724 bt_hfp_agent_error_t err)
726 return _bt_ag_send_response(t_device, err);
729 int _bt_hfp_subscriber_number(bt_ag_info_t *hs, const char *buf)
731 _bt_hfp_subscriber_number_request(hs);
736 int _bt_call_waiting_indicator(const char *number, int type)
741 DBG("Call waiting indicator to hf");
742 _bt_ag_send_foreach_headset(active_devices, __bt_cwa_cmp,
743 "\r\n+CCWA: \"%s\",%d\r\n",
748 int _bt_list_current_calls_response(void *t_device,
749 bt_hfp_agent_error_t err)
751 return _bt_ag_send_response(t_device, err);
754 int _bt_hfp_list_current_calls(bt_ag_info_t *hs, const char *buf)
756 _bt_list_current_calls(hs);
761 int _bt_hfp_extended_errors(bt_ag_info_t *hs, const char *buf)
763 bt_ag_slconn_t *slconn = hs->slc;
769 slconn->is_cme_enabled = TRUE;
770 DBG("CME errors enabled for headset %p", hs);
772 slconn->is_cme_enabled = FALSE;
773 DBG("CME errors disabled for headset %p", hs);
776 return _bt_ag_send_at(hs, "\r\nOK\r\n");
779 int _bt_hfp_call_waiting_notify(bt_ag_info_t *hs, const char *buf)
781 bt_ag_slconn_t *slconn = hs->slc;
787 slconn->is_cwa_enabled = TRUE;
788 DBG("Call waiting notification enabled for headset %p", hs);
790 slconn->is_cwa_enabled = FALSE;
791 DBG("Call waiting notification disabled for headset %p", hs);
794 return _bt_ag_send_at(hs, "\r\nOK\r\n");
797 int _bt_operator_selection_response(void *t_device,
798 bt_hfp_agent_error_t err)
800 return _bt_ag_send_response(t_device, err);
803 int _bt_call_hold_response(void *t_device, bt_hfp_agent_error_t err)
805 return _bt_ag_send_response(t_device, err);
808 int _bt_nr_and_ec_response(void *t_device, bt_hfp_agent_error_t err)
810 bt_ag_info_t *hs = t_device;
811 bt_ag_slconn_t *slconn = hs->slc;
813 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
816 for (l = hs->nrec_cbs; l; l = l->next) {
817 struct hs_nrec_callback *nrec_cb = l->data;
819 nrec_cb->cb(hs, slconn->is_nrec_req,
823 slconn->is_nrec = hs->slc->is_nrec_req;
826 return _bt_ag_send_response(t_device, err);
829 int _bt_voice_dial_response(void *t_device, bt_hfp_agent_error_t err)
831 return _bt_ag_send_response(t_device, err);
834 int _bt_operator_selection_indicator(int mode, const char *oper)
839 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
840 "\r\n+COPS: %d,0,\"%s\"\r\n",
845 int _bt_hfp_operator_selection(bt_ag_info_t *hs, const char *buf)
852 _bt_hfp_get_operator_selection_request(hs);
856 return _bt_ag_send_at(hs, "\r\n+CME ERROR: %d\r\n",
857 HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
859 return _bt_ag_send_at(hs, "\r\nOK\r\n");
868 int _bt_hfp_nr_and_ec(bt_ag_info_t *hs, const char *buf)
870 bt_ag_slconn_t *slconn = hs->slc;
876 slconn->is_nrec_req = FALSE;
878 slconn->is_nrec_req = TRUE;
880 _bt_hfp_noise_red_and_echo_cancel_request(slconn->is_nrec_req, hs);
885 int _bt_hfp_voice_dial(bt_ag_info_t *hs, const char *buf)
887 bt_ag_slconn_t *slconn = hs->slc;
898 _bt_hfp_voice_dial_request(enable, hs);
900 slconn->is_voice_recognition_running = enable;
905 int _bt_hfp_indicators_activation(bt_ag_info_t *hs, const char *buf)
907 if (strlen(buf) < 7) {
908 printf("Invalid indicator activation request\n");
912 _bt_hfp_set_indicators(&buf[6], hs);
916 int _bt_indicators_activation_response(void *t_device,
917 bt_hfp_agent_error_t err)
919 return _bt_ag_send_response(t_device, err);
922 int _bt_select_phonebook_memory_status_response(void *t_device,
924 uint32_t total, uint32_t used,
925 bt_hfp_agent_error_t err)
927 bt_ag_info_t *hs = t_device;
928 bt_ag_slconn_t *slconn = hs->slc;
930 if (err != (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
931 if (slconn->is_cme_enabled)
932 return _bt_ag_send_at(hs,
933 "\r\n+CME ERROR: %d\r\n", err);
935 return _bt_ag_send_at(hs, "\r\nERROR\r\n");
941 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
942 "\r\n+CPBS: %s,%d,%d\r\n",
945 return _bt_ag_send_at(hs, "\r\nOK\r\n");
948 int _bt_select_phonebook_memory_list_response(void *t_device,
950 bt_hfp_agent_error_t err)
952 bt_ag_info_t *hs = t_device;
953 bt_ag_slconn_t *slconn = hs->slc;
955 if ((err != (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) ||
957 if (slconn->is_cme_enabled)
958 return _bt_ag_send_at(hs,
959 "\r\n+CME ERROR: %d\r\n", err);
961 return _bt_ag_send_at(hs, "\r\nERROR\r\n");
968 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
969 "\r\n+CPBS: %s\r\n", buf);
972 return _bt_ag_send_at(hs, "\r\nOK\r\n");
975 int _bt_select_phonebook_memory_response(void *t_device,
976 bt_hfp_agent_error_t err)
978 return _bt_ag_send_response(t_device, err);
981 int _bt_hfp_select_pb_memory(bt_ag_info_t *hs, const char *buf)
987 _bt_hfp_select_phonebook_memory_status(hs);
993 _bt_hfp_select_phonebook_memory_list(hs);
996 _bt_hfp_select_phonebook_memory(hs, &buf[8]);
1003 int _bt_read_phonebook_entries_list_response(void *t_device,
1005 uint32_t number_length,
1006 uint32_t name_length,
1007 bt_hfp_agent_error_t err)
1009 bt_ag_info_t *hs = t_device;
1010 bt_ag_slconn_t *slconn = hs->slc;
1015 if (err != (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
1016 if (slconn->is_cme_enabled)
1017 return _bt_ag_send_at(hs,
1018 "\r\n+CME ERROR: %d\r\n", err);
1020 return _bt_ag_send_at(hs, "\r\nERROR\r\n");
1026 send_err = _bt_ag_send_at(hs, "\r\n+CPBR: (%d-%d),%d,%d\r\n",
1027 index, used, number_length, name_length);
1031 return _bt_ag_send_at(hs, "\r\nOK\r\n");
1034 int _bt_read_phonebook_entries_response(void *t_device,
1035 bt_hfp_agent_error_t err)
1037 return _bt_ag_send_response(t_device, err);
1040 int _bt_read_phonebook_entries_indicator(const char *name, const char *number,
1044 const char *pos = NULL;
1047 while (*pos == ' ' || *pos == '\t')
1050 /* 145 means international access code, otherwise 129 is used */
1054 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1055 "\r\n+CPBR: %d,\"%s\",%d,\"%s\"\r\n",
1056 handle, number, type, name);
1060 int _bt_hfp_read_pb_entries(bt_ag_info_t *hs, const char *buf)
1062 if (strlen(buf) < 8)
1069 _bt_hfp_read_phonebook_entries_list(hs);
1071 _bt_hfp_read_phonebook_entries(hs, &buf[8]);
1076 int _bt_find_phonebook_entries_status_response(void *t_device,
1077 bt_hfp_agent_error_t err)
1079 return _bt_ag_send_response(t_device, err);
1082 int _bt_find_phonebook_entries_response(void *t_device,
1083 bt_hfp_agent_error_t err)
1085 return _bt_ag_send_response(t_device, err);
1088 int _bt_find_phonebook_entries_status_indicator(uint32_t number_length,
1089 uint32_t name_length)
1091 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1092 "\r\n+CPBF: %d,%d\r\n",
1093 number_length, name_length);
1098 int _bt_hfp_find_pb_entires(bt_ag_info_t *hs, const char *buf)
1100 if (strlen(buf) < 8)
1107 _bt_hfp_find_phonebook_entries_status(hs);
1109 _bt_hfp_find_phonebook_entries(hs, &buf[8]);
1114 int _bt_supported_character_generic_response(void *t_device,
1115 char *character_set_list,
1116 bt_hfp_agent_error_t err)
1118 bt_ag_info_t *hs = t_device;
1119 bt_ag_slconn_t *slconn = hs->slc;
1121 if (err != (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
1122 if (slconn->is_cme_enabled)
1123 return _bt_ag_send_at(hs,
1124 "\r\n+CME ERROR: %d\r\n", err);
1126 return _bt_ag_send_at(hs, "\r\nERROR\r\n");
1129 if (NULL != character_set_list) {
1130 if (!active_devices)
1133 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1134 "\r\n+CSCS: %s\r\n", character_set_list);
1136 return _bt_ag_send_at(hs, "\r\nOK\r\n");
1139 int _bt_set_characterset_generic_response(void *t_device,
1140 bt_hfp_agent_error_t err)
1142 return _bt_ag_send_response(t_device, err);
1145 int _bt_hfp_select_character_set(bt_ag_info_t *hs, const char *buf)
1148 if (strlen(buf) < 7)
1151 if (buf[7] == '?') {
1152 _bt_hfp_get_character_set(hs);
1156 if (buf[7] == '=') {
1158 _bt_hfp_list_supported_character(hs);
1160 _bt_hfp_set_character_set(hs, &buf[8]);
1167 int _bt_battery_charge_status_response(void *t_device,
1170 bt_hfp_agent_error_t err)
1172 bt_ag_info_t *hs = t_device;
1174 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
1175 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1176 "\r\n+CBC: %d,%d\r\n", bcs, bcl);
1179 return _bt_ag_send_response(hs, err);
1182 int _bt_hfp_get_battery_charge_status(bt_ag_info_t *hs, const char *buf)
1184 if (strlen(buf) < 6)
1188 return _bt_ag_send_response(hs, HFP_STATE_MNGR_ERR_NONE);
1190 _bt_hfp_get_battery_property(hs);
1194 int _bt_hfp_apl_command(bt_ag_info_t *hs, const char *buf)
1196 DBG("Got Apple command: %s", buf);
1198 return _bt_ag_send_response(hs, HFP_STATE_MNGR_ERR_NONE);
1201 /* convert signal strength to a RSSI level */
1202 static int __bt_telephony_convert_signal_to_rssi(int signal)
1204 /* input : BT signal strength (0~5) */
1205 /* output : RSSI strength (0~31) */
1221 int _bt_signal_quality_response(void *t_device,
1224 bt_hfp_agent_error_t err)
1226 bt_ag_info_t *hs = t_device;
1228 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
1229 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1230 "\r\n+CSQ: %d,%d\r\n",
1231 __bt_telephony_convert_signal_to_rssi(rssi), ber);
1233 return _bt_ag_send_response(hs, err);
1236 int _bt_telephony_signal_quality_list_supported_response(void *t_device,
1237 bt_hfp_agent_error_t err)
1239 bt_ag_info_t *device = t_device;
1241 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
1242 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1243 "\r\n+CSQ: (0-31,99),(99)\r\n");
1245 return _bt_ag_send_response(device, err);
1248 int _bt_hfp_get_signal_quality(bt_ag_info_t *hs, const char *buf)
1250 if (strlen(buf) < 6)
1254 _bt_telephony_signal_quality_list_supported_response(hs,
1255 HFP_STATE_MNGR_ERR_NONE);
1257 _bt_ag_agent_get_signal_quality(hs);
1262 int _bt_hfp_get_activity_status_rsp(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+CPAS: %d\r\n", status);
1273 return _bt_ag_send_response(device, err);
1276 int _bt_hfp_get_activity_status(bt_ag_info_t *device, const char *buf)
1278 if (strlen(buf) < 7)
1281 if (buf[7] == '?') {
1282 return _bt_ag_send_response(device,
1283 HFP_STATE_MNGR_ERR_AG_FAILURE);
1284 } else if (buf[7] == '=') {
1285 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1286 "\r\n+CPAS: (0-4)\r\n");
1287 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1290 _bt_get_activity_status(device);
1294 int _bt_hfp_get_equipment_identity_rsp(void *t_device,
1295 char *identity, bt_hfp_agent_error_t err)
1298 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1299 "\r\n+CGSN: %s\r\n", identity);
1300 return _bt_ag_send_response(t_device, err);
1303 int _bt_hfp_get_imsi_rsp(void *t_device,
1304 char *mcc, char *mnc, char *msin, bt_hfp_agent_error_t err)
1306 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE)
1307 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1308 "\r\n%s%s%s\r\n", mcc, mnc, msin);
1309 return _bt_ag_send_response(t_device, err);
1312 int _bt_hfp_get_creg_status_rsp(void *t_device,
1313 int n, int status, bt_hfp_agent_error_t err)
1315 if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE)
1316 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1317 "\r\n+CREG: %d,%d\r\n", n, status);
1318 return _bt_ag_send_response(t_device, err);
1321 int _bt_hfp_get_equipment_identity(bt_ag_info_t *device, const char *buf)
1323 int len = strlen(buf);
1325 if (len == 9 && buf[7] == '=' && buf[8] == '?') /* AT+CGSN=? */
1326 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1331 _bt_hfp_get_equipment_identity_req(device); /* AT+CGSN */
1335 int _bt_hfp_get_model_info_rsp(void *t_device, char *model,
1336 bt_hfp_agent_error_t err)
1339 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1340 "\r\n+CGMM: %s\r\n", model);
1341 return _bt_ag_send_response(t_device, err);
1344 int _bt_hfp_get_model_information(bt_ag_info_t *device, const char *buf)
1346 int len = strlen(buf);
1348 if (len == 9 && buf[7] == '=' && buf[8] == '?') /* AT+CGMM=? */
1349 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1354 _bt_hfp_get_model_info_req(device);/* AT+CGMM */
1358 int _bt_hfp_get_device_manufacturer_rsp(void *t_device,
1359 char *manufacturer, bt_hfp_agent_error_t err)
1362 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1363 "\r\n+CGMI: %s\r\n", manufacturer);
1364 return _bt_ag_send_response(t_device, err);
1367 int _bt_hfp_get_device_manufacturer(bt_ag_info_t *device, const char *buf)
1369 int len = strlen(buf);
1371 if (len == 9 && buf[7] == '=' && buf[8] == '?') /* AT+CGMI=? */
1372 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1377 _bt_hfp_get_device_manufacturer_req(device);
1381 int _bt_hfp_get_imsi(bt_ag_info_t *device, const char *buf)
1383 int len = strlen(buf);
1384 DBG_SECURE("Buf %s", buf);
1387 _bt_hfp_get_imsi_req(device);
1389 _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_INVALID_INDEX);
1394 int _bt_hfp_get_creg_status(bt_ag_info_t *device, const char *buf)
1396 int len = strlen(buf);
1397 DBG_SECURE("buf %s", buf);
1398 if (len < 7 || len > 9)
1401 _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_INVALID_INDEX);
1402 else if (buf[7] == '=')
1403 _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_INVALID_INDEX);
1404 else if (buf[7] == '?')
1405 _bt_hfp_get_creg_status_req(device);
1409 int _bt_hfp_get_revision_info_rsp(void *t_device, char *revision,
1410 bt_hfp_agent_error_t err)
1413 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1414 "\r\n+CGMR: %s\r\n", revision);
1415 return _bt_ag_send_response(t_device, err);
1418 int _bt_hfp_get_revision_information(bt_ag_info_t *device, const char *buf)
1420 int len = strlen(buf);
1422 if (len == 9 && buf[7] == '=' && buf[8] == '?') /* AT+CGMR=? */
1423 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1428 _bt_hfp_get_revision_info_req(device);