This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CC2640R2F:GATT_readlongcharvalue 的问题

Guru**** 2577385 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/589499/cc2640r2f-issues-with-gatt_readlongcharvalue

器件型号:CC2640R2F

大家好、

 GATT_ReadLongCharValue  函数存在问题。我们从开发人员指南(www.ti.com/.../swru393d.pdf)中阅读了这一内容  

"如果返回状态为成功、则调用应用程序任务会接收多条 GATT_MSG_EVENT 消息、这些消息的类型为 ATT_READ_BLOB_RSP 或 ATT_ERROR_RSP (如果服务器上发生错误)。 当调用应用程序任务接收到 ATT_READ_BLOB_RSP (具有 bleProcedureComplete 或 bleTimeout 状态)或 ATT_ERROR_RSP (具有成功状态)时、此子过程即完成。"、  
但是、当我们检查最后一个数据包的状态时、它是成功的、而不是按预期执行的 bleProcedurComplete。 我们在两个 cc2640r2 (外围设备中央)之间的通信中遇到了此问题、而当我们尝试使用 btool 执行此操作时、btool 获取 bleProcedureComplete。  
我们遇到了另一个问题、即在长时间读取后、我们尝试对另一个外设特性执行写入操作。 我们遇到写入不返回 write_rsp 回调(请参阅 log_pairing.psd 的 pkt.153)
希望在一些建议中、提前感谢您的帮助。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Roberto:

    请确保在 SimpleBLECentral_processGATTMsg()中正确处理 ATT_READ_BLOB_RSP。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Marie、

    我发布了我的 processGATTMsg 句柄(请注意、我将用作启动项目"多角色项目")。

    我按如下方式处理 ATT_READ_BLOB_RSP:

    静态 uint8_t multi_role_role_processGATTMsg (gattMsgEvent_t *pMsg)
    {
    
    //查看 GATT 服务器是否无法发送 ATT 响应
    (如果(pMsg->HDR.status == blePending)
    {
    //没有 HCI 缓冲器可用。 让我们尝试重新传输响应
    //发生下一个连接事件。
    if (HCI_EXT_ConnEventNoticeCmd (pMsg->connHandle、self 实体、
    MR_CONN_EVT_END_EVT)=成功)
    {
    //首先释放任何待处理的响应
    multi_role_freeAttsp (故障);
    
    //保持响应消息以重新传输
    pAttRsp = pMsg;
    
    //尚未释放响应消息
    返回(false);
    }
    }
    否则、如果(pMsg->method =ATT_flow_CTRL_쟖 랸_event)
    {
    // ATT 请求-响应或指示-确认流量控制为
    //违反。 所有后续 ATT 请求或指示将被丢弃。
    //如果应用程序想要断开连接,将通知该应用程序。
    
    //显示导致违规的消息的操作码。
    //Display_Print1 (dispHandle、MR_ROW_STATUS1、0、"FC 违例:%d"、pMsg->msg.flowCtrlEvt.opcode);
    DebugPush ("FC inceeded:%d"、pMsg->msg.flowCtrlEvt.opcode);
    }
    否则(pMsg->method =ATT_MTU_updated_event)
    {
    // MTU 大小已更新
    Display_Print1 (dispHandle、MR_ROW_STATUS1、0、"MTU 大小:%d"、pMsg->msg.mtuEvt.MTU);
    }
    否则、if (pMsg->method = ATT_Handle_value_Noti){
    //i dati sono contenuti in pMsg->msg.handleValueNoti
    uint8_t notify_packet[2]={0};
    memcpy (&notify_packet、pMsg->msg.handleValueNoti.pValue、2*sizeof (uint8_t));
    //indica la lettura
    doWrite = false;
    //devo leggere la caratteristic a 7 Che è la n 6 nel vettore dove mi sono memorizzato
    //le caratteristche
    assign_char_index=6;
    MR_doGattRw (0);
    }
    // GATT 服务器中的消息
    if (linkDB_NumActive()> 0)
    {
    //从连接句柄查找索引
    connIndex = multi_role_mapConnHandleToIndex (pMsg->connHandle);
    if ((pMsg->method =ATT_READ_RSP)||
    (((pMsg->method =ATT_ERROR_RSP)&&
    (pMsg->msg.errorRsp.reqOpcode =ATT_READ_REQ))
    {
    if (pMsg->method == ATT_ERROR_RSP)
    {
    Display_Print1 (dispHandle、MR_ROW_STATUS2、0、"Read Error %d"、pMsg->msg.errorRsp.errCode);
    }
    其他
    {
    //成功读取后,显示读取值
    Display_Print1 (dispHandle、MR_ROW_STATUS2、0、"Read rs:%d"、pMsg->msg.readRsp.pValue[0]);
    //测试写入 dopo una 半序列读取
    Multi_role_GetPingHandle (&P);
    isOutputBufferWritten=1;
    doWrite = true;
    assign_char_index=4;
    memset (&charVal、get_ping、sizeof (uint8_t));
    memcpy (&charVal[1]、&pingReqArg、4*sizeof (uint8_t));
    DebugPush ("%d"、charVal);
    message_size=0x00;
    message_size=0x05;
    MR_doGattRw (0);
    //fine
    }
    }
    否则、如果((pMsg->method =ATT_WRITE_RSP)||
    (((pMsg->method =ATT_ERROR_RSP)&&
    (pMsg->msg.errorRsp.reqOpcode =ATT_write_Req))
    {
    Display_Print1 (dispHandle、MR_ROW_STATUS2、0、"写入状态:%d"、pMsg->HDR.status);
    if (pMsg->method =ATT_ERROR_RSP == ATT_ERROR_RSP)
    {
    Display_Print1 (dispHandle、MR_ROW_STATUS2、0、"写入错误%d"、pMsg->msg.errorRsp.errCode);
    }
    其他
    {
    //成功写入后,显示写入的值,然后
    //递增值
    Display_Print1 (dispHandle、MR_ROW_STATUS2、0、"写入已发送:%d"、charVal);
    if (isOutputBufferWritten=1){
    assign_char_index=3;
    doWrite = true;
    memcpy (&charVal、&message_size_temp、2*sizeof (uint8_t));
    message_size=0x00;
    message_size=0x02;
    MR_doGattRw (0);
    isOutputBufferWritten=0;
    }
    }
    
    否则、如果((pMsg->method =ATT_READ_BLOB_RSP)||
    (((pMsg->method =ATT_ERROR_RSP)&&
    (pMsg->msg.errorRsp.reqOpcode =ATT_READ_BLOB_REQ))){
    if (pMsg->method == ATT_ERROR_RSP)
    {
    Display_Print1 (dispHandle、MR_ROW_STATUS2、0、"Blob 读取错误%d"、pMsg->msg.errorRsp.errCode);
    }
    否则{
    Display_Print1 (dispHandle、MR_ROW_STATUS2、0、"读取 blob 状态:%d "、pMsg->HDR.status);
    if (pMsg->HDR.status!=bleProcedureComplete){
    if (indice_read_blob MSG.readBlobRsp.pValue[0]= ble_central_cmd_verify)&&(indice_read_blob=0)){
    memcpy (radio_event_buf+((9+indice_read_blob)* sizeof (uint8_t))、pMsg->msg.readBlobRsp.pValue+(2*sizeof (uint8_t))、(pMsg->msg.readBlobRsp.pint8)
    、(uint8)的 sizet)
    否则、如果(((pMsg->msg.readBlobRsp.pValue[0]!=ble_central_cmd_verify)&&(indice_read_blob=0)){
    Indice_read_blob=public_key_size*10;
    CHECK_CMD_RESPONSE=1;
    }
    否则 if (indice_read_blob>0){
    memcpy (radio_event_buf+((9+indice_read_blob)* sizeof (uint8_t))、pMsg->msg.readBlobRsp.pmsg、pMsg->Value.readBlobRsp.len* sizeof (uint8_t));
    }
    否则{
    DebugPush ("勘误表");
    }
    Indice_read_blob = indice_read_blob + pMsg->msg.readBlobRsp.len;
    if (indice_read_blob=public_key_size+2){
    //权变措施
    doWrite=true;
    assign_char_index=6;
    message_size=0x00;
    message_size=0x01;
    MR_doGattRw (0);
    }
    }否则{
    DebugPush ("Errore2");
    }
    }
    否则{
    //Display_Print1 (dispHandle、MR_ROW_STATUS2、0、"读取 blob rs:%d"、&RADIO_EVENT_buf);
    Indice_read_blob=0;
    if (check_cmd_Response==1){
    //devo button
    CHECK_CMD_RESPONSE=0;
    }否则{
    switch (ble_central _cmd_verify){
    案例 GET_PBKEY:
    switch (centralStatus){
    案例配对状态:
    //devo inviare una ping 请求
    //da verificare se è stata fatta bene
    Multi_role_GetPingHandle (&P);
    isOutputBufferWritten=1;
    doWrite = true;
    assign_char_index=4;
    memset (&charVal、get_ping、5*sizeof (uint8_t));
    //memcpy (&charVal[1]、&pingReqArg, 4*sizeof (uint8_t));
    //DebugPush ("%d"、charVal);
    message_size=0x00;
    message_size=0x01;
    MR_doGattRw (0);
    中断;
    案例 connection_request_status:
    case normal_status:
    默认值:
    中断;
    }
    案例 get_ping:
    if (multi_role_GetPingCheck (radio_event_Buf)){
    switch (centralStatus){
    案例配对状态:
    radioEventPushFxn (radio_event_Buf);
    GPIO_writeDio (GD0_PIN、1);
    Task_sleep (100);
    GPIO_writeDio (GD0_PIN、0);
    中断;
    案例 connection_request_status:
    中断;
    case normal_status:
    中断;
    默认值:
    中断;
    }
    }否则{
    //se fallisce il confronto del tick
    //devo fare I retry
    }
    中断;
    }
    }
    BLE_CENTRAL_CMD_VERIFICT=0xff;
    }
    }
    
    否则(discInfo[connIndex].discState!= BLE_DISC_State_Idle)
    {
    multi_role_processGATTDiscEvent (pMsg);
    }
    }//否则-如果连接断开后出现 GATT 消息,请忽略它。
    
    //自由消息有效载荷。 仅用于 ATT 协议消息
    GATT_BM_FREE (&pMsg->msg、pMsg->方法);
    //释放传入消息
    返回是安全的(真);
    } 

    感谢你的帮助。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Roberto:

    根据文档、长读取过程将被"ATT_READ_BLOB_RSP (具有 bleProcedureComplete 或 bleTimeout 状态)或 ATT_ERROR_RSP (具有成功状态)"终止。

    我看不到您在代码中检查了 ATT_ERROR_RSP 是否具有成功状态?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    此外、您是否更改了 MAX_NUM_PDU? (请在此处阅读: software-dl.ti.com/.../index.html )
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Marie、

    条件下

    if((pMsg->method == ATT_READ_BLOB_RSP)  ||
                 ((pMsg->method == ATT_ERROR_RSP) &&
                  (pMsg->msg.errorRsp.reqOpcode == ATT_READ_BLOB_REQ)))
    我处理
       
     if(pMsg->method == ATT_ERROR_RSP){ DebugPush("Read blob error");}
    但代码永远不会达到这一点、因此我永远不会看到调试打印"读取 blob 错误"。 长读取结束过程似乎仅在请求下一个双传输(写入或读取长)时触发、因为如果在第一次读取长整型之后请求新的写入或读取长操作、则返回第一个状态、 是针对方法 ATT_READ_BLOB_RSP 的、具有值 bleProceduComplete (0x1A)。
    代码未输入的唯一情况是条件  
    (pMsg->method == ATT_ERROR_RSP)  is true but the condition (pMsg->msg.errorRsp.reqOpcode == ATT_READ_BLOB_REQ) is false, but the request is a READ_BLOB_REQ!
    每次 processGattmsg 回调启动时、我都尝试进行调试打印、但从长时间读取操作启动时、它仅打印6次。
    我是否必须更改条件?
    提前感谢您的帮助!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Roberto:
    此主题中建议的更改是否有助于长读? e2e.ti.com/.../2175326