hfp: sort code, use assert

This commit is contained in:
Matthias Ringwald 2020-10-12 12:09:29 +02:00
parent 2e755e5da0
commit 76cc152743
2 changed files with 145 additions and 139 deletions

View File

@ -109,6 +109,15 @@ static int subscriber_numbers_count = 0;
hfp_ag_indicator_t * hfp_ag_get_ag_indicators(hfp_connection_t * hfp_connection);
static void hfp_ag_emit_simple_event(uint8_t event_subtype){
uint8_t event[3];
event[0] = HCI_EVENT_HFP_META;
event[1] = sizeof(event) - 2;
event[2] = event_subtype;
if (!hfp_ag_callback) return;
(*hfp_ag_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
static int hfp_ag_get_ag_indicators_nr(hfp_connection_t * hfp_connection){
if (hfp_connection->ag_indicators_nr != hfp_ag_indicators_nr){
hfp_connection->ag_indicators_nr = hfp_ag_indicators_nr;
@ -160,15 +169,6 @@ static hfp_connection_t * get_hfp_ag_connection_context_for_acl_handle(uint16_t
return NULL;
}
void hfp_ag_register_packet_handler(btstack_packet_handler_t callback){
if (callback == NULL){
log_error("hfp_ag_register_packet_handler called with NULL callback");
return;
}
hfp_ag_callback = callback;
hfp_set_ag_callback(callback);
}
static int use_in_band_tone(void){
return get_bit(hfp_supported_features, HFP_AGSF_IN_BAND_RING_TONE);
}
@ -191,33 +191,7 @@ static int has_hf_indicators_feature(hfp_connection_t * hfp_connection){
return hf && ag;
}
void hfp_ag_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint8_t ability_to_reject_call, uint16_t supported_features, int wide_band_speech){
if (!name){
name = default_hfp_ag_service_name;
}
hfp_create_sdp_record(service, service_record_handle, BLUETOOTH_SERVICE_CLASS_HANDSFREE_AUDIO_GATEWAY, rfcomm_channel_nr, name);
/*
* 0x01 Ability to reject a call
* 0x00 No ability to reject a call
*/
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0301); // Hands-Free Profile - Network
de_add_number(service, DE_UINT, DE_SIZE_8, ability_to_reject_call);
// Construct SupportedFeatures for SDP bitmap:
//
// "The values of the “SupportedFeatures” bitmap given in Table 5.4 shall be the same as the values
// of the Bits 0 to 4 of the unsolicited result code +BRSF"
//
// Wide band speech (bit 5) requires Codec negotiation
//
uint16_t sdp_features = supported_features & 0x1f;
if (wide_band_speech && (supported_features & (1 << HFP_AGSF_CODEC_NEGOTIATION))){
sdp_features |= 1 << 5;
}
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0311); // Hands-Free Profile - SupportedFeatures
de_add_number(service, DE_UINT, DE_SIZE_16, sdp_features);
}
/* unsolicited responses */
static int hfp_ag_send_change_in_band_ring_tone_setting_cmd(uint16_t cid){
char buffer[20];
@ -516,6 +490,8 @@ static uint8_t hfp_ag_suggest_codec(hfp_connection_t *hfp_connection){
return HFP_CODEC_CVSD;
}
/* state machines */
static uint8_t hfp_ag_esco_s4_supported(hfp_connection_t * hfp_connection){
return (hfp_connection->remote_supported_features & (1<<HFP_HFSF_ESCO_S4)) && (hfp_supported_features & (1<<HFP_AGSF_ESCO_S4));
}
@ -995,15 +971,6 @@ static void hfp_ag_trigger_reject_call(void){
}
}
static void hfp_ag_emit_simple_event(uint8_t event_subtype){
uint8_t event[3];
event[0] = HCI_EVENT_HFP_META;
event[1] = sizeof(event) - 2;
event[2] = event_subtype;
if (!hfp_ag_callback) return;
(*hfp_ag_callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
static void hfp_ag_trigger_terminate_call(void){
int call_indicator_index = get_ag_indicator_index_for_name("call");
@ -1754,14 +1721,11 @@ static int hfp_ag_send_commands(hfp_connection_t *hfp_connection){
static void hfp_ag_run_for_context(hfp_connection_t *hfp_connection){
if (!hfp_connection) return;
btstack_assert(hfp_connection != NULL);
btstack_assert(hfp_connection->local_role == HFP_ROLE_AG);
if (!hfp_connection->rfcomm_cid) return;
if (hfp_connection->local_role != HFP_ROLE_AG) {
log_info("HFP AG%p, wrong role %u", hfp_connection, hfp_connection->local_role);
return;
}
// during SDP query, RFCOMM CID is not set
if (hfp_connection->rfcomm_cid == 0) return;
if (!rfcomm_can_send_packet_now(hfp_connection->rfcomm_cid)) {
log_info("hfp_ag_run_for_context: request can send for 0x%02x", hfp_connection->rfcomm_cid);
@ -2407,3 +2371,39 @@ void hfp_ag_notify_incoming_call_waiting(hci_con_handle_t acl_handle){
hfp_ag_run_for_context(hfp_connection);
}
void hfp_ag_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint8_t ability_to_reject_call, uint16_t supported_features, int wide_band_speech){
if (!name){
name = default_hfp_ag_service_name;
}
hfp_create_sdp_record(service, service_record_handle, BLUETOOTH_SERVICE_CLASS_HANDSFREE_AUDIO_GATEWAY, rfcomm_channel_nr, name);
/*
* 0x01 Ability to reject a call
* 0x00 No ability to reject a call
*/
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0301); // Hands-Free Profile - Network
de_add_number(service, DE_UINT, DE_SIZE_8, ability_to_reject_call);
// Construct SupportedFeatures for SDP bitmap:
//
// "The values of the “SupportedFeatures” bitmap given in Table 5.4 shall be the same as the values
// of the Bits 0 to 4 of the unsolicited result code +BRSF"
//
// Wide band speech (bit 5) requires Codec negotiation
//
uint16_t sdp_features = supported_features & 0x1f;
if (wide_band_speech && (supported_features & (1 << HFP_AGSF_CODEC_NEGOTIATION))){
sdp_features |= 1 << 5;
}
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0311); // Hands-Free Profile - SupportedFeatures
de_add_number(service, DE_UINT, DE_SIZE_16, sdp_features);
}
void hfp_ag_register_packet_handler(btstack_packet_handler_t callback){
if (callback == NULL){
log_error("hfp_ag_register_packet_handler called with NULL callback");
return;
}
hfp_ag_callback = callback;
hfp_set_ag_callback(callback);
}

View File

@ -84,7 +84,27 @@ static hfp_call_status_t hfp_call_status;
static hfp_callsetup_status_t hfp_callsetup_status;
static hfp_callheld_status_t hfp_callheld_status;
static char phone_number[25];
static char phone_number[25];
static int has_codec_negotiation_feature(hfp_connection_t * hfp_connection){
int hf = get_bit(hfp_supported_features, HFP_HFSF_CODEC_NEGOTIATION);
int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_CODEC_NEGOTIATION);
return hf && ag;
}
static int has_call_waiting_and_3way_calling_feature(hfp_connection_t * hfp_connection){
int hf = get_bit(hfp_supported_features, HFP_HFSF_THREE_WAY_CALLING);
int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_THREE_WAY_CALLING);
return hf && ag;
}
static int has_hf_indicators_feature(hfp_connection_t * hfp_connection){
int hf = get_bit(hfp_supported_features, HFP_HFSF_HF_INDICATORS);
int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_HF_INDICATORS);
return hf && ag;
}
static hfp_connection_t * get_hfp_hf_connection_context_for_acl_handle(uint16_t handle){
btstack_linked_list_iterator_t it;
@ -98,14 +118,7 @@ static hfp_connection_t * get_hfp_hf_connection_context_for_acl_handle(uint16_t
return NULL;
}
void hfp_hf_register_packet_handler(btstack_packet_handler_t callback){
if (callback == NULL){
log_error("hfp_hf_register_packet_handler called with NULL callback");
return;
}
hfp_hf_callback = callback;
hfp_set_hf_callback(callback);
}
/* emit functinos */
static void hfp_hf_emit_subscriber_information(btstack_packet_handler_t callback, uint8_t event_subtype, uint8_t status, uint8_t bnip_type, const char * bnip_number){
if (!callback) return;
@ -154,46 +167,41 @@ static void hfp_hf_emit_enhanced_call_status(btstack_packet_handler_t callback,
(*callback)(HCI_EVENT_PACKET, 0, event, pos);
}
static int has_codec_negotiation_feature(hfp_connection_t * hfp_connection){
int hf = get_bit(hfp_supported_features, HFP_HFSF_CODEC_NEGOTIATION);
int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_CODEC_NEGOTIATION);
return hf && ag;
static void hfp_emit_ag_indicator_event(btstack_packet_handler_t callback, hfp_ag_indicator_t indicator){
if (!callback) return;
uint8_t event[10+HFP_MAX_INDICATOR_DESC_SIZE+1];
int pos = 0;
event[pos++] = HCI_EVENT_HFP_META;
event[pos++] = sizeof(event) - 2;
event[pos++] = HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED;
event[pos++] = indicator.index;
event[pos++] = indicator.status;
event[pos++] = indicator.min_range;
event[pos++] = indicator.max_range;
event[pos++] = indicator.mandatory;
event[pos++] = indicator.enabled;
event[pos++] = indicator.status_changed;
strncpy((char*)&event[pos], indicator.name, HFP_MAX_INDICATOR_DESC_SIZE);
pos += HFP_MAX_INDICATOR_DESC_SIZE;
event[pos] = 0;
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
static int has_call_waiting_and_3way_calling_feature(hfp_connection_t * hfp_connection){
int hf = get_bit(hfp_supported_features, HFP_HFSF_THREE_WAY_CALLING);
int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_THREE_WAY_CALLING);
return hf && ag;
}
static int has_hf_indicators_feature(hfp_connection_t * hfp_connection){
int hf = get_bit(hfp_supported_features, HFP_HFSF_HF_INDICATORS);
int ag = get_bit(hfp_connection->remote_supported_features, HFP_AGSF_HF_INDICATORS);
return hf && ag;
}
void hfp_hf_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint16_t supported_features, int wide_band_speech){
if (!name){
name = default_hfp_hf_service_name;
}
hfp_create_sdp_record(service, service_record_handle, BLUETOOTH_SERVICE_CLASS_HANDSFREE, rfcomm_channel_nr, name);
// Construct SupportedFeatures for SDP bitmap:
//
// "The values of the “SupportedFeatures” bitmap given in Table 5.4 shall be the same as the values
// of the Bits 0 to 4 of the unsolicited result code +BRSF"
//
// Wide band speech (bit 5) requires Codec negotiation
//
uint16_t sdp_features = supported_features & 0x1f;
if (wide_band_speech && (supported_features & (1 << HFP_HFSF_CODEC_NEGOTIATION))){
sdp_features |= 1 << 5;
}
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0311); // Hands-Free Profile - SupportedFeatures
de_add_number(service, DE_UINT, DE_SIZE_16, sdp_features);
static void hfp_emit_network_operator_event(btstack_packet_handler_t callback, hfp_network_opearator_t network_operator){
if (!callback) return;
uint8_t event[5+HFP_MAX_NETWORK_OPERATOR_NAME_SIZE+1];
event[0] = HCI_EVENT_HFP_META;
event[1] = sizeof(event) - 2;
event[2] = HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED;
event[3] = network_operator.mode;
event[4] = network_operator.format;
strncpy((char*)&event[5], network_operator.name, HFP_MAX_NETWORK_OPERATOR_NAME_SIZE);
event[5+HFP_MAX_NETWORK_OPERATOR_NAME_SIZE] = 0;
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
/* send commands */
static inline int hfp_hf_send_cmd(uint16_t cid, const char * cmd){
char buffer[20];
@ -358,38 +366,7 @@ static int hfp_hf_send_clcc(uint16_t cid){
return hfp_hf_send_cmd(cid, HFP_LIST_CURRENT_CALLS);
}
static void hfp_emit_ag_indicator_event(btstack_packet_handler_t callback, hfp_ag_indicator_t indicator){
if (!callback) return;
uint8_t event[10+HFP_MAX_INDICATOR_DESC_SIZE+1];
int pos = 0;
event[pos++] = HCI_EVENT_HFP_META;
event[pos++] = sizeof(event) - 2;
event[pos++] = HFP_SUBEVENT_AG_INDICATOR_STATUS_CHANGED;
event[pos++] = indicator.index;
event[pos++] = indicator.status;
event[pos++] = indicator.min_range;
event[pos++] = indicator.max_range;
event[pos++] = indicator.mandatory;
event[pos++] = indicator.enabled;
event[pos++] = indicator.status_changed;
strncpy((char*)&event[pos], indicator.name, HFP_MAX_INDICATOR_DESC_SIZE);
pos += HFP_MAX_INDICATOR_DESC_SIZE;
event[pos] = 0;
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
static void hfp_emit_network_operator_event(btstack_packet_handler_t callback, hfp_network_opearator_t network_operator){
if (!callback) return;
uint8_t event[5+HFP_MAX_NETWORK_OPERATOR_NAME_SIZE+1];
event[0] = HCI_EVENT_HFP_META;
event[1] = sizeof(event) - 2;
event[2] = HFP_SUBEVENT_NETWORK_OPERATOR_CHANGED;
event[3] = network_operator.mode;
event[4] = network_operator.format;
strncpy((char*)&event[5], network_operator.name, HFP_MAX_NETWORK_OPERATOR_NAME_SIZE);
event[5+HFP_MAX_NETWORK_OPERATOR_NAME_SIZE] = 0;
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
}
/* state machines */
static int hfp_hf_run_for_context_service_level_connection(hfp_connection_t * hfp_connection){
if (hfp_connection->state >= HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED) return 0;
@ -580,13 +557,12 @@ static int call_setup_state_machine(hfp_connection_t * hfp_connection){
}
static void hfp_run_for_context(hfp_connection_t * hfp_connection){
if (!hfp_connection) return;
if (!hfp_connection->rfcomm_cid) return;
if (hfp_connection->local_role != HFP_ROLE_HF) {
log_info("HFP HF%p, wrong role %u", hfp_connection, hfp_connection->local_role);
return;
}
btstack_assert(hfp_connection != NULL);
btstack_assert(hfp_connection->local_role == HFP_ROLE_HF);
// during SDP query, RFCOMM CID is not set
if (hfp_connection->rfcomm_cid == 0) return;
if (hfp_connection->hf_accept_sco && hci_can_send_command_packet_now()){
@ -998,10 +974,6 @@ static void hfp_hf_switch_on_ok(hfp_connection_t *hfp_connection){
hfp_connection->command = HFP_CMD_NONE;
}
static int hfp_parser_is_end_of_line(uint8_t byte){
return (byte == '\n') || (byte == '\r');
}
static void hfp_hf_handle_transfer_ag_indicator_status(hfp_connection_t * hfp_connection) {
uint16_t i;
for (i = 0; i < hfp_connection->ag_indicators_nr; i++){
@ -1107,6 +1079,10 @@ static void hfp_hf_handle_rfcomm_command(hfp_connection_t * hfp_connection){
}
}
static int hfp_parser_is_end_of_line(uint8_t byte){
return (byte == '\n') || (byte == '\r');
}
static void hfp_hf_handle_rfcomm_data(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
UNUSED(packet_type); // ok: only called with RFCOMM_DATA_PACKET
// assertion: size >= 1 as rfcomm.c does not deliver empty packets
@ -1760,3 +1736,33 @@ int hfp_hf_in_band_ringtone_active(hci_con_handle_t acl_handle){
}
return get_bit(hfp_connection->remote_supported_features, HFP_AGSF_IN_BAND_RING_TONE);
}
void hfp_hf_create_sdp_record(uint8_t * service, uint32_t service_record_handle, int rfcomm_channel_nr, const char * name, uint16_t supported_features, int wide_band_speech){
if (!name){
name = default_hfp_hf_service_name;
}
hfp_create_sdp_record(service, service_record_handle, BLUETOOTH_SERVICE_CLASS_HANDSFREE, rfcomm_channel_nr, name);
// Construct SupportedFeatures for SDP bitmap:
//
// "The values of the “SupportedFeatures” bitmap given in Table 5.4 shall be the same as the values
// of the Bits 0 to 4 of the unsolicited result code +BRSF"
//
// Wide band speech (bit 5) requires Codec negotiation
//
uint16_t sdp_features = supported_features & 0x1f;
if (wide_band_speech && (supported_features & (1 << HFP_HFSF_CODEC_NEGOTIATION))){
sdp_features |= 1 << 5;
}
de_add_number(service, DE_UINT, DE_SIZE_16, 0x0311); // Hands-Free Profile - SupportedFeatures
de_add_number(service, DE_UINT, DE_SIZE_16, sdp_features);
}
void hfp_hf_register_packet_handler(btstack_packet_handler_t callback){
if (callback == NULL){
log_error("hfp_hf_register_packet_handler called with NULL callback");
return;
}
hfp_hf_callback = callback;
hfp_set_hf_callback(callback);
}