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