This commit is contained in:
Matthias Ringwald 2015-07-16 14:08:56 +02:00
commit 83ec85e25a
3 changed files with 43 additions and 31 deletions

View File

@ -64,7 +64,7 @@ static hfp_callback_t hfp_callback;
static linked_list_t hfp_connections = NULL;
int send_str_over_rfcomm(uint16_t cid, char * command){
if (!rfcomm_can_send_packet_now(cid)) return 1;
// if (!rfcomm_can_send_packet_now(cid)) return 1;
int err = rfcomm_send_internal(cid, (uint8_t*) command, strlen(command));
if (err){
printf("rfcomm_send_internal -> error 0X%02x", err);
@ -104,13 +104,13 @@ static void hfp_emit_event(hfp_callback_t callback, uint8_t event_subtype, uint8
}
static linked_item_t * get_hfp_connections(){
linked_item_t * hfp_get_connections(){
return (linked_item_t *) &hfp_connections;
}
hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid){
linked_item_t *it;
for (it = get_hfp_connections(); it ; it = it->next){
for (it = hfp_get_connections(); it ; it = it->next){
hfp_connection_t * connection = (hfp_connection_t *) it;
if (connection->rfcomm_cid == cid){
return connection;
@ -119,20 +119,9 @@ hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid){
return NULL;
}
static hfp_connection_t * get_hfp_connection_context_for_handle(uint16_t handle){
linked_item_t *it;
for (it = get_hfp_connections(); it ; it = it->next){
hfp_connection_t * connection = (hfp_connection_t *) it;
if (connection->con_handle == handle){
return connection;
}
}
return NULL;
}
static hfp_connection_t * get_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr){
linked_item_t *it;
for (it = get_hfp_connections(); it ; it = it->next){
for (it = hfp_get_connections(); it ; it = it->next){
hfp_connection_t * connection = (hfp_connection_t *) it;
if (memcmp(connection->remote_addr, bd_addr, 6) == 0) {
return connection;
@ -165,14 +154,15 @@ hfp_connection_t * provide_hfp_connection_context_for_bd_addr(bd_addr_t bd_addr)
return context;
}
hfp_connection_t * provide_hfp_connection_context_for_conn_handle(uint16_t con_handle){
hfp_connection_t * context = get_hfp_connection_context_for_handle(con_handle);
hfp_connection_t * provide_hfp_connection_context_for_rfcomm_cid(uint16_t rfcomm_cid){
hfp_connection_t * context = get_hfp_connection_context_for_rfcomm_cid(rfcomm_cid);
if (context) return context;
context = create_hfp_connection_context();
context->con_handle = con_handle;
context->rfcomm_cid = rfcomm_cid;
return context;
}
void hfp_register_packet_handler(hfp_callback_t callback){
if (callback == NULL){
log_error("hfp_register_packet_handler called with NULL callback");
@ -306,6 +296,7 @@ static void hfp_reset_state(hfp_connection_t * connection){
hfp_connection_t * hfp_handle_hci_event(uint8_t packet_type, uint8_t *packet, uint16_t size){
bd_addr_t event_addr;
hfp_connection_t * context = NULL;
@ -339,18 +330,20 @@ hfp_connection_t * hfp_handle_hci_event(uint8_t packet_type, uint8_t *packet, ui
case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE:
// data: event(8), len(8), status (8), address (48), handle(16), server channel(8), rfcomm_cid(16), max frame size(16)
printf("RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE packet_handler type %u, packet[0] %x\n", packet_type, packet[0]);
bt_flip_addr(event_addr, &packet[3]);
context = provide_hfp_connection_context_for_bd_addr(event_addr);
if (!context || context->state != HFP_W4_RFCOMM_CONNECTED) return context;
if (packet[2]) {
hfp_reset_state(context);
hfp_emit_event(context->callback, HFP_SUBEVENT_AUDIO_CONNECTION_COMPLETE, packet[2]);
// hfp_emit_event(context->callback, HFP_SUBEVENT_CONNECTION_COMPLETE, packet[2]);
} else {
context->con_handle = READ_BT_16(packet, 9);
context->rfcomm_cid = READ_BT_16(packet, 12);
// uint16_t mtu = READ_BT_16(packet, 14);
uint16_t mtu = READ_BT_16(packet, 14);
context->state = HFP_EXCHANGE_SUPPORTED_FEATURES;
printf("RFCOMM channel open succeeded. Context %p, RFCOMM Channel ID 0x%02x, max frame size %u\n", context, context->rfcomm_cid, mtu);
}
break;
case HCI_EVENT_DISCONNECTION_COMPLETE:
@ -358,6 +351,10 @@ hfp_connection_t * hfp_handle_hci_event(uint8_t packet_type, uint8_t *packet, ui
break;
case RFCOMM_EVENT_CHANNEL_CLOSED:
printf(" RFCOMM_EVENT_CHANNEL_CLOSED\n");
// hfp_emit_event(context->callback, HFP_SUBEVENT_DISCONNECTION_COMPLETE,0);
break;
case RFCOMM_EVENT_CREDITS:
context = provide_hfp_connection_context_for_rfcomm_cid(READ_BT_16(packet, 2));
break;
default:
break;

View File

@ -153,7 +153,8 @@ hfp_connection_t * hfp_handle_hci_event(uint8_t packet_type, uint8_t *packet, ui
void hfp_init(uint16_t rfcomm_channel_nr);
void hfp_connect(bd_addr_t bd_addr, uint16_t service_uuid);
hfp_connection_t * get_hfp_connection_context_for_rfcomm_cid(uint16_t cid);
hfp_connection_t * provide_hfp_connection_context_for_rfcomm_cid(uint16_t cid);
linked_item_t * hfp_get_connections();
// TODO: move to utils
int send_str_over_rfcomm(uint16_t cid, char * command);

View File

@ -168,9 +168,11 @@ int has_hf_indicators_feature(hfp_connection_t * connection){
return get_bit(hfp_supported_features,8) && get_bit(connection->remote_supported_features,10);
}
static void hfp_run(hfp_connection_t * connection){
static void hfp_run_for_context(hfp_connection_t * connection){
if (!connection) return;
if (!rfcomm_can_send_packet_now(connection->rfcomm_cid)) return;
int err = 0;
switch (connection->state){
case HFP_EXCHANGE_SUPPORTED_FEATURES:
@ -178,30 +180,38 @@ static void hfp_run(hfp_connection_t * connection){
err = hfp_hs_exchange_supported_features_cmd(connection->rfcomm_cid);
break;
case HFP_NOTIFY_ON_CODECS:
log_info("HFP_NOTIFY_ON_CODECS 0x%02x", connection->rfcomm_cid);
err = hfp_hs_retrieve_codec_cmd(connection->rfcomm_cid);
break;
case HFP_RETRIEVE_INDICATORS:
log_info("HFP_RETRIEVE_INDICATORS 0x%02x", connection->rfcomm_cid);
err = hfp_hs_retrieve_indicators_cmd(connection->rfcomm_cid);
break;
case HFP_RETRIEVE_INDICATORS_STATUS:
log_info("HFP_RETRIEVE_INDICATORS_STATUS 0x%02x", connection->rfcomm_cid);
err = hfp_hs_retrieve_indicators_cmd(connection->rfcomm_cid);
break;
case HFP_ENABLE_INDICATORS_STATUS_UPDATE:
err = 0;
if (connection->remote_indicators_update_enabled == 0){
log_info("HFP_ENABLE_INDICATORS_STATUS_UPDATE 0x%02x", connection->rfcomm_cid);
err = hfp_hs_toggle_indicator_status_update_cmd(connection->rfcomm_cid);
}
break;
case HFP_RETRIEVE_CAN_HOLD_CALL:
log_info("HFP_RETRIEVE_CAN_HOLD_CALL 0x%02x", connection->rfcomm_cid);
err = hfp_hs_retrieve_can_hold_call_cmd(connection->rfcomm_cid);
break;
case HFP_LIST_GENERIC_STATUS_INDICATORS:
log_info("HFP_LIST_GENERIC_STATUS_INDICATORS 0x%02x", connection->rfcomm_cid);
err = hfp_hs_list_supported_generic_status_indicators_cmd(connection->rfcomm_cid);
break;
case HFP_RETRIEVE_GENERIC_STATUS_INDICATORS:
log_info("HFP_RETRIEVE_GENERIC_STATUS_INDICATORS 0x%02x", connection->rfcomm_cid);
err = hfp_hs_retrieve_supported_generic_status_indicators_cmd(connection->rfcomm_cid);
break;
case HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS:
log_info("HFP_RETRIEVE_INITITAL_STATE_GENERIC_STATUS_INDICATORS 0x%02x", connection->rfcomm_cid);
err = hfp_hs_list_initital_supported_generic_status_indicators_cmd(connection->rfcomm_cid);
break;
default:
@ -210,7 +220,7 @@ static void hfp_run(hfp_connection_t * connection){
}
hfp_connection_t * hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
hfp_connection_t * context = get_hfp_connection_context_for_rfcomm_cid(channel);
hfp_connection_t * context = provide_hfp_connection_context_for_rfcomm_cid(channel);
int offset = 0;
if (!context) return NULL;
@ -218,7 +228,6 @@ hfp_connection_t * hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel
size--;
packet++;
}
printf("packet_handler packet size %u\n", size);
if (context->wait_ok){
if (strncmp((char *)packet, HFP_OK, strlen(HFP_OK)) == 0){
@ -351,21 +360,26 @@ hfp_connection_t * hfp_handle_rfcomm_event(uint8_t packet_type, uint16_t channel
return context;
}
static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
// printf("packet_handler type %u, packet[0] %x\n", packet_type, packet[0]);
hfp_connection_t * context = NULL;
static void hfp_run(){
linked_item_t *it;
for (it = hfp_get_connections(); it ; it = it->next){
hfp_connection_t * connection = (hfp_connection_t *) it;
hfp_run_for_context(connection);
}
}
static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
switch (packet_type){
case RFCOMM_DATA_PACKET:
context = hfp_handle_rfcomm_event(packet_type, channel, packet, size);
hfp_handle_rfcomm_event(packet_type, channel, packet, size);
break;
case HCI_EVENT_PACKET:
context = hfp_handle_hci_event(packet_type, packet, size);
hfp_handle_hci_event(packet_type, packet, size);
break;
default:
break;
}
hfp_run(context);
hfp_run();
}
void hfp_hf_init(uint16_t rfcomm_channel_nr, uint32_t supported_features, uint8_t * codecs, int codecs_nr, uint16_t * indicators, int indicators_nr, uint32_t indicators_status){