diff --git a/src/l2cap.c b/src/l2cap.c index fdfd24e96..717e71c16 100644 --- a/src/l2cap.c +++ b/src/l2cap.c @@ -276,17 +276,19 @@ void l2cap_disconnect_internal(uint16_t local_cid, uint8_t reason){ } static void l2cap_handle_connection_failed_for_addr(bd_addr_t address, uint8_t status){ - linked_item_t *it; - for (it = (linked_item_t *) l2cap_channels; it ; it = it->next){ - l2cap_channel_t * channel = (l2cap_channel_t *) it; + linked_item_t *it = (linked_item_t *) &l2cap_channels; + while (it->next){ + l2cap_channel_t * channel = (l2cap_channel_t *) it->next; if ( ! BD_ADDR_CMP( channel->address, address) ){ if (channel->state == L2CAP_STATE_CLOSED) { // failure, forward error code l2cap_emit_channel_opened(channel, status); // discard channel - linked_list_remove(&l2cap_channels, (linked_item_t *) channel); + it->next = it->next->next; free (channel); } + } else { + it = it->next; } } } @@ -343,13 +345,16 @@ void l2cap_event_handler( uint8_t *packet, uint16_t size ){ case HCI_EVENT_DISCONNECTION_COMPLETE: // send l2cap disconnect events for all channels on this handle handle = READ_BT_16(packet, 3); - // only access next element to allows for removal - for (it = (linked_item_t *) &l2cap_channels; it->next ; it = it->next){ + it = (linked_item_t *) &l2cap_channels; + while (it->next){ l2cap_channel_t * channel = (l2cap_channel_t *) it->next; if ( channel->handle == handle ){ - // update prev item before free'ing next element - it->next = it->next->next; - l2cap_finialize_channel_close(channel); + // update prev item before free'ing next element - don't call l2cap_finalize_channel_close + it->next->next = it->next; + l2cap_emit_channel_closed(channel); + free (channel); + } else { + it = it->next; } } break; @@ -764,11 +769,10 @@ static void l2cap_packet_handler(uint8_t packet_type, uint8_t *packet, uint16_t } } -// finalize closed channel +// finalize closed channel - l2cap_handle_disconnect_request & DISCONNECTION_RESPONSE void l2cap_finialize_channel_close(l2cap_channel_t *channel){ channel->state = L2CAP_STATE_CLOSED; l2cap_emit_channel_closed(channel); - // discard channel linked_list_remove(&l2cap_channels, (linked_item_t *) channel); free (channel); @@ -830,7 +834,7 @@ void l2cap_close_connection(void *connection){ // unregister services it = (linked_item_t *) &l2cap_services; - while (it->next){ + while (it->next) { l2cap_service_t * service = (l2cap_service_t *) it->next; if (service->connection == connection){ it->next = it->next->next; diff --git a/src/socket_connection.c b/src/socket_connection.c index 6324ce3cd..58763bba9 100644 --- a/src/socket_connection.c +++ b/src/socket_connection.c @@ -172,6 +172,8 @@ int socket_connection_hci_process(struct data_source *ds) { int bytes_read = read(ds->fd, &conn->buffer[conn->bytes_read], conn->bytes_to_read); if (bytes_read <= 0){ + fprintf(stderr, "socket_connection_hci_process read bytes %d\n", bytes_read); + // connection broken (no particular channel, no date yet) uint8_t event[1]; event[0] = DAEMON_EVENT_CONNECTION_CLOSED; @@ -185,7 +187,7 @@ int socket_connection_hci_process(struct data_source *ds) { } conn->bytes_read += bytes_read; conn->bytes_to_read -= bytes_read; - // hexdump( conn->buffer, conn->bytes_read); + if (conn->bytes_to_read > 0) { return 0; } @@ -222,11 +224,9 @@ int socket_connection_hci_process(struct data_source *ds) { */ void socket_connection_retry_parked(){ // log_dbg("socket_connection_hci_process retry parked\n"); - linked_item_t *next; - linked_item_t *it; - for (it = (linked_item_t *) parked; it ; it = next){ - next = it->next; // cache pointer to next connection_t to allow for removal - connection_t * conn = (connection_t *) it; + linked_item_t *it = (linked_item_t *) &parked; + wile (it->next) { + connection_t * conn = (connection_t *) it->next; // dispatch packet !!! connection, type, channel, data, size log_dbg("socket_connection_hci_process retry parked #0\n"); @@ -235,8 +235,10 @@ void socket_connection_retry_parked(){ // "un-park" if successful if (!dispatch_err) { log_dbg("socket_connection_hci_process dispatch succeeded -> un-park connection\n"); - linked_list_remove(&parked, it); + it->next = it->next->next; run_loop_add_data_source( (data_source_t *) conn); + } else { + it = it->next; } } } @@ -464,7 +466,6 @@ void socket_connection_register_packet_callback( int (*packet_callback)(connecti * send HCI packet to single connection */ void socket_connection_send_packet(connection_t *conn, uint16_t type, uint16_t channel, uint8_t *packet, uint16_t size){ - uint8_t header[sizeof(packet_header_t)]; bt_store_16(header, 0, type); bt_store_16(header, 2, channel);