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.

[参考译文] LP-CC2652RB:发送定期广播数据失败。

Guru**** 2538950 points


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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1215502/lp-cc2652rb-failed-to-send-periodic-adv-data

器件型号:LP-CC2652RB

大家好、

以下是客户的请求:

客户按照   SimpleLink TM CC13x2/CC26x2 SDK BLE5-Stack 用户指南2.02.01.00中定期广播部分的步骤来编写外设代码。

但是、主机中央器件无法接收 由 GapAdv_SetPeriodicAdvData 函数设置的周期性 Adv 数据、但可以接收由 GapAdv_loadByHandle 设置的数据。   外围设备配置的定期广播部分的代码段如下所示。 他检查了每个函数返回的状态、所有函数都返回成功。

// Periodic Advertising Intervals
#define PERIDIC_ADV_INTERVAL_MIN    160  
#define PERIDIC_ADV_INTERVAL_MAX    160 

/// 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 = { 0x74, 0xD2, 0x85, 0xD4, 0x63, 0xB4 },                      \
  .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                                                                \
}

static uint8 advHandleNCNS;      // Non-Connactable & Non-Scannable

static uint8_t periodicData[] =
{
  'P',
  'e',
  'r',
  'i',
  'o',
  'd',
  'i',
  'c',
  'A',
  'd',
  'v'
};

#define GAPADV_DATA_PERIODIC_ADV {                          \
   .operation = GAPADV_PERIODIC_ADV_DATA_COMPLETE,           \
   .dataLength = sizeof(periodicData),                       \
   .pData = periodicData                                     \
 }

// Advertisement data
static uint8_t advertData[] =
{
  0x0C,                         // Length of this data
  GAP_ADTYPE_LOCAL_NAME_SHORT,  // Type of this data
  'P',
  'e',
  'r',
  'i',
  'o',
  'd',
  'i',
  'c',
  'A',
  'd',
  'v',
  0x02,   // length of this data
  GAP_ADTYPE_FLAGS,
  GAP_ADTYPE_FLAGS_GENERAL | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
};

// Create non connectable & non scannable advertising set #3
GapAdv_params_t advParamNonConn = GAPADV_PARAMS_AE_NC_NS;

// Create Advertisement set #3 and assign handle
status = GapAdv_create(&SimplePeripheral_advCallback, &advParamNonConn, &advHandleNCNS);

// 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);

// 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);

// Enable non connectable & non scannable advertising for set #3
status = GapAdv_enable(advHandleNCNS, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0);

// Set Periodic Advertising parameters
GapAdv_periodicAdvParams_t perParams = {PERIDIC_ADV_INTERVAL_MIN,
                                        PERIDIC_ADV_INTERVAL_MAX, 0x40};
status = GapAdv_SetPeriodicAdvParams(advHandleNCNS, &perParams);

GapAdv_periodicAdvData_t periodicDataParams = GAPADV_DATA_PERIODIC_ADV;
status = GapAdv_SetPeriodicAdvData(advHandleNCNS, &periodicDataParams);

// Enable the periodic advertising
status = GapAdv_SetPeriodicAdvEnable(1, advHandleNCNS);

您能帮助检查这个问题吗? 谢谢。

谢谢。 此致、                                                         

