From 2955b20f2ebbd813b077f4fd34818cae7935c2f7 Mon Sep 17 00:00:00 2001 From: island Date: Mon, 6 Mar 2017 17:20:45 +0800 Subject: [PATCH 1/4] bt component: fix bluetooth gatt packets process bugs 1. Add process of prepare write request packets 2. Add process of execute write request packets 3. Add process of reliable write request packets 4. Fix bug of processing read blob request packets 5. Fix bug of processing write request packets 6. Optimize error check and process in stack --- components/bt/bluedroid/api/esp_gatts_api.c | 45 +++ components/bt/bluedroid/stack/gatt/gatt_db.c | 185 +++++++--- components/bt/bluedroid/stack/gatt/gatt_sr.c | 335 +++++++++++++++--- .../bt/bluedroid/stack/gatt/gatt_utils.c | 21 ++ .../bluedroid/stack/gatt/include/gatt_int.h | 37 ++ .../bt/bluedroid/stack/include/gatt_api.h | 2 + 6 files changed, 511 insertions(+), 114 deletions(-) diff --git a/components/bt/bluedroid/api/esp_gatts_api.c b/components/bt/bluedroid/api/esp_gatts_api.c index f5ebe59a2..3a31d7959 100644 --- a/components/bt/bluedroid/api/esp_gatts_api.c +++ b/components/bt/bluedroid/api/esp_gatts_api.c @@ -142,6 +142,28 @@ esp_err_t esp_ble_gatts_add_char(uint16_t service_handle, esp_bt_uuid_t *char_ return ESP_ERR_INVALID_STATE; } + /* parameter validation check */ + if ((control != NULL) && (control->auto_rsp == GATT_STACK_RSP)){ + if (char_val == NULL){ + LOG_ERROR("Error in %s, line=%d, for stack respond attribute, char_val should not be NULL here\n",\ + __func__, __LINE__); + return ESP_ERR_INVALID_ARG; + } + else if (char_val->attr_max_len == 0){ + LOG_ERROR("Error in %s, line=%d, for stack respond attribute, attribute max length should not be 0\n",\ + __func__, __LINE__); + return ESP_ERR_INVALID_ARG; + } + } + + if (char_val != NULL){ + if (char_val->attr_len > char_val->attr_max_len){ + LOG_ERROR("Error in %s, line=%d,attribute actual length should not be larger than max length\n",\ + __func__, __LINE__); + return ESP_ERR_INVALID_ARG; + } + } + memset(&arg, 0, sizeof(btc_ble_gatts_args_t)); msg.sig = BTC_SIG_API_CALL; msg.pid = BTC_PID_GATTS; @@ -175,6 +197,29 @@ esp_err_t esp_ble_gatts_add_char_descr (uint16_t service_handle, if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { return ESP_ERR_INVALID_STATE; } + + /* parameter validation check */ + if ((control != NULL) && (control->auto_rsp == GATT_STACK_RSP)){ + if (char_descr_val == NULL){ + LOG_ERROR("Error in %s, line=%d, for stack respond attribute, char_descr_val should not be NULL here\n",\ + __func__, __LINE__); + return ESP_ERR_INVALID_ARG; + } + else if (char_descr_val->attr_max_len == 0){ + LOG_ERROR("Error in %s, line=%d, for stack respond attribute, attribute max length should not be 0\n",\ + __func__, __LINE__); + return ESP_ERR_INVALID_ARG; + } + } + + if (char_descr_val != NULL){ + if (char_descr_val->attr_len > char_descr_val->attr_max_len){ + LOG_ERROR("Error in %s, line=%d,attribute actual length should not be larger than max length\n",\ + __func__, __LINE__); + return ESP_ERR_INVALID_ARG; + } + } + memset(&arg, 0, sizeof(btc_ble_gatts_args_t)); msg.sig = BTC_SIG_API_CALL; diff --git a/components/bt/bluedroid/stack/gatt/gatt_db.c b/components/bt/bluedroid/stack/gatt/gatt_db.c index bb9bfc5f7..60749a0f4 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_db.c +++ b/components/bt/bluedroid/stack/gatt/gatt_db.c @@ -268,14 +268,22 @@ static tGATT_STATUS read_attr_value (void *p_attr, status = GATT_SUCCESS; } } else { /* characteristic description or characteristic value */ - if (p_attr16->control.auto_rsp == GATT_RSP_BY_STACK) { - if (p_attr16->p_value != NULL && p_attr16->p_value->attr_val.attr_val != NULL) { - uint8_t *value = p_attr16->p_value->attr_val.attr_val + offset; - len = (mtu >= p_attr16->p_value->attr_val.attr_len) ? (p_attr16->p_value->attr_val.attr_len) : mtu; - ARRAY_TO_STREAM(p, value, len); + if (p_attr16->p_value == NULL || p_attr16->p_value->attr_val.attr_val == NULL) { + status = GATT_ESP_ERROR; + } + /*if offset equal to max_len, should respond with zero byte value + //if offset is greater than max_len, should respond with an error*/ + else if (offset > p_attr16->p_value->attr_val.attr_len){ + status = GATT_INVALID_OFFSET; + } + else { + UINT8 *value = (UINT8 *)(p_attr16->p_value->attr_val.attr_val) + offset; + UINT16 len_left = p_attr16->p_value->attr_val.attr_len - offset; + len = (mtu >= len_left) ? (len_left) : mtu; + ARRAY_TO_STREAM(p, value, len); + status = GATT_STACK_RSP; } - status = GATT_STACK_RSP; } else { status = GATT_PENDING; @@ -463,6 +471,28 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_CHAR_DECLARE}}; GATT_TRACE_DEBUG("gatts_add_characteristic perm=0x%0x property=0x%0x\n", perm, property); + /* parameter validation check */ + if ((control != NULL) && (control->auto_rsp == GATT_STACK_RSP)){ + if (attr_val == NULL){ + GATT_TRACE_ERROR("Error in %s, line=%d, for stack respond attribute, attr_val should not be NULL here\n",\ + __func__, __LINE__); + return 0; + } + else if (attr_val->attr_max_len == 0){ + GATT_TRACE_ERROR("Error in %s, line=%d, for stack respond attribute, attribute max length should not be 0\n",\ + __func__, __LINE__); + return 0; + } + } + + if (attr_val != NULL){ + if (attr_val->attr_len > attr_val->attr_max_len){ + GATT_TRACE_ERROR("Error in %s, line=%d,attribute actual length should not be larger than max length\n",\ + __func__, __LINE__); + return 0; + } + } + if ((p_char_decl = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ)) != NULL) { if (!copy_extra_byte_in_db(p_db, (void **)&p_char_decl->p_value, sizeof(tGATT_CHAR_DECL))) { @@ -483,10 +513,9 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, p_char_val->control.auto_rsp = control->auto_rsp; } else { p_char_val->control.auto_rsp = GATT_RSP_DEFAULT; - } - if (attr_val != NULL) { + if (attr_val != NULL) { if (!copy_extra_byte_in_db(p_db, (void **)&p_char_val->p_value, sizeof(tGATT_ATTR_VAL))) { deallocate_attr_in_db(p_db, p_char_val); return 0; @@ -496,12 +525,23 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, p_char_val->p_value->attr_val.attr_len = attr_val->attr_len; p_char_val->p_value->attr_val.attr_max_len = attr_val->attr_max_len; p_char_val->p_value->attr_val.attr_val = GKI_getbuf(attr_val->attr_max_len); - if (p_char_val->p_value->attr_val.attr_val != NULL) { - GATT_TRACE_DEBUG("attribute value not NULL"); - memcpy(p_char_val->p_value->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len); + if (p_char_val->p_value->attr_val.attr_val == NULL) { + deallocate_attr_in_db(p_db, p_char_decl); + deallocate_attr_in_db(p_db, p_char_val); + GATT_TRACE_ERROR("Warning in %s, line=%d, insufficient resource to allocate for attribute value\n", __func__, __LINE__); + return 0; + } + + //initiate characteristic attribute value part + memset(p_char_val->p_value->attr_val.attr_val, 0, attr_val->attr_max_len); + if (attr_val->attr_val != NULL) { + if (attr_val->attr_max_len < attr_val->attr_len){ + GATT_TRACE_ERROR("Error in %s, Line=%d, attribute actual length(%d) should not larger than max size(%d)\n", + __func__, __LINE__, attr_val->attr_len, attr_val->attr_max_len); + } + UINT16 actual_len = (attr_val->attr_max_len < attr_val->attr_len) ? (attr_val->attr_max_len) : (attr_val->attr_len); + memcpy(p_char_val->p_value->attr_val.attr_val, attr_val->attr_val, actual_len); } - } else { - p_char_val->p_value = NULL; } return p_char_val->handle; @@ -582,14 +622,37 @@ UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, GATT_TRACE_DEBUG("gatts_add_char_descr uuid=0x%04x\n", p_descr_uuid->uu.uuid16); + /* parameter validation check */ + if ((control != NULL) && (control->auto_rsp == GATT_STACK_RSP)){ + if (attr_val == NULL){ + GATT_TRACE_ERROR("Error in %s, line=%d, for stack respond attribute, attr_val should not be NULL here\n",\ + __func__, __LINE__); + return 0; + } + else if (attr_val->attr_max_len == 0){ + GATT_TRACE_ERROR("Error in %s, line=%d, for stack respond attribute, attribute max length should not be 0\n",\ + __func__, __LINE__); + return 0; + } + } + + if (attr_val != NULL){ + if (attr_val->attr_len > attr_val->attr_max_len){ + GATT_TRACE_ERROR("Error in %s, line=%d,attribute actual length should not be larger than max length\n",\ + __func__, __LINE__); + return 0; + } + } + + /* Add characteristic descriptors */ if ((p_char_dscptr = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, p_descr_uuid, perm)) == NULL) { + deallocate_attr_in_db(p_db, p_char_dscptr); GATT_TRACE_DEBUG("gatts_add_char_descr Fail for adding char descriptors."); return 0; - } else { - if (control != NULL) { - p_char_dscptr->control.auto_rsp = control->auto_rsp; - } + } + else { + p_char_dscptr->control.auto_rsp = (control == NULL) ? GATT_RSP_DEFAULT : (control->auto_rsp); if (attr_val != NULL) { if (!copy_extra_byte_in_db(p_db, (void **)&p_char_dscptr->p_value, sizeof(tGATT_ATTR_VAL))) { deallocate_attr_in_db(p_db, p_char_dscptr); @@ -599,12 +662,16 @@ UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, p_char_dscptr->p_value->attr_val.attr_max_len = attr_val->attr_max_len; if (attr_val->attr_max_len != 0) { p_char_dscptr->p_value->attr_val.attr_val = GKI_getbuf(attr_val->attr_max_len); - if (p_char_dscptr->p_value->attr_val.attr_val != NULL) { - memset(p_char_dscptr->p_value->attr_val.attr_val, 0, attr_val->attr_max_len); - if(attr_val->attr_val != NULL) { - memcpy(p_char_dscptr->p_value->attr_val.attr_val, - attr_val->attr_val, attr_val->attr_len); - } + if (p_char_dscptr->p_value->attr_val.attr_val == NULL) { + deallocate_attr_in_db(p_db, p_char_dscptr); + GATT_TRACE_ERROR("Warning in %s, line=%d, insufficient resource to allocate for descriptor value\n", __func__, __LINE__); + return 0; + } + + //initiate characteristic attribute value part + memset(p_char_dscptr->p_value->attr_val.attr_val, 0, attr_val->attr_max_len); + if(attr_val->attr_val != NULL) { + memcpy(p_char_dscptr->p_value->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len); } } } @@ -628,7 +695,7 @@ UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, ** *******************************************************************************/ tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, - UINT16 length, UINT8 *value) + UINT16 length, UINT8 *value) { tGATT_ATTR16 *p_cur; @@ -640,51 +707,48 @@ tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, GATT_TRACE_DEBUG("gatts_set_attribute_value Fail:p_db->p_attr_list is NULL.\n"); return GATT_INVALID_PDU; } + if ((length > 0) && (value == NULL)){ + GATT_TRACE_ERROR("Error in %s, line=%d, value should not be NULL here\n",__func__, __LINE__); + return GATT_INVALID_PDU; + } p_cur = (tGATT_ATTR16 *) p_db->p_attr_list; while (p_cur != NULL) { if (p_cur->handle == attr_handle) { - + /* for characteristic should not be set, return GATT_NOT_FOUND */ if (p_cur->uuid_type == GATT_ATTR_UUID_TYPE_16) { switch (p_cur->uuid) { - case GATT_UUID_PRI_SERVICE: - case GATT_UUID_SEC_SERVICE: - case GATT_UUID_CHAR_DECLARE: - case GATT_UUID_INCLUDE_SERVICE: - return GATT_NOT_FOUND; - default: - if (p_cur->p_value != NULL && p_cur->p_value->attr_val.attr_max_len < length) { - GATT_TRACE_ERROR("gatts_set_attribute_vaule failt:Invalid value length"); - return GATT_INVALID_ATTR_LEN; - } else if (p_cur->p_value != NULL && p_cur->p_value->attr_val.attr_max_len > 0) { - memcpy(p_cur->p_value->attr_val.attr_val, value, length); - p_cur->p_value->attr_val.attr_len = length; - } else { - return GATT_INVALID_ATTR_LEN; - } - break; - } - } else { - if (p_cur->p_value != NULL && p_cur->p_value->attr_val.attr_max_len < length) { - GATT_TRACE_ERROR("gatts_set_attribute_vaule failt:Invalid value length"); - } else if (p_cur->p_value != NULL && p_cur->p_value->attr_val.attr_max_len > 0) { - memcpy(p_cur->p_value->attr_val.attr_val, value, length); - p_cur->p_value->attr_val.attr_len = length; - } else { - return GATT_INVALID_ATTR_LEN; + case GATT_UUID_PRI_SERVICE: + case GATT_UUID_SEC_SERVICE: + case GATT_UUID_CHAR_DECLARE: + return GATT_NOT_FOUND; + break; } } + + /* in other cases, value can be set*/ + if ((p_cur->p_value == NULL) || (p_cur->p_value->attr_val.attr_val == NULL) \ + || (p_cur->p_value->attr_val.attr_max_len == 0)){ + GATT_TRACE_ERROR("Error in %s, line=%d, attribute value should not be NULL here\n", __func__, __LINE__); + return GATT_NOT_FOUND; + } + else if (p_cur->p_value->attr_val.attr_max_len < length) { + GATT_TRACE_ERROR("gatts_set_attribute_value failed:Invalid value length"); + return GATT_INVALID_ATTR_LEN; + } + else{ + memcpy(p_cur->p_value->attr_val.attr_val, value, length); + p_cur->p_value->attr_val.attr_len = length; + } break; } - p_cur = p_cur->p_next; } return GATT_SUCCESS; } - /******************************************************************************* ** ** Function gatts_get_attribute_value @@ -875,20 +939,27 @@ tGATT_STATUS gatts_write_attr_value_by_handle(tGATT_SVC_DB *p_db, return GATT_APP_RSP; } - if (p_attr->p_value != NULL && (p_attr->p_value->attr_val.attr_max_len >= - offset + len) && p_attr->p_value->attr_val.attr_val != NULL) { + if ((p_attr->p_value != NULL) && + (p_attr->p_value->attr_val.attr_max_len >= offset + len) && + p_attr->p_value->attr_val.attr_val != NULL) { memcpy(p_attr->p_value->attr_val.attr_val + offset, p_value, len); p_attr->p_value->attr_val.attr_len = len + offset; return GATT_SUCCESS; - } else { - return GATT_NOT_LONG; + } + else if (p_attr->p_value->attr_val.attr_max_len < offset + len){ + GATT_TRACE_DEBUG("Remote device try to write with a length larger then attribute's max length\n"); + return GATT_INVALID_ATTR_LEN; + } + else if ((p_attr->p_value == NULL) || (p_attr->p_value->attr_val.attr_val == NULL)){ + GATT_TRACE_ERROR("Error in %s, line=%d, %s should not be NULL here\n", __func__, __LINE__, \ + (p_attr->p_value == NULL) ? "p_value" : "attr_val.attr_val"); + return GATT_ESP_ERROR; } } p_attr = (tGATT_ATTR16 *)p_attr->p_next; } - } return status; diff --git a/components/bt/bluedroid/stack/gatt/gatt_sr.c b/components/bt/bluedroid/stack/gatt/gatt_sr.c index 2d34a0504..317eaaca7 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_sr.c +++ b/components/bt/bluedroid/stack/gatt/gatt_sr.c @@ -33,6 +33,42 @@ #define GATT_MTU_REQ_MIN_LEN 2 + +/******************************************************************************* +** +** Function gatt_send_packet +** +** Description This function is called to send gatt packets directly + +** +** Returns status +** +*******************************************************************************/ +tGATT_STATUS gatt_send_packet (tGATT_TCB *p_tcb, UINT8 *p_data, UINT16 len) +{ + BT_HDR *p_msg = NULL; + UINT8 *p_m = NULL; + UINT16 buf_len; + tGATT_STATUS status; + + if (len > p_tcb->payload_size){ + return GATT_ILLEGAL_PARAMETER; + } + + buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET); + if ((p_msg = (BT_HDR *)GKI_getbuf(buf_len)) == NULL) { + return GATT_NO_RESOURCES; + } + + memset(p_msg, 0, buf_len); + p_msg->len = len; + p_m = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET; + memcpy(p_m, p_data, len); + + status = attp_send_sr_msg(p_tcb, p_msg); + return status; +} + /******************************************************************************* ** ** Function gatt_sr_enqueue_cmd @@ -300,7 +336,11 @@ void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, U UINT32 trans_id = 0; tGATT_IF gatt_if; UINT16 conn_id; - + UINT16 queue_num = 0; + BOOLEAN is_prepare_write_valid = FALSE; + BOOLEAN is_need_dequeue_sr_cmd = FALSE; + tGATT_PREPARE_WRITE_RECORD *prepare_record = NULL; + tGATT_PREPARE_WRITE_QUEUE_DATA * queue_data = NULL; UNUSED(len); #if GATT_CONFORMANCE_TESTING == TRUE @@ -319,11 +359,63 @@ void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, U /* mask the flag */ flag &= GATT_PREP_WRITE_EXEC; + prepare_record = &(p_tcb->prepare_write_record); + queue_num = prepare_record->queue._count; + - /* no prep write is queued */ + //if received prepare_write packets include stack_rsp and app_rsp, + //stack respond to execute_write only when stack_rsp handle has invalid_offset + //or invalid_length error; + //app need to respond to execute_write if it has received app_rsp handle packets + if (((prepare_record->error_code_app == GATT_SUCCESS) && + (prepare_record->total_num == queue_num)) + || (flag == GATT_PREP_WRITE_CANCEL)){ + tGATT_EXEC_WRITE_RSP gatt_exec_write_rsp; + gatt_exec_write_rsp.op_code = GATT_RSP_EXEC_WRITE; + gatt_send_packet(p_tcb, (UINT8 *)(&gatt_exec_write_rsp), sizeof(gatt_exec_write_rsp)); + gatt_dequeue_sr_cmd(p_tcb); + if (flag != GATT_PREP_WRITE_CANCEL){ + is_prepare_write_valid = TRUE; + } + GATT_TRACE_DEBUG("Send execute_write_rsp\n"); + } + else if ((prepare_record->error_code_app == GATT_SUCCESS) && + (prepare_record->total_num > queue_num)){ + //No error for stack_rsp's handles and there exist some app_rsp's handles, + //so exec_write_rsp depends to app's response; but stack_rsp's data is valid + //TODO: there exist problem if stack_rsp's data is valid but app_rsp's data is not valid. + is_prepare_write_valid = TRUE; + } + else if(prepare_record->total_num < queue_num) { + GATT_TRACE_ERROR("Error in %s, line=%d, prepare write total number(=%d) \ + should not smaller than prepare queue number(=%d)\n", \ + __func__, __LINE__,prepare_record->total_num, queue_num); + } + else if (prepare_record->error_code_app != GATT_SUCCESS){ + GATT_TRACE_DEBUG("Send error code for execute_write, code=0x%x\n", prepare_record->error_code_app); + is_need_dequeue_sr_cmd = (prepare_record->total_num == queue_num) ? TRUE : FALSE; + gatt_send_error_rsp(p_tcb, prepare_record->error_code_app, GATT_REQ_EXEC_WRITE, 0, is_need_dequeue_sr_cmd); + } + + //dequeue prepare write data + while(GKI_getfirst(&(prepare_record->queue))) { + queue_data = GKI_dequeue(&(prepare_record->queue)); + if (is_prepare_write_valid){ + if((queue_data->p_attr->p_value != NULL) && (queue_data->p_attr->p_value->attr_val.attr_val != NULL)){ + memcpy(queue_data->p_attr->p_value->attr_val.attr_val+queue_data->offset, queue_data->value, queue_data->len); + } + } + GKI_freebuf(queue_data); + } + + /* according to ble spec, even if there is no prep write queued, + * need to respond execute_write_response + * Note: exec_write_rsp callback should be called after all data has been written*/ if (!gatt_sr_is_prep_cnt_zero(p_tcb)) { - trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, 0); - gatt_sr_copy_prep_cnt_to_cback_cnt(p_tcb); + if (prepare_record->total_num > queue_num){ + trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, 0); + gatt_sr_copy_prep_cnt_to_cback_cnt(p_tcb); + } for (i = 0; i < GATT_MAX_APPS; i++) { if (p_tcb->prep_cnt[i]) { @@ -336,10 +428,10 @@ void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, U p_tcb->prep_cnt[i] = 0; } } - } else { /* nothing needs to be executed , send response now */ - GATT_TRACE_ERROR("gatt_process_exec_write_req: no prepare write pending"); - gatt_send_error_rsp(p_tcb, GATT_ERROR, GATT_REQ_EXEC_WRITE, 0, FALSE); } + + prepare_record->total_num = 0; + prepare_record->error_code_app = GATT_SUCCESS; } /******************************************************************************* @@ -987,54 +1079,29 @@ void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle, UINT8 op_code, UINT16 len, UINT8 *p_data) { - UINT16 buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET); tGATTS_DATA sr_data; UINT32 trans_id; tGATT_STATUS status; - UINT8 sec_flag, key_size, *p = p_data, *p_m; + UINT8 sec_flag, key_size, *p = p_data; tGATT_SR_REG *p_sreg; UINT16 conn_id, offset = 0; - BT_HDR *p_msg = NULL; + memset(&sr_data, 0, sizeof(tGATTS_DATA)); + sr_data.write_req.need_rsp = FALSE; - if ((p_msg = (BT_HDR *)GKI_getbuf(buf_len)) == NULL) { - GATT_TRACE_ERROR("gatts_process_write_req failed. no resources.\n"); - } - - memset(p_msg, 0, buf_len); - p_m = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET; - *p_m ++ = op_code + 1; - p_msg->len = 1; - buf_len = p_tcb->payload_size - 1; - switch (op_code) { - case GATT_REQ_PREPARE_WRITE: - sr_data.write_req.is_prep = TRUE; - STREAM_TO_UINT16(sr_data.write_req.offset, p); - UINT16_TO_STREAM(p_m, sr_data.write_req.is_prep); - offset = sr_data.write_req.offset; - len -= 2; - /* fall through */ case GATT_SIGN_CMD_WRITE: if (op_code == GATT_SIGN_CMD_WRITE) { - GATT_TRACE_DEBUG("Write CMD with data sigining" ); + GATT_TRACE_DEBUG("Write CMD with data signing" ); len -= GATT_AUTH_SIGN_LEN; } /* fall through */ case GATT_CMD_WRITE: case GATT_REQ_WRITE: - if (op_code == GATT_REQ_WRITE || op_code == GATT_REQ_PREPARE_WRITE) { - sr_data.write_req.need_rsp = TRUE; - if(op_code == GATT_REQ_PREPARE_WRITE){ - memcpy(p_m, p, len); - p_msg->len += len; - } - } sr_data.write_req.handle = handle; sr_data.write_req.len = len; if (len != 0 && p != NULL) { memcpy (sr_data.write_req.value, p, len); - } break; } @@ -1059,42 +1126,194 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle, conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_sreg->gatt_if); status = gatts_write_attr_value_by_handle(gatt_cb.sr_reg[i_rcb].p_db, handle, offset, p, len); - if((sr_data.write_req.need_rsp == TRUE) && (status == GATT_APP_RSP)){ + if((op_code == GATT_REQ_WRITE) && (status == GATT_APP_RSP)){ sr_data.write_req.need_rsp = TRUE; status = GATT_PENDING; } - else{ - sr_data.write_req.need_rsp = FALSE; - } - gatt_sr_send_req_callback(conn_id, trans_id, GATTS_REQ_TYPE_WRITE, &sr_data); - - if (status == GATT_SUCCESS) { - attp_send_sr_msg(p_tcb, p_msg); - gatt_dequeue_sr_cmd(p_tcb); - } else { - GKI_freebuf(p_msg); - } - - } else { - GATT_TRACE_ERROR("max pending command, send error\n"); + } + else { + GATT_TRACE_ERROR("Error in %s, line=%d, max pending command, send error\n", __func__, __LINE__); status = GATT_BUSY; /* max pending command, application error */ } } + //test isl + GATT_TRACE_ERROR("!!!write opcode=0x%x, need_rsp=0x%x, status=0x%x\n",op_code, sr_data.write_req.need_rsp, status); - /* in theroy BUSY is not possible(should already been checked), protected check */ - if (status != GATT_PENDING && status != GATT_BUSY && status != GATT_SUCCESS && - (op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_REQ_WRITE)) { - gatt_send_error_rsp (p_tcb, status, op_code, handle, FALSE); - gatt_dequeue_sr_cmd(p_tcb); + /* response should be sent only for write_request */ + if ((op_code == GATT_REQ_WRITE) && (sr_data.write_req.need_rsp == FALSE)){ + if (status == GATT_SUCCESS){ + tGATT_WRITE_REQ_RSP gatt_write_req_rsp; + gatt_write_req_rsp.op_code = GATT_RSP_WRITE; + gatt_send_packet(p_tcb, (UINT8 *)(&gatt_write_req_rsp), sizeof(gatt_write_req_rsp)); + gatt_dequeue_sr_cmd(p_tcb); + } + else if (status != GATT_PENDING){ + /* note: in case of GATT_BUSY, will respond this application error to remote device */ + gatt_send_error_rsp (p_tcb, status, op_code, handle, TRUE); + } } + return; } + +/******************************************************************************* + ** + ** Function gatts_attr_process_preapre_write + ** + ** Description This function is called to process the prepare write request + ** from client. + ** + ** Returns void + ** + *******************************************************************************/ +void gatt_attr_process_prepare_write (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle, + UINT8 op_code, UINT16 len, UINT8 *p_data) +{ + tGATT_STATUS status; + tGATT_PREPARE_WRITE_QUEUE_DATA * queue_data = NULL; + tGATT_ATTR16 *p_attr; + tGATT_ATTR16 *p_attr_temp; + tGATTS_DATA sr_data; + UINT32 trans_id = 0; + UINT8 sec_flag, key_size, *p = p_data; + tGATT_SR_REG *p_sreg; + UINT16 conn_id, offset = 0; + tGATT_SVC_DB *p_db; + BOOLEAN is_need_prepare_write_rsp = FALSE; + BOOLEAN is_need_queue_data = FALSE; + tGATT_PREPARE_WRITE_RECORD *prepare_record = NULL; + memset(&sr_data, 0, sizeof(tGATTS_DATA)); + + //get offset from p_data + STREAM_TO_UINT16(offset, p); + len -= 2; + p_sreg = &gatt_cb.sr_reg[i_rcb]; + conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_sreg->gatt_if); + //prepare_record = &(prepare_write_record); + prepare_record = &(p_tcb->prepare_write_record); + + gatt_sr_get_sec_info(p_tcb->peer_bda, + p_tcb->transport, + &sec_flag, + &key_size); + + status = gatts_write_attr_perm_check (gatt_cb.sr_reg[i_rcb].p_db, + op_code, + handle, + sr_data.write_req.offset, + p, + len, + sec_flag, + key_size); + + if (status == GATT_SUCCESS){ + if ((trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, handle)) != 0) { + p_db = gatt_cb.sr_reg[i_rcb].p_db; + if (p_db && p_db->p_attr_list) { + p_attr = (tGATT_ATTR16 *)p_db->p_attr_list; + while (p_attr && handle >= p_attr->handle) { + if (p_attr->handle == handle ) { + p_attr_temp = p_attr; + if (p_attr->control.auto_rsp == GATT_RSP_BY_APP) { + status = GATT_APP_RSP; + } + else if (p_attr->p_value != NULL && + offset > p_attr->p_value->attr_val.attr_max_len) { + status = GATT_INVALID_OFFSET; + is_need_prepare_write_rsp = TRUE; + is_need_queue_data = TRUE; + } + else if (p_attr->p_value != NULL && + ((offset + len) > p_attr->p_value->attr_val.attr_max_len)){ + status = GATT_INVALID_ATTR_LEN; + is_need_prepare_write_rsp = TRUE; + is_need_queue_data = TRUE; + } + else if (p_attr->p_value == NULL) { + LOG_ERROR("Error in %s, attribute of handle 0x%x not allocate value buffer\n", + __func__, handle); + status = GATT_ESP_ERROR; + } + else { + //valid prepare write request, need to send response and queue the data + //status: GATT_SUCCESS + is_need_prepare_write_rsp = TRUE; + is_need_queue_data = TRUE; + } + } + p_attr = (tGATT_ATTR16 *)p_attr->p_next; + } + } + } + else{ + status = GATT_ESP_ERROR; + GATT_TRACE_ERROR("Error in %s, Line %d: GATT BUSY\n", __func__, __LINE__); + } + } + + if (is_need_queue_data){ + queue_data = (tGATT_PREPARE_WRITE_QUEUE_DATA *)GKI_getbuf(len + sizeof(tGATT_PREPARE_WRITE_QUEUE_DATA)); + if (queue_data == NULL){ + status = GATT_PREPARE_Q_FULL; + } + else { + queue_data->p_attr = p_attr_temp; + queue_data->len = len; + queue_data->handle = handle; + queue_data->offset = offset; + memcpy(queue_data->value, p, len); + GKI_enqueue(&(prepare_record->queue), queue_data); + } + } + + if (is_need_prepare_write_rsp){ + //send prepare write response + if (queue_data != NULL){ + queue_data->op_code = op_code + 1; + //5: op_code 1 + handle 2 + offset 2 + tGATT_STATUS rsp_send_status = gatt_send_packet(p_tcb, &(queue_data->op_code), queue_data->len + 5); + gatt_sr_update_prep_cnt(p_tcb, p_sreg->gatt_if, TRUE, FALSE); + gatt_dequeue_sr_cmd(p_tcb); + + if (rsp_send_status != GATT_SUCCESS){ + LOG_ERROR("Error in %s, line=%d, fail to send prepare_write_rsp, status=0x%x\n", + __func__, __LINE__, rsp_send_status); + } + } + else{ + LOG_ERROR("Error in %s, line=%d, queue_data should not be NULL here, fail to send prepare_write_rsp\n", + __func__, __LINE__); + } + } + + if ((status == GATT_APP_RSP) || (is_need_prepare_write_rsp)){ + prepare_record->total_num++; + memset(&sr_data, 0, sizeof(sr_data)); + sr_data.write_req.is_prep = TRUE; + sr_data.write_req.handle = handle; + sr_data.write_req.offset = offset; + sr_data.write_req.len = len; + sr_data.write_req.need_rsp = (status == GATT_APP_RSP) ? TRUE : FALSE; + memcpy(sr_data.write_req.value, p, len); + gatt_sr_send_req_callback(conn_id, trans_id, GATTS_REQ_TYPE_WRITE, &sr_data); + } + else{ + gatt_send_error_rsp(p_tcb, status, GATT_REQ_PREPARE_WRITE, handle, TRUE); + } + + if ((prepare_record->error_code_app == GATT_SUCCESS) + && ((status == GATT_INVALID_OFFSET) || (status == GATT_INVALID_ATTR_LEN))){ + prepare_record->error_code_app = status; + } + +} + /******************************************************************************* ** ** Function gatts_process_read_req @@ -1226,9 +1445,11 @@ void gatts_process_attribute_req (tGATT_TCB *p_tcb, UINT8 op_code, case GATT_REQ_WRITE: /* write char/char descriptor value */ case GATT_CMD_WRITE: case GATT_SIGN_CMD_WRITE: - case GATT_REQ_PREPARE_WRITE: gatts_process_write_req(p_tcb, i, handle, op_code, len, p); break; + + case GATT_REQ_PREPARE_WRITE: + gatt_attr_process_prepare_write (p_tcb, i, handle, op_code, len, p); default: break; } diff --git a/components/bt/bluedroid/stack/gatt/gatt_utils.c b/components/bt/bluedroid/stack/gatt/gatt_utils.c index 09f4e8df2..60f99966b 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_utils.c +++ b/components/bt/bluedroid/stack/gatt/gatt_utils.c @@ -116,6 +116,26 @@ void gatt_free_pending_enc_queue(tGATT_TCB *p_tcb) } } +/******************************************************************************* +** +** Function gatt_free_pending_prepare_write_queue +** +** Description Free all buffers in pending prepare write packets queue +** +** Returns None +** +*******************************************************************************/ +void gatt_free_pending_prepare_write_queue(tGATT_TCB *p_tcb) +{ + GATT_TRACE_DEBUG("gatt_free_pending_prepare_write_queue"); + /* release all queued prepare write packets */ + while (!GKI_queue_is_empty(&(p_tcb->prepare_write_record.queue))) { + GKI_freebuf (GKI_dequeue (&(p_tcb->prepare_write_record.queue))); + } + p_tcb->prepare_write_record.total_num = 0; + p_tcb->prepare_write_record.error_code_app = GATT_SUCCESS; +} + /******************************************************************************* ** ** Function gatt_delete_dev_from_srv_chg_clt_list @@ -2108,6 +2128,7 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport) btu_stop_timer (&p_tcb->conf_timer_ent); gatt_free_pending_ind(p_tcb); gatt_free_pending_enc_queue(p_tcb); + gatt_free_pending_prepare_write_queue(p_tcb); for (i = 0; i < GATT_MAX_APPS; i ++) { p_reg = &gatt_cb.cl_rcb[i]; diff --git a/components/bt/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/bluedroid/stack/gatt/include/gatt_int.h index c9622a24c..9aca0c5df 100644 --- a/components/bt/bluedroid/stack/gatt/include/gatt_int.h +++ b/components/bt/bluedroid/stack/gatt/include/gatt_int.h @@ -133,6 +133,16 @@ typedef struct { UINT8 reason; } tGATT_ERROR; +/* Execute write response structure */ +typedef struct { + UINT8 op_code; +}__attribute__((packed)) tGATT_EXEC_WRITE_RSP; + +/* Write request response structure */ +typedef struct { + UINT8 op_code; +}__attribute__((packed)) tGATT_WRITE_REQ_RSP; + /* server response message to ATT protocol */ typedef union { @@ -329,6 +339,32 @@ typedef struct { UINT16 count; } tGATT_SRV_LIST_INFO; +/* prepare write queue data */ +typedef struct{ + //len: length of value + tGATT_ATTR16 *p_attr; + UINT16 len; + UINT8 op_code; + UINT16 handle; + UINT16 offset; + UINT8 value[2]; +}__attribute__((packed)) tGATT_PREPARE_WRITE_QUEUE_DATA; + +/* structure to store prepare write packts information */ +typedef struct{ + //only store prepare write packets which need + //to be responded by stack (not by application) + BUFFER_Q queue; + + //store the total number of prepare write packets + //including that should be responded by stack or by application + UINT16 total_num; + + //store application error code for prepare write, + //invalid offset && invalid length + UINT8 error_code_app; +}tGATT_PREPARE_WRITE_RECORD; + typedef struct { BUFFER_Q pending_enc_clcb; /* pending encryption channel q */ tGATT_SEC_ACTION sec_act; @@ -362,6 +398,7 @@ typedef struct { BOOLEAN in_use; UINT8 tcb_idx; + tGATT_PREPARE_WRITE_RECORD prepare_write_record; /* prepare write packets record */ } tGATT_TCB; diff --git a/components/bt/bluedroid/stack/include/gatt_api.h b/components/bt/bluedroid/stack/include/gatt_api.h index 9360d4fbf..42812a5be 100644 --- a/components/bt/bluedroid/stack/include/gatt_api.h +++ b/components/bt/bluedroid/stack/include/gatt_api.h @@ -65,6 +65,8 @@ #define GATT_CONGESTED 0x8f #define GATT_STACK_RSP 0x90 #define GATT_APP_RSP 0x91 +//Error caused by customer application or stack bug +#define GATT_ESP_ERROR 0X9f /* 0xE0 ~ 0xFC reserved for future use */ #define GATT_CCC_CFG_ERR 0xFD /* Client Characteristic Configuration Descriptor Improperly Configured */ From 5ffe5474acc5f5ff7a2d74ff57f8bc865c489fef Mon Sep 17 00:00:00 2001 From: island Date: Tue, 7 Mar 2017 19:55:21 +0800 Subject: [PATCH 2/4] bt component: optimize gatt debug information --- components/bt/bluedroid/api/esp_gatts_api.c | 8 ++++---- components/bt/bluedroid/stack/gatt/gatt_db.c | 10 +++++----- components/bt/bluedroid/stack/gatt/gatt_sr.c | 6 ++---- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/components/bt/bluedroid/api/esp_gatts_api.c b/components/bt/bluedroid/api/esp_gatts_api.c index 3a31d7959..3e5d8f581 100644 --- a/components/bt/bluedroid/api/esp_gatts_api.c +++ b/components/bt/bluedroid/api/esp_gatts_api.c @@ -158,8 +158,8 @@ esp_err_t esp_ble_gatts_add_char(uint16_t service_handle, esp_bt_uuid_t *char_ if (char_val != NULL){ if (char_val->attr_len > char_val->attr_max_len){ - LOG_ERROR("Error in %s, line=%d,attribute actual length should not be larger than max length\n",\ - __func__, __LINE__); + LOG_ERROR("Error in %s, line=%d,attribute actual length (%d) should not be larger than max length (%d)\n",\ + __func__, __LINE__, char_val->attr_len, char_val->attr_max_len); return ESP_ERR_INVALID_ARG; } } @@ -214,8 +214,8 @@ esp_err_t esp_ble_gatts_add_char_descr (uint16_t service_handle, if (char_descr_val != NULL){ if (char_descr_val->attr_len > char_descr_val->attr_max_len){ - LOG_ERROR("Error in %s, line=%d,attribute actual length should not be larger than max length\n",\ - __func__, __LINE__); + LOG_ERROR("Error in %s, line=%d,attribute actual length (%d) should not be larger than max length (%d)\n",\ + __func__, __LINE__, char_descr_val->attr_len, char_descr_val->attr_max_len); return ESP_ERR_INVALID_ARG; } } diff --git a/components/bt/bluedroid/stack/gatt/gatt_db.c b/components/bt/bluedroid/stack/gatt/gatt_db.c index 60749a0f4..3f9066d05 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_db.c +++ b/components/bt/bluedroid/stack/gatt/gatt_db.c @@ -528,7 +528,7 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, if (p_char_val->p_value->attr_val.attr_val == NULL) { deallocate_attr_in_db(p_db, p_char_decl); deallocate_attr_in_db(p_db, p_char_val); - GATT_TRACE_ERROR("Warning in %s, line=%d, insufficient resource to allocate for attribute value\n", __func__, __LINE__); + GATT_TRACE_WARNING("Warning in %s, line=%d, insufficient resource to allocate for attribute value\n", __func__, __LINE__); return 0; } @@ -536,7 +536,7 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, memset(p_char_val->p_value->attr_val.attr_val, 0, attr_val->attr_max_len); if (attr_val->attr_val != NULL) { if (attr_val->attr_max_len < attr_val->attr_len){ - GATT_TRACE_ERROR("Error in %s, Line=%d, attribute actual length(%d) should not larger than max size(%d)\n", + GATT_TRACE_ERROR("Error in %s, Line=%d, attribute actual length (%d) should not larger than max size (%d)\n", __func__, __LINE__, attr_val->attr_len, attr_val->attr_max_len); } UINT16 actual_len = (attr_val->attr_max_len < attr_val->attr_len) ? (attr_val->attr_max_len) : (attr_val->attr_len); @@ -638,8 +638,8 @@ UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, if (attr_val != NULL){ if (attr_val->attr_len > attr_val->attr_max_len){ - GATT_TRACE_ERROR("Error in %s, line=%d,attribute actual length should not be larger than max length\n",\ - __func__, __LINE__); + GATT_TRACE_ERROR("Error in %s, line=%d,attribute actual length (%d) should not be larger than max length (%d)\n",\ + __func__, __LINE__, attr_val->attr_len, attr_val->attr_max_len); return 0; } } @@ -664,7 +664,7 @@ UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, p_char_dscptr->p_value->attr_val.attr_val = GKI_getbuf(attr_val->attr_max_len); if (p_char_dscptr->p_value->attr_val.attr_val == NULL) { deallocate_attr_in_db(p_db, p_char_dscptr); - GATT_TRACE_ERROR("Warning in %s, line=%d, insufficient resource to allocate for descriptor value\n", __func__, __LINE__); + GATT_TRACE_WARNING("Warning in %s, line=%d, insufficient resource to allocate for descriptor value\n", __func__, __LINE__); return 0; } diff --git a/components/bt/bluedroid/stack/gatt/gatt_sr.c b/components/bt/bluedroid/stack/gatt/gatt_sr.c index 317eaaca7..4afcab794 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_sr.c +++ b/components/bt/bluedroid/stack/gatt/gatt_sr.c @@ -387,8 +387,8 @@ void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, U is_prepare_write_valid = TRUE; } else if(prepare_record->total_num < queue_num) { - GATT_TRACE_ERROR("Error in %s, line=%d, prepare write total number(=%d) \ - should not smaller than prepare queue number(=%d)\n", \ + GATT_TRACE_ERROR("Error in %s, line=%d, prepare write total number (%d) \ + should not smaller than prepare queue number (%d)\n", \ __func__, __LINE__,prepare_record->total_num, queue_num); } else if (prepare_record->error_code_app != GATT_SUCCESS){ @@ -1141,8 +1141,6 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle, status = GATT_BUSY; /* max pending command, application error */ } } - //test isl - GATT_TRACE_ERROR("!!!write opcode=0x%x, need_rsp=0x%x, status=0x%x\n",op_code, sr_data.write_req.need_rsp, status); /* response should be sent only for write_request */ if ((op_code == GATT_REQ_WRITE) && (sr_data.write_req.need_rsp == FALSE)){ From 3543d8170c4658933d13c2c66996e1895fe20ac8 Mon Sep 17 00:00:00 2001 From: island Date: Wed, 8 Mar 2017 17:00:56 +0800 Subject: [PATCH 3/4] =?UTF-8?q?bt=20component:=20update=20if=E2=80=A6else?= =?UTF-8?q?=20code=20style?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/bt/bluedroid/stack/gatt/gatt_db.c | 9 +++------ components/bt/bluedroid/stack/gatt/gatt_sr.c | 18 ++++++------------ 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/components/bt/bluedroid/stack/gatt/gatt_db.c b/components/bt/bluedroid/stack/gatt/gatt_db.c index 3f9066d05..525375a05 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_db.c +++ b/components/bt/bluedroid/stack/gatt/gatt_db.c @@ -276,8 +276,7 @@ static tGATT_STATUS read_attr_value (void *p_attr, //if offset is greater than max_len, should respond with an error*/ else if (offset > p_attr16->p_value->attr_val.attr_len){ status = GATT_INVALID_OFFSET; - } - else { + } else { UINT8 *value = (UINT8 *)(p_attr16->p_value->attr_val.attr_val) + offset; UINT16 len_left = p_attr16->p_value->attr_val.attr_len - offset; len = (mtu >= len_left) ? (len_left) : mtu; @@ -650,8 +649,7 @@ UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, deallocate_attr_in_db(p_db, p_char_dscptr); GATT_TRACE_DEBUG("gatts_add_char_descr Fail for adding char descriptors."); return 0; - } - else { + } else { p_char_dscptr->control.auto_rsp = (control == NULL) ? GATT_RSP_DEFAULT : (control->auto_rsp); if (attr_val != NULL) { if (!copy_extra_byte_in_db(p_db, (void **)&p_char_dscptr->p_value, sizeof(tGATT_ATTR_VAL))) { @@ -736,8 +734,7 @@ tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, else if (p_cur->p_value->attr_val.attr_max_len < length) { GATT_TRACE_ERROR("gatts_set_attribute_value failed:Invalid value length"); return GATT_INVALID_ATTR_LEN; - } - else{ + } else{ memcpy(p_cur->p_value->attr_val.attr_val, value, length); p_cur->p_value->attr_val.attr_len = length; } diff --git a/components/bt/bluedroid/stack/gatt/gatt_sr.c b/components/bt/bluedroid/stack/gatt/gatt_sr.c index 4afcab794..d43a3a2c8 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_sr.c +++ b/components/bt/bluedroid/stack/gatt/gatt_sr.c @@ -1135,8 +1135,7 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle, trans_id, GATTS_REQ_TYPE_WRITE, &sr_data); - } - else { + } else { GATT_TRACE_ERROR("Error in %s, line=%d, max pending command, send error\n", __func__, __LINE__); status = GATT_BUSY; /* max pending command, application error */ } @@ -1237,8 +1236,7 @@ void gatt_attr_process_prepare_write (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 hand LOG_ERROR("Error in %s, attribute of handle 0x%x not allocate value buffer\n", __func__, handle); status = GATT_ESP_ERROR; - } - else { + } else { //valid prepare write request, need to send response and queue the data //status: GATT_SUCCESS is_need_prepare_write_rsp = TRUE; @@ -1248,8 +1246,7 @@ void gatt_attr_process_prepare_write (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 hand p_attr = (tGATT_ATTR16 *)p_attr->p_next; } } - } - else{ + } else{ status = GATT_ESP_ERROR; GATT_TRACE_ERROR("Error in %s, Line %d: GATT BUSY\n", __func__, __LINE__); } @@ -1259,8 +1256,7 @@ void gatt_attr_process_prepare_write (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 hand queue_data = (tGATT_PREPARE_WRITE_QUEUE_DATA *)GKI_getbuf(len + sizeof(tGATT_PREPARE_WRITE_QUEUE_DATA)); if (queue_data == NULL){ status = GATT_PREPARE_Q_FULL; - } - else { + } else { queue_data->p_attr = p_attr_temp; queue_data->len = len; queue_data->handle = handle; @@ -1283,8 +1279,7 @@ void gatt_attr_process_prepare_write (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 hand LOG_ERROR("Error in %s, line=%d, fail to send prepare_write_rsp, status=0x%x\n", __func__, __LINE__, rsp_send_status); } - } - else{ + } else{ LOG_ERROR("Error in %s, line=%d, queue_data should not be NULL here, fail to send prepare_write_rsp\n", __func__, __LINE__); } @@ -1300,8 +1295,7 @@ void gatt_attr_process_prepare_write (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 hand sr_data.write_req.need_rsp = (status == GATT_APP_RSP) ? TRUE : FALSE; memcpy(sr_data.write_req.value, p, len); gatt_sr_send_req_callback(conn_id, trans_id, GATTS_REQ_TYPE_WRITE, &sr_data); - } - else{ + } else{ gatt_send_error_rsp(p_tcb, status, GATT_REQ_PREPARE_WRITE, handle, TRUE); } From a74f3f9fd731fecd6467fdbd1801399a09a84c45 Mon Sep 17 00:00:00 2001 From: island Date: Wed, 8 Mar 2017 17:09:05 +0800 Subject: [PATCH 4/4] bt component: code style update --- components/bt/bluedroid/api/esp_gatts_api.c | 3 +-- components/bt/bluedroid/stack/gatt/gatt_db.c | 19 +++++++----------- components/bt/bluedroid/stack/gatt/gatt_sr.c | 21 +++++++------------- 3 files changed, 15 insertions(+), 28 deletions(-) diff --git a/components/bt/bluedroid/api/esp_gatts_api.c b/components/bt/bluedroid/api/esp_gatts_api.c index 3e5d8f581..318dd25bf 100644 --- a/components/bt/bluedroid/api/esp_gatts_api.c +++ b/components/bt/bluedroid/api/esp_gatts_api.c @@ -148,8 +148,7 @@ esp_err_t esp_ble_gatts_add_char(uint16_t service_handle, esp_bt_uuid_t *char_ LOG_ERROR("Error in %s, line=%d, for stack respond attribute, char_val should not be NULL here\n",\ __func__, __LINE__); return ESP_ERR_INVALID_ARG; - } - else if (char_val->attr_max_len == 0){ + } else if (char_val->attr_max_len == 0){ LOG_ERROR("Error in %s, line=%d, for stack respond attribute, attribute max length should not be 0\n",\ __func__, __LINE__); return ESP_ERR_INVALID_ARG; diff --git a/components/bt/bluedroid/stack/gatt/gatt_db.c b/components/bt/bluedroid/stack/gatt/gatt_db.c index 525375a05..ae4f6430f 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_db.c +++ b/components/bt/bluedroid/stack/gatt/gatt_db.c @@ -272,9 +272,9 @@ static tGATT_STATUS read_attr_value (void *p_attr, if (p_attr16->p_value == NULL || p_attr16->p_value->attr_val.attr_val == NULL) { status = GATT_ESP_ERROR; } - /*if offset equal to max_len, should respond with zero byte value - //if offset is greater than max_len, should respond with an error*/ else if (offset > p_attr16->p_value->attr_val.attr_len){ + /*if offset equal to max_len, should respond with zero byte value + //if offset is greater than max_len, should respond with an error*/ status = GATT_INVALID_OFFSET; } else { UINT8 *value = (UINT8 *)(p_attr16->p_value->attr_val.attr_val) + offset; @@ -476,8 +476,7 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm, GATT_TRACE_ERROR("Error in %s, line=%d, for stack respond attribute, attr_val should not be NULL here\n",\ __func__, __LINE__); return 0; - } - else if (attr_val->attr_max_len == 0){ + } else if (attr_val->attr_max_len == 0){ GATT_TRACE_ERROR("Error in %s, line=%d, for stack respond attribute, attribute max length should not be 0\n",\ __func__, __LINE__); return 0; @@ -627,8 +626,7 @@ UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm, GATT_TRACE_ERROR("Error in %s, line=%d, for stack respond attribute, attr_val should not be NULL here\n",\ __func__, __LINE__); return 0; - } - else if (attr_val->attr_max_len == 0){ + } else if (attr_val->attr_max_len == 0){ GATT_TRACE_ERROR("Error in %s, line=%d, for stack respond attribute, attribute max length should not be 0\n",\ __func__, __LINE__); return 0; @@ -730,8 +728,7 @@ tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle, || (p_cur->p_value->attr_val.attr_max_len == 0)){ GATT_TRACE_ERROR("Error in %s, line=%d, attribute value should not be NULL here\n", __func__, __LINE__); return GATT_NOT_FOUND; - } - else if (p_cur->p_value->attr_val.attr_max_len < length) { + } else if (p_cur->p_value->attr_val.attr_max_len < length) { GATT_TRACE_ERROR("gatts_set_attribute_value failed:Invalid value length"); return GATT_INVALID_ATTR_LEN; } else{ @@ -942,12 +939,10 @@ tGATT_STATUS gatts_write_attr_value_by_handle(tGATT_SVC_DB *p_db, memcpy(p_attr->p_value->attr_val.attr_val + offset, p_value, len); p_attr->p_value->attr_val.attr_len = len + offset; return GATT_SUCCESS; - } - else if (p_attr->p_value->attr_val.attr_max_len < offset + len){ + } else if (p_attr->p_value->attr_val.attr_max_len < offset + len){ GATT_TRACE_DEBUG("Remote device try to write with a length larger then attribute's max length\n"); return GATT_INVALID_ATTR_LEN; - } - else if ((p_attr->p_value == NULL) || (p_attr->p_value->attr_val.attr_val == NULL)){ + } else if ((p_attr->p_value == NULL) || (p_attr->p_value->attr_val.attr_val == NULL)){ GATT_TRACE_ERROR("Error in %s, line=%d, %s should not be NULL here\n", __func__, __LINE__, \ (p_attr->p_value == NULL) ? "p_value" : "attr_val.attr_val"); return GATT_ESP_ERROR; diff --git a/components/bt/bluedroid/stack/gatt/gatt_sr.c b/components/bt/bluedroid/stack/gatt/gatt_sr.c index d43a3a2c8..79d518398 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_sr.c +++ b/components/bt/bluedroid/stack/gatt/gatt_sr.c @@ -378,20 +378,17 @@ void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, U is_prepare_write_valid = TRUE; } GATT_TRACE_DEBUG("Send execute_write_rsp\n"); - } - else if ((prepare_record->error_code_app == GATT_SUCCESS) && + } else if ((prepare_record->error_code_app == GATT_SUCCESS) && (prepare_record->total_num > queue_num)){ //No error for stack_rsp's handles and there exist some app_rsp's handles, //so exec_write_rsp depends to app's response; but stack_rsp's data is valid //TODO: there exist problem if stack_rsp's data is valid but app_rsp's data is not valid. is_prepare_write_valid = TRUE; - } - else if(prepare_record->total_num < queue_num) { + } else if(prepare_record->total_num < queue_num) { GATT_TRACE_ERROR("Error in %s, line=%d, prepare write total number (%d) \ should not smaller than prepare queue number (%d)\n", \ __func__, __LINE__,prepare_record->total_num, queue_num); - } - else if (prepare_record->error_code_app != GATT_SUCCESS){ + } else if (prepare_record->error_code_app != GATT_SUCCESS){ GATT_TRACE_DEBUG("Send error code for execute_write, code=0x%x\n", prepare_record->error_code_app); is_need_dequeue_sr_cmd = (prepare_record->total_num == queue_num) ? TRUE : FALSE; gatt_send_error_rsp(p_tcb, prepare_record->error_code_app, GATT_REQ_EXEC_WRITE, 0, is_need_dequeue_sr_cmd); @@ -1148,8 +1145,7 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle, gatt_write_req_rsp.op_code = GATT_RSP_WRITE; gatt_send_packet(p_tcb, (UINT8 *)(&gatt_write_req_rsp), sizeof(gatt_write_req_rsp)); gatt_dequeue_sr_cmd(p_tcb); - } - else if (status != GATT_PENDING){ + } else if (status != GATT_PENDING){ /* note: in case of GATT_BUSY, will respond this application error to remote device */ gatt_send_error_rsp (p_tcb, status, op_code, handle, TRUE); } @@ -1219,20 +1215,17 @@ void gatt_attr_process_prepare_write (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 hand p_attr_temp = p_attr; if (p_attr->control.auto_rsp == GATT_RSP_BY_APP) { status = GATT_APP_RSP; - } - else if (p_attr->p_value != NULL && + } else if (p_attr->p_value != NULL && offset > p_attr->p_value->attr_val.attr_max_len) { status = GATT_INVALID_OFFSET; is_need_prepare_write_rsp = TRUE; is_need_queue_data = TRUE; - } - else if (p_attr->p_value != NULL && + } else if (p_attr->p_value != NULL && ((offset + len) > p_attr->p_value->attr_val.attr_max_len)){ status = GATT_INVALID_ATTR_LEN; is_need_prepare_write_rsp = TRUE; is_need_queue_data = TRUE; - } - else if (p_attr->p_value == NULL) { + } else if (p_attr->p_value == NULL) { LOG_ERROR("Error in %s, attribute of handle 0x%x not allocate value buffer\n", __func__, handle); status = GATT_ESP_ERROR;