Loading system/stack/gatt/att_protocol.cc +7 −6 Original line number Diff line number Diff line Loading @@ -189,8 +189,8 @@ BT_HDR* attp_build_read_by_type_value_cmd(uint16_t payload_size, * Returns None. * ******************************************************************************/ BT_HDR* attp_build_read_multi_cmd(uint16_t payload_size, uint16_t num_handle, uint16_t* p_handle) { BT_HDR* attp_build_read_multi_cmd(uint8_t op_code, uint16_t payload_size, uint16_t num_handle, uint16_t* p_handle) { uint8_t *p, i = 0; BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + num_handle * 2 + 1 + L2CAP_MIN_OFFSET); Loading @@ -199,7 +199,7 @@ BT_HDR* attp_build_read_multi_cmd(uint16_t payload_size, uint16_t num_handle, p_buf->offset = L2CAP_MIN_OFFSET; p_buf->len = 1; UINT8_TO_STREAM(p, GATT_REQ_READ_MULTI); UINT8_TO_STREAM(p, op_code); for (i = 0; i < num_handle && p_buf->len + 2 <= payload_size; i++) { UINT16_TO_STREAM(p, *(p_handle + i)); Loading Loading @@ -570,8 +570,9 @@ tGATT_STATUS attp_send_cl_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, break; case GATT_REQ_READ_MULTI: p_cmd = attp_build_read_multi_cmd(payload_size, p_msg->read_multi.num_handles, case GATT_REQ_READ_MULTI_VAR: p_cmd = attp_build_read_multi_cmd(op_code, payload_size, p_msg->read_multi.num_handles, p_msg->read_multi.handles); break; Loading system/stack/gatt/gatt_attr.cc +5 −1 Original line number Diff line number Diff line Loading @@ -42,6 +42,10 @@ using bluetooth::Uuid; #define BLE_GATT_CL_SUP_FEAT_CACHING_BITMASK 0x01 #define BLE_GATT_CL_SUP_FEAT_EATT_BITMASK 0x02 #define BLE_GATT_CL_SUP_FEAT_MULTI_NOTIF_BITMASK 0x04 #define BLE_GATT_CL_ANDROID_SUP_FEAT \ (BLE_GATT_CL_SUP_FEAT_EATT_BITMASK | BLE_GATT_CL_SUP_FEAT_MULTI_NOTIF_BITMASK) using gatt_eatt_support_cb = base::OnceCallback<void(const RawAddress&, bool)>; Loading Loading @@ -408,7 +412,7 @@ void gatt_profile_db_init(void) { gatt_cb.handle_cl_supported_feat = service[3].attribute_handle; gatt_cb.gatt_svr_supported_feat_mask |= BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK; gatt_cb.gatt_cl_supported_feat_mask |= BLE_GATT_CL_SUP_FEAT_EATT_BITMASK; gatt_cb.gatt_cl_supported_feat_mask |= BLE_GATT_CL_ANDROID_SUP_FEAT; VLOG(1) << __func__ << ": gatt_if=" << gatt_cb.gatt_if << " EATT supported"; } Loading system/stack/gatt/gatt_cl.cc +37 −14 Original line number Diff line number Diff line Loading @@ -625,9 +625,9 @@ void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, tGATT_STATUS encrypt_status; uint8_t* p = p_data; uint8_t i; uint8_t event = (op_code == GATT_HANDLE_VALUE_NOTIF) ? GATTC_OPTYPE_NOTIFICATION : GATTC_OPTYPE_INDICATION; uint8_t event = (op_code == GATT_HANDLE_VALUE_IND) ? GATTC_OPTYPE_INDICATION : GATTC_OPTYPE_NOTIFICATION; VLOG(1) << __func__; Loading @@ -638,12 +638,19 @@ void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, memset(&value, 0, sizeof(value)); STREAM_TO_UINT16(value.handle, p); if (op_code == GATT_HANDLE_MULTI_VALUE_NOTIF) { STREAM_TO_UINT16(value.len, p); } else { value.len = len - 2; } if (value.len > GATT_MAX_ATTR_LEN) { LOG(ERROR) << "value.len larger than GATT_MAX_ATTR_LEN, discard"; return; } memcpy(value.value, p, value.len); STREAM_TO_ARRAY(value.value, p, value.len); if (!GATT_HANDLE_IS_VALID(value.handle)) { /* illegal handle, send ack now */ Loading Loading @@ -686,6 +693,9 @@ void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, } encrypt_status = gatt_get_link_encrypt_status(tcb); uint16_t rem_len = len; while (rem_len) { tGATT_CL_COMPLETE gatt_cl_complete; gatt_cl_complete.att_value = value; gatt_cl_complete.cid = cid; Loading @@ -697,6 +707,17 @@ void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, &gatt_cl_complete); } } if (op_code != GATT_HANDLE_MULTI_VALUE_NOTIF) return; /* 4 stands for 2 octects for handle and 2 octecs for len */ rem_len -= (4 + value.len); if (rem_len) { STREAM_TO_UINT16(value.handle, p); STREAM_TO_UINT16(value.len, p); STREAM_TO_ARRAY(value.value, p, value.len); } } } /******************************************************************************* Loading Loading @@ -1112,7 +1133,8 @@ void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint16_t cid, uint16_t payload_size = gatt_tcb_get_payload_size_rx(tcb, cid); if (op_code == GATT_HANDLE_VALUE_IND || op_code == GATT_HANDLE_VALUE_NOTIF) { if (op_code == GATT_HANDLE_VALUE_IND || op_code == GATT_HANDLE_VALUE_NOTIF || op_code == GATT_HANDLE_MULTI_VALUE_NOTIF) { if (len >= payload_size) { LOG(ERROR) << StringPrintf( "%s: invalid indicate pkt size: %d, PDU size: %d", __func__, len + 1, Loading Loading @@ -1173,6 +1195,7 @@ void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint16_t cid, case GATT_RSP_READ: case GATT_RSP_READ_BLOB: case GATT_RSP_READ_MULTI: case GATT_RSP_READ_MULTI_VAR: gatt_process_read_rsp(tcb, p_clcb, op_code, len, p_data); break; Loading system/stack/gatt/gatt_sr.cc +93 −76 Original line number Diff line number Diff line Loading @@ -134,48 +134,26 @@ void gatt_dequeue_sr_cmd(tGATT_TCB& tcb, uint16_t cid) { fixed_queue_free(p_cmd->multi_rsp_q, NULL); memset(p_cmd, 0, sizeof(tGATT_SR_CMD)); } /******************************************************************************* * * Function process_read_multi_rsp * * Description This function check the read multiple response. * * Returns bool if all replies have been received * ******************************************************************************/ static bool process_read_multi_rsp(tGATT_SR_CMD* p_cmd, tGATT_STATUS status, tGATTS_RSP* p_msg, uint16_t mtu) { static void build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) { uint16_t ii, total_len, len; uint8_t* p; bool is_overflow = false; VLOG(1) << StringPrintf("%s status=%d mtu=%d", __func__, status, mtu); if (p_cmd->multi_rsp_q == NULL) p_cmd->multi_rsp_q = fixed_queue_new(SIZE_MAX); /* Enqueue the response */ BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(tGATTS_RSP)); memcpy((void*)p_buf, (const void*)p_msg, sizeof(tGATTS_RSP)); fixed_queue_enqueue(p_cmd->multi_rsp_q, p_buf); p_cmd->status = status; if (status == GATT_SUCCESS) { VLOG(1) << "Multi read count=" << fixed_queue_length(p_cmd->multi_rsp_q) << " num_hdls=" << p_cmd->multi_req.num_handles; /* Wait till we get all the responses */ if (fixed_queue_length(p_cmd->multi_rsp_q) == p_cmd->multi_req.num_handles) { len = sizeof(BT_HDR) + L2CAP_MIN_OFFSET + mtu; p_buf = (BT_HDR*)osi_calloc(len); BT_HDR* p_buf = (BT_HDR*)osi_calloc(len); p_buf->offset = L2CAP_MIN_OFFSET; p = (uint8_t*)(p_buf + 1) + p_buf->offset; /* First byte in the response is the opcode */ if (p_cmd->multi_req.variable_len) *p++ = GATT_RSP_READ_MULTI_VAR; else *p++ = GATT_RSP_READ_MULTI; p_buf->len = 1; /* Now walk through the buffers puting the data into the response in order /* Now walk through the buffers putting the data into the response in order */ list_t* list = NULL; const list_node_t* node = NULL; Loading Loading @@ -206,6 +184,11 @@ static bool process_read_multi_rsp(tGATT_SR_CMD* p_cmd, tGATT_STATUS status, len = p_rsp->attr_value.len; } if (p_cmd->multi_req.variable_len) { UINT16_TO_STREAM(p, len); p_buf->len += 2; } if (p_rsp->attr_value.handle == p_cmd->multi_req.handles[ii]) { memcpy(p, p_rsp->attr_value.value, len); if (!is_overflow) p += len; Loading Loading @@ -235,7 +218,38 @@ static bool process_read_multi_rsp(tGATT_SR_CMD* p_cmd, tGATT_STATUS status, } else { p_cmd->p_rsp_msg = p_buf; } } /******************************************************************************* * * Function process_read_multi_rsp * * Description This function check the read multiple response. * * Returns bool if all replies have been received * ******************************************************************************/ static bool process_read_multi_rsp(tGATT_SR_CMD* p_cmd, tGATT_STATUS status, tGATTS_RSP* p_msg, uint16_t mtu) { VLOG(1) << StringPrintf("%s status=%d mtu=%d", __func__, status, mtu); if (p_cmd->multi_rsp_q == NULL) p_cmd->multi_rsp_q = fixed_queue_new(SIZE_MAX); /* Enqueue the response */ BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(tGATTS_RSP)); memcpy((void*)p_buf, (const void*)p_msg, sizeof(tGATTS_RSP)); fixed_queue_enqueue(p_cmd->multi_rsp_q, p_buf); p_cmd->status = status; if (status == GATT_SUCCESS) { VLOG(1) << "Multi read count=" << fixed_queue_length(p_cmd->multi_rsp_q) << " num_hdls=" << p_cmd->multi_req.num_handles << " variable=" << p_cmd->multi_req.variable_len; /* Wait till we get all the responses */ if (fixed_queue_length(p_cmd->multi_rsp_q) == p_cmd->multi_req.num_handles) { build_read_multi_rsp(p_cmd, mtu); return (true); } } else /* any handle read exception occurs, return error */ Loading Loading @@ -269,7 +283,8 @@ tGATT_STATUS gatt_sr_process_app_rsp(tGATT_TCB& tcb, tGATT_IF gatt_if, gatt_sr_update_cback_cnt(tcb, sr_res_p->cid, gatt_if, false, false); if (op_code == GATT_REQ_READ_MULTI) { if ((op_code == GATT_REQ_READ_MULTI) || (op_code == GATT_REQ_READ_MULTI_VAR)) { /* If no error and still waiting, just return */ if (!process_read_multi_rsp(sr_res_p, status, p_msg, payload_size)) return (GATT_SUCCESS); Loading Loading @@ -396,6 +411,7 @@ void gatt_process_read_multi_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, tGATT_READ_MULTI* multi_req = gatt_sr_get_read_multi(tcb, cid); multi_req->num_handles = 0; multi_req->variable_len = (op_code == GATT_REQ_READ_MULTI_VAR); gatt_sr_get_sec_info(tcb.peer_bda, tcb.transport, &sec_flag, &key_size); #if (GATT_CONFORMANCE_TESTING == TRUE) Loading Loading @@ -1292,6 +1308,7 @@ void gatt_server_handle_client_req(tGATT_TCB& tcb, uint16_t cid, break; case GATT_REQ_READ_MULTI: case GATT_REQ_READ_MULTI_VAR: gatt_process_read_multi_req(tcb, cid, op_code, len, p_data); break; Loading system/stack/include/gatt_api.h +13 −1 Original line number Diff line number Diff line Loading @@ -109,10 +109,15 @@ typedef enum : uint8_t { GATT_HANDLE_VALUE_NOTIF = 0x1B, GATT_HANDLE_VALUE_IND = 0x1D, GATT_HANDLE_VALUE_CONF = 0x1E, GATT_REQ_READ_MULTI_VAR = 0x20, GATT_RSP_READ_MULTI_VAR = 0x21, GATT_HANDLE_MULTI_VALUE_NOTIF = 0x23, /* changed in V4.0 1101-0010 (signed write) see write cmd above*/ GATT_SIGN_CMD_WRITE = 0xD2, /* 0x1E = 30 + 1 = 31*/ GATT_OP_CODE_MAX = (GATT_HANDLE_VALUE_CONF + 1), GATT_OP_CODE_MAX = (GATT_HANDLE_MULTI_VALUE_NOTIF + 1), } tGATT_OP_CODE; inline std::string gatt_op_code_text(const tGATT_OP_CODE& op_code) { Loading Loading @@ -171,6 +176,12 @@ inline std::string gatt_op_code_text(const tGATT_OP_CODE& op_code) { return std::string("GATT_HANDLE_VALUE_IND"); case GATT_HANDLE_VALUE_CONF: return std::string("GATT_HANDLE_VALUE_CONF"); case GATT_REQ_READ_MULTI_VAR: return std::string("GATT_REQ_READ_MULTI_VAR"); case GATT_RSP_READ_MULTI_VAR: return std::string("GATT_RSP_READ_MULTI_VAR"); case GATT_HANDLE_MULTI_VALUE_NOTIF: return std::string("GATT_HANDLE_MULTI_VALUE_NOTIF"); case GATT_SIGN_CMD_WRITE: return std::string("GATT_SIGN_CMD_WRITE"); case GATT_OP_CODE_MAX: Loading Loading @@ -499,6 +510,7 @@ typedef struct { tGATT_AUTH_REQ auth_req; uint16_t num_handles; /* number of handles to read */ uint16_t handles[GATT_MAX_READ_MULTI_HANDLES]; /* handles list to be read */ bool variable_len; } tGATT_READ_MULTI; /* Read By Handle Request (GATT_READ_BY_HANDLE) data */ Loading Loading
system/stack/gatt/att_protocol.cc +7 −6 Original line number Diff line number Diff line Loading @@ -189,8 +189,8 @@ BT_HDR* attp_build_read_by_type_value_cmd(uint16_t payload_size, * Returns None. * ******************************************************************************/ BT_HDR* attp_build_read_multi_cmd(uint16_t payload_size, uint16_t num_handle, uint16_t* p_handle) { BT_HDR* attp_build_read_multi_cmd(uint8_t op_code, uint16_t payload_size, uint16_t num_handle, uint16_t* p_handle) { uint8_t *p, i = 0; BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(BT_HDR) + num_handle * 2 + 1 + L2CAP_MIN_OFFSET); Loading @@ -199,7 +199,7 @@ BT_HDR* attp_build_read_multi_cmd(uint16_t payload_size, uint16_t num_handle, p_buf->offset = L2CAP_MIN_OFFSET; p_buf->len = 1; UINT8_TO_STREAM(p, GATT_REQ_READ_MULTI); UINT8_TO_STREAM(p, op_code); for (i = 0; i < num_handle && p_buf->len + 2 <= payload_size; i++) { UINT16_TO_STREAM(p, *(p_handle + i)); Loading Loading @@ -570,8 +570,9 @@ tGATT_STATUS attp_send_cl_msg(tGATT_TCB& tcb, tGATT_CLCB* p_clcb, break; case GATT_REQ_READ_MULTI: p_cmd = attp_build_read_multi_cmd(payload_size, p_msg->read_multi.num_handles, case GATT_REQ_READ_MULTI_VAR: p_cmd = attp_build_read_multi_cmd(op_code, payload_size, p_msg->read_multi.num_handles, p_msg->read_multi.handles); break; Loading
system/stack/gatt/gatt_attr.cc +5 −1 Original line number Diff line number Diff line Loading @@ -42,6 +42,10 @@ using bluetooth::Uuid; #define BLE_GATT_CL_SUP_FEAT_CACHING_BITMASK 0x01 #define BLE_GATT_CL_SUP_FEAT_EATT_BITMASK 0x02 #define BLE_GATT_CL_SUP_FEAT_MULTI_NOTIF_BITMASK 0x04 #define BLE_GATT_CL_ANDROID_SUP_FEAT \ (BLE_GATT_CL_SUP_FEAT_EATT_BITMASK | BLE_GATT_CL_SUP_FEAT_MULTI_NOTIF_BITMASK) using gatt_eatt_support_cb = base::OnceCallback<void(const RawAddress&, bool)>; Loading Loading @@ -408,7 +412,7 @@ void gatt_profile_db_init(void) { gatt_cb.handle_cl_supported_feat = service[3].attribute_handle; gatt_cb.gatt_svr_supported_feat_mask |= BLE_GATT_SVR_SUP_FEAT_EATT_BITMASK; gatt_cb.gatt_cl_supported_feat_mask |= BLE_GATT_CL_SUP_FEAT_EATT_BITMASK; gatt_cb.gatt_cl_supported_feat_mask |= BLE_GATT_CL_ANDROID_SUP_FEAT; VLOG(1) << __func__ << ": gatt_if=" << gatt_cb.gatt_if << " EATT supported"; } Loading
system/stack/gatt/gatt_cl.cc +37 −14 Original line number Diff line number Diff line Loading @@ -625,9 +625,9 @@ void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, tGATT_STATUS encrypt_status; uint8_t* p = p_data; uint8_t i; uint8_t event = (op_code == GATT_HANDLE_VALUE_NOTIF) ? GATTC_OPTYPE_NOTIFICATION : GATTC_OPTYPE_INDICATION; uint8_t event = (op_code == GATT_HANDLE_VALUE_IND) ? GATTC_OPTYPE_INDICATION : GATTC_OPTYPE_NOTIFICATION; VLOG(1) << __func__; Loading @@ -638,12 +638,19 @@ void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, memset(&value, 0, sizeof(value)); STREAM_TO_UINT16(value.handle, p); if (op_code == GATT_HANDLE_MULTI_VALUE_NOTIF) { STREAM_TO_UINT16(value.len, p); } else { value.len = len - 2; } if (value.len > GATT_MAX_ATTR_LEN) { LOG(ERROR) << "value.len larger than GATT_MAX_ATTR_LEN, discard"; return; } memcpy(value.value, p, value.len); STREAM_TO_ARRAY(value.value, p, value.len); if (!GATT_HANDLE_IS_VALID(value.handle)) { /* illegal handle, send ack now */ Loading Loading @@ -686,6 +693,9 @@ void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, } encrypt_status = gatt_get_link_encrypt_status(tcb); uint16_t rem_len = len; while (rem_len) { tGATT_CL_COMPLETE gatt_cl_complete; gatt_cl_complete.att_value = value; gatt_cl_complete.cid = cid; Loading @@ -697,6 +707,17 @@ void gatt_process_notification(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, &gatt_cl_complete); } } if (op_code != GATT_HANDLE_MULTI_VALUE_NOTIF) return; /* 4 stands for 2 octects for handle and 2 octecs for len */ rem_len -= (4 + value.len); if (rem_len) { STREAM_TO_UINT16(value.handle, p); STREAM_TO_UINT16(value.len, p); STREAM_TO_ARRAY(value.value, p, value.len); } } } /******************************************************************************* Loading Loading @@ -1112,7 +1133,8 @@ void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint16_t cid, uint16_t payload_size = gatt_tcb_get_payload_size_rx(tcb, cid); if (op_code == GATT_HANDLE_VALUE_IND || op_code == GATT_HANDLE_VALUE_NOTIF) { if (op_code == GATT_HANDLE_VALUE_IND || op_code == GATT_HANDLE_VALUE_NOTIF || op_code == GATT_HANDLE_MULTI_VALUE_NOTIF) { if (len >= payload_size) { LOG(ERROR) << StringPrintf( "%s: invalid indicate pkt size: %d, PDU size: %d", __func__, len + 1, Loading Loading @@ -1173,6 +1195,7 @@ void gatt_client_handle_server_rsp(tGATT_TCB& tcb, uint16_t cid, case GATT_RSP_READ: case GATT_RSP_READ_BLOB: case GATT_RSP_READ_MULTI: case GATT_RSP_READ_MULTI_VAR: gatt_process_read_rsp(tcb, p_clcb, op_code, len, p_data); break; Loading
system/stack/gatt/gatt_sr.cc +93 −76 Original line number Diff line number Diff line Loading @@ -134,48 +134,26 @@ void gatt_dequeue_sr_cmd(tGATT_TCB& tcb, uint16_t cid) { fixed_queue_free(p_cmd->multi_rsp_q, NULL); memset(p_cmd, 0, sizeof(tGATT_SR_CMD)); } /******************************************************************************* * * Function process_read_multi_rsp * * Description This function check the read multiple response. * * Returns bool if all replies have been received * ******************************************************************************/ static bool process_read_multi_rsp(tGATT_SR_CMD* p_cmd, tGATT_STATUS status, tGATTS_RSP* p_msg, uint16_t mtu) { static void build_read_multi_rsp(tGATT_SR_CMD* p_cmd, uint16_t mtu) { uint16_t ii, total_len, len; uint8_t* p; bool is_overflow = false; VLOG(1) << StringPrintf("%s status=%d mtu=%d", __func__, status, mtu); if (p_cmd->multi_rsp_q == NULL) p_cmd->multi_rsp_q = fixed_queue_new(SIZE_MAX); /* Enqueue the response */ BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(tGATTS_RSP)); memcpy((void*)p_buf, (const void*)p_msg, sizeof(tGATTS_RSP)); fixed_queue_enqueue(p_cmd->multi_rsp_q, p_buf); p_cmd->status = status; if (status == GATT_SUCCESS) { VLOG(1) << "Multi read count=" << fixed_queue_length(p_cmd->multi_rsp_q) << " num_hdls=" << p_cmd->multi_req.num_handles; /* Wait till we get all the responses */ if (fixed_queue_length(p_cmd->multi_rsp_q) == p_cmd->multi_req.num_handles) { len = sizeof(BT_HDR) + L2CAP_MIN_OFFSET + mtu; p_buf = (BT_HDR*)osi_calloc(len); BT_HDR* p_buf = (BT_HDR*)osi_calloc(len); p_buf->offset = L2CAP_MIN_OFFSET; p = (uint8_t*)(p_buf + 1) + p_buf->offset; /* First byte in the response is the opcode */ if (p_cmd->multi_req.variable_len) *p++ = GATT_RSP_READ_MULTI_VAR; else *p++ = GATT_RSP_READ_MULTI; p_buf->len = 1; /* Now walk through the buffers puting the data into the response in order /* Now walk through the buffers putting the data into the response in order */ list_t* list = NULL; const list_node_t* node = NULL; Loading Loading @@ -206,6 +184,11 @@ static bool process_read_multi_rsp(tGATT_SR_CMD* p_cmd, tGATT_STATUS status, len = p_rsp->attr_value.len; } if (p_cmd->multi_req.variable_len) { UINT16_TO_STREAM(p, len); p_buf->len += 2; } if (p_rsp->attr_value.handle == p_cmd->multi_req.handles[ii]) { memcpy(p, p_rsp->attr_value.value, len); if (!is_overflow) p += len; Loading Loading @@ -235,7 +218,38 @@ static bool process_read_multi_rsp(tGATT_SR_CMD* p_cmd, tGATT_STATUS status, } else { p_cmd->p_rsp_msg = p_buf; } } /******************************************************************************* * * Function process_read_multi_rsp * * Description This function check the read multiple response. * * Returns bool if all replies have been received * ******************************************************************************/ static bool process_read_multi_rsp(tGATT_SR_CMD* p_cmd, tGATT_STATUS status, tGATTS_RSP* p_msg, uint16_t mtu) { VLOG(1) << StringPrintf("%s status=%d mtu=%d", __func__, status, mtu); if (p_cmd->multi_rsp_q == NULL) p_cmd->multi_rsp_q = fixed_queue_new(SIZE_MAX); /* Enqueue the response */ BT_HDR* p_buf = (BT_HDR*)osi_malloc(sizeof(tGATTS_RSP)); memcpy((void*)p_buf, (const void*)p_msg, sizeof(tGATTS_RSP)); fixed_queue_enqueue(p_cmd->multi_rsp_q, p_buf); p_cmd->status = status; if (status == GATT_SUCCESS) { VLOG(1) << "Multi read count=" << fixed_queue_length(p_cmd->multi_rsp_q) << " num_hdls=" << p_cmd->multi_req.num_handles << " variable=" << p_cmd->multi_req.variable_len; /* Wait till we get all the responses */ if (fixed_queue_length(p_cmd->multi_rsp_q) == p_cmd->multi_req.num_handles) { build_read_multi_rsp(p_cmd, mtu); return (true); } } else /* any handle read exception occurs, return error */ Loading Loading @@ -269,7 +283,8 @@ tGATT_STATUS gatt_sr_process_app_rsp(tGATT_TCB& tcb, tGATT_IF gatt_if, gatt_sr_update_cback_cnt(tcb, sr_res_p->cid, gatt_if, false, false); if (op_code == GATT_REQ_READ_MULTI) { if ((op_code == GATT_REQ_READ_MULTI) || (op_code == GATT_REQ_READ_MULTI_VAR)) { /* If no error and still waiting, just return */ if (!process_read_multi_rsp(sr_res_p, status, p_msg, payload_size)) return (GATT_SUCCESS); Loading Loading @@ -396,6 +411,7 @@ void gatt_process_read_multi_req(tGATT_TCB& tcb, uint16_t cid, uint8_t op_code, tGATT_READ_MULTI* multi_req = gatt_sr_get_read_multi(tcb, cid); multi_req->num_handles = 0; multi_req->variable_len = (op_code == GATT_REQ_READ_MULTI_VAR); gatt_sr_get_sec_info(tcb.peer_bda, tcb.transport, &sec_flag, &key_size); #if (GATT_CONFORMANCE_TESTING == TRUE) Loading Loading @@ -1292,6 +1308,7 @@ void gatt_server_handle_client_req(tGATT_TCB& tcb, uint16_t cid, break; case GATT_REQ_READ_MULTI: case GATT_REQ_READ_MULTI_VAR: gatt_process_read_multi_req(tcb, cid, op_code, len, p_data); break; Loading
system/stack/include/gatt_api.h +13 −1 Original line number Diff line number Diff line Loading @@ -109,10 +109,15 @@ typedef enum : uint8_t { GATT_HANDLE_VALUE_NOTIF = 0x1B, GATT_HANDLE_VALUE_IND = 0x1D, GATT_HANDLE_VALUE_CONF = 0x1E, GATT_REQ_READ_MULTI_VAR = 0x20, GATT_RSP_READ_MULTI_VAR = 0x21, GATT_HANDLE_MULTI_VALUE_NOTIF = 0x23, /* changed in V4.0 1101-0010 (signed write) see write cmd above*/ GATT_SIGN_CMD_WRITE = 0xD2, /* 0x1E = 30 + 1 = 31*/ GATT_OP_CODE_MAX = (GATT_HANDLE_VALUE_CONF + 1), GATT_OP_CODE_MAX = (GATT_HANDLE_MULTI_VALUE_NOTIF + 1), } tGATT_OP_CODE; inline std::string gatt_op_code_text(const tGATT_OP_CODE& op_code) { Loading Loading @@ -171,6 +176,12 @@ inline std::string gatt_op_code_text(const tGATT_OP_CODE& op_code) { return std::string("GATT_HANDLE_VALUE_IND"); case GATT_HANDLE_VALUE_CONF: return std::string("GATT_HANDLE_VALUE_CONF"); case GATT_REQ_READ_MULTI_VAR: return std::string("GATT_REQ_READ_MULTI_VAR"); case GATT_RSP_READ_MULTI_VAR: return std::string("GATT_RSP_READ_MULTI_VAR"); case GATT_HANDLE_MULTI_VALUE_NOTIF: return std::string("GATT_HANDLE_MULTI_VALUE_NOTIF"); case GATT_SIGN_CMD_WRITE: return std::string("GATT_SIGN_CMD_WRITE"); case GATT_OP_CODE_MAX: Loading Loading @@ -499,6 +510,7 @@ typedef struct { tGATT_AUTH_REQ auth_req; uint16_t num_handles; /* number of handles to read */ uint16_t handles[GATT_MAX_READ_MULTI_HANDLES]; /* handles list to be read */ bool variable_len; } tGATT_READ_MULTI; /* Read By Handle Request (GATT_READ_BY_HANDLE) data */ Loading