static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){ if (packet_type != ATT_DATA_PACKET) return; // handle value indication confirms if (packet[0] == ATT_HANDLE_VALUE_CONFIRMATION && att_handle_value_indication_handle){ run_loop_remove_timer(&att_handle_value_indication_timer); uint16_t att_handle = att_handle_value_indication_handle; att_handle_value_indication_handle = 0; att_handle_value_indication_notify_client(0, att_connection.con_handle, att_handle); return; } // check size if (size > sizeof(att_request_buffer)) return; // last request still in processing? if (att_server_state != ATT_SERVER_IDLE) return; // store request att_server_state = ATT_SERVER_REQUEST_RECEIVED; att_request_size = size; memcpy(att_request_buffer, packet, size); att_run(); }
static void att_handle_value_indication_timeout(btstack_timer_source_t *ts){ void * context = btstack_run_loop_get_timer_context(ts); hci_con_handle_t con_handle = (hci_con_handle_t) (uintptr_t) context; att_server_t * att_server = att_server_for_handle(con_handle); if (!att_server) return; uint16_t att_handle = att_server->value_indication_handle; att_handle_value_indication_notify_client(ATT_HANDLE_VALUE_INDICATION_TIMEOUT, att_server->connection.con_handle, att_handle); }
static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){ if (packet_type != ATT_DATA_PACKET) return; // handle value indication confirms if (packet[0] == ATT_HANDLE_VALUE_CONFIRMATION && att_handle_value_indication_handle){ run_loop_remove_timer(&att_handle_value_indication_timer); uint16_t att_handle = att_handle_value_indication_handle; att_handle_value_indication_handle = 0; att_handle_value_indication_notify_client(0, att_connection.con_handle, att_handle); return; } // directly process commands // note: signed write cannot be handled directly as authentication needs to be verified if (packet[0] == ATT_WRITE_COMMAND){ att_handle_request(&att_connection, packet, size, 0); return; } // check size if (size > sizeof(att_request_buffer)) { log_info("att_packet_handler: dropping att pdu 0x%02x as size %u > att_request_buffer %u", packet[0], size, (int) sizeof(att_request_buffer)); return; } // last request still in processing? if (att_server_state != ATT_SERVER_IDLE){ log_info("att_packet_handler: skipping att pdu 0x%02x as server not idle (state %u)", packet[0], att_server_state); return; } // store request att_server_state = ATT_SERVER_REQUEST_RECEIVED; att_request_size = size; memcpy(att_request_buffer, packet, size); att_run(); }
static void att_handle_value_indication_timeout(timer_source_t *ts){ uint16_t att_handle = att_handle_value_indication_handle; att_handle_value_indication_notify_client(ATT_HANDLE_VALUE_INDICATION_TIMEOUT, att_connection.con_handle, att_handle); }
static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){ att_server_t * att_server; switch (packet_type){ case HCI_EVENT_PACKET: switch (packet[0]){ case L2CAP_EVENT_CAN_SEND_NOW: att_server_handle_can_send_now(); break; case ATT_EVENT_MTU_EXCHANGE_COMPLETE: // GATT client has negotiated the mtu for this connection att_server = att_server_for_handle(handle); if (!att_server) break; att_server->connection.mtu = little_endian_read_16(packet, 4); break; default: break; } break; case ATT_DATA_PACKET: log_debug("ATT Packet, handle 0x%04x", handle); att_server = att_server_for_handle(handle); if (!att_server) break; // handle value indication confirms if (packet[0] == ATT_HANDLE_VALUE_CONFIRMATION && att_server->value_indication_handle){ btstack_run_loop_remove_timer(&att_server->value_indication_timer); uint16_t att_handle = att_server->value_indication_handle; att_server->value_indication_handle = 0; att_handle_value_indication_notify_client(0, att_server->connection.con_handle, att_handle); return; } // directly process command // note: signed write cannot be handled directly as authentication needs to be verified if (packet[0] == ATT_WRITE_COMMAND){ att_handle_request(&att_server->connection, packet, size, 0); return; } // check size if (size > sizeof(att_server->request_buffer)) { log_info("att_packet_handler: dropping att pdu 0x%02x as size %u > att_server->request_buffer %u", packet[0], size, (int) sizeof(att_server->request_buffer)); return; } // last request still in processing? if (att_server->state != ATT_SERVER_IDLE){ log_info("att_packet_handler: skipping att pdu 0x%02x as server not idle (state %u)", packet[0], att_server->state); return; } // store request att_server->state = ATT_SERVER_REQUEST_RECEIVED; att_server->request_size = size; memcpy(att_server->request_buffer, packet, size); att_run_for_context(att_server); break; } }