Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f3e3aebf authored by Łukasz Rymanowski's avatar Łukasz Rymanowski
Browse files

gatt: Fix EATT MTU

Make sure that EATT MTU is as per Bluetooth Specification

"The ATT_MTU for the Enhanced ATT bearer shall be set to the minimum of the
MTU field values of the two devices; these values come from the L2CAP_-
CREDIT_BASED_CONNECTION_REQ and L2CAP_CREDIT_BASED_-
CONNECTION_RSP signaling packets or the latest L2CAP_CREDIT_-
BASED_RECONFIGURE_REQ packets.
Note: The minimum ATT_MTU for an Enhanced ATT bearer is 64 octets"

Bug: 282719753
Test: Manual
Tag: #feature
Change-Id: I5bb6f7fb36d11c53255de91b927fce226d3c7841
parent fe1322e6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -519,7 +519,7 @@ tGATT_STATUS attp_send_cl_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
    return GATT_ILLEGAL_PARAMETER;
  }

  uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, p_clcb->cid);
  uint16_t payload_size = gatt_tcb_get_payload_size(tcb, p_clcb->cid);

  switch (op_code) {
    case GATT_REQ_MTU:
+4 −5
Original line number Diff line number Diff line
@@ -475,7 +475,7 @@ tGATT_STATUS GATTS_HandleValueIndication(uint16_t conn_id, uint16_t attr_handle,
  tGATT_SR_MSG gatt_sr_msg;
  gatt_sr_msg.attr_value = indication;

  uint16_t payload_size = gatt_tcb_get_payload_size_tx(*p_tcb, cid);
  uint16_t payload_size = gatt_tcb_get_payload_size(*p_tcb, cid);
  BT_HDR* p_msg = attp_build_sr_msg(*p_tcb, GATT_HANDLE_VALUE_IND, &gatt_sr_msg,
                                    payload_size);
  if (!p_msg) return GATT_NO_RESOURCES;
@@ -494,7 +494,7 @@ static tGATT_STATUS GATTS_HandleMultileValueNotification(
  LOG_INFO("");

  uint16_t cid = gatt_tcb_get_att_cid(*p_tcb, true /* eatt support */);
  uint16_t payload_size = gatt_tcb_get_payload_size_tx(*p_tcb, cid);
  uint16_t payload_size = gatt_tcb_get_payload_size(*p_tcb, cid);

  /* TODO Handle too big packet size here. Not needed now for testing. */
  /* Just build the message. */
@@ -608,7 +608,7 @@ tGATT_STATUS GATTS_HandleValueNotification(uint16_t conn_id,
  gatt_sr_msg.attr_value = notif;

  uint16_t cid = gatt_tcb_get_att_cid(*p_tcb, p_reg->eatt_support);
  uint16_t payload_size = gatt_tcb_get_payload_size_tx(*p_tcb, cid);
  uint16_t payload_size = gatt_tcb_get_payload_size(*p_tcb, cid);
  BT_HDR* p_buf = attp_build_sr_msg(*p_tcb, GATT_HANDLE_VALUE_NOTIF,
                                    &gatt_sr_msg, payload_size);

@@ -967,8 +967,7 @@ tGATT_STATUS GATTC_Read(uint16_t conn_id, tGATT_READ_TYPE type,
  p_clcb->op_subtype = type;
  p_clcb->auth_req = p_read->by_handle.auth_req;
  p_clcb->counter = 0;
  p_clcb->read_req_current_mtu =
      gatt_tcb_get_payload_size_tx(*p_tcb, p_clcb->cid);
  p_clcb->read_req_current_mtu = gatt_tcb_get_payload_size(*p_tcb, p_clcb->cid);

  switch (type) {
    case GATT_READ_BY_TYPE:
+5 −5
Original line number Diff line number Diff line
@@ -230,7 +230,7 @@ void gatt_act_write(tGATT_CLCB* p_clcb, uint8_t sec_act) {
  CHECK(p_clcb->p_attr_buf);
  tGATT_VALUE& attr = *((tGATT_VALUE*)p_clcb->p_attr_buf);

  uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, p_clcb->cid);
  uint16_t payload_size = gatt_tcb_get_payload_size(tcb, p_clcb->cid);

  switch (p_clcb->op_subtype) {
    case GATT_WRITE_NO_RSP: {
@@ -351,7 +351,7 @@ void gatt_send_prepare_write(tGATT_TCB& tcb, tGATT_CLCB* p_clcb) {
  VLOG(1) << __func__ << StringPrintf(" type=0x%x", type);
  uint16_t to_send = p_attr->len - p_attr->offset;

  uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, p_clcb->cid);
  uint16_t payload_size = gatt_tcb_get_payload_size(tcb, p_clcb->cid);
  if (to_send > (payload_size -
                 GATT_WRITE_LONG_HDR_SIZE)) /* 2 = uint16_t offset bytes  */
    to_send = payload_size - GATT_WRITE_LONG_HDR_SIZE;
@@ -805,7 +805,7 @@ void gatt_process_read_by_type_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
  }

  STREAM_TO_UINT8(value_len, p);
  uint16_t payload_size = gatt_tcb_get_payload_size_rx(tcb, p_clcb->cid);
  uint16_t payload_size = gatt_tcb_get_payload_size(tcb, p_clcb->cid);
  if ((value_len > (payload_size - 2)) || (value_len > (len - 1))) {
    /* this is an error case that server's response containing a value length
       which is larger than MTU-2
@@ -995,7 +995,7 @@ void gatt_process_read_rsp(tGATT_TCB& tcb, tGATT_CLCB* p_clcb,
  uint16_t offset = p_clcb->counter;
  uint8_t* p = p_data;

  uint16_t payload_size = gatt_tcb_get_payload_size_rx(tcb, p_clcb->cid);
  uint16_t payload_size = gatt_tcb_get_payload_size(tcb, p_clcb->cid);

  if (p_clcb->operation == GATTC_OPTYPE_READ) {
    if (p_clcb->op_subtype != GATT_READ_BY_HANDLE) {
@@ -1207,7 +1207,7 @@ void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint16_t cid,
                                   uint8_t* p_data) {
  VLOG(1) << __func__ << " opcode: " << loghex(op_code) << " cid" << +cid;

  uint16_t payload_size = gatt_tcb_get_payload_size_rx(tcb, cid);
  uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);

  if (op_code == GATT_HANDLE_VALUE_IND || op_code == GATT_HANDLE_VALUE_NOTIF ||
      op_code == GATT_HANDLE_MULTI_VALUE_NOTIF) {
+1 −2
Original line number Diff line number Diff line
@@ -598,8 +598,7 @@ bool gatt_tcb_get_cid_available_for_indication(tGATT_TCB* p_tcb,
bool gatt_tcb_find_indicate_handle(tGATT_TCB& tcb, uint16_t cid,
                                   uint16_t* indicated_handle_p);
uint16_t gatt_tcb_get_att_cid(tGATT_TCB& tcb, bool eatt_support);
uint16_t gatt_tcb_get_payload_size_tx(tGATT_TCB& tcb, uint16_t cid);
uint16_t gatt_tcb_get_payload_size_rx(tGATT_TCB& tcb, uint16_t cid);
uint16_t gatt_tcb_get_payload_size(tGATT_TCB& tcb, uint16_t cid);
void gatt_clcb_invalidate(tGATT_TCB* p_tcb, const tGATT_CLCB* p_clcb);
uint16_t gatt_get_mtu(const RawAddress& bda, tBT_TRANSPORT transport);
bool gatt_is_pending_mtu_exchange(tGATT_TCB* p_tcb);
+7 −7
Original line number Diff line number Diff line
@@ -287,7 +287,7 @@ tGATT_STATUS gatt_sr_process_app_rsp(tGATT_TCB& tcb, tGATT_IF gatt_if,
                                     tGATTS_RSP* p_msg,
                                     tGATT_SR_CMD* sr_res_p) {
  tGATT_STATUS ret_code = GATT_SUCCESS;
  uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, sr_res_p->cid);
  uint16_t payload_size = gatt_tcb_get_payload_size(tcb, sr_res_p->cid);

  VLOG(1) << __func__ << " gatt_if=" << +gatt_if;

@@ -521,7 +521,7 @@ static tGATT_STATUS gatt_build_primary_service_rsp(

  uint8_t* p = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;

  uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, cid);
  uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);

  for (tGATT_SRV_LIST_ELEM& el : *gatt_cb.srv_list_info) {
    if (el.s_hdl < s_hdl || el.s_hdl > e_hdl ||
@@ -716,7 +716,7 @@ void gatts_process_primary_service_req(tGATT_TCB& tcb, uint16_t cid,
    }
  }

  uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, cid);
  uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);

  uint16_t msg_len =
      (uint16_t)(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);
@@ -752,7 +752,7 @@ static void gatts_process_find_info(tGATT_TCB& tcb, uint16_t cid,
    return;
  }

  uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, cid);
  uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);
  uint16_t buf_len =
      (uint16_t)(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);

@@ -891,7 +891,7 @@ static void gatts_process_read_by_type_req(tGATT_TCB& tcb, uint16_t cid,
    return;
  }

  uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, cid);
  uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);

  size_t msg_len = sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET;
  BT_HDR* p_msg = (BT_HDR*)osi_calloc(msg_len);
@@ -1038,7 +1038,7 @@ static void gatts_process_read_req(tGATT_TCB& tcb, uint16_t cid,
                                   tGATT_SRV_LIST_ELEM& el, uint8_t op_code,
                                   uint16_t handle, uint16_t len,
                                   uint8_t* p_data) {
  uint16_t payload_size = gatt_tcb_get_payload_size_tx(tcb, cid);
  uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);

  size_t buf_len = sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET;
  uint16_t offset = 0;
@@ -1355,7 +1355,7 @@ void gatt_server_handle_client_req(tGATT_TCB& tcb, uint16_t cid,
  /* The message has to be smaller than the agreed MTU, len does not include op
   * code */

  uint16_t payload_size = gatt_tcb_get_payload_size_rx(tcb, cid);
  uint16_t payload_size = gatt_tcb_get_payload_size(tcb, cid);
  if (len >= payload_size) {
    LOG(ERROR) << StringPrintf("server receive invalid PDU size:%d pdu size:%d",
                               len + 1, payload_size);
Loading