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.

[参考译文] CC2642R:运行 AoA 演示 SDK 6.20.0029时扫描混淆的结果数据

Guru**** 2791195 points

Other Parts Discussed in Thread: SYSCONFIG

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1184439/cc2642r-scan-results-data-mixed-up-when-running-aoa-demo-sdk-6-20-0029

器件型号:CC2642R
"Thread:SysConfig"中讨论的其他器件

您好!

背景:

rtLS_responser_CC26X2R1_LAUNCHXL_tirtos7_ticlang

rtLS_Coordinator_CC26X2R1_LAUNCHXL_tirtos7_ticlang

SDK 6.20.00.29

修改了工程以在 Adv 数据(在 GAP_DEVICE_INIT_DONE_EVENT 内)内嵌入 MAC 地址、例如:

// AiRISTA added
advertData[19] = pPkt->devAddr[0];
advertData[20] = pPkt->devAddr[1];
advertData[21] = pPkt->devAddr[2];
advertData[22] = pPkt->devAddr[3];
advertData[23] = pPkt->devAddr[4];
advertData[24] = pPkt->devAddr[5];

问题-在 RC_EVT_ADV_REPORT 事件处理程序中、当我们检查堆栈报告的 MAC 地址与 ADV 数据中的相应字节匹配时、确实偶尔会出现差异、因为 BLE 堆栈报告的 MAC 与 Adv 数据中的 MAC 不同。 我们检查 Mac 的最后3个字节,因为前三个字节从不改变我们的设备,我们可以看到下面的行偶尔打印...

