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.

[参考译文] CC2652RB:如何使用 blePending?

Guru**** 2546960 points
Other Parts Discussed in Thread: CC2640, CC2650

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/988719/cc2652rb-how-to-use-blepending

器件型号:CC2652RB
Thread 中讨论的其他器件:CC2640CC2650

我们有一个基于 SimplePeripheral 示例的项目。  我们希望能够通过 BLE 读取一些经常变化的值、例如 CC2652的 RTC 的器件时间。  我们希望能够在读取时按需获取数据、而不是不断更新缓冲区以确保这些值在读取时是最新的。  我猜到,正确的方法是在 SimplePeripheral_ReadAttrCB()中返回 blePending,如下所示:

    // See if request is regarding the Clock Characteristic Value
    if ( ! memcmp(pAttr->type.uuid, MyService_ClockUUID, pAttr->type.len) )
    {
        if ( offset > MYSERVICE_CLOCK_LEN ) // Prevent malicious ATT ReadBlob offsets.
        {
            status = ATT_ERR_INVALID_OFFSET;
        }
        else
        {
            if ( pAppCBs && pAppCBs->pfnReadCb )
                pAppCBs->pfnReadCb(connHandle, MYSERVICE_CLOCK_ID); // Call app function from stack task context.
            return blePending;
        }
    }

其中我创建了 pAppCBs->pfnReadCb(),与对 SimplePeripheral_WriteAttrCB()执行应用程序回调的方式相同。  这将为我们的应用程序任务排队一条消息,并由 SimplePeripheral_processAppMsg()处理,后者会调用以下函数:

