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.

LAUNCHXL-CC2640R2: Simple Observer Not Capturing All Advertising Packets

Part Number: LAUNCHXL-CC2640R2

I am having some reliability issues with the simple_observer_cc2640r2lp_app from the 1_35_00_33 simplelink SDK.  I am trying to capture all advertising packets from a Peripheral device that is sending them every 100mSec (another CC2640R2 LaunchXL running Project_Zero app).  The Peripheral device includes in its advertising data a counter that increments when each ADV packet is sent.  I am inspecting that data in the Observer code and am missing roughly 10% of them.   When I inspect the BLE traffic using TI Packet Sniffer I can see all of the ADV packets sent from the Peripheral, with none missing, so the problem does not seem to lie in the Peripheral device.  I have modified the GAP_DEVICE_INFO_EVENT to filter events to only those that match the Address I am interested in and check that the counter in the mfr. area of the ADV packet is sequential, which indicates that I have not missed a packet.  Code is shown below, along with typical output.  I have DEFAULT_SCAN_DURATION set to 0 to scan indefinitely and DEFAULT_MAX_SCAN_RES set to 8.   I have also set some other GAP parameters as shown below...

//EC - set scan duty cycle to 100%, per e2e.ti.com/.../345382
GAP_SetParamValue( TGAP_GEN_DISC_SCAN_INT, 16);
GAP_SetParamValue( TGAP_GEN_DISC_SCAN_WIND, 16);

//EC - Do not filter by device address.....allow app to receive all ADV packets
GAP_SetParamValue(TGAP_FILTER_ADV_REPORTS, FALSE);

I'm thinking it may be a scan window/interval or timing issue, but am not sure exactly how to attack the problem other than trial and error....any help to solve this is much appreciated.

static void SimpleBLEObserver_processRoleEvent(gapObserverRoleEvent_t *pEvent)
{
    uint8_t event_addr[B_ADDR_LEN];   //!< Address of the advertisement or SCAN_RSP
    uint16_t advDataDifference = 0;
    uint32_t currentTicks = 0;

  switch ( pEvent->gap.opcode )
  {
    case GAP_DEVICE_INIT_DONE_EVENT:
      {
        //Display_print0(dispHandle, 1, 0, Util_convertBdAddr2Str(pEvent->initDone.devAddr));
        //Display_print0(dispHandle, 2, 0, "Initialized");

        // Prompt user to begin scanning.
        //Display_print0(dispHandle, 5, 0, "Discover ->");
      }
      break;

    case GAP_DEVICE_INFO_EVENT:
      {
        //SimpleBLEObserver_addDeviceInfo(pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType);
        advTotEvntCnt++;
        memcpy (event_addr, pEvent->deviceInfo.addr, B_ADDR_LEN);
        currentTicks = Clock_getTicks();

        //check if address matches our matchBuf pattern, so we know it's one of our BLE devices
        if (memcmp(&event_addr[B_ADDR_LEN-ADV_ID_MATCH_LEN], &matchBuf[B_ADDR_LEN-ADV_ID_MATCH_LEN], ADV_ID_MATCH_LEN) == 0)
        {
            advFiltEvntCnt++;
            //store ticks and mfr ADV data to buffers for offline inspection/debuggging.  Perepherial advances counter in mfr.
            //ADV data from with each ADV packet, when it reaches 1000, it wraps back to 0.
            advFiltEvntTicks[advDataBufIndex] = currentTicks;
            memcpy(&advFiltEvntData[advDataBufIndex], pEvent->deviceInfo.pEvtData + 6, sizeof(uint32_t));
            
            //check if the advertising data is sequential...if not log # missed, check for zero ignores when buffer wraps, so not exact, but close enough
            if (advFiltEvntData[advDataBufIndex] > 0)
            {
               advDataDifference = advFiltEvntData[advDataBufIndex] - advFiltLastData;
               if ((advDataDifference > 1) && (advFiltEvntCnt > 1))
               {
                   advFiltMissedEvntCnt += advDataDifference - 1;
               }
            }
            advFiltLastData = advFiltEvntData[advDataBufIndex];
            advDataBufIndex = (advDataBufIndex < ADV_DATA_BUF_LEN) ? advDataBufIndex++ : 0;
        }

        //output performance numbers every 10 seconds
        if (currentTicks - startTicks > 1000000)
        {
            startTicks = currentTicks;
            advFiltMissedEvntPct = ((float)advFiltMissedEvntCnt / (float)advFiltEvntCnt)*100;
            Display_print1(dispHandle, 1, 0, "Time Stamp Ticks: %d", currentTicks);
            Display_print1(dispHandle, 2, 0, "Total Event Count: %d", advTotEvntCnt);
            Display_print1(dispHandle, 3, 0, "Filtered Event Count: %d", advFiltEvntCnt);
            Display_print1(dispHandle, 4, 0, "Missed Event Count: %d", advFiltMissedEvntCnt);
            Display_print1(dispHandle, 5, 0, "Missed Event Percent: %d", advFiltMissedEvntPct);
            advTotEvntCnt = 0;
            advFiltEvntCnt = 0;
            advFiltMissedEvntCnt = 0;
        }
      }
      break;

    case GAP_DEVICE_DISCOVERY_EVENT:
      {
        // Discovery complete.
        scanning = FALSE;

        // Copy results.
        scanRes = pEvent->discCmpl.numDevs;
        memcpy(devList, pEvent->discCmpl.pDevList,
               (sizeof(gapDevRec_t) * pEvent->discCmpl.numDevs));

        Display_print1(dispHandle, 2, 0, "Devices Found %d", scanRes);

        if ( scanRes > 0 )
        {
          Display_print0(dispHandle, 3, 0, "<- To Select");
        }

        // Initialize scan index.
        scanIdx = -1;

        // Prompt user that re-performing scanning at this state is possible.
        Display_print0(dispHandle, 5, 0, "Discover ->");
      }
      break;

    default:
      break;
  }
}

   

