0 Replies Latest reply on Jun 5, 2015 2:23 PM by OceanS_76

    BCM92073X BLE Profile Configuration

    OceanS_76

      Overview

      The BLE profile configuration structure BLE_PROFILE_CFG is used to configure parameters for WICED Smart device, such as advertising, connection, encryption, TX power level, find-me profile, led, buzzer and buttons. The structure BLE_PROFILE_CFG is defined in bleprofile.h. This document describes definition of parameters and gives some examples how to use them.

       

                    // BLE Profile Configuration
      typedef PACKED struct
      {
          UINT16 fine_timer_interval;                  // ms
          UINT8 default_adv;                              // default adv
          UINT8 button_adv_toggle;                    // pairing button make adv toggle (if 1) or always on (if 0)
          UINT16 high_undirect_adv_interval;      // slots
          UINT16 low_undirect_adv_interval;        // slots
          UINT16 high_undirect_adv_duration;      // seconds
          UINT16 low_undirect_adv_duration;      // seconds
          UINT16 high_direct_adv_interval;          // seconds
          UINT16 low_direct_adv_interval;            // seconds
          UINT16 high_direct_adv_duration;          // seconds
          UINT16 low_direct_adv_duration;          // seconds
          char local_name[LOCAL_NAME_LEN_MAX];
          char cod[COD_LEN];                            // First two bytes are used as appearance
          char ver[VERSION_LEN];
          UINT8 encr_required;                            // if 1, encryption is needed before sending indication/notification
          UINT8 disc_required;                            // if 1, disconnection after confirmation
          UINT8 test_enable;
          UINT8 tx_power_level;                          // dbm
          UINT8 con_idle_timeout;                        // second
          UINT8 powersave_timeout;                    // second
          UINT16 hdl[HANDLE_NUM_MAX];        // GATT HANDLE number
          UINT16 serv[HANDLE_NUM_MAX];      // GATT service UUID
          UINT16 cha[HANDLE_NUM_MAX];      // GATT characteristic UUID
          UINT8 findme_locator_enable;                // if 1 Find me locator is enable
          UINT8 findme_alert_level;                      // alert level of find me
          UINT8 client_grouptype_enable;            // if 1 grouptype read can be used
          UINT8 linkloss_button_enable;              // if 1 linkloss button is enable
          UINT8 pathloss_check_interval;            // second
          UINT8 alert_interval;                              // interval of alert
          UINT8 high_alert_num;                          // number of alert for each interval
          UINT8 mild_alert_num;                          // number of alert for each interval
          UINT8 status_led_enable;                      // if 1 status LED is enable
          UINT8 status_led_interval;                    // second
          UINT8 status_led_con_blink;                  // blink num of connection
          UINT8 status_led_dir_adv_blink;            // blink num of dir adv
          UINT8 status_led_un_adv_blink;            // blink num of undir adv
          UINT16 led_on_ms;                              // led blink on duration in ms
          UINT16 led_off_ms;                              // led blink off duration in ms
          UINT16 buz_on_ms;                              // buzzer on duration in ms
          UINT8 button_power_timeout;                // seconds
          UINT8 button_client_timeout;                // seconds
          UINT8 button_discover_timeout;            // seconds
          UINT8 button_filter_timeout;                  // seconds
      #ifdef BLE_UART_LOOPBACK_TRACE
          UINT8 button_uart_timeout;                    // seconds
      #endif
      }BLE_PROFILE_CFG;
      
      
      
      

      UINT16 fine_timer_interval

      Define the timeout of fine timer. The resolution of fine timer is 12.5ms, developer can define the timeout by multiplying 12.5ms, but max value is 1000ms.

      The application use the function bleprofile_regTimerCb to register the callback function of fine timer, use the function bleprofile_StartTimer/bleprofile_KillTimer to start/stop fine timer.

       

      UINT8  default_adv

      Define the default mode of discovery. The following definition of discovery mode is in bleprofile.h.

      //Discoverable mode
      enum ble_discover_mode
      {
          NO_DISCOVERABLE              = 0,
          LOW_DIRECTED_DISCOVERABLE    = 1,
          HIGH_DIRECTED_DISCOVERABLE  = 2,
          LOW_UNDIRECTED_DISCOVERABLE  = 3,
          HIGH_UNDIRECTED_DISCOVERABLE = 4,
          MANDATORY_DISCOVERABLE      = 0xFF, //without NVRAM checking and start high undirected advertising
      };
      
      
      
      

      All central devices can connect peripheral device if the peripheral device is set to undirected discovery mode, but only special central device can connect peripheral device if the peripheral device is set to directed discovery mode.

      The “default_adv” usually is used in function xxx_connDown, the following sample code is in bletime.c.

      void bletime_connDown(void)
      {
          …
          // Mandatory discovery mode
          if(bleprofile_p_cfg->default_adv == MANDATORY_DISCOVERABLE)
          {
              bleprofile_Discoverable(HIGH_UNDIRECTED_DISCOVERABLE, NULL);
          }
          // check NVRAM for previously paired BD_ADDR
          else
          {
              bleprofile_ReadNVRAM(VS_BLE_HOST_LIST, sizeof(BLEPROFILE_HOSTINFO), (UINT8 *)&bletime_hostinfo);
              bleprofile_Discoverable(bleprofile_p_cfg->default_adv, bletime_hostinfo.bdAddr);
          }
          …
      }
      
      
      
      

      UINT8  button_adv_toggle

      Enable or Disable the advertising toggle when BUTTON_DISCOVER pressed.

      If enable “button_adv_toogle”, the discover mode will be changed from HIGH_UNDIRECTED_DISCOVERABLE or LOW_UNDIRECTED_DISCOVERABLE  to NO_DISCOVERABLE when BUTTON_DISCOVER is pressed.

      The following reference code is in bleprofile.c.

      void bleprofile_ReadButton(void)
      {
                  ...
                  //BUTTON_DISCOVER is pressed
      
                  // application level overide
                  if (bleprofile_buttonfunctionCb)
                  {
                      if (bleprofile_buttonfunctionCb(BUTTON_DISCOVER))
                      {
                          TRACE(TRACE_INFO, MODULE_ID_BLEAPP, "Button function %d skipped", TVF_D(BUTTON_DISCOVER));
                          return;
                      }
                  }
                  …
                  if ((bleprofile_GetDiscoverable()!= HIGH_UNDIRECTED_DISCOVERABLE)      &&                                                                      (bleprofile_GetDiscoverable()!= LOW_UNDIRECTED_DISCOVERABLE))
                  {
      
                      //disconnect if connection exist
                      if (emconinfo_getState() == CONNECTION)
                      {
                          // We want to drop the connection.
                          // This will call bleprofile_connDown()
                          // This corner case is prevented by if (bleprofile_app_powersave == -1);
                          bleprofile_app_powersave = -1; //disable powersave defer
                          blecm_disconnect(BT_ERROR_CODE_CONNECTION_TERMINATED_BY_LOCAL_HOST);
                      }
      
                      bleprofile_Discoverable(HIGH_UNDIRECTED_DISCOVERABLE, NULL);
                  }
                  else if (bleprofile_p_cfg->button_adv_toggle)
                  {
                      bleprofile_Discoverable(NO_DISCOVERABLE, NULL);
                  }
                  …
      }
      
      
      
      

      UINT16 high_undirect_adv_interval

      UINT16 low_undirect_adv_interval

      Define the interval of undirected advertising. Unit is slot, 0.625ms per slot. The range of interval is from 20 ms to 10.24 s.

       

      UINT16 high_direct_adv_interval

      UINT16 low_direct_adv_interval 

      Define the interval of directed advertising. Unit is second.

       

      UINT16 high_undirect_adv_duration

      UINT16 low_undirect_adv_duration

      UINT16 high_direct_adv_duration

      UINT16 low_direct_adv_duration

      Define the duration of undirected or direct advertising. Unit is second.

       

      char local_name[LOCAL_NAME_LEN_MAX]

      Define the name of device. The name can be same with the UUID_CHARACTERISTIC_DEVICE_NAME definition in GATT DB, or be a shortened string from UUID_CHARACTERISTIC_DEVICE_NAME definition.

      The “local_name” usually is used in customized advertising.

       

      char cod[COD_LEN]

      Define the appearance of device. Please use the same value with the UUID_CHARACTERISTIC_APPEARANCE definition in GATT DB.

      The “cod” usually is used in customized advertising.

       

      char ver[VERSION_LEN]

      Define software version of application.


      UINT8 encr_required

      Define the encryption setting. The following definition of encryption is in bleprofile.h.

      #define SECURITY_ENABLED 0x01
      #define SECURITY_REQUEST 0x02
      
      
      
      

      Enable the encryption if the SECURITY_ENABLED bit is set.

      Send the encryption request by device when creating connection if the SECURITY_REQUEST bit is set.

      The following reference code is in blecgm.c.

      void blecgm_connUp(void)
      {
          …
          if((bleprofile_p_cfg->encr_required&SECURITY_REQUEST) == SECURITY_REQUEST)
          {
              lesmp_sendSecurityRequest();
          }
      }
      
      
      
      

      UINT8  disc_required

      Define the setting of disconnect. The following definition is in bleprofile.h.

      enum ble_disc_setting
      {
          DISC_NONE          = 0x00,
          DISC_AFTER_CONFIRM  = 0x01,
          DISC_ATT_TIMEOUT    = 0x02,
          DISABLE_ATT_TIMEOUT = 0x04,
      };
      
      
      
      
      • DISC_AFTER_CONFIRM

      If DISC_AFTER_CONFIRM bit is set, disconnect the connection when confirmed the indication had sent.

      The following sample code is in blews.c.

        void blews_IndicationConf(void)
      {
          …                                                                                        
          if((bleprofile_p_cfg->disc_required) & DISC_AFTER_CONFIRM)
          {
              if(blews_con_handle && blews_indication_enable && blews_measurement_done) 
              //Encryption and data measurement is done
              {
                  blecm_disconnect(BT_ERROR_CODE_CONNECTION_TERMINATED_BY_LOCAL_HOST);      
                  …
              }
          }
      }
      
      
      
      
      • DISC_ATT_TIMEOUT

      If DISC_ATT_TIMEOUT bit is set, disconnect the connection when ATT timeout.

      The following sample code is in blews.c.

      void blews_transactionTimeout(void)
      {
          ble_trace0("WS ATT timeout");
                                                                              
          if((bleprofile_p_cfg->disc_required) & DISC_ATT_TIMEOUT)
          {
              {
                  blecm_disconnect(BT_ERROR_CODE_CONNECTION_TERMINATED_BY_LOCAL_HOST);      
                  …
              }
          }
      }
      
      
      
      
      • DISABLE_ATT_TIMEOUT

      If DISABLE_ATT_TIMEOUT is set, disable the ATT timeout in communication.

      The following reference code is in bleprofile.c.

      void bleprofile_sendIndication(UINT16 attrHandle, UINT8 *attr, int len, LEATT_NO_PARAM_CB cb)
      {
          UINT8 data[LEATT_ATT_MTU];
          LEATT_PDU_INDICATION_HDR *msg = (LEATT_PDU_INDICATION_HDR *)data;
      
          //attrCode is written by leatt //UINT8  attrCode;    // 0x1d = Handle Value Indicataion
          msg->handle = attrHandle;
        memcpy((UINT8 *)(msg + 1), attr, len);
      
      
          if ((bleprofile_p_cfg->disc_required) & DISABLE_ATT_TIMEOUT)
          {
              leatt_setATTTimeout(0);
          }
      
          leatt_sendIndication(msg, len, cb);
      }
      
      
      
      

      UINT8  test_enable

      Developer can add special or test code under “test_enable” control.

       

      UINT8  tx_power_level

      Define the default TX power level of device. But TX power level can be changed by function blecm_setTxPowerInADV or blecm_setTxPowerInConnection.

       

      UINT8  con_idle_timeout

      Define the timeout of connect idle timer. No timeout if “con_idle_timeout” value is 0.

      Disconnect the connection if no communication between two BLE devices when connect idle timeout expires.

      The following reference code is in bleprofile.c.

      void bleprofile_connUp(void)
      {
          …
          if (bleprofile_p_cfg && bleprofile_p_cfg->con_idle_timeout)
          {
              emconinfo_setIdleConnTimeout(bleprofile_p_cfg->con_idle_timeout);
              blecm_startConnIdleTimer(bleprofile_appTimerCb);  
          }
          …
      }
      
      void bleprofile_appTimerCb( UINT32 arg)
      {
                            switch(arg)
                            {
                              …
                  case BLEAPP_APP_TIMER_CONN_IDLE:
                  {
                      int id = emconinfo_getAppTimerId();
                      if ( id >= 0 )
                      {
                          // we are going to stop the timer.
                          bleapptimer_stopAppTimer( id );
                          emconinfo_setAppTimerId(-1);
      
                          // We want to drop the connection.
                          blecm_disconnect(BT_ERROR_CODE_CONNECTION_TERMINATED_BY_LOCAL_HOST);
                      }
                  }
                  break;
          …
          }
      }
      
      
      
      

      UINT8  powersave_timeout

      Define the timeout of power save. No timeout if “powersave_timeout “ value is 0.

      If device no connection and no advertising, the device will enter power save mode when power-save timeout expires.

      Note: If “powersave_timeout” value isn’t 0, the function bleprofile_pollPowersave must be called in normal timer callback functions, because whether enter power save mode or not is implemented in function bleprofile_pollPowersave.

       

      UINT16 hdl[HANDLE_NUM_MAX]

      UINT16 serv[HANDLE_NUM_MAX]

      UINT16 cha[HANDLE_NUM_MAX]

      Used to store the handles in the GATT DB. These handles are used to operate the GATT DB item in application.

      The following sample code is in bleprox.c.

                //find the handle, and store it.
      void bleprox_DBInit(void)
      {
          …
          for (i = 0; i < HANDLE_NUM_MAX; i++)
      {
          …
              else if (bleprofile_p_cfg->serv[i] == UUID_SERVICE_IMMEDIATE_ALERT &&
                  bleprofile_p_cfg->cha[i]  == UUID_CHARACTERISTIC_ALERT_LEVEL)
              {
                  proxAppState->bleprox_ia_alt_hdl = bleprofile_p_cfg->hdl[i];
                  …
              }
              …
          }
      }
      
                  //use the handle to read the GATT DB
      void bleprox_CheckPathLoss(void)
      {
          BLEPROFILE_DB_PDU db_pdu;
          int result;
      
              result = bleprofile_ReadHandle(proxAppState->bleprox_ia_alt_hdl, &db_pdu);
              …
          }
      
      
      
      

      UINT8  findme_locator_enable

      Enable or Disable find-me profile. The find-me profile is realized in ROM code.

      If the bit0 of “findme_locator_enable” is 1, the ROM find-me profile is used to find the peer device.

      If the bit1 of “findme_locator_enable” is 1, enable the find-me alert toggle.

      The sample code , please refer to proximity_plus.c in SDK1.1.0.

       

      UINT8  findme_alert_level

      Define the alert level of find-me profile.

      The following definition is in bleprox.h.

      //Alert mode
      enum ble_prox_alert_level
      {
          NO_ALERT                        = 0,
          MILD_ALERT                      = 1,
          HIGH_ALERT                      = 2,
       UNDIRECTED_DISCOVERABLE_ALERT  = 3,
      };
      
      
      
      

      UINT8  client_grouptype_enable

      Enable or Disable the group type request when locating the find-me handle of peer device.

      Locate the find-me handle of peer device by group-type request if “client_grouptype_enable” is set, locate the find-me handle of peer device by type request if “client_grouptype_enable” is clear.

      The following reference code is in blefind.c.

      void blefind_FindmeReq(void)
      {
          if (bleprofile_p_cfg->findme_locator_enable)
          {
                    …
                  if (bleprofile_p_cfg->client_grouptype_enable)
                  {
                      bleprofile_sendReadByGroupTypeReq(findAppState->blefind_s_handle, findAppState->blefind_e_handle,
                      UUID_ATTRIBUTE_PRIMARY_SERVICE);
                  }
                  else
                  {
                      bleprofile_sendReadByTypeReq(findAppState->blefind_s_handle, findAppState->blefind_e_handle,
                      UUID_ATTRIBUTE_PRIMARY_SERVICE);
                  }
                  …
          }
          }
      
      
      
      

      UINT8  linkloss_button_enable

      Enable or Disable link-loss button.

      The sample code refers to bleprox.c.

       

      UINT8  pathloss_check_interval

      Define the interval of checking path loss, unit is second.

      The sample code refers to bleprox.c.

       

      UINT8  alert_interval

      Define the interval of device alert.

      Usually use the LED or Buzzer to do an alert. The sample code refers to bleprox.c.

       

      UINT8  high_alert_num

      UINT8  mild_alert_num

      Define the alert number for high or middle alert.

      The sample code refers to bleprox.c.

       

      UINT8  status_led_enable

      Enable or Disable status LED. The status LED is used to indicate device status, such as advertising or connection.

      The sample code refers to bleprox.c.

       

      UINT8  status_led_interval

      Define the blink interval of status LED. Unit is second.

       

      UINT8  status_led_con_blink

      Define the blink number of status LED when device is in connection state.

       

      UINT8  status_led_dir_adv_blink

      UINT8  status_led_un_adv_blink

      Define LED blink number of status LED when device is sending undirected or direct advertising.

       

      UINT16 led_on_ms

      UINT16 led_off_ms

      Define the duration of LED on or off when LED blink.

       

      UINT16 buz_on_ms

      Define the duration of buzzer on.

      UINT8 button_power_timeout

      UINT8 button_client_timeout

      UINT8 button_discover_timeout

      UINT8 button_filter_timeout

      UINT8 button_uart_timeout

      Define the timeout of BUTTON_POWER, BUTTON_CLIENT, BUTTON_DISCOVER, BUTTON_FILTER and BUTTON_UART.

      The BUTTON_XXX is generated by long pressing the GPIO_BUTTON. For example, if the “button_power_timeout” value is 3, will detect the BUTTON_POWER is pressed when holding GPIO_BUTTON >3S.

      Note: Must call the function bleprofile_ReadButton in fine timer callback function, because checking whether BUTTON_XXX is pressed or not in the function bleprox_ProxButton by polling.

      The following sample code is in bleprox.c.

      PLACE_IN_DROM const BLE_PROFILE_CFG bleprox_cfg =
      {
          …
          /*.button_power_timeout      =*/ 1,    // seconds
          /*.button_client_timeout        =*/ 3,    // seconds
          /*.button_discover_timeout    =*/ 5,  // seconds
          /*.button_filter_timeout          =*/ 10, // seconds
      #ifdef BLE_UART_LOOPBACK_TRACE
          /*.button_uart_timeout            =*/ 15,  // seconds
      #endif
      };                   
      
      void bleprox_Create(void)
      {
          …
          bleprofile_regButtonFunctionCb(bleprox_ProxButton);
          …
      }
      
      void bleprox_FineTimeout(UINT32 finecount)
      {
          …
          bleprofile_ReadButton();
          …
      }
      
      UINT32 bleprox_ProxButton(UINT32 function)
      {
          …
          if (function == BUTTON_PRESS)
      {
          …
          }
          else if (function == BUTTON_RELEASE)
          {
              …
          }
          else if (function == BUTTON_POWER)
      {
          …
          }
      else if (function == BUTTON_CLIENT)
      {
          …
      }
          else if (function == BUTTON_DISCOVER)
      {
          …
      }
          …
          return 0;
      }
      
      
      
      

      The source code of function bleprofile_ReadButoon is in bleprofile.c, please see the follow reference code to get more information. When detecting the BUTTON_XXX is pressed, call the button callback function that registered by function  bleprofile_regButtonFunctionCb, then do the actions if button callback function return 0, or do nothing if button callback function return 1.

      void bleprofile_ReadButton(void)
      {
          …    
      //button pressed
      {
              …
                  // application level overide
                  if (bleprofile_buttonfunctionCb)
                  {
                      if (bleprofile_buttonfunctionCb(BUTTON_PRESS))
                      {
                          return;
                      }
                  }
                  bleprofile_LEDOn();
                  bleprofile_BUZBeep(bleprofile_p_cfg->buz_on_ms*2);
                …
        }
      
        …
        //button released
        { …
                      // application level overide
                      if (bleprofile_buttonfunctionCb)
                      {
                          if (bleprofile_buttonfunctionCb(BUTTON_RELEASE))
                          {
                              return;
                          }
                      }
                      bleprofile_LEDOff();
                  }
                  …
                            }
      
          …
      // button discover 
      {
              if (bleprofile_p_cfg->button_discover_timeout &&
                bleprofile_button_count >= bleprofile_p_cfg->button_discover_timeout * call_per_sec &&
                bleprofile_button_count <= (bleprofile_p_cfg->button_discover_timeout + 1) * call_per_sec)
              {
                  // application level overide
                  if (bleprofile_buttonfunctionCb)
                  {
                      if (bleprofile_buttonfunctionCb(BUTTON_DISCOVER))
                      {
                          return;
                      }
                  }
                  …
      
                  if ((bleprofile_GetDiscoverable()!= HIGH_UNDIRECTED_DISCOVERABLE) &&
                              (bleprofile_GetDiscoverable()!= LOW_UNDIRECTED_DISCOVERABLE))
                  {
                      //disconnect if connection exist
                      if (emconinfo_getState() == CONNECTION)
                      {
                          …
                          blecm_disconnect( BT_ERROR_CODE_CONNECTION_TERMINATED_BY_LOCAL_HOST);
                      }
                      bleprofile_Discoverable(HIGH_UNDIRECTED_DISCOVERABLE, NULL);
                  }
                  else if (bleprofile_p_cfg->button_adv_toggle)
                  {
                      bleprofile_Discoverable(NO_DISCOVERABLE, NULL);
                  }
              }
              …
        }