merge follow-up

This commit is contained in:
Matthias Ringwald 2016-03-03 14:29:18 +01:00
parent a0ffb263e0
commit d63c37a1e9
8 changed files with 264 additions and 91 deletions

View File

@ -766,11 +766,13 @@ typedef uint8_t sm_key_t[16];
// #define HCI_EVENT_SDP_META 0xxx
// #define HCI_EVENT_SM_META 0xxx
/** HSP Subevent */
/**
* @format 11H
* @format 11
* @param subevent_code
* @param status 0 == OK
* @param handle
*/
#define HSP_SUBEVENT_AUDIO_CONNECTION_COMPLETE 0x01
@ -818,31 +820,195 @@ typedef uint8_t sm_key_t[16];
#define HSP_SUBEVENT_AG_INDICATION 0x07
// HFP Subevents
/** HFP Subevent */
/**
* @format 11
* @param subevent_code
* @param status 0 == OK
*/
#define HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED 0x01
/**
* @format 1
* @param subevent_code
*/
#define HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED 0x02
/**
* @format 11
* @param subevent_code
* @param status 0 == OK
*/
#define HFP_SUBEVENT_AUDIO_CONNECTION_ESTABLISHED 0x03
/**
* @format 1
* @param subevent_code
*/
#define HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED 0x04
/**
* @format 11
* @param subevent_code
* @param status 0 == OK
*/
#define HFP_SUBEVENT_COMPLETE 0x05
/**
* @format 111T
* @param subevent_code
* @param indicator_index
* @param indicator_status
* @param indicator_name
*/
#define HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED 0x06
/**
* @format 1111T
* @param subevent_code
* @param network_operator_mode
* @param network_operator_format
* @param network_operator_name
*/
#define HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED 0x07
#define HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR 0x08
#define HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE 0x09
#define HFP_SUBEVENT_START_RINGINIG 0x0A
#define HFP_SUBEVENT_STOP_RINGINIG 0x0B
#define HFP_SUBEVENT_CALL_TERMINATED 0x0C
#define HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER 0x0D
#define HFP_SUBEVENT_REDIAL_LAST_NUMBER 0x0E
#define HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG 0x0F
#define HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG 0x10
#define HFP_SUBEVENT_TRANSMIT_DTMF_CODES 0x11
#define HFP_SUBEVENT_TRANSMIT_STATUS_OF_CURRENT_CALL 0x12
#define HFP_SUBEVENT_CALL_ANSWERED 0x13
#define HFP_SUBEVENT_CONFERENCE_CALL 0x14
#define HFP_SUBEVENT_RING 0x15
#define HFP_SUBEVENT_SPEAKER_VOLUME 0x16
#define HFP_SUBEVENT_MICROPHONE_VOLUME 0x17
/**
* @format 11
* @param subevent_code
* @param error
*/
#define HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR 0x08
/**
* @format 11
* @param subevent_code
* @param status
*/
#define HFP_SUBEVENT_CODECS_CONNECTION_COMPLETE 0x09
/**
* @format 1
* @param subevent_code
*/
#define HFP_SUBEVENT_START_RINGINIG 0x0A
/**
* @format 1
* @param subevent_code
*/
#define HFP_SUBEVENT_STOP_RINGINIG 0x0B
/**
* @format 1
* @param subevent_code
*/
#define HFP_SUBEVENT_CALL_TERMINATED 0x0C
/**
* @format 1T
* @param subevent_code
* @param number
*/
#define HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER 0x0D
/**
* @format 1
* @param subevent_code
*/
#define HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG 0x0E
/**
* @format 1T
* @param subevent_code
* @param number
*/
#define HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG 0x0F
/**
* @format 1T
* @param subevent_code
* @param dtmf code
*/
#define HFP_SUBEVENT_TRANSMIT_DTMF_CODES 0x10
/**
* @format 1
* @param subevent_code
*/
#define HFP_SUBEVENT_CALL_ANSWERED 0x11
/**
* @format 1
* @param subevent_code
*/
#define HFP_SUBEVENT_CONFERENCE_CALL 0x12
/**
* @format 1
* @param subevent_code
*/
#define HFP_SUBEVENT_RING 0x13
/**
* @format 111
* @param subevent_code
* @param status
* @param gain
*/
#define HFP_SUBEVENT_SPEAKER_VOLUME 0x14
/**
* @format 111
* @param subevent_code
* @param status
* @param gain
*/
#define HFP_SUBEVENT_MICROPHONE_VOLUME 0x15
/**
* @format 11T
* @param subevent_code
* @param type
* @param number
*/
#define HFP_SUBEVENT_CALL_WAITING_NOTIFICATION 0x16
/**
* @format 11T
* @param subevent_code
* @param type
* @param number
*/
#define HFP_SUBEVENT_CALLING_LINE_INDETIFICATION_NOTIFICATION 0x17
/**
* @format 111111T
* @param subevent_code
* @param clcc_idx
* @param clcc_dir
* @param clcc_status
* @param clcc_mpty
* @param bnip_type
* @param bnip_number
*/
#define HFP_SUBEVENT_ENHANCED_CALL_STATUS 0x18
/**
* @format 111T
* @param subevent_code
* @param status
* @param bnip_type
* @param bnip_number
*/
#define HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION 0x19
/**
* @format 1T
* @param subevent_code
* @param value
*/
#define HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS 0x1A
// ANCS Client