Thank You,

Ed

  • Hi Ed,

    What scanning parameters are you using? To be sure to catch all advertisements the scan window should be greater than the advertisment interval. Read more here: dev.ti.com/.../
  • Advertising is at 100mSec and I have tried scan windows between 100mSec and 5000mSec without success.  I can reliably receive 95-99% of the ADV packets being sent, but not 100%.  I have also tried increasing the overall amount of ADV traffic over the air by adding 3 more peripheral devices (CC2640r2 LaunchXL boards) each advertising at 100mSec intervals, but this does not seem to impact the reliability, ie. make it worse....

    Is it possible that because the BLE stack is scanning on all 3 advertising channels that it may be missing some packets because it is 'listening' on ch38 for example and the peripheral is transmitting on ch37 or ch39?  Is it possible to set the BLE stack to scan on only one of the 3 advertising channels, for example ch37 only?   It seems you can set the stack to advertise on a single channel per below....

    Thank You.

    Ed

  • Hi Ed,

    To comply with the Bluetooth Core Spec, the device must scan on all three advertising channels. www.bluetooth.com/.../adopted-specifications

    However the peripheral device may advertise on only one channel.

    The scan window represents how long the device scans on each channel. Setting the scan window larger than the advertising interval should thus ensure that all advertisement packets are received.

    Are you working in a noisy environment?
  • Hello Marie,

    I have tried setting the scan window larger than the advertising interval on the 'simple observer' example code, however, when I do this I never receive the GAP_DEVICE_INFO_EVENT.  I have tried with various ranges of values, most recent was below....is there something I am missing here (note DEFAULT_SCAN_DURATION = 0)?

      // Setup GAP
      GAP_SetParamValue(TGAP_GEN_DISC_SCAN, DEFAULT_SCAN_DURATION);
      GAP_SetParamValue(TGAP_LIM_DISC_SCAN, DEFAULT_SCAN_DURATION);
    
      //EC - set scan duty cycle to 100%, per e2e.ti.com/.../345382
      GAP_SetParamValue( TGAP_GEN_DISC_SCAN_INT, 8000);
      GAP_SetParamValue( TGAP_GEN_DISC_SCAN_WIND, 9000);
    
      //EC - Do not filter by device address.....allow app to receive all ADV packets
      GAP_SetParamValue(TGAP_FILTER_ADV_REPORTS, FALSE);
    
    

    As far as a noisy environment, I used TI packet sniffer to double check that the peripheral device is working properly and had 0% missing packets after 500 advertisements with the peripheral setup to advertise once/second so I could easily watch it on the packet sniffer display.  Using simple observer I get 1% missing packets at best.  On average I am receiving around 6 ADV messages each second that are not from my peripheral (other things in the area such as phones, tv, etc..), however, this amount of traffic does not seem to cause an issue for the TI packet sniffer, so I wouldn't think it would be an issue for the simple observer either.  I have the peripheral and observer boards placed on a table a few inches from each other, so signal strength should not be an issue.  I have also removed all debug and console printf's to ensure that was not hurting, but no improvement seen.  Any other ideas?

    thx,

    Ed

  • Hi Ed,

    Can you use SMartRF Studio to test the packet error rate? www.ti.com/.../smartrftm-studio