Fix dlog format issues
[platform/core/connectivity/bluetooth-agent.git] / ag-agent / bluetooth-ag-handler.c
1 /*
2  * bluetooth-ag-handler.c
3  *
4  * Copyright (c) 2014 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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>
10  *
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
14  *
15  *              http://www.apache.org/licenses/LICENSE-2.0
16  *
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.
22  *
23  */
24 #include "bluetooth-ag-agent.h"
25 #include "bluetooth-ag-handler.h"
26 #include "vconf.h"
27 #include "vconf-keys.h"
28
29 extern bt_ag_status_t ag;
30 extern GSList *active_devices;
31 extern GDBusConnection *ag_dbus_conn;
32 extern gchar *remote_dev_path;
33
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.
37 */
38 #define BT_SIGNAL_QUALITY_BER 99
39
40 wbs_options wbs_opts = {
41         .wbs_enable = FALSE,
42         .i2s_enable = 0x00,
43         .is_master = 0x00,
44         .clock_rate = 0x02,
45         .pcm_interface_rate = 0x00,
46 };
47
48 /* LCOV_EXCL_START */
49 /* AT+BRSF response */
50 int _bt_hfp_supported_features(bt_ag_info_t *hs, const char *buf)
51 {
52         bt_ag_slconn_t *slconn = hs->slc;
53         int err;
54 //      bt_hfp_agent_error_t ret = BT_HFP_AGENT_ERROR_NONE;
55
56         DBG("AT + BRSF");
57         if (strlen(buf) < 9)
58                 return -EINVAL;
59
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");
66         } else {
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");
71         }
72 #endif
73         err = _bt_ag_send_at(hs, "\r\n+BRSF: %u\r\n", ag.features);
74         if (err < 0)
75                 return err;
76
77         return _bt_ag_send_at(hs, "\r\nOK\r\n");
78 }
79
80 static char *__bt_get_indicator_ranges(const bt_ag_indicators_t *indicators)
81 {
82         int i;
83         GString *gstr;
84
85         DBG("__bt_get_indicator_ranges");
86         gstr = g_string_new("\r\n+CIND: ");
87
88         for (i = 0; indicators[i].indicator_desc != NULL; i++) {
89                 if (i == 0)
90                         g_string_append_printf(gstr, "(\"%s\",(%s))",
91                                 indicators[i].indicator_desc,
92                                 indicators[i].indicator_range);
93                 else
94                         g_string_append_printf(gstr, ",(\"%s\",(%s))",
95                                 indicators[i].indicator_desc,
96                                 indicators[i].indicator_range);
97         }
98         g_string_append(gstr, "\r\n");
99         return g_string_free(gstr, FALSE);
100 }
101
102 static char *__bt_get_indicator_values(const bt_ag_indicators_t *indicators)
103 {
104         int i;
105         GString *gstr;
106
107         gstr = g_string_new("\r\n+CIND: ");
108         DBG("__bt_get_indicator_values");
109         for (i = 0; indicators[i].indicator_range != NULL; i++) {
110                 if (i == 0)
111                         g_string_append_printf(gstr, "%d",
112                                 indicators[i].hfp_value);
113                 else
114                         g_string_append_printf(gstr, ",%d",
115                                 indicators[i].hfp_value);
116         }
117         g_string_append(gstr, "\r\n");
118
119         return g_string_free(gstr, FALSE);
120 }
121
122 static int __bt_check_hdset(bt_ag_info_t *hdset)
123 {
124         bt_ag_slconn_t *slconn = hdset->slc;
125
126         if (!hdset->hfp_active)
127                 return -1;
128
129         if (slconn->is_client_active)
130                 return 0;
131         else
132                 return -1;
133 }
134 /* LCOV_EXCL_STOP */
135
136 static int __bt_hfp_cmp(bt_ag_info_t *hs)
137 {
138         if (hs->hfp_active)
139                 return 0;
140         else
141                 return -1;
142 }
143
144 /* LCOV_EXCL_START */
145 static int __bt_cwa_cmp(bt_ag_info_t *hs)
146 {
147         if (!hs->hfp_active)
148                 return -1;
149
150         if (hs->slc->is_cwa_enabled)
151                 return 0;
152         else
153                 return -1;
154 }
155
156 gboolean __bt_ring_timer_cb(gpointer data)
157 {
158         _bt_ag_send_foreach_headset(active_devices, NULL, "\r\nRING\r\n");
159
160         if (ag.number)
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);
164
165         return TRUE;
166 }
167
168 int _bt_incoming_call_indicator(const char *number, int type)
169 {
170         bt_ag_info_t *hs;
171         bt_ag_slconn_t *slconn;
172
173         if (!active_devices)
174                 return -ENODEV;
175
176         /* Get the updated list of connected devices */
177         hs = active_devices->data;
178         slconn = hs->slc;
179
180         if (ag.ring_timer) {
181                 DBG("incoming_call_indicator: already calling....");
182                 return -EBUSY;
183         }
184
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");
188                 return 0;
189         }
190
191         DBG("Inband ring tone not supported.. so send a RING to HF");
192         g_free(ag.number);
193         ag.number = g_strdup(number);
194         ag.number_type = type;
195
196         if (slconn->is_inband_ring &&
197                                         hs->state != HEADSET_STATE_ON_CALL) {
198                 slconn->is_pending_ring = TRUE;
199                 return 0;
200         }
201
202         __bt_ring_timer_cb(NULL);
203         ag.ring_timer = g_timeout_add(AG_RING_INTERVAL, __bt_ring_timer_cb, NULL);
204
205         return 0;
206 }
207
208 int _bt_calling_stopped_indicator(void)
209 {
210         bt_ag_info_t *dev;
211
212         if (ag.ring_timer) {
213                 g_source_remove(ag.ring_timer);
214                 ag.ring_timer = 0;
215         }
216
217         if (!active_devices)
218                 return 0;
219
220         /* In case SCO is in intermediate state to connect */
221         dev = active_devices->data;
222
223         if (!dev->slc->is_pending_ring && !ag.ring_timer)
224                 return -EINVAL;
225
226         dev->slc->is_pending_ring = FALSE;
227
228         return 0;
229 }
230 /* LCOV_EXCL_STOP */
231
232 void _bt_hfp_set_ag_indicator(uint32_t ag_features,
233                         const bt_ag_indicators_t *ag_indicators, int rh,
234                         const char *chld)
235 {
236         DBG("Set Ag Features");
237         ag.telephony_ready = TRUE;
238         ag.features = ag_features;
239         ag.indicators = ag_indicators;
240         ag.rh = rh;
241         ag.chld = chld;
242 }
243
244 void _bt_hfp_deinitialize(void)
245 {
246         g_free(ag.number);
247         memset(&ag, 0, sizeof(ag));
248         ag.rh = BT_RSP_HOLD_NOT_SUPPORTED;
249         ag.er_mode = 3;
250 }
251
252 /* LCOV_EXCL_START */
253 /* Send event indication call from Statemanager module */
254 bt_hfp_agent_error_t _bt_hfp_event_indicator(int index)
255 {
256         if (!active_devices) {
257                 DBG("No Active devices present");
258                 return BT_HFP_AGENT_ERROR_NOT_AVAILABLE;
259         }
260
261         if (!ag.er_ind) {
262                 DBG("Indicate event called but event reporting is disabled");
263                 return BT_HFP_AGENT_ERROR_INTERNAL;
264         }
265
266         DBG("Sending event notification to hf....");
267
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);
271
272         return BT_HFP_AGENT_ERROR_NONE;
273 }
274
275 /* AT+CIND response */
276 int _bt_hfp_report_indicators(bt_ag_info_t *hs, const char *buf)
277 {
278         int err;
279         char *str;
280
281         if (strlen(buf) < 8)
282                 return -EINVAL;
283
284         if (buf[7] == '=')
285                 str = __bt_get_indicator_ranges(ag.indicators);
286         else
287                 str = __bt_get_indicator_values(ag.indicators);
288
289         err = _bt_ag_send_at(hs, "%s", str);
290
291         g_free(str);
292
293         if (err < 0)
294                 return err;
295
296         return _bt_ag_send_at(hs, "\r\nOK\r\n");
297 }
298
299 /* AT+CMER response */
300 int _bt_event_reporting_response(void *t_device,
301                                 bt_hfp_agent_error_t err)
302 {
303         bt_ag_info_t *hdset = t_device;
304         bt_ag_slconn_t *slconn = hdset->slc;
305         int ret_val;
306
307         if (err != (bt_hfp_agent_error_t) HFP_STATE_MNGR_ERR_NONE)
308                 return _bt_ag_send_response(t_device, err);
309
310         ret_val = _bt_ag_send_at(hdset, "\r\nOK\r\n");
311         if (ret_val < 0)
312                 return ret_val;
313
314         if (hdset->state != HEADSET_STATE_CONNECTING)
315                 return 0;
316
317         if (slconn->hs_features & HANDSFREE_FEATURE_CALL_WAITING_AND_3WAY &&
318                         ag.features & BT_AG_FEATURE_THREE_WAY_CALL)
319                 return 0;
320
321         _bt_ag_slconn_complete(hdset);
322
323         return 0;
324 }
325
326 int _bt_hfp_enable_indicators(bt_ag_info_t *hdset, const char *buffer)
327 {
328         if (strlen(buffer) < 13)
329                 return -EINVAL;
330
331         /* tokenks can be <mode>,<keyp>,<disp>,<ind>,<bfr>*/
332         char **ind_tokens = g_strsplit(&buffer[8], ",", 5);
333
334         if (g_strv_length(ind_tokens) < 4) {
335                 g_strfreev(ind_tokens);
336                 return -EINVAL;
337         }
338
339         ag.er_mode = atoi(ind_tokens[0]);
340         ag.er_ind = atoi(ind_tokens[3]);
341
342         DBG("hfp_enable_indicators (CMER): indicator=%d, mode=%d",
343                 ag.er_ind, ag.er_mode);
344
345         g_strfreev(ind_tokens);
346         ind_tokens = NULL;
347
348         switch (ag.er_ind) {
349         case 0:
350         case 1:
351                 _bt_hfp_update_event_request(ag.er_ind, hdset);
352                 break;
353         default:
354                 return -EINVAL;
355         }
356         return 0;
357 }
358
359         /* AT+CHLD response */
360 int _bt_hfp_call_hold(bt_ag_info_t *hs, const char *buf)
361 {
362         int err;
363
364         if (strlen(buf) < 9)
365                 return -EINVAL;
366
367         if (buf[8] != '?') {
368                 _bt_hfp_call_hold_request(&buf[8], hs);
369                 return 0;
370         }
371
372         err = _bt_ag_send_at(hs, "\r\n+CHLD: (%s)\r\n", ag.chld);
373         if (err < 0)
374                 return err;
375
376         err = _bt_ag_send_at(hs, "\r\nOK\r\n");
377         if (err < 0)
378                 return err;
379
380         _bt_ag_slconn_complete(hs);
381
382         return 0;
383 }
384
385 int _bt_key_press_response(void *t_device, bt_hfp_agent_error_t err)
386 {
387         return _bt_ag_send_response(t_device, err);
388 }
389
390 int _bt_hfp_key_press(bt_ag_info_t *hs, const char *buf)
391 {
392         if (strlen(buf) < 9)
393                 return -EINVAL;
394
395         if (ag.ring_timer) {
396                 g_source_remove(ag.ring_timer);
397                 ag.ring_timer = 0;
398         }
399
400         _bt_hfp_key_press_request(&buf[8], hs);
401
402         return 0;
403 }
404
405 int _bt_answer_call_response(void *hs, bt_hfp_agent_error_t err)
406 {
407         return _bt_ag_send_response(hs, err);
408 }
409
410 int _bt_hfp_answer_call(bt_ag_info_t *hs, const char *buf)
411 {
412         if (ag.ring_timer) {
413                 g_source_remove(ag.ring_timer);
414                 ag.ring_timer = 0;
415         }
416
417         if (ag.number) {
418                 g_free(ag.number);
419                 ag.number = NULL;
420         }
421
422         if (remote_dev_path)
423                 g_free(remote_dev_path);
424
425         remote_dev_path = g_strdup(hs->path);
426
427         _bt_hfp_answer_call_request(hs);
428
429         return 0;
430 }
431 int _bt_terminate_call_response(void *t_device,
432                                         hfp_state_manager_err_t err)
433 {
434         bt_ag_info_t *hs = t_device;
435
436         if (err != HFP_STATE_MNGR_ERR_NONE)
437                 return _bt_ag_send_response(hs, err);
438
439         return _bt_ag_send_at(hs, "\r\nOK\r\n");
440 }
441
442 int _bt_hfp_terminate_call(bt_ag_info_t *hs, const char *buf)
443 {
444         if (ag.number) {
445                 g_free(ag.number);
446                 ag.number = NULL;
447         }
448
449         if (ag.ring_timer) {
450                 g_source_remove(ag.ring_timer);
451                 ag.ring_timer = 0;
452         }
453
454         _bt_hfp_terminate_call_request(hs);
455
456         return 0;
457 }
458
459 int _bt_hfp_cli_notification(bt_ag_info_t *hs, const char *buf)
460 {
461         bt_ag_slconn_t *slconn = hs->slc;
462
463         if (strlen(buf) < 9)
464                 return -EINVAL;
465
466         slconn->is_client_active = buf[8] == '1' ? TRUE : FALSE;
467
468         return _bt_ag_send_at(hs, "\r\nOK\r\n");
469 }
470
471 int _bt_response_and_hold_response(void *t_device,
472                                         bt_hfp_agent_error_t err)
473 {
474         return _bt_ag_send_response(t_device, err);
475 }
476
477 int _bt_hfp_response_and_hold(bt_ag_info_t *hs, const char *buf)
478 {
479
480         if (strlen(buf) < 8)
481                 return -EINVAL;
482
483         if (ag.rh == BT_RSP_HOLD_NOT_SUPPORTED)
484                 return _bt_ag_send_response(hs,
485                         HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
486
487         if (buf[7] == '=') {
488                 _bt_hfp_response_and_hold_request(hs);
489                 return 0;
490         }
491
492         if (ag.rh >= 0)
493                 _bt_ag_send_at(hs, "\r\n+BTRH: %d\r\n", ag.rh);
494
495         return _bt_ag_send_at(hs, "\r\nOK\r\n");
496 }
497
498 int _bt_hfp_last_dialed_number(bt_ag_info_t *hs, const char *buf)
499 {
500         if (remote_dev_path)
501                 g_free(remote_dev_path);
502
503         remote_dev_path = g_strdup(hs->path);
504         _bt_hfp_last_dialed_number_request(hs);
505
506         return 0;
507 }
508
509 int _bt_dial_number_response(void *t_device, bt_hfp_agent_error_t err)
510 {
511         return _bt_ag_send_response(t_device, err);
512 }
513
514 int _bt_hfp_dial_number(bt_ag_info_t *hs, const char *buf)
515 {
516         char number[MAX_BUFFER_SIZE];
517         size_t buf_len;
518
519         buf_len = strlen(buf);
520
521         if (buf[buf_len - 1] != ';') {
522                 DBG("Reject the non-voice call dial number request");
523                 return -EINVAL;
524         }
525
526         memset(number, 0, sizeof(number));
527         strncpy(number, &buf[3], buf_len - 4);
528
529         if (remote_dev_path)
530                 g_free(remote_dev_path);
531
532         remote_dev_path = g_strdup(hs->path);
533
534         _bt_hfp_dial_number_request(number, hs);
535
536         return 0;
537 }
538
539 static int __bt_headset_set_gain(bt_ag_info_t *hs, uint16_t gain, char type)
540 {
541         bt_ag_slconn_t *slconn = hs->slc;
542         const char *property;
543
544         if (gain > 15) {
545                 DBG("Invalid gain value: %u", gain);
546                 return -EINVAL;
547         }
548
549         switch (type) {
550         case BT_HFP_SPEAKER_GAIN:
551                 if (slconn->speaker_gain == gain) {
552                         DBG("Ignoring no-change in speaker gain");
553                         return -EALREADY;
554                 }
555                 property = "SpeakerGain";
556                 slconn->speaker_gain = gain;
557                 break;
558         case BT_HFP_MICROPHONE_GAIN:
559                 if (slconn->microphone_gain == gain) {
560                         DBG("Ignoring no-change in microphone gain");
561                         return -EALREADY;
562                 }
563                 property = "MicrophoneGain";
564                 slconn->microphone_gain = gain;
565                 break;
566         default:
567                 DBG("Unknown gain setting\n");
568                 return -EINVAL;
569         }
570
571         _bt_ag_agent_emit_property_changed(ag_dbus_conn, hs->path,
572                                 BT_HEADSET_INTERFACE, property,
573                                 g_variant_new("q", gain));
574         return 0;
575 }
576
577 int _bt_hfp_signal_gain_setting(bt_ag_info_t *hs, const char *buf)
578 {
579         uint16_t gain;
580         int err;
581
582         if (strlen(buf) < 8) {
583                 DBG("very short string to use for Gain setting\n");
584                 return -EINVAL;
585         }
586
587         gain = (uint16_t) strtol(&buf[7], NULL, 10);
588
589         err = __bt_headset_set_gain(hs, gain, buf[5]);
590         if (err < 0 && err != -EALREADY)
591                 return err;
592
593         return _bt_ag_send_at(hs, "\r\nOK\r\n");
594 }
595 /* LCOV_EXCL_STOP */
596
597 int _bt_transmit_dtmf_response(void *t_device,
598                         bt_hfp_agent_error_t err)
599 {
600         return _bt_ag_send_response(t_device, err);
601 }
602
603 /* LCOV_EXCL_START */
604 int _bt_hfp_dtmf_tone(bt_ag_info_t *hs, const char *buf)
605 {
606         char tone;
607
608         if (strlen(buf) < 8) {
609                 printf("Too short string for DTMF tone");
610                 return -EINVAL;
611         }
612
613         tone = buf[7];
614         if (tone >= '#' && tone <= 'D')
615                 _bt_hfp_channel_dtmf_request(tone, hs);
616         else
617                 return -EINVAL;
618
619         return 0;
620 }
621
622 int _bt_hfp_set_speaker_gain(bt_ag_info_t *hs,
623                 uint16_t gain_value)
624 {
625         int err;
626         char type = BT_HFP_SPEAKER_GAIN;
627
628         err = __bt_headset_set_gain(hs, gain_value, type);
629         if (err < 0)
630                 return BT_HFP_AGENT_ERROR_INTERNAL;
631
632         if (hs->state == HEADSET_STATE_ON_CALL) {
633                 err = _bt_ag_send_at(hs, "\r\n+VG%c=%u\r\n", type,
634                                 gain_value);
635                 if (err < 0)
636                         return BT_HFP_AGENT_ERROR_INTERNAL;
637         }
638         return BT_HFP_AGENT_ERROR_NONE;
639 }
640
641 int _bt_hfp_set_microphone_gain(bt_ag_info_t *hs,
642                 uint16_t gain_value)
643 {
644         int err;
645         char type = BT_HFP_MICROPHONE_GAIN;
646
647         if (hs == NULL) {
648                 DBG("hs is NULL");
649                 return BT_HFP_AGENT_ERROR_INVALID_PARAM;
650         }
651
652         err = __bt_headset_set_gain(hs, gain_value, type);
653         if (err < 0)
654                 return BT_HFP_AGENT_ERROR_INTERNAL;
655
656         if (hs->state == HEADSET_STATE_ON_CALL) {
657                 err = _bt_ag_send_at(hs, "\r\n+VG%c=%u\r\n", type,
658                                 gain_value);
659                 if (err < 0)
660                         return BT_HFP_AGENT_ERROR_INTERNAL;
661         }
662         return BT_HFP_AGENT_ERROR_NONE;
663 }
664
665
666 int _bt_hfp_set_voice_dial(bt_ag_info_t *hs,
667                 gboolean enable)
668 {
669         DBG("_bt_hfp_set_voice_dial = %d", enable);
670
671         if (_bt_ag_send_at(hs, "\r\n+BVRA: %d\r\n", enable) < 0)
672                 return BT_HFP_AGENT_ERROR_INTERNAL;
673
674         return BT_HFP_AGENT_ERROR_NONE;
675 }
676
677 int _bt_hfp_send_vendor_cmd(bt_ag_info_t *hs,
678                 const char *cmd)
679 {
680         DBG("_bt_hfp_send_vendor_cmd = %s", cmd);
681
682         if (_bt_ag_send_at(hs, "\r\n%s\r\n", cmd) < 0)
683                 return BT_HFP_AGENT_ERROR_INTERNAL;
684
685         return BT_HFP_AGENT_ERROR_NONE;
686 }
687 /* LCOV_EXCL_STOP */
688
689 int _bt_vendor_cmd_response(void *t_device,
690                         bt_hfp_agent_error_t err)
691 {
692         return _bt_ag_send_response(t_device, err);
693 }
694
695 /* LCOV_EXCL_START */
696 int _bt_hfp_vendor_cmd(bt_ag_info_t *hs, const char *buf)
697 {
698         DBG("XSAT vendor command");
699
700         _bt_hfp_vendor_cmd_request(buf, hs);
701
702         return 0;
703 }
704
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)
707 {
708         if (call_num && strlen(call_num) > 0) {
709                 _bt_ag_send_at(hs,
710                         "\r\n+CLCC: %d,%d,%d,%d,%d,\"%s\",%d\r\n",
711                         index, direction, status, mode, conference,
712                                 call_num, t_num);
713         } else {
714                 _bt_ag_send_at(hs,
715                         "\r\n+CLCC: %d,%d,%d,%d,%d\r\n",
716                         index, direction, status, mode, conference);
717         }
718
719         return 0;
720 }
721 int _bt_subscriber_number_indicator(const char *call_num, int type, int service)
722 {
723         if (!active_devices)
724                 return -ENODEV;
725
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);
729         return 0;
730 }
731 /* LCOV_EXCL_STOP */
732
733 int _bt_subscriber_number_response(void *t_device,
734                                         bt_hfp_agent_error_t err)
735 {
736         return _bt_ag_send_response(t_device, err);
737 }
738
739 /* LCOV_EXCL_START */
740 int _bt_hfp_subscriber_number(bt_ag_info_t *hs, const char *buf)
741 {
742         _bt_hfp_subscriber_number_request(hs);
743
744         return 0;
745 }
746
747 int _bt_call_waiting_indicator(const char *number, int type)
748 {
749         if (!active_devices)
750                 return -ENODEV;
751
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",
755                                 number, type);
756         return 0;
757 }
758 /* LCOV_EXCL_STOP */
759
760 int _bt_list_current_calls_response(void *t_device,
761                                         bt_hfp_agent_error_t err)
762 {
763         return _bt_ag_send_response(t_device, err);
764 }
765
766 /* LCOV_EXCL_START */
767 int _bt_hfp_list_current_calls(bt_ag_info_t *hs, const char *buf)
768 {
769         _bt_list_current_calls(hs);
770
771         return 0;
772 }
773
774 int _bt_hfp_extended_errors(bt_ag_info_t *hs, const char *buf)
775 {
776         bt_ag_slconn_t *slconn = hs->slc;
777
778         if (strlen(buf) < 9)
779                 return -EINVAL;
780
781         if (buf[8] == '1') {
782                 slconn->is_cme_enabled = TRUE;
783                 DBG("CME errors enabled for headset %p", hs);
784         } else {
785                 slconn->is_cme_enabled = FALSE;
786                 DBG("CME errors disabled for headset %p", hs);
787         }
788
789         return _bt_ag_send_at(hs, "\r\nOK\r\n");
790 }
791
792 int _bt_hfp_call_waiting_notify(bt_ag_info_t *hs, const char *buf)
793 {
794         bt_ag_slconn_t *slconn = hs->slc;
795
796         if (strlen(buf) < 9)
797                 return -EINVAL;
798
799         if (buf[8] == '1') {
800                 slconn->is_cwa_enabled = TRUE;
801                 DBG("Call waiting notification enabled for headset %p", hs);
802         } else {
803                 slconn->is_cwa_enabled = FALSE;
804                 DBG("Call waiting notification disabled for headset %p", hs);
805         }
806
807         return _bt_ag_send_at(hs, "\r\nOK\r\n");
808 }
809 /* LCOV_EXCL_STOP */
810
811 int _bt_operator_selection_response(void *t_device,
812                                         bt_hfp_agent_error_t err)
813 {
814         return _bt_ag_send_response(t_device, err);
815 }
816
817 int _bt_call_hold_response(void *t_device, bt_hfp_agent_error_t err)
818 {
819         return _bt_ag_send_response(t_device, err);
820 }
821
822 int _bt_nr_and_ec_response(void *t_device, bt_hfp_agent_error_t err)
823 {
824         bt_ag_info_t *hs = t_device;
825         bt_ag_slconn_t *slconn = hs->slc;
826
827         if (err == (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) {
828                 GSList *l;
829
830                 for (l = hs->nrec_cbs; l; l = l->next) {
831                         struct hs_nrec_callback *nrec_cb = l->data;
832
833                         nrec_cb->cb(hs, slconn->is_nrec_req,
834                                 nrec_cb->user_data);
835                 }
836
837                 slconn->is_nrec = hs->slc->is_nrec_req;
838         }
839
840         return _bt_ag_send_response(t_device, err);
841 }
842
843 int _bt_voice_dial_response(void *t_device, bt_hfp_agent_error_t err)
844 {
845         return _bt_ag_send_response(t_device, err);
846 }
847
848 int _bt_operator_selection_indicator(int mode, const char *oper)
849 {
850         if (!active_devices)
851                 return -ENODEV;
852
853         _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
854                                 "\r\n+COPS: %d,0,\"%s\"\r\n",
855                                 mode, oper);
856         return 0;
857 }
858
859 /* LCOV_EXCL_START */
860 int _bt_hfp_operator_selection(bt_ag_info_t *hs, const char *buf)
861 {
862         if (strlen(buf) < 8)
863                 return -EINVAL;
864
865         switch (buf[7]) {
866         case '?':
867                 _bt_hfp_get_operator_selection_request(hs);
868                 break;
869         case '=': {
870                 if (buf[8] == '?')
871                         return _bt_ag_send_at(hs, "\r\n+CME ERROR: %d\r\n",
872                                 HFP_STATE_MNGR_ERR_NOT_SUPPORTED);
873                 else
874                         return _bt_ag_send_at(hs, "\r\nOK\r\n");
875         }
876         default:
877                 return -EINVAL;
878         }
879
880         return 0;
881 }
882
883 int _bt_hfp_nr_and_ec(bt_ag_info_t *hs, const char *buf)
884 {
885         bt_ag_slconn_t *slconn = hs->slc;
886
887         if (strlen(buf) < 9)
888                 return -EINVAL;
889
890         if (buf[8] == '0')
891                 slconn->is_nrec_req = FALSE;
892         else
893                 slconn->is_nrec_req = TRUE;
894
895         _bt_hfp_noise_red_and_echo_cancel_request(slconn->is_nrec_req, hs);
896
897         return 0;
898 }
899
900 int _bt_hfp_voice_dial(bt_ag_info_t *hs, const char *buf)
901 {
902         bt_ag_slconn_t *slconn = hs->slc;
903         gboolean enable;
904
905         if (strlen(buf) < 9)
906                 return -EINVAL;
907
908         if (buf[8] == '0')
909                 enable = FALSE;
910         else
911                 enable = TRUE;
912
913         _bt_hfp_voice_dial_request(enable, hs);
914
915         slconn->is_voice_recognition_running = enable;
916
917         return 0;
918 }
919
920 int _bt_hfp_indicators_activation(bt_ag_info_t *hs, const char *buf)
921 {
922         if (strlen(buf) < 7) {
923                 printf("Invalid indicator activation request\n");
924                 return -EINVAL;
925         }
926
927         _bt_hfp_set_indicators(&buf[6], hs);
928         return 0;
929 }
930 /* LCOV_EXCL_STOP */
931
932 int _bt_indicators_activation_response(void *t_device,
933                                         bt_hfp_agent_error_t err)
934 {
935         return _bt_ag_send_response(t_device, err);
936 }
937
938 int _bt_select_phonebook_memory_status_response(void *t_device,
939                                                 const char *path,
940                                                 uint32_t total, uint32_t used,
941                                                 bt_hfp_agent_error_t err)
942 {
943         bt_ag_info_t *hs = t_device;
944         bt_ag_slconn_t *slconn = hs->slc;
945
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);
950                 else
951                         return _bt_ag_send_at(hs, "\r\nERROR\r\n");
952         }
953
954         if (!active_devices)
955                 return -ENODEV;
956
957         _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
958                         "\r\n+CPBS: %s,%d,%d\r\n",
959                         path, used, total);
960
961         return _bt_ag_send_at(hs, "\r\nOK\r\n");
962 }
963
964 int _bt_select_phonebook_memory_list_response(void *t_device,
965                                                 const char *buf,
966                                                 bt_hfp_agent_error_t err)
967 {
968         bt_ag_info_t *hs = t_device;
969         bt_ag_slconn_t *slconn = hs->slc;
970
971         if ((err != (bt_hfp_agent_error_t)HFP_STATE_MNGR_ERR_NONE) ||
972                                 (NULL == buf)) {
973                 if (slconn->is_cme_enabled)
974                         return _bt_ag_send_at(hs,
975                                         "\r\n+CME ERROR: %d\r\n", err);
976                 else
977                         return _bt_ag_send_at(hs, "\r\nERROR\r\n");
978         }
979
980         if (NULL != buf) {
981                 if (!active_devices)
982                         return -ENODEV;
983
984                 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
985                                         "\r\n+CPBS: %s\r\n", buf);
986
987         }
988         return _bt_ag_send_at(hs, "\r\nOK\r\n");
989 }
990
991 int _bt_select_phonebook_memory_response(void *t_device,
992                                                 bt_hfp_agent_error_t err)
993 {
994         return _bt_ag_send_response(t_device, err);
995 }
996
997 /* LCOV_EXCL_START */
998 int _bt_hfp_select_pb_memory(bt_ag_info_t *hs, const char *buf)
999 {
1000         if (strlen(buf) < 8)
1001                 return -EINVAL;
1002
1003         if (buf[7] == '?') {
1004                 _bt_hfp_select_phonebook_memory_status(hs);
1005                 return 0;
1006         }
1007
1008         if (buf[7] == '=') {
1009                 if (buf[8] == '?') {
1010                         _bt_hfp_select_phonebook_memory_list(hs);
1011                         return 0;
1012                 }
1013                 _bt_hfp_select_phonebook_memory(hs, &buf[8]);
1014                 return 0;
1015         }
1016
1017         return -EINVAL;
1018 }
1019 /* LCOV_EXCL_STOP */
1020
1021 int _bt_read_phonebook_entries_list_response(void *t_device,
1022                                                 uint32_t used,
1023                                                 uint32_t number_length,
1024                                                 uint32_t name_length,
1025                                                 bt_hfp_agent_error_t err)
1026 {
1027         bt_ag_info_t *hs = t_device;
1028         bt_ag_slconn_t *slconn = hs->slc;
1029
1030         int send_err = 0;
1031         int index = 1;
1032
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);
1037                 else
1038                         return _bt_ag_send_at(hs, "\r\nERROR\r\n");
1039         }
1040
1041         if (used < 1)
1042                 index = 0;
1043
1044         send_err = _bt_ag_send_at(hs, "\r\n+CPBR: (%d-%d),%d,%d\r\n",
1045                         index, used, number_length, name_length);
1046         if (send_err < 0)
1047                 return send_err;
1048
1049         return _bt_ag_send_at(hs, "\r\nOK\r\n");
1050 }
1051
1052 int _bt_read_phonebook_entries_response(void *t_device,
1053                                         bt_hfp_agent_error_t err)
1054 {
1055         return _bt_ag_send_response(t_device, err);
1056 }
1057
1058 /* LCOV_EXCL_START */
1059 int _bt_read_phonebook_entries_indicator(const char *name, const char *number,
1060                                         uint32_t handle)
1061 {
1062         int type = 129;
1063         const char *pos = NULL;
1064
1065         pos = number;
1066         while (*pos == ' ' || *pos == '\t')
1067                 pos++;
1068
1069         /* 145 means international access code, otherwise 129 is used */
1070         if (*pos == '+')
1071                 type = 145;
1072
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);
1076         return 0;
1077 }
1078
1079 int _bt_hfp_read_pb_entries(bt_ag_info_t *hs, const char *buf)
1080 {
1081         if (strlen(buf) < 8)
1082                 return -EINVAL;
1083
1084         if (buf[7] != '=')
1085                 return -EINVAL;
1086
1087         if (buf[8] == '?')
1088                 _bt_hfp_read_phonebook_entries_list(hs);
1089         else
1090                 _bt_hfp_read_phonebook_entries(hs, &buf[8]);
1091
1092         return 0;
1093 }
1094 /* LCOV_EXCL_STOP */
1095
1096 int _bt_find_phonebook_entries_status_response(void *t_device,
1097                                                 bt_hfp_agent_error_t err)
1098 {
1099         return _bt_ag_send_response(t_device, err);
1100 }
1101
1102 int _bt_find_phonebook_entries_response(void *t_device,
1103                                         bt_hfp_agent_error_t err)
1104 {
1105         return _bt_ag_send_response(t_device, err);
1106 }
1107
1108 int _bt_find_phonebook_entries_status_indicator(uint32_t number_length,
1109                                         uint32_t name_length)
1110 {
1111         _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1112                         "\r\n+CPBF: %d,%d\r\n",
1113                         number_length, name_length);
1114
1115         return 0;
1116 }
1117
1118 /* LCOV_EXCL_START */
1119 int _bt_hfp_find_pb_entires(bt_ag_info_t *hs, const char *buf)
1120 {
1121         if (strlen(buf) < 8)
1122                 return -EINVAL;
1123
1124         if (buf[7] != '=')
1125                 return -EINVAL;
1126
1127         if (buf[8] == '?')
1128                 _bt_hfp_find_phonebook_entries_status(hs);
1129         else
1130                 _bt_hfp_find_phonebook_entries(hs, &buf[8]);
1131
1132         return 0;
1133 }
1134 /* LCOV_EXCL_STOP */
1135
1136 int _bt_supported_character_generic_response(void *t_device,
1137                                                 char *character_set_list,
1138                                                 bt_hfp_agent_error_t err)
1139 {
1140         bt_ag_info_t *hs = t_device;
1141         bt_ag_slconn_t *slconn = hs->slc;
1142
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);
1147                 else
1148                         return _bt_ag_send_at(hs, "\r\nERROR\r\n");
1149         }
1150
1151         if (NULL != character_set_list) {
1152                 if (!active_devices)
1153                         return -ENODEV;
1154
1155                 _bt_ag_send_foreach_headset(active_devices, __bt_hfp_cmp,
1156                         "\r\n+CSCS: %s\r\n", character_set_list);
1157         }
1158         return _bt_ag_send_at(hs, "\r\nOK\r\n");
1159 }
1160
1161 int _bt_set_characterset_generic_response(void *t_device,
1162                                         bt_hfp_agent_error_t err)
1163 {
1164         return _bt_ag_send_response(t_device, err);
1165 }
1166
1167 /* LCOV_EXCL_START */
1168 int _bt_hfp_select_character_set(bt_ag_info_t *hs, const char *buf)
1169 {
1170         if (NULL != buf) {
1171                 if (strlen(buf) < 7)
1172                         return -EINVAL;
1173
1174                 if (buf[7] == '?') {
1175                         _bt_hfp_get_character_set(hs);
1176                         return 0;
1177                 }
1178
1179                 if (buf[7] == '=') {
1180                         if (buf[8] == '?')
1181                                 _bt_hfp_list_supported_character(hs);
1182                         else
1183                                 _bt_hfp_set_character_set(hs, &buf[8]);
1184                 }
1185         }
1186         return 0;
1187
1188 }
1189 /* LCOV_EXCL_STOP */
1190
1191 int _bt_battery_charge_status_response(void *t_device,
1192                                                 int32_t bcs,
1193                                                 int32_t bcl,
1194                                                 bt_hfp_agent_error_t err)
1195 {
1196         bt_ag_info_t *hs = t_device;
1197
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);
1201         }
1202
1203         return _bt_ag_send_response(hs, err);
1204 }
1205
1206 /* LCOV_EXCL_START */
1207 int _bt_hfp_get_battery_charge_status(bt_ag_info_t *hs, const char *buf)
1208 {
1209         if (strlen(buf) < 6)
1210                 return -EINVAL;
1211
1212         if (buf[6] == '=')
1213                 return _bt_ag_send_response(hs, HFP_STATE_MNGR_ERR_NONE);
1214
1215         _bt_hfp_get_battery_property(hs);
1216         return 0;
1217 }
1218
1219 int _bt_hfp_apl_command(bt_ag_info_t *hs, const char *buf)
1220 {
1221         DBG("Got Apple command: %s", buf);
1222
1223         return _bt_ag_send_response(hs, HFP_STATE_MNGR_ERR_NONE);
1224 }
1225 /* LCOV_EXCL_STOP */
1226
1227 /* convert signal strength to a RSSI level */
1228 static int __bt_telephony_convert_signal_to_rssi(int signal)
1229 {
1230         /* input  : BT signal strength (0~5) */
1231         /* output : RSSI strength (0~31) */
1232         switch (signal) {
1233         case 0: return 0;
1234         case 1: return 4;
1235         case 2: return 8;
1236         case 3: return 13;
1237         case 4: return 19;
1238         case 5: return 31;
1239         }
1240
1241         if (signal > 5)
1242                 return 31;
1243
1244         return 0;
1245 }
1246
1247 int _bt_signal_quality_response(void *t_device,
1248                                                 int32_t rssi,
1249                                                 int32_t ber,
1250                                                 bt_hfp_agent_error_t err)
1251 {
1252         bt_ag_info_t *hs = t_device;
1253
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);
1258         }
1259         return _bt_ag_send_response(hs, err);
1260 }
1261
1262 /* LCOV_EXCL_START */
1263 int _bt_telephony_signal_quality_list_supported_response(void *t_device,
1264                                                 bt_hfp_agent_error_t err)
1265 {
1266         bt_ag_info_t *device = t_device;
1267
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");
1271         }
1272         return _bt_ag_send_response(device, err);
1273 }
1274
1275 int _bt_hfp_get_signal_quality(bt_ag_info_t *hs, const char *buf)
1276 {
1277         if (strlen(buf) < 6)
1278                 return -EINVAL;
1279
1280         if (buf[6] == '=')
1281                 _bt_telephony_signal_quality_list_supported_response(hs,
1282                                         HFP_STATE_MNGR_ERR_NONE);
1283         else
1284                 _bt_ag_agent_get_signal_quality(hs);
1285
1286         return 0;
1287 }
1288 /* LCOV_EXCL_STOP */
1289
1290 int _bt_hfp_get_activity_status_rsp(void *t_device,
1291                                                 int status,
1292                                                 bt_hfp_agent_error_t err)
1293 {
1294         bt_ag_info_t *device = t_device;
1295
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);
1299         }
1300
1301         return _bt_ag_send_response(device, err);
1302 }
1303
1304 /* LCOV_EXCL_START */
1305 int _bt_hfp_get_activity_status(bt_ag_info_t *device, const char *buf)
1306 {
1307         if (strlen(buf) < 7)
1308                 return -EINVAL;
1309
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);
1317         }
1318
1319         _bt_get_activity_status(device);
1320         return 0;
1321 }
1322 /* LCOV_EXCL_STOP */
1323
1324 int _bt_hfp_get_equipment_identity_rsp(void *t_device,
1325                                 char *identity, bt_hfp_agent_error_t err)
1326 {
1327         if (identity)
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);
1331 }
1332
1333 int _bt_hfp_get_imsi_rsp(void *t_device,
1334                 char *mcc, char *mnc, char *msin, bt_hfp_agent_error_t err)
1335 {
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);
1340 }
1341
1342 int _bt_hfp_get_creg_status_rsp(void *t_device,
1343                 int n, int status, bt_hfp_agent_error_t err)
1344 {
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);
1349 }
1350
1351 int _bt_hfp_get_equipment_identity(bt_ag_info_t *device, const char *buf)
1352 {
1353         int len = strlen(buf);
1354
1355         if (len == 9 && buf[7] == '=' && buf[8] == '?')  /* AT+CGSN=? */
1356                 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1357
1358         else if (len > 7)
1359                 return -EINVAL;
1360
1361         _bt_hfp_get_equipment_identity_req(device); /* AT+CGSN */
1362         return 0;
1363 }
1364
1365 int _bt_hfp_get_model_info_rsp(void *t_device, char *model,
1366                                                 bt_hfp_agent_error_t err)
1367 {
1368         if (model)
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);
1372 }
1373
1374 int _bt_hfp_get_model_information(bt_ag_info_t *device, const char *buf)
1375 {
1376         int len = strlen(buf);
1377
1378         if (len == 9 && buf[7] == '=' && buf[8] == '?')  /* AT+CGMM=? */
1379                 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1380
1381         else if (len > 7)
1382                 return -EINVAL;
1383
1384         _bt_hfp_get_model_info_req(device);/* AT+CGMM */
1385         return 0;
1386 }
1387
1388 int _bt_hfp_get_device_manufacturer_rsp(void *t_device,
1389                                 char *manufacturer, bt_hfp_agent_error_t err)
1390 {
1391         if (manufacturer)
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);
1395 }
1396
1397 int _bt_hfp_get_device_manufacturer(bt_ag_info_t *device, const char *buf)
1398 {
1399         int len = strlen(buf);
1400
1401         if (len == 9 && buf[7] == '=' && buf[8] == '?')  /* AT+CGMI=? */
1402                 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1403
1404         else if (len > 7)
1405                 return -EINVAL;
1406
1407         _bt_hfp_get_device_manufacturer_req(device);
1408         return 0;
1409 }
1410
1411 int _bt_hfp_get_imsi(bt_ag_info_t *device, const char *buf)
1412 {
1413         int len = strlen(buf);
1414         DBG_SECURE("Buf %s", buf);
1415
1416         if (len == 7)
1417                 _bt_hfp_get_imsi_req(device);
1418         else
1419                 _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_INVALID_INDEX);
1420
1421         return 0;
1422 }
1423
1424 int _bt_hfp_get_creg_status(bt_ag_info_t *device, const char *buf)
1425 {
1426         int len = strlen(buf);
1427         DBG_SECURE("buf %s", buf);
1428         if (len < 7 || len > 9)
1429                 return -EINVAL;
1430         else if (len == 7)
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);
1436
1437         return 0;
1438 }
1439 int _bt_hfp_get_revision_info_rsp(void *t_device, char *revision,
1440                                                 bt_hfp_agent_error_t err)
1441 {
1442         if (revision)
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);
1446 }
1447
1448 int _bt_hfp_get_revision_information(bt_ag_info_t *device, const char *buf)
1449 {
1450         int len = strlen(buf);
1451
1452         if (len == 9 && buf[7] == '=' && buf[8] == '?')  /* AT+CGMR=? */
1453                 return _bt_ag_send_response(device, HFP_STATE_MNGR_ERR_NONE);
1454
1455         else if (len > 7)
1456                 return -EINVAL;
1457
1458         _bt_hfp_get_revision_info_req(device);
1459         return 0;
1460 }