static uint8_t att_mtu_rsp(struct bt_att *att, struct net_buf *buf) { struct bt_att_exchange_mtu_rsp *rsp; uint16_t mtu; if (!att) { return 0; } rsp = (void *)buf->data; mtu = sys_le16_to_cpu(rsp->mtu); BT_DBG("Server MTU %u", mtu); /* Check if MTU is valid */ if (mtu < BT_ATT_DEFAULT_LE_MTU) { return att_handle_rsp(att, NULL, 0, BT_ATT_ERR_INVALID_PDU); } att->chan.rx.mtu = min(mtu, CONFIG_BLUETOOTH_ATT_MTU); /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part F] page 484: * * A device's Exchange MTU Request shall contain the same MTU as the * device's Exchange MTU Response (i.e. the MTU shall be symmetric). */ att->chan.tx.mtu = att->chan.rx.mtu; BT_DBG("Negotiated MTU %u", att->chan.rx.mtu); return att_handle_rsp(att, rsp, buf->len, 0); }
static uint8_t att_handle_exec_write_rsp(struct bt_att *att, struct net_buf *buf) { BT_DBG(""); return att_handle_rsp(att, buf->data, buf->len, 0); }
static void bt_att_disconnected(struct bt_l2cap_chan *chan) { struct bt_att *att = CONTAINER_OF(chan, struct bt_att, chan); BT_DBG("chan %p cid 0x%04x", chan, chan->tx.cid); /* Notify client if request is pending */ att_handle_rsp(att, NULL, 0, BT_ATT_ERR_UNLIKELY); bt_gatt_disconnected(chan->conn); memset(att, 0, sizeof(*att)); }
static uint8_t att_error_rsp(struct bt_att *att, struct net_buf *buf) { struct bt_att_req *req = &att->req; struct bt_att_error_rsp *rsp; struct bt_att_hdr *hdr; uint8_t err; rsp = (void *)buf->data; BT_DBG("request 0x%02x handle 0x%04x error 0x%02x", rsp->request, sys_le16_to_cpu(rsp->handle), rsp->error); if (!req->buf) { err = BT_ATT_ERR_UNLIKELY; goto done; } hdr = (void *)req->buf->data; err = rsp->request == hdr->code ? rsp->error : BT_ATT_ERR_UNLIKELY; #if defined(CONFIG_BLUETOOTH_SMP) if (req->retrying) { goto done; } /* Check if security needs to be changed */ if (!att_change_security(att->chan.conn, err)) { req->retrying = true; /* Wait security_changed: TODO: Handle fail case */ return 0; } #endif /* CONFIG_BLUETOOTH_SMP */ done: return att_handle_rsp(att, NULL, 0, err); }