View File

@ -99,9 +99,6 @@ static const char * hfp_ag_features[] = {
"Reserved for future definition"
};
static int hfp_generic_status_indicators_nr = 0;
static hfp_generic_status_indicator_t hfp_generic_status_indicators[HFP_MAX_NUM_HF_INDICATORS];
static btstack_linked_list_t hfp_connections = NULL;
static void parse_sequence(hfp_connection_t * context);
static hfp_callback_t hfp_callback;
@ -312,7 +309,7 @@ static hfp_connection_t * create_hfp_connection_context(){
hfp_reset_context_flags(hfp_connection);
btstack_linked_list_add(&hfp_connections, (linked_item_t*)hfp_connection);
btstack_linked_list_add(&hfp_connections, (btstack_linked_item_t*)hfp_connection);
return hfp_connection;
}
@ -424,7 +421,7 @@ static void handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *pac
static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
hfp_connection_t * hfp_connection = connection_doing_sdp_query;
if ( hfp_connection->state != HFP_W4_SDP_EVENT_QUERY_COMPLETE) return;
if ( hfp_connection->state != HFP_W4_SDP_QUERY_COMPLETE) return;
switch (hci_event_packet_get_type(packet)){
case SDP_EVENT_QUERY_RFCOMM_SERVICE:
@ -461,14 +458,14 @@ void hfp_handle_hci_event(uint8_t packet_type, uint8_t *packet, uint16_t size){
case RFCOMM_EVENT_INCOMING_CONNECTION:
// data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
reverse_bd_addr(&packet[2], event_addr);
context = provide_hfp_connection_context_for_bd_addr(event_addr);
hfp_connection = provide_hfp_connection_context_for_bd_addr(event_addr);
if (!context || context->state != HFP_IDLE) return;
if (!hfp_connection || hfp_connection->state != HFP_IDLE) return;
context->rfcomm_cid = little_endian_read_16(packet, 9);
context->state = HFP_W4_RFCOMM_CONNECTED;
printf("RFCOMM channel %u requested for %s\n", context->rfcomm_cid, bd_addr_to_str(context->remote_addr));
rfcomm_accept_connection(context->rfcomm_cid);
hfp_connection->rfcomm_cid = little_endian_read_16(packet, 9);
hfp_connection->state = HFP_W4_RFCOMM_CONNECTED;
printf("RFCOMM channel %u requested for %s\n", hfp_connection->rfcomm_cid, bd_addr_to_str(hfp_connection->remote_addr));
rfcomm_accept_connection(hfp_connection->rfcomm_cid);
break;
case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE:
@ -476,26 +473,26 @@ void hfp_handle_hci_event(uint8_t packet_type, uint8_t *packet, uint16_t size){
printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE packet_handler type %u, size %u\n", packet_type, size);
reverse_bd_addr(&packet[3], event_addr);
context = get_hfp_connection_context_for_bd_addr(event_addr);
if (!context || context->state != HFP_W4_RFCOMM_CONNECTED) return;
hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr);
if (!hfp_connection || hfp_connection->state != HFP_W4_RFCOMM_CONNECTED) return;
if (packet[2]) {
hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_ESTABLISHED, packet[2]);
remove_hfp_connection_context(context);
remove_hfp_connection_context(hfp_connection);
} else {
context->acl_handle = little_endian_read_16(packet, 9);
printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE con_handle 0x%02x\n", context->acl_handle);
hfp_connection->acl_handle = little_endian_read_16(packet, 9);
printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE con_handle 0x%02x\n", hfp_connection->acl_handle);
context->rfcomm_cid = little_endian_read_16(packet, 12);
hfp_connection->rfcomm_cid = little_endian_read_16(packet, 12);
uint16_t mtu = little_endian_read_16(packet, 14);
printf("RFCOMM channel open succeeded. Context %p, RFCOMM Channel ID 0x%02x, max frame size %u\n", context, context->rfcomm_cid, mtu);
printf("RFCOMM channel open succeeded. hfp_connection %p, RFCOMM Channel ID 0x%02x, max frame size %u\n", hfp_connection, hfp_connection->rfcomm_cid, mtu);
switch (context->state){
switch (hfp_connection->state){
case HFP_W4_RFCOMM_CONNECTED:
context->state = HFP_EXCHANGE_SUPPORTED_FEATURES;
hfp_connection->state = HFP_EXCHANGE_SUPPORTED_FEATURES;
break;
case HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN:
context->state = HFP_W2_DISCONNECT_RFCOMM;
hfp_connection->state = HFP_W2_DISCONNECT_RFCOMM;
printf("Shutting down RFCOMM.\n");
break;
default:
@ -514,29 +511,29 @@ void hfp_handle_hci_event(uint8_t packet_type, uint8_t *packet, uint16_t size){
log_error("(e)SCO Connection failed status %u", status);
// if outgoing && link_setting != d0 && appropriate error
if (status != 0x11 && status != 0x1f) break; // invalid params / unspecified error
context = get_hfp_connection_context_for_bd_addr(event_addr);
if (!context) break;
switch (context->link_setting){
hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr);
if (!hfp_connection) break;
switch (hfp_connection->link_setting){
case HFP_LINK_SETTINGS_D0:
return; // no other option left
case HFP_LINK_SETTINGS_D1:
// context->link_setting = HFP_LINK_SETTINGS_D0;
// hfp_connection->link_setting = HFP_LINK_SETTINGS_D0;
// break;
case HFP_LINK_SETTINGS_S1:
// context->link_setting = HFP_LINK_SETTINGS_D1;
// hfp_connection->link_setting = HFP_LINK_SETTINGS_D1;
// break;
case HFP_LINK_SETTINGS_S2:
case HFP_LINK_SETTINGS_S3:
case HFP_LINK_SETTINGS_S4:
// context->link_setting = HFP_LINK_SETTINGS_S1;
// hfp_connection->link_setting = HFP_LINK_SETTINGS_S1;
// break;
case HFP_LINK_SETTINGS_T1:
case HFP_LINK_SETTINGS_T2:
// context->link_setting = HFP_LINK_SETTINGS_S3;
context->link_setting = HFP_LINK_SETTINGS_D0;
// hfp_connection->link_setting = HFP_LINK_SETTINGS_S3;
hfp_connection->link_setting = HFP_LINK_SETTINGS_D0;
break;
}
context->establish_audio_connection = 1;
hfp_connection->establish_audio_connection = 1;
break;
}
@ -574,55 +571,55 @@ void hfp_handle_hci_event(uint8_t packet_type, uint8_t *packet, uint16_t size){
" rx_packet_length %u bytes, tx_packet_length %u bytes, air_mode 0x%2x (0x02 == CVSD)\n", sco_handle,
bd_addr_to_str(event_addr), transmission_interval, retransmission_interval, rx_packet_length, tx_packet_length, air_mode);
context = get_hfp_connection_context_for_bd_addr(event_addr);
hfp_connection = get_hfp_connection_context_for_bd_addr(event_addr);
if (!context) {
log_error("SCO link created, context for address %s not found.", bd_addr_to_str(event_addr));
if (!hfp_connection) {
log_error("SCO link created, hfp_connection for address %s not found.", bd_addr_to_str(event_addr));
break;
}
if (context->state == HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){
if (hfp_connection->state == HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN){
log_info("SCO about to disconnect: HFP_W4_CONNECTION_ESTABLISHED_TO_SHUTDOWN");
context->state = HFP_W2_DISCONNECT_SCO;
hfp_connection->state = HFP_W2_DISCONNECT_SCO;
break;
}
context->sco_handle = sco_handle;
context->establish_audio_connection = 0;
context->state = HFP_AUDIO_CONNECTION_ESTABLISHED;
hfp_connection->sco_handle = sco_handle;
hfp_connection->establish_audio_connection = 0;
hfp_connection->state = HFP_AUDIO_CONNECTION_ESTABLISHED;
hfp_emit_audio_connection_established_event(hfp_callback, packet[2], sco_handle);
break;
}
case RFCOMM_EVENT_CHANNEL_CLOSED:
rfcomm_cid = little_endian_read_16(packet,2);
context = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid);
if (!context) break;
if (context->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){
context->state = HFP_IDLE;
hfp_establish_service_level_connection(context->remote_addr, context->service_uuid);
hfp_connection = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid);
if (!hfp_connection) break;
if (hfp_connection->state == HFP_W4_RFCOMM_DISCONNECTED_AND_RESTART){
hfp_connection->state = HFP_IDLE;
hfp_establish_service_level_connection(hfp_connection->remote_addr, hfp_connection->service_uuid);
break;
}
hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0);
remove_hfp_connection_context(context);
remove_hfp_connection_context(hfp_connection);
break;
case HCI_EVENT_DISCONNECTION_COMPLETE:
handle = little_endian_read_16(packet,3);
context = get_hfp_connection_context_for_sco_handle(handle);
hfp_connection = get_hfp_connection_context_for_sco_handle(handle);
if (!context) break;
if (!hfp_connection) break;
if (context->state != HFP_W4_SCO_DISCONNECTED){
if (hfp_connection->state != HFP_W4_SCO_DISCONNECTED){
log_info("Received gap disconnect in wrong hfp state");
}
log_info("Check SCO handle: incoming 0x%02x, context 0x%02x\n", handle,context->sco_handle);
log_info("Check SCO handle: incoming 0x%02x, hfp_connection 0x%02x\n", handle, hfp_connection->sco_handle);
if (handle == context->sco_handle){
if (handle == hfp_connection->sco_handle){
log_info("SCO disconnected, w2 disconnect RFCOMM\n");
context->sco_handle = 0;
context->release_audio_connection = 0;
context->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
hfp_connection->sco_handle = 0;
hfp_connection->release_audio_connection = 0;
hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
hfp_emit_event(hfp_callback, HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED, 0);
break;
}
@ -1284,7 +1281,7 @@ void hfp_establish_service_level_connection(bd_addr_t bd_addr, uint16_t service_
return;
case HFP_IDLE:
memcpy(hfp_connection->remote_addr, bd_addr, 6);
hfp_connection->state = HFP_W4_SDP_EVENT_QUERY_COMPLETE;
hfp_connection->state = HFP_W4_SDP_QUERY_COMPLETE;
connection_doing_sdp_query = hfp_connection;
hfp_connection->service_uuid = service_uuid;
sdp_query_rfcomm_channel_and_name_for_uuid(&handle_query_rfcomm_event, hfp_connection->remote_addr, service_uuid);

View File

@ -800,7 +800,7 @@ static int hfp_ag_run_for_audio_connection(hfp_connection_t * hfp_connection){
if (hfp_connection->establish_audio_connection){
hfp_connection->state = HFP_W4_SCO_CONNECTED;
hfp_connection->establish_audio_connection = 0;
hfp_setup_synchronous_connection(hfp_connection->acl_handle, context->link_setting);
hfp_setup_synchronous_connection(hfp_connection->acl_handle, hfp_connection->link_setting);
return 1;
}
return 0;
@ -820,10 +820,10 @@ static hfp_connection_t * hfp_ag_context_for_timer(btstack_timer_source_t * ts){
}
static void hfp_timeout_handler(btstack_timer_source_t * timer){
hfp_connection_t * context = hfp_ag_context_for_timer(timer);
if (!context) return;
hfp_connection_t * hfp_connection = hfp_ag_context_for_timer(timer);
if (!hfp_connection) return;
log_info("HFP start ring timeout, con handle 0x%02x", hfp_connection->con_handle);
log_info("HFP start ring timeout, con handle 0x%02x", hfp_connection->acl_handle);
hfp_connection->ag_ring = 1;
hfp_connection->ag_send_clip = hfp_gsm_clip_type() && hfp_connection->clip_enabled;
@ -880,7 +880,7 @@ static void hfp_ag_trigger_incoming_call(void){
hfp_ag_establish_service_level_connection(hfp_connection->remote_addr);
if (hfp_connection->call_state == HFP_CALL_IDLE){
hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, indicator_index, 1);
hfp_ag_hf_start_ringing(connection);
hfp_ag_hf_start_ringing(hfp_connection);
}
if (hfp_connection->call_state == HFP_CALL_ACTIVE){
hfp_connection->call_state = HFP_CALL_W2_SEND_CALL_WAITING;
@ -1008,7 +1008,7 @@ static void hfp_ag_trigger_terminate_call(void){
btstack_linked_list_iterator_init(&it, hfp_get_connections());
while (btstack_linked_list_iterator_has_next(&it)){
hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
hfp_ag_establish_service_level_connection(connection->remote_addr);
hfp_ag_establish_service_level_connection(hfp_connection->remote_addr);
if (hfp_connection->call_state == HFP_CALL_IDLE) continue;
hfp_connection->call_state = HFP_CALL_IDLE;
hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, call_indicator_index, 1);
@ -1958,10 +1958,10 @@ static void hfp_handle_rfcomm_data(uint8_t packet_type, uint16_t channel, uint8_
}
static void hfp_run(void){
linked_list_iterator_t it;
linked_list_iterator_init(&it, hfp_get_connections());
while (linked_list_iterator_has_next(&it)){
hfp_connection_t * hfp_connection = (hfp_connection_t *)linked_list_iterator_next(&it);
btstack_linked_list_iterator_t it;
btstack_linked_list_iterator_init(&it, hfp_get_connections());
while (btstack_linked_list_iterator_has_next(&it)){
hfp_connection_t * hfp_connection = (hfp_connection_t *)btstack_linked_list_iterator_next(&it);
hfp_run_for_context(hfp_connection);
}
}
@ -2016,10 +2016,13 @@ void hfp_ag_init_call_hold_services(int call_hold_services_nr, const char * call
void hfp_ag_init(uint16_t rfcomm_channel_nr){
// register for HCI events
hci_event_callback_registration.callback = &packet_handler;
hci_add_event_handler(&hci_event_callback_registration);
l2cap_init();
l2cap_register_packet_handler(packet_handler);
rfcomm_register_packet_handler(packet_handler);
hfp_init(rfcomm_channel_nr);
rfcomm_register_service(packet_handler, rfcomm_channel_nr, 0xffff);
hfp_ag_response_and_hold_active = 0;
subscriber_numbers = NULL;

View File

@ -1082,10 +1082,13 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
}
void hfp_hf_init(uint16_t rfcomm_channel_nr){
// register for HCI events
hci_event_callback_registration.callback = &packet_handler;
hci_add_event_handler(&hci_event_callback_registration);
l2cap_init();
l2cap_register_packet_handler(packet_handler);
rfcomm_register_packet_handler(packet_handler);
hfp_init(rfcomm_channel_nr);
rfcomm_register_service(packet_handler, rfcomm_channel_nr, 0xffff);
hfp_supported_features = HFP_DEFAULT_HF_SUPPORTED_FEATURES;
hfp_codecs_nr = 0;

View File

@ -559,7 +559,7 @@ static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uin
switch (hci_event_packet_get_type(packet)){
case SDP_EVENT_QUERY_RFCOMM_SERVICE:
channel_nr = sdp_event_query_rfcomm_service_get_rfcomm_channel(packet);
log_info("** Service name: '%s', RFCOMM port %u", ve->service_name, channel_nr);
log_info("** Service name: '%s', RFCOMM port %u", sdp_event_query_rfcomm_service_get_name(packet), channel_nr);
break;
case SDP_EVENT_QUERY_COMPLETE:
if (channel_nr > 0){

View File

@ -4,7 +4,7 @@ CC = g++
BTSTACK_ROOT = ../..
CFLAGS = -DUNIT_TEST -x c++ -g -Wall -Wnarrowing -Wconversion-null -I. -I../ -I${BTSTACK_ROOT}/src -I${BTSTACK_ROOT}/ble -I${BTSTACK_ROOT}/include
CFLAGS = -DUNIT_TEST -x c++ -g -Wall -Wnarrowing -Wconversion-null -I. -I../ -I${BTSTACK_ROOT}/src -I${BTSTACK_ROOT}/ble
LDFLAGS += -lCppUTest -lCppUTestExt
VPATH += ${BTSTACK_ROOT}/src

View File

@ -61,11 +61,14 @@ static void att_init_connection(att_connection_t * att_connection){
att_connection->authorized = 0;
}
int hci_can_send_acl_le_packet_now(void){
return 1;
}
int l2cap_can_send_connectionless_packet_now(void){
return 1;
}
uint8_t *l2cap_get_outgoing_buffer(void){
// printf("l2cap_get_outgoing_buffer\n");
return (uint8_t *)&l2cap_stack_buffer; // 8 bytes

View File

@ -45,6 +45,7 @@
#include "CppUTest/CommandLineTestRunner.h"
#include "classic/hfp.h"
#include "classic/hfp_ag.h"
void hfp_parse(hfp_connection_t * context, uint8_t byte, int isHandsFree);