Nick

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

    您好、Nick。

    感谢您与我们联系。 我们将查看您的问题、并尽快与您联系。 同时、您能否向我们提供正在使用的 SDK 版本?

    此致、

    1月

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

    大家好、Jan B ö,

    SDK 版本为 simplelink_cc13x2_26x2_SDK_5_10_00_48。

    谢谢。 此致、                                                         

    Nick

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

    您好、Nick。

    为了捕捉周期性广播、必须在 simple_central 端进行一些额外的代码修改。 与周期性广播序列同步 部分列出了这些修改。 客户是否实施了这些步骤?

    此致、

    1月

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

    大家好、Jan、

    以下是客户的进一步回复:

    附件是我的 simple_central 代码、初始化代码如下:

    void SimpleCentral_scanCb(uint32_t evt, void* pMsg, uintptr_t arg)
    {
      uint8_t event;
    
      if (evt & GAP_EVT_ADV_REPORT)
      {
        event = SC_EVT_ADV_REPORT;
      }
      else if (evt & GAP_EVT_SCAN_ENABLED)
      {
        event = SC_EVT_SCAN_ENABLED;
      }
      else if (evt & GAP_EVT_SCAN_DISABLED)
      {
        event = SC_EVT_SCAN_DISABLED;
      }
      else if (evt & GAP_EVT_INSUFFICIENT_MEMORY)
      {
        event = SC_EVT_INSUFFICIENT_MEM;
      }
      else
      {
        return;
      }
    
      if(SimpleCentral_enqueueMsg(event, SUCCESS, pMsg) != SUCCESS)
      {
        ICall_free(pMsg);
      }
    }
    
    GapScan_registerCb(SimpleCentral_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,
                       DEFAULT_SCAN_INTERVAL, DEFAULT_SCAN_WINDOW);
    
    // Set Advertising report fields to keep
    temp16 = (SCAN_ADVRPT_FLD_ADDRESS | SCAN_ADVRPT_FLD_ADDRTYPE);
    GapScan_setParam(SCAN_PARAM_RPT_FIELDS, &temp16);
    // Set Scanning Primary PHY
    temp8 = SCAN_PRIM_PHY_1M;
    GapScan_setParam(SCAN_PARAM_PRIM_PHYS, &temp8);
    // Set LL Duplicate Filter
    temp8 = SCAN_FLT_DUP_ENABLE;
    GapScan_setParam(SCAN_PARAM_FLT_DUP, &temp8);
    
    temp16 = SCAN_FLT_PDU_NONCONNECTABLE_ONLY;
    GapScan_setParam(SCAN_PARAM_FLT_PDU_TYPE, &temp16);
    
    // Set initiating PHY parameters
    // INIT_PHYPARAM_MAX_CONN_INT = 80
    GapInit_setPhyParam(INIT_PHY_1M, INIT_PHYPARAM_CONN_INT_MIN,
    				  INIT_PHYPARAM_MIN_CONN_INT);
    GapInit_setPhyParam(INIT_PHY_1M, INIT_PHYPARAM_CONN_INT_MAX,
    				  INIT_PHYPARAM_MAX_CONN_INT);

    客户 在 函数 SimpleCentral_processAppMsg 中的 SC_EVT_ADV_REPORT 广播扫描报告事件中添加了打印功能。 第一个现象是,他没有看到 pAdvRpt->periodicAdvInt != 0的定期广播数据,第二个现象是,他发现 GapAdv_loadByHandle 广播数据集由 simple_peripheral 使用以下代码:

    static void SimpleCentral_processAppMsg(scEvt_t *pMsg)
    {
      bool safeToDealloc = TRUE;
    
      if (pMsg->hdr.event <= APP_EVT_EVENT_MAX)
      {
        BLE_LOG_INT_STR(0, BLE_LOG_MODULE_APP, "APP : App msg status=%d, event=%s\n", 0, appEventStrings[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 SC_EVT_KEY_CHANGE:
          SimpleCentral_handleKeys(pMsg->hdr.state);
          break;
    
        case SC_EVT_ADV_REPORT:
        {
          GapScan_Evt_AdvRpt_t* pAdvRpt = (GapScan_Evt_AdvRpt_t*) (pMsg->pData);
            if(0 != pAdvRpt->periodicAdvInt)
            {
             // this is a periodic advertisement
                Display_printf(dispHandle, SC_ROW_9, 0, "this is a periodic advertisement");
                SimpleCentral_doStopDiscovering(0);
            }
            else
            {
             // this is NOT a periodic advertisement
            }
            // reporting the advData according to the peripheral address
            if(pAdvRpt->addr[0] == 0x8c && pAdvRpt->addr[5] == 0x74) { // this is my peripheral address
                Display_printf(dispHandle, SC_ROW_NON_CONN, 0, "Discovered: %s", Util_convertBdAddr2Str(pAdvRpt->addr));
                int j = 0;
                Display_printf(dispHandle, SC_ROW_9 + 1, 0, "advertisement data len: %d", pAdvRpt->dataLen);
                for(j = 0; j < pAdvRpt->dataLen; j++) {
                    Display_printf(dispHandle, SC_ROW_9 + 2 + j, 0, "%x", *(pAdvRpt->pData + j));
                }
            }
          
    
          // Free report payload data
          if (pAdvRpt->pData != NULL)
          {
            ICall_free(pAdvRpt->pData);
          }
          break;
        }
        
        // ...
        
        default:
          // Do nothing.
          break;
    }

    根据 与定期广告培训同步中的步骤、他 目前在第6步中遇到了识别定期广告客户的问题:

    谢谢。 此致、                                                         

    Nick

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

    您好、Nick。

    我建议 他们确认广告商是首先发送定期广告。 这可以通过使用逻辑分析仪并使用射频调试引脚来完成、您可以像这样启用这些引脚。  

    https://dev.ti.com/tirex/content/simplelink_cc13xx_cc26xx_sdk_6_41_00_17/docs/ble5stack/ble_user_guide/html/ble-stack-5.x-guide/debugging-index.html#debugging-rf-output

    我还建议他们使用 GAPADV_PERIOD_ADV_ENABLE_TX_POWER 而不使用0x40十六进制值。

    一旦我们确认广告主实际上是发送定期广播、我们就可以了解如何让中央服务器与它们同步。

    此致、

    Rogelio