mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-02-27 12:39:49 +00:00
hfp: allow to use ag and hf at the same time
This commit is contained in:
parent
323d300063
commit
ca59be5193
@ -99,13 +99,21 @@ static const char * hfp_ag_features[] = {
|
||||
|
||||
static btstack_linked_list_t hfp_connections = NULL;
|
||||
static void parse_sequence(hfp_connection_t * context);
|
||||
static btstack_packet_handler_t hfp_callback;
|
||||
static btstack_packet_handler_t rfcomm_packet_handler;
|
||||
|
||||
static btstack_packet_handler_t hfp_hf_callback;
|
||||
static btstack_packet_handler_t hfp_ag_callback;
|
||||
|
||||
static btstack_packet_handler_t hfp_hf_rfcomm_packet_handler;
|
||||
static btstack_packet_handler_t hfp_ag_rfcomm_packet_handler;
|
||||
|
||||
static hfp_connection_t * sco_establishment_active;
|
||||
|
||||
void hfp_set_callback(btstack_packet_handler_t callback){
|
||||
hfp_callback = callback;
|
||||
void hfp_set_hf_callback(btstack_packet_handler_t callback){
|
||||
hfp_hf_callback = callback;
|
||||
}
|
||||
|
||||
void hfp_set_ag_callback(btstack_packet_handler_t callback){
|
||||
hfp_ag_callback = callback;
|
||||
}
|
||||
|
||||
const char * hfp_hf_feature(int index){
|
||||
@ -200,27 +208,38 @@ int join_bitmap(char * buffer, int buffer_size, uint32_t values, int values_nr){
|
||||
return offset;
|
||||
}
|
||||
|
||||
void hfp_emit_simple_event(btstack_packet_handler_t callback, uint8_t event_subtype){
|
||||
if (!callback) return;
|
||||
static void hfp_emit_event_for_context(hfp_connection_t * hfp_connection, uint8_t * packet, uint16_t size){
|
||||
if (!hfp_connection) return;
|
||||
btstack_packet_handler_t callback = NULL;
|
||||
switch (hfp_connection->local_role){
|
||||
case HFP_ROLE_HF:
|
||||
callback = hfp_hf_callback;
|
||||
case HFP_ROLE_AG:
|
||||
callback = hfp_ag_callback;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
(*callback)(HCI_EVENT_PACKET, 0, packet, size);
|
||||
}
|
||||
|
||||
void hfp_emit_simple_event(hfp_connection_t * hfp_connection, uint8_t event_subtype){
|
||||
uint8_t event[3];
|
||||
event[0] = HCI_EVENT_HFP_META;
|
||||
event[1] = sizeof(event) - 2;
|
||||
event[2] = event_subtype;
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
|
||||
}
|
||||
|
||||
void hfp_emit_event(btstack_packet_handler_t callback, uint8_t event_subtype, uint8_t value){
|
||||
if (!callback) return;
|
||||
void hfp_emit_event(hfp_connection_t * hfp_connection, uint8_t event_subtype, uint8_t value){
|
||||
uint8_t event[4];
|
||||
event[0] = HCI_EVENT_HFP_META;
|
||||
event[1] = sizeof(event) - 2;
|
||||
event[2] = event_subtype;
|
||||
event[3] = value; // status 0 == OK
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
|
||||
}
|
||||
|
||||
void hfp_emit_slc_connection_event(btstack_packet_handler_t callback, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr){
|
||||
if (!callback) return;
|
||||
void hfp_emit_slc_connection_event(hfp_connection_t * hfp_connection, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr){
|
||||
uint8_t event[12];
|
||||
int pos = 0;
|
||||
event[pos++] = HCI_EVENT_HFP_META;
|
||||
@ -231,11 +250,10 @@ void hfp_emit_slc_connection_event(btstack_packet_handler_t callback, uint8_t st
|
||||
pos += 2;
|
||||
reverse_bd_addr(addr,&event[pos]);
|
||||
pos += 6;
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
|
||||
}
|
||||
|
||||
static void hfp_emit_sco_event(btstack_packet_handler_t callback, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr, uint8_t negotiated_codec){
|
||||
if (!callback) return;
|
||||
static void hfp_emit_sco_event(hfp_connection_t * hfp_connection, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr, uint8_t negotiated_codec){
|
||||
uint8_t event[13];
|
||||
int pos = 0;
|
||||
event[pos++] = HCI_EVENT_HFP_META;
|
||||
@ -247,11 +265,10 @@ static void hfp_emit_sco_event(btstack_packet_handler_t callback, uint8_t status
|
||||
reverse_bd_addr(addr,&event[pos]);
|
||||
pos += 6;
|
||||
event[pos++] = negotiated_codec;
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
|
||||
}
|
||||
|
||||
void hfp_emit_string_event(btstack_packet_handler_t callback, uint8_t event_subtype, const char * value){
|
||||
if (!callback) return;
|
||||
void hfp_emit_string_event(hfp_connection_t * hfp_connection, uint8_t event_subtype, const char * value){
|
||||
uint8_t event[40];
|
||||
event[0] = HCI_EVENT_HFP_META;
|
||||
event[1] = sizeof(event) - 2;
|
||||
@ -259,7 +276,7 @@ void hfp_emit_string_event(btstack_packet_handler_t callback, uint8_t event_subt
|
||||
int size = ( strlen(value) < sizeof(event) - 4) ? (int) strlen(value) : (int) sizeof(event) - 4;
|
||||
strncpy((char*)&event[3], value, size);
|
||||
event[3 + size] = 0;
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
hfp_emit_event_for_context(hfp_connection, event, sizeof(event));
|
||||
}
|
||||
|
||||
btstack_linked_list_t * hfp_get_connections(void){
|
||||
@ -479,11 +496,12 @@ static void handle_query_rfcomm_event(uint8_t packet_type, uint16_t channel, uin
|
||||
if (hfp_connection->rfcomm_channel_nr > 0){
|
||||
hfp_connection->state = HFP_W4_RFCOMM_CONNECTED;
|
||||
log_info("HFP: SDP_EVENT_QUERY_COMPLETE context %p, addr %s, state %d", hfp_connection, bd_addr_to_str( hfp_connection->remote_addr), hfp_connection->state);
|
||||
rfcomm_create_channel(rfcomm_packet_handler, hfp_connection->remote_addr, hfp_connection->rfcomm_channel_nr, NULL);
|
||||
btstack_packet_handler_t packet_handler = hfp_connection->local_role == HFP_ROLE_AG ? hfp_ag_rfcomm_packet_handler : hfp_hf_rfcomm_packet_handler;
|
||||
rfcomm_create_channel(packet_handler, hfp_connection->remote_addr, hfp_connection->rfcomm_channel_nr, NULL);
|
||||
break;
|
||||
}
|
||||
hfp_connection->state = HFP_IDLE;
|
||||
hfp_emit_slc_connection_event(hfp_callback, sdp_event_query_complete_get_status(packet), HCI_CON_HANDLE_INVALID, hfp_connection->remote_addr);
|
||||
hfp_emit_slc_connection_event(hfp_connection, sdp_event_query_complete_get_status(packet), HCI_CON_HANDLE_INVALID, hfp_connection->remote_addr);
|
||||
log_info("rfcomm service not found, status %u.", sdp_event_query_complete_get_status(packet));
|
||||
break;
|
||||
default:
|
||||
@ -592,7 +610,7 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
if (!hfp_connection || hfp_connection->state != HFP_W4_RFCOMM_CONNECTED) return;
|
||||
|
||||
if (status) {
|
||||
hfp_emit_slc_connection_event(hfp_callback, status, rfcomm_event_channel_opened_get_con_handle(packet), event_addr);
|
||||
hfp_emit_slc_connection_event(hfp_connection, status, rfcomm_event_channel_opened_get_con_handle(packet), event_addr);
|
||||
remove_hfp_connection_context(hfp_connection);
|
||||
} else {
|
||||
hfp_connection->acl_handle = rfcomm_event_channel_opened_get_con_handle(packet);
|
||||
@ -682,7 +700,7 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
hfp_connection->sco_handle = sco_handle;
|
||||
hfp_connection->establish_audio_connection = 0;
|
||||
hfp_connection->state = HFP_AUDIO_CONNECTION_ESTABLISHED;
|
||||
hfp_emit_sco_event(hfp_callback, packet[2], sco_handle, event_addr, hfp_connection->negotiated_codec);
|
||||
hfp_emit_sco_event(hfp_connection, packet[2], sco_handle, event_addr, hfp_connection->negotiated_codec);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -696,7 +714,7 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
break;
|
||||
}
|
||||
|
||||
hfp_emit_event(hfp_callback, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0);
|
||||
hfp_emit_event(hfp_connection, HFP_SUBEVENT_SERVICE_LEVEL_CONNECTION_RELEASED, 0);
|
||||
remove_hfp_connection_context(hfp_connection);
|
||||
break;
|
||||
|
||||
@ -716,7 +734,7 @@ void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet
|
||||
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);
|
||||
hfp_emit_event(hfp_connection, HFP_SUBEVENT_AUDIO_CONNECTION_RELEASED, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -1451,7 +1469,10 @@ void hfp_setup_synchronous_connection(hfp_connection_t * hfp_connection){
|
||||
sco_voice_setting, hfp_link_settings[setting].retransmission_effort, hfp_link_settings[setting].packet_types); // all types 0x003f, only 2-ev3 0x380
|
||||
}
|
||||
|
||||
void hfp_set_packet_handler_for_rfcomm_connections(btstack_packet_handler_t handler){
|
||||
rfcomm_packet_handler = handler;
|
||||
void hfp_set_ag_rfcomm_packet_handler(btstack_packet_handler_t handler){
|
||||
hfp_ag_rfcomm_packet_handler = handler;
|
||||
}
|
||||
void hfp_set_hf_rfcomm_packet_handler(btstack_packet_handler_t handler){
|
||||
hfp_hf_rfcomm_packet_handler = handler;
|
||||
}
|
||||
|
||||
|
@ -641,16 +641,18 @@ int get_bit(uint16_t bitmap, int position);
|
||||
int store_bit(uint32_t bitmap, int position, uint8_t value);
|
||||
// UTILS_END
|
||||
|
||||
void hfp_set_callback(btstack_packet_handler_t callback);
|
||||
void hfp_set_ag_callback(btstack_packet_handler_t callback);
|
||||
void hfp_set_ag_rfcomm_packet_handler(btstack_packet_handler_t handler);
|
||||
|
||||
void hfp_set_packet_handler_for_rfcomm_connections(btstack_packet_handler_t handler);
|
||||
void hfp_set_hf_callback(btstack_packet_handler_t callback);
|
||||
void hfp_set_hf_rfcomm_packet_handler(btstack_packet_handler_t handler);
|
||||
|
||||
void hfp_create_sdp_record(uint8_t * service, uint32_t service_record_handle, uint16_t service_uuid, int rfcomm_channel_nr, const char * name);
|
||||
void hfp_handle_hci_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size, hfp_role_t local_role);
|
||||
void hfp_emit_event(btstack_packet_handler_t callback, uint8_t event_subtype, uint8_t value);
|
||||
void hfp_emit_simple_event(btstack_packet_handler_t callback, uint8_t event_subtype);
|
||||
void hfp_emit_string_event(btstack_packet_handler_t callback, uint8_t event_subtype, const char * value);
|
||||
void hfp_emit_slc_connection_event(btstack_packet_handler_t callback, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr);
|
||||
void hfp_emit_event(hfp_connection_t * hfp_connection, uint8_t event_subtype, uint8_t value);
|
||||
void hfp_emit_simple_event(hfp_connection_t * hfp_connection, uint8_t event_subtype);
|
||||
void hfp_emit_string_event(hfp_connection_t * hfp_connection, uint8_t event_subtype, const char * value);
|
||||
void hfp_emit_slc_connection_event(hfp_connection_t * hfp_connection, uint8_t status, hci_con_handle_t con_handle, bd_addr_t addr);
|
||||
|
||||
hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid);
|
||||
hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr);
|
||||
|
@ -98,7 +98,7 @@ static hfp_generic_status_indicator_t hfp_generic_status_indicators[HFP_MAX_NUM_
|
||||
|
||||
static int hfp_ag_call_hold_services_nr = 0;
|
||||
static char *hfp_ag_call_hold_services[6];
|
||||
static btstack_packet_handler_t hfp_callback;
|
||||
static btstack_packet_handler_t hfp_ag_callback;
|
||||
|
||||
static hfp_response_and_hold_state_t hfp_ag_response_and_hold_state;
|
||||
static int hfp_ag_response_and_hold_active = 0;
|
||||
@ -154,8 +154,8 @@ void hfp_ag_register_packet_handler(btstack_packet_handler_t callback){
|
||||
log_error("hfp_ag_register_packet_handler called with NULL callback");
|
||||
return;
|
||||
}
|
||||
hfp_callback = callback;
|
||||
hfp_set_callback(callback);
|
||||
hfp_ag_callback = callback;
|
||||
hfp_set_ag_callback(callback);
|
||||
}
|
||||
|
||||
static int use_in_band_tone(void){
|
||||
@ -599,7 +599,7 @@ static int codecs_exchange_state_machine(hfp_connection_t * hfp_connection){
|
||||
|
||||
static void hfp_ag_slc_established(hfp_connection_t * hfp_connection){
|
||||
hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
|
||||
hfp_emit_slc_connection_event(hfp_callback, 0, hfp_connection->acl_handle, hfp_connection->remote_addr);
|
||||
hfp_emit_slc_connection_event(hfp_connection, 0, hfp_connection->acl_handle, hfp_connection->remote_addr);
|
||||
|
||||
// if active call exist, set per-hfp_connection state active, too (when audio is on)
|
||||
if (hfp_gsm_call_status() == HFP_CALL_STATUS_ACTIVE_OR_HELD_CALL_IS_PRESENT){
|
||||
@ -850,7 +850,7 @@ static void hfp_ag_hf_start_ringing(hfp_connection_t * hfp_connection){
|
||||
hfp_connection->ag_ring = 1;
|
||||
hfp_connection->ag_send_clip = hfp_gsm_clip_type() && hfp_connection->clip_enabled;
|
||||
hfp_connection->call_state = HFP_CALL_RINGING;
|
||||
hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_START_RINGINIG);
|
||||
hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_START_RINGINIG);
|
||||
}
|
||||
}
|
||||
|
||||
@ -858,7 +858,7 @@ static void hfp_ag_hf_stop_ringing(hfp_connection_t * hfp_connection){
|
||||
hfp_connection->ag_ring = 0;
|
||||
hfp_connection->ag_send_clip = 0;
|
||||
hfp_timeout_stop(hfp_connection);
|
||||
hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_STOP_RINGINIG);
|
||||
hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_STOP_RINGINIG);
|
||||
}
|
||||
|
||||
static void hfp_ag_trigger_incoming_call(void){
|
||||
@ -993,6 +993,15 @@ 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");
|
||||
|
||||
@ -1007,7 +1016,7 @@ static void hfp_ag_trigger_terminate_call(void){
|
||||
hfp_connection->release_audio_connection = 1;
|
||||
hfp_run_for_context(hfp_connection);
|
||||
}
|
||||
hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_CALL_TERMINATED);
|
||||
hfp_ag_emit_simple_event(HFP_SUBEVENT_CALL_TERMINATED);
|
||||
}
|
||||
|
||||
static void hfp_ag_set_callsetup_indicator(void){
|
||||
@ -1078,7 +1087,7 @@ static int call_setup_state_machine(hfp_connection_t * hfp_connection){
|
||||
hfp_connection->ag_send_clip = hfp_gsm_clip_type() && hfp_connection->clip_enabled;
|
||||
hfp_connection->call_state = HFP_CALL_RINGING;
|
||||
hfp_connection->call_state = HFP_CALL_RINGING;
|
||||
hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_START_RINGINIG);
|
||||
hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_START_RINGINIG);
|
||||
break;
|
||||
case HFP_CALL_W4_AUDIO_CONNECTION_FOR_ACTIVE:
|
||||
if (hfp_connection->state != HFP_AUDIO_CONNECTION_ESTABLISHED) return 0;
|
||||
@ -1174,7 +1183,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con
|
||||
hfp_gsm_handle_event(HFP_AG_HELD_CALL_JOINED_BY_AG);
|
||||
hfp_ag_set_callheld_indicator();
|
||||
hfp_ag_transfer_callheld_state();
|
||||
hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_CONFERENCE_CALL);
|
||||
hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_CONFERENCE_CALL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1195,7 +1204,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con
|
||||
hfp_ag_set_call_indicator();
|
||||
hfp_ag_hf_accept_call(hfp_connection);
|
||||
log_info("HF answers call, accept call by GSM");
|
||||
hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_CALL_ANSWERED);
|
||||
hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_CALL_ANSWERED);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1383,7 +1392,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con
|
||||
|
||||
hfp_connection->call_state = HFP_CALL_OUTGOING_INITIATED;
|
||||
|
||||
hfp_emit_string_event(hfp_callback, HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER, (const char *) &hfp_connection->line_buffer[3]);
|
||||
hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER, (const char *) &hfp_connection->line_buffer[3]);
|
||||
break;
|
||||
|
||||
case HFP_AG_OUTGOING_REDIAL_INITIATED:{
|
||||
@ -1402,7 +1411,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con
|
||||
|
||||
if (strlen(last_dialed_number) > 0){
|
||||
log_info("Last number exists: accept call");
|
||||
hfp_emit_string_event(hfp_callback, HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER, last_dialed_number);
|
||||
hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_PLACE_CALL_WITH_NUMBER, last_dialed_number);
|
||||
} else {
|
||||
log_info("log_infoLast number missing: reject call");
|
||||
hfp_ag_outgoing_call_rejected();
|
||||
@ -1552,7 +1561,7 @@ static void hfp_ag_call_sm(hfp_ag_call_event_t event, hfp_connection_t * hfp_con
|
||||
hfp_gsm_handle_event(HFP_AG_CALL_HOLD_ADD_HELD_CALL);
|
||||
hfp_ag_set_callheld_indicator();
|
||||
hfp_connection->ag_indicators_status_update_bitmap = store_bit(hfp_connection->ag_indicators_status_update_bitmap, callheld_indicator_index, 1);
|
||||
hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_CONFERENCE_CALL);
|
||||
hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_CONFERENCE_CALL);
|
||||
}
|
||||
hfp_connection->call_state = HFP_CALL_ACTIVE;
|
||||
break;
|
||||
@ -1886,11 +1895,11 @@ static void hfp_handle_rfcomm_data(uint8_t packet_type, uint16_t channel, uint8_
|
||||
break;
|
||||
case HFP_CMD_TRANSMIT_DTMF_CODES:
|
||||
hfp_connection->command = HFP_CMD_NONE;
|
||||
hfp_emit_string_event(hfp_callback, HFP_SUBEVENT_TRANSMIT_DTMF_CODES, (const char *) &hfp_connection->line_buffer[0]);
|
||||
hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_TRANSMIT_DTMF_CODES, (const char *) &hfp_connection->line_buffer[0]);
|
||||
break;
|
||||
case HFP_CMD_HF_REQUEST_PHONE_NUMBER:
|
||||
hfp_connection->command = HFP_CMD_NONE;
|
||||
hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG);
|
||||
hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_ATTACH_NUMBER_TO_VOICE_TAG);
|
||||
break;
|
||||
case HFP_CMD_TURN_OFF_EC_AND_NR:
|
||||
hfp_connection->command = HFP_CMD_NONE;
|
||||
@ -2062,7 +2071,7 @@ void hfp_ag_init(uint16_t rfcomm_channel_nr){
|
||||
subscriber_numbers = NULL;
|
||||
subscriber_numbers_count = 0;
|
||||
|
||||
hfp_set_packet_handler_for_rfcomm_connections(&packet_handler);
|
||||
hfp_set_ag_rfcomm_packet_handler(&packet_handler);
|
||||
|
||||
hfp_gsm_init();
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ static uint32_t hfp_indicators_value[HFP_MAX_NUM_HF_INDICATORS];
|
||||
static uint8_t hfp_hf_speaker_gain = 9;
|
||||
static uint8_t hfp_hf_microphone_gain = 9;
|
||||
|
||||
static btstack_packet_handler_t hfp_callback;
|
||||
static btstack_packet_handler_t hfp_hf_callback;
|
||||
|
||||
static hfp_call_status_t hfp_call_status;
|
||||
static hfp_callsetup_status_t hfp_callsetup_status;
|
||||
@ -88,13 +88,12 @@ static char phone_number[25];
|
||||
static btstack_packet_callback_registration_t hci_event_callback_registration;
|
||||
|
||||
void hfp_hf_register_packet_handler(btstack_packet_handler_t callback){
|
||||
hfp_callback = callback;
|
||||
if (callback == NULL){
|
||||
log_error("hfp_hf_register_packet_handler called with NULL callback");
|
||||
return;
|
||||
}
|
||||
hfp_callback = callback;
|
||||
hfp_set_callback(callback);
|
||||
hfp_hf_callback = callback;
|
||||
hfp_set_hf_callback(callback);
|
||||
}
|
||||
|
||||
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){
|
||||
@ -834,15 +833,15 @@ static void hfp_run_for_context(hfp_connection_t * hfp_connection){
|
||||
static void hfp_ag_slc_established(hfp_connection_t * hfp_connection){
|
||||
hfp_connection->state = HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED;
|
||||
|
||||
hfp_emit_slc_connection_event(hfp_callback, 0, hfp_connection->acl_handle, hfp_connection->remote_addr);
|
||||
hfp_emit_slc_connection_event(hfp_connection, 0, hfp_connection->acl_handle, hfp_connection->remote_addr);
|
||||
|
||||
// restore volume settings
|
||||
hfp_connection->speaker_gain = hfp_hf_speaker_gain;
|
||||
hfp_connection->send_speaker_gain = 1;
|
||||
hfp_emit_event(hfp_callback, HFP_SUBEVENT_SPEAKER_VOLUME, hfp_hf_speaker_gain);
|
||||
hfp_emit_event(hfp_connection, HFP_SUBEVENT_SPEAKER_VOLUME, hfp_hf_speaker_gain);
|
||||
hfp_connection->microphone_gain = hfp_hf_microphone_gain;
|
||||
hfp_connection->send_microphone_gain = 1;
|
||||
hfp_emit_event(hfp_callback, HFP_SUBEVENT_MICROPHONE_VOLUME, hfp_hf_microphone_gain);
|
||||
hfp_emit_event(hfp_connection, HFP_SUBEVENT_MICROPHONE_VOLUME, hfp_hf_microphone_gain);
|
||||
// enable all indicators
|
||||
int i;
|
||||
for (i=0;i<hfp_indicators_nr;i++){
|
||||
@ -908,13 +907,13 @@ static void hfp_hf_switch_on_ok(hfp_connection_t *hfp_connection){
|
||||
case HFP_SERVICE_LEVEL_CONNECTION_ESTABLISHED:
|
||||
if (hfp_connection->enable_status_update_for_ag_indicators != 0xFF){
|
||||
hfp_connection->enable_status_update_for_ag_indicators = 0xFF;
|
||||
hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0);
|
||||
hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (hfp_connection->change_status_update_for_individual_ag_indicators == 1){
|
||||
hfp_connection->change_status_update_for_individual_ag_indicators = 0;
|
||||
hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 0);
|
||||
hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -925,7 +924,7 @@ static void hfp_hf_switch_on_ok(hfp_connection_t *hfp_connection){
|
||||
break;
|
||||
case HPF_HF_QUERY_OPERATOR_W4_RESULT:
|
||||
hfp_connection->hf_query_operator_state = HFP_HF_QUERY_OPERATOR_FORMAT_SET;
|
||||
hfp_emit_network_operator_event(hfp_callback, hfp_connection->network_operator);
|
||||
hfp_emit_network_operator_event(hfp_hf_callback, hfp_connection->network_operator);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -981,19 +980,19 @@ static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8
|
||||
case HFP_CMD_GET_SUBSCRIBER_NUMBER_INFORMATION:
|
||||
hfp_connection->command = HFP_CMD_NONE;
|
||||
// printf("Subscriber Number: number %s, type %u\n", hfp_connection->bnip_number, hfp_connection->bnip_type);
|
||||
hfp_hf_emit_subscriber_information(hfp_callback, HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION, 0, hfp_connection->bnip_type, hfp_connection->bnip_number);
|
||||
hfp_hf_emit_subscriber_information(hfp_hf_callback, HFP_SUBEVENT_SUBSCRIBER_NUMBER_INFORMATION, 0, hfp_connection->bnip_type, hfp_connection->bnip_number);
|
||||
break;
|
||||
case HFP_CMD_RESPONSE_AND_HOLD_STATUS:
|
||||
hfp_connection->command = HFP_CMD_NONE;
|
||||
// printf("Response and Hold status: %s\n", hfp_connection->line_buffer);
|
||||
hfp_emit_event(hfp_callback, HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS, btstack_atoi((char *)&hfp_connection->line_buffer[0]));
|
||||
hfp_emit_event(hfp_connection, HFP_SUBEVENT_RESPONSE_AND_HOLD_STATUS, btstack_atoi((char *)&hfp_connection->line_buffer[0]));
|
||||
break;
|
||||
case HFP_CMD_LIST_CURRENT_CALLS:
|
||||
hfp_connection->command = HFP_CMD_NONE;
|
||||
// printf("Enhanced Call Status: idx %u, dir %u, status %u, mpty %u, number %s, type %u\n",
|
||||
// hfp_connection->clcc_idx, hfp_connection->clcc_dir, hfp_connection->clcc_status, hfp_connection->clcc_mpty,
|
||||
// hfp_connection->bnip_number, hfp_connection->bnip_type);
|
||||
hfp_hf_emit_enhanced_call_status(hfp_callback, hfp_connection->clcc_idx,
|
||||
hfp_hf_emit_enhanced_call_status(hfp_hf_callback, hfp_connection->clcc_idx,
|
||||
hfp_connection->clcc_dir, hfp_connection->clcc_status, hfp_connection->clcc_mpty,
|
||||
hfp_connection->bnip_type, hfp_connection->bnip_number);
|
||||
break;
|
||||
@ -1001,43 +1000,43 @@ static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8
|
||||
hfp_connection->command = HFP_CMD_NONE;
|
||||
value = btstack_atoi((char*)hfp_connection->line_buffer);
|
||||
hfp_hf_speaker_gain = value;
|
||||
hfp_emit_event(hfp_callback, HFP_SUBEVENT_SPEAKER_VOLUME, value);
|
||||
hfp_emit_event(hfp_connection, HFP_SUBEVENT_SPEAKER_VOLUME, value);
|
||||
break;
|
||||
case HFP_CMD_SET_MICROPHONE_GAIN:
|
||||
hfp_connection->command = HFP_CMD_NONE;
|
||||
value = btstack_atoi((char*)hfp_connection->line_buffer);
|
||||
hfp_hf_microphone_gain = value;
|
||||
hfp_emit_event(hfp_callback, HFP_SUBEVENT_MICROPHONE_VOLUME, value);
|
||||
hfp_emit_event(hfp_connection, HFP_SUBEVENT_MICROPHONE_VOLUME, value);
|
||||
break;
|
||||
case HFP_CMD_AG_SENT_PHONE_NUMBER:
|
||||
hfp_connection->command = HFP_CMD_NONE;
|
||||
hfp_emit_string_event(hfp_callback, HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG, hfp_connection->bnip_number);
|
||||
hfp_emit_string_event(hfp_connection, HFP_SUBEVENT_NUMBER_FOR_VOICE_TAG, hfp_connection->bnip_number);
|
||||
break;
|
||||
case HFP_CMD_AG_SENT_CALL_WAITING_NOTIFICATION_UPDATE:
|
||||
hfp_connection->command = HFP_CMD_NONE;
|
||||
hfp_hf_emit_type_and_number(hfp_callback, HFP_SUBEVENT_CALL_WAITING_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number);
|
||||
hfp_hf_emit_type_and_number(hfp_hf_callback, HFP_SUBEVENT_CALL_WAITING_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number);
|
||||
break;
|
||||
case HFP_CMD_AG_SENT_CLIP_INFORMATION:
|
||||
hfp_connection->command = HFP_CMD_NONE;
|
||||
hfp_hf_emit_type_and_number(hfp_callback, HFP_SUBEVENT_CALLING_LINE_IDENTIFICATION_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number);
|
||||
hfp_hf_emit_type_and_number(hfp_hf_callback, HFP_SUBEVENT_CALLING_LINE_IDENTIFICATION_NOTIFICATION, hfp_connection->bnip_type, hfp_connection->bnip_number);
|
||||
break;
|
||||
case HFP_CMD_EXTENDED_AUDIO_GATEWAY_ERROR:
|
||||
hfp_connection->ok_pending = 0;
|
||||
hfp_connection->command = HFP_CMD_NONE;
|
||||
hfp_connection->extended_audio_gateway_error = 0;
|
||||
hfp_emit_event(hfp_callback, HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR, hfp_connection->extended_audio_gateway_error_value);
|
||||
hfp_emit_event(hfp_connection, HFP_SUBEVENT_EXTENDED_AUDIO_GATEWAY_ERROR, hfp_connection->extended_audio_gateway_error_value);
|
||||
break;
|
||||
case HFP_CMD_ERROR:
|
||||
hfp_connection->ok_pending = 0;
|
||||
hfp_reset_context_flags(hfp_connection);
|
||||
hfp_connection->command = HFP_CMD_NONE;
|
||||
hfp_emit_event(hfp_callback, HFP_SUBEVENT_COMPLETE, 1);
|
||||
hfp_emit_event(hfp_connection, HFP_SUBEVENT_COMPLETE, 1);
|
||||
break;
|
||||
case HFP_CMD_OK:
|
||||
hfp_hf_switch_on_ok(hfp_connection);
|
||||
break;
|
||||
case HFP_CMD_RING:
|
||||
hfp_emit_simple_event(hfp_callback, HFP_SUBEVENT_RING);
|
||||
hfp_emit_simple_event(hfp_connection, HFP_SUBEVENT_RING);
|
||||
break;
|
||||
case HFP_CMD_TRANSFER_AG_INDICATOR_STATUS:
|
||||
for (i = 0; i < hfp_connection->ag_indicators_nr; i++){
|
||||
@ -1052,7 +1051,7 @@ static void hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8
|
||||
hfp_call_status = (hfp_call_status_t) hfp_connection->ag_indicators[i].status;
|
||||
}
|
||||
hfp_connection->ag_indicators[i].status_changed = 0;
|
||||
hfp_emit_ag_indicator_event(hfp_callback, hfp_connection->ag_indicators[i]);
|
||||
hfp_emit_ag_indicator_event(hfp_hf_callback, hfp_connection->ag_indicators[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1093,7 +1092,7 @@ void hfp_hf_init(uint16_t rfcomm_channel_nr){
|
||||
|
||||
rfcomm_register_service(packet_handler, rfcomm_channel_nr, 0xffff);
|
||||
|
||||
hfp_set_packet_handler_for_rfcomm_connections(&packet_handler);
|
||||
hfp_set_hf_rfcomm_packet_handler(&packet_handler);
|
||||
|
||||
hfp_supported_features = HFP_DEFAULT_HF_SUPPORTED_FEATURES;
|
||||
hfp_codecs_nr = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user