connection failure for RFCOMM L2CAP channel now results in rfcomm channel open errors and removal of prepared channels and multiplexer

This commit is contained in:
matthias.ringwald 2012-07-30 14:39:29 +00:00
parent d4d72cf99a
commit aac3545b0e

View File

@ -347,7 +347,7 @@ static void rfcomm_channel_initialize(rfcomm_channel_t *channel, rfcomm_multiple
static rfcomm_channel_t * rfcomm_channel_create(rfcomm_multiplexer_t * multiplexer,
rfcomm_service_t * service, uint8_t server_channel){
log_info("rfcomm_channel_create for service %p, channel %u --- begin\n", service, server_channel);
log_info("rfcomm_channel_create for service %p, channel %u --- list of channels:\n", service, server_channel);
rfcomm_dump_channels();
// alloc structure
@ -580,14 +580,21 @@ static void rfcomm_send_uih_credits(rfcomm_multiplexer_t *multiplexer, uint8_t d
}
// MARK: RFCOMM MULTIPLEXER
static void rfcomm_multiplexer_finalize(rfcomm_multiplexer_t * multiplexer){
// remove (potential) timer
static void rfcomm_multiplexer_stop_timer(rfcomm_multiplexer_t * multiplexer){
if (multiplexer->timer_active) {
run_loop_remove_timer(&multiplexer->timer);
multiplexer->timer_active = 0;
}
}
static void rfcomm_multiplexer_free(rfcomm_multiplexer_t * multiplexer){
linked_list_remove( &rfcomm_multiplexers, (linked_item_t *) multiplexer);
btstack_memory_rfcomm_multiplexer_free(multiplexer);
}
static void rfcomm_multiplexer_finalize(rfcomm_multiplexer_t * multiplexer){
// remove (potential) timer
rfcomm_multiplexer_stop_timer(multiplexer);
// close and remove all channels
linked_item_t *it = (linked_item_t *) &rfcomm_channels;
@ -613,8 +620,7 @@ static void rfcomm_multiplexer_finalize(rfcomm_multiplexer_t * multiplexer){
uint16_t l2cap_cid = multiplexer->l2cap_cid;
// remove mutliplexer
linked_list_remove( &rfcomm_multiplexers, (linked_item_t *) multiplexer);
btstack_memory_rfcomm_multiplexer_free(multiplexer);
rfcomm_multiplexer_free(multiplexer);
// close l2cap multiplexer channel, too
l2cap_disconnect_internal(l2cap_cid, 0x13);
@ -671,6 +677,8 @@ static int rfcomm_multiplexer_hci_event_handler(uint8_t *packet, uint16_t size){
uint16_t l2cap_cid;
hci_con_handle_t con_handle;
rfcomm_multiplexer_t *multiplexer = NULL;
uint8_t status;
switch (packet[0]) {
// accept incoming PSM_RFCOMM connection if no multiplexer exists yet
@ -709,8 +717,12 @@ static int rfcomm_multiplexer_hci_event_handler(uint8_t *packet, uint16_t size){
// l2cap connection opened -> store l2cap_cid, remote_addr
case L2CAP_EVENT_CHANNEL_OPENED:
if (READ_BT_16(packet, 11) != PSM_RFCOMM) break;
log_info("L2CAP_EVENT_CHANNEL_OPENED for PSM_RFCOMM\n");
status = packet[2];
log_info("L2CAP_EVENT_CHANNEL_OPENED for PSM_RFCOMM, status %u\n", status);
// get multiplexer for remote addr
con_handle = READ_BT_16(packet, 9);
l2cap_cid = READ_BT_16(packet, 13);
@ -720,6 +732,31 @@ static int rfcomm_multiplexer_hci_event_handler(uint8_t *packet, uint16_t size){
log_error("L2CAP_EVENT_CHANNEL_OPENED but no multiplexer prepared\n");
return 1;
}
// on l2cap open error discard everything
if (status){
// remove (potential) timer
rfcomm_multiplexer_stop_timer(multiplexer);
// emit rfcomm_channel_opened with status and free channel
linked_item_t * it = (linked_item_t *) &rfcomm_channels;
while (it->next) {
rfcomm_channel_t * channel = (rfcomm_channel_t *) it->next;
if (channel->multiplexer == multiplexer){
rfcomm_emit_channel_opened(channel, status);
it->next = it->next->next;
btstack_memory_rfcomm_channel_free(channel);
} else {
it = it->next;
}
}
// free multiplexer
rfcomm_multiplexer_free(multiplexer);
return 1;
}
if (multiplexer->state == RFCOMM_MULTIPLEXER_W4_CONNECT) {
log_info("L2CAP_EVENT_CHANNEL_OPENED: outgoing connection\n");
// wrong remote addr