static void MyService_processValueReadEvt(MyServiceReadCharacteristic_t *pData)
{
    switch(pData->paramID)
    {
        case MYSERVICE_CLOCK_ID:
        {
            bStatus_t status;
            attReadRsp_t clockRsp;
            uint16_t len;

            clockRsp.pValue = (uint8 *)GATT_bm_alloc( pData->connHandle, ATT_READ_RSP, MYSERVICE_CLOCK_LEN, &len );
            if ( clockRsp.pValue != NULL )
            {
                if (len != MYSERVICE_CLOCK_LEN)
                {
                    GATT_bm_free( (gattMsg_t *)&clockRsp, ATT_READ_RSP );
                    // TODO: couldn't allocate enough memory, but we still have to tell the BLE stack something to end "blePending", right?
                }
                else
                {
                    uint32_t time = Seconds_get();
                    memcpy(clockRsp.pValue, &time, len);
                    clockRsp.len = len;
                    status = ATT_ReadRsp(pData->connHandle, &clockRsp);
                    if ( status != SUCCESS )
                    {
                        GATT_bm_free( (gattMsg_t *)&clockRsp, ATT_READ_RSP );
                        // TODO: we failed to return the data for some reason; does the BLE stack still need us to do anything?
                    }
                }
            }
            else
            {
                // TODO: couldn't allocate any memory, but we still have to tell the BLE stack something, right?
            }
        }
        break;

我的第一个问题是:这是正确的方法吗?  我不得不进行一些挖掘以找到 attReadRsp_t 和 ATT_ReadRsp()。  我已经测试过这种方法、但它可以正常工作、因此我知道我至少处于正确的轨道上。

我的第二个问题是:假设上述内容正确、我需要调用什么来代替代码中的注释?  如果我无法分配将读取响应发送回 BLE 堆栈所需的存储器、我假设我仍需要 执行一些操作 、这样它就不会一直处于"待处理"状态、对吧?  如果 ATT_ReadRsp()不成功,我们是否仍然需要做一些事情来防止堆栈等待成功?

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

    您好!

    我已经指派了一名专家来帮助您处理您的问题。 同时、您能告诉我们您使用的是 SDK 的哪个版本吗?  

    此致、

    1月

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

    4.20.01.04

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

    有更新吗?

    我还有第三个问题、这个专家的后续问题:可以为此动态分配多少内存、如果需要、我们可以在某个地方增加多少内存?  我们还将从器件中读取日志;我们的页大小具有一些开销、这意味着288字节的特征。  这在 应用程序中作为静态 RAM 缓冲器运行正常、但 GATT_BM_ALLOC() 调用使用了什么堆、我们是否应该能够请求288个字节?

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

    第四个问题:等待处理后、您需要以多快的速度回复数据?  我们是否应该有时间通过 SPI 从外部闪存芯片中读取上述内容并对其进行加密、然后再将其返回?

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

    尊敬的 Chris:

    我对延误深表歉意。 您能否验证以下 E2E 主题是否回答了您的问题?

    https://e2e.ti.com/support/wireless-connectivity/bluetooth/f/bluetooth-forum/445751/blepending---cc2640

    https://e2e.ti.com/support/wireless-connectivity/bluetooth/f/bluetooth-forum/953408/cc2642r-delayed-response-using-gattservapp_readrsp/3543573

    我相信您尝试使用 blePending 的方式是正确的。

    此致、

    1月

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

    第二个主题似乎非常相关、我很惊讶在搜索时没有找到它。  不过,我不确定它是否完全回答了我的问题,它实际上又提出了另一个问题。   但是、第一个线程的主要"答案"是对 SimpleNP_GATT.c 文件中可能找到的示例的引用、CC26x2 SDK 似乎不包含该示例、因此这种做法用处不大。   让我仔细检查我要求的所有内容、以便保持直立...

    问题1:似乎是"是"。   我很高兴看到第二个线程中的示例代码基本上就是我自己编写的代码。

    问题2: 当 我无法分配内存时、仍然无法清除要执行的操作。  第二个线程中的示例代码返回 eBTStatusNoMem 的是 SDK 中任何位置未定义的、没有上下文可以说明它甚至"返回"到什么位置以及调用函数如何处理错误返回。  因此、我仍然不知道如何处理错误、也不知道如何告知 BLE 堆栈因出现错误而停止挂起、或者我是否需要这么做。

    问题3:仍然不知道这是来自什么堆、我可以可靠地要求多少、以及如果需要、它是否可以增加。

    问题4:第一个线程可以回答这个问题、但它已使用6年、适用于具有不同 SDK 的不同芯片。  JXS   CC2640的前面说过"您需要在最初接收到来自客户端的读取请求后30秒内进行读取 RSP 调用。"  如果较新的 CC26x2 SDK 仍然如此、我们将有足够的时间来完成此操作。  情况是否仍然如此?

    问题5:第二个线程中的示例代码似乎也意味着有三 ATT_READ_x_REQ 种不同类型的代码需要以不同的方式处理、而我目前正在假定它始终是、 ATT_READ_REQ 因为这是我唯一知道的代码。  对于我们的4字节时间特性、这最终是一个安全事故。  但是、我们有一个30字节的特征、该特征可能只能通过始终协商更高的 MTU 来有效。  我猜、在不能进行数据长度扩展的预 BLE4.2电话上、这不会很热。   ATT_ReadBlobRsp() 我当然需要288字节的特性。  那么、如果您对 REQ 类型使用错误的 ReadRsp 与 ReadBlobRsp 进行应答、会发生什么情况?  我想我必须将该方法作为参数添加到回调中、并将其包含在应用任务的消息中、以便我能够以正确的方式做出响应?  示例代码未提及 blob 读取案例的偏移量;我不必担心这一点吗?  我可以用整个288个字节进行响应、然后堆栈会根据需要进行斩波吗?  我有疑问、因为我认为 SimplePeripheral_ReadAttrCB() 会被呼叫、然后将再次触发每个数据包的应用回调。  然后我甚至不知道为什么 ATT_READ_BY_TYPE_REQ会有这样的情况。  我认为这是为了服务发现;单个特征属性句柄不应接收这种类型的读取请求、对吧?    是否有人也能澄清所有这些问题?

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

    您好 Chris、

    对于问题2、该代码块是伪代码、因此可能不是100%正确。 要使用的更好的返回状态可能是 bleMemAllocError。 以下线程描述了 GATT_BM_ALLOC()函数的工作方式。

    https://e2e.ti.com/support/wireless-connectivity/bluetooth/f/bluetooth-forum/947014/launchxl-cc26x2r1-gatt_bm_alloc-returns-value

    对于问题3、 GATT_BM_ALLOC()分配由 OSAL 层处理。 我相信你应该能够通过使用 ROV 和 HEAPMGR_METERIN评估 定义来监视分配对堆的确切影响。 以下 E2E 主题介绍了调试存储器问题的好方法:

    https://e2e.ti.com/support/wireless-connectivity/bluetooth/f/bluetooth-forum/973731/cc2642r-debugging-memory-issues/3598030

    关于问题4,我认为情况仍然如此,但核查的最佳方法是对其进行测试。

    对于问题5、我认为您提出的解决方案是可行的、但与问题4一样、验证的最佳方法是测试。

    此致、

    1月

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

    问题2:是的、我看到它是伪代码、因此我希望您提到的专家能够给出明确的答案。  我知道如何GATT_bm_alloc()工作(或者至少我认为我是这样做的;该线程询问它是否可以将非空指针返回到比要求的更少的字节、我不确定答案是否确实清楚地显示"是"、但这不是我要问的。  假设它未能在堆上分配内存、我得到一个 NULL;我该怎么做?  我在应用任务中处于消息队列处理功能、而不是 BLE 堆栈回调;没有用于返回 任何结果的与无线电相关的调用功能。  如果我有数据,我会调用ATT_ReadRsp();如果无法 发送数据,我会调用什么? ATT_ReadRsp() 当然、如果我知道我永远不会响应、我不会让 BLE 堆栈挂起30秒、对吧?

    问题3:那么、你说这会使用主 CPU 的堆吗?   不是射频内核的 SRAM?

    问题4:我的意思是... 我可以尝试通过实验验证它、但我不知道要查找什么来指示该时间段已过期。  如果堆栈代码中存在超时、有人可以告诉我的值、这很好。

    问题5:也许我在这里提出了不止一个问题、但该段中仍然有很多未回答的内容、我无法仅进行测试、可以对这些内容使用明确的回答。

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

    尊敬的 Chris:

    很抱歉耽误你的时间。 我与一位同事取得了一些见解、他向我提供了一些有用的信息。 最新问题。

    Q2和 Q5

    根据蓝牙规范、"如果服务器没有足够的资源来处理请求、 然后、服务器应使用 ATT_ERROR_RSP PDU 进行响应、错误代码资源不足、将"错误中的属性句柄"设置为0x0000" [蓝牙核心规范版本5.2 |第3卷、第 F 部分、§3.3]。  本节还介绍了使用不受支持的 PDU 时会发生的情况。

    问题3.

    没错。 内存分配在堆上、而不是在射频内核 RAM 上。

    问题4.

    根据蓝牙规范、"一旦客户端向服务器发送请求、在收到响应 PDU 之前、该客户端不应向同一 ATT 承载器上的同一服务器发送任何其他请求。" [蓝牙核心规范版本5.2 |第3卷、第 F 部分、§3.3.3]。 这意味着没有超时。

    如果您有任何其他问题或这些答案未能完全澄清您的问题、请告诉我、我们将尽力尽快找到答案。

    此致、

    1月

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

    问题2:这就是无线电应该如何响应的、是的。  但是、您仍然没有告诉我我需要调用什么函数来使堆栈实现该目的。  堆栈正在等待我回复它;这就是 blePending 的全部要点。  如果我有数据,我将调用 ATT_ReadRsp()。  我原来的问题是并且仍然是:如果我由于某种原因而没有数据,比如无法分配内存,我会调用什么函数而不 ATT_ReadRsp()是?

    问题4:我需要知道如何告知堆栈如果我无法分配内存、响应永远不会出现、因为它不会超时。  那么、您链接我的另一个线程中的30秒是错误的?

    问题5:我将详细介绍上周的所有未回答的问题:

    Q5.1: 那么、如果你对 REQ 类型回答错误的 ReadRsp 与 ReadBlobRsp、会发生什么情况?

    问题5.2:在执行此操作时,我是否需要担心偏移 ATT_ReadBlobRsp()?  我可以使用整个288字节的特征进行响应、然后堆栈会根据需要进行斩波吗?  我有疑问、因为我认为 SimplePeripheral_ReadAttrCB() 会被呼叫、然后将再次触发每个数据包的应用回调。

    Q5.3:我 ATT_READ_BY_TYPE_REQ? 实际上是否需要一个案例、因为我认为这是用于服务发现的;单个特征属性句柄不应接收该类型的读取请求、对吧?

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

    尊敬的 Chris:

    我们认为您应该使用的功能是 ATT 延迟请求功能。 以下是一些描述此功能、如何使用它及其一般行为的文档: https://dev.ti.com/tirex/content/simplelink_cc13x2_26x2_sdk_4_40_04_04/docs/ble5stack/ble_user_guide/html/ble-stack-5.x/gatt.html#delaying-an-att-read-request

    上述文档还包括上面链接的第二个 E2E 主题中提到的代码、但还提供了有关如何启用和正确使用该功能的其他说明。

    具体来说,关于 Q5.1:使用错误的 RSP 应答可能会导致连接的客户端出现问题。

    请告诉我所提供的链接是否澄清了您的任何问题。 我将在此期间调查您的问题、并尽快回复您。

    此致、

    1月

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

    这与上述类似的 E2E 主题有何不同?  我的所有相同问题仍然适用。

    我不知道我可以 更清楚地重复我自己的事情。  您 无法运行伪代码。  该示例没有上下文。  它使用return一条语句将发送 bleMemAllocError 到某个位置。  什么是调用函数、它如何解决我的问题?  所有这些中缺少的部分 仍然告诉堆栈没有响应。  两周前我在这里粘贴了我的代码; 您可以清楚地看到、我不能只在return代码中粘贴一条语句、而 是希望 在主应用程序中退出任务事件将向 BLE 堆栈发送任何内容、以防止它无限期地处于该堆栈等待 blePending 状态。

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

    尊敬的 Chris:

    我们将研究这一点、并将在周一(4/12)之前发布更新。 由此 给您带来的不便、我深表歉意。

    此致、

    1月

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

    尊敬的 Chris:

    我已经咨询 过团队、在做了一些研究后、我们得出了以下结论。

    Q1:您的实施是正确的。 但是、请确保已将 ATT_DERAED_REQ 添加到预定义配置中。 这将确保我们的 BLEStack 允许出现这种请求。

    Q2:如果没有足够的堆可用、则必须实现一种执行虚拟应答的方法。 如果未完成此操作、30秒后将禁用连接的 ATT 承载卡。 这是因为发送读取请求的器件期望回读/错误响应。 蓝牙规范 [蓝牙核心规范版本5.1 |第3卷、第 F 部分、§3.3.3]中对此进行了讨论

    Q3:如前所述、内存分配在堆上、而不是在射频内核上。 只要你有足够的堆、你就应该能够分配你需要的任何东西。 我建议在调试期间启用堆指标(https://dev.ti.com/tirex/content/simplelink_cc13x2_26x2_sdk_4_40_04_04/docs/ble5stack/ble_user_guide/html/ble-stack-5.x-guide/debugging-index.html#debugging-common-heap-issues)。 这将使您很好地了解调试期间您所剩的堆的确切大小。  但是、根据技术规格、ATT 的最大可用数据为255 -开销。 对于 att_readRSP、开销为1字节、这意味着可以发送的最大数据为254字节。 这意味着对等设备将需要使用读取 Blob 请求来读取剩余数据。 该规范在以下部分进行了相关介绍: [蓝牙核心规范版本5.1 |第3卷、第 F 部分、§3.4]

    Q4:需要在30秒内发送 att_readRsp。 这由蓝牙规范定义。 (请参阅 Q2)

    问题5:我认为这里提到的一些问题是由第三季度的内容回答的。 需要实现偏移来处理 READ_BLOBRsp。 您无法使用所有288个字节进行响应、因为我们的堆栈不允许这样做、因为这超过了支持的最大 MTU 大小。 规范中存在以下行、应回答您的一个问题: "按类型读取请求用于获取属性值、其中属性类型已知的句柄未知"  [蓝牙核心规范版本5.1 |第3卷、第 F 部分、§3.4.1]

    您可能会发现以下内容很有用:

    API 文档: ATT_ReadReq()

    API 文档: ATT_ReadRsp()

    API 文档: ATT_ReadBlobReq()

    API 文档: ATT_ReadBlobRsp()

    E2E 主题: https://e2e.ti.com/support/wireless-connectivity/bluetooth/f/bluetooth-forum/471864/ble-v2-1-gatt-read-data-not-ready-how-to-delay/1696116

    此致、

    1月

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

    6年前的 E2E 线程与您之前链接我的另一个6年前的 E2E 线程存在相同的问题:它指的是一些不属于任何最新 SDK 的"简单 NP"项目。  当我询问在哪里可以找到它时、我想您之前没有回答过我、所以我会再次询问、因为这是您第二次向我推荐 它。

    我希望它存在于某个地方、因为一些实际运行的示例代码会非常好。  我没有找到任何上述 API"文档"、只是重复指向函数原型 、其 4字描述并不是很有用。

    这个"虚拟回复"是这里最有希望的线索、但我并不需要 BLE 规范的链接。  我有这个。  我没有编写自己的 BLE 堆栈。  我需要知道 TI 的 BLE 堆栈会做什么、因为我要编写一个 TI 应用。  所以... 明显的后续问题... 如何使用  TI 的 SDK  发送"虚拟回复"?  我可以ATT_ReadRsp()用 attReadRsp_t.len A 和0attReadRsp_t.pValue 来调用NULL吗?  这是 API 文档实际上并不能告诉我的内容。

    实际上、API 文档列出了ATT_ErrorRsp()一个函数。  在堆栈上下文服务回调本身中,如果不返回""blePending,则可以返回SUCCESS或特定的错误消息,如ATT_ERR_INVALID_OFFSET。  如果我使用blePending、并且我的应用遇到问题(例如无法为响应分配内存)、我是否可以调用ATT_ErrorRsp()抛出ATT_ERR_INSUFFICIENT_RESOURCES、这足以让响应 GATT 客户端继续连接?   是否有某些原因不起作用?  我是否 必须使用ATT_Read*Rsp()"虚拟回复"进行呼叫?

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

    尊敬的 Chris:

    simple NP 项目是 BLE-STACK 版本2.2.5的一部分。 该堆栈支持 CC2640/CC2650器件。 简单的 NP 项目位于此处、可能对您的用例有用、因为它在其应用程序文件中使用 blePending。 不能发送空的 attReadRsp_t 作为"虚拟答复"。 对于虚拟应答、您可以发送1个字节(0x00或一些其他字节值)、并在接收器侧设置一些后处理、以识别虚拟值并根据虚拟值进行一些进一步处理 (例如、等待一段时间或在等待时执行一些其他处理)。

    此致、

    1月

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

    "在接收器侧"?  呼叫后ATT_Read*Rsp(),我是否可以访问它的位置?  堆栈中的这一点不是全部?  您肯定 不是在谈论作为 GATT 客户端连接的中央设备、我无法控制它吗?

    如果ATT_ErrorRsp()该器件的工作方式与我在前面所说的相同、那么它看起来会是更好的解决方案呢?

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

    尊敬的 Chris:

    我指的是连接中的对等器件。 我真的很抱歉、我认为您在这种情况下控制了中央和外设。 我有几个问题需要澄清。 另一台设备需要发送电池读取请求、因此如果您不控制中央设备、这种情况是如何发生的? 如果您不能控制中央、那么中央问题的电瓶电极如何读取? 您能否澄清一下您对中央设备的控制意味着什么? 我将查看 ATT_ErrorResp()并返回给您。 您能否描述一下、如果 READ_Rsp 被发送为虚拟值、您的用例中会出现什么行为?

    此致、

    1月

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

    中央设备通常是 Android 或 iOS 智能手机。  我们有一个应用程序、但我们的应用程序不是唯一可以与外设通信的应用程序。  即使是这样、在较低级别的层面上也无法查看在操作系统处理该问题时、从 blob 读取的哪个数据包具有虚拟值、 在更高级别上确定数据中的任何随机字节是否为实字节也很重要、而是这些虚拟读取中的一个结果。  将负担放在连接的另一端不是解决方案。

    到目前为止,我在测试中很幸运,在我的回调/消息中添加了长度/偏移/方法参数,以处理多种请求类型,并使用 ATT_ErrorRsp()。  如果我将 MTU 设置为23并尝试读取其中一个较长的特征、它以前不起作用、但现在我能够使用 ATT_READ_BLOB_REQ/正确读取它ATT_ReadBlobRsp()。  这甚至还没有添加  ATT_DEAL_REQ ,我怀疑它更适合使用 GATTServApp_ReadRsp() ,而不是手动处理所有的 REQ 类型和调用 GATT_bm_alloc() 和 ATT_Read*Rsp()

     ATT_READ_BY_TYPE_REQ 对此、我仍不清楚。  老实说、我甚至不知道这种类型的请求是由单个特征发出的、以及响应中应该包含哪些数据。  此外、 在您以文档示例(https://dev.ti.com/tirex/content/simplelink_cc13x2_26x2_sdk_4_40_04_04/docs/ble5stack/ble_user_guide/html/ble-stack-5.x/gatt.html#delaying-an-att-read-request)形式发送给我的链接中、处理方式如下:

     case ATT_READ_BY_TYPE_REQ:
        {
            Status = GATTServApp_ReadRsp( ConnHandle, pAttrValue, attrLen, attrHandle );
            break;
        }

    
    

    忽略不清楚该情况的值指针是什么、因为在其他情况attrHandle下、数据必须首先组合在一起、而这个只是预先显示它已经存在在某个位置、请查看最后一个参数""。  这与实际源代码中的函数原型和此处的 API 文档(dev.ti.com/.../group___g_a_t_t_serv_app.html)冲突、两者都显示参数应该是偏移、而不是属性句柄:

    extern bStatus_t GATTServApp_ReadRsp( uint16 connHandle, uint8 *pValue, uint16 pLen, uint16 offset );

    这就是我所说的伪代码示例没有真正的帮助;很明显、编写该示例的人并不打算将其作为一个彻底的解决方案。  基本的想法很有帮助、但如果要实际运行、则必须在某个时候填写详细信息。

    至于 ATT_ErrorRsp(),我可以在没有30秒超时的情况下立即发送错误,在另一侧接收错误,然后继续读取其他属性而不丢失连接,这正是我想要的。  不过、我不确定是否所有参数都正确。

     attErrorRsp_t rsp;
     rsp.reqOpcode = pData->method;
     rsp.handle = pData->pAttr->handle;
     rsp.errCode = ATT_ERR_INSUFFICIENT_RESOURCES;
     ATT_ErrorRsp(pData->connHandle, &rsp);

    错误代码看起来正常。  对于属性句柄、我必须添加 gattAttribute_t *pAttr 到参数列表 WriteAttrCB() 中才能将消息发送到我的应用程序任务、但我认为这是正确的。  我最不能确定的是 reqOpcode,是“method,”等 ATT_READ_REQ ?

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

    尊敬的 Chris:

    我希望你们做得好。 我咨询了团队、并对您的问题提供了一些答案。 关于 ATT_READ_BY_TYPE_REQ 案例、这是在您不知道属性句柄时发出的。 与团队交谈时、伪代码似乎正确、doxygen 错误。 启用 ATT_Delayed_Req 的主要原因是处理 ATT_readByTypeReq。 如果未启用此功能、并且有另一个中央发送按类型读取请求(包含与需要延迟响应的属性相对应的起始句柄/结束句柄和属性类型)、则不会延迟响应、并返回非实时值。 如果您不需要任何随机应用程序来获取实时值、则无需启用 ATT_Delayed_Req。

    与团队一起查看 ATT_ErrorRsp()函数及其实施情况时。 正确、 rsp.reqOpcode 只是 我们使用 att_errorRsp 进行响应的方法。 因此、在您的情况下、它将是 ATT_READ_REQ。 我们相信您的实施是正确的。 我们预计不会出现任何问题。 但是、如果您发现任何意外行为、请告知我们、我们将对此进行更详细的了解。

    此致。

    1月