1 /*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holders nor the names of
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * 4. Any redistribution, use, or modification is done solely for
17 * personal benefit and not for any commercial purpose or for
18 * monetary gain.
19 *
20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Please inquire about commercial licensing options at
34 * [email protected]
35 *
36 */
37
38 #define BTSTACK_FILE__ "hfp.c"
39
40
41 #include "btstack_config.h"
42
43 #include <stdint.h>
44 #include <stdio.h>
45 #include <string.h>
46 #include <inttypes.h>
47
48 #include "bluetooth_sdp.h"
49 #include "btstack_debug.h"
50 #include "btstack_event.h"
51 #include "btstack_memory.h"
52 #include "btstack_run_loop.h"
53 #include "classic/sdp_client_rfcomm.h"
54 #include "classic/sdp_server.h"
55 #include "classic/sdp_util.h"
56 #include "classic/sdp_client.h"
57 #include "hci.h"
58 #include "hci_cmd.h"
59 #include "hci_dump.h"
60
61 #if defined(ENABLE_CC256X_ASSISTED_HFP) && !defined(ENABLE_SCO_OVER_PCM)
62 #error "Assisted HFP is only possible over PCM/I2S. Please add define: ENABLE_SCO_OVER_PCM"
63 #endif
64
65 #if defined(ENABLE_BCM_PCM_WBS) && !defined(ENABLE_SCO_OVER_PCM)
66 #error "WBS for PCM is only possible over PCM/I2S. Please add define: ENABLE_SCO_OVER_PCM"
67 #endif
68
69 #define HFP_HF_FEATURES_SIZE 10
70 #define HFP_AG_FEATURES_SIZE 12
71
72 typedef struct {
73 hfp_role_t local_role;
74 bd_addr_t remote_address;
75 } hfp_sdp_query_context_t;
76
77 // globals
78
79 static btstack_linked_list_t hfp_connections ;
80
81 static btstack_packet_handler_t hfp_hf_callback;
82 static btstack_packet_handler_t hfp_ag_callback;
83
84 static btstack_packet_handler_t hfp_hf_rfcomm_packet_handler;
85 static btstack_packet_handler_t hfp_ag_rfcomm_packet_handler;
86
87 static uint8_t hfp_hf_indicators_nr;
88 static const uint8_t * hfp_hf_indicators;
89
90 static uint16_t hfp_allowed_sco_packet_types;
91 static hfp_connection_t * hfp_sco_establishment_active;
92
93 static hfp_sdp_query_context_t hfp_sdp_query_context;
94 static btstack_context_callback_registration_t hfp_sdp_query_request;
95
96
97
98
99
100 // custom commands
101 static btstack_linked_list_t hfp_custom_commands_ag;
102 static btstack_linked_list_t hfp_custom_commands_hf;
103
104 // prototypes
105 static hfp_link_settings_t hfp_next_link_setting_for_connection(hfp_link_settings_t current_setting, hfp_connection_t * hfp_connection, uint8_t eSCO_S4_supported);
106 static void parse_sequence(hfp_connection_t * context);
107
108
109 #define CODEC_MASK_CVSD (1 << HFP_CODEC_CVSD)
110 #define CODEC_MASK_OTHER ((1 << HFP_CODEC_MSBC) | (1 << HFP_CODEC_LC3_SWB))
111
112 static const struct {
113 const uint16_t max_latency;
114 const uint8_t retransmission_effort;
115 const uint16_t packet_types;
116 const uint8_t codec_mask;
117 } hfp_link_settings [] = {
118 {0x0004, 0xff, SCO_PACKET_TYPES_HV1, CODEC_MASK_CVSD }, // HFP_LINK_SETTINGS_D0
119 {0x0005, 0xff, SCO_PACKET_TYPES_HV3, CODEC_MASK_CVSD }, // HFP_LINK_SETTINGS_D1
120 {0x0007, 0x01, SCO_PACKET_TYPES_EV3, CODEC_MASK_CVSD }, // HFP_LINK_SETTINGS_S1
121 {0x0007, 0x01, SCO_PACKET_TYPES_2EV3, CODEC_MASK_CVSD }, // HFP_LINK_SETTINGS_S2
122 {0x000a, 0x01, SCO_PACKET_TYPES_2EV3, CODEC_MASK_CVSD }, // HFP_LINK_SETTINGS_S3
123 {0x000c, 0x02, SCO_PACKET_TYPES_2EV3, CODEC_MASK_CVSD }, // HFP_LINK_SETTINGS_S4
124 {0x0008, 0x02, SCO_PACKET_TYPES_EV3, CODEC_MASK_OTHER}, // HFP_LINK_SETTINGS_T1
125 {0x000d, 0x02, SCO_PACKET_TYPES_2EV3, CODEC_MASK_OTHER} // HFP_LINK_SETTINGS_T2
126 };
127
128 #ifdef ENABLE_HFP_HF_SAFE_SETTINGS
129 // HFP v1.9, table 6.10 'mandatory safe settings' for eSCO + similar entries for SCO
130 static const struct hfp_mandatory_safe_setting {
131 const uint8_t codec_mask;
132 const bool secure_connection_in_use;
133 hfp_link_settings_t link_setting;
134 } hfp_mandatory_safe_settings[] = {
135 { CODEC_MASK_CVSD, false, HFP_LINK_SETTINGS_D1},
136 { CODEC_MASK_CVSD, true, HFP_LINK_SETTINGS_D1},
137 { CODEC_MASK_CVSD, false, HFP_LINK_SETTINGS_S1},
138 { CODEC_MASK_CVSD, true, HFP_LINK_SETTINGS_S4},
139 { CODEC_MASK_OTHER, false, HFP_LINK_SETTINGS_T1},
140 { CODEC_MASK_OTHER, true, HFP_LINK_SETTINGS_T2},
141 };
142 #endif
143
144 static const char * hfp_hf_features[] = {
145 "EC and/or NR function",
146 "Three-way calling",
147 "CLI presentation capability",
148 "Voice recognition activation",
149 "Remote volume control",
150
151 "Enhanced call status",
152 "Enhanced call control",
153
154 "Codec negotiation",
155
156 "HF Indicators",
157 "eSCO S4 (and T2) Settings Supported",
158 "Reserved for future definition"
159 };
160
161 static const char * hfp_ag_features[] = {
162 "Three-way calling",
163 "EC and/or NR function",
164 "Voice recognition function",
165 "In-band ring tone capability",
166 "Attach a number to a voice tag",
167 "Ability to reject a call",
168 "Enhanced call status",
169 "Enhanced call control",
170 "Extended Error Result Codes",
171 "Codec negotiation",
172 "HF Indicators",
173 "eSCO S4 (and T2) Settings Supported",
174 "Reserved for future definition"
175 };
176
177 static const char * hfp_enhanced_call_dir[] = {
178 "outgoing",
179 "incoming"
180 };
181
182 static const char * hfp_enhanced_call_status[] = {
183 "active",
184 "held",
185 "outgoing dialing",
186 "outgoing alerting",
187 "incoming",
188 "incoming waiting",
189 "call held by response and hold"
190 };
191
192 static const char * hfp_enhanced_call_mode[] = {
193 "voice",
194 "data",
195 "fax"
196 };
197
198 static const char * hfp_enhanced_call_mpty[] = {
199 "not a conference call",
200 "conference call"
201 };
202
hfp_enhanced_call_dir2str(uint16_t index)203 const char * hfp_enhanced_call_dir2str(uint16_t index){
204 if (index <= HFP_ENHANCED_CALL_DIR_INCOMING) return hfp_enhanced_call_dir[index];
205 return "not defined";
206 }
207
hfp_enhanced_call_status2str(uint16_t index)208 const char * hfp_enhanced_call_status2str(uint16_t index){
209 if (index <= HFP_ENHANCED_CALL_STATUS_CALL_HELD_BY_RESPONSE_AND_HOLD) return hfp_enhanced_call_status[index];
210 return "not defined";
211 }
212
hfp_enhanced_call_mode2str(uint16_t index)213 const char * hfp_enhanced_call_mode2str(uint16_t index){
214 if (index <= HFP_ENHANCED_CALL_MODE_FAX) return hfp_enhanced_call_mode[index];
215 return "not defined";
216 }
217
hfp_enhanced_call_mpty2str(uint16_t index)218 const char * hfp_enhanced_call_mpty2str(uint16_t index){
219 if (index <= HFP_ENHANCED_CALL_MPTY_CONFERENCE_CALL) return hfp_enhanced_call_mpty[index];
220 return "not defined";
221 }
222
hfp_parse_indicator_index(hfp_connection_t * hfp_connection)223 static uint16_t hfp_parse_indicator_index(hfp_connection_t * hfp_connection){
224 uint16_t index = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
225
226 if (index > HFP_MAX_NUM_INDICATORS){
227 log_info("ignoring invalid indicator index bigger then HFP_MAX_NUM_INDICATORS");
228 return HFP_MAX_NUM_INDICATORS - 1;
229 }
230
231 // indicator index enumeration starts with 1, we substract 1 to store in array with starting index 0
232 if (index > 0){
233 index -= 1;
234 } else {
235 log_info("ignoring invalid indicator index 0");
236 return 0;
237 }
238 return index;
239 }
240
hfp_next_indicators_index(hfp_connection_t * hfp_connection)241 static void hfp_next_indicators_index(hfp_connection_t * hfp_connection){
242 if (hfp_connection->parser_item_index < HFP_MAX_NUM_INDICATORS - 1){
243 hfp_connection->parser_item_index++;
244 } else {
245 log_info("Ignoring additional indicator");
246 }
247 }
248
hfp_next_codec_index(hfp_connection_t * hfp_connection)249 static void hfp_next_codec_index(hfp_connection_t * hfp_connection){
250 if (hfp_connection->parser_item_index < HFP_MAX_NUM_CODECS - 1){
251 hfp_connection->parser_item_index++;
252 } else {
253 log_info("Ignoring additional codec index");
254 }
255 }
256
hfp_next_remote_call_services_index(hfp_connection_t * hfp_connection)257 static void hfp_next_remote_call_services_index(hfp_connection_t * hfp_connection){
258 if (hfp_connection->remote_call_services_index < HFP_MAX_NUM_CALL_SERVICES - 1){
259 hfp_connection->remote_call_services_index++;
260 } else {
261 log_info("Ignoring additional remote_call_services");
262 }
263 }
264
hfp_hf_feature(int index)265 const char * hfp_hf_feature(int index){
266 if (index > HFP_HF_FEATURES_SIZE){
267 return hfp_hf_features[HFP_HF_FEATURES_SIZE];
268 }
269 return hfp_hf_features[index];
270 }
271
hfp_ag_feature(int index)272 const char * hfp_ag_feature(int index){
273 if (index > HFP_AG_FEATURES_SIZE){
274 return hfp_ag_features[HFP_AG_FEATURES_SIZE];
275 }
276 return hfp_ag_features[index];
277 }
278
send_str_over_rfcomm(uint16_t cid,const char * command)279 int send_str_over_rfcomm(uint16_t cid, const char * command){
280 if (!rfcomm_can_send_packet_now(cid)) return 1;
281 log_info("HFP_TX %s", command);
282 int err = rfcomm_send(cid, (uint8_t*) command, (uint16_t) strlen(command));
283 if (err){
284 log_error("rfcomm_send -> error 0x%02x \n", err);
285 }
286 #ifdef ENABLE_HFP_AT_MESSAGES
287 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_rfcomm_cid(cid);
288 hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_AT_MESSAGE_SENT, command);
289 #endif
290 return 1;
291 }
292
hfp_supports_codec(uint8_t codec,int codecs_nr,uint8_t * codecs)293 int hfp_supports_codec(uint8_t codec, int codecs_nr, uint8_t * codecs){
294
295 // mSBC requires support for eSCO connections
296 if ((codec == HFP_CODEC_MSBC) && !hci_extended_sco_link_supported()) return 0;
297
298 int i;
299 for (i = 0; i < codecs_nr; i++){
300 if (codecs[i] != codec) continue;
301 return 1;
302 }
303 return 0;
304 }
305
hfp_hf_drop_mSBC_if_eSCO_not_supported(uint8_t * codecs,uint8_t * codecs_nr)306 void hfp_hf_drop_mSBC_if_eSCO_not_supported(uint8_t * codecs, uint8_t * codecs_nr){
307 if (hci_extended_sco_link_supported()) return;
308 uint8_t i;
309 int filtered_codec_count = 0;
310 for (i=0; i < *codecs_nr; i++){
311 if (codecs[i] != HFP_CODEC_MSBC) {
312 codecs[filtered_codec_count++] = codecs[i];
313 }
314 }
315 *codecs_nr = filtered_codec_count;
316 }
317
318 // UTILS
get_bit(uint16_t bitmap,int position)319 int get_bit(uint16_t bitmap, int position){
320 return (bitmap >> position) & 1;
321 }
322
store_bit(uint32_t bitmap,int position,uint8_t value)323 int store_bit(uint32_t bitmap, int position, uint8_t value){
324 if (value){
325 bitmap |= 1 << position;
326 } else {
327 bitmap &= ~ (1 << position);
328 }
329 return bitmap;
330 }
331
join(char * buffer,int buffer_size,uint8_t * values,int values_nr)332 int join(char * buffer, int buffer_size, uint8_t * values, int values_nr){
333 if (buffer_size < (values_nr * 3)) return 0;
334 int i;
335 int offset = 0;
336 for (i = 0; i < (values_nr-1); i++) {
337 offset += btstack_snprintf_assert_complete(buffer+offset, buffer_size-offset, "%d,", values[i]); // puts string into buffer
338 }
339 if (i<values_nr){
340 offset += btstack_snprintf_assert_complete(buffer+offset, buffer_size-offset, "%d", values[i]);
341 }
342 return offset;
343 }
344
join_bitmap(char * buffer,int buffer_size,uint32_t values,int values_nr)345 int join_bitmap(char * buffer, int buffer_size, uint32_t values, int values_nr){
346 if (buffer_size < (values_nr * 3)) return 0;
347
348 int i;
349 int offset = 0;
350 for (i = 0; i < (values_nr-1); i++) {
351 offset += btstack_snprintf_assert_complete(buffer+offset, buffer_size-offset, "%d,", get_bit(values,i)); // puts string into buffer
352 }
353
354 if (i<values_nr){
355 offset += btstack_snprintf_assert_complete(buffer+offset, buffer_size-offset, "%d", get_bit(values,i));
356 }
357 return offset;
358 }
hfp_emit_event_for_role(hfp_role_t local_role,uint8_t * packet,uint16_t size)359 static void hfp_emit_event_for_role(hfp_role_t local_role, uint8_t * packet, uint16_t size){
360 switch (local_role){
361 case HFP_ROLE_HF:
362 (*hfp_hf_callback)(HCI_EVENT_PACKET, 0, packet, size);
363 break;
364 case HFP_ROLE_AG:
365 (*hfp_ag_callback)(HCI_EVENT_PACKET, 0, packet, size);
366 break;
367 default:
368 btstack_unreachable();
369 break;
370 }
371 }
372
hfp_emit_event_for_context(hfp_connection_t * hfp_connection,uint8_t * packet,uint16_t size)373 static void hfp_emit_event_for_context(hfp_connection_t * hfp_connection, uint8_t * packet, uint16_t size){
374 if (!hfp_connection) return;
375 hfp_emit_event_for_role(hfp_connection->local_role, packet, size);
376 }
377
hfp_emit_simple_event(hfp_connection_t * hfp_connection,uint8_t event_subtype)378 void hfp_emit_simple_event(hfp_connection_t * hfp_connection, uint8_t event_subtype){
379 hci_con_handle_t acl_handle = (hfp_connection != NULL) ? hfp_connection->acl_handle : HCI_CON_HANDLE_INVALID;
380 uint8_t event[5];
381 event[0] = HCI_EVENT_HFP_META;
382 event[1] = sizeof(event) - 2;
383 event[2] = event_subtype;
384 little_endian_store_16(event, 3, acl_handle);
385 hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
386 }
387
hfp_emit_event(hfp_connection_t * hfp_connection,uint8_t event_subtype,uint8_t value)388 void hfp_emit_event(hfp_connection_t * hfp_connection, uint8_t event_subtype, uint8_t value){
389 hci_con_handle_t acl_handle = (hfp_connection != NULL) ? hfp_connection->acl_handle : HCI_CON_HANDLE_INVALID;
390 uint8_t event[6];
391 event[0] = HCI_EVENT_HFP_META;
392 event[1] = sizeof(event) - 2;
393 event[2] = event_subtype;
394 little_endian_store_16(event, 3, acl_handle);
395 event[5] = value; // status 0 == OK
396 hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
397 }
398
hfp_emit_voice_recognition_enabled(hfp_connection_t * hfp_connection,uint8_t status)399 void hfp_emit_voice_recognition_enabled(hfp_connection_t * hfp_connection, uint8_t status){
400 btstack_assert(hfp_connection != NULL);
401
402 uint8_t event[7];
403 event[0] = HCI_EVENT_HFP_META;
404 event[1] = sizeof(event) - 2;
405 event[2] = HFP_SUBEVENT_VOICE_RECOGNITION_ACTIVATED;
406
407 little_endian_store_16(event, 3, hfp_connection->acl_handle);
408 event[5] = status; // 0:success
409 event[6] = hfp_connection->enhanced_voice_recognition_enabled ? 1 : 0;
410 hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
411 }
412
hfp_emit_voice_recognition_disabled(hfp_connection_t * hfp_connection,uint8_t status)413 void hfp_emit_voice_recognition_disabled(hfp_connection_t * hfp_connection, uint8_t status){
414 btstack_assert(hfp_connection != NULL);
415
416 uint8_t event[6];
417 event[0] = HCI_EVENT_HFP_META;
418 event[1] = sizeof(event) - 2;
419 event[2] = HFP_SUBEVENT_VOICE_RECOGNITION_DEACTIVATED;
420
421 little_endian_store_16(event, 3, hfp_connection->acl_handle);
422 event[5] = status; // 0:success
423 hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
424 }
425
hfp_emit_enhanced_voice_recognition_hf_ready_for_audio_event(hfp_connection_t * hfp_connection,uint8_t status)426 void hfp_emit_enhanced_voice_recognition_hf_ready_for_audio_event(hfp_connection_t * hfp_connection, uint8_t status){
427 hci_con_handle_t acl_handle = (hfp_connection != NULL) ? hfp_connection->acl_handle : HCI_CON_HANDLE_INVALID;
428
429 uint8_t event[6];
430 event[0] = HCI_EVENT_HFP_META;
431 event[1] = sizeof(event) - 2;
432 event[2] = HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_HF_READY_FOR_AUDIO;
433 little_endian_store_16(event, 3, acl_handle);
434 event[5] = status;
435 hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
436 }
437
hfp_emit_enhanced_voice_recognition_state_event(hfp_connection_t * hfp_connection,uint8_t status)438 void hfp_emit_enhanced_voice_recognition_state_event(hfp_connection_t * hfp_connection, uint8_t status){
439 hci_con_handle_t acl_handle = (hfp_connection != NULL) ? hfp_connection->acl_handle : HCI_CON_HANDLE_INVALID;
440
441 uint8_t event[6];
442 event[0] = HCI_EVENT_HFP_META;
443 event[1] = sizeof(event) - 2;
444 switch (hfp_connection->ag_vra_state){
445 case HFP_VOICE_RECOGNITION_STATE_AG_READY_TO_ACCEPT_AUDIO_INPUT:
446 event[2] = HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_AG_READY_TO_ACCEPT_AUDIO_INPUT;
447 break;
448 case HFP_VOICE_RECOGNITION_STATE_AG_IS_STARTING_SOUND:
449 event[2] = HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_AG_IS_STARTING_SOUND;
450 break;
451 case HFP_VOICE_RECOGNITION_STATE_AG_IS_PROCESSING_AUDIO_INPUT:
452 event[2] = HFP_SUBEVENT_ENHANCED_VOICE_RECOGNITION_AG_IS_PROCESSING_AUDIO_INPUT;
453 break;
454 default:
455 btstack_unreachable();
456 break;
457 }
458
459 little_endian_store_16(event, 3, acl_handle);
460 event[5] = status;
461 hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
462 }
463
hfp_emit_slc_connection_event(hfp_role_t local_role,uint8_t status,hci_con_handle_t con_handle,bd_addr_t addr)464 void hfp_emit_slc_connection_event(hfp_role_t local_role, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr){
465 uint8_t event[12];
466 int pos = 0;
467 event[pos++] = HCI_EVENT_HFP_META;
468 event[pos++] = sizeof(event) - 2;
469 event[pos++] = HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
470 little_endian_store_16(event, pos, con_handle);
471 pos += 2;
472 event[pos++] = status; // status 0 == OK
473 reverse_bd_addr(addr,&event[pos]);
474 pos += 6;
475 hfp_emit_event_for_role(local_role, event, sizeof(event));
476 }
477
hfp_emit_audio_connection_released(hfp_connection_t * hfp_connection,hci_con_handle_t sco_handle)478 static void hfp_emit_audio_connection_released(hfp_connection_t * hfp_connection, hci_con_handle_t sco_handle){
479 btstack_assert(hfp_connection != NULL);
480 uint8_t event[7];
481 int pos = 0;
482 event[pos++] = HCI_EVENT_HFP_META;
483 event[pos++] = sizeof(event) - 2;
484 event[pos++] = HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED;
485 little_endian_store_16(event, pos, hfp_connection->acl_handle);
486 pos += 2;
487 little_endian_store_16(event, pos, sco_handle);
488 pos += 2;
489 hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
490 }
491
hfp_emit_sco_connection_established(hfp_connection_t * hfp_connection,uint8_t status,uint8_t negotiated_codec,uint16_t rx_packet_length,uint16_t tx_packet_length)492 void hfp_emit_sco_connection_established(hfp_connection_t *hfp_connection, uint8_t status, uint8_t negotiated_codec,
493 uint16_t rx_packet_length, uint16_t tx_packet_length) {
494 btstack_assert(hfp_connection != NULL);
495 uint8_t event[21];
496 int pos = 0;
497 event[pos++] = HCI_EVENT_HFP_META;
498 event[pos++] = sizeof(event) - 2;
499 event[pos++] = HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED;
500 little_endian_store_16(event, pos, hfp_connection->acl_handle);
501 pos += 2;
502 event[pos++] = status; // status 0 == OK
503 little_endian_store_16(event, pos, hfp_connection->sco_handle);
504 pos += 2;
505 reverse_bd_addr(hfp_connection->remote_addr,&event[pos]);
506 pos += 6;
507 event[pos++] = negotiated_codec;
508 little_endian_store_16(event, pos, hfp_connection->packet_types);
509 pos += 2;
510 little_endian_store_16(event, pos, rx_packet_length);
511 pos += 2;
512 little_endian_store_16(event, pos, tx_packet_length);
513 pos += 2;
514 hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
515 }
516
hfp_emit_string_event(hfp_connection_t * hfp_connection,uint8_t event_subtype,const char * value)517 void hfp_emit_string_event(hfp_connection_t * hfp_connection, uint8_t event_subtype, const char * value){
518 btstack_assert(hfp_connection != NULL);
519 #ifdef ENABLE_HFP_AT_MESSAGES
520 uint8_t event[256];
521 #else
522 uint8_t event[40];
523 #endif
524 uint16_t string_len = btstack_min((uint16_t) strlen(value), sizeof(event) - 6);
525 event[0] = HCI_EVENT_HFP_META;
526 event[1] = 4 + string_len;
527 event[2] = event_subtype;
528 little_endian_store_16(event, 3, hfp_connection->acl_handle);
529 memcpy((char*)&event[5], value, string_len);
530 event[5 + string_len] = 0;
531 hfp_emit_event_for_context(hfp_connection, event, 6 + string_len);
532 }
533
hfp_get_connections(void)534 btstack_linked_list_t * hfp_get_connections(void){
535 return (btstack_linked_list_t *) &hfp_connections;
536 }
537
get_hfp_connection_context_for_rfcomm_cid(uint16_t cid)538 hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid){
539 btstack_linked_list_iterator_t it;
540 btstack_linked_list_iterator_init(&it, hfp_get_connections());
541 while (btstack_linked_list_iterator_has_next(&it)){
542 hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
543 if (hfp_connection->rfcomm_cid == cid){
544 return hfp_connection;
545 }
546 }
547 return NULL;
548 }
549
get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr,hfp_role_t hfp_role)550 hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr, hfp_role_t hfp_role){
551 btstack_linked_list_iterator_t it;
552 btstack_linked_list_iterator_init(&it, hfp_get_connections());
553 while (btstack_linked_list_iterator_has_next(&it)){
554 hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
555 if ((memcmp(hfp_connection->remote_addr, bd_addr, 6) == 0) && (hfp_connection->local_role == hfp_role)) {
556 return hfp_connection;
557 }
558 }
559 return NULL;
560 }
561
get_hfp_connection_context_for_sco_handle(uint16_t handle,hfp_role_t hfp_role)562 hfp_connection_t * get_hfp_connection_context_for_sco_handle(uint16_t handle, hfp_role_t hfp_role){
563 btstack_linked_list_iterator_t it;
564 btstack_linked_list_iterator_init(&it, hfp_get_connections());
565 while (btstack_linked_list_iterator_has_next(&it)){
566 hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
567 if ((hfp_connection->sco_handle == handle) && (hfp_connection->local_role == hfp_role)){
568 return hfp_connection;
569 }
570 }
571 return NULL;
572 }
573
get_hfp_connection_context_for_acl_handle(uint16_t handle,hfp_role_t hfp_role)574 hfp_connection_t * get_hfp_connection_context_for_acl_handle(uint16_t handle, hfp_role_t hfp_role){
575 btstack_linked_list_iterator_t it;
576 btstack_linked_list_iterator_init(&it, hfp_get_connections());
577 while (btstack_linked_list_iterator_has_next(&it)){
578 hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
579 if ((hfp_connection->acl_handle == handle) && (hfp_connection->local_role == hfp_role)){
580 return hfp_connection;
581 }
582 }
583 return NULL;
584 }
585
586
hfp_reset_voice_recognition(hfp_connection_t * hfp_connection)587 static void hfp_reset_voice_recognition(hfp_connection_t * hfp_connection){
588 btstack_assert(hfp_connection != NULL);
589 hfp_voice_recognition_activation_status_t current_vra_state = hfp_connection->vra_state;
590 hfp_connection->vra_state = HFP_VRA_VOICE_RECOGNITION_OFF;
591
592 if (current_vra_state != HFP_VRA_VOICE_RECOGNITION_OFF){
593 hfp_emit_voice_recognition_disabled(hfp_connection, ERROR_CODE_SUCCESS);
594 } else if (hfp_connection->vra_state_requested != HFP_VRA_VOICE_RECOGNITION_OFF){
595 hfp_emit_voice_recognition_disabled(hfp_connection, ERROR_CODE_SUCCESS);
596 }
597
598 hfp_connection->vra_state_requested = HFP_VRA_VOICE_RECOGNITION_OFF;
599 hfp_connection->activate_voice_recognition = false;
600 hfp_connection->deactivate_voice_recognition = false;
601 hfp_connection->enhanced_voice_recognition_enabled = false;
602 hfp_connection->ag_vra_status = 0;
603 hfp_connection->ag_vra_state = HFP_VOICE_RECOGNITION_STATE_AG_READY;
604 }
605
hfp_reset_context_flags(hfp_connection_t * hfp_connection)606 void hfp_reset_context_flags(hfp_connection_t * hfp_connection){
607 if (!hfp_connection) return;
608 hfp_connection->ok_pending = 0;
609 hfp_connection->send_error = 0;
610
611 hfp_connection->found_equal_sign = false;
612
613 hfp_connection->change_status_update_for_individual_ag_indicators = 0;
614 hfp_connection->operator_name_changed = 0;
615
616 hfp_connection->enable_extended_audio_gateway_error_report = 0;
617 hfp_connection->extended_audio_gateway_error = 0;
618
619 // establish codecs hfp_connection
620 hfp_connection->suggested_codec = 0;
621 hfp_connection->negotiated_codec = 0;
622 hfp_connection->codec_confirmed = 0;
623
624 hfp_connection->establish_audio_connection = 0;
625 hfp_connection->call_waiting_notification_enabled = 0;
626 hfp_connection->command = HFP_CMD_NONE;
627 hfp_connection->enable_status_update_for_ag_indicators = 0xFF;
628 hfp_connection->clip_have_alpha = false;
629 hfp_reset_voice_recognition(hfp_connection);
630 }
631
create_hfp_connection_context(void)632 static hfp_connection_t * create_hfp_connection_context(void){
633 hfp_connection_t * hfp_connection = btstack_memory_hfp_connection_get();
634 if (!hfp_connection) return NULL;
635
636 hfp_connection->state = HFP_IDLE;
637 hfp_connection->call_state = HFP_CALL_IDLE;
638 hfp_connection->codecs_state = HFP_CODECS_IDLE;
639
640 hfp_connection->parser_state = HFP_PARSER_CMD_HEADER;
641
642 hfp_connection->acl_handle = HCI_CON_HANDLE_INVALID;
643 hfp_connection->sco_handle = HCI_CON_HANDLE_INVALID;
644
645 // HF only
646 hfp_connection->hf_call_status = HFP_CALL_STATUS_NO_HELD_OR_ACTIVE_CALLS;
647 hfp_connection->hf_callsetup_status = HFP_CALLSETUP_STATUS_NO_CALL_SETUP_IN_PROGRESS;
648 hfp_connection->hf_callheld_status = HFP_CALLHELD_STATUS_NO_CALLS_HELD;
649
650 hfp_reset_context_flags(hfp_connection);
651
652 btstack_linked_list_add_tail(&hfp_connections, (btstack_linked_item_t*)hfp_connection);
653 return hfp_connection;
654 }
655
hfp_finalize_connection_context(hfp_connection_t * hfp_connection)656 void hfp_finalize_connection_context(hfp_connection_t * hfp_connection){
657 btstack_linked_list_remove(&hfp_connections, (btstack_linked_item_t*) hfp_connection);
658 btstack_memory_hfp_connection_free(hfp_connection);
659 }
660
hfp_create_connection(bd_addr_t bd_addr,hfp_role_t local_role)661 static hfp_connection_t * hfp_create_connection(bd_addr_t bd_addr, hfp_role_t local_role){
662 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(bd_addr, local_role);
663 if (hfp_connection) return hfp_connection;
664 hfp_connection = create_hfp_connection_context();
665 if (!hfp_connection) {
666 return NULL;
667 }
668 (void)memcpy(hfp_connection->remote_addr, bd_addr, 6);
669 hfp_connection->local_role = local_role;
670 log_info("Create HFP context %p: role %u, addr %s", hfp_connection, local_role, bd_addr_to_str(bd_addr));
671
672 #ifdef ENABLE_NXP_PCM_WBS
673 hfp_connection->nxp_start_audio_handle = HCI_CON_HANDLE_INVALID;
674 hfp_connection->nxp_stop_audio_handle = HCI_CON_HANDLE_INVALID;
675 #endif
676
677 return hfp_connection;
678 }
679
680 /* @param network.
681 * 0 == no ability to reject a call.
682 * 1 == ability to reject a call.
683 */
684
685 /* @param suported_features
686 * HF bit 0: EC and/or NR function (yes/no, 1 = yes, 0 = no)
687 * HF bit 1: Call waiting or three-way calling(yes/no, 1 = yes, 0 = no)
688 * HF bit 2: CLI presentation capability (yes/no, 1 = yes, 0 = no)
689 * HF bit 3: Voice recognition activation (yes/no, 1= yes, 0 = no)
690 * HF bit 4: Remote volume control (yes/no, 1 = yes, 0 = no)
691 * HF bit 5: Wide band speech (yes/no, 1 = yes, 0 = no)
692 */
693 /* Bit position:
694 * AG bit 0: Three-way calling (yes/no, 1 = yes, 0 = no)
695 * AG bit 1: EC and/or NR function (yes/no, 1 = yes, 0 = no)
696 * AG bit 2: Voice recognition function (yes/no, 1 = yes, 0 = no)
697 * AG bit 3: In-band ring tone capability (yes/no, 1 = yes, 0 = no)
698 * AG bit 4: Attach a phone number to a voice tag (yes/no, 1 = yes, 0 = no)
699 * AG bit 5: Wide band speech (yes/no, 1 = yes, 0 = no)
700 */
701
hfp_create_sdp_record(uint8_t * service,uint32_t service_record_handle,uint16_t service_uuid,int rfcomm_channel_nr,const char * name)702 void hfp_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint16_t service_uuid, int rfcomm_channel_nr, const char * name){
703 uint8_t* attribute;
704 de_create_sequence(service);
705
706 // 0x0000 "Service Record Handle"
707 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_RECORD_HANDLE);
708 de_add_number(service, DE_UINT, DE_SIZE_32, service_record_handle);
709
710 // 0x0001 "Service Class ID List"
711 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST);
712 attribute = de_push_sequence(service);
713 {
714 // "UUID for Service"
715 de_add_number(attribute, DE_UUID, DE_SIZE_16, service_uuid);
716 de_add_number(attribute, DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_GENERIC_AUDIO);
717 }
718 de_pop_sequence(service, attribute);
719
720 // 0x0004 "Protocol Descriptor List"
721 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST);
722 attribute = de_push_sequence(service);
723 {
724 uint8_t* l2cpProtocol = de_push_sequence(attribute);
725 {
726 de_add_number(l2cpProtocol, DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_L2CAP);
727 }
728 de_pop_sequence(attribute, l2cpProtocol);
729
730 uint8_t* rfcomm = de_push_sequence(attribute);
731 {
732 de_add_number(rfcomm, DE_UUID, DE_SIZE_16, BLUETOOTH_PROTOCOL_RFCOMM); // rfcomm_service
733 de_add_number(rfcomm, DE_UINT, DE_SIZE_8, rfcomm_channel_nr); // rfcomm channel
734 }
735 de_pop_sequence(attribute, rfcomm);
736 }
737 de_pop_sequence(service, attribute);
738
739
740 // 0x0005 "Public Browse Group"
741 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BROWSE_GROUP_LIST); // public browse group
742 attribute = de_push_sequence(service);
743 {
744 de_add_number(attribute, DE_UUID, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_PUBLIC_BROWSE_ROOT);
745 }
746 de_pop_sequence(service, attribute);
747
748 // 0x0009 "Bluetooth Profile Descriptor List"
749 de_add_number(service, DE_UINT, DE_SIZE_16, BLUETOOTH_ATTRIBUTE_BLUETOOTH_PROFILE_DESCRIPTOR_LIST);
750 attribute = de_push_sequence(service);
751 {
752 uint8_t *sppProfile = de_push_sequence(attribute);
753 {
754 de_add_number(sppProfile, DE_UUID, DE_SIZE_16, BLUETOOTH_SERVICE_CLASS_HANDSFREE);
755 de_add_number(sppProfile, DE_UINT, DE_SIZE_16, 0x0109); // Version 1.9
756 }
757 de_pop_sequence(attribute, sppProfile);
758 }
759 de_pop_sequence(service, attribute);
760
761 // 0x0100 "Service Name"
762 if (strlen(name) > 0){
763 de_add_number(service, DE_UINT, DE_SIZE_16, 0x0100);
764 de_add_data(service, DE_STRING, (uint16_t) strlen(name), (uint8_t *) name);
765 }
766 }
767
hfp_handle_slc_setup_error(hfp_connection_t * hfp_connection,uint8_t status)768 static void hfp_handle_slc_setup_error(hfp_connection_t * hfp_connection, uint8_t status){
769 // cache fields for event
770 hfp_role_t local_role = hfp_connection->local_role;
771 bd_addr_t remote_addr;
772 // cppcheck-suppress uninitvar ; remote_addr is reported as uninitialized although it's the destination of the memcpy
773 (void)memcpy(remote_addr, hfp_connection->remote_addr, 6);
774 // finalize connection struct
775 hfp_finalize_connection_context(hfp_connection);
776 // emit event
777 hfp_emit_slc_connection_event(local_role, status, HCI_CON_HANDLE_INVALID, remote_addr);
778 }
779
handle_query_rfcomm_event(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)780 static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
781 UNUSED(packet_type); // ok: handling own sdp events
782 UNUSED(channel); // ok: no channel
783 UNUSED(size); // ok: handling own sdp events
784
785 hfp_connection_t * hfp_connection = get_hfp_connection_context_for_bd_addr(hfp_sdp_query_context.remote_address, hfp_sdp_query_context.local_role);
786 if (hfp_connection == NULL) {
787 log_info("connection with %s and local role %d not found", hfp_sdp_query_context.remote_address, hfp_sdp_query_context.local_role);
788 return;
789 }
790
791 switch (hci_event_packet_get_type(packet)){
792 case SDP_EVENT_QUERY_RFCOMM_SERVICE:
793 hfp_connection->rfcomm_channel_nr = sdp_event_query_rfcomm_service_get_rfcomm_channel(packet);
794 break;
795 case SDP_EVENT_QUERY_COMPLETE:
796 if (hfp_connection->rfcomm_channel_nr > 0){
797 hfp_connection->state = HFP_W4_RFCOMM_CONNECTED;
798 btstack_packet_handler_t packet_handler;
799 switch (hfp_connection->local_role){
800 case HFP_ROLE_AG:
801 packet_handler = hfp_ag_rfcomm_packet_handler;
802 break;
803 case HFP_ROLE_HF:
804 packet_handler = hfp_hf_rfcomm_packet_handler;
805 break;
806 default:
807 btstack_assert(false);
808 return;
809 }
810
811 rfcomm_create_channel(packet_handler, hfp_connection->remote_addr, hfp_connection->rfcomm_channel_nr, NULL);
812
813 } else {
814 uint8_t status = sdp_event_query_complete_get_status(packet);
815 if (status == ERROR_CODE_SUCCESS){
816 // report service not found
817 status = SDP_SERVICE_NOT_FOUND;
818 }
819 hfp_handle_slc_setup_error(hfp_connection, status);
820 log_info("rfcomm service not found, status 0x%02x", status);
821 }
822
823 // register the SDP Query request to check if there is another connection waiting for the query
824 // ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback
825 (void) sdp_client_register_query_callback(&hfp_sdp_query_request);
826 break;
827 default:
828 break;
829 }
830 }
831
832 // returns 0 if unexpected error or no other link options remained, otherwise 1
hfp_handle_failed_sco_connection(uint8_t status)833 static int hfp_handle_failed_sco_connection(uint8_t status){
834
835 if (hfp_sco_establishment_active->accept_sco != 0){
836 log_info("(e)SCO Connection failed but not started by us");
837 return 0;
838 }
839
840 log_info("(e)SCO Connection failed 0x%02x", status);
841 switch (status){
842 case ERROR_CODE_INVALID_LMP_PARAMETERS_INVALID_LL_PARAMETERS:
843 case ERROR_CODE_SCO_AIR_MODE_REJECTED:
844 case ERROR_CODE_SCO_INTERVAL_REJECTED:
845 case ERROR_CODE_SCO_OFFSET_REJECTED:
846 case ERROR_CODE_UNSPECIFIED_ERROR:
847 case ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE:
848 case ERROR_CODE_UNSUPPORTED_LMP_PARAMETER_VALUE_UNSUPPORTED_LL_PARAMETER_VALUE:
849 case ERROR_CODE_UNSUPPORTED_REMOTE_FEATURE_UNSUPPORTED_LMP_FEATURE:
850 break;
851 default:
852 return 0;
853 }
854
855 // note: eSCO_S4 supported flag not available, but it's only relevant for highest CVSD link setting (and the current failed)
856 hfp_link_settings_t next_setting = hfp_next_link_setting_for_connection(hfp_sco_establishment_active->link_setting, hfp_sco_establishment_active, false);
857
858 // handle no valid setting found
859 if (next_setting == HFP_LINK_SETTINGS_NONE) {
860 if (hfp_sco_establishment_active->negotiated_codec == HFP_CODEC_MSBC){
861 log_info("T2/T1 failed, fallback to CVSD - D1");
862 hfp_sco_establishment_active->negotiated_codec = HFP_CODEC_CVSD;
863 hfp_sco_establishment_active->sco_for_msbc_failed = 1;
864 hfp_sco_establishment_active->ag_send_common_codec = true;
865 hfp_sco_establishment_active->link_setting = HFP_LINK_SETTINGS_D1;
866 } else {
867 // no other options
868 return 0;
869 }
870 }
871
872 log_info("e)SCO Connection: try new link_setting %d", next_setting);
873 hfp_sco_establishment_active->establish_audio_connection = 1;
874 hfp_sco_establishment_active->link_setting = next_setting;
875 hfp_sco_establishment_active->accept_sco = 0;
876 hfp_sco_establishment_active = NULL;
877 return 1;
878 }
879
hfp_handle_hci_event(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size,hfp_role_t local_role)880 void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size, hfp_role_t local_role){
881 UNUSED(packet_type);
882 UNUSED(channel); // ok: no channel
883 UNUSED(size);
884
885 bd_addr_t event_addr;
886 hci_con_handle_t handle;
887 hfp_connection_t * hfp_connection = NULL;
888 uint8_t status;
889
890 log_debug("HFP HCI event handler type %u, event type %x, size %u", packet_type, hci_event_packet_get_type(packet), size);
891
892 switch (hci_event_packet_get_type(packet)) {
893
894 case HCI_EVENT_CONNECTION_REQUEST:
895 switch(hci_event_connection_request_get_link_type(packet)){
896 case 0: // SCO
897 case 2: // eSCO
898 hci_event_connection_request_get_bd_addr(packet, event_addr);
899 hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr, local_role);
900 if (!hfp_connection) break;
901 if (hci_event_connection_request_get_link_type(packet) == 2){
902 hfp_connection->accept_sco = 2;
903 } else {
904 hfp_connection->accept_sco = 1;
905 }
906 // configure SBC coded if needed
907 hfp_prepare_for_sco(hfp_connection);
908 log_info("accept sco %u\n", hfp_connection->accept_sco);
909 break;
910 default:
911 break;
912 }
913 break;
914
915 case HCI_EVENT_COMMAND_STATUS:
916 if (hci_event_command_status_get_command_opcode(packet) == hci_setup_synchronous_connection.opcode) {
917 if (hfp_sco_establishment_active == NULL) break;
918 status = hci_event_command_status_get_status(packet);
919 if (status == ERROR_CODE_SUCCESS) break;
920
921 hfp_connection = hfp_sco_establishment_active;
922 if (hfp_handle_failed_sco_connection(status)) break;
923
924 hfp_connection->accept_sco = 0;
925 hfp_connection->establish_audio_connection = 0;
926 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
927 hfp_sco_establishment_active = NULL;
928 hfp_emit_sco_connection_established(hfp_connection, status,
929 hfp_connection->negotiated_codec, 0, 0);
930 }
931 break;
932
933 case HCI_EVENT_SYNCHRONOUS_CONNECTION_COMPLETE:{
934 if (hfp_sco_establishment_active == NULL) break;
935
936 hfp_connection = hfp_sco_establishment_active;
937
938 status = hci_event_synchronous_connection_complete_get_status(packet);
939 if (status != ERROR_CODE_SUCCESS){
940 if (hfp_handle_failed_sco_connection(status)) break;
941
942 hfp_connection->accept_sco = 0;
943 hfp_connection->establish_audio_connection = 0;
944 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
945 hfp_sco_establishment_active = NULL;
946 hfp_emit_sco_connection_established(hfp_connection, status,
947 hfp_connection->negotiated_codec, 0, 0);
948 break;
949 }
950
951 uint16_t sco_handle = hci_event_synchronous_connection_complete_get_handle(packet);
952 uint8_t link_type = hci_event_synchronous_connection_complete_get_link_type(packet);
953 uint8_t transmission_interval = hci_event_synchronous_connection_complete_get_transmission_interval(packet); // measured in slots
954 uint8_t retransmission_interval = hci_event_synchronous_connection_complete_get_retransmission_interval(packet);// measured in slots
955 uint16_t rx_packet_length = hci_event_synchronous_connection_complete_get_rx_packet_length(packet); // measured in bytes
956 uint16_t tx_packet_length = hci_event_synchronous_connection_complete_get_tx_packet_length(packet); // measured in bytes
957
958 switch (link_type){
959 case 0x00:
960 log_info("SCO Connection established.");
961 if (transmission_interval != 0) log_error("SCO Connection: transmission_interval not zero: %d.", transmission_interval);
962 if (retransmission_interval != 0) log_error("SCO Connection: retransmission_interval not zero: %d.", retransmission_interval);
963 if (rx_packet_length != 0) log_error("SCO Connection: rx_packet_length not zero: %d.", rx_packet_length);
964 if (tx_packet_length != 0) log_error("SCO Connection: tx_packet_length not zero: %d.", tx_packet_length);
965 break;
966 case 0x02:
967 log_info("eSCO Connection established. \n");
968 break;
969 default:
970 log_error("(e)SCO reserved link_type 0x%2x", link_type);
971 break;
972 }
973
974 log_info("sco_handle 0x%2x, address %s, transmission_interval %u slots, retransmission_interval %u slots, "
975 " rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)\n", sco_handle,
976 bd_addr_to_str(event_addr), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length,
977 hci_event_synchronous_connection_complete_get_air_mode(packet));
978
979 if (hfp_connection->state == HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){
980 log_info("SCO about to disconnect: HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN");
981 hfp_connection->state = HFP_W2_DISCONNECT_SCO;
982 break;
983 }
984 hfp_connection->sco_handle = sco_handle;
985 hfp_connection->accept_sco = 0;
986 hfp_connection->establish_audio_connection = 0;
987
988 hfp_connection->state = HFP_AUDIO_CONNECTION_ESTABLISHED;
989
990 switch (hfp_connection->vra_state){
991 case HFP_VRA_VOICE_RECOGNITION_ACTIVATED:
992 hfp_connection->ag_audio_connection_opened_before_vra = false;
993 break;
994 default:
995 hfp_connection->ag_audio_connection_opened_before_vra = true;
996 break;
997 }
998
999 hfp_sco_establishment_active = NULL;
1000
1001 hfp_emit_sco_connection_established(hfp_connection, status,
1002 hfp_connection->negotiated_codec, rx_packet_length, tx_packet_length);
1003
1004 #ifdef ENABLE_NXP_PCM_WBS
1005 hfp_connection->nxp_start_audio_handle = hfp_connection->sco_handle;
1006 #endif
1007 break;
1008 }
1009
1010 case HCI_EVENT_DISCONNECTION_COMPLETE:
1011 handle = little_endian_read_16(packet,3);
1012 hfp_connection = get_hfp_connection_context_for_sco_handle(handle, local_role);
1013
1014 if (!hfp_connection) break;
1015
1016 #ifdef ENABLE_CC256X_ASSISTED_HFP
1017 hfp_connection->cc256x_send_wbs_disassociate = true;
1018 #endif
1019 #ifdef ENABLE_BCM_PCM_WBS
1020 hfp_connection->bcm_send_disable_wbs = true;
1021 #endif
1022 #ifdef ENABLE_NXP_PCM_WBS
1023 hfp_connection->nxp_stop_audio_handle = hfp_connection->sco_handle;
1024 #endif
1025
1026 if (hfp_connection->sco_handle == handle){
1027 hfp_connection->sco_handle = HCI_CON_HANDLE_INVALID;
1028 hfp_connection->release_audio_connection = 0;
1029 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
1030 hfp_emit_audio_connection_released(hfp_connection, handle);
1031
1032 hfp_connection->ag_audio_connection_opened_before_vra = false;
1033
1034 if (hfp_connection->acl_handle == HCI_CON_HANDLE_INVALID){
1035 hfp_reset_voice_recognition(hfp_connection);
1036 hfp_emit_event(hfp_connection, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0);
1037 hfp_finalize_connection_context(hfp_connection);
1038 break;
1039 } else if (hfp_connection->release_slc_connection == 1){
1040 hfp_connection->release_slc_connection = 0;
1041 hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM;
1042 rfcomm_disconnect(hfp_connection->acl_handle);
1043 }
1044 }
1045
1046 if (hfp_connection->state == HFP_W4_SCO_DISCONNECTED_TO_SHUTDOWN){
1047 // RFCOMM already closed -> remote power off
1048 #if defined(ENABLE_CC256X_ASSISTED_HFP) || defined (ENABLE_BCM_PCM_WBS)
1049 hfp_connection->state = HFP_W4_WBS_SHUTDOWN;
1050 #else
1051 hfp_finalize_connection_context(hfp_connection);
1052 #endif
1053 break;
1054 }
1055 break;
1056
1057 default:
1058 break;
1059 }
1060 }
1061
1062
hfp_handle_rfcomm_event(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size,hfp_role_t local_role)1063 void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size, hfp_role_t local_role){
1064 UNUSED(packet_type);
1065 UNUSED(channel); // ok: no channel
1066 UNUSED(size);
1067
1068 bd_addr_t event_addr;
1069 uint16_t rfcomm_cid;
1070 hfp_connection_t * hfp_connection = NULL;
1071 uint8_t status;
1072
1073 log_debug("HFP packet_handler type %u, event type %x, size %u", packet_type, hci_event_packet_get_type(packet), size);
1074
1075 switch (hci_event_packet_get_type(packet)) {
1076
1077 case RFCOMM_EVENT_INCOMING_CONNECTION:
1078 // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
1079 rfcomm_event_incoming_connection_get_bd_addr(packet, event_addr);
1080 hfp_connection = hfp_create_connection(event_addr, local_role);
1081 if (!hfp_connection){
1082 log_info("hfp: no memory to accept incoming connection - decline");
1083 rfcomm_decline_connection(rfcomm_event_incoming_connection_get_rfcomm_cid(packet));
1084 return;
1085 }
1086 if (hfp_connection->state != HFP_IDLE) {
1087 log_error("hfp: incoming connection but not idle, reject");
1088 rfcomm_decline_connection(rfcomm_event_incoming_connection_get_rfcomm_cid(packet));
1089 return;
1090 }
1091
1092 hfp_connection->rfcomm_cid = rfcomm_event_incoming_connection_get_rfcomm_cid(packet);
1093 hfp_connection->state = HFP_W4_RFCOMM_CONNECTED;
1094 rfcomm_accept_connection(hfp_connection->rfcomm_cid);
1095 break;
1096
1097 case RFCOMM_EVENT_CHANNEL_OPENED:
1098 rfcomm_event_channel_opened_get_bd_addr(packet, event_addr);
1099
1100 hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr, local_role);
1101 btstack_assert(hfp_connection != NULL);
1102
1103 if (hfp_connection->state != HFP_W4_RFCOMM_CONNECTED){
1104 break;
1105 }
1106
1107 status = rfcomm_event_channel_opened_get_status(packet);
1108 if (status != ERROR_CODE_SUCCESS) {
1109 hfp_handle_slc_setup_error(hfp_connection, status);
1110 break;
1111 }
1112
1113 hfp_connection->acl_handle = rfcomm_event_channel_opened_get_con_handle(packet);
1114 hfp_connection->rfcomm_cid = rfcomm_event_channel_opened_get_rfcomm_cid(packet);
1115 hfp_connection->rfcomm_mtu = rfcomm_event_channel_opened_get_max_frame_size(packet);
1116 bd_addr_copy(hfp_connection->remote_addr, event_addr);
1117 hfp_connection->state = HFP_EXCHANGE_SUPPORTED_FEATURES;
1118
1119 if (local_role == HFP_ROLE_HF) {
1120 // setup HF Indicators
1121 uint8_t i;
1122 for (i=0; i < hfp_hf_indicators_nr; i++){
1123 hfp_connection->generic_status_indicators[i].uuid = hfp_hf_indicators[i];
1124 hfp_connection->generic_status_indicators[i].state = 0;
1125 }
1126 }
1127
1128 rfcomm_request_can_send_now_event(hfp_connection->rfcomm_cid);
1129 break;
1130
1131 case RFCOMM_EVENT_CHANNEL_CLOSED:
1132 rfcomm_cid = little_endian_read_16(packet,2);
1133 hfp_connection = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid);
1134 if (!hfp_connection) break;
1135 switch (hfp_connection->state){
1136 case HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART:
1137 hfp_connection->acl_handle = HCI_CON_HANDLE_INVALID;
1138 hfp_connection->state = HFP_IDLE;
1139 hfp_establish_service_level_connection(hfp_connection->remote_addr, hfp_connection->service_uuid, local_role);
1140 break;
1141
1142 case HFP_AUDIO_CONNECTION_ESTABLISHED:
1143 // service connection was released, this implicitly releases audio connection as well
1144 hfp_connection->release_audio_connection = 0;
1145 hfp_connection->acl_handle = HCI_CON_HANDLE_INVALID;
1146 hfp_connection->state = HFP_W4_SCO_DISCONNECTED_TO_SHUTDOWN;
1147 gap_disconnect(hfp_connection->sco_handle);
1148 break;
1149
1150 default:
1151 // regular case
1152 hfp_reset_voice_recognition(hfp_connection);
1153 hfp_emit_event(hfp_connection, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0);
1154 hfp_finalize_connection_context(hfp_connection);
1155 break;
1156 }
1157 break;
1158
1159 default:
1160 break;
1161 }
1162 }
1163 // translates command string into hfp_command_t CMD
1164
1165 typedef struct {
1166 const char * command;
1167 hfp_command_t command_id;
1168 } hfp_command_entry_t;
1169
1170 static hfp_command_entry_t hfp_ag_command_table[] = {
1171 { "AT+BAC=", HFP_CMD_AVAILABLE_CODECS },
1172 { "AT+BCC", HFP_CMD_TRIGGER_CODEC_CONNECTION_SETUP },
1173 { "AT+BCS=", HFP_CMD_HF_CONFIRMED_CODEC },
1174 { "AT+BIA=", HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE, }, // +BIA:<enabled>,,<enabled>,,,<enabled>
1175 { "AT+BIEV=", HFP_CMD_HF_INDICATOR_STATUS },
1176 { "AT+BIND=", HFP_CMD_LIST_GENERIC_STATUS_INDICATORS },
1177 { "AT+BIND=?", HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS },
1178 { "AT+BIND?", HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE },
1179 { "AT+BINP=", HFP_CMD_HF_REQUEST_PHONE_NUMBER },
1180 { "AT+BLDN", HFP_CMD_REDIAL_LAST_NUMBER },
1181 { "AT+BRSF=", HFP_CMD_SUPPORTED_FEATURES },
1182 { "AT+BTRH=", HFP_CMD_RESPONSE_AND_HOLD_COMMAND },
1183 { "AT+BTRH?", HFP_CMD_RESPONSE_AND_HOLD_QUERY },
1184 { "AT+BVRA=", HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION },
1185 { "AT+CCWA=", HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION},
1186 { "AT+CHLD=", HFP_CMD_CALL_HOLD },
1187 { "AT+CHLD=?", HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES },
1188 { "AT+CHUP", HFP_CMD_HANG_UP_CALL },
1189 { "AT+CIND=?", HFP_CMD_RETRIEVE_AG_INDICATORS },
1190 { "AT+CIND?", HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS },
1191 { "AT+CLCC", HFP_CMD_LIST_CURRENT_CALLS },
1192 { "AT+CLIP=", HFP_CMD_ENABLE_CLIP},
1193 { "AT+CMEE=", HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR},
1194 { "AT+CMER=", HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE },
1195 { "AT+CNUM", HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION },
1196 { "AT+COPS=", HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT },
1197 { "AT+COPS?", HFP_CMD_QUERY_OPERATOR_SELECTION_NAME },
1198 { "AT+IPHONEACCEV=", HFP_CMD_APPLE_ACCESSORY_STATE },
1199 { "AT+NREC=", HFP_CMD_TURN_OFF_EC_AND_NR, },
1200 { "AT+VGM=", HFP_CMD_SET_MICROPHONE_GAIN },
1201 { "AT+VGS=", HFP_CMD_SET_SPEAKER_GAIN },
1202 { "AT+VTS=", HFP_CMD_TRANSMIT_DTMF_CODES },
1203 { "AT+XAPL=", HFP_CMD_APPLE_ACCESSORY_INFORMATION },
1204 { "ATA", HFP_CMD_CALL_ANSWERED },
1205 };
1206
1207 static hfp_command_entry_t hfp_hf_command_table[] = {
1208 { "+BCS:", HFP_CMD_AG_SUGGESTED_CODEC },
1209 { "+BIND:", HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS },
1210 { "+BINP:", HFP_CMD_AG_SENT_PHONE_NUMBER },
1211 { "+BRSF:", HFP_CMD_SUPPORTED_FEATURES },
1212 { "+BSIR:", HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING },
1213 { "+BTRH:", HFP_CMD_RESPONSE_AND_HOLD_STATUS },
1214 { "+BVRA:", HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION },
1215 { "+CCWA:", HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE, },
1216 { "+CHLD:", HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES },
1217 { "+CIEV:", HFP_CMD_TRANSFER_AG_INDICATOR_STATUS},
1218 { "+CIND:", HFP_CMD_RETRIEVE_AG_INDICATORS_GENERIC },
1219 { "+CLCC:", HFP_CMD_LIST_CURRENT_CALLS },
1220 { "+CLIP:", HFP_CMD_AG_SENT_CLIP_INFORMATION },
1221 { "+CME ERROR:", HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR },
1222 { "+CNUM:", HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION},
1223 { "+COPS:", HFP_CMD_QUERY_OPERATOR_SELECTION_NAME },
1224 { "+VGM:", HFP_CMD_SET_MICROPHONE_GAIN },
1225 { "+VGM=", HFP_CMD_SET_MICROPHONE_GAIN },
1226 { "+VGS:", HFP_CMD_SET_SPEAKER_GAIN},
1227 { "+VGS=", HFP_CMD_SET_SPEAKER_GAIN},
1228 { "+XAPL=", HFP_CMD_APPLE_DEVICE_INFORMATION },
1229 { "ERROR", HFP_CMD_ERROR},
1230 { "NOP", HFP_CMD_NONE}, // dummy command used by unit tests
1231 { "OK", HFP_CMD_OK },
1232 { "RING", HFP_CMD_RING },
1233 };
1234
1235 static const hfp_custom_at_command_t *
hfp_custom_command_lookup(bool isHandsFree,const char * text)1236 hfp_custom_command_lookup(bool isHandsFree, const char *text) {
1237 btstack_linked_list_t * custom_commands = isHandsFree ? &hfp_custom_commands_hf : &hfp_custom_commands_ag;
1238 btstack_linked_list_iterator_t it;
1239 btstack_linked_list_iterator_init(&it, custom_commands);
1240 while (btstack_linked_list_iterator_has_next(&it)) {
1241 hfp_custom_at_command_t *at_command = (hfp_custom_at_command_t *) btstack_linked_list_iterator_next(&it);
1242 int match = strcmp(text, at_command->command);
1243 if (match == 0) {
1244 return at_command;
1245 }
1246 }
1247 return NULL;
1248 }
1249
parse_command(const char * line_buffer,int isHandsFree)1250 static hfp_command_t parse_command(const char * line_buffer, int isHandsFree){
1251
1252 // check for custom commands, AG only
1253 const hfp_custom_at_command_t * custom_at_command = hfp_custom_command_lookup(isHandsFree, line_buffer);
1254 if (custom_at_command != NULL){
1255 return HFP_CMD_CUSTOM_MESSAGE;
1256 }
1257
1258 // table lookup based on role
1259 uint16_t num_entries;
1260 hfp_command_entry_t * table;
1261 if (isHandsFree == 0){
1262 table = hfp_ag_command_table;
1263 num_entries = sizeof(hfp_ag_command_table) / sizeof(hfp_command_entry_t);
1264 } else {
1265 table = hfp_hf_command_table;
1266 num_entries = sizeof(hfp_hf_command_table) / sizeof(hfp_command_entry_t);
1267 }
1268 // binary search
1269 uint16_t left = 0;
1270 uint16_t right = num_entries - 1;
1271 while (left <= right){
1272 uint16_t middle = left + (right - left) / 2;
1273 hfp_command_entry_t *entry = &table[middle];
1274 int match = strcmp(line_buffer, entry->command);
1275 if (match < 0){
1276 // search term is lower than middle element
1277 if (middle == 0) break;
1278 right = middle - 1;
1279 } else if (match == 0){
1280 return entry->command_id;
1281 } else {
1282 // search term is higher than middle element
1283 left = middle + 1;
1284 }
1285 }
1286
1287 // note: if parser in CMD_HEADER state would treats digits and maybe '+' as separator, match on "ATD" would work.
1288 // note: phone number is currently expected in line_buffer[3..]
1289 // prefix match on 'ATD', AG only
1290 if ((isHandsFree == 0) && (strncmp(line_buffer, HFP_CALL_PHONE_NUMBER, strlen(HFP_CALL_PHONE_NUMBER)) == 0)){
1291 return HFP_CMD_CALL_PHONE_NUMBER;
1292 }
1293
1294 // Valid looking, but unknown commands/responses
1295 if ((isHandsFree == 0) && (strncmp(line_buffer, "AT+", 3) == 0)){
1296 return HFP_CMD_UNKNOWN;
1297 }
1298
1299 if ((isHandsFree != 0) && (strncmp(line_buffer, "+", 1) == 0)){
1300 return HFP_CMD_UNKNOWN;
1301 }
1302
1303 return HFP_CMD_NONE;
1304 }
1305
hfp_parser_store_byte(hfp_connection_t * hfp_connection,uint8_t byte)1306 static void hfp_parser_store_byte(hfp_connection_t * hfp_connection, uint8_t byte){
1307 if ((hfp_connection->line_size + 1) >= HFP_MAX_VR_TEXT_SIZE) return;
1308 hfp_connection->line_buffer[hfp_connection->line_size++] = byte;
1309 hfp_connection->line_buffer[hfp_connection->line_size] = 0;
1310 }
hfp_parser_is_buffer_empty(hfp_connection_t * hfp_connection)1311 static int hfp_parser_is_buffer_empty(hfp_connection_t * hfp_connection){
1312 return hfp_connection->line_size == 0;
1313 }
1314
hfp_parser_is_end_of_line(uint8_t byte)1315 static int hfp_parser_is_end_of_line(uint8_t byte){
1316 return (byte == '\n') || (byte == '\r');
1317 }
1318
hfp_parser_reset_line_buffer(hfp_connection_t * hfp_connection)1319 void hfp_parser_reset_line_buffer(hfp_connection_t *hfp_connection) {
1320 hfp_connection->line_size = 0;
1321 // we don't set the first byte to '\0' to allow access to last argument e.g. in hfp_hf_handle_rfcommand
1322 }
1323
hfp_parser_store_if_token(hfp_connection_t * hfp_connection,uint8_t byte)1324 static void hfp_parser_store_if_token(hfp_connection_t * hfp_connection, uint8_t byte){
1325 switch (byte){
1326 case ',':
1327 case '-':
1328 case ';':
1329 case '(':
1330 case ')':
1331 case '\n':
1332 case '\r':
1333 break;
1334 default:
1335 hfp_parser_store_byte(hfp_connection, byte);
1336 break;
1337 }
1338 }
1339
hfp_parser_is_separator(uint8_t byte)1340 static bool hfp_parser_is_separator( uint8_t byte){
1341 switch (byte){
1342 case ',':
1343 case '-':
1344 case ';':
1345 case '\n':
1346 case '\r':
1347 return true;
1348 default:
1349 return false;
1350 }
1351 }
1352
1353 // returns true if received bytes was processed. Otherwise, functions will be called with same byte again
1354 // this is used to for a one byte lookahead, where an unexpected byte is pushed back by returning false
hfp_parse_byte(hfp_connection_t * hfp_connection,uint8_t byte,int isHandsFree)1355 static bool hfp_parse_byte(hfp_connection_t * hfp_connection, uint8_t byte, int isHandsFree){
1356
1357 #ifdef HFP_DEBUG
1358 if (byte >= ' '){
1359 printf("Parse '%c' - state %u, buffer %s\n", byte, hfp_connection->parser_state, hfp_connection->line_buffer);
1360 } else {
1361 printf("Parse 0x%02x - state %u, buffer %s\n", byte, hfp_connection->parser_state, hfp_connection->line_buffer);
1362 }
1363 #endif
1364
1365 // handle doubles quotes
1366 if (byte == '"'){
1367 hfp_connection->parser_quoted = !hfp_connection->parser_quoted;
1368 return true;
1369 }
1370 if (hfp_connection->parser_quoted) {
1371 hfp_parser_store_byte(hfp_connection, byte);
1372 return true;
1373 }
1374
1375 // ignore spaces outside command or double quotes (required e.g. for '+CME ERROR:..") command
1376 if ((byte == ' ') && (hfp_connection->parser_state != HFP_PARSER_CMD_HEADER)) return true;
1377
1378 bool processed = true;
1379
1380 switch (hfp_connection->parser_state) {
1381 case HFP_PARSER_CMD_HEADER:
1382 switch (byte) {
1383 case '\n':
1384 case '\r':
1385 case ';':
1386 // ignore separator
1387 break;
1388 case ':':
1389 case '?':
1390 // store separator
1391 hfp_parser_store_byte(hfp_connection, byte);
1392 break;
1393 case '=':
1394 // equal sign: remember and wait for next char to decided between '=?' and '=\?'
1395 hfp_connection->found_equal_sign = true;
1396 hfp_parser_store_byte(hfp_connection, byte);
1397 return true;
1398 default:
1399 // store if not lookahead
1400 if (!hfp_connection->found_equal_sign) {
1401 hfp_parser_store_byte(hfp_connection, byte);
1402 return true;
1403 }
1404 // mark as lookahead
1405 processed = false;
1406 break;
1407 }
1408
1409 // ignore empty tokens
1410 if (hfp_parser_is_buffer_empty(hfp_connection)) return true;
1411
1412 // parse
1413 hfp_connection->command = parse_command((char *)hfp_connection->line_buffer, isHandsFree);
1414
1415 // pick +CIND version based on connection state: descriptions during SLC vs. states later
1416 if (hfp_connection->command == HFP_CMD_RETRIEVE_AG_INDICATORS_GENERIC){
1417 switch(hfp_connection->state){
1418 case HFP_W4_RETRIEVE_INDICATORS_STATUS:
1419 hfp_connection->command = HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS;
1420 break;
1421 case HFP_W4_RETRIEVE_INDICATORS:
1422 hfp_connection->command = HFP_CMD_RETRIEVE_AG_INDICATORS;
1423 break;
1424 default:
1425 hfp_connection->command = HFP_CMD_UNKNOWN;
1426 break;
1427 }
1428 }
1429
1430 log_info("command string '%s', handsfree %u -> cmd id %u", (char *)hfp_connection->line_buffer, isHandsFree, hfp_connection->command);
1431
1432 // store command id for custom command and just store rest of line
1433 if (hfp_connection->command == HFP_CMD_CUSTOM_MESSAGE){
1434 const hfp_custom_at_command_t * at_command = hfp_custom_command_lookup(isHandsFree, (const char *) hfp_connection->line_buffer);
1435 hfp_connection->custom_at_command_id = at_command->command_id;
1436 hfp_connection->parser_state = HFP_PARSER_CUSTOM_COMMAND;
1437 return processed;
1438 }
1439
1440 // next state
1441 hfp_parser_reset_line_buffer(hfp_connection);
1442 hfp_connection->parser_state = HFP_PARSER_CMD_SEQUENCE;
1443
1444 return processed;
1445
1446 case HFP_PARSER_CMD_SEQUENCE:
1447 // handle empty fields
1448 if ((byte == ',' ) && (hfp_connection->line_size == 0)){
1449 hfp_connection->line_buffer[0] = 0;
1450 hfp_connection->ignore_value = 1;
1451 parse_sequence(hfp_connection);
1452 return true;
1453 }
1454
1455 hfp_parser_store_if_token(hfp_connection, byte);
1456 if (!hfp_parser_is_separator(byte)) return true;
1457
1458 // ignore empty tokens
1459 switch (hfp_connection->command){
1460 case HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION:
1461 // don't ignore empty string
1462 break;
1463 default:
1464 if (hfp_parser_is_buffer_empty(hfp_connection) && (hfp_connection->ignore_value == 0)) {
1465 return true;
1466 }
1467 break;
1468 }
1469
1470 parse_sequence(hfp_connection);
1471
1472 hfp_parser_reset_line_buffer(hfp_connection);
1473
1474 switch (hfp_connection->command){
1475 case HFP_CMD_AG_SENT_PHONE_NUMBER:
1476 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
1477 case HFP_CMD_AG_SENT_CLIP_INFORMATION:
1478 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
1479 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
1480 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT:
1481 case HFP_CMD_RETRIEVE_AG_INDICATORS:
1482 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE:
1483 case HFP_CMD_HF_INDICATOR_STATUS:
1484 hfp_connection->parser_state = HFP_PARSER_SECOND_ITEM;
1485 break;
1486 default:
1487 break;
1488 }
1489 return true;
1490
1491 case HFP_PARSER_SECOND_ITEM:
1492
1493 hfp_parser_store_if_token(hfp_connection, byte);
1494 if (!hfp_parser_is_separator(byte)) return true;
1495
1496 switch (hfp_connection->command){
1497 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
1498 log_info("format %s, ", hfp_connection->line_buffer);
1499 hfp_connection->network_operator.format = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1500 break;
1501 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT:
1502 log_info("format %s \n", hfp_connection->line_buffer);
1503 hfp_connection->network_operator.format = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1504 break;
1505 case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS:
1506 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS:
1507 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE:
1508 hfp_connection->generic_status_indicators[hfp_connection->parser_item_index].state = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1509 break;
1510 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
1511 hfp_connection->ag_indicators[hfp_connection->parser_item_index].status = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1512 log_info("%d \n", hfp_connection->ag_indicators[hfp_connection->parser_item_index].status);
1513 hfp_connection->ag_indicators[hfp_connection->parser_item_index].status_changed = 1;
1514 break;
1515 case HFP_CMD_RETRIEVE_AG_INDICATORS:
1516 hfp_connection->ag_indicators[hfp_connection->parser_item_index].min_range = btstack_atoi((char *)hfp_connection->line_buffer);
1517 log_info("%s, ", hfp_connection->line_buffer);
1518 break;
1519 case HFP_CMD_AG_SENT_PHONE_NUMBER:
1520 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
1521 case HFP_CMD_AG_SENT_CLIP_INFORMATION:
1522 hfp_connection->bnip_type = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1523 break;
1524 case HFP_CMD_HF_INDICATOR_STATUS:
1525 hfp_connection->parser_indicator_value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1526 break;
1527 default:
1528 break;
1529 }
1530
1531 hfp_parser_reset_line_buffer(hfp_connection);
1532
1533 hfp_connection->parser_state = HFP_PARSER_THIRD_ITEM;
1534
1535 return true;
1536
1537 case HFP_PARSER_THIRD_ITEM:
1538
1539 hfp_parser_store_if_token(hfp_connection, byte);
1540 if (!hfp_parser_is_separator(byte)) return true;
1541
1542 switch (hfp_connection->command){
1543 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
1544 btstack_strcpy(hfp_connection->network_operator.name, HFP_MAX_NETWORK_OPERATOR_NAME_SIZE, (char *)hfp_connection->line_buffer);
1545 break;
1546 case HFP_CMD_RETRIEVE_AG_INDICATORS:
1547 hfp_connection->ag_indicators[hfp_connection->parser_item_index].max_range = btstack_atoi((char *)hfp_connection->line_buffer);
1548 hfp_next_indicators_index(hfp_connection);
1549 hfp_connection->ag_indicators_nr = hfp_connection->parser_item_index;
1550 break;
1551 case HFP_CMD_AG_SENT_CLIP_INFORMATION:
1552 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
1553 // track if last argument exists
1554 hfp_connection->clip_have_alpha = hfp_connection->line_size != 0;
1555 break;
1556 default:
1557 break;
1558 }
1559
1560 hfp_parser_reset_line_buffer(hfp_connection);
1561
1562 if (hfp_connection->command == HFP_CMD_RETRIEVE_AG_INDICATORS){
1563 hfp_connection->parser_state = HFP_PARSER_CMD_SEQUENCE;
1564 }
1565 return true;
1566
1567 case HFP_PARSER_CUSTOM_COMMAND:
1568 if (hfp_parser_is_end_of_line(byte) == false){
1569 hfp_parser_store_byte(hfp_connection, byte);
1570 }
1571 return true;
1572
1573 default:
1574 btstack_assert(false);
1575 return true;
1576 }
1577 }
1578
hfp_parse(hfp_connection_t * hfp_connection,uint8_t byte,int isHandsFree)1579 void hfp_parse(hfp_connection_t * hfp_connection, uint8_t byte, int isHandsFree){
1580 bool processed = false;
1581 while (!processed){
1582 processed = hfp_parse_byte(hfp_connection, byte, isHandsFree);
1583 }
1584 // reset parser state on end-of-line
1585 if (hfp_parser_is_end_of_line(byte)){
1586 hfp_connection->found_equal_sign = false;
1587 hfp_connection->parser_item_index = 0;
1588 hfp_connection->parser_state = HFP_PARSER_CMD_HEADER;
1589 }
1590 }
1591
parse_sequence(hfp_connection_t * hfp_connection)1592 static void parse_sequence(hfp_connection_t * hfp_connection){
1593 int value;
1594 switch (hfp_connection->command){
1595 case HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS:
1596 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1597 int i;
1598 switch (hfp_connection->parser_item_index){
1599 case 0:
1600 for (i=0;i<hfp_connection->generic_status_indicators_nr;i++){
1601 if (hfp_connection->generic_status_indicators[i].uuid == value){
1602 hfp_connection->parser_indicator_index = i;
1603 break;
1604 }
1605 }
1606 break;
1607 case 1:
1608 if (hfp_connection->parser_indicator_index <0) break;
1609 hfp_connection->generic_status_indicators[hfp_connection->parser_indicator_index].state = value;
1610 log_info("HFP_CMD_SET_GENERIC_STATUS_INDICATOR_STATUS set indicator at index %u, to %u\n",
1611 hfp_connection->parser_item_index, value);
1612 break;
1613 default:
1614 break;
1615 }
1616 hfp_next_indicators_index(hfp_connection);
1617 break;
1618
1619 case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION:
1620 switch(hfp_connection->parser_item_index){
1621 case 0:
1622 // <alpha>: This optional field is not supported, and shall be left blank.
1623 break;
1624 case 1:
1625 // <number>: Quoted string containing the phone number in the format specified by <type>.
1626 btstack_strcpy(hfp_connection->bnip_number, sizeof(hfp_connection->bnip_number), (char *)hfp_connection->line_buffer);
1627 break;
1628 case 2:
1629 /*
1630 <type> field specifies the format of the phone number provided, and can be one of the following values:
1631 - values 128-143: The phone number format may be a national or international format, and may contain prefix and/or escape digits. No changes on the number presentation are required.
1632 - values 144-159: The phone number format is an international number, including the country code prefix. If the plus sign ("+") is not included as part of the number and shall be added by the AG as needed.
1633 - values 160-175: National number. No prefix nor escape digits included.
1634 */
1635 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1636 hfp_connection->bnip_type = value;
1637 break;
1638 case 3:
1639 // <speed>: This optional field is not supported, and shall be left blank.
1640 break;
1641 case 4:
1642 // <service>: Indicates which service this phone number relates to. Shall be either 4 (voice) or 5 (fax).
1643 default:
1644 break;
1645 }
1646 // index > 2 are ignored in switch above
1647 hfp_connection->parser_item_index++;
1648 break;
1649 case HFP_CMD_LIST_CURRENT_CALLS:
1650 switch(hfp_connection->parser_item_index){
1651 case 0:
1652 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1653 hfp_connection->clcc_idx = value;
1654 break;
1655 case 1:
1656 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1657 hfp_connection->clcc_dir = value;
1658 break;
1659 case 2:
1660 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1661 hfp_connection->clcc_status = value;
1662 break;
1663 case 3:
1664 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1665 hfp_connection->clcc_mode = value;
1666 break;
1667 case 4:
1668 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1669 hfp_connection->clcc_mpty = value;
1670 break;
1671 case 5:
1672 btstack_strcpy(hfp_connection->bnip_number, sizeof(hfp_connection->bnip_number), (char *)hfp_connection->line_buffer);
1673 break;
1674 case 6:
1675 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1676 hfp_connection->bnip_type = value;
1677 break;
1678 default:
1679 break;
1680 }
1681 // index > 6 are ignored in switch above
1682 hfp_connection->parser_item_index++;
1683 break;
1684 case HFP_CMD_SET_MICROPHONE_GAIN:
1685 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1686 hfp_connection->microphone_gain = value;
1687 log_info("hfp parse HFP_CMD_SET_MICROPHONE_GAIN %d\n", value);
1688 break;
1689 case HFP_CMD_SET_SPEAKER_GAIN:
1690 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1691 hfp_connection->speaker_gain = value;
1692 log_info("hfp parse HFP_CMD_SET_SPEAKER_GAIN %d\n", value);
1693 break;
1694 case HFP_CMD_TURN_OFF_EC_AND_NR:
1695 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1696 hfp_connection->ag_echo_and_noise_reduction = value;
1697 log_info("hfp parse HFP_CMD_TURN_OFF_EC_AND_NR %d\n", value);
1698 break;
1699 case HFP_CMD_CHANGE_IN_BAND_RING_TONE_SETTING:
1700 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1701 hfp_connection->remote_supported_features = store_bit(hfp_connection->remote_supported_features, HFP_AGSF_IN_BAND_RING_TONE, value);
1702 log_info("hfp parse HFP_CHANGE_IN_BAND_RING_TONE_SETTING %d\n", value);
1703 break;
1704 case HFP_CMD_HF_CONFIRMED_CODEC:
1705 hfp_connection->codec_confirmed = btstack_atoi((char*)hfp_connection->line_buffer);
1706 log_info("hfp parse HFP_CMD_HF_CONFIRMED_CODEC %d\n", hfp_connection->codec_confirmed);
1707 break;
1708 case HFP_CMD_AG_SUGGESTED_CODEC:
1709 hfp_connection->suggested_codec = btstack_atoi((char*)hfp_connection->line_buffer);
1710 log_info("hfp parse HFP_CMD_AG_SUGGESTED_CODEC %d\n", hfp_connection->suggested_codec);
1711 break;
1712 case HFP_CMD_SUPPORTED_FEATURES:
1713 hfp_connection->remote_supported_features = btstack_atoi((char*)hfp_connection->line_buffer);
1714 log_info("Parsed supported feature %d\n", (int) hfp_connection->remote_supported_features);
1715 break;
1716 case HFP_CMD_AVAILABLE_CODECS:
1717 log_info("Parsed codec %s\n", hfp_connection->line_buffer);
1718 hfp_connection->remote_codecs[hfp_connection->parser_item_index] = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1719 hfp_next_codec_index(hfp_connection);
1720 hfp_connection->remote_codecs_nr = hfp_connection->parser_item_index;
1721 break;
1722 case HFP_CMD_RETRIEVE_AG_INDICATORS:
1723 btstack_strcpy((char *)hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, HFP_MAX_INDICATOR_DESC_SIZE, (char *)hfp_connection->line_buffer);
1724 hfp_connection->ag_indicators[hfp_connection->parser_item_index].index = hfp_connection->parser_item_index+1;
1725 log_info("Indicator %d: %s (", hfp_connection->ag_indicators_nr+1, hfp_connection->line_buffer);
1726 break;
1727 case HFP_CMD_RETRIEVE_AG_INDICATORS_STATUS:
1728 log_info("Parsed Indicator %d with status: %s\n", hfp_connection->parser_item_index+1, hfp_connection->line_buffer);
1729 hfp_connection->ag_indicators[hfp_connection->parser_item_index].status = btstack_atoi((char *) hfp_connection->line_buffer);
1730 hfp_next_indicators_index(hfp_connection);
1731 break;
1732 case HFP_CMD_ENABLE_INDICATOR_STATUS_UPDATE:
1733 hfp_next_indicators_index(hfp_connection);
1734 if (hfp_connection->parser_item_index != 4) break;
1735 log_info("Parsed Enable indicators: %s\n", hfp_connection->line_buffer);
1736 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1737 hfp_connection->enable_status_update_for_ag_indicators = (uint8_t) value;
1738 break;
1739 case HFP_CMD_SUPPORT_CALL_HOLD_AND_MULTIPARTY_SERVICES:
1740 log_info("Parsed Support call hold: %s\n", hfp_connection->line_buffer);
1741 if (hfp_connection->line_size > 2 ) break;
1742 memcpy((char *)hfp_connection->remote_call_services[hfp_connection->remote_call_services_index].name, (char *)hfp_connection->line_buffer, HFP_CALL_SERVICE_SIZE-1);
1743 hfp_connection->remote_call_services[hfp_connection->remote_call_services_index].name[HFP_CALL_SERVICE_SIZE - 1] = 0;
1744 hfp_next_remote_call_services_index(hfp_connection);
1745 break;
1746 case HFP_CMD_LIST_GENERIC_STATUS_INDICATORS:
1747 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS:
1748 log_info("Parsed Generic status indicator: %s\n", hfp_connection->line_buffer);
1749 hfp_connection->generic_status_indicators[hfp_connection->parser_item_index].uuid = (uint16_t)btstack_atoi((char*)hfp_connection->line_buffer);
1750 hfp_next_indicators_index(hfp_connection);
1751 hfp_connection->generic_status_indicators_nr = hfp_connection->parser_item_index;
1752 break;
1753 case HFP_CMD_RETRIEVE_GENERIC_STATUS_INDICATORS_STATE:
1754 // HF parses inital AG gen. ind. state
1755 log_info("Parsed List generic status indicator %s state: ", hfp_connection->line_buffer);
1756 hfp_connection->parser_item_index = hfp_parse_indicator_index(hfp_connection);
1757 break;
1758 case HFP_CMD_HF_INDICATOR_STATUS:
1759 hfp_connection->parser_indicator_index = hfp_parse_indicator_index(hfp_connection);
1760 log_info("Parsed HF indicator index %u", hfp_connection->parser_indicator_index);
1761 break;
1762 case HFP_CMD_ENABLE_INDIVIDUAL_AG_INDICATOR_STATUS_UPDATE:
1763 // AG parses new gen. ind. state
1764 if (hfp_connection->ignore_value){
1765 hfp_connection->ignore_value = 0;
1766 log_info("Parsed Enable AG indicator pos %u('%s') - unchanged (stays %u)\n", hfp_connection->parser_item_index,
1767 hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, hfp_connection->ag_indicators[hfp_connection->parser_item_index].enabled);
1768 }
1769 else if (hfp_connection->ag_indicators[hfp_connection->parser_item_index].mandatory){
1770 log_info("Parsed Enable AG indicator pos %u('%s') - ignore (mandatory)\n",
1771 hfp_connection->parser_item_index, hfp_connection->ag_indicators[hfp_connection->parser_item_index].name);
1772 } else {
1773 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1774 hfp_connection->ag_indicators[hfp_connection->parser_item_index].enabled = value;
1775 log_info("Parsed Enable AG indicator pos %u('%s'): %u\n", hfp_connection->parser_item_index,
1776 hfp_connection->ag_indicators[hfp_connection->parser_item_index].name, value);
1777 }
1778 hfp_next_indicators_index(hfp_connection);
1779 break;
1780 case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
1781 // indicators are indexed starting with 1
1782 hfp_connection->parser_item_index = hfp_parse_indicator_index(hfp_connection);
1783 log_info("Parsed status of the AG indicator %d, status ", hfp_connection->parser_item_index);
1784 break;
1785 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME:
1786 hfp_connection->network_operator.mode = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1787 log_info("Parsed network operator mode: %d, ", hfp_connection->network_operator.mode);
1788 break;
1789 case HFP_CMD_QUERY_OPERATOR_SELECTION_NAME_FORMAT:
1790 if (hfp_connection->line_buffer[0] == '3'){
1791 log_info("Parsed Set network operator format : %s, ", hfp_connection->line_buffer);
1792 break;
1793 }
1794 // TODO emit ERROR, wrong format
1795 log_info("ERROR Set network operator format: index %s not supported\n", hfp_connection->line_buffer);
1796 break;
1797 case HFP_CMD_ERROR:
1798 break;
1799 case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR:
1800 hfp_connection->extended_audio_gateway_error = 1;
1801 hfp_connection->extended_audio_gateway_error_value = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1802 break;
1803 case HFP_CMD_ENABLE_EXTENDED_AUDIO_GATEWAY_ERROR:
1804 hfp_connection->enable_extended_audio_gateway_error_report = (uint8_t)btstack_atoi((char*)hfp_connection->line_buffer);
1805 hfp_connection->extended_audio_gateway_error = 0;
1806 break;
1807 case HFP_CMD_AG_SENT_PHONE_NUMBER:
1808 case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
1809 case HFP_CMD_AG_SENT_CLIP_INFORMATION:
1810 btstack_strcpy((char *)hfp_connection->bnip_number, sizeof(hfp_connection->bnip_number), (char *)hfp_connection->line_buffer);
1811 break;
1812 case HFP_CMD_CALL_HOLD:
1813 hfp_connection->ag_call_hold_action = hfp_connection->line_buffer[0] - '0';
1814 if (hfp_connection->line_buffer[1] != '\0'){
1815 hfp_connection->call_index = btstack_atoi((char *)&hfp_connection->line_buffer[1]);
1816 }
1817 break;
1818 case HFP_CMD_RESPONSE_AND_HOLD_COMMAND:
1819 hfp_connection->ag_response_and_hold_action = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1820 break;
1821 case HFP_CMD_TRANSMIT_DTMF_CODES:
1822 hfp_connection->ag_dtmf_code = hfp_connection->line_buffer[0];
1823 break;
1824 case HFP_CMD_ENABLE_CLIP:
1825 hfp_connection->clip_enabled = hfp_connection->line_buffer[0] != '0';
1826 break;
1827 case HFP_CMD_ENABLE_CALL_WAITING_NOTIFICATION:
1828 hfp_connection->call_waiting_notification_enabled = hfp_connection->line_buffer[0] != '0';
1829 break;
1830 case HFP_CMD_HF_ACTIVATE_VOICE_RECOGNITION:
1831 value = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1832 hfp_connection->ag_activate_voice_recognition_value = value;
1833 break;
1834 case HFP_CMD_AG_ACTIVATE_VOICE_RECOGNITION:
1835 switch(hfp_connection->parser_item_index){
1836 case 0:
1837 hfp_connection->ag_vra_status = btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1838 break;
1839 case 1:
1840 hfp_connection->ag_vra_state = (hfp_voice_recognition_state_t) btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1841 break;
1842 case 2:
1843 hfp_connection->ag_msg.text_id = 0;
1844 for (i = 0 ; i < 4; i++){
1845 hfp_connection->ag_msg.text_id = (hfp_connection->ag_msg.text_id << 4) | nibble_for_char(hfp_connection->line_buffer[i]);
1846 }
1847 break;
1848 case 3:
1849 hfp_connection->ag_msg.text_type = (hfp_text_type_t) btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1850 break;
1851 case 4:
1852 hfp_connection->ag_msg.text_operation = (hfp_text_operation_t) btstack_atoi((char *)&hfp_connection->line_buffer[0]);
1853 break;
1854 case 5:
1855 hfp_connection->line_buffer[hfp_connection->line_size] = 0;
1856 hfp_connection->ag_vra_msg_length = hfp_connection->line_size + 1;
1857 break;
1858 default:
1859 break;
1860 }
1861 hfp_connection->parser_item_index++;
1862 break;
1863 case HFP_CMD_APPLE_ACCESSORY_INFORMATION:
1864 switch (hfp_connection->parser_item_index){
1865 case 0:
1866 hfp_connection->apple_accessory_vendor_id = 0;
1867 for (i = 0 ; i < 4; i++){
1868 hfp_connection->apple_accessory_vendor_id = (hfp_connection->apple_accessory_vendor_id << 4) | nibble_for_char(hfp_connection->line_buffer[i]);
1869 }
1870 break;
1871 case 1:
1872 hfp_connection->apple_accessory_product_id = 0;
1873 for (i = 0 ; i < 4; i++){
1874 hfp_connection->apple_accessory_product_id = (hfp_connection->apple_accessory_product_id << 4) | nibble_for_char(hfp_connection->line_buffer[i]);
1875 }
1876 break;
1877 case 2:
1878 btstack_strcpy(hfp_connection->apple_accessory_version, sizeof(hfp_connection->apple_accessory_version), (const char *) hfp_connection->line_buffer);
1879 break;
1880 case 3:
1881 hfp_connection->apple_accessory_features = btstack_atoi((char *)hfp_connection->line_buffer);
1882 break;
1883 default:
1884 break;
1885 }
1886 hfp_connection->parser_item_index++;
1887 break;
1888 case HFP_CMD_APPLE_ACCESSORY_STATE:
1889 // ignore K/V count
1890 if (hfp_connection->parser_item_index > 0){
1891 if ((hfp_connection->parser_item_index & 1) == 1){
1892 hfp_connection->apple_accessory_key = btstack_atoi((char *)hfp_connection->line_buffer);
1893 } else {
1894 switch (hfp_connection->apple_accessory_key){
1895 case 1:
1896 hfp_connection->apple_accessory_battery_level = btstack_atoi((char *)hfp_connection->line_buffer);
1897 break;
1898 case 2:
1899 hfp_connection->apple_accessory_docked = btstack_atoi((char *)hfp_connection->line_buffer);
1900 break;
1901 default:
1902 break;
1903 }
1904 }
1905 }
1906 hfp_connection->parser_item_index++;
1907 break;
1908
1909 default:
1910 break;
1911 }
1912 }
1913
hfp_handle_start_sdp_client_query(void * context)1914 static void hfp_handle_start_sdp_client_query(void * context){
1915 UNUSED(context);
1916
1917 btstack_linked_list_iterator_t it;
1918 btstack_linked_list_iterator_init(&it, &hfp_connections);
1919 while (btstack_linked_list_iterator_has_next(&it)){
1920 hfp_connection_t * connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
1921
1922 if (connection->state != HFP_W2_SEND_SDP_QUERY) continue;
1923
1924 connection->state = HFP_W4_SDP_QUERY_COMPLETE;
1925 hfp_sdp_query_context.local_role = connection->local_role;
1926 (void)memcpy(hfp_sdp_query_context.remote_address, connection->remote_addr, 6);
1927 sdp_client_query_rfcomm_channel_and_name_for_service_class_uuid(&handle_query_rfcomm_event, connection->remote_addr, connection->service_uuid);
1928 return;
1929 }
1930 }
1931
hfp_establish_service_level_connection(bd_addr_t bd_addr,uint16_t service_uuid,hfp_role_t local_role)1932 uint8_t hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_uuid, hfp_role_t local_role){
1933 hfp_connection_t * connection = get_hfp_connection_context_for_bd_addr(bd_addr, local_role);
1934 if (connection != NULL){
1935 // allow to call hfp_establish_service_level_connection after SLC was triggered remotely
1936 // @note this also allows to call hfp_establish_service_level_connection again before SLC is complete
1937 if (connection->state < HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED){
1938 return ERROR_CODE_SUCCESS;
1939 } else {
1940 return ERROR_CODE_COMMAND_DISALLOWED;
1941 }
1942 }
1943
1944 connection = hfp_create_connection(bd_addr, local_role);
1945 if (!connection){
1946 return BTSTACK_MEMORY_ALLOC_FAILED;
1947 }
1948
1949 connection->state = HFP_W2_SEND_SDP_QUERY;
1950
1951 bd_addr_copy(connection->remote_addr, bd_addr);
1952 connection->service_uuid = service_uuid;
1953
1954 hfp_sdp_query_request.callback = &hfp_handle_start_sdp_client_query;
1955 // ignore ERROR_CODE_COMMAND_DISALLOWED because in that case, we already have requested an SDP callback
1956 (void) sdp_client_register_query_callback(&hfp_sdp_query_request);
1957 return ERROR_CODE_SUCCESS;
1958 }
1959
hfp_trigger_release_service_level_connection(hfp_connection_t * hfp_connection)1960 void hfp_trigger_release_service_level_connection(hfp_connection_t * hfp_connection){
1961 // called internally, NULL check already performed
1962 btstack_assert(hfp_connection != NULL);
1963
1964 hfp_trigger_release_audio_connection(hfp_connection);
1965 if (hfp_connection->state < HFP_W4_RFCOMM_CONNECTED){
1966 hfp_connection->state = HFP_IDLE;
1967 return;
1968 }
1969
1970 if (hfp_connection->state == HFP_W4_RFCOMM_CONNECTED){
1971 hfp_connection->state = HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN;
1972 return;
1973 }
1974 hfp_connection->release_slc_connection = 1;
1975 if (hfp_connection->state < HFP_W4_SCO_CONNECTED){
1976 hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM;
1977 return;
1978 }
1979
1980 if (hfp_connection->state < HFP_W4_SCO_DISCONNECTED){
1981 hfp_connection->state = HFP_W2_DISCONNECT_SCO;
1982 hfp_connection->release_audio_connection = 1;
1983 return;
1984 }
1985 }
1986
hfp_trigger_release_audio_connection(hfp_connection_t * hfp_connection)1987 uint8_t hfp_trigger_release_audio_connection(hfp_connection_t * hfp_connection){
1988 // called internally, NULL check already performed
1989 btstack_assert(hfp_connection != NULL);
1990 if (hfp_connection->state <= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED){
1991 return ERROR_CODE_COMMAND_DISALLOWED;
1992 }
1993 switch (hfp_connection->state) {
1994 case HFP_W2_CONNECT_SCO:
1995 hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
1996 break;
1997 case HFP_W4_SCO_CONNECTED:
1998 case HFP_AUDIO_CONNECTION_ESTABLISHED:
1999 hfp_connection->release_audio_connection = 1;
2000 break;
2001 default:
2002 return ERROR_CODE_COMMAND_DISALLOWED;
2003 }
2004 return ERROR_CODE_SUCCESS;
2005 }
2006
hfp_sco_setup_active(void)2007 bool hfp_sco_setup_active(void){
2008 return hfp_sco_establishment_active != NULL;
2009 }
2010
hfp_setup_synchronous_connection(hfp_connection_t * hfp_connection)2011 void hfp_setup_synchronous_connection(hfp_connection_t * hfp_connection){
2012
2013 hfp_sco_establishment_active = hfp_connection;
2014
2015 // all packet types, fixed bandwidth
2016 int setting = hfp_connection->link_setting;
2017 log_info("hfp_setup_synchronous_connection using setting nr %u", setting);
2018 uint16_t sco_voice_setting = hci_get_sco_voice_setting();
2019 if (hfp_connection->negotiated_codec != HFP_CODEC_CVSD){
2020 #ifdef ENABLE_BCM_PCM_WBS
2021 sco_voice_setting = 0x0063; // Transparent data, 16-bit for BCM controllers
2022 #else
2023 sco_voice_setting = 0x0043; // Transparent data, 8-bit otherwise
2024 #endif
2025 }
2026 uint16_t packet_types = hfp_link_settings[setting].packet_types;
2027 hfp_connection->packet_types = packet_types;
2028
2029 // get packet types - bits 6-9 are 'don't allow'
2030 uint16_t packet_types_flipped = packet_types ^ 0x03c0;
2031 #if defined(ENABLE_SCO_OVER_PCM) && defined(ENABLE_NXP_PCM_WBS)
2032 uint8_t radio_coding_format = 3;
2033 uint32_t host_bandwidth = 0;
2034 uint8_t coded_data_size = 0;
2035 switch (hfp_connection->negotiated_codec){
2036 case HFP_CODEC_CVSD:
2037 radio_coding_format = 0x02;
2038 host_bandwidth = 16000;
2039 coded_data_size = 0x10;
2040 break;
2041 case HFP_CODEC_MSBC:
2042 radio_coding_format = 0x05;
2043 host_bandwidth = 32000;
2044 coded_data_size = 0x08;
2045 break;
2046 default:
2047 log_error("Coding format %u not supported by Controller", hfp_connection->negotiated_codec);
2048 btstack_assert(false);
2049 break;
2050 }
2051 hci_send_cmd(&hci_enhanced_setup_synchronous_connection,
2052 // ACL Handle
2053 hfp_connection->acl_handle,
2054 // Transmit_Bandwidth
2055 8000,
2056 // Receive_Bandwidth
2057 8000,
2058 // Transmit_Coding_Format: radio_config_format, company, codec
2059 radio_coding_format, 0x00, 0x00,
2060 // Receive_Coding_Format: radio_config_format, company, codec
2061 radio_coding_format, 0x00, 0x00,
2062 // Transmit_Codec_Frame_Size
2063 0x3c,
2064 // Receive_Codec_Frame_Size
2065 0x3c,
2066 // Input_Bandwidth
2067 host_bandwidth,
2068 // Output_Bandwidth
2069 host_bandwidth,
2070 // Input_Coding_Format, 0x04 = Linear PCM, company, codec
2071 0x04, 0x00, 0x00,
2072 // Output_Coding_Format, 0x04 = Linear PCM, company, codec
2073 0x04, 0x00, 0x00,
2074 // Input_Coded_Data_Size
2075 coded_data_size,
2076 // Output_Coded_Data_Size
2077 coded_data_size,
2078 // Input_PCM_Data_Format, 0x02 = 2’s complement
2079 0x02,
2080 // Output_PCM_Data_Format, 0x02 = 2’s complement
2081 0x02,
2082 // Input_PCM_Sample_Payload_MSB_Position
2083 0x00,
2084 // Output_PCM_Sample_Payload_MSB_Position
2085 0x00,
2086 // Input_Data_Path - vendor specific: NXP - I2S/PCM
2087 0x01,
2088 // Output_Data_Path - vendor specific: NXP - I2S/PCM
2089 0x01,
2090 // Input_Transport_Unit_Size
2091 0x10,
2092 // Output_Transport_Unit_Size
2093 0x10,
2094 //
2095 hfp_link_settings[setting].max_latency,
2096 packet_types_flipped,
2097 hfp_link_settings[setting].retransmission_effort);
2098 #else
2099 hci_send_cmd(&hci_setup_synchronous_connection, hfp_connection->acl_handle, 8000, 8000, hfp_link_settings[setting].max_latency,
2100 sco_voice_setting, hfp_link_settings[setting].retransmission_effort, packet_types_flipped);
2101 #endif
2102 }
2103
2104 #ifdef ENABLE_HFP_HF_SAFE_SETTINGS
hfp_safe_settings_for_context(bool use_eSCO,uint8_t negotiated_codec,bool secure_connection_in_use)2105 hfp_link_settings_t hfp_safe_settings_for_context(bool use_eSCO, uint8_t negotiated_codec, bool secure_connection_in_use){
2106 uint8_t i;
2107 hfp_link_settings_t link_setting = HFP_LINK_SETTINGS_NONE;
2108 for (i=0 ; i < (sizeof(hfp_mandatory_safe_settings) / sizeof(struct hfp_mandatory_safe_setting)) ; i++){
2109 uint16_t packet_types = hfp_link_settings[(uint8_t)(hfp_mandatory_safe_settings[i].link_setting)].packet_types;
2110 bool is_eSCO_setting = (packet_types & SCO_PACKET_TYPES_ESCO) != 0;
2111 if (is_eSCO_setting != use_eSCO) continue;
2112 if ((hfp_mandatory_safe_settings[i].codec_mask & (1 << negotiated_codec)) == 0) continue;
2113 if (hfp_mandatory_safe_settings[i].secure_connection_in_use != secure_connection_in_use) continue;
2114 link_setting = hfp_mandatory_safe_settings[i].link_setting;
2115 break;
2116 }
2117 return link_setting;
2118 }
2119 #endif
2120
hfp_accept_synchronous_connection(hfp_connection_t * hfp_connection,bool use_eSCO)2121 void hfp_accept_synchronous_connection(hfp_connection_t * hfp_connection, bool use_eSCO){
2122
2123 hfp_sco_establishment_active = hfp_connection;
2124
2125 // lookup safe settings based on SCO type, SC use and Codec type
2126 uint16_t max_latency;
2127 uint16_t packet_types;
2128 uint16_t retransmission_effort;
2129
2130 #ifdef ENABLE_HFP_HF_SAFE_SETTINGS
2131 hfp_link_settings_t link_setting = HFP_LINK_SETTINGS_NONE;
2132 // fallback for non-CVSD codec and SCO connection
2133 if ((hfp_connection->negotiated_codec != HFP_CODEC_CVSD) && (use_eSCO == false)){
2134 max_latency = 0xffff;
2135 retransmission_effort = 0xff;
2136 packet_types = SCO_PACKET_TYPES_HV3 | SCO_PACKET_TYPES_HV1;
2137 } else {
2138 // use safe settings from HFP v1.9, table 6.10
2139 bool secure_connection_in_use = gap_secure_connection(hfp_connection->acl_handle);
2140 link_setting = hfp_safe_settings_for_context(use_eSCO, hfp_connection->negotiated_codec, secure_connection_in_use);
2141 max_latency = hfp_link_settings[(uint8_t) link_setting].max_latency;
2142 retransmission_effort = hfp_link_settings[(uint8_t) link_setting].retransmission_effort;
2143 packet_types = hfp_link_settings[(uint8_t) link_setting].packet_types;
2144 }
2145 #else
2146 max_latency = 0xffff;
2147 retransmission_effort = 0xff;
2148 if (use_eSCO) {
2149 packet_types = SCO_PACKET_TYPES_EV3 | SCO_PACKET_TYPES_2EV3;
2150 } else {
2151 packet_types = SCO_PACKET_TYPES_HV3 | SCO_PACKET_TYPES_HV1;
2152 }
2153 #endif
2154
2155 // transparent data for non-CVSD connections or if codec provided by Controller
2156 uint16_t sco_voice_setting = hci_get_sco_voice_setting();
2157 if (hfp_connection->negotiated_codec != HFP_CODEC_CVSD){
2158 #ifdef ENABLE_BCM_PCM_WBS
2159 sco_voice_setting = 0x0063; // Transparent data, 16-bit for BCM controllers
2160 #else
2161 sco_voice_setting = 0x0043; // Transparent data, 8-bit otherwise
2162 #endif
2163 }
2164
2165 // filter packet types
2166 packet_types &= hfp_get_sco_packet_types();
2167
2168 hfp_connection->packet_types = packet_types;
2169
2170 // bits 6-9 are 'don't allow'
2171 uint16_t packet_types_flipped = packet_types ^ 0x3c0;
2172
2173 log_info("Sending hci_accept_connection_request: packet types 0x%04x, sco_voice_setting 0x%02x",
2174 packet_types, sco_voice_setting);
2175
2176 #if defined(ENABLE_SCO_OVER_PCM) && defined(ENABLE_NXP_PCM_WBS)
2177 uint8_t radio_coding_format = 3;
2178 uint32_t host_bandwidth = 0;
2179 uint8_t coded_data_size = 0;
2180 switch (hfp_connection->negotiated_codec){
2181 case HFP_CODEC_CVSD:
2182 radio_coding_format = 0x02;
2183 host_bandwidth = 16000;
2184 coded_data_size = 0x10;
2185 break;
2186 case HFP_CODEC_MSBC:
2187 radio_coding_format = 0x05;
2188 host_bandwidth = 32000;
2189 coded_data_size = 0x08;
2190 break;
2191 default:
2192 log_error("Coding format %u not supported by Controller", hfp_connection->negotiated_codec);
2193 btstack_assert(false);
2194 break;
2195 }
2196 hci_send_cmd(&hci_enhanced_accept_synchronous_connection,
2197 // BD_ADDR
2198 hfp_connection->remote_addr,
2199 // Transmit_Bandwidth
2200 8000,
2201 // Receive_Bandwidth
2202 8000,
2203 // Transmit_Coding_Format: radio_config_format, company, codec
2204 radio_coding_format, 0x00, 0x00,
2205 // Receive_Coding_Format: radio_config_format, company, codec
2206 radio_coding_format, 0x00, 0x00,
2207 // Transmit_Codec_Frame_Size
2208 0x3c,
2209 // Receive_Codec_Frame_Size
2210 0x3c,
2211 // Input_Bandwidth
2212 host_bandwidth,
2213 // Output_Bandwidth
2214 host_bandwidth,
2215 // Input_Coding_Format, 0x04 = Linear PCM, company, codec
2216 0x04, 0x00, 0x00,
2217 // Output_Coding_Format, 0x04 = Linear PCM, company, codec
2218 0x04, 0x00, 0x00,
2219 // Input_Coded_Data_Size
2220 coded_data_size,
2221 // Output_Coded_Data_Size
2222 coded_data_size,
2223 // Input_PCM_Data_Format, 0x02 = 2’s complement
2224 0x02,
2225 // Output_PCM_Data_Format, 0x02 = 2’s complement
2226 0x02,
2227 // Input_PCM_Sample_Payload_MSB_Position
2228 0x00,
2229 // Output_PCM_Sample_Payload_MSB_Position
2230 0x00,
2231 // Input_Data_Path - vendor specific: NXP - I2S/PCM
2232 0x01,
2233 // Output_Data_Path - vendor specific: NXP - I2S/PCM
2234 0x01,
2235 // Input_Transport_Unit_Size
2236 0x10,
2237 // Output_Transport_Unit_Size
2238 0x10,
2239 //
2240 max_latency,
2241 packet_types_flipped,
2242 retransmission_effort);
2243 #else
2244 hci_send_cmd(&hci_accept_synchronous_connection, hfp_connection->remote_addr, 8000, 8000, max_latency,
2245 sco_voice_setting, retransmission_effort, packet_types_flipped);
2246 #endif
2247 }
2248
2249 #ifdef ENABLE_CC256X_ASSISTED_HFP
hfp_cc256x_write_codec_config(hfp_connection_t * hfp_connection)2250 void hfp_cc256x_write_codec_config(hfp_connection_t * hfp_connection){
2251 uint32_t sample_rate_hz;
2252 uint16_t clock_rate_khz;
2253 if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
2254 clock_rate_khz = 512;
2255 sample_rate_hz = 16000;
2256 } else {
2257 clock_rate_khz = 256;
2258 sample_rate_hz = 8000;
2259 }
2260 uint8_t clock_direction = 0; // master
2261 uint16_t frame_sync_duty_cycle = 0; // i2s with 50%
2262 uint8_t frame_sync_edge = 1; // rising edge
2263 uint8_t frame_sync_polarity = 0; // active high
2264 uint8_t reserved = 0;
2265 uint16_t size = 16;
2266 uint16_t chan_1_offset = 1;
2267 uint16_t chan_2_offset = chan_1_offset + size;
2268 uint8_t out_edge = 1; // rising
2269 uint8_t in_edge = 0; // falling
2270 hci_send_cmd(&hci_ti_write_codec_config, clock_rate_khz, clock_direction, sample_rate_hz, frame_sync_duty_cycle,
2271 frame_sync_edge, frame_sync_polarity, reserved,
2272 size, chan_1_offset, out_edge, size, chan_1_offset, in_edge, reserved,
2273 size, chan_2_offset, out_edge, size, chan_2_offset, in_edge, reserved);
2274 }
2275 #endif
2276
2277 #ifdef ENABLE_BCM_PCM_WBS
hfp_bcm_write_i2spcm_interface_param(hfp_connection_t * hfp_connection)2278 void hfp_bcm_write_i2spcm_interface_param(hfp_connection_t * hfp_connection){
2279 uint8_t sample_rate = (hfp_connection->negotiated_codec == HFP_CODEC_MSBC) ? 1 : 0;
2280 // i2s enable, master, 8/16 kHz, 512 kHz
2281 hci_send_cmd(&hci_bcm_write_i2spcm_interface_param, 1, 1, sample_rate, 2);
2282 }
2283 #endif
2284
hfp_prepare_for_sco(hfp_connection_t * hfp_connection)2285 void hfp_prepare_for_sco(hfp_connection_t * hfp_connection){
2286 UNUSED(hfp_connection);
2287 #ifdef ENABLE_CC256X_ASSISTED_HFP
2288 hfp_connection->cc256x_send_write_codec_config = true;
2289 if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
2290 hfp_connection->cc256x_send_wbs_associate = true;
2291 }
2292 #endif
2293
2294 #ifdef ENABLE_BCM_PCM_WBS
2295 #ifndef HAVE_BCM_PCM_NBS_16KHZ
2296 hfp_connection->bcm_send_write_i2spcm_interface_param = true;
2297 #endif
2298 if (hfp_connection->negotiated_codec == HFP_CODEC_MSBC){
2299 hfp_connection->bcm_send_enable_wbs = true;
2300 }
2301 #endif
2302
2303 #ifdef ENABLE_RTK_PCM_WBS
2304 hfp_connection->rtk_send_sco_config = true;
2305 #endif
2306 }
2307
hfp_set_hf_callback(btstack_packet_handler_t callback)2308 void hfp_set_hf_callback(btstack_packet_handler_t callback){
2309 hfp_hf_callback = callback;
2310 }
2311
hfp_set_ag_callback(btstack_packet_handler_t callback)2312 void hfp_set_ag_callback(btstack_packet_handler_t callback){
2313 hfp_ag_callback = callback;
2314 }
2315
hfp_set_ag_rfcomm_packet_handler(btstack_packet_handler_t handler)2316 void hfp_set_ag_rfcomm_packet_handler(btstack_packet_handler_t handler){
2317 hfp_ag_rfcomm_packet_handler = handler;
2318 }
2319
hfp_set_hf_rfcomm_packet_handler(btstack_packet_handler_t handler)2320 void hfp_set_hf_rfcomm_packet_handler(btstack_packet_handler_t handler){
2321 hfp_hf_rfcomm_packet_handler = handler;
2322 }
2323
hfp_set_hf_indicators(uint8_t indicators_nr,const uint8_t * indicators)2324 void hfp_set_hf_indicators(uint8_t indicators_nr, const uint8_t * indicators) {
2325 hfp_hf_indicators_nr = indicators_nr;
2326 hfp_hf_indicators = indicators;
2327 }
2328
hfp_init(void)2329 void hfp_init(void){
2330 hfp_allowed_sco_packet_types = SCO_PACKET_TYPES_ALL;
2331 }
2332
hfp_deinit(void)2333 void hfp_deinit(void){
2334 hfp_allowed_sco_packet_types = 0;
2335 hfp_connections = NULL;
2336 hfp_hf_callback = NULL;
2337 hfp_ag_callback = NULL;
2338 hfp_hf_rfcomm_packet_handler = NULL;
2339 hfp_ag_rfcomm_packet_handler = NULL;
2340 hfp_sco_establishment_active = NULL;
2341 hfp_custom_commands_ag = NULL;
2342 hfp_custom_commands_hf = NULL;
2343 (void) memset(&hfp_sdp_query_context, 0, sizeof(hfp_sdp_query_context_t));
2344 (void) memset(&hfp_sdp_query_request, 0, sizeof(btstack_context_callback_registration_t));
2345 }
2346
hfp_set_sco_packet_types(uint16_t packet_types)2347 void hfp_set_sco_packet_types(uint16_t packet_types){
2348 hfp_allowed_sco_packet_types = packet_types;
2349 }
2350
hfp_get_sco_packet_types(void)2351 uint16_t hfp_get_sco_packet_types(void){
2352 return hfp_allowed_sco_packet_types;
2353 }
2354
hfp_next_link_setting(hfp_link_settings_t current_setting,uint16_t local_sco_packet_types,uint16_t remote_sco_packet_types,bool eSCO_S4_supported,uint8_t negotiated_codec)2355 hfp_link_settings_t hfp_next_link_setting(hfp_link_settings_t current_setting, uint16_t local_sco_packet_types,
2356 uint16_t remote_sco_packet_types, bool eSCO_S4_supported,
2357 uint8_t negotiated_codec) {
2358 int8_t setting = (int8_t) current_setting;
2359 while (setting > 0){
2360 setting--;
2361 // skip S4 if not supported
2362 if ((setting == (int8_t) HFP_LINK_SETTINGS_S4) && !eSCO_S4_supported) continue;
2363 // skip wrong codec
2364 if ((hfp_link_settings[setting].codec_mask & (1 << negotiated_codec)) == 0) continue;
2365 // skip disabled or not supported packet types
2366 uint16_t required_packet_types = hfp_link_settings[setting].packet_types;
2367 uint16_t allowed_packet_types = hfp_allowed_sco_packet_types & local_sco_packet_types & remote_sco_packet_types;
2368 if ((required_packet_types & allowed_packet_types) == 0) continue;
2369
2370 // found matching setting
2371 return (hfp_link_settings_t) setting;
2372 }
2373 return HFP_LINK_SETTINGS_NONE;
2374 }
2375
hfp_next_link_setting_for_connection(hfp_link_settings_t current_setting,hfp_connection_t * hfp_connection,uint8_t eSCO_S4_supported)2376 static hfp_link_settings_t hfp_next_link_setting_for_connection(hfp_link_settings_t current_setting, hfp_connection_t * hfp_connection, uint8_t eSCO_S4_supported){
2377 uint8_t negotiated_codec = hfp_connection->negotiated_codec;
2378 uint16_t local_sco_packet_types = hci_usable_sco_packet_types();
2379 uint16_t remote_sco_packet_types = hci_remote_sco_packet_types(hfp_connection->acl_handle);
2380 return hfp_next_link_setting(current_setting, local_sco_packet_types, remote_sco_packet_types, eSCO_S4_supported,
2381 negotiated_codec);
2382 }
2383
hfp_init_link_settings(hfp_connection_t * hfp_connection,uint8_t eSCO_S4_supported)2384 void hfp_init_link_settings(hfp_connection_t * hfp_connection, uint8_t eSCO_S4_supported){
2385 // get highest possible link setting
2386 hfp_connection->link_setting = hfp_next_link_setting_for_connection(HFP_LINK_SETTINGS_NONE, hfp_connection, eSCO_S4_supported);
2387 log_info("hfp_init_link_settings: %u", hfp_connection->link_setting);
2388 }
2389
2390 #define HFP_HF_RX_DEBUG_PRINT_LINE 80
2391
hfp_log_rfcomm_message(const char * tag,uint8_t * packet,uint16_t size)2392 void hfp_log_rfcomm_message(const char * tag, uint8_t * packet, uint16_t size){
2393 #ifdef ENABLE_LOG_INFO
2394 // encode \n\r
2395 char printable[HFP_HF_RX_DEBUG_PRINT_LINE+2];
2396 int i = 0;
2397 int pos;
2398 for (pos=0 ; (pos < size) && (i < (HFP_HF_RX_DEBUG_PRINT_LINE - 3)) ; pos++){
2399 switch (packet[pos]){
2400 case '\n':
2401 printable[i++] = '\\';
2402 printable[i++] = 'n';
2403 break;
2404 case '\r':
2405 printable[i++] = '\\';
2406 printable[i++] = 'r';
2407 break;
2408 default:
2409 printable[i++] = packet[pos];
2410 break;
2411 }
2412 }
2413 printable[i] = 0;
2414 log_info("%s: '%s'", tag, printable);
2415 #else
2416 UNUSED(tag);
2417 UNUSED(packet);
2418 UNUSED(size);
2419 #endif
2420 }
2421
hfp_register_custom_ag_command(hfp_custom_at_command_t * custom_at_command)2422 void hfp_register_custom_ag_command(hfp_custom_at_command_t * custom_at_command){
2423 btstack_linked_list_add(&hfp_custom_commands_ag, (btstack_linked_item_t *) custom_at_command);
2424 }
2425
hfp_register_custom_hf_command(hfp_custom_at_command_t * custom_at_command)2426 void hfp_register_custom_hf_command(hfp_custom_at_command_t * custom_at_command){
2427 btstack_linked_list_add(&hfp_custom_commands_hf, (btstack_linked_item_t *) custom_at_command);
2428 }
2429
2430 // HFP H2 Synchronization - might get moved into a hfp_h2.c
2431
2432 // find position of h2 sync header, returns -1 if not found, or h2 sync position
hfp_h2_sync_find(const uint8_t * frame_data,uint16_t frame_len)2433 static int16_t hfp_h2_sync_find(const uint8_t * frame_data, uint16_t frame_len){
2434 uint16_t i;
2435 for (i=0;i<(frame_len - 1);i++){
2436 // check: first byte == 1
2437 uint8_t h2_first_byte = frame_data[i];
2438 if (h2_first_byte == 0x01) {
2439 uint8_t h2_second_byte = frame_data[i + 1];
2440 // check lower nibble of second byte == 0x08
2441 if ((h2_second_byte & 0x0F) == 8) {
2442 // check if bits 0+2 == bits 1+3
2443 uint8_t hn = h2_second_byte >> 4;
2444 if (((hn >> 1) & 0x05) == (hn & 0x05)) {
2445 return (int16_t) i;
2446 }
2447 }
2448 }
2449 }
2450 return -1;
2451 }
2452
hfp_h2_sync_reset(hfp_h2_sync_t * hfp_h2_sync)2453 static void hfp_h2_sync_reset(hfp_h2_sync_t * hfp_h2_sync){
2454 hfp_h2_sync->frame_len = 0;
2455 }
2456
hfp_h2_sync_init(hfp_h2_sync_t * hfp_h2_sync,bool (* callback)(bool bad_frame,const uint8_t * frame_data,uint16_t frame_len))2457 void hfp_h2_sync_init(hfp_h2_sync_t * hfp_h2_sync,
2458 bool (*callback)(bool bad_frame, const uint8_t * frame_data, uint16_t frame_len)){
2459 hfp_h2_sync->callback = callback;
2460 hfp_h2_sync->dropped_bytes = 0;
2461 hfp_h2_sync_reset(hfp_h2_sync);
2462 }
2463
hfp_h2_report_bad_frames(hfp_h2_sync_t * hfp_h2_sync)2464 static void hfp_h2_report_bad_frames(hfp_h2_sync_t *hfp_h2_sync){
2465 // report bad frames
2466 while (hfp_h2_sync->dropped_bytes >= HFP_H2_SYNC_FRAME_SIZE){
2467 hfp_h2_sync->dropped_bytes -= HFP_H2_SYNC_FRAME_SIZE;
2468 (void)(*hfp_h2_sync->callback)(true,NULL, HFP_H2_SYNC_FRAME_SIZE);
2469 }
2470 }
2471
hfp_h2_sync_drop_bytes(hfp_h2_sync_t * hfp_h2_sync,uint16_t bytes_to_drop)2472 static void hfp_h2_sync_drop_bytes(hfp_h2_sync_t * hfp_h2_sync, uint16_t bytes_to_drop){
2473 btstack_assert(bytes_to_drop <= hfp_h2_sync->frame_len);
2474 memmove(hfp_h2_sync->frame_data, &hfp_h2_sync->frame_data[bytes_to_drop], hfp_h2_sync->frame_len - bytes_to_drop);
2475 hfp_h2_sync->dropped_bytes += bytes_to_drop;
2476 hfp_h2_sync->frame_len -= bytes_to_drop;
2477 hfp_h2_report_bad_frames(hfp_h2_sync);
2478 }
2479
hfp_h2_sync_process(hfp_h2_sync_t * hfp_h2_sync,bool bad_frame,const uint8_t * frame_data,uint16_t frame_len)2480 void hfp_h2_sync_process(hfp_h2_sync_t *hfp_h2_sync, bool bad_frame, const uint8_t *frame_data, uint16_t frame_len) {
2481
2482 if (bad_frame){
2483 // drop all data
2484 hfp_h2_sync->dropped_bytes += hfp_h2_sync->frame_len;
2485 hfp_h2_sync->frame_len = 0;
2486 // all new data is bad, too
2487 hfp_h2_sync->dropped_bytes += frame_len;
2488 // report frames
2489 hfp_h2_report_bad_frames(hfp_h2_sync);
2490 return;
2491 }
2492
2493 while (frame_len > 0){
2494 // Fill hfp_h2_sync->frame_buffer
2495 uint16_t bytes_free_in_frame_buffer = HFP_H2_SYNC_FRAME_SIZE - hfp_h2_sync->frame_len;
2496 uint16_t bytes_to_append = btstack_min(frame_len, bytes_free_in_frame_buffer);
2497 memcpy(&hfp_h2_sync->frame_data[hfp_h2_sync->frame_len], frame_data, bytes_to_append);
2498 frame_data += bytes_to_append;
2499 frame_len -= bytes_to_append;
2500 hfp_h2_sync->frame_len += bytes_to_append;
2501 // check complete frame for h2 sync
2502 if (hfp_h2_sync->frame_len == HFP_H2_SYNC_FRAME_SIZE){
2503 bool valid_frame = true;
2504 int16_t h2_pos = hfp_h2_sync_find(hfp_h2_sync->frame_data, hfp_h2_sync->frame_len);
2505 if (h2_pos < 0){
2506 // no h2 sync, no valid frame, keep last byte if it is 0x01
2507 if (hfp_h2_sync->frame_data[HFP_H2_SYNC_FRAME_SIZE-1] == 0x01){
2508 hfp_h2_sync_drop_bytes(hfp_h2_sync, HFP_H2_SYNC_FRAME_SIZE - 1);
2509 } else {
2510 hfp_h2_sync_drop_bytes(hfp_h2_sync, HFP_H2_SYNC_FRAME_SIZE);
2511 }
2512 valid_frame = false;
2513 }
2514 else if (h2_pos > 0){
2515 // drop data before h2 sync
2516 hfp_h2_sync_drop_bytes(hfp_h2_sync, h2_pos);
2517 valid_frame = false;
2518 }
2519 if (valid_frame) {
2520 // h2 sync at pos 0 and complete frame
2521 bool codec_ok = (*hfp_h2_sync->callback)(false, hfp_h2_sync->frame_data, hfp_h2_sync->frame_len);
2522 if (codec_ok){
2523 hfp_h2_sync_reset(hfp_h2_sync);
2524 } else {
2525 // drop first two bytes
2526 hfp_h2_sync_drop_bytes(hfp_h2_sync, 2);
2527 }
2528 }
2529 }
2530 }
2531 }
2532