ESP32 BLE读写发送----续

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhejfl/article/details/87262672

1、背景

ESP32 BLE应用理解GATT这篇文章是在是太长了,东西也太杂了,不对的对的夹杂在其中。

因此新开一个续章。以问题为节

2.问题节

2.1esp_ble_gatts_send_response

/*************************************打印记录如下********************************************************

_[0;33mW (2275295) BT_BTC: btc_gatts_arg_deep_copy 11, NULL response_[0m

/************************************************************************************************************

BT_BTC:btc_gatts_arg_deep_copy  指文件名+程序名+case-BTC_GATTS_ACT_SEND_RESPONSE+结果

esp_err_t esp_ble_gatts_send_response(esp_gatt_if_t gatts_if, uint16_t conn_id, uint32_t trans_id,
                                      esp_gatt_status_t status, esp_gatt_rsp_t *rsp)
{
    btc_msg_t msg;
    btc_ble_gatts_args_t arg;

    ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
    
    msg.sig = BTC_SIG_API_CALL;
    msg.pid = BTC_PID_GATTS;
    msg.act = BTC_GATTS_ACT_SEND_RESPONSE;
    arg.send_rsp.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id);
    arg.send_rsp.trans_id = trans_id;
    arg.send_rsp.status = status;
    arg.send_rsp.rsp = rsp;

    return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t),
                                 btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

从函数简介上看这个函数用途是针对请求发送一个应答。

参数:status--应答的状态

rsp---应答的数据

这个函数核心是调用btc_transfer_context()这个底层传输数据的接口

接下去btc_transfer_context()接口

//

bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg_deep_copy_t copy_func)
{
    btc_msg_t lmsg;

    if (msg == NULL) {
        return BT_STATUS_PARM_INVALID;
    }

    BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg->sig, msg->pid, msg->act, arg);

    memcpy(&lmsg, msg, sizeof(btc_msg_t));
    if (arg) {
        lmsg.arg = (void *)osi_malloc(arg_len);
        if (lmsg.arg == NULL) {
            return BT_STATUS_NOMEM;
        }
        memset(lmsg.arg, 0x00, arg_len);    //important, avoid arg which have no length
        memcpy(lmsg.arg, arg, arg_len);
        if (copy_func) {
            copy_func(&lmsg, lmsg.arg, arg);
        }
    } else {
        lmsg.arg = NULL;
    }

    return btc_task_post(&lmsg, TASK_POST_BLOCKING);
}

这个btc_transfer_context()接口旨在检查参数的同时组成btc_msg_t结构数据,并把它post到队列中,还有一个就是目的是调用copy_func函数,即btc_gatts_arg_deep_copy。

接下去看看 btc_gatts_arg_deep_copy这个函数,switch中选择BTC_GATTS_ACT_SEND_RESPONSE,由于src->send_rsp.rsp =NULL,因此打印输出NULL response

void btc_gatts_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
    btc_ble_gatts_args_t *dst = (btc_ble_gatts_args_t *) p_dest;
    btc_ble_gatts_args_t *src = (btc_ble_gatts_args_t *)p_src;

    switch (msg->act) {
    case BTC_GATTS_ACT_SEND_INDICATE: {
        if (src->send_ind.value && (src->send_ind.value_len > 0)) {
            dst->send_ind.value = (uint8_t *) osi_malloc(src->send_ind.value_len);
            if (dst->send_ind.value) {
                memcpy(dst->send_ind.value, src->send_ind.value, src->send_ind.value_len);
            } else {
                BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
            }
        } else {
            dst->send_ind.value = NULL;
            if (src->send_ind.value) {
                BTC_TRACE_ERROR("%s %d, invalid length", __func__, msg->act);
            } else {
                BTC_TRACE_WARNING("%s %d, NULL value", __func__, msg->act);
            }
        }
        break;
    }
    case BTC_GATTS_ACT_SEND_RESPONSE: {
        if (src->send_rsp.rsp) {
            dst->send_rsp.rsp = (esp_gatt_rsp_t *) osi_malloc(sizeof(esp_gatt_rsp_t));
            if (dst->send_rsp.rsp) {
                memcpy(dst->send_rsp.rsp, src->send_rsp.rsp, sizeof(esp_gatt_rsp_t));
            } else {
                BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
            }
        } else {
            BTC_TRACE_WARNING("%s %d, NULL response", __func__, msg->act);
        }
        break;
    
    }
    case BTC_GATTS_ACT_ADD_CHAR: {
        if (src->add_char.char_val.attr_value && (src->add_char.char_val.attr_len > 0)) {
            dst->add_char.char_val.attr_value = (uint8_t *) osi_malloc(src->add_char.char_val.attr_len);
            if (dst->add_char.char_val.attr_value) {
                memcpy(dst->add_char.char_val.attr_value, src->add_char.char_val.attr_value, 
                        src->add_char.char_val.attr_len);
            } else {
                BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
            }
        } else {
            dst->add_char.char_val.attr_value = NULL;
            if (src->add_char.char_val.attr_value) {
                BTC_TRACE_ERROR("%s %d, invalid length", __func__, msg->act);
            } else {
                BTC_TRACE_WARNING("%s %d, NULL value", __func__, msg->act);
            }
        }
        break;
    }
    case BTC_GATTS_ACT_ADD_CHAR_DESCR: {
        if (src->add_descr.descr_val.attr_value && (src->add_descr.descr_val.attr_len > 0)) {
            dst->add_descr.descr_val.attr_value = (uint8_t *) osi_malloc(src->add_descr.descr_val.attr_len);
            if (dst->add_descr.descr_val.attr_value) {
                memcpy(dst->add_descr.descr_val.attr_value, src->add_descr.descr_val.attr_value,
                        src->add_descr.descr_val.attr_len);
            } else {
                BTC_TRACE_ERROR("%s %d no mem\n", __func__, msg->act);
            }
        } else {
            dst->add_descr.descr_val.attr_value = NULL;
            if (src->add_descr.descr_val.attr_value) {
                BTC_TRACE_ERROR("%s %d, invalid length", __func__, msg->act);
            } else {
                BTC_TRACE_WARNING("%s %d, NULL value", __func__, msg->act);
            }
        }
        break;
    }
    case BTC_GATTS_ACT_CREATE_ATTR_TAB: {
        uint8_t num_attr = src->create_attr_tab.max_nb_attr;
        if (src->create_attr_tab.gatts_attr_db && (num_attr > 0)) {
            dst->create_attr_tab.gatts_attr_db = (esp_gatts_attr_db_t *) osi_malloc(sizeof(esp_gatts_attr_db_t) * num_attr);
            if (dst->create_attr_tab.gatts_attr_db) {
                memcpy(dst->create_attr_tab.gatts_attr_db, src->create_attr_tab.gatts_attr_db,
                        sizeof(esp_gatts_attr_db_t) * num_attr);
            } else {
                BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act);
            }
        } else {
            BTC_TRACE_ERROR("%s %d, NULL data", __func__, msg->act);
        }
        break;
    }
   case BTC_GATTS_ACT_SET_ATTR_VALUE: {
        if (src->set_attr_val.value && (src->set_attr_val.length > 0)) {
            dst->set_attr_val.value = (uint8_t *) osi_malloc(src->set_attr_val.length);
            if (dst->set_attr_val.value) {
                memcpy(dst->set_attr_val.value, src->set_attr_val.value, src->set_attr_val.length);
            } else {
                BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act);
            }
        } else {
            dst->set_attr_val.value = NULL;
            if (src->set_attr_val.value) {
                BTC_TRACE_ERROR("%s %d, invalid length", __func__, msg->act);
            } else {
                BTC_TRACE_WARNING("%s %d, NULL value", __func__, msg->act);
            }
        }
        break;
    }
    default:
        BTC_TRACE_DEBUG("%s Unhandled deep copy %d\n", __func__, msg->act);
        break;
    }

}

深入对btc_task_post()这个入发送队列的操作

static bt_status_t btc_task_post(btc_msg_t *msg, task_post_t timeout)
{
    if (msg == NULL) {
        return BT_STATUS_PARM_INVALID;
    }

    if (xQueueSend(xBtcQueue, msg, timeout) != pdTRUE) {
        BTC_TRACE_ERROR("Btc Post failed\n");
        return BT_STATUS_BUSY;
    }

    return BT_STATUS_SUCCESS;
}

看看任务对于这个xBtcQueue的处理

static void btc_task(void *arg)
{
    btc_msg_t msg;

    for (;;) {
        if (pdTRUE == xQueueReceive(xBtcQueue, &msg, (portTickType)portMAX_DELAY)) {
            BTC_TRACE_DEBUG("%s msg %u %u %u %p\n", __func__, msg.sig, msg.pid, msg.act, msg.arg);
            switch (msg.sig) {
            case BTC_SIG_API_CALL:
                profile_tab[msg.pid].btc_call(&msg);
                break;
            case BTC_SIG_API_CB:
                profile_tab[msg.pid].btc_cb(&msg);
                break;
            default:
                break;
            }
            if (msg.arg) {
                osi_free(msg.arg);
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/zhejfl/article/details/87262672