11 Replies Latest reply on Oct 3, 2017 11:41 AM by e.pratt_1639216

    Help with Dynamic Broadcaster

    user_478787221

      I have seen the day 9 project, Dynamic Broadcaster, but still need assistance with its implementation. This partly may be a C Language issue but an understanding of the use of CyBle_GapUpdateAdvData is also lacking.

       

      I successfully enter broadcasting mode (Broadcaster shows up under scan by CySmart 1.2), but with dynamic broadcasting I want to add and modify the Scan Response Packet each time.  Not only with this snippet of code do I NOT create a Scan Response Packet (cannot be seen under CySmart 1.2 scan response data tab) but I also lose my Broadcaster Label - Public identifier-and revert to the Advertiser Label of BLE Serial.

       

      Note that both my ScanData.scanRspDataLen variable and ScanData.scanRspData array fill out with the correct data.

       

      void DynamicADVPayloadUpdate(char *p, uint16 DataLength)

      {

          uint16  i;

          CYBLE_GAPP_SCAN_RSP_DATA_T ScanData;

          uint8 test;

       

          memset(ScanData.scanRspData,0,N_COUNT);

       

          ScanData.scanRspDataLen = DataLength;

          for(i=0; i < ScanData.scanRspDataLen; i++)

              ScanData.scanRspData[i] = *(p+i);

          

          if(CyBle_GetBleSsState() == CYBLE_BLESS_STATE_EVENT_CLOSE)

          {

       

           CyBle_GapUpdateAdvData(cyBle_discoveryModeInfo.advData, &ScanData);

           test = 1;

         

          }//end if(CyBle_GetBleSsState()

      }

       

      *****************************************

      If I replace the code above with this code, I resolve the issue having to do with losing the broadcaster label, but I still see nothing under the Scan Response Data Tab.

       

      void DynamicADVPayloadUpdate(char *p, uint16 DataLength)

      {

          uint16  i;

          CYBLE_GAPP_SCAN_RSP_DATA_T ScanData;

          uint8 test;

       

               memset(ScanData.scanRspData,0,31);

        

          ScanData.scanRspDataLen = DataLength;

         // for(i=0; i < ScanData.scanRspDataLen; i++)

         //     ScanData.scanRspData[i] = *(p+i);

           

           

            /* Define the Broadcast advertisement parameters - including the BD address,

           * advertisement type, advertisement interval etc.

           */

       

         CYBLE_GAPP_DISC_PARAM_T myAdvParameters =

          {

              // Minimum Advertisement interval = 100 ms

              CYBLE_GAP_ADV_ADVERT_INTERVAL_NONCON_MIN,

           

              // Maximum Advertisement interval = Minimum = 100 ms

              CYBLE_GAP_ADV_ADVERT_INTERVAL_NONCON_MIN,

           

              // Advertisement type - Non-connectable undirected (broadcasting)

              CYBLE_GAPP_NON_CONNECTABLE_UNDIRECTED_ADV,

           

              // Own BD address type - Public

              CYBLE_GAP_ADDR_TYPE_PUBLIC,

           

              // Address type of peer for directed advertisement - not applicable

              CYBLE_GAP_ADDR_TYPE_PUBLIC,

           

              // Address for directed advertisement - not applicable

              {0},     

           

              // Channel map - advertise on all 3 channels

              0x07,    

           

              // Advertisement filter policy - not applicable

              0        

          };

       

       

          // Define the advertisement data for the broadcast - this includes the

          // advertisement flags and the device name advertised. The device name

          // used for Broadcasting is different from the device name used when

          // we want to connect to another device.

          //

          CYBLE_GAPP_DISC_DATA_T myAdvData =

          {

              {

                  2,      // Length for Flags field - Counts as 1 Byte

                  1,      // Identifier that following data is Flags field - Counts as 1 Byte

                  4,      // Advertisement Flags - BR/EDR not supported - Counts as 1 Byte

                  12,     // Length for Complete Name field - Counts as 1 Byte

                  0x09,   // Identifier that following data is Complete Name field - plus 12

               

                  // Name

                  'B', 'r', 'o', 'a', 'd', 'c', 'a', 's', 't', 'e', 'r'

              },

              16          // Total bytes in the advertisement packet

          };

       

          // There is no scan response data configured for this broadcast

          CYBLE_GAPP_SCAN_RSP_DATA_T myScanRespData =

          {

              {*p,*(p+1),*(p+2),*(p+3),*(p+4),*(p+5),*(p+6),*(p+7),*(p+8),*(p+9),*(p+10),*(p+11),*(p+12),\

              *(p+13),*(p+14),*(p+15),*(p+16),*(p+18),*(p+19),*(p+20),*(p+21),*(p+22),*(p+23),*(p+24),*(p+25),\

              *(p+26),*(p+27),*(p+28),*(p+29),*(p+30),*(p+31)},        // Scan response packet

              ScanData.scanRspDataLen           // Length of the scan response packet

          };

       

          // Top level structure for holding all advertisement parameters

          CYBLE_GAPP_DISC_MODE_INFO_T discoveryModeInfo =

          {

              CYBLE_GAPP_NONE_DISC_BROADCAST_MODE,   // Discoverable mode

              &myAdvParameters,                      // Advertisement parameters

              &myAdvData,                            // Advertisement data

              &myScanRespData,                       // Scan response data

              0                                      // Advertisement timeout: none

          }; 

            

          if(CyBle_GetBleSsState() == CYBLE_BLESS_STATE_EVENT_CLOSE)

          {

           CyBle_GapUpdateAdvData(discoveryModeInfo.advData,discoveryModeInfo.scanRspData);

             //CyBle_GapUpdateAdvData(cyBle_discoveryModeInfo.advData,&ScanData);

          test = 1;

           

          }//end if(CyBle_GetBleSsState()

      }

       

      *****************************

       

      I think I see one of the mistakes I am making.   The Scan Response Packet is not a blind 31 byte field.  It needs to be cast in one of the categories provided, like Manufacturer Specific Data.  Correct?  If this is the case, how do assign the data array to the Manufacturing Index?  Your example requires only a single byte assignment to the manufacturing index.  (eg, advPayload[MANUFACTURER_SPECIFIC_DYNAMIC_DATA_INDEX] = dynamicPayload++;, < 255).   However, the ScanRespPayload will contain an array of data.

        • 1. Re: Help with Dynamic Broadcaster
          e.pratt_1639216

          BLEScanResponseDataPacketExample.PNG

          The above image is an example of the scan response data array of data as seen from the BLE component editor.

          The value and indices on the right are the ones you are looking for/need to set/change for programmatically updating the advertisement data.

           

          CYBLE_GAPP_SCAN_RSP_DATA_T scanrsp; //declaration of scan response data array

          CYBLE_GAPP_DISC_MODE_INFO_T Mode;

          CYBLE_GAPP_DISC_PARAM_T Param;

           

          Param.advChannelMap = 7;//Use all three channels

          Param.advFilterPolicy = CYBLE_GAPP_SCAN_ANY_CONN_ANY;

          Param.advIntvMax = cyBle_discoveryModeInfo.advParam->advIntvMax;

          Param.advIntvMin = cyBle_discoveryModeInfo.advParam->advIntvMin;

          Param.advType = 00;

          memset(Param.directAddr, 0x00, 6);

          Param.ownAddrType = CYBLE_GAP_ADDR_TYPE_PUBLIC;

           

          Mode.advData = &advrsp;

          Mode.advParam = &BondingParam;

          Mode.advTo = 00;

          Mode.discMode = CYBLE_GAPP_GEN_DISC_MODE;

          Mode.scanRspData = &scanrsp;

           

          scanrsp.scanRspData[0] = 0x05;//protocol defines that the first byte is the length of the advertisement field

          scanrsp.scanRspData[1] = 0x09;//Protocol defined constant that signifies which formate/service the data is

          scanrsp.scanRspData[2] = 'T';//Our advertisement data

          scanrsp.scanRspData[3] = 'E';

          scanrsp.scanRspData[4] = 'S';

          scanrsp.scanRspData[5] = 'T';

          scanrsp.scanRspDataLen = 6; //length of the raw number of bytes in the array of data

          The above code snippet shows the data structures and data initialization for the advertisement packets; Of course you will want to change the actual data and the location of the different parts for your needs.

          Let me know if you have questions on parts of the code; I grabbed some of it from cypress examples/code and didn't bother to comment them due to the comments in the API libraries being sufficient.

           

          Regards,

          Epratt

          • 2. Re: Help with Dynamic Broadcaster
            user_478787221

            Can I use the Scan Response packet as a free 31 byte array for data, or must the data be caste in the framework of categories, such as Local Address, Manufacturer Specific Data, etc.?

            • 3. Re: Help with Dynamic Broadcaster
              user_478787221

              My code is not much different than what you provided.   However, a key difference is that I do not tailor the Scan Response Packet to pre-existing categories, and this is what might be hurting me.   I am simply sending, for example, the string ABC, so while my ScanRespPacket sees this string and get the packet length correct, the data may not be allocated correctly.  I do not see anything under Cysmart 1.2, with the ScanResponseData tab.

               

              If I am to assign data to manufacturing data,  how do I go about this?  Let’s say I am using Cypress as the ID (28u).  I want to pass ‘ABC’ to that manufacturer with index 28.  What would the structure of code look like?

               

              Thanks

               

              void DynamicADVPayloadUpdate(char *p, uint16 DataLength)

              {

                  uint16  i;

                  CYBLE_GAPP_SCAN_RSP_DATA_T ScanData;

                  uint8 test;

               

               

               

               

                 // for(i=0; i < ScanData.scanRspDataLen; i++)

                 //     ScanData.scanRspData[i] = *(p+i);

               

               

                    /* Define the Broadcast advertisement parameters - including the BD address,

                    

              • advertisement type, advertisement interval etc.

                   */

                 CYBLE_GAPP_DISC_PARAM_T myAdvParameters =

                  {

                      // Minimum Advertisement interval = 100 ms

                      CYBLE_GAP_ADV_ADVERT_INTERVAL_NONCON_MIN,

               

                      // Maximum Advertisement interval = Minimum = 100 ms

                      CYBLE_GAP_ADV_ADVERT_INTERVAL_NONCON_MIN,

               

                      // Advertisement type - Non-connectable undirected (broadcasting)

                      //CYBLE_GAPP_NON_CONNECTABLE_UNDIRECTED_ADV,

                      CYBLE_GAPP_SCANNABLE_UNDIRECTED_ADV,

               

                      // Own BD address type - Public

                      CYBLE_GAP_ADDR_TYPE_PUBLIC,

               

                      // Address type of peer for directed advertisement - not applicable

                      CYBLE_GAP_ADDR_TYPE_PUBLIC,

               

                      // Address for directed advertisement - not applicable

                      {0},

               

                      // Channel map - advertise on all 3 channels

                      0x07,

               

                      // Advertisement filter policy - not applicable

                      0

                  };

               

                  // Define the advertisement data for the broadcast - this includes the

                  // advertisement flags and the device name advertised. The device name

                  // used for Broadcasting is different from the device name used when

                  // we want to connect to another device.

                  //

                  CYBLE_GAPP_DISC_DATA_T myAdvData =

                  {

                      {

                          2,      // Length for Flags field - Counts as 1 Byte

                          1,      // Identifier that following data is Flags field - Counts as 1 Byte

                          4,      // Advertisement Flags - BR/EDR not supported - Counts as 1 Byte

                          12,     // Length for Complete Name field - Counts as 1 Byte

                          0x09,   // Identifier that following data is Complete Name field - plus 12

               

                          // Name

                          'B', 'r', 'o', 'a', 'd', 'c', 'a', 's', 't', 'e', 'r'

                      },

                      16          // Total bytes in the advertisement packet

                  };

               

               

                  memset(ScanData.scanRspData,0,31);

                  for(i=0; i < ScanData.scanRspDataLen; i++)

                      ScanData.scanRspData[i] = *(p+i);

               

                  ScanData.scanRspDataLen = DataLength;

               

                  // Top level structure for holding all advertisement parameters

                 CYBLE_GAPP_DISC_MODE_INFO_T discoveryModeInfo =

                  {

                      CYBLE_GAPP_NONE_DISC_BROADCAST_MODE,   // Discoverable mode

                      &myAdvParameters,                      // Advertisement parameters

                      &myAdvData,                            // Advertisement data

                      &ScanData,                             // Scan response data

                      0                                      // Advertisement timeout: none

                  };

               

               

                  if(CyBle_GetBleSsState() == CYBLE_BLESS_STATE_EVENT_CLOSE)

                  {

                   CyBle_GapUpdateAdvData(discoveryModeInfo.advData,discoveryModeInfo.scanRspData);

                     //CyBle_GapUpdateAdvData(cyBle_discoveryModeInfo.advData,&ScanData);

                  test = 1;

               

                  }//end if(CyBle_GetBleSsState()

              }

              • 4. Re: Help with Dynamic Broadcaster
                e.pratt_1639216

                You don't have to use the data structure for working with the array iirc. But, you will want to use the length and type bytes at the beginning of the field in order for other bluetooth devices to properly parse your data for reading/usage.

                If you are developing both halves of the connection, then you can probably get away without using categories, but otherwise I would strongly recommend following the category format to allow other devices to interpret the data.

                • 5. Re: Help with Dynamic Broadcaster
                  e.pratt_1639216

                  The CySmart app uses the category bytes to format the output; You can still see the raw scan response packet data, but it will only show up in the "raw data" window of the CySmart app.

                  Ideally, the manufacturing category would be the best use for having custom data/format/fields. That way other devices won't expect it to be, say, a local name or something else and interpret it as such.

                  For setting up a manufacturer specific field:

                  <Length Byte>

                  <0xFF> (signifies a manufacturer specific data)

                  <2-Byte company ID> (0xFF,0xFF is the "Other" field)

                  Then follow with the custom data you have.

                  If you only have this field, you can get 28 bytes of data for the Custom Manufacturer Data Field. Otherwise, there will be lost bytes to overhead for each designated field. (I'm not sure if regular bluetooth has larger advertising packets or not).

                  • 6. Re: Help with Dynamic Broadcaster
                    user_478787221

                    OK, that helped.  Thanks!   I see the raw data but do not see it formatted as you suggested

                     

                     

                    //DataLength

                        ScanData.scanRspDataLen = DataLength + 3;

                     

                        memset(ScanData.scanRspData,0,31);

                        //Data Must be correctly parsed

                        ScanData.scanRspData[0] = 0xFF;     //Indicates Manufacturer Specific Data

                        ScanData.scanRspData[1] = 0x31;     //Next Two Bytes Point to Cypress Semi

                        ScanData.scanRspData[2] = 0x01;

                        for (i=3; i < ScanData.scanRspDataLen; i++)

                            ScanData.scanRspData[i] = *(p+i-3);

                     

                     

                     

                    • 7. Re: Help with Dynamic Broadcaster
                      user_478787221

                      One more question about cysmart.   I appears that if I send successive broadcasts, the Cysmart does not automatically refresh the raw data field.  It appears that I need to re-scan and then click again on my Device field to get updated values.  Does this make sense to you?

                      • 8. Re: Help with Dynamic Broadcaster
                        e.pratt_1639216

                        FormatvsRawData.PNG

                        There are just two windows showing the raw data, and the data organized by field.

                        • 9. Re: Help with Dynamic Broadcaster
                          e.pratt_1639216

                          The advertisement data is only physically received from the device while the scanning is active; Once you click Stop Scan the dongle will no longer update the advertisement data last seen for the device.

                          (Also of note, but not directly related I think is the setting under Configure Master Settings->Scan Parameters->Duplicate Filter Policy; Turning this off will allow multiple advertisement packets with the same data to show up in the Log at the bottom of the screen.)

                          • 10. Re: Help with Dynamic Broadcaster
                            user_478787221

                            To be more precise, I see the advertisement data as raw AND formatted, but only see the raw scan data (no formatting).  But I believe you said that is what I should expect.

                            • 11. Re: Help with Dynamic Broadcaster
                              e.pratt_1639216

                              Ah; So you are referring to the Scan response data window. I don't remember how the window normally looks. I think it should be showing up formatting if you use the example cypress peripheral programs; Otherwise, just going off of the custom data formats, I don't think it would be showing up in the formatted/description section.

                               

                              Regards,

                              Epratt