case RC_EVT_ADV_REPORT:
{
    GapScan_Evt_AdvRpt_t* pAdvRpt = (GapScan_Evt_AdvRpt_t*) (pMsg->pData);
    uint8_t status;

    if (pAdvRpt->addr[2] != pAdvRpt->pData[21] || pAdvRpt->addr[1] != pAdvRpt->pData[20] || pAdvRpt->addr[0] != pAdvRpt->pData[19])
        AiRISTA_DEBUG_SendDataToBackend_String("*** MISMATCH1 ***");

日志:

MAC 不匹配时、您可以看到偶尔会打印"MISMATCH1"。

 此时、我们有两个广告标签、主 Adv 间隔为100ms、定期 Adv 间隔为100ms、此时协调器同步到这两个标签、同时还接收 IQ 样本。 我们的问题是、如果 Adv Data 与实际源 BLE Mac 混淆、这是否可能导致 IQ 样本在两个标签之间混在一起? 如果发生这种情况、那么在计算时、角度显然将是错误的

最后3条 MAC 为:

29c2 80和12 12 12 12

正常状态下的行与此类似(请注意"29c280、29c280"-来自 BLE 的 Mac 与来自 Adv 数据的 Mac -相同)

"2023-01-04 00:23:24:314"、$AdvRpt、2981883、273676829c280、29c280、80、-46、26、0、0、1、87

不匹配的行(注意事项"29c280、12121212"- BLE MAC 为29c280、Adv 数据中的 MAC 为121212)

2023-01-04 00:23:24:515",*** MISMATCH1 ***$AdvRpt, 2981883,2736768,29c280,1212,80,-68213,0,1,87

下面的代码用于打印这些代码行、以帮助您了解我们正在查看的内容:

char id_rx[12];
char id_tx[12];
char ble_tx[7];
char ble_tx_adv[7];
char interval[7];
char rssi[5];

itoa(AIRISTA_LOC_ID, id_rx,10);
itoa(((pAdvRpt->addr[2]<<16) + (pAdvRpt->addr[1]<<8) + pAdvRpt->addr[0]), id_tx, 10);
itoa(((pAdvRpt->addr[2]<<16) + (pAdvRpt->addr[1]<<8) + pAdvRpt->addr[0]), ble_tx, 16);//THIS IS MAC FROM BLE STACK
itoa(((pAdvRpt->pData[21]<<16) + (pAdvRpt->pData[20]<<8) + pAdvRpt->pData[19]), ble_tx_adv, 16); //THIS IS MAC FROM Adv Data
itoa(pAdvRpt->periodicAdvInt,interval,10);
itoa(pAdvRpt->rssi,rssi,10);

//2022/09/26 - change the @ to $ sign before AdvRpt
//strcpy(buffer, "@AdvRpt,");

strcpy(buffer, "$AdvRpt,");
strcat(buffer,id_rx);
strcat(buffer, ",");
strcat(buffer, id_tx);
strcat(buffer, ",");
strcat(buffer, ble_tx);
strcat(buffer, ",");
strcat(buffer, ble_tx_adv);
strcat(buffer, ",");
strcat(buffer, interval);
strcat(buffer, ",");
strcat(buffer, rssi);
strcat(buffer, ",");


e2e.ti.com/.../2063.log.txt

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

    同时、尝试从协调器中删除同步、还删除了响应器端的定期 Adv、仍然可以看到行为:

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

    如果我使响应器广播传统类型:

    /// Default parameters for legacy, scannable, connectable advertising
    #define GAPADV_PARAMS_LEGACY_SCANN_CONN {                                 \
     .eventProps = GAP_ADV_PROP_CONNECTABLE | GAP_ADV_PROP_SCANNABLE |        \
                   GAP_ADV_PROP_LEGACY,                                       \
     .primIntMin = 160,                                                       \
     .primIntMax = 160,                                                       \
     .primChanMap = GAP_ADV_CHAN_ALL,                                         \
     .peerAddrType = PEER_ADDRTYPE_PUBLIC_OR_PUBLIC_ID,                       \
     .peerAddr = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },                      \
     .filterPolicy = GAP_ADV_WL_POLICY_ANY_REQ,                               \
     .txPower = GAP_ADV_TX_POWER_NO_PREFERENCE,                               \
     .primPhy = GAP_ADV_PRIM_PHY_1_MBPS,                                      \
     .secPhy = GAP_ADV_SEC_PHY_1_MBPS,                                        \
     .sid = 0                                                                 \
    }

    并且还修改协调器以仅扫描传统:

    temp16 = SCAN_FLT_PDU_LEGACY_ONLY | SCAN_FLT_PDU_COMPLETE_ONLY;
    GapScan_setParam(SCAN_PARAM_FLT_PDU_TYPE, &temp16);

    10分钟内我尚未获得任何不匹配的照片:

    很明显、仅当 ADV 类型为扩展 ADV 时、才会混合物理 BLE MAC 与实际 ADV 数据。

    请告知您是否可以复制此案例以及可能的修复方法。

    e2e.ti.com/.../log_5F00_legacy.txt

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

    嗨、Ivan:

    感谢您在 e2e 上发帖。 我希望你不介意,我重新格式化你的帖子,使它更容易阅读。 将来、我建议使用代码插入工具、并将日志语句保存在 log.txt 文件中并上传(两者都可以使用 Insert 菜单完成)。

    我已经将您的帖子分配给了可以帮助解决您的 AoA 问题的同事。 他目前正在商务旅行,所以可能有一个轻微的延迟,我希望这是可以的,并真正感谢你的耐心。

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

    Ammar、感谢您的回复!

    这对我们来说是相当紧迫的。
    如果为了复制此案例而需要其他信息、请发布回复、我将立即跟进。
    我将在接下来的2周内远程办公、我将请我的同事监控此主题并在需要时跟进。

    我期待收到 TI 的回复-感谢您的提前支持!

    Ivan Slavov

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

    伊凡、您好!

    要确认、地址模式是否已更改为公共地址以外的模式? 如何更改广播数据? 是否正在使用 GapAdv_prepareLoadByBuffer() 函数? 扫描和广播 SLA 实验室 提供了一些有关如何在运行时修改广播数据的有用信息、在这里可能会有所帮助。

    此致、

    1月

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

    大家好、Jan、

    在启用广播之前、我们在器件初始化事件内将 MAC 地址字节设置为"Adv data byte "数组。 下面是初始函数"rtlsResponse_advertInit"、它在 RTLSResponseer_processGapMessage 中的"GAP_DEVICE_INIT_DONE_EVENT"处理程序内部调用。 我们添加了几行、主要是从"GAP_DEVICE_INIT_DONE_EVENT"参数中复制提供给应用的6个字节 MAC、并设置 Adv 数据中的这些字节-我们期望扫描器在检测到这些信标时 BLE MAC 地址来自协调器侧 RC_EVT_ADV_REPORT 内的"GapScan_Evt_AdvRpt_t"参数、以匹配刚刚检测到的 Adv 数据中的6个字节。 这里是我们看到差异的地方。。

    我希望 以下内容足以回答您的问题。 如果您有任何其他需要、请告诉我。

    谢谢。

    伊万

    static void RTLSResponder_advertInit(gapDeviceInitDoneEvent_t *pPkt)
    {
      bStatus_t status = FAILURE;
    
      
    #ifdef USE_PERIODIC_ADV
      // Create non connectable & non scannable advertising set #3
    
        GapAdv_params_t advParamNonConn = GAPADV_PARAMS_AE_NC_NS;
    
      // AiRISTA added
      // shorten advertizing interval on the primary channel
      advParamNonConn.primIntMax = RR_NCNS_ADV_PRIM_INT_625US; // 2021.12.3
      advParamNonConn.primIntMin = RR_NCNS_ADV_PRIM_INT_625US;
      // end AiRISTA added
    
      // Create Advertisement set #3 and assign handle
      status = GapAdv_create(&RTLSResponder_advCb, &advParamNonConn,
                                                       &advHandleNCNS);
      RTLSRESPONDER_ASSERT(status == SUCCESS);
    
      // AiRISTA added
      advertData[20] = pPkt->devAddr[0];
      advertData[21] = pPkt->devAddr[1];
      advertData[22] = pPkt->devAddr[2];
      advertData[23] = pPkt->devAddr[3];
      advertData[24] = pPkt->devAddr[4];
      advertData[25] = pPkt->devAddr[5];
      // end AiRISTA added
    
      // Load advertising data for set #3 that is statically allocated by the app
      status = GapAdv_loadByHandle(advHandleNCNS, GAP_ADV_DATA_TYPE_ADV,
                                         sizeof(advertData), advertData);
      RTLSRESPONDER_ASSERT(status == SUCCESS);
    
      // Set event mask for set #3
      status = GapAdv_setEventMask(advHandleNCNS,
                                   GAP_ADV_EVT_MASK_START_AFTER_ENABLE |
                                   GAP_ADV_EVT_MASK_END_AFTER_DISABLE |
                                   GAP_ADV_EVT_MASK_SET_TERMINATED
                                   | GAP_ADV_EVT_MASK_END//(2022/09/23 - Ivan)
                                   );
    
      // Enable non connectable & non scannable advertising for set #3
    
      status = GapAdv_enable(advHandleNCNS, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0); 
    
      RTLSRESPONDER_ASSERT(status == SUCCESS);
    
      // Set Periodic Advertising parameters
      GapAdv_periodicAdvParams_t perParams = {PERIDIC_ADV_INTERVAL_MIN, PERIDIC_ADV_INTERVAL_MAX, 0x40};
      status = GapAdv_SetPeriodicAdvParams(advHandleNCNS, &perParams);
      RTLSRESPONDER_ASSERT(status == SUCCESS);
    
    #endif
    }

    以下是 GAPADV_PARAMS_AE_NC_NS 中的 ADV 数据设置

    /// Non-Connectable & Non-Scannable advertising set
    #define GAPADV_PARAMS_AE_NC_NS {                                           \
      .eventProps = 0,                                                         \
      .primIntMin = 160,                                                       \
      .primIntMax = 160,                                                       \
      .primChanMap = GAP_ADV_CHAN_ALL,                                         \
      .peerAddrType = PEER_ADDRTYPE_PUBLIC_OR_PUBLIC_ID,                       \
      .peerAddr = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },                      \
      .filterPolicy = GAP_ADV_WL_POLICY_ANY_REQ,                               \
      .txPower = GAP_ADV_TX_POWER_NO_PREFERENCE,                               \
      .primPhy = GAP_ADV_PRIM_PHY_1_MBPS,                                      \
      .secPhy = GAP_ADV_SEC_PHY_1_MBPS,                                        \
      .sid = 1                                                                 \
    }

    PS:

    我们通过"TI 闪存编程器"MAC 地址"选项卡为器件提供一个 MAC 地址、并且该 MAC 地址从 BLE 用作源 MAC。 我们使用这一概念为我们的标签提供 MAC 地址、并且已经为我们100%完成了工作。

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

    一月、

    我想您可能已经要求设置此设置、而我之前误解了:

    我们没有更改该设置、它是 ADDRMODE_PUBLIC

    // Address mode of the local device
    // Note: When using the DEFAULT_ADDRESS_MODE as ADDRMODE_RANDOM or
    // ADDRMODE_RP_WITH_RANDOM_ID, GAP_DeviceInit() should be called with
    // it's last parameter set to a static random address
    #define DEFAULT_ADDRESS_MODE                  ADDRMODE_PUBLIC

    如果结果/打印周围只有一个标签是正常的,当我们打开第二个标签时,我们就开始得到偶尔的差异..

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

    伊凡、您好!

    明白了。 不用担心! 感谢您的澄清。 您是否具有监听器的访问权限? 如果是、那么您能否在两个器件都在广播时使用嗅探器记录无线通信? 这将有助于我们确保所发送的数据包符合我们的预期。 此时、我认为中央侧可能会发生一些事情、因此这将帮助我们缩小行为的来源。 如果您没有监听器、则可以使用 SmartRF 数据包监听器2  软件和附加的 LaunchPad 来监听广播数据包。

    此致、

    1月

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

    大家好、Jan、

    我们尝试使用 SmartRF 数据包监听器2工具捕获 BLE 扩展广播、但没有收到来自我们使用扩展广播的两个标签的数据包。

      

    但是、我们会接收到来自 MAC 地址范围内其他器件的旧广播。

    我们的配置是否有问题、或者此工具是否只能接收旧的 BLE 广播?

    谢谢!

    Shayan

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

    大家好、Jan、

    我们正在尝试嗅探、但这些工具似乎只捕获传统广告。 能否请大家尝试使用初始线程启动响应中的步骤重现此问题:

    1.在 Adv 数据字节中设置 Mac 的最后3个

    2.修改协调器以将堆栈中的 Mac 地址字节与 Adv 数据中的字节进行比较,并确认不匹配-我确信您会看到差异

    复制应该非常简单、您需要3个 LP - 1个协调人和2个响应者。

    请告知我们是否 能够观看。 我们正在 等待您的回复

    谢谢。

    伊万

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

    您好!

    您是对的。 Packet Sniffer 2软件只能检测传统广播。 要监听扩展数据包、此处需要专用监听器。 您能否共享应用程序代码供我们使用并尝试重现此行为?

    此致、

    1月

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

    大家好、Jan、

    您建议我们如何共享代码? 您能否向我发送一个电子邮件地址、以便我们通过电子邮件向您发送、而不是在此处公开共享?

    谢谢。

    伊万

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

    伊凡、您好!

    您是否有包含展示该行为所需的最少修改的项目或应用程序代码版本? 无需共享您的自定义应用程序。 具体而言、如果您的项目仅进行了以下能够表现出所观察行为的修改、那么这是理想情况。

    1.在 Adv 数据字节中设置 Mac 的最后3个

    2.修改协调器以将堆栈中的 Mac 地址字节与 Adv 数据中的字节进行比较,并确认不匹配-我确信您会看到差异

    [/报价]

    此致、

    1月

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

    大家好、Jan、

    如果您给我发送电子邮件、我很乐意给您发送电子邮件、告诉您您您的团队可以直接运行并且希望能够重现的两个项目。

    我的电子邮件是: ivan.slavov@airista.com

    我试图概述这些变化、这些变化也很简单。

    换句话说、将 MAC 地址字节嵌入到响应器端的 ADV 数据中、然后在协调器端将来自 ADV 数据的 MAC 字节与堆栈报告的 MAC 字节进行比较、

    响应者项目更改:

    1.我们修改了 Adv 数据,不是很 相关,但下面是我们如何拥有它:

    // Advertisement data
    uint8_t advertData[] =
    {
      0x0E,							// Length of this data
      GAP_ADTYPE_LOCAL_NAME_SHORT,  // Type of this data
      'R',
      'T',
      'L',
      'S',
      'R',
      'e',
      's',
      'p',
      'o',
      'n',
      'd',
      'e',
      'r',
      0x02,   // length of this data
      GAP_ADTYPE_FLAGS,
      DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
      0x0B,//AiRISTA Added //11 more bytes to follow
      GAP_ADTYPE_MANUFACTURER_SPECIFIC,//0xFF
      0xFF,//i20 MAC1
      0xFF,//i21 MAC2
      0xFF,//i22 MAC3
      0xFF,//i23 MAC4
      0xFF,//i24 MAC5
      0xFF,//i25 MAC6
      0x00,//(2022/09/23, Ivan), index[26] - SQN8
      0x00,//(2022/09/23, Ivan), index[27] - reason code
      0x00,//(2022/09/23, Ivan), index[28] - additional info(bit0=Charging, bit1=Safety Switch)
      0x00,//(2022/09/23, Ivan), index[29] - battery %
        //size of advData is now 30
    };

    2.更新 Adv 数据以嵌入器件 Mac,并启用 Adv

    static void RTLSResponder_advertInit(gapDeviceInitDoneEvent_t *pPkt)
    {
      bStatus_t status = FAILURE;
    
      // Setup and start Advertising
      // For more information, see the GAP section in the User's Guide:
      // software-dl.ti.com/.../
    
      // Temporary memory for advertising parameters for set #1. These will be copied
      // by the GapAdv module
    
      //AiRISTA - disable legacy
    //  GapAdv_params_t advParamLegacy = GAPADV_PARAMS_LEGACY_SCANN_CONN;
    //
    //  BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : ---- call GapAdv_create set=%d,%d\n", 0, 0);
    //  // Create Advertisement set #1 and assign handle
    //  status = GapAdv_create(&RTLSResponder_advCb, &advParamLegacy, &advHandleLegacy);
    //  RTLSRESPONDER_ASSERT(status == SUCCESS);
    //
    //  // Load advertising data for set #1 that is statically allocated by the app
    //  status = GapAdv_loadByHandle(advHandleLegacy, GAP_ADV_DATA_TYPE_ADV,
    //                               sizeof(advertData), advertData);
    //  RTLSRESPONDER_ASSERT(status == SUCCESS);
    //
    //  // Load scan response data for set #1 that is statically allocated by the app
    //  status = GapAdv_loadByHandle(advHandleLegacy, GAP_ADV_DATA_TYPE_SCAN_RSP, sizeof(scanRspData), scanRspData);
    //  RTLSRESPONDER_ASSERT(status == SUCCESS);
    //
    //  // Set event mask for set #1
    //  status = GapAdv_setEventMask(advHandleLegacy,
    //                               GAP_ADV_EVT_MASK_START_AFTER_ENABLE |
    //                               GAP_ADV_EVT_MASK_END_AFTER_DISABLE |
    //                               GAP_ADV_EVT_MASK_SET_TERMINATED);
    //
    //  BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- GapAdv_enable", 0);
    //  // Enable legacy advertising for set #1
    //  status = GapAdv_enable(advHandleLegacy, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0);
    //  RTLSRESPONDER_ASSERT(status == SUCCESS);
    
    #ifdef USE_PERIODIC_ADV
      // Create non connectable & non scannable advertising set #3
    
      GapAdv_params_t advParamNonConn = GAPADV_PARAMS_AE_NC_NS;
    
      // AiRISTA added
      // shorten advertizing interval on the primary channel
      advParamNonConn.primIntMax = RR_NCNS_ADV_PRIM_INT_625US; // 2021.12.3
      advParamNonConn.primIntMin = RR_NCNS_ADV_PRIM_INT_625US;
      // end AiRISTA added
    
      // Create Advertisement set #3 and assign handle
      status = GapAdv_create(&RTLSResponder_advCb, &advParamNonConn,
                                                       &advHandleNCNS);
      RTLSRESPONDER_ASSERT(status == SUCCESS);
    
      // AiRISTA added
      advertData[20] = pPkt->devAddr[0];
      advertData[21] = pPkt->devAddr[1];
      advertData[22] = pPkt->devAddr[2];
      advertData[23] = pPkt->devAddr[3];
      advertData[24] = pPkt->devAddr[4];
      advertData[25] = pPkt->devAddr[5];
      // end AiRISTA added
    
      // Load advertising data for set #3 that is statically allocated by the app
      status = GapAdv_loadByHandle(advHandleNCNS, GAP_ADV_DATA_TYPE_ADV,
                                         sizeof(advertData), advertData);
      RTLSRESPONDER_ASSERT(status == SUCCESS);
    
      // Set event mask for set #3
      status = GapAdv_setEventMask(advHandleNCNS,
                                   GAP_ADV_EVT_MASK_START_AFTER_ENABLE |
                                   GAP_ADV_EVT_MASK_END_AFTER_DISABLE |
                                   GAP_ADV_EVT_MASK_SET_TERMINATED
                                   | GAP_ADV_EVT_MASK_END//(2022/09/23 - Ivan)
                                   );
    
      // Enable non connectable & non scannable advertising for set #3
    
        status = GapAdv_enable(advHandleNCNS, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0); // Original
    
      RTLSRESPONDER_ASSERT(status == SUCCESS);
    
      // Set Periodic Advertising parameters
      GapAdv_periodicAdvParams_t perParams = {PERIDIC_ADV_INTERVAL_MIN, PERIDIC_ADV_INTERVAL_MAX, 0x40};
      status = GapAdv_SetPeriodicAdvParams(advHandleNCNS, &perParams);
      RTLSRESPONDER_ASSERT(status == SUCCESS);
    
    
      Xpert_Board_Keys_Led2_Green_Swap();
    
    #endif
    }

    3.此时,响应者项目中没有其他的相关内容。 下面是 Adv 参数,我不相信我们已经修改:

    /// Non-Connectable & Non-Scannable advertising set
    #define GAPADV_PARAMS_AE_NC_NS {                                           \
      .eventProps = 0,                                                         \
      .primIntMin = 160,                                                       \
      .primIntMax = 160,                                                       \
      .primChanMap = GAP_ADV_CHAN_ALL,                                         \
      .peerAddrType = PEER_ADDRTYPE_PUBLIC_OR_PUBLIC_ID,                       \
      .peerAddr = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },                      \
      .filterPolicy = GAP_ADV_WL_POLICY_ANY_REQ,                               \
      .txPower = GAP_ADV_TX_POWER_NO_PREFERENCE,                               \
      .primPhy = GAP_ADV_PRIM_PHY_1_MBPS,                                      \
      .secPhy = GAP_ADV_SEC_PHY_1_MBPS,                                        \
      .sid = 1                                                                 \
    }
    

    协调器项目更改:

    1.启用扫描:

        case GAP_DEVICE_INIT_DONE_EVENT:
        {
          uint8_t temp8;
          int8_t signed_temp8;
          uint16_t temp16;
    
          BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- got GAP_DEVICE_INIT_DONE_EVENT", 0);
          // Setup scanning
          // For more information, see the GAP section in the User's Guide:
          // software-dl.ti.com/.../
    
          // Register callback to process Scanner events
          GapScan_registerCb(RTLSCoordinator_scanCb, NULL);
    
          // Set Scanner Event Mask
          GapScan_setEventMask(GAP_EVT_SCAN_ENABLED | GAP_EVT_SCAN_DISABLED |
                               GAP_EVT_ADV_REPORT);
    
          // AiRISTA modified
          // Set Scan PHY parameters
          //GapScan_setPhyParams(DEFAULT_SCAN_PHY, SCAN_TYPE_PASSIVE,
          //                     200, 100); // Original
          GapScan_setPhyParams(DEFAULT_SCAN_PHY, SCAN_TYPE_PASSIVE,
                               SCAN_PARAM_INTERVAL_625US, SCAN_PARAM_WINDOW_625US); // 2021.12.1
    
          // Set Advertising report fields to keep
          temp16 = RC_ADV_RPT_FIELDS;
          GapScan_setParam(SCAN_PARAM_RPT_FIELDS, &temp16);
          // Set Scanning Primary PHY
          temp8 = DEFAULT_SCAN_PHY;
          GapScan_setParam(SCAN_PARAM_PRIM_PHYS, &temp8);
          // Set RSSI Filter // Added 2021.11.30
          signed_temp8 = -128;//-90;
          GapScan_setParam(SCAN_PARAM_FLT_MIN_RSSI, &signed_temp8);
          // Set LL Duplicate Filter
          temp8 = SCAN_FLT_DUP_DISABLE;
          //temp8 = SCAN_FLT_DUP_ENABLE;
          GapScan_setParam(SCAN_PARAM_FLT_DUP, &temp8);
    
          // Set PDU type filter -
          // Only 'Complete' packets are desired.
          // It doesn't matter if received packets are
          // whether Scannable or Non-Scannable, whether Directed or Undirected,
          // whether Connectable or Non-Connectable, whether Scan_Rsp's or Advertisements,
          // and whether Legacy or Extended.
          // temp16 = SCAN_FLT_PDU_COMPLETE_ONLY; // Original
    
          temp16 = SCAN_FLT_PDU_EXTENDED_ONLY | SCAN_FLT_PDU_COMPLETE_ONLY; // 2021.12.1
    
          BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- GapScan_setParam", 0);
          GapScan_setParam(SCAN_PARAM_FLT_PDU_TYPE, &temp16);
          // End AiRISTA modified
    
          // AiRISTA added
          AiRISTA_CL_Init((gapDeviceInitDoneEvent_t *)pMsg); // 2021.10.28
          // end AiRISTA added
        }
        
        
        
        static void AiRISTA_CL_Init(gapDeviceInitDoneEvent_t *pPkt)
    {
        // Locator ID is last 3 bytes of MAC address
        AIRISTA_LOC_ID = (pPkt->devAddr[2]<<16) + (pPkt->devAddr[1]<<8) + pPkt->devAddr[0];
        #ifdef AiRISTA_DEBUG
          AiRISTA_SendDataToBackend_String("\r\nAIRISTA_LOC_ID:");
          AiRISTA_SendDataToBackend_Int(AIRISTA_LOC_ID);
        #else
          AiRISTA_sendRxDeviceId(AIRISTA_LOC_ID);
        #endif
    
        // Allocate memory for sync terminated device
        pTerminateSyncDevice = RTLSCtrl_malloc(sizeof(AiRISTA_terminateSyncDevice_t)); // 2021.12.29
        if (pTerminateSyncDevice == NULL)
        {
            #ifdef AiRISTA_DEBUG //2021.12.29
              AiRISTA_SendDataToBackend_String("\r\nAiRISTA_CL_Init - pTerminateSyncDevice, malloc error");
            #endif
            return;
        }
    
        // Allocate memory for sync linked list
        AiRISTA_pSyncLinkList = RTLSCtrl_malloc(sizeof(AiRISTA_syncLinkList_t)); // 2021.11.12
        if (AiRISTA_pSyncLinkList != NULL)
        {
            AiRISTA_pSyncLinkList->count = 0;
            AiRISTA_pSyncLinkList->devicesHead = NULL;
            AiRISTA_pSyncLinkList->devicesTail = NULL;
    
            #ifdef AiRISTA_DEBUG //2021.11.11
              AiRISTA_SendDataToBackend_String("\r\nAiRISTA_CL_Init - pSyncLinkList, count:");
              AiRISTA_SendDataToBackend_Int((AiRISTA_pSyncLinkList->count));
            #endif
        }
        else
        {
            #ifdef AiRISTA_DEBUG //2021.11.11
              AiRISTA_SendDataToBackend_String("\r\nAiRISTA_CL_Init - pSyncLinkList, malloc error");
            #endif
            return;
        }
    
        if (AiRISTA_USE_PERIODIC_ADV_LIST == 1)
        {
            // Allocate memory for periodic advertisers linked list
            AiRISTA_pPerAdvLinkList = RTLSCtrl_malloc(sizeof(AiRISTA_perAdvLinkList_t)); // 2021.12.13 // 1234
            if (AiRISTA_pPerAdvLinkList != NULL)
            {
                AiRISTA_pPerAdvLinkList->count = 0;
                AiRISTA_pPerAdvLinkList->devicesHead = NULL;
                AiRISTA_pPerAdvLinkList->devicesTail = NULL;
    
                #ifdef AiRISTA_DEBUG
                  AiRISTA_SendDataToBackend_String("\r\nAiRISTA_CL_Init - pPerAdvLinkList, count:");
                  AiRISTA_SendDataToBackend_Int((AiRISTA_pSyncLinkList->count));
                #endif
            }
            else
            {
                #ifdef AiRISTA_DEBUG
                  AiRISTA_SendDataToBackend_String("\r\nAiRISTA_CL_Init - pPerAdvLinkList, malloc error");
                #endif
                return;
            } // 1234
        }
    
        // Start scan
        scanRes = 0;
        uint8_t status = GapScan_enable(AIRISTA_SCAN_PERIOD_1280MS,AIRISTA_SCAN_DUR_10MS,AIRISTA_SCAN_MAX_RPT_NUM);
        // uint8_t status = GapScan_enable(0, DEFAULT_SCAN_DURATION,DEFAULT_MAX_SCAN_RES); // single scan
        #ifdef AiRISTA_DEBUG
          AiRISTA_DEBUG_SendDataToBackend_String("\r\nGapScan_enable");
          AiRISTA_DEBUG_SendDataToBackend_String(", status:");
          AiRISTA_DEBUG_SendDataToBackend_Int(status);
        #endif
    }
    
    
    defines:
    // AiRISTA added
    #define RTLS_CMD_AOA_RESULT_RAW             0x24
    #define AiRISTA_USE_PERIODIC_ADV_LIST       1
    //#define SCAN_PARAM_INTERVAL_625US           176*2                   // scan interval (in 625 us ticks) // 2021.12.3
    //#define SCAN_PARAM_WINDOW_625US             176                     // scan window (in 625 us ticks) // 2021.12.3
    #define SCAN_PARAM_INTERVAL_625US           176                     // scan interval (in 625 us ticks) // 2021.12.3
    #define SCAN_PARAM_WINDOW_625US             160                     // scan window (in 625 us ticks) // 2021.12.3
    //#define AiRISTA_SYNC_TIMEOUT_10MS           25                      // sync timeout (in 10ms units) // 2021.12.07
    //#define AiRISTA_SYNC_TIMEOUT_10MS           500
    #define AiRISTA_SYNC_TIMEOUT_10MS           100
    //#define AiRISTA_SYNC_TIMEOUT_10MS           1600
    #define AIRISTA_SCAN_PERIOD_1280MS          0                       // no period
    #define AIRISTA_SCAN_DUR_10MS               0                       // continuous scan
    #define AIRISTA_SCAN_MAX_RPT_NUM            DEFAULT_MAX_SCAN_RES    // user-defined limit
    

    2.以下是 报告事件中存在的差异:

    您可以看到我们在日志中捕获和共享的"MISMATCH1"指纹

    case RC_EVT_ADV_REPORT:
        {
          GapScan_Evt_AdvRpt_t* pAdvRpt = (GapScan_Evt_AdvRpt_t*) (pMsg->pData);
          uint8_t status;
    
    
    
          char responderScanRsp[] = {'R','T','L','S','R','e','s','p','o','n','d','e','r'};
    
          // Filter results to only consider the testng tags 
          if (memcmp(&pAdvRpt->pData[2], responderScanRsp, sizeof(responderScanRsp)) == 0)
          {
              if (pAdvRpt->addr[2] != pAdvRpt->pData[22] || pAdvRpt->addr[1] != pAdvRpt->pData[21] || pAdvRpt->addr[0] != pAdvRpt->pData[20])
            {
                //we should not be coming here...
                //it happens from time to time when there are two or more tags adverstising, and the MAC addresses are getting mixed up....
                AiRISTA_DEBUG_SendDataToBackend_String("*** MISMATCH1 ***");
            }
            // AiRISTA added
            #ifdef AiRISTA_DEBUG // temporary // 2021.11.30
    //          char buffer[128];
    //          char temp[12];
    //          strcpy(buffer, "\r\n Adv Report: ");
    //          itoa(pAdvRpt->addr[2], temp, 16);
    //          strcat(buffer,temp);
    //          itoa(pAdvRpt->addr[1], temp, 16);
    //          strcat(buffer,temp);
    //          itoa(pAdvRpt->addr[0], temp, 16);
    //          strcat(buffer,temp);
    //          strcat(buffer, ", ");
    //          itoa(pAdvRpt->periodicAdvInt, temp, 10);
    //          strcat(buffer,temp);
    //          strcat(buffer, ", ");
    //          itoa(pAdvRpt->dataLen,temp,10);
    //          strcat(buffer,temp);
    //          strcat(buffer, ", ");
    //          itoa(pAdvRpt->pData[21],temp,16);
    //          strcat(buffer,temp);
    //          itoa(pAdvRpt->pData[20],temp,16);
    //          strcat(buffer,temp);
    //          itoa(pAdvRpt->pData[19],temp,16);
    //          strcat(buffer,temp);
    
    //          ICall_heapStats_t stats;
    //          ICall_getHeapStats(&stats);
    //          AiRISTA_DEBUG_SendDataToBackend_String("\r\nICall_getHeapStats, tot. free size:");
    //          AiRISTA_DEBUG_SendDataToBackend_Int(stats.totalFreeSize);
            #else
              AiRISTA_sendAdvRptData(pAdvRpt);
            #endif
    
        
            // End AiRISTA added
            // RTLSCoordinator_addDeviceInfo(pAdvRpt); // original // Commented out 2021.11.09
          }
    
          // Free report payload data
          if (pAdvRpt->pData != NULL)
          {
            ICall_free(pAdvRpt->pData);
          }
        }
        break;
    

    谢谢。
    伊万

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

    伊凡、您好!

    这很有帮助! 我将尝试使用此代码来复制最终的行为

    此致、

    1月

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

    伊凡、您好!

    我仍在研究这一问题。 我将在星期二的某个时候提供有关当前状态的更新。 给您带来不便、我们深表歉意。

    此致、

    1月

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

    感谢 更新、Jan!

    等你准备好后,我会等待你的回应。

    谢谢。

    伊万

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

    伊凡、您好!

    我在构建协调员和响应者项目时遇到了问题、因为您进行了给定的修改。 在响应者项目中、我只缺少 RR_NCNS ADV_Prim_INT_625US 的定义。 在协调器项目中、我错过了您的许多自定义功能。

    后退一步、似乎该行为可以简化为以下内容。  

    1.响应者-正在其广播数据中广播自己的 BLE 地址

    2.协调器-正在扫描响应者通告,偶尔会看到扫描的广播包包含所广播的地址与发送广播的设备的地址不匹配。

    是这样吗? 如果是、那么您是否可以采用未经修改的 RTLS_Coordinator 和 RTLS_Response 并实施重建您看到的行为所需的最少修改? 这将有助于我们查明这种行为的潜在原因。

    此致、

    1月

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

    一月、

    是的、你的总结完全正确-这正是我试图描述的-它应该很容易编译和运行。 您可以忽略任何自定义函数、然后尝试您所描述的内容-当您启动第二个响应者时、我们开始看到协调器端的差异。

    以下是您缺少的定义:

    //this is primary adv interval
    #define AiRISTA_RR_NCNS_ADV_PRIM_INT_625US  160    // 100ms
    
    //below are the intervals of the PERIDIC_ADV
    //!< Minimum periodic advertising interval; Range: 0x0006 to 0xFFFF Time = N * 1.25 ms Time Range: 7.5ms to 81.91875s
    //old values were 80 (100msec)
    #define AiRISTA_PERIDIC_ADV_INTERVAL_MIN    80  // 100 ms
    #define AiRISTA_PERIDIC_ADV_INTERVAL_MAX    80  // 100 ms
    
    
    

    如果您能够运行、请告知我们。

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

    伊凡、您好!

    明白了! 我懂了。 我将在我身边设置一些示例、以便在进行必要的最少更改的情况下重现此行为。 我会尽快报告。

    此致、

    1月

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

    伊凡、您好!

    我还没有时间在我身边测试这一点。 我真的很抱歉。 我明天会向你介绍我能够取得的任何进展。 对于由此可能造成的任何不便、我深表歉意。

    此致、

    1月

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

    伊凡、您好!

    向 RTLS 示例添加功能时遇到一些问题、因此我退一步、能够快速将其添加到 simple_central 和 simple_peripheral 示例。 在这些示例中、我没有看到所描述的问题、但我想与您分享我执行的项目和更改、以防我漏掉了一些内容。

    1.将简单外设设置为使用公共地址(SysConfig)

    2.简单外设广播数据更改为了包含唯一的 UUID 及其地址空间(SysConfig)

    3.在创建 advHandle 之前,简单外设的广播数据按如下方式加载:(GAPP_DEVICE_INIT_DONE_EVENT 在 SimplePeripheral_processGapMessage 中)

    4. Advdata2和远距离广播句柄已从项目中移除。 (sysconfig 和整个 simple_peripheral.c)

    5.通过 UUID (SysConfig)启用 Simple Central 发现

    6.向 Simple Central 添加了逻辑,以检查是否存在唯一的 UUID,并确定公布数据中的地址和设备的地址是否相同(在 SimpleCentral_processAppMsg ()的 SC_EVT_ADV_REPORT 事件中)[下面可以看到其中一些逻辑]

    我已在此处上传项目:

    e2e.ti.com/.../simple_5F00_peripheral_5F00_CC26X2R1_5F00_LAUNCHXL_5F00_tirtos7_5F00_ticlang.zip

    e2e.ti.com/.../simple_5F00_central_5F00_CC26X2R1_5F00_LAUNCHXL_5F00_tirtos7_5F00_ticlang.zip

    一旦在两个器件上刷写工程、当中心设备扫描时、它将查找 simple_peripheral 器件并检查其广播数据和地址:

    您能否仔细看一下项目、看看您是否可以在最终看到相同的行为? 在调用 gap_advCreate ()函数之前,您可以尝试在 advt 数据数组中设置设备地址吗?

    此致、

    1月

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

    一月、

    我想您可能正在使用传统广播(我很确定 simple_peripheral_CC26X2R1项目使用 传统)、但当标签广播传统时不会发生该问题、仅当它们使用扩展广播时才会发生。

    我正在尝试运行您的项目并进行确认、但无法导入它们... 我随后下载了项目、并尝试将项目导入到工作区中。  我正在使用 CCS 12.1.0.00007、并得到下面的错误。

    您正在使用哪个 CCS 版本?

    我会继续尝试、并尽快回复更多详细信息。

    谢谢。

    伊万

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

    一月、

    我仍然无法编译您的项目、但与此同时、您可以将 Adv 更改为不再保留并尝试运行您的示例吗?

    例如使用这些设置

    /// Non-Connectable & Non-Scannable advertising set
    #define GAPADV_PARAMS_AE_NC_NS {                                           \
      .eventProps = 0,                                                         \
      .primIntMin = 160,                                                       \
      .primIntMax = 160,                                                       \
      .primChanMap = GAP_ADV_CHAN_ALL,                                         \
      .peerAddrType = PEER_ADDRTYPE_PUBLIC_OR_PUBLIC_ID,                       \
      .peerAddr = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },                      \
      .filterPolicy = GAP_ADV_WL_POLICY_ANY_REQ,                               \
      .txPower = GAP_ADV_TX_POWER_NO_PREFERENCE,                               \
      .primPhy = GAP_ADV_PRIM_PHY_1_MBPS,                                      \
      .secPhy = GAP_ADV_SEC_PHY_1_MBPS,                                        \
      .sid = 1                                                                 \
    }

    我认为、您使用的是这样的器件、它是传统器件、我们在使用传统 Adv 时从未观察到混音

    GapAdv_params_t advParams1 = {
      .eventProps =   GAP_ADV_PROP_CONNECTABLE | GAP_ADV_PROP_LEGACY | GAP_ADV_PROP_SCANNABLE,
      .primIntMin =   160,
      .primIntMax =   160,
      .primChanMap =  GAP_ADV_CHAN_ALL,
      .peerAddrType = PEER_ADDRTYPE_PUBLIC_OR_PUBLIC_ID,
      .peerAddr =     { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa },
      .filterPolicy = GAP_ADV_WL_POLICY_ANY_REQ,
      .txPower =      GAP_ADV_TX_POWER_NO_PREFERENCE,
      .primPhy =      GAP_ADV_PRIM_PHY_1_MBPS,
      .secPhy =       GAP_ADV_SEC_PHY_1_MBPS,
      .sid =          0
    };

    如果您使用 SysConfig 进行编辑、则将传统模式更改为扩展模式、并请尝试使用两个外设和一个中央设备再次运行

    谢谢。

    伊万

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

    伊凡、您好!

    我的道歉。 我在测试中使用了旧广播类型。 在导入之前、您是否已解压缩我发送给您的项目? 这可能是导致错误的原因。 您能否尝试一下、看看该项目最终是否有效? 如果是、那么您是否可以尝试将其更改为"extended"以查看您是否观察到相同的行为? 如果在正确导入工程时遇到任何问题、请告诉我、我将在最后进行测试并重新打包工程。

    此致、

    1月

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

    一月、

    我无法导入您的项目、收到此错误:

    请告诉我、您认为我可以修复它吗、或者只是尝试将"Adv"切换到"Extended"

    谢谢。

    伊万

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

    伊凡、您好!

    您是否可以尝试展开窗口并粘贴此处的完整错误? 这可能有助于我们了解 CCS 无法导入工程的原因。 我可能没有时间运行测试、直到明天。

    此致、

    1月

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

    Jan、我尝试使用6.20 SDK 中未更改的简单外设和中央设备、进行了您所描述的更改并扩展了广播、而不是传统广播-结果是-没有 MISMTARCHES。

    我有两个标签在运行、我可以看到两条 MAC、而不是一条故障码。

    明天我将着手将简单的 PERIPH 和中央项目与 RTLS 响应者和协调器进行比较- RTLS 方面的问题必然会导致错误-明天我将会用更多详细信息更新此线程。

    谢谢。

    伊万

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

    伊凡、您好!

    听起来不错! 我很高兴您能够重现我在 simple_peripheral 中看到的行为、并确认该行为对扩展广播具有保留。 期待您的更新。

    此致、

    1月

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

    一月、

    下面是我早上的更新-我正在运行相同的2个简单外设客户端进行广播、然后我运行 RTLS 协调器并修改扫描结果以打印任何不匹配、我看到了不匹配

    以下是我打印它们的位置/方式:

    case RC_EVT_ADV_REPORT:
        {
          GapScan_Evt_AdvRpt_t* pAdvRpt = (GapScan_Evt_AdvRpt_t*) (pMsg->pData);
          uint8_t status;
          
          if (pAdvRpt->pData[2] == 'S' && pAdvRpt->pData[3] == 'P')
          {
              AiRISTA_DEBUG_SendDataToBackend_String("+");
    
              if (
                      pAdvRpt->addr[0] == pAdvRpt->pData[15] &&
                      pAdvRpt->addr[1] == pAdvRpt->pData[16] &&
                      pAdvRpt->addr[2] == pAdvRpt->pData[17] &&
                      pAdvRpt->addr[3] == pAdvRpt->pData[18] &&
                      pAdvRpt->addr[4] == pAdvRpt->pData[19] &&
                      pAdvRpt->addr[5] == pAdvRpt->pData[20]
              )
              {
                  ++matches;
                  AiRISTA_DEBUG_SendDataToBackend_String("+");
              }
              else
              {
                  ++mismatches;
                  AiRISTA_DEBUG_SendDataToBackend_String("\r\n");
                  AiRISTA_DEBUG_SendDataToBackend_String(Util_convertBdAddr2Str(&pAdvRpt->addr[0]));
                  AiRISTA_DEBUG_SendDataToBackend_String(" MISMATCH ");
                  AiRISTA_DEBUG_SendDataToBackend_String(Util_convertBdAddr2Str(&pAdvRpt->pData[15]));
                  //AiRISTA_DEBUG_SendDataToBackend_String();
              }
          }
    
          // Free report payload data
          if (pAdvRpt->pData != NULL)
          {
            ICall_free(pAdvRpt->pData);
          }
        }

    接下来、我将尝试从 OEM RTLS 协调器开始执行相同的操作、并清楚地记录我的更改、然后在此主题中嵌入式共享 RTLS 协调器项目以供您审阅。

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

    伊凡、您好!

    感谢您发送编修。 这很有趣、由于某种原因、协调器的扫描似乎引入了不匹配。 这可能是应用程序代码中的一个简单逻辑差异。 我完全同意、我认为下一步是尝试在未经修改的协调器示例上重现此示例(仅添加简单中央项目的不匹配逻辑)。 感谢您进行详细更新和全面调试!

    此致、

    1月

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

    一月、

    附加的是仅有几处更改的 RTLS_Coordinator、全部都用如下行注释掉://aiRISTA

    您应该能够导入库存 RTLS_Coordinator 工程、改写此文件、然后运行它。 如果您搜索"//aiRISTA"、您将看到这些更改、我相信它们会有意义。

    /******************************************************************************
    
     @file  rtls_coordinator.c
    
     @brief This file contains the RTLS Coordinator sample application for use
            with the CC2650 Bluetooth Low Energy Protocol Stack.
    
     Group: WCS, BTS
     Target Device: cc13xx_cc26xx
    
     ******************************************************************************
     
     Copyright (c) 2013-2022, Texas Instruments Incorporated
     All rights reserved.
    
     Redistribution and use in source and binary forms, with or without
     modification, are permitted provided that the following conditions
     are met:
    
     *  Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
    
     *  Redistributions in binary form must reproduce the above copyright
        notice, this list of conditions and the following disclaimer in the
        documentation and/or other materials provided with the distribution.
    
     *  Neither the name of Texas Instruments Incorporated nor the names of
        its contributors may be used to endorse or promote products derived
        from this software without specific prior written permission.
    
     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
     ******************************************************************************
     
     
     *****************************************************************************/
    
    /*********************************************************************
     * INCLUDES
     */
    #include <string.h>
    
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Event.h>
    #include <ti/sysbios/knl/Queue.h>
    
    #include "bcomdef.h"
    #include "l2cap.h"
    
    #include <icall.h>
    #include "util.h"
    /* This Header file contains all BLE API and icall structure definition */
    #include <icall_ble_api.h>
    #include "osal_list.h"
    #include "board_key.h"
    #include <ti_drivers_config.h>
    
    #include "ble_user_config.h"
    
    #include "rtls_coordinator.h"
    
    #include "rtls_ctrl_api.h"
    #include "rtls_ble.h"
    #ifdef RTLS_CTE
    #include "rtls_aoa_api.h"
    #endif /* RTLS_CTE*/
    
    /*********************************************************************
     * MACROS
     */
    
    /*********************************************************************
     * CONSTANTS
     */
    
    // Application events
    #define RC_EVT_SCAN_ENABLED        0x01
    #define RC_EVT_SCAN_DISABLED       0x02
    #define RC_EVT_ADV_REPORT          0x03
    #define RC_EVT_ADV_EVT             0x04
    #define RC_EVT_PAIR_STATE          0x05
    #define RC_EVT_PASSCODE_NEEDED     0x06
    #define RC_EVT_INSUFFICIENT_MEM    0x07
    #define RC_EVT_RTLS_CTRL_MSG_EVT   0x08
    #define RC_EVT_RTLS_SRV_MSG_EVT    0x09
    #define RC_EVT_CONN_EVT            0x0A
    
    // RTLS Coordinator Task Events
    #define RC_ICALL_EVT                         ICALL_MSG_EVENT_ID  // Event_Id_31
    #define RC_QUEUE_EVT                         UTIL_QUEUE_EVENT_ID // Event_Id_30
    
    #define RC_ALL_EVENTS                        (RC_ICALL_EVT | RC_QUEUE_EVT)
    
    // Address mode of the local device
    // Note: When using the DEFAULT_ADDRESS_MODE as ADDRMODE_RANDOM or
    // ADDRMODE_RP_WITH_RANDOM_ID, GAP_DeviceInit() should be called with
    // it's last parameter set to a static random address
    #define DEFAULT_ADDRESS_MODE                 ADDRMODE_PUBLIC
    
    // General discoverable mode: advertise indefinitely
    #define DEFAULT_DISCOVERABLE_MODE            GAP_ADTYPE_FLAGS_GENERAL
    
    // Minimum connection interval (units of 1.25ms, 80=100ms) for parameter update request
    #define DEFAULT_DESIRED_MIN_CONN_INTERVAL    80
    
    // Maximum connection interval (units of 1.25ms, 104=130ms) for  parameter update request
    #define DEFAULT_DESIRED_MAX_CONN_INTERVAL    104
    
    // Default PHY for scanning and initiating
    #define DEFAULT_SCAN_PHY                     SCAN_PRIM_PHY_1M
    #define DEFAULT_INIT_PHY                     INIT_PHY_1M
    
    // Default scan duration in 10 ms
    #define DEFAULT_SCAN_DURATION                200 // 2 sec
    
    // Default supervision timeout in 10ms
    #define DEFAULT_UPDATE_CONN_TIMEOUT          200
    
    // Task configuration
    #define RC_TASK_PRIORITY                     1
    
    #ifndef RC_TASK_STACK_SIZE
    #define RC_TASK_STACK_SIZE                   1024
    #endif
    
    // Advertising report fields to keep in the list
    // Interested in only peer address type and peer address
    #define RC_ADV_RPT_FIELDS   (SCAN_ADVRPT_FLD_ADDRTYPE | SCAN_ADVRPT_FLD_ADDRESS)
    
    // Connection event registration
    typedef enum
    {
      NOT_REGISTERED     = 0x0,
      FOR_RTLS            = 0x2,
    } connectionEventRegisterCause_u;
    
    // Spin if the expression is not true
    #define RTLSCOORDINATOR_ASSERT(expr) if (!(expr)) rtls_coordinator_spin();
    
    // Set the register cause to the registration bit-mask
    #define CONNECTION_EVENT_REGISTER_BIT_SET(RegisterCause) (connEventRegCauseBitmap |= RegisterCause)
    // Remove the register cause from the registration bit-mask
    #define CONNECTION_EVENT_REGISTER_BIT_REMOVE(RegisterCause) (connEventRegCauseBitmap &= (~RegisterCause))
    // Gets whether the current App is registered to the receive connection events
    #define CONNECTION_EVENT_IS_REGISTERED (connEventRegCauseBitmap > 0)
    // Gets whether the RegisterCause was registered to receive connection event
    #define CONNECTION_EVENT_REGISTRATION_CAUSE(RegisterCause) (connEventRegCauseBitmap & RegisterCause)
    
    // Hard coded PSM for passing data between central and peripheral
    #define RTLS_PSM      0x0080
    #define RTLS_PDU_SIZE MAX_PDU_SIZE
    
    #define SYNC_HANDLE_MASK 0x1000
    
    /*********************************************************************
     * TYPEDEFS
     */
    
    // App event passed from stack modules. This type is defined by the application
    // since it can queue events to itself however it wants.
    typedef struct
    {
      appEvtHdr_t hdr; // event header
      uint8_t *pData;  // event data
    } rcEvt_t;
    
    // Container to store paring state info when passing from gapbondmgr callback
    // to app event. See the pfnPairStateCB_t documentation from the gapbondmgr.h
    // header file for more information on each parameter.
    typedef struct
    {
      uint16_t connHandle;
      uint8_t  status;
    } rcPairStateData_t;
    
    // Container to store passcode data when passing from gapbondmgr callback
    // to app event. See the pfnPasscodeCB_t documentation from the gapbondmgr.h
    // header file for more information on each parameter.
    typedef struct
    {
      uint8_t deviceAddr[B_ADDR_LEN];
      uint16_t connHandle;
      uint8_t uiInputs;
      uint8_t uiOutputs;
      uint32_t numComparison;
    } rcPasscodeData_t;
    
    // Scanned device information record
    typedef struct
    {
      uint8_t addrType;         // Peer Device's Address Type
      uint8_t addr[B_ADDR_LEN]; // Peer Device Address
    } scanRec_t;
    
    typedef struct
    {
      uint16_t cocCID;
      uint8_t  isActive;
    } rcConnCB_t;
    
    // Container to store advertising event data when passing from advertising
    // callback to app event. See the respective event in GapAdvScan_Event_IDs
    // in gap_advertiser.h for the type that pBuf should be cast to.
    typedef struct
    {
      uint32_t event;
      void *pBuf;
    } rcGapAdvEventData_t;
    
    /*********************************************************************
     * GLOBAL VARIABLES
     */
    
    /*********************************************************************
     * EXTERNAL VARIABLES
     */
    #define APP_EVT_BLE_LOG_STRINGS_MAX  0xA
    char *appEvent_BleLogStrings[] = {
      "APP_EVT_ZERO              ",
      "APP_EVT_SCAN_ENABLED      ",
      "APP_EVT_SCAN_DISABLED     ",
      "APP_EVT_ADV_REPORT        ",
      "APP_EVT_ADV_EVT           ",
      "APP_EVT_PAIR_STATE        ",
      "APP_EVT_PASSCODE_NEEDED   ",
      "APP_EVT_INSUFFICIENT_MEM  ",
      "APP_EVT_RTLS_CTRL_MSG_EVT ",
      "APP_EVT_RTLS_SRV_MSG_EVT  ",
      "APP_EVT_CONN_EVT          ",
    };
    
    /*********************************************************************
     * LOCAL VARIABLES
     */
    
    // Entity ID globally used to check for source and/or destination of messages
    static ICall_EntityID selfEntity;
    
    // Event globally used to post local events and pend on system and
    // local events.
    static ICall_SyncHandle syncEvent;
    
    // Queue object used for app messages
    static Queue_Struct appMsg;
    static Queue_Handle appMsgQueue;
    
    // Task configuration
    Task_Struct rcTask;
    #if defined __TI_COMPILER_VERSION__
    #pragma DATA_ALIGN(rcTaskStack, 8)
    #else
    #pragma data_alignment=8
    #endif
    uint8_t rcTaskStack[RC_TASK_STACK_SIZE];
    
    // Array of connection handles and information for each handle
    static rcConnCB_t rcConnCB[MAX_NUM_BLE_CONNS];
    
    // Address mode
    static GAP_Addr_Modes_t addrMode = DEFAULT_ADDRESS_MODE;
    
    // Number of scan results and scan result index
    static uint8_t scanRes = 0;
    
    // Scan result list
    static scanRec_t scanList[DEFAULT_MAX_SCAN_RES];
    
    // Advertisement data
    static uint8_t advertData[] =
    {
      0x10,                         // Length of this data
      GAP_ADTYPE_LOCAL_NAME_SHORT,  // Type of this data
      'R',
      'T',
      'L',
      'S',
      'C',
      'o',
      'o',
      'r',
      'd',
      'i',
      'n',
      'a',
      't',
      'o',
      'r',
      0x02,   // length of this data
      GAP_ADTYPE_FLAGS,
      DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
    };
    
    // Scan Response Data
    static uint8_t scanRspData[] =
    {
      16,                             // length of this data
      GAP_ADTYPE_LOCAL_NAME_COMPLETE, // Type of this data
      'R',
      'T',
      'L',
      'S',
      'C',
      'o',
      'o',
      'r',
      'd',
      'i',
      'n',
      'a',
      't',
      'o',
      'r',
    
      // connection interval range
      5,   // length of this data
      GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
      LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),   // 100ms
      HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
      LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),   // 1s
      HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
    
      // Tx power level
      2,   // length of this data
      GAP_ADTYPE_POWER_LEVEL,
      0       // 0dBm
    };
    
    // Advertising handles
    static uint8 advHandleLegacy;
    
    // Handle the registration and un-registration for the connection event, since only one can be registered.
    uint32_t connEventRegCauseBitmap = NOT_REGISTERED;
    
    /*********************************************************************
     * LOCAL FUNCTIONS
     */
    static void RTLSCoordinator_init(void);
    static void RTLSCoordinator_taskFxn(uintptr_t a0, uintptr_t a1);
    
    static uint8_t RTLSCoordinator_processStackMsg(ICall_Hdr *pMsg);
    static void RTLSCoordinator_processAppMsg(rcEvt_t *pMsg);
    static void RTLSCoordinator_processGapMsg(gapEventHdr_t *pMsg);
    static void RTLSCoordinator_processPairState(uint8_t state, rcPairStateData_t* pPairStateData);
    static void RTLSCoordinator_processPasscode(rcPasscodeData_t *pData);
    static void RTLSCoordinator_processAdvEvent(rcGapAdvEventData_t *pEventData);
    static void RTLSCoordinator_advertInit(void);
    static void RTLSCoordinator_scanInit(void);
    static void RTLSCoordinator_addDeviceInfo(GapScan_Evt_AdvRpt_t *pEvent);
    static void RTLSCoordinator_advCb(uint32_t event, void *pBuf, uintptr_t arg);
    static void RTLSCoordinator_scanCb(uint32_t evt, void* msg, uintptr_t arg);
    static void RTLSCoordinator_passcodeCb(uint8_t *deviceAddr, uint16_t connHandle,
                                         uint8_t uiInputs, uint8_t uiOutputs,
                                         uint32_t numComparison);
    static void RTLSCoordinator_pairStateCb(uint16_t connHandle, uint8_t state, uint8_t status);
    static status_t RTLSCoordinator_enqueueMsg(uint8_t event, uint8_t status, uint8_t *pData);
    
    // RTLS specific functions
    static bStatus_t RTLSCoordinator_sendRTLSData(rtlsPacket_t *pMsg);
    static void RTLSCoordinator_processRTLSScanReq(void);
    static void RTLSCoordinator_processRTLSScanRes(GapScan_Evt_AdvRpt_t *deviceInfo);
    static void RTLSCoordinator_processRTLSConnReq(bleConnReq_t *bleConnReq);
    static void RTLSCoordinator_processRTLSConnInfo(uint16_t connHandle);
    static void RTLSCoordinator_setCreateSyncParams(rtlsCreateSyncParams_t *pParams);
    static void RTLSCoordinator_syncCancelCmd(void);
    static void RTLSCoordinator_terminateSync(rtlsTerminateSync_t *handle);
    static void RTLSCoordinator_periodicReceiveEnable(rtlsReceiveEnableParams_t *pParams);
    static void RTLSCoordinator_addDeviceToPeriodicAdvList(rtlsAdvListDeviceParams_t *pParams);
    static void RTLSCoordinator_removeDeviceFromPeriodicAdvList(rtlsAdvListDeviceParams_t *pParams);
    static void RTLSCoordinator_readPeriodicAdvListSize( void );
    static void RTLSCoordinator_clearPeriodicAdvList( void );
    static void RTLSCoordinator_enableRtlsSync(rtlsEnableSync_t *enable);
    static void RTLSCoordinator_connEvtCB(Gap_ConnEventRpt_t *pReport);
    static void RTLSCoordinator_processConnEvt(Gap_ConnEventRpt_t *pReport);
    static void RTLSCoordinator_processRtlsCtrlMsg(uint8_t *pMsg);
    static void RTLSCoordinator_terminateLinkReq(rtlsTerminateLinkReq_t *termInfo);
    static void RTLSCoordinator_rtlsSrvlMsgCb(rtlsSrv_evt_t *pRtlsSrvEvt);
    static void RTLSCoordinator_processRtlsSrvMsg(rtlsSrv_evt_t *pEvt);
    static void RTLSCoordinator_processRTLSUpdateConnInterval(rtlsUpdateConnIntReq_t *updateReq);
    #ifdef RTLS_CTE
    static void RTLSCoordinator_setAoaParamsReq(rtlsAoaConfigReq_t *config);
    static void RTLSCoordinator_enableAoaReq(rtlsAoaEnableReq_t *pReq);
    static void RTLSCoordinator_CLAoaSamplingEnableReq(rtlsCLAoaEnableReq_t *pReq);
    #endif /* RTLS_CTE*/
    
    // L2CAP COC Handling
    static bStatus_t RTLSCoordinator_openL2CAPChanCoc(uint16_t connHandle);
    static void RTLSCoordinator_processL2CAPSignalEvent(l2capSignalEvent_t *pMsg);
    static void RTLSCoordinator_processL2CAPDataEvent(l2capDataEvent_t *pMsg);
    
    /*********************************************************************
     * EXTERN FUNCTIONS
     */
    extern void AssertHandler(uint8 assertCause, uint8 assertSubcause);
    
    /*********************************************************************
     * PROFILE CALLBACKS
     */
    
    // Bond Manager Callbacks
    static gapBondCBs_t RTLSCoordinator_bondMgrCBs =
    {
     (pfnPasscodeCB_t)RTLSCoordinator_passcodeCb, // Passcode callback
      RTLSCoordinator_pairStateCb // Pairing/Bonding state Callback
    };
    
    /*********************************************************************
     * PUBLIC FUNCTIONS
     */
    
    /*********************************************************************
     * @fn      rtls_coordinator_spin
     *
     * @brief   Spin forever
     *
     * @param   none
     */
    static void rtls_coordinator_spin(void)
    {
      volatile uint8_t x = 0;
    
      while(1)
      {
        x++;
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_createTask
     *
     * @brief   Task creation function for the RTLS Coordinator.
     *
     * @param   none
     *
     * @return  none
     */
    void RTLSCoordinator_createTask(void)
    {
      Task_Params taskParams;
    
      // Configure task
      Task_Params_init(&taskParams);
      taskParams.stack = rcTaskStack;
      taskParams.stackSize = RC_TASK_STACK_SIZE;
      taskParams.priority = RC_TASK_PRIORITY;
    
      Task_construct(&rcTask, RTLSCoordinator_taskFxn, &taskParams, NULL);
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_Init
     *
     * @brief   Initialization function for the RTLS Coordinator App Task.
     *          This is called during initialization and should contain
     *          any application specific initialization (ie. hardware
     *          initialization/setup, table initialization, power up
     *          notification).
     *
     * @param   none
     *
     * @return  none
     */
    static void RTLSCoordinator_init(void)
    {
      BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- init ", RC_TASK_PRIORITY);
      // ******************************************************************
      // N0 STACK API CALLS CAN OCCUR BEFORE THIS CALL TO ICall_registerApp
      // ******************************************************************
      // Register the current thread as an ICall dispatcher application
      // so that the application can send and receive messages.
      ICall_registerApp(&selfEntity, &syncEvent);
    
      // Create an RTOS queue for message from profile to be sent to app.
      appMsgQueue = Util_constructQueue(&appMsg);
    
      // Set default values for Data Length Extension
      // Extended Data Length Feature is already enabled by default
      // in build_config.opt in stack project.
      {
        //Change initial values of RX/TX PDU and Time, RX is set to max. by default(251 octets, 2120us)
        #define APP_SUGGESTED_RX_PDU_SIZE 251     //default is 251 octets(RX)
        #define APP_SUGGESTED_RX_TIME     17000   //default is 17000us(RX)
        #define APP_SUGGESTED_TX_PDU_SIZE 27      //default is 27 octets(TX)
        #define APP_SUGGESTED_TX_TIME     328     //default is 328us(TX)
    
        //This API is documented in hci.h
        //See the LE Data Length Extension section in the BLE5-Stack User's Guide for information on using this command:
        //software-dl.ti.com/.../
        HCI_EXT_SetMaxDataLenCmd(APP_SUGGESTED_TX_PDU_SIZE, APP_SUGGESTED_TX_TIME, APP_SUGGESTED_RX_PDU_SIZE, APP_SUGGESTED_RX_TIME);
      }
    
      // Set Bond Manager parameters
      {
        // Don't wait, initiate a pairing request or slave security request
        uint8_t pairMode = GAPBOND_PAIRING_MODE_INITIATE;
        // Do not use authenticated pairing
        uint8_t mitm = FALSE;
        // This is a display only device
        uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
        // Create a bond during the pairing process
        uint8_t bonding = TRUE;
    
        GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode);
        GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t), &mitm);
        GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
        GAPBondMgr_SetParameter(GAPBOND_BONDING_ENABLED, sizeof(uint8_t), &bonding);
      }
    
      // Start Bond Manager and register callback
      // This must be done before initialing the GAP layer
      VOID GAPBondMgr_Register(&RTLSCoordinator_bondMgrCBs);
    
      // Accept all parameter update requests
      GAP_SetParamValue(GAP_PARAM_LINK_UPDATE_DECISION, GAP_UPDATE_REQ_ACCEPT_ALL);
    
      // Register with GAP for HCI/Host messages (for RSSI)
      GAP_RegisterForMsgs(selfEntity);
    
      BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- call GAP_DeviceInit", GAP_PROFILE_CENTRAL);
      // Initialize GAP layer for Central role and register to receive GAP events
      GAP_DeviceInit(GAP_PROFILE_CENTRAL | GAP_PROFILE_PERIPHERAL, selfEntity, addrMode, NULL);
    
      //Read the LE locally supported features
      HCI_LE_ReadLocalSupportedFeaturesCmd();
    
      // Initialize RTLS Services
      RTLSSrv_init(MAX_NUM_BLE_CONNS);
      RTLSSrv_register(RTLSCoordinator_rtlsSrvlMsgCb);
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_taskFxn
     *
     * @brief   Application task entry point for the RTLS Coordinator.
     *
     * @param   none
     *
     * @return  events not processed
     */
    static void RTLSCoordinator_taskFxn(uintptr_t a0, uintptr_t a1)
    {
      // Initialize application
      RTLSCoordinator_init();
    
      // Application main loop
      for (;;)
      {
        uint32_t events;
    
        // Waits for an event to be posted associated with the calling thread.
        // Note that an event associated with a thread is posted when a
        // message is queued to the message receive queue of the thread
        events = Event_pend(syncEvent, Event_Id_NONE, RC_ALL_EVENTS,
                            ICALL_TIMEOUT_FOREVER);
    
        if (events)
        {
          ICall_EntityID dest;
          ICall_ServiceEnum src;
          ICall_HciExtEvt *pMsg = NULL;
    
          // Fetch any available messages that might have been sent from the stack
          if (ICall_fetchServiceMsg(&src, &dest,
                                    (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
          {
            uint8 safeToDealloc = TRUE;
    
            if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
            {
              ICall_Stack_Event *pEvt = (ICall_Stack_Event *)pMsg;
    
              // Check for BLE stack events first
              if (pEvt->signature != 0xffff)
              {
                // Process inter-task message
                safeToDealloc = RTLSCoordinator_processStackMsg((ICall_Hdr *)pMsg);
              }
            }
    
            if (pMsg && safeToDealloc)
            {
              ICall_freeMsg(pMsg);
            }
          }
    
          // If RTOS queue is not empty, process app message
          if (events & RC_QUEUE_EVT)
          {
            while (!Queue_empty(appMsgQueue))
            {
              rcEvt_t *pMsg = (rcEvt_t *)Util_dequeueMsg(appMsgQueue);
              if(pMsg)
              {
                // Process message
                RTLSCoordinator_processAppMsg(pMsg);
    
                // Free the space from the message
                ICall_free(pMsg);
              }
            }
          }
        }
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_processStackMsg
     *
     * @brief   Process an incoming task message.
     *
     * @param   pMsg - message to process
     *
     * @return  TRUE if safe to deallocate incoming message, FALSE otherwise.
     */
    static uint8_t RTLSCoordinator_processStackMsg(ICall_Hdr *pMsg)
    {
      uint8_t safeToDealloc = TRUE;
    
      BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : Stack msg status=%d, event=0x%x\n", pMsg->status, pMsg->event);
    
      switch (pMsg->event)
      {
        case GAP_MSG_EVENT:
          RTLSCoordinator_processGapMsg((gapEventHdr_t*) pMsg);
          break;
    
        case L2CAP_SIGNAL_EVENT:
          RTLSCoordinator_processL2CAPSignalEvent((l2capSignalEvent_t *)pMsg);
          break;
    
        case L2CAP_DATA_EVENT:
          RTLSCoordinator_processL2CAPDataEvent((l2capDataEvent_t *)pMsg);
          break;
    
        case HCI_GAP_EVENT_EVENT:
        {
          // Process HCI message
          switch (pMsg->status)
          {
            case HCI_COMMAND_COMPLETE_EVENT_CODE:
            {
              // Parse Command Complete Event for opcode and status
              hciEvt_CmdComplete_t* command_complete = (hciEvt_CmdComplete_t*) pMsg;
    
              //find which command this command complete is for
              switch (command_complete->cmdOpcode)
              {
                case HCI_LE_READ_LOCAL_SUPPORTED_FEATURES:
                {
                  uint8_t featSet[8];
    
                  // Get current feature set from received event (byte 1-8)
                  memcpy( featSet, &command_complete->pReturnParam[1], 8 );
    
                  // Clear the CSA#2 feature bit
                  CLR_FEATURE_FLAG( featSet[1], LL_FEATURE_CHAN_ALGO_2 );
    
                  // Enable CTE
                  SET_FEATURE_FLAG( featSet[2], LL_FEATURE_CONNECTION_CTE_REQUEST );
                  SET_FEATURE_FLAG( featSet[2], LL_FEATURE_CONNECTION_CTE_RESPONSE );
                  SET_FEATURE_FLAG( featSet[2], LL_FEATURE_ANTENNA_SWITCHING_DURING_CTE_RX );
                  SET_FEATURE_FLAG( featSet[2], LL_FEATURE_RECEIVING_CTE );
    
                  // Update controller with modified features
                  HCI_EXT_SetLocalSupportedFeaturesCmd( featSet );
                }
                break;
    
                default:
                  break;
              }
            }
            break;
    
            case HCI_BLE_HARDWARE_ERROR_EVENT_CODE:
            {
              AssertHandler(HAL_ASSERT_CAUSE_HARDWARE_ERROR,0);
            }
            break;
    
            // LE Events
            case HCI_LE_EVENT_CODE:
            {
              hciEvt_BLEChanMapUpdate_t *pCMU = (hciEvt_BLEChanMapUpdate_t*) pMsg;
    
              // Update the host on channel map changes
              if (pCMU->BLEEventCode == HCI_BLE_CHANNEL_MAP_UPDATE_EVENT)
              {
                if (pCMU->connHandle != LINKDB_CONNHANDLE_INVALID)
                {
                  BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : Stack msg HCI_GAP_EVENT_EVENT HCI_LE_EVENT_CODE, HCI_BLE_CHANNEL_MAP_UPDATE_EVENT %d,0x%x\n", pMsg->status, pCMU->BLEEventCode);
                  // Upon param update, resend connection information
                  RTLSCoordinator_processRTLSConnInfo(pCMU->connHandle);
                }
              }
            }
            break;
    
            default:
              break;
          }
          break;
        }
        default:
          break;
      }
    
      return (safeToDealloc);
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_processAppMsg
     *
     * @brief   Scanner application event processing function.
     *
     * @param   pMsg - pointer to event structure
     *
     * @return  none
     */
    
    //AiRISTA 2023/01/24 - declare these variables here so we can debug
    GapScan_Evt_AdvRpt_t* pAdvRpt;
    uint32_t matches=0,mismatches=0;
    static void RTLSCoordinator_processAppMsg(rcEvt_t *pMsg)
    {
      bool safeToDealloc = TRUE;
    
      if (pMsg->hdr.event <= APP_EVT_BLE_LOG_STRINGS_MAX)
      {
        if (pMsg->hdr.event != RC_EVT_CONN_EVT)
        {
          BLE_LOG_INT_STR(0, BLE_LOG_MODULE_APP, "APP : App msg status=%d, event=%s\n", 0, appEvent_BleLogStrings[pMsg->hdr.event]);
        }
      }
      else
      {
        BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : App msg status=%d, event=0x%x\n", 0, pMsg->hdr.event);
      }
    
      switch (pMsg->hdr.event)
      {
        case RC_EVT_ADV_REPORT:
        {
         //GapScan_Evt_AdvRpt_t* pAdvRpt = (GapScan_Evt_AdvRpt_t*) (pMsg->pData);
            pAdvRpt = (GapScan_Evt_AdvRpt_t*) (pMsg->pData);
    
            //===================================================================
            //AiRISTA 2023/01/24 - comment out original code
    //      char responderScanRsp[] = {'R','T','L','S','R','e','s','p','o','n','d','e','r'};
    //
    //      // Filter results by the responder's scanRsp array
    //      if (memcmp(&pAdvRpt->pData[2], responderScanRsp, sizeof(responderScanRsp)) == 0)
    //      {
    //        RTLSCoordinator_addDeviceInfo(pAdvRpt);
    //      }
          //add code to check for mismatches
    
            if (pAdvRpt->pData[2] == 'S' && pAdvRpt->pData[3] == 'P')
            {
                if (
                        pAdvRpt->addr[0] == pAdvRpt->pData[15] &&
                        pAdvRpt->addr[1] == pAdvRpt->pData[16] &&
                        pAdvRpt->addr[2] == pAdvRpt->pData[17] &&
                        pAdvRpt->addr[3] == pAdvRpt->pData[18] &&
                        pAdvRpt->addr[4] == pAdvRpt->pData[19] &&
                        pAdvRpt->addr[5] == pAdvRpt->pData[20]
                )
                {
                    ++matches;
                }
                else
                {
                    ++mismatches;
                }
            }
    
            if (mismatches > 5)
            {
                uint8_t x = 0;
    
                while(1)
                {
                    x++;
                }
            }
            //===================================================================
    
          // Free report payload data
          if (pAdvRpt->pData != NULL)
          {
            ICall_free(pAdvRpt->pData);
          }
        }
        break;
    
        case RC_EVT_SCAN_DISABLED:
        {
          if(((gapEstLinkReqEvent_t*) pMsg)->hdr.status == SUCCESS)
          {
            // Scan stopped (no more results)
            RTLSCtrl_scanResultEvt(RTLS_SUCCESS, 0, 0);
          }
          else
          {
            // Scan stopped (failed due to wrong parameters)
            RTLSCtrl_scanResultEvt(RTLS_FAIL, 0, 0);
          }
        }
        break;
    
        // Pairing event
        case RC_EVT_PAIR_STATE:
        {
          RTLSCoordinator_processPairState(pMsg->hdr.state, (rcPairStateData_t*)(pMsg->pData));
        }
        break;
    
        // Passcode event
        case RC_EVT_PASSCODE_NEEDED:
        {
          RTLSCoordinator_processPasscode((rcPasscodeData_t *)(pMsg->pData));
        }
        break;
    
        case RC_EVT_ADV_EVT:
        {
          RTLSCoordinator_processAdvEvent((rcGapAdvEventData_t*)(pMsg->pData));
        }
        break;
    
        case RC_EVT_RTLS_CTRL_MSG_EVT:
        {
          RTLSCoordinator_processRtlsCtrlMsg((uint8_t *)pMsg->pData);
        }
        break;
    
        case RC_EVT_RTLS_SRV_MSG_EVT:
        {
          RTLSCoordinator_processRtlsSrvMsg((rtlsSrv_evt_t *)pMsg->pData);
        }
        break;
    
        case RC_EVT_CONN_EVT:
        {
          RTLSCoordinator_processConnEvt((Gap_ConnEventRpt_t *)pMsg->pData);
        }
        break;
    
        default:
          // Do nothing.
        break;
      }
    
      if ((safeToDealloc == TRUE) && (pMsg->pData != NULL))
      {
        ICall_free(pMsg->pData);
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_processGapMsg
     *
     * @brief   GAP message processing function.
     *
     * @param   pMsg - pointer to event message structure
     *
     * @return  none
     */
    static void RTLSCoordinator_processGapMsg(gapEventHdr_t *pMsg)
    {
      uint16_t connHandle;
    
      switch (pMsg->opcode)
      {
        case GAP_DEVICE_INIT_DONE_EVENT:
        {
          gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *)pMsg;
    
          if(pPkt->hdr.status == SUCCESS)
          {
            BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- got GAP_DEVICE_INIT_DONE_EVENT", 0);
            //Setup and start advertising
            RTLSCoordinator_advertInit();
          }
    
          //Setup scanning
          RTLSCoordinator_scanInit();
        }
        break;
    
        case GAP_LINK_ESTABLISHED_EVENT:
        {
          BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- got GAP_LINK_ESTABLISHED_EVENT", 0);
          // The amount of current connections
          uint8_t numActive = linkDB_NumActive();
    
          connHandle = ((gapEstLinkReqEvent_t *) pMsg)->connectionHandle;
    
          if (connHandle != LINKDB_CONNHANDLE_INVALID && connHandle < MAX_NUM_BLE_CONNS &&
              ((gapEstLinkReqEvent_t *) pMsg)->hdr.status == SUCCESS)
          {
            rcConnCB[connHandle].isActive = TRUE;
    
            HCI_LE_ReadRemoteUsedFeaturesCmd(connHandle);
    
            // We send out the connection information at this point
            // Note: we are not yet connected (will be after pairing)
            RTLSCoordinator_processRTLSConnInfo(connHandle);
    
          }
          else
          {
            // Link failed to establish
            RTLSCtrl_connResultEvt(LINKDB_CONNHANDLE_INVALID, RTLS_LINK_ESTAB_FAIL);
          }
    
          if ((numActive < MAX_NUM_BLE_CONNS))
          {
            // Start advertising since there is room for more connections
            GapAdv_enable(advHandleLegacy, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0);
          }
          else
          {
            // Stop advertising since there is no room for more connections
            GapAdv_disable(advHandleLegacy);
          }
        }
        break;
    
        case GAP_LINK_TERMINATED_EVENT:
        {
          BLE_LOG_INT_STR(0, BLE_LOG_MODULE_APP, "APP : GAP msg status=%d, opcode=%s\n", 0, "GAP_LINK_TERMINATED_EVENT");
          connHandle = ((gapTerminateLinkEvent_t *) pMsg)->connectionHandle;
    
          if (connHandle != LINKDB_CONNHANDLE_INVALID && connHandle < MAX_NUM_BLE_CONNS)
          {
            // This connection is inactive
            rcConnCB[connHandle].isActive = FALSE;
    
            // Link terminated
            RTLSCtrl_connResultEvt(connHandle, RTLS_LINK_TERMINATED);
          }
    
          // Start advertising since there is room for more connections
          GapAdv_enable(advHandleLegacy, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0);
        }
        break;
    
        case GAP_LINK_PARAM_UPDATE_EVENT:
        {
          BLE_LOG_INT_STR(0, BLE_LOG_MODULE_APP, "APP : GAP msg status=%d, opcode=%s\n", 0, "GAP_LINK_PARAM_UPDATE_EVENT");
          connHandle = ((gapLinkUpdateEvent_t *) pMsg)->connectionHandle;
    
          if (connHandle != LINKDB_CONNHANDLE_INVALID && connHandle < MAX_NUM_BLE_CONNS &&
              ((gapLinkUpdateEvent_t *) pMsg)->hdr.status == SUCCESS)
          {
            // Upon param update, resend connection information
            RTLSCoordinator_processRTLSConnInfo(connHandle);
          }
        }
        break;
    
        default:
          break;
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_processPairState
     *
     * @brief   Process the new paring state.
     *
     * @return  none
     */
    static void RTLSCoordinator_processPairState(uint8_t state, rcPairStateData_t* pPairData)
    {
      uint8_t status = pPairData->status;
    
    #ifdef RTLS_DEBUG
      RTLSCtrl_sendDebugEvt("RTLSCoordinator_processPairState", state);
    #endif
    
      switch (state)
      {
        // Once Coordinator and Responder are paired, we can open a COC channel
        case GAPBOND_PAIRING_STATE_COMPLETE:
        case GAPBOND_PAIRING_STATE_ENCRYPTED:
        {
          if (status == SUCCESS)
          {
            // We are paired, open a L2CAP channel to pass data
            if (RTLSCoordinator_openL2CAPChanCoc(pPairData->connHandle) != SUCCESS)
            {
              // We could not establish an L2CAP link, drop the connection
              // We will notify host that this connection is terminated when the GAP_LINK_TERMINATED_EVENT returns
              GAP_TerminateLinkReq(pPairData->connHandle, HCI_DISCONNECT_REMOTE_USER_TERM);
            }
          }
          else
          {
            // We could not establish an L2CAP link, drop the connection
            // We will notify host that this connection is terminated when the GAP_LINK_TERMINATED_EVENT returns
            GAP_TerminateLinkReq(pPairData->connHandle, HCI_DISCONNECT_REMOTE_USER_TERM);
          }
        }
        break;
    
        default:
          break;
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_processPasscode
     *
     * @brief   Process the Passcode request.
     *
     * @return  none
     */
    static void RTLSCoordinator_processPasscode(rcPasscodeData_t *pData)
    {
      // This app uses a default passcode. A real-life scenario would handle all
      // pairing scenarios and likely generate this randomly.
      uint32_t passcode = B_APP_DEFAULT_PASSCODE;
    
      // Send passcode response
      GAPBondMgr_PasscodeRsp(pData->connHandle, SUCCESS, passcode);
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_processAdvEvent
     *
     * @brief   Process advertising event in app context
     *
     * @param   pEventData
     */
    static void RTLSCoordinator_processAdvEvent(rcGapAdvEventData_t *pEventData)
    {
      switch (pEventData->event)
      {
        default:
          break;
      }
    
      // All events have associated memory to free except the insufficient memory
      // event
      if (pEventData->event != GAP_EVT_INSUFFICIENT_MEMORY)
      {
        ICall_free(pEventData->pBuf);
      }
    }
    
    /*********************************************************************
    * @fn      RTLSCoordinator_advertInit
    *
    * @brief   Setup initial advertisement and start advertising from device init.
    *
    * @return  None.
    */
    static void RTLSCoordinator_advertInit(void)
    {
      bStatus_t status = FAILURE;
    
      // Setup and start Advertising
      // For more information, see the GAP section in the User's Guide:
      // software-dl.ti.com/.../
    
      // Temporary memory for advertising parameters for set #1. These will be copied
      // by the GapAdv module
      GapAdv_params_t advParamLegacy = GAPADV_PARAMS_LEGACY_SCANN_CONN;
    
      BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : ---- call GapAdv_create set=%d,%d\n", 0, 0);
      // Create Advertisement set #1 and assign handle
      status = GapAdv_create(&RTLSCoordinator_advCb, &advParamLegacy, &advHandleLegacy);
      RTLSCOORDINATOR_ASSERT(status == SUCCESS);
    
      // Load advertising data for set #1 that is statically allocated by the app
      status = GapAdv_loadByHandle(advHandleLegacy, GAP_ADV_DATA_TYPE_ADV,
                                   sizeof(advertData), advertData);
      RTLSCOORDINATOR_ASSERT(status == SUCCESS);
    
      // Load scan response data for set #1 that is statically allocated by the app
      status = GapAdv_loadByHandle(advHandleLegacy, GAP_ADV_DATA_TYPE_SCAN_RSP,
                                   sizeof(scanRspData), scanRspData);
      RTLSCOORDINATOR_ASSERT(status == SUCCESS);
    
      // Set event mask for set #1
      status = GapAdv_setEventMask(advHandleLegacy,
                                   GAP_ADV_EVT_MASK_START_AFTER_ENABLE |
                                   GAP_ADV_EVT_MASK_END_AFTER_DISABLE |
                                   GAP_ADV_EVT_MASK_SET_TERMINATED);
    
      BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- GapAdv_enable", 0);
      // Enable legacy advertising for set #1
      status = GapAdv_enable(advHandleLegacy, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0);
      RTLSCOORDINATOR_ASSERT(status == SUCCESS);
    }
    
    /*********************************************************************
    * @fn      RTLSCoordinator_scanInit
    *
    * @brief   Setup initial device scan settings.
    *
    * @return  None.
    */
    static void RTLSCoordinator_scanInit(void)
    {
      uint8_t temp8;
      uint16_t temp16;
    
      // Setup scanning
      // For more information, see the GAP section in the User's Guide:
      // software-dl.ti.com/.../
    
      // Register callback to process Scanner events
      GapScan_registerCb(RTLSCoordinator_scanCb, NULL);
    
      // Set Scanner Event Mask
      GapScan_setEventMask(GAP_EVT_SCAN_ENABLED | GAP_EVT_SCAN_DISABLED |
                           GAP_EVT_ADV_REPORT);
    
      // Set Scan PHY parameters
      GapScan_setPhyParams(DEFAULT_SCAN_PHY, SCAN_TYPE_PASSIVE,
                           200, 100);
    
      // Set Advertising report fields to keep
      temp16 = RC_ADV_RPT_FIELDS;
      GapScan_setParam(SCAN_PARAM_RPT_FIELDS, &temp16);
      // Set Scanning Primary PHY
      temp8 = DEFAULT_SCAN_PHY;
      GapScan_setParam(SCAN_PARAM_PRIM_PHYS, &temp8);
      // Set LL Duplicate Filter
      //AiRISTA 2023/01/24
      //Allow Dups
      //temp8 = SCAN_FLT_DUP_ENABLE;
      temp8 = SCAN_FLT_DUP_DISABLE;
      GapScan_setParam(SCAN_PARAM_FLT_DUP, &temp8);
    
      // Set PDU type filter -
      // Only 'Complete' packets are desired.
      // It doesn't matter if received packets are
      // whether Scannable or Non-Scannable, whether Directed or Undirected,
      // whether Connectable or Non-Connectable, whether Scan_Rsp's or Advertisements,
      // and whether Legacy or Extended.
    
      //AiRISTA 2023/01/24
      //Only Extended and Complete Advertisements
      //temp16 = SCAN_FLT_PDU_COMPLETE_ONLY;
      temp16 = SCAN_FLT_PDU_EXTENDED_ONLY | SCAN_FLT_PDU_COMPLETE_ONLY;
      BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- GapScan_setParam", 0);
      GapScan_setParam(SCAN_PARAM_FLT_PDU_TYPE, &temp16);
    
    
      //AiRISTA 2023/01/24
      //added to Start discovery so we dont rely on host app to drive the actions. All we want to demo is to start one scan and see if we get MAC discrepancies
      //units are in 10 ms
      //scan for 60 secs, 200 results max
      GapScan_enable(0, 6000, 200);
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_addDeviceInfo
     *
     * @brief   Add a device to the device discovery result list
     *
     * @return  none
     */
    static void RTLSCoordinator_addDeviceInfo(GapScan_Evt_AdvRpt_t *deviceInfo)
    {
      uint8_t i;
    
      // If result count not at max
      if (scanRes < DEFAULT_MAX_SCAN_RES)
      {
        // Check if device is already in scan results
        for (i = 0; i < scanRes; i++)
        {
          if (memcmp(deviceInfo->addr, scanList[i].addr , B_ADDR_LEN) == 0)
          {
            return;
          }
        }
    
        // Send the device info to RTLS Control
        RTLSCoordinator_processRTLSScanRes(deviceInfo);
    
        // Add addr to scan result list
        memcpy(scanList[scanRes].addr, deviceInfo->addr, B_ADDR_LEN);
        scanList[scanRes].addrType = deviceInfo->addrType;
    
        // Increment scan result count
        scanRes++;
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_advCb
     *
     * @brief   GapAdv module callback
     *
     * @param   pMsg - message to process
     */
    static void RTLSCoordinator_advCb(uint32_t event, void *pBuf, uintptr_t arg)
    {
      rcGapAdvEventData_t *pData = ICall_malloc(sizeof(rcGapAdvEventData_t));
    
      if (pData)
      {
        pData->event = event;
        pData->pBuf = pBuf;
    
        if(RTLSCoordinator_enqueueMsg(RC_EVT_ADV_EVT, SUCCESS, (uint8_t*)pData) != SUCCESS)
        {
          ICall_free(pData);
        }
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_scanCb
     *
     * @brief   Callback called by GapScan module
     *
     * @param   evt - event
     * @param   msg - message coming with the event
     * @param   arg - user argument
     *
     * @return  none
     */
    static void RTLSCoordinator_scanCb(uint32_t evt, void* pMsg, uintptr_t arg)
    {
      uint8_t event;
    
      if (evt & GAP_EVT_ADV_REPORT)
      {
        event = RC_EVT_ADV_REPORT;
      }
      else if (evt & GAP_EVT_SCAN_ENABLED)
      {
        event = RC_EVT_SCAN_ENABLED;
      }
      else if (evt & GAP_EVT_SCAN_DISABLED)
      {
        event = RC_EVT_SCAN_DISABLED;
      }
      else
      {
        return;
      }
    
      if (RTLSCoordinator_enqueueMsg(event, SUCCESS, pMsg) != SUCCESS)
      {
        ICall_free(pMsg);
      }
    }
    
    /*********************************************************************
    * @fn      RTLSCoordinator_passcodeCb
    *
    * @brief   Passcode callback.
    *
    * @param   deviceAddr - pointer to device address
    * @param   connHandle - the connection handle
    * @param   uiInputs - pairing User Interface Inputs
    * @param   uiOutputs - pairing User Interface Outputs
    * @param   numComparison - numeric Comparison 20 bits
    *
    * @return  none
    */
    static void RTLSCoordinator_passcodeCb(uint8_t *deviceAddr, uint16_t connHandle,
                                      uint8_t uiInputs, uint8_t uiOutputs,
                                      uint32_t numComparison)
    {
      rcPasscodeData_t *pData = ICall_malloc(sizeof(rcPasscodeData_t));
    
      // Allocate space for the passcode event.
      if (pData)
      {
        pData->connHandle = connHandle;
        memcpy(pData->deviceAddr, deviceAddr, B_ADDR_LEN);
        pData->uiInputs = uiInputs;
        pData->uiOutputs = uiOutputs;
        pData->numComparison = numComparison;
    
        // Enqueue the event.
        if (RTLSCoordinator_enqueueMsg(RC_EVT_PASSCODE_NEEDED, 0,(uint8_t *) pData) != SUCCESS)
        {
          ICall_free(pData);
        }
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_pairStateCb
     *
     * @brief   Pairing state callback.
     *
     * @param connectionHandle - connection handle of current pairing process
     * @param state - @ref GAPBondMgr_Events
     * @param status - pairing status
     *
     * @return  none
     */
    static void RTLSCoordinator_pairStateCb(uint16_t connHandle, uint8_t state, uint8_t status)
    {
      rcPairStateData_t *pData;
    
      // Allocate space for the event data.
      if ((pData = ICall_malloc(sizeof(rcPairStateData_t))))
      {
        pData->connHandle = connHandle;
        pData->status = status;
    
        // Queue the event.
        if (RTLSCoordinator_enqueueMsg(RC_EVT_PAIR_STATE, state, (uint8_t*) pData) != SUCCESS)
        {
          ICall_free(pData);
        }
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_enqueueMsg
     *
     * @brief   Creates a message and puts the message in RTOS queue.
     *
     * @param   event - message event.
     * @param   state - message state.
     * @param   pData - message data pointer.
     *
     * @return  TRUE or FALSE
     */
    static status_t RTLSCoordinator_enqueueMsg(uint8_t event, uint8_t state,
                                               uint8_t *pData)
    {
      uint8_t success;
      rcEvt_t *pMsg = ICall_malloc(sizeof(rcEvt_t));
    
      // Create dynamic pointer to message.
      if (pMsg)
      {
        pMsg->hdr.event = event;
        pMsg->hdr.state = state;
        pMsg->pData = pData;
    
        // Enqueue the message.
        success = Util_enqueueMsg(appMsgQueue, syncEvent, (uint8_t *)pMsg);
        return (success) ? SUCCESS : FAILURE;
      }
    
      return(bleMemAllocError);
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_connEvtCB
     *
     * @brief   Connection event callback.
     *
     * @param   pReport pointer to connection event report
     */
    static void RTLSCoordinator_connEvtCB(Gap_ConnEventRpt_t *pReport)
    {
      // Enqueue the event for processing in the app context.
      if (RTLSCoordinator_enqueueMsg(RC_EVT_CONN_EVT, SUCCESS, (uint8_t *)pReport) != SUCCESS)
      {
        ICall_free(pReport);
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_processConnEvt
     *
     * @brief   Connection event callback.
     *
     * @param   pReport - pointer to connection event report
     *
     * @return  none
     */
    static void RTLSCoordinator_processConnEvt(Gap_ConnEventRpt_t *pReport)
    {
      // Sanity check
      if (!pReport)
      {
      return;
      }
    
      if (CONNECTION_EVENT_REGISTRATION_CAUSE(FOR_RTLS) && rcConnCB[pReport->handle].isActive)
      {
        rtlsStatus_e status;
    
        // Convert BLE specific status to RTLS Status
        if (pReport->status != GAP_CONN_EVT_STAT_MISSED)
        {
          status = RTLS_SUCCESS;
        }
        else
        {
          status = RTLS_FAIL;
        }
    
    #ifdef RTLS_TEST_CHAN_MAP_DYNAMIC_CHANGE
        // For testing - do dynamic change of the channel map after 10 connection events
        {
            static int connectionEventCount = 0;
    
            if (++connectionEventCount == 10)
            {
              uint8_t chanMap[5] = {0xFF, 0xFF, 0xFF, 0x00, 0x1F};      // unmap channels 24..31
              HCI_LE_SetHostChanClassificationCmd(chanMap);
            }
        }
    #endif //RTLS_TEST_CHAN_MAP_DYNAMIC_CHANGE
    
        RTLSCtrl_syncNotifyEvt(pReport->handle, status, pReport->nextTaskTime, pReport->lastRssi, pReport->channel);
      }
    
      if (pReport != NULL)
      {
        // Free the report once we are done using it
        ICall_free(pReport);
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_sendRTLSData
     *
     * @brief   Send RTLS data to the peer
     *
     * @param   pMsg - pointer to the message to send
     *
     * @return  none
     */
    static bStatus_t RTLSCoordinator_sendRTLSData(rtlsPacket_t *pMsg)
    {
      l2capPacket_t pkt;
      bStatus_t status = SUCCESS;
    
      // Sanity check
      if (!pMsg)
      {
        return FAILURE;
      }
    
      // Tell L2CAP the desired Channel ID
      pkt.CID = rcConnCB[pMsg->connHandle].cocCID;
    
      // Allocate space for payload
      pkt.pPayload = L2CAP_bm_alloc(pMsg->payloadLen);
    
      if (pkt.pPayload != NULL)
      {
        // The request is the payload for the L2CAP SDU
        memcpy(pkt.pPayload, pMsg, pMsg->payloadLen);
        pkt.len = pMsg->payloadLen;
        status = L2CAP_SendSDU(&pkt);
    
        // Check that the packet was sent
        if (SUCCESS != status)
        {
          // If SDU wasn't sent, free
          BM_free(pkt.pPayload);
        }
      }
      else
      {
        status = bleMemAllocError;
      }
    
      return (status);
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_processRTLSScanRes
     *
     * @brief   Process a scan response and forward to RTLS Control
     *
     * @param   deviceInfo - a single scan response
     *
     * @return  none
     */
    static void RTLSCoordinator_processRTLSScanRes(GapScan_Evt_AdvRpt_t *deviceInfo)
    {
      GapScan_Evt_AdvRpt_t *devInfo;
      size_t resSize;
      bleScanInfo_t *scanResult;
    
      // Sanity check
      if (!deviceInfo)
      {
        return;
      }
    
      devInfo = deviceInfo;
    
      // Assign and allocate space
      resSize = sizeof(bleScanInfo_t) + devInfo->dataLen;
      scanResult = (bleScanInfo_t *)ICall_malloc(resSize);
    
      // We could not allocate memory, report to host and exit
      if (!scanResult)
      {
        RTLSCtrl_scanResultEvt(RTLS_OUT_OF_MEMORY, NULL, 0);
        return;
      }
    
      memcpy(scanResult->addr, devInfo->addr, B_ADDR_LEN);
      scanResult->addrType = devInfo->addrType;
      scanResult->eventType = devInfo->evtType;
      scanResult->dataLen = devInfo->dataLen;
      scanResult->rssi = devInfo->rssi;
      scanResult->advSID = devInfo->advSid;
      scanResult->periodicAdvInt = devInfo->periodicAdvInt;
      memcpy(scanResult->pEvtData, devInfo->pData, devInfo->dataLen);
    
      RTLSCtrl_scanResultEvt(RTLS_SUCCESS, (uint8_t*)scanResult, resSize);
    
      ICall_free(scanResult);
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_processRTLSScanReq
     *
     * @brief   Process a scan request
     *
     * @param   none
     *
     * @return  none
     */
    static void RTLSCoordinator_processRTLSScanReq(void)
    {
      scanRes = 0;
    
      // Start discovery
      GapScan_enable(0, DEFAULT_SCAN_DURATION, DEFAULT_MAX_SCAN_RES);
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_processRTLSConnReq
     *
     * @brief   Start the connection process with another device
     *
     * @param   bleConnReq - pointer from RTLS control containing connection params
     *
     * @return  none
     */
    static void RTLSCoordinator_processRTLSConnReq(bleConnReq_t *bleConnReq)
    {
      bStatus_t status;
    
      // Sanity check
      if (!bleConnReq)
      {
       return;
      }
    
      //Set connection interval and supervision timeout
      GapInit_setPhyParam(INIT_PHY_1M | INIT_PHY_2M | INIT_PHY_CODED, INIT_PHYPARAM_CONN_INT_MAX, bleConnReq->connInterval);
      GapInit_setPhyParam(INIT_PHY_1M | INIT_PHY_2M | INIT_PHY_CODED, INIT_PHYPARAM_CONN_INT_MIN, bleConnReq->connInterval);
      GapInit_setPhyParam(INIT_PHY_1M | INIT_PHY_2M | INIT_PHY_CODED, INIT_PHYPARAM_SUP_TIMEOUT, DEFAULT_UPDATE_CONN_TIMEOUT);
    
      status = GapInit_connect(bleConnReq->addrType & MASK_ADDRTYPE_ID, bleConnReq->addr, DEFAULT_INIT_PHY, 0);
      if (status != SUCCESS)
      {
        // Notify RTLS Control that we are not connected
        RTLSCtrl_connResultEvt(0, RTLS_FAIL);
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_processRTLSConnRes
     *
     * @brief   Process a connection established event - send conn info to RTLS Control
     *
     * @param   connHandle - connection handle
     *
     * @return  none
     */
    static void RTLSCoordinator_processRTLSConnInfo(uint16_t connHandle)
    {
      hciActiveConnInfo_t connInfo;
      linkDBInfo_t addrInfo;
      bleConnInfo_t rtlsConnInfo = {0};
    
      // Get BD Address of the requested Responder
      linkDB_GetInfo(connHandle, &addrInfo);
      memcpy(rtlsConnInfo.addr, addrInfo.addr, B_ADDR_LEN);
    
      // Get current active connection information
      HCI_EXT_GetActiveConnInfoCmd(connHandle, &connInfo);
    
      BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : RTLSConnInfo hopValue=%d, currChan=%d\n", connInfo.hopValue, connInfo.nextChan);
      rtlsConnInfo.connHandle = connHandle;
      rtlsConnInfo.accessAddr = connInfo.accessAddr;
      rtlsConnInfo.connRole = addrInfo.connRole;
      rtlsConnInfo.connInterval = connInfo.connInterval;
      rtlsConnInfo.currChan = connInfo.nextChan;
      rtlsConnInfo.hopValue = connInfo.hopValue;
      rtlsConnInfo.cSCA = connInfo.mSCA;
      rtlsConnInfo.crcInit = BUILD_UINT32(connInfo.crcInit[0], connInfo.crcInit[1], connInfo.crcInit[2], 0);
      memcpy(rtlsConnInfo.chanMap, connInfo.chanMap, LL_NUM_BYTES_FOR_CHAN_MAP);
    
      RTLSCtrl_connInfoEvt((uint8_t*)&rtlsConnInfo, sizeof(bleConnInfo_t));
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_openL2CAPChanCoc
     *
     * @brief   Opens a communication channel between RTLS Coordinator/Responder
     *
     * @param   connHandle - connection handle
     *
     * @return  status - 0 = success, 1 = failed
     */
    static bStatus_t RTLSCoordinator_openL2CAPChanCoc(uint16_t connHandle)
    {
      uint8_t ret;
      l2capPsm_t psm;
      l2capPsmInfo_t psmInfo;
    
      if (L2CAP_PsmInfo(RTLS_PSM, &psmInfo) == INVALIDPARAMETER)
      {
        // Prepare the PSM parameters
        psm.initPeerCredits = 0xFFFF;
        psm.maxNumChannels = MAX_NUM_BLE_CONNS;
        psm.mtu = RTLS_PDU_SIZE;
        psm.peerCreditThreshold = 0;
        psm.pfnVerifySecCB = NULL;
        psm.psm = RTLS_PSM;
        psm.taskId = ICall_getLocalMsgEntityId(ICALL_SERVICE_CLASS_BLE_MSG, selfEntity);
    
        // Register PSM with L2CAP task
        ret = L2CAP_RegisterPsm(&psm);
    
        if (ret == SUCCESS)
        {
          // Send the connection request to RTLS responder
          ret = L2CAP_ConnectReq(connHandle, RTLS_PSM, RTLS_PSM);
        }
      }
      else
      {
        // Send the connection request to RTLS responder
        ret = L2CAP_ConnectReq(connHandle, RTLS_PSM, RTLS_PSM);
      }
    
      return ret;
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_processL2CAPSignalEvent
     *
     * @brief   Handle L2CAP signal events
     *
     * @param   pMsg - pointer to the signal that was received
     *
     * @return  none
     */
    static void RTLSCoordinator_processL2CAPSignalEvent(l2capSignalEvent_t *pMsg)
    {
      // Sanity check
      if (!pMsg)
      {
        return;
      }
    
      switch (pMsg->opcode)
      {
        case L2CAP_CHANNEL_ESTABLISHED_EVT:
        {
          l2capChannelEstEvt_t *pEstEvt = &(pMsg->cmd.channelEstEvt);
    
          // Connection established, save the CID
          if (pMsg->connHandle != LINKDB_CONNHANDLE_INVALID && pMsg->connHandle < MAX_NUM_BLE_CONNS)
          {
            rcConnCB[pMsg->connHandle].cocCID = pEstEvt->CID;
    
            // Give max credits to the other side
            L2CAP_FlowCtrlCredit(pEstEvt->CID, 0xFFFF);
    
            // L2CAP establishing a COC channel means that both Coordinator and Responder are ready
            // Tell RTLS Control that we are ready for more commands
            RTLSCtrl_connResultEvt(pMsg->connHandle, RTLS_SUCCESS);
          }
          else
          {
            // We could not establish an L2CAP link, drop the connection
            RTLSCtrl_sendDebugEvt((uint8_t *)"L2CAP COC: could not establish", pMsg->connHandle);
            GAP_TerminateLinkReq(pMsg->connHandle, HCI_DISCONNECT_REMOTE_USER_TERM);
          }
        }
        break;
    
        case L2CAP_SEND_SDU_DONE_EVT:
        {
          if (pMsg->hdr.status == SUCCESS)
          {
            RTLSCtrl_dataSentEvt(pMsg->connHandle, RTLS_SUCCESS);
          }
          else
          {
            RTLSCtrl_dataSentEvt(pMsg->connHandle, RTLS_FAIL);
          }
        }
        break;
    
        case L2CAP_CHANNEL_TERMINATED_EVT:
        {
          // Terminate the connection
          GAP_TerminateLinkReq(pMsg->connHandle, HCI_DISCONNECT_REMOTE_USER_TERM);
          RTLSCtrl_sendDebugEvt((uint8_t *)"L2CAP COC: terminated connHandle: ", pMsg->connHandle);
        }
        break;
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_processL2CAPDataEvent
     *
     * @brief   Handles incoming L2CAP data
     *          RTLS Coordinator does not expect any incoming data
     *
     * @param   pMsg - pointer to the signal that was received
     *
     * @return  none
     */
    static void RTLSCoordinator_processL2CAPDataEvent(l2capDataEvent_t *pMsg)
    {
      // Sanity check
      if (!pMsg)
      {
        return;
      }
    
      // Free the payload (must use BM_free here according to L2CAP documentation)
      BM_free(pMsg->pkt.pPayload);
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_enableRtlsSync
     *
     * @brief   This function is used by RTLS Control to notify the RTLS application
     *          to start sending synchronization events (for BLE this is a connection event)
     *
     * @param   enable - start/stop synchronization
     *
     * @return  none
     */
    static void RTLSCoordinator_enableRtlsSync(rtlsEnableSync_t *enable)
    {
      bStatus_t status = RTLS_FALSE;
    
      if (enable->enable == RTLS_TRUE)
      {
        if (!CONNECTION_EVENT_IS_REGISTERED)
        {
          status = Gap_RegisterConnEventCb(RTLSCoordinator_connEvtCB, GAP_CB_REGISTER, GAP_CB_CONN_EVENT_ALL, LINKDB_CONNHANDLE_ALL);
        }
    
        if (status == SUCCESS)
        {
          CONNECTION_EVENT_REGISTER_BIT_SET(FOR_RTLS);
        }
      }
      else if (enable->enable == RTLS_FALSE)
      {
        CONNECTION_EVENT_REGISTER_BIT_REMOVE(FOR_RTLS);
    
        // If there is nothing registered to the connection event, request to unregister
        if (!CONNECTION_EVENT_IS_REGISTERED)
        {
          Gap_RegisterConnEventCb(RTLSCoordinator_connEvtCB, GAP_CB_UNREGISTER, GAP_CB_CONN_EVENT_ALL, LINKDB_CONNHANDLE_ALL);
        }
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_terminateLinkReq
     *
     * @brief   Terminate active link
     *
     * @param   termInfo - information about the connection to terminate
     *
     * @return  none
     */
    static void RTLSCoordinator_terminateLinkReq(rtlsTerminateLinkReq_t *termInfo)
    {
      if (termInfo->connHandle != LINKDB_CONNHANDLE_INVALID && termInfo->connHandle < MAX_NUM_BLE_CONNS)
      {
        L2CAP_DisconnectReq(rcConnCB[termInfo->connHandle].cocCID);
      }
      else
      {
        RTLSCtrl_sendDebugEvt((uint8_t *)"Connection Handle invalid", LINKDB_CONNHANDLE_INVALID);
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_setCreateSyncParams
     *
     * @brief   Configure sync parameters
     *
     * @param   pParams - Pointer to create sync parameters
     *
     * @return  none
     */
    static void RTLSCoordinator_setCreateSyncParams(rtlsCreateSyncParams_t *pParams)
    {
      uint32_t status;
      GapScan_PeriodicAdvCreateSyncParams_t pSyncParams;
    
      pSyncParams.options = pParams->options;
      pSyncParams.advAddrType = pParams->advAddrType;
      MAP_osal_memcpy(pSyncParams.advAddress, pParams->advAddress, B_ADDR_LEN);
      pSyncParams.skip = pParams->skip;
      pSyncParams.syncTimeout = pParams->syncTimeout;
      pSyncParams.syncCteType = pParams->syncCteType;
    
      status = GapScan_PeriodicAdvCreateSync(pParams->advSID, &pSyncParams);
    
      if( status != SUCCESS)
      {
        RTLSCtrl_sendDebugEvt((uint8_t *)"Set create sync params failed", status);
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_syncCancelCmd
     *
     * @brief   Cancels the create sync command
     *
     * @param   none
     *
     * @return  none
     */
    static void RTLSCoordinator_syncCancelCmd( void )
    {
      GapScan_PeriodicAdvCreateSyncCancel();
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_terminateSync
     *
     * @brief   Terminate synchronization with the periodic advertising
     *          identified by the syncHandle given
     *
     * @param   handle - The syncHandle of the periodic advertising
     *
     * @return  none
     */
    static void RTLSCoordinator_terminateSync(rtlsTerminateSync_t *handle)
    {
      uint32_t status;
    
      status = GapScan_PeriodicAdvTerminateSync(handle->syncHandle);
    
      if( status != SUCCESS)
      {
        RTLSCtrl_sendDebugEvt((uint8_t *)"Terminate sync failed", status);
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_periodicReceiveEnable
     *
     * @brief   Disable/Enable periodic advertising report from the periodic
     *          advetising identified by the syncHandle given
     *
     * @param   pParams - The parameter given to enable/disable the periodic
     *                    reports
     *
     * @return  none
     */
    static void RTLSCoordinator_periodicReceiveEnable(rtlsReceiveEnableParams_t *pParams)
    {
      uint32_t status;
    
      status = GapScan_SetPeriodicAdvReceiveEnable(pParams->syncHandle, pParams->enable);
    
      if( status != SUCCESS)
      {
        RTLSCtrl_sendDebugEvt((uint8_t *)"Receive enable failed", status);
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_addDeviceToPeriodicAdvList
     *
     * @brief   Adding a device to the advertisers list
     *
     * @param   pParams - Device information
     *
     * @return  none
     */
    static void RTLSCoordinator_addDeviceToPeriodicAdvList(rtlsAdvListDeviceParams_t *pParams)
    {
      uint32_t status;
      rtlsAdvListDeviceParams_t *pAddParams = (rtlsAdvListDeviceParams_t *)pParams;
    
      status = GapScan_AddDeviceToPeriodicAdvList(pAddParams->advAddrType, pAddParams->advAddress, pAddParams->advSID);
    
      if( status != SUCCESS)
      {
        RTLSCtrl_sendDebugEvt((uint8_t *)"Add to adv list failed", status);
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_removeDeviceFromPeriodicAdvList
     *
     * @brief   Removing a device from the advertisers list
     *
     * @param   pParams - Device information
     *
     * @return  none
     */
    static void RTLSCoordinator_removeDeviceFromPeriodicAdvList(rtlsAdvListDeviceParams_t *pParams)
    {
      uint32_t status;
      rtlsAdvListDeviceParams_t *pAddParams = (rtlsAdvListDeviceParams_t *)pParams;
    
      status = GapScan_RemoveDeviceFromPeriodicAdvList(pAddParams->advAddrType, pAddParams->advAddress, pAddParams->advSID);
    
      if( status != SUCCESS)
      {
        RTLSCtrl_sendDebugEvt((uint8_t *)"Remove from adv list failed", status);
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_readPeriodicAdvListSize
     *
     * @brief   Read the advertisers list size
     *
     * @param   none
     *
     * @return  none
     */
    static void RTLSCoordinator_readPeriodicAdvListSize( void )
    {
      GapScan_ReadPeriodicAdvListSize();
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_clearPeriodicAdvList
     *
     * @brief   Clear the advertisers list
     *
     * @param   none
     *
     * @return  none
     */
    static void RTLSCoordinator_clearPeriodicAdvList( void )
    {
      GapScan_ClearPeriodicAdvList();
    }
    
    #ifdef RTLS_CTE
    /*********************************************************************
     * @fn      RTLSCoordinator_setAoaParamsReq
     *
     * @brief   Configure AoA parameters to the BLE Stack
     *
     * @param   config - Parameters to configure
     *
     * @return  none
     */
    static void RTLSCoordinator_setAoaParamsReq(rtlsAoaConfigReq_t *pConfig)
    {
      bStatus_t status;
      // Initialize GPIO's specified in sysConfig or in ble_user_config.c (antennaTbl)
      // Initialize one of the antenna ID's as the main antenna (in this case the first antenna in the pattern)
      status = RTLSSrv_initAntArray(pConfig->pAntPattern[0]);
    
      if (status == FAILURE)
      {
        RTLSCtrl_sendDebugEvt((uint8_t *)"Antenna array configuration invalid", 0);
        AssertHandler(HAL_ASSERT_CAUSE_HARDWARE_ERROR,0);
      }
    
      // Configure AoA receiver parameters
      RTLSSrv_setConnCteReceiveParams(pConfig->connHandle,
                                      pConfig->samplingEnable,
                                      pConfig->slotDurations,
                                      pConfig->numAnt,
                                      pConfig->pAntPattern);
    
      // Configure sample accuracy
      RTLSSrv_setCteSampleAccuracy(pConfig->connHandle,
                                   pConfig->sampleRate,
                                   pConfig->sampleSize,
                                   pConfig->sampleRate,
                                   pConfig->sampleSize,
                                   pConfig->sampleCtrl);
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_enableAoaReq
     *
     * @brief   Enable sampling AoA
     *
     * @param   config - Parameters to configure
     *
     * @return  none
     */
    static void RTLSCoordinator_enableAoaReq(rtlsAoaEnableReq_t *pReq)
    {
      // Sanity check
      if (pReq == NULL)
      {
        return;
      }
    
      // Request CTE from our peer
      RTLSSrv_setConnCteRequestEnableCmd(pReq->connHandle,
                                         pReq->enableAoa,
                                         pReq->cteInterval,
                                         pReq->cteLength,
                                         RTLSSRV_CTE_TYPE_AOA);
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_CLAoaSamplingEnableReq
     *
     * @brief   Enable sampling AoA
     *
     * @param   config - Parameters to configure
     *
     * @return  none
     */
    static void RTLSCoordinator_CLAoaSamplingEnableReq(rtlsCLAoaEnableReq_t *pReq)
    {
      bStatus_t status;
      uint8_t cmdStatus;
      uint16_t syncHandle;
    
      // Sanity check
      if (pReq == NULL)
      {
        return;
      }
    
      // Initialize GPIO's specified in ble_user_config.c (antennaTbl)
      // Initialize one of the antenna ID's as the main antenna (in this case the first antenna in the pattern)
      status = RTLSSrv_initAntArray(pReq->pAntPattern[0]);
    
      if (status == FAILURE)
      {
        RTLSCtrl_sendDebugEvt((uint8_t *)"Antenna array configuration invalid", 0);
        AssertHandler(HAL_ASSERT_CAUSE_HARDWARE_ERROR,0);
      }
    
      // Mask the syncHandle to notify the controller it is CL CTE req
      syncHandle = pReq->syncHandle | SYNC_HANDLE_MASK;
    
      // Configure sample accuracy
      RTLSSrv_setCteSampleAccuracy( syncHandle,
                                    pReq->sampleRate,
                                    pReq->sampleSize,
                                    pReq->sampleRate,
                                    pReq->sampleSize,
                                    pReq->sampleCtrl );
    
      // Request connectionless CTE from our peer
      cmdStatus = RTLSSrv_setCLCteSamplingEnableCmd( pReq->syncHandle,
                                                     pReq->enable,
                                                     pReq->slotDuration,
                                                     pReq->maxSampleCte,
                                                     pReq->numAnt,
                                                     pReq->pAntPattern );
    
      if( cmdStatus != SUCCESS)
      {
        RTLSCtrl_sendDebugEvt((uint8_t *)"CL AoA enable request failed", cmdStatus);
        // We need to remove the CL AoA node
        RTLSCtrl_processClAoaEnableEvt(RTLSSRV_SET_CL_IQ_SAMPLING_ENABLE,
                                       cmdStatus,
                                       pReq->syncHandle);
      }
    }
    #endif /* RTLS_CTE */
    
    /*********************************************************************
     * @fn      RTLSCoordinator_processRTLSUpdateConnInterval
     *
     * @brief   Update connection interval
     *
     * @param   updateReq - pointer from RTLS control containing connection params
     *
     * @return  none
     */
    static void RTLSCoordinator_processRTLSUpdateConnInterval(rtlsUpdateConnIntReq_t *updateReq)
    {
      gapUpdateLinkParamReq_t params;
      linkDBInfo_t linkInfo;
    
      // Sanity check
      if (!updateReq)
      {
        return;
      }
    
      if (linkDB_GetInfo(updateReq->connHandle, &linkInfo) == SUCCESS)
      {
        params.connLatency = linkInfo.connLatency;
        params.connTimeout = linkInfo.connTimeout;
        params.connectionHandle = updateReq->connHandle;
    
        // Min/Max set to the same value
        params.intervalMax = updateReq->connInterval;
        params.intervalMin = updateReq->connInterval;
    
        GAP_UpdateLinkParamReq(&params);
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_processRtlsCtrlMsg
     *
     * @brief   Handle processing messages from RTLS Control
     *
     * @param   msg - a pointer to the message
     *
     * @return  none
     */
    static void RTLSCoordinator_processRtlsCtrlMsg(uint8_t *pMsg)
    {
      rtlsCtrlReq_t *pReq;
    
      // Sanity check
      if (!pMsg)
      {
        return;
      }
    
      // Cast to appropriate struct
      pReq = (rtlsCtrlReq_t *)pMsg;
    
      if (pReq->reqOp <= RTLS_REQ_BLE_LOG_STRINGS_MAX)
      {
        BLE_LOG_INT_STR(0, BLE_LOG_MODULE_APP, "APP : RTLS msg status=%d, event=%s\n", 0, rtlsReq_BleLogStrings[pReq->reqOp]);
      }
      else
      {
        BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : RTLS msg status=%d, event=0x%x\n", 0, pReq->reqOp);
      }
    
      switch(pReq->reqOp)
      {
        case RTLS_REQ_CONN:
        {
          RTLSCoordinator_processRTLSConnReq((bleConnReq_t *)pReq->pData);
        }
        break;
    
        case RTLS_REQ_SCAN:
        {
          RTLSCoordinator_processRTLSScanReq();
        }
        break;
    
        case RTLS_REQ_ENABLE_SYNC:
        {
          RTLSCoordinator_enableRtlsSync((rtlsEnableSync_t *)pReq->pData);
        }
        break;
    
        case RTLS_REQ_SEND_DATA:
        {
          RTLSCoordinator_sendRTLSData((rtlsPacket_t *)pReq->pData);
        }
        break;
    
        case RTLS_REQ_TERMINATE_LINK:
        {
          RTLSCoordinator_terminateLinkReq((rtlsTerminateLinkReq_t *)pReq->pData);
        }
        break;
    
        case RTLS_REQ_SET_CREATE_SYNC_PARAMS:
        {
          RTLSCoordinator_setCreateSyncParams((rtlsCreateSyncParams_t *)pReq->pData);
        }
        break;
    
        case RTLS_REQ_CREATE_SYNC_CANCEL:
        {
          RTLSCoordinator_syncCancelCmd();
        }
        break;
    
        case RTLS_REQ_TERMINATE_SYNC:
        {
          RTLSCoordinator_terminateSync((rtlsTerminateSync_t *)pReq->pData);
        }
        break;
    
        case RTLS_REQ_PERIODIC_RECEIVE_ENABLE:
        {
          RTLSCoordinator_periodicReceiveEnable((rtlsReceiveEnableParams_t *)pReq->pData);
        }
        break;
    
        case RTLS_REQ_ADD_DEVICE_ADV_LIST:
        {
          RTLSCoordinator_addDeviceToPeriodicAdvList((rtlsAdvListDeviceParams_t *)pReq->pData);
        }
        break;
    
        case RTLS_REQ_REMOVE_DEVICE_ADV_LIST:
        {
          RTLSCoordinator_removeDeviceFromPeriodicAdvList((rtlsAdvListDeviceParams_t *)pReq->pData);
        }
        break;
    
        case RTLS_REQ_READ_ADV_LIST_SIZE:
        {
          RTLSCoordinator_readPeriodicAdvListSize();
        }
        break;
    
        case RTLS_REQ_CLEAR_ADV_LIST:
        {
          RTLSCoordinator_clearPeriodicAdvList();
        }
        break;
    
        case RTLS_REQ_UPDATE_CONN_INTERVAL:
        {
          RTLSCoordinator_processRTLSUpdateConnInterval((rtlsUpdateConnIntReq_t *)pReq->pData);
        }
        break;
    
        case RTLS_REQ_GET_ACTIVE_CONN_INFO:
        {
          rtlsGetActiveConnInfo_t *pConnInfoReq = (rtlsGetActiveConnInfo_t *)pReq->pData;
    
          if (pConnInfoReq)
          {
            RTLSCoordinator_processRTLSConnInfo(pConnInfoReq->connHandle);
          }
        }
        break;
    
    #ifdef RTLS_CTE
        case RTLS_REQ_SET_AOA_PARAMS:
        {
          RTLSCoordinator_setAoaParamsReq((rtlsAoaConfigReq_t *)pReq->pData);
        }
        break;
    
        case RTLS_REQ_AOA_ENABLE:
        {
          RTLSCoordinator_enableAoaReq((rtlsAoaEnableReq_t *)pReq->pData);
        }
        break;
    
        case RTLS_REQ_CL_AOA_ENABLE:
        {
          RTLSCoordinator_CLAoaSamplingEnableReq((rtlsCLAoaEnableReq_t *)pReq->pData);
        }
        break;
    #endif /* RTLS_CTE */
    
        default:
          break;
      }
    
      // Free the payload
      if (pReq->pData)
      {
        ICall_free(pReq->pData);
      }
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_processRtlsSrvMsg
     *
     * @brief   Handle processing messages from RTLS Services host module
     *
     * @param   pEvt - a pointer to the event
     *
     * @return  none
     */
    static void RTLSCoordinator_processRtlsSrvMsg(rtlsSrv_evt_t *pEvt)
    {
      if (!pEvt)
      {
        return;
      }
    
      BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : RTLSsrv msg status=%d, event=0x%x\n", 0, pEvt->evtType);
      switch (pEvt->evtType)
      {
        case RTLSSRV_ANTENNA_INFORMATION_EVT:
        {
          // This is for demonstration purposes - we could either use RTLSCtrl_sendDebugEvent
          // Or read the information by using a debugger
          // rtlsSrv_antennaInfo_t *pAntInfo = (rtlsSrv_antennaInfo_t)pEvt->evtData;
        }
        break;
    
        case RTLSSRV_ERROR_EVT:
        {
          rtlsSrv_errorEvt_t *pError = (rtlsSrv_errorEvt_t *)pEvt->evtData;
          RTLSCtrl_sendDebugEvt((uint8_t *)"RTLS Services Error", (uint32_t)pError->errCause);
        }
        break;
    
        case RTLSSRV_READ_PERIODIC_LIST_SIZE_EVT:
        {
          RTLSCtrl_sendPeriodicListSize(pEvt->evtData);
        }
        break;
    
        case RTLSSRV_SYNC_EST_EVT:
        {
          rtlsSrv_SyncEstEvt_t *pEvent = (rtlsSrv_SyncEstEvt_t *)pEvt->evtData;
    
          RTLSCtrl_processSyncEstEvt(pEvent->opcode,
                                     pEvent->status,
                                     pEvent->syncHandle,
                                     pEvent->advSid,
                                     pEvent->advAddrType,
                                     pEvent->advAddress,
                                     pEvent->advPhy,
                                     pEvent->periodicAdvInt,
                                     pEvent->advClockAccuracy);
        }
        break;
    
        case RTLSSRV_SYNC_LOST_EVT:
        {
          rtlsSrv_SyncLostEvt_t *pEvent = (rtlsSrv_SyncLostEvt_t *)pEvt->evtData;
    
          RTLSCtrl_processSyncLostEvt(pEvent->opcode,
                                      pEvent->syncHandle);
        }
        break;
    
        case RTLSSRV_PERIODIC_ADV_TERMINATE_SYNC:
        {
          RTLSCtrl_processTerminateSyncEvt();
        }
        break;
    
        case RTLSSRV_PERIODIC_ADV_RPT:
        {
          rtlsSrv_PeriodicAdvRpt_t *pReport = (rtlsSrv_PeriodicAdvRpt_t *)pEvt->evtData;
    
          RTLSCTRL_processPeriodicAdvReport(pReport->opcode,
                                            pReport->syncHandle,
                                            pReport->txPower,
                                            pReport->rssi,
                                            pReport->cteType,
                                            pReport->dataStatus,
                                            pReport->dataLen,
                                            pReport->pData);
    
          if(pReport->pData != NULL)
          {
            ICall_free(pReport->pData);
          }
        }
        break;
    
    #ifdef RTLS_CTE
        case RTLSSRV_CONNECTION_CTE_IQ_REPORT_EVT:
        {
          rtlsSrv_connectionIQReport_t *pReport = (rtlsSrv_connectionIQReport_t *)pEvt->evtData;
    
          RTLSAoa_processAoaResults(pReport->connHandle,
                                    pReport->rssi,
                                    pReport->dataChIndex,
                                    pReport->sampleCount,
                                    pReport->sampleRate,
                                    pReport->sampleSize,
                                    pReport->sampleCtrl,
                                    pReport->slotDuration,
                                    pReport->numAnt,
                                    pReport->iqSamples);
        }
        break;
    
        case RTLSSRV_CTE_REQUEST_FAILED_EVT:
        {
          rtlsSrv_cteReqFailed_t *pReqFail = (rtlsSrv_cteReqFailed_t *)pEvt->evtData;
          RTLSCtrl_sendDebugEvt((uint8_t *)"RTLS Services CTE Req Fail", (uint32_t)pReqFail->status);
    
        }
        break;
    
        case RTLSSRV_CL_AOA_ENABLE_EVT:
        {
          rtlsSrv_ClAoAEnableEvt_t *pEvent = (rtlsSrv_ClAoAEnableEvt_t *)pEvt->evtData;
          RTLSCtrl_processClAoaEnableEvt(pEvent->opcode,
                                         pEvent->status,
                                         pEvent->syncHandle);
        }
        break;
    
        case RTLSSRV_CL_CTE_IQ_REPORT_EVT:
        {
          rtlsSrv_clIQReport_t *pReport = (rtlsSrv_clIQReport_t *)pEvt->evtData;
    
          RTLSAoa_processAoaResults( pReport->syncHandle,
                                     pReport->rssi,
                                     pReport->channelIndex,
                                     pReport->sampleCount,
                                     pReport->sampleRate,
                                     pReport->sampleSize,
                                     pReport->sampleCtrl,
                                     pReport->slotDuration,
                                     pReport->numAnt,
                                     pReport->iqSamples );
        }
        break;
    #endif /* RTLS_CTE */
    
        default:
          break;
      }
    
      // Free the payload
      if (pEvt->evtData)
      {
        ICall_free(pEvt->evtData);
      }
    }
    
    
    /*********************************************************************
     * @fn      RTLSCoordinator_rtlsCtrlMsgCb
     *
     * @brief   Callback given to RTLS Control
     *
     * @param  cmd - the command to be enqueued
     *
     * @return  none
     */
    void RTLSCoordinator_rtlsCtrlMsgCb(uint8_t *cmd)
    {
      // Enqueue the message to switch context
      RTLSCoordinator_enqueueMsg(RC_EVT_RTLS_CTRL_MSG_EVT, SUCCESS, (uint8_t *)cmd);
    }
    
    /*********************************************************************
     * @fn      RTLSCoordinator_rtlsSrvlMsgCb
     *
     * @brief   Callback given to RTLS Services
     *
     * @param   pRtlsSrvEvt - the command to be enqueued
     *
     * @return  none
     */
    void RTLSCoordinator_rtlsSrvlMsgCb(rtlsSrv_evt_t *pRtlsSrvEvt)
    {
      // Enqueue the message to switch context
      RTLSCoordinator_enqueueMsg(RC_EVT_RTLS_SRV_MSG_EVT, SUCCESS, (uint8_t *)pRtlsSrvEvt);
    }
    
    /*********************************************************************
    *********************************************************************/
    

    请记住、这旨在与"simple_peripheral_CC26X2R1_LAUNCHXL_tirtos7_ticlang"配对、我将在此处添加。 该项目中的更改将在 Adv 数据字节中添加 MAC 地址、然后添加代码以扩展广播 (而非传统)。 请注意、您的示例中有一些索引不匹配、我已经在下面的项目中修复了该问题:

    simple_peripheral_CC26X2R1_LAUNCHXL_tirtos7_ticlang.zip

    这就是我对索引的含义、你把注释行计数为一个字节索引、我已经在随附的 Simple periph 项目中调整了它-你需要这个项目、因为这是我修改为 Adv extended vs legacy

    1.从 stock rtls_Coordinator 开始,覆写我要发送给你的 c 文件。 在 LaunchPad 上运行这个。 我没有添加任何打印操作来工作、我只是以交互方式调试了它、在跟踪过程中、我可以看到设置了不匹配的变量(我添加了一个命中旋转锁定断点)

    2.在2个 LaunchPad 上运行简单的 periph,确保给他们不同的 MAC

    3.调试 RTLS_Coordinator 后发现这个断点在应用程序运行大约30-40秒后被命中:

    请在您能够复制以及更重要的是、您认为导致此问题的原因时、及时告知我们。

    我们相信这样的差异会影响行中的 AoA 精度(但这是在发生同步和检测到 IQ 样本之后)。 现在、不会发生同步、也不会有 AoA IQ 样本、因为这是库存 RTLS 协调器、而且我们没有运行任何主机来驱动任务。

    期待您的答复

    谢谢。

    伊万

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

    伊凡、您好!

    感谢您提供该项目、并提供了可轻松放入 SDK 项目的文件。 我将尝试构建项目、今天进行测试、明天再和您联系。

    此致、

    1月

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

    伊凡、您好!

    我能够使用您的示例和提供的代码重现行为。 我还能够验证、它仅在两个 simple_peripheral LaunchPad 打开时发生。 我的第一个想法是尝试修改扫描参数、使它们与我们使用的 simple_central 示例匹配。 要确认、您是否无法使用 simple_central 和 simple_peripheral (使用扩展广播)看到问题? 如果是、作为测试、您可以尝试更改协调器示例的扫描参数以匹配 simple_central 并重新测试?

    此致、

    1月

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

    一月、

    我很高兴您能看到不匹配情况。 如果可能、我们是否可以将此问题上报 TI 以进一步解决?

    总之、我们有2个(或更多)扩展广播客户端(基于 simple_peripheral)和1个扫描器(基于 RTLS_Coordinator)、没有同步、没有连接、只是扫描、并且似乎实际结果混淆了、其中有多个广播器。

    是的、我没有看到 simple_central 和 simple_peripheral 的扩展广播问题。 我将尝试使用与使用 simple_central 相同的扫描参数(我认为这是默认值)、但我认为扫描参数不是导致此问题的原因。

    原因必须在 RTLS 协调器项目中、其中包含 AoA 文件和多个天线、即使使用我共享的 RTLS 协调器版本、我们也只能进行简单的扫描。 我无法解释为什么会发生这种情况,我正在寻求你们的帮助。

    当我们使用实际的 AoA 数据、IQ 样本以及最终的角度进行测试时、我们发现了这一点-对于1-2个标签、甚至可能是3-4个标签、这非常准确、但当我们开始时、更多的标签会零星地停留在周围。 当我们尝试回溯并在扫描过程中注意到这些差异时(在任何同步、AoA IQ 数据发挥作用之前)、 我们相信、这些问题会在流程的后期混合 IQ 样本、然后所有角度都会混淆-这只是一个理论。

    请告知我们、您是否可以参与更多有关此方面的 TI 资源、并尝试对此进行解释

    谢谢。

    Ivan S.

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

    伊凡、您好!

    感谢您提供详细的总结。 我将提交一张票与所提供的信息,并继续他在我的侧面首次亮相。 我认为这不是预期的行为、在我们的测试中、我们已经显示它已本地化为协调器项目。 对于由此给您带来的不便、我深表歉意。 我将在下周早些时候(周一或周二)向您介绍我得出的任何结果。

    此致、

    1月

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

    大家好、Jan、

    您是否有任何更新?

    我们站在旁边,这是重要的和时间敏感的。

    谢谢!

    Ivan S.

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

    伊凡、您好!

    我今天执行了更多的测试。 我发现、将扫描参数更改为 simple_central 扫描参数对该行为没有影响。 这进一步表明问题必须在 AOA 逻辑中。 我将继续与团队合作解决此问题、看看我们是否能够找到根本原因并修复或提供解决方法。 在我们继续调查的过程中、我会不断向您提供最新信息。 对于由此给您带来的不便、我深表歉意。

    此致、

    1月

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

    伊凡、您好!

    我已经与团队进一步讨论了该行为、我们认为我们找到了可能有帮助的权变措施。  对此、我们有两种可能的权变措施。 我在 下面列出了这些功能:

    1.向每位广告商提供自己的服务质量(SID),确保没有任何广告商具有相同的 SID。 我对它进行了几分钟的测试、没有遇到任何不匹配情况

    2.更改通道映射,使每个广播者在不同的通道上进行广播。 我没有机会对此进行深入的测试、但我们认为这也应该起作用。

    请告诉我、这些解决方法是否最终有效 团队和我已经确认此问题位于 AOA/RTLS 后端。 对于此行为可能给您带来的不便、我深表歉意、希望提供的解决方法已经足够。

    此致、

    1月

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

    大家好、Jan、


    谢谢您的建议。

    我们将尝试#1、尝试随机化标签/响应器固件上的 SID。 我看到 SID 被定义为一个字节、因此这里有一些限制、因为即使 SID = random (255)、从理论上讲、也有可能发生冲突。

    /**
     * Per-advertising set parameters
     *
     * These can be set with @ref GapAdv_setParam
     * See the specific parameter linked to each element for more information.
     */
    typedef struct
    {
      uint16_t eventProps;                   //!< @ref GAP_ADV_PARAM_PROPS
      uint32_t primIntMin;                   //!< @ref GAP_ADV_PARAM_PRIMARY_INTERVAL_MIN
      uint32_t primIntMax;                   //!< @ref GAP_ADV_PARAM_PRIMARY_INTERVAL_MAX
      GapAdv_advChannels_t primChanMap;      //!< @ref GAP_ADV_PARAM_PRIMARY_CHANNEL_MAP
      GAP_Peer_Addr_Types_t peerAddrType;    //!< @ref GAP_ADV_PARAM_PEER_ADDRESS_TYPE
      uint8_t peerAddr[B_ADDR_LEN];          //!< @ref GAP_ADV_PARAM_PEER_ADDRESS
      GapAdv_filterPolicy_t filterPolicy;    //!< @ref GAP_ADV_PARAM_FILTER_POLICY
      int8_t txPower;                        //!< NOT CURRENTLY IMPLEMENTED
      GapAdv_primaryPHY_t primPhy;           //!< @ref GAP_ADV_PARAM_PRIMARY_PHY
      GapAdv_secondaryPHY_t secPhy;          //!< @ref GAP_ADV_PARAM_SECONDARY_PHY
      uint8_t sid;                           //!< @ref GAP_ADV_PARAM_SID
    } GapAdv_params_t;
    

    您是否对何时发布永久修复有任何想法?

    PS:我的团队提请我注意、每个 BLE 规格的 SID 仅为4位。 您能详细说明一下吗? 我的意思是、我可以看到它被定义为 uint8 (位于 gap_advertiser.h 的代码段上方)、但 BLE 核心规范将其显示为复合字段以及广播数据 ID (DID)、我没有看到它暴露在应用程序中

    下面是 BLE 核心规格的屏幕:

    当我们在 SDK 级别设置 uint8 SID 时、您知道 TI 堆栈是否将使用它旁边的低4位来感受 SID 字段您是否使用所有8位?

    我希望阐明、我们应该使用什么随机范围来测试 SID? 0至0b1111 (Dec15)还是0至0b11111111 (DEC255)?

    谢谢。

    Ivan S.

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


    大家好、Jan、

    确认、我们没有收到与不同 SID 发生的冲突。

    我想我们解答了有关 SID 范围的问题-我尝试了 SID 的较高位、似乎使用了所有8位。 我尝试两个 SID=255和 SID=254标签、但没有遇到冲突

    相同 SID:

    不同的 SID:

    我们将实现 SID = random (255)逻辑来暂时使我们继续、但请告知我们这将何时永久解决-我将观察此主题、或者在您有更新时也请向我发送消息。

    谢谢!

    Ivan S.

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

    伊凡、您好!

    我很高兴听到解决方法运行良好! 我想澄清一点、Set ID 字段的范围是0到15、因此这些值应该在该情况下使用。 TT 已提交、并将由研发部门在未来 SDK 版本的某个时刻查找。 很遗憾、我不知道此时哪个 SDK 将包含此修复程序。 对于由此可能造成的任何不便、我深表歉意。 同时、如果您遇到与权变措施有关的任何问题、请告诉我、我将非常乐意提供帮助。

    此致、

    1月

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

    一月、

    我之前很激动、因为我测试了 SID=255和 SID=254、这个想法是我们可以用0-255将 SID 随机化。 但这两个值未测试4位 SID 理论(这些数字具有较低的位不同、因此可行)。

    现在、阅读您对0-15范围的评论、我使用 sid=15 (0b1111)和31 (0b11111)进行了测试、确实获得了重复项。

    这证实了 SID 修复的范围只有0-15,这意味着我们只能随机化16个数字,而只有16个,那么生成相同 SID...的标签的百分比要高得多

    如果不进行统计、0-255似乎更容易被接受、希望标签具有相同的 SID。 现在、由于只有16个可随机化的 SID、我认为重复的概率相当高、约为6%(100/16 =约6%)

    请您是否可以上报此问题、并可能向我们提供解决此问题的 SDK 库版本。

    从前瞻性测试来看、我们可以硬化16个感应器上的不同 SID、并测试负载和角度准确度、但我不认为现在较小的范围0-15、我们可以考虑任何种类的最终解决方案/固件。

    如果您能做些什么来加快进度、请随时向我们提供最新信息。

    谢谢。

    伊万

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

    大家好、Jan、

    我只是想跟进一些 ETA 以更永久的方式修复这一问题-请保持我们发布。

    是否有可能获得一个临时库、我们可以手动替换和编译用于修复该问题的程序、以便我们可以很快进行更多更大规模的测试。 现在、我们只能使用16个标签进行测试、但这样做的局限性很大。

    谢谢。
    Ivan S.

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

    伊凡、您好!

    很遗憾、我还没有确切的时间安排问题解决时间。 我会再次咨询研发团队、告知他们这是一个紧迫的问题。 与此同时、您是否仍能够继续开发16个标签、直到我们找到更持久的解决方案?

    此致、

    1月

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

    一月、

    请保持此主题处于更新状态、我们正在监控响应。

    我们对16个标签的工作方式感到满意、下一个是可扩展性测试、我们希望扩展多达50、100个标签来观察系统性能和数据流-从发送 IQ 样本的标签到实际 UI 更新标签位置。 考虑到实际数据(IQ 样本)的数量和频率、我们必须确保我们的系统能够处理更多标签-这是我们需要您帮助才能完成的重要复选框。

    当您收到研发团队的反馈时、请及时告知我们

    谢谢。

    Ivan S.

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

    伊凡、您好!

    我完全理解。 我会经常跟研发部门说、看看他们什么时候可以解决这个问题。 我将随时向您通报最新情况。 对于由此给您带来的不便、我深表歉意。

    此致、

    1月

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

    一月、

    我很抱歉一直在问、您是听到了什么、还是这似乎不是一个快速解决方案?

    我们正在积极地在平台上实施 AoA、但由于此限制、我们真的不打算发布 AoA。

    预期修复的实际时间框架是什么、以便我可以将其传递给业务开发团队、从而能够调整项目时间表并规划产品发布?

    谢谢。
    Ivan S.

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

    伊凡、您好!

    无需道歉! 目前、我无法提供此行为何时会完全解决的确切时间表。 这可能需要解决一个或两个 SDK 版本。 我将继续研究是否可以采取任何措施来进一步缓解这种行为。 对于由此给您带来的不便、我深表歉意。

    此致、

    1月

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

    伊凡、您好!

    我有另一个建议,可能增加我们可以有的广告客户数量,而不会陷入重复。 我们正在与 R&D 合作以尽快解决此问题、但与此同时、该附加的权变措施应能为我们带来最多16个广播器、最多64个器件。 简而言之、我们仍然使用 SID 解决方法、但每组16个器件将使用不重叠的通道子集进行广播。 例如:

    • 器件0 - 15:将具有0至15n 的 SID、并将使用通道0、4、8、12、16、 20、24、28、32
    • 器件16 - 31:将具有0至15n 的 SID、并将使用通道1、5、9、13、17、 21、25、29、33
    • 器件32 - 47:将具有0至15n 的 SID、并将使用通道  2、6、10、14、18、 22、26、30、34
    • 器件48 - 63:将具有0至15n 的 SID、并将使用通道3、7、11、15、19、 23、27、31、35

    以下 SLA 提供了一些有关如何修改通道映射的有用信息: https://dev.ti.com/tirex/content/simplelink_academy_cc13xx_cc26xxsdk_6_40_00_00/modules/rtls_toolbox_ble5/ble_aoa/ble_aoa_target.html#change-the-channel-map-connectionless-aoa-

    我知道这并不理想、如果该变通办法能够按预期工作、那么标签总数将为64 (比以前限制为16个标签增加了4倍、但仍然是您提到的256个所需设备的1/4)、 但在我们通过研发解决这个问题之前、这可能有助于解除开发的障碍 对于这可能造成的任何延误或不便、我深表歉意。

    此致、

    1月