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.

how to only listen for advertising packets, and receive payload data?

now I have managed to get the simpleperipheral project modified to send adc data in advetising packet payload:

unit16 adc;

GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( uint16 ), &adc);

and then enable advertising for 1s by

      uint8 current_adv_enabled_status;

      //Find the current GAP advertisement status
      GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, &current_adv_enabled_status );

      if( current_adv_enabled_status != TRUE )
      {
        //change the GAP advertisement status advertising

       uint8 new_adv_enabled_status = TRUE;
        GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &new_adv_enabled_status );
      }

packet sniffer show the payload of the advertising packet as expected.

now I want to know how to modify the SimpleBLEObserver, to get the payload back to a variable:

unit16 adc;

thanks a lot any one could help!

  • If you look at the call back function smipleBLEObserverEventCB() you'll see a handle for a GAP_DEVICE_INFO_EVENT. This event occurs when you discover a new adv device and currently the handler only stores addr and addr type of that device for use later and doesn't do anything with the actual data rx'ed in the packet. It's here that you'll want to access the adv data.

    When receiving a device info event, the argument of the call back function pEvent is of type gapDeviceInfoEvent_t (gapObserverRoleEvent_t is  a union). Check out the definition of that struct in gap.h and you'll see it has fields dataLen and *pEvtData. The adv data will be in pEvtData.

    -Matt

  • Matt, thank you so much!

    what is needed for a GAP_DEVICE_INFO_EVENT to show up as a GAP event?

        case GAP_DEVICE_INFO_EVENT:
          {
            adc = *((uint16 *)(pEvent->deviceInfo.pEvtData));
            simpleBLEAddDeviceInfo( pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType );
          }
          break;

    when debug with break point, the oberver seems never reach this part of code.

    UP key to scan make it reached the point,  and adc value is as advertised. is passive scan only turn on the RF receiver and start to receive any advertising packet?

    is it possible to automatically continuously passive scan without pushing the UP key? will this catch every duplicate packet or duplicate packets are suppressed?  to make broadcaster advertis more frequently or make observer scan more frequently, which saves more battery power? is it possible for observer detect broadercaster advertising interval and get observer syncronized with broadcaster to save battery power?

  • The observer will only reach that part of the code when advertising is enabled so it makes sense that you don't hit the break point until you enable adversiting. You receive a device info event for every adv packet that is received that is not a duplicate of one you have already rx'ed. This means if the data in the packet is changed but is from the same addr you've already had an info event for you will still receive a new info event (you'll see simpleBLEAddDeviceInfo() will ignore duplicate devices for the device list if you look into that function).  

    With passive scanning there will be no transmitted packets from the central device. You can begin advertising w/o a button press if you move the StartDiscovery() call from the key press handle (HandleKeys()) to the end of the START_DEVICE_EVT handler.

    For the most part BLE prioritizes power savings of the peripheral/broadcaster device as opposed to the central/broadcaster device. I would probably increase the scan window of your cent/broadcaster device first if you need better performance. If you need to save power you can also limit the number of channels over which you are adv. on.

    It may be possible to synchronize the scans with the broadcasts of one pair of devices but you would not be able to synchronize the advertisements of two broadcasters. So if you had multiple broadcasters to a single observer you would still potentially require a large scan window.

    -Matt

  • http://e2e.ti.com/support/wireless_connectivity/f/538/t/338212.aspx

    |<Scan Win 5ms>        Scan Interv 15ms              >(xN)<Scan Wind 5ms>        Scan Interv 15ms              >|

    Where everything between || is the scan duration, the scan interval is the time between starting active scan and scan window is how long the scan is active.

    http://e2e.ti.com/support/wireless_connectivity/f/538/p/284084/1000001.aspx#1000001

    1) Scan duty cycle is not 100%. Set this to 100% by calling
    GAP_SetParamValue( TGAP_GEN_DISC_SCAN_INT, 16); 
    GAP_SetParamValue( TGAP_GEN_DISC_SCAN_WIND, 16);  

    Or _LIM_ if you are scanning for limited.

    2) Maybe your processing takes up too much time, so that it nevertheless will never be 100% duty cycle scanning.
    Enable CPU during RF events (scan included) by calling
    HCI_EXT_HaltDuringRfCmd(HCI_EXT_HALT_DURING_RF_DISABLE); 

  • ke fan,

    I see that you have successfully managed to update the advertising packets with the code you listed. I was wondering if you were obtaining this data via UART/SPI as I saw some of your earlier posts.

    I am trying to obtain a defined number of bytes via SPI and update the advertData in this way. If it is expecting constant values can you suggest how I might go about accomplishing this?

    Basically I am asking how can I store a new valid form of advertData from my SPI data before updating the advertised data using the GAPRole_SetParameter()  in the way that you did?

    Thanks in advance!

  • to collect uint16 data from ADC,  just use the uint16 as whole advertisement payload data, not following any BLE regulated format to save battery power. the data is obtained via none-standard SPI. data signal read from a GPIO port by DMA and clock signal generated using Timers. 

    if your data length is no more than 31 bytes, you can store it in a block of continous memory such as "uint8 yourdata[len]"

    if more than 31 bytes,  it need to be  segmented into packets of 31 bytes or less, and each segment need to be advertised in sequence.some sequence information might be needed in the advertimesment payload to reasemble the packets back to whole data.

  • Thanks for the reply.

    I'm actually doing the second method that you attempted "uint8 yourdata [len].

    The problem is that I am embedding this code into the SimpleBLEBroadcaster example, so I know there have been a number of forums where having Rf active halts the cpu and causes the data to be corrupted. In this example where the Rf is continuously active I believe that is why I am receiving corrupted data

    Ex. rxBuffer = {0xff, 0xff, ....}

    Is it possible to explain where to look or if this could be my problem? I have seen the HCI_Halt_Disable command but not sure how it is best implemented.

  • I actually got this working thanks in part to your posting. I am now trying to do the same by reading in the advertisement packets on the observer side.

    In the case GAP_DEVICE_INFO_EVENT: I am pointing to pEvent->deviceInfo.pEvtData and trying to dynamically store the advPacket into me receivedData array.

    I'm trying to read in the array of data that I am sending, but can only seem to capture the first byte. Have you or anybody else gotten this to work?

  • Where is it a good place to update the advertisement data? the performPeriodicTask? or under the GAPROLE_ADVERTISING case?
    and if I'm using the 1.4 version, is it enough to just call GAPRole_SetParameter(GAPROLE_ADVERT_DATA,...) ?
    Or, do I have to switch advertising off, update the advertisement data, and switch it back on?

  • It really just depends at which point in the program you would like to update your advertising parameters. I don't know what your application is or which project so hard to say. If you're using a periodic task that might be the place to do all of your updating depending on where you are getting your data from to advertise.

    From my understanding it is in simpleBLEBroadcaster that you have to make the changes to the header file (which I had to do) since it has not been updated, but if you're using Peripheral it should be ok to just call SetParameter and it will correctly update your advertisement data.