/** * send HCI packet to all connections */ void socket_connection_send_packet_all(uint16_t type, uint16_t channel, uint8_t *packet, uint16_t size){ linked_item_t *next; linked_item_t *it; for (it = (linked_item_t *) connections; it ; it = next){ next = it->next; // cache pointer to next connection_t to allow for removal socket_connection_send_packet( (connection_t *) linked_item_get_user(it), type, channel, packet, size); } }
int socket_connection_hci_process(struct data_source *ds) { connection_t *conn = (connection_t *) ds; int bytes_read = read(ds->fd, &conn->buffer[conn->bytes_read], conn->bytes_to_read); if (bytes_read <= 0){ // connection broken (no particular channel, no date yet) socket_connection_emit_connection_closed(conn); // free connection socket_connection_free_connection(linked_item_get_user(&conn->item)); socket_connection_emit_nr_connections(); return 0; } 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; } int dispatch = 0; switch (conn->state){ case SOCKET_W4_HEADER: conn->state = SOCKET_W4_DATA; conn->bytes_to_read = READ_BT_16( conn->buffer, 4); if (conn->bytes_to_read == 0){ dispatch = 1; } break; case SOCKET_W4_DATA: dispatch = 1; break; default: break; } if (dispatch){ // dispatch packet !!! connection, type, channel, data, size int dispatch_err = (*socket_connection_packet_callback)(conn, READ_BT_16( conn->buffer, 0), READ_BT_16( conn->buffer, 2), &conn->buffer[sizeof(packet_header_t)], READ_BT_16( conn->buffer, 4)); // reset state machine socket_connection_init_statemachine(conn); // "park" if dispatch failed if (dispatch_err) { log_info("socket_connection_hci_process dispatch failed -> park connection\n"); run_loop_remove_data_source(ds); linked_list_add_tail(&parked, (linked_item_t *) ds); } } return 0; }
static void hci_connection_timeout_handler(timer_source_t *timer){ hci_connection_t * connection = (hci_connection_t *) linked_item_get_user(&timer->item); #ifdef HAVE_TIME struct timeval tv; gettimeofday(&tv, NULL); if (tv.tv_sec >= connection->timestamp.tv_sec + HCI_CONNECTION_TIMEOUT_MS/1000) { // connections might be timed out hci_emit_l2cap_check_timeout(connection); } #endif #ifdef HAVE_TICK if (embedded_get_ticks() > connection->timestamp + embedded_ticks_for_ms(HCI_CONNECTION_TIMEOUT_MS)){ // connections might be timed out hci_emit_l2cap_check_timeout(connection); } #endif run_loop_set_timer(timer, HCI_CONNECTION_TIMEOUT_MS); run_loop_add_timer(timer); }