mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-04-07 16:20:19 +00:00
re-wrote iterate over linked list and delete element code
This commit is contained in:
parent
3a35442530
commit
15ec09bb89
28
src/l2cap.c
28
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){
|
static void l2cap_handle_connection_failed_for_addr(bd_addr_t address, uint8_t status){
|
||||||
linked_item_t *it;
|
linked_item_t *it = (linked_item_t *) &l2cap_channels;
|
||||||
for (it = (linked_item_t *) l2cap_channels; it ; it = it->next){
|
while (it->next){
|
||||||
l2cap_channel_t * channel = (l2cap_channel_t *) it;
|
l2cap_channel_t * channel = (l2cap_channel_t *) it->next;
|
||||||
if ( ! BD_ADDR_CMP( channel->address, address) ){
|
if ( ! BD_ADDR_CMP( channel->address, address) ){
|
||||||
if (channel->state == L2CAP_STATE_CLOSED) {
|
if (channel->state == L2CAP_STATE_CLOSED) {
|
||||||
// failure, forward error code
|
// failure, forward error code
|
||||||
l2cap_emit_channel_opened(channel, status);
|
l2cap_emit_channel_opened(channel, status);
|
||||||
// discard channel
|
// discard channel
|
||||||
linked_list_remove(&l2cap_channels, (linked_item_t *) channel);
|
it->next = it->next->next;
|
||||||
free (channel);
|
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:
|
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||||
// send l2cap disconnect events for all channels on this handle
|
// send l2cap disconnect events for all channels on this handle
|
||||||
handle = READ_BT_16(packet, 3);
|
handle = READ_BT_16(packet, 3);
|
||||||
// only access next element to allows for removal
|
it = (linked_item_t *) &l2cap_channels;
|
||||||
for (it = (linked_item_t *) &l2cap_channels; it->next ; it = it->next){
|
while (it->next){
|
||||||
l2cap_channel_t * channel = (l2cap_channel_t *) it->next;
|
l2cap_channel_t * channel = (l2cap_channel_t *) it->next;
|
||||||
if ( channel->handle == handle ){
|
if ( channel->handle == handle ){
|
||||||
// update prev item before free'ing next element
|
// update prev item before free'ing next element - don't call l2cap_finalize_channel_close
|
||||||
it->next = it->next->next;
|
it->next->next = it->next;
|
||||||
l2cap_finialize_channel_close(channel);
|
l2cap_emit_channel_closed(channel);
|
||||||
|
free (channel);
|
||||||
|
} else {
|
||||||
|
it = it->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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){
|
void l2cap_finialize_channel_close(l2cap_channel_t *channel){
|
||||||
channel->state = L2CAP_STATE_CLOSED;
|
channel->state = L2CAP_STATE_CLOSED;
|
||||||
l2cap_emit_channel_closed(channel);
|
l2cap_emit_channel_closed(channel);
|
||||||
|
|
||||||
// discard channel
|
// discard channel
|
||||||
linked_list_remove(&l2cap_channels, (linked_item_t *) channel);
|
linked_list_remove(&l2cap_channels, (linked_item_t *) channel);
|
||||||
free (channel);
|
free (channel);
|
||||||
@ -830,7 +834,7 @@ void l2cap_close_connection(void *connection){
|
|||||||
|
|
||||||
// unregister services
|
// unregister services
|
||||||
it = (linked_item_t *) &l2cap_services;
|
it = (linked_item_t *) &l2cap_services;
|
||||||
while (it->next){
|
while (it->next) {
|
||||||
l2cap_service_t * service = (l2cap_service_t *) it->next;
|
l2cap_service_t * service = (l2cap_service_t *) it->next;
|
||||||
if (service->connection == connection){
|
if (service->connection == connection){
|
||||||
it->next = it->next->next;
|
it->next = it->next->next;
|
||||||
|
@ -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);
|
int bytes_read = read(ds->fd, &conn->buffer[conn->bytes_read], conn->bytes_to_read);
|
||||||
if (bytes_read <= 0){
|
if (bytes_read <= 0){
|
||||||
|
fprintf(stderr, "socket_connection_hci_process read bytes %d\n", bytes_read);
|
||||||
|
|
||||||
// connection broken (no particular channel, no date yet)
|
// connection broken (no particular channel, no date yet)
|
||||||
uint8_t event[1];
|
uint8_t event[1];
|
||||||
event[0] = DAEMON_EVENT_CONNECTION_CLOSED;
|
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_read += bytes_read;
|
||||||
conn->bytes_to_read -= bytes_read;
|
conn->bytes_to_read -= bytes_read;
|
||||||
// hexdump( conn->buffer, conn->bytes_read);
|
|
||||||
if (conn->bytes_to_read > 0) {
|
if (conn->bytes_to_read > 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -222,11 +224,9 @@ int socket_connection_hci_process(struct data_source *ds) {
|
|||||||
*/
|
*/
|
||||||
void socket_connection_retry_parked(){
|
void socket_connection_retry_parked(){
|
||||||
// log_dbg("socket_connection_hci_process retry parked\n");
|
// log_dbg("socket_connection_hci_process retry parked\n");
|
||||||
linked_item_t *next;
|
linked_item_t *it = (linked_item_t *) &parked;
|
||||||
linked_item_t *it;
|
wile (it->next) {
|
||||||
for (it = (linked_item_t *) parked; it ; it = next){
|
connection_t * conn = (connection_t *) it->next;
|
||||||
next = it->next; // cache pointer to next connection_t to allow for removal
|
|
||||||
connection_t * conn = (connection_t *) it;
|
|
||||||
|
|
||||||
// dispatch packet !!! connection, type, channel, data, size
|
// dispatch packet !!! connection, type, channel, data, size
|
||||||
log_dbg("socket_connection_hci_process retry parked #0\n");
|
log_dbg("socket_connection_hci_process retry parked #0\n");
|
||||||
@ -235,8 +235,10 @@ void socket_connection_retry_parked(){
|
|||||||
// "un-park" if successful
|
// "un-park" if successful
|
||||||
if (!dispatch_err) {
|
if (!dispatch_err) {
|
||||||
log_dbg("socket_connection_hci_process dispatch succeeded -> un-park connection\n");
|
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);
|
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
|
* 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){
|
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)];
|
uint8_t header[sizeof(packet_header_t)];
|
||||||
bt_store_16(header, 0, type);
|
bt_store_16(header, 0, type);
|
||||||
bt_store_16(header, 2, channel);
|
bt_store_16(header, 2, channel);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user