att_dispatch: Propogate MTU update to both att_server and gatt_client.

According to the BT 5.0 spec. A MTU negotiation shall only be required in one
direction. I.e. We must propogate the negotiated MTU between gatt_client
and att_server.
This commit is contained in:
Jakob Krantz 2018-01-16 12:01:19 +01:00 committed by Matthias Ringwald
parent 25818320b7
commit b12646c53b
4 changed files with 47 additions and 0 deletions

View File

@ -140,3 +140,23 @@ void att_dispatch_server_request_can_send_now_event(hci_con_handle_t con_handle)
att_server_waiting_for_can_send = 1;
l2cap_request_can_send_fix_channel_now_event(con_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL);
}
void att_dispatch_server_mtu_exchanged(hci_con_handle_t con_handle, uint16_t new_mtu){
if (!att_client_handler) return;
uint8_t packet[6];
packet[0] = ATT_EVENT_MTU_EXCHANGE_COMPLETE;
packet[1] = sizeof(packet) - 2;
little_endian_store_16(packet, 2, con_handle);
little_endian_store_16(packet, 4, new_mtu);
att_client_handler(ATT_DATA_PACKET, con_handle, packet, 1);
}
void att_dispatch_client_mtu_exchanged(hci_con_handle_t con_handle, uint16_t new_mtu){
if (!att_server_handler) return;
uint8_t packet[6];
packet[0] = ATT_EVENT_MTU_EXCHANGE_COMPLETE;
packet[1] = sizeof(packet) - 2;
little_endian_store_16(packet, 2, con_handle);
little_endian_store_16(packet, 4, new_mtu);
att_server_handler(ATT_DATA_PACKET, con_handle, packet, 1);
}

View File

@ -89,6 +89,20 @@ void att_dispatch_client_request_can_send_now_event(hci_con_handle_t con_handle)
*/
void att_dispatch_server_request_can_send_now_event(hci_con_handle_t con_handle);
/**
* @brief Used for propogating a updated MTU from att_server to gatt_client
* @param con_handle
* @param mtu
*/
void att_dispatch_server_mtu_exchanged(hci_con_handle_t con_handle, uint16_t new_mtu);
/**
* @brief Used for propogating a updated MTU from gatt_client to att_server
* @param con_handle
* @param mtu
*/
void att_dispatch_client_mtu_exchanged(hci_con_handle_t con_handle, uint16_t new_mtu);
#if defined __cplusplus
}
#endif

View File

@ -141,6 +141,7 @@ static void att_emit_mtu_event(hci_con_handle_t con_handle, uint16_t mtu){
little_endian_store_16(event, pos, con_handle);
pos += 2;
little_endian_store_16(event, pos, mtu);
att_dispatch_server_mtu_exchanged(con_handle, mtu);
(*att_client_packet_handler)(HCI_EVENT_PACKET, 0, &event[0], sizeof(event));
}
@ -489,6 +490,11 @@ static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *pa
att_server = att_server_for_handle(handle);
if (!att_server) break;
// Gatt client have negotiated the mtu for this connection
if (packet[0] == ATT_EVENT_MTU_EXCHANGE_COMPLETE){
att_server->connection.mtu = little_endian_read_16(packet, 4);
}
// 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);

View File

@ -559,6 +559,7 @@ static void emit_gatt_mtu_exchanged_result_event(gatt_client_t * peripheral, uin
packet[1] = sizeof(packet) - 2;
little_endian_store_16(packet, 2, peripheral->con_handle);
little_endian_store_16(packet, 4, new_mtu);
att_dispatch_client_mtu_exchanged(peripheral->con_handle, new_mtu);
emit_event_new(peripheral->callback, packet, sizeof(packet));
}
///
@ -1071,6 +1072,12 @@ static void gatt_client_att_packet_handler(uint8_t packet_type, uint16_t handle,
if (!peripheral) return;
switch (packet[0]){
// att_server has negotiated the mtu for this connection
case ATT_EVENT_MTU_EXCHANGE_COMPLETE:
{
peripheral->mtu = little_endian_read_16(packet, 4);
break;
}
case ATT_EXCHANGE_MTU_RESPONSE:
{
uint16_t remote_rx_mtu = little_endian_read_16(packet, 1);