Esempio n. 1
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      startAdvertising
 *
 *  DESCRIPTION
 *      This function is called to start advertisements.
 *
 *      Advertisement packet will contain Flags AD and Manufacturer-specific
 *      AD with Manufacturer id set to CSR and payload set to the value of
 *      the User Key 0. The payload size is set by the User Key 1.
 *
 *      +--------+-------------------------------------------------+
 *      |FLAGS AD|MANUFACTURER AD                                  |
 *      +--------+-------------------------------------------------+
 *       0      2 3
 *
 *  RETURNS
 *      Nothing.
 *
 *---------------------------------------------------------------------------*/
static void BeaconInit(void)
{
    uint8 filler;
    uint16 advInterval;
    uint8 advPayloadSize;
    ls_addr_type addressType = ls_addr_type_public;     /* use public address */
    
    /* initialise values from User CsKeys */
    
    /* read User key 0 for the payload filler */
    filler = (uint8)(CSReadUserKey(0) & 0x00FF);
    
    /* read User key 1 for the payload size */
    advPayloadSize = (uint8)(CSReadUserKey(1) & 0x00FF);
    
    /* range check */
    if((advPayloadSize < 1) || (advPayloadSize > MAX_ADVERT_PAYLOAD_SIZE))
    {
        /* revert to default payload size */
        advPayloadSize = DEFAULT_ADVERT_PAYLOAD_SIZE;
    }
    
    /* read User key 2 for the advertising interval */
    advInterval = CSReadUserKey(2);


    /* range check */
    if((advInterval < MIN_ADVERTISING_INTERVAL) ||
       (advInterval > MAX_ADVERTISING_INTERVAL))
    {
        /* revert to default advertising interval */
        advInterval = DEFAULT_ADVERTISING_INTERVAL;
    }

    /* read address type from User key 3 */
    if(CSReadUserKey(3))
    {
        /* use random address type */
        addressType = ls_addr_type_random;

        /* generate and set the random address */
        appSetRandomAddress();
    }

    /* set the GAP Broadcaster role */
    GapSetMode(gap_role_broadcaster,
               gap_mode_discover_no,
               gap_mode_connect_no,
               gap_mode_bond_no,
               gap_mode_security_none);
    
    /* clear the existing advertisement data, if any */
    LsStoreAdvScanData(0, NULL, ad_src_advertise);

    /* set the advertisement interval, API accepts the value in microseconds */
    GapSetAdvInterval(advInterval * MILLISECOND, advInterval * MILLISECOND);
    
}
Esempio n. 2
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      startBeaconing
 *
 *  DESCRIPTION
 *      This function is called to start beacon advertisements
 *
 *  RETURNS
 *      Nothing.
 *
 *---------------------------------------------------------------------------*/
void startBeaconing(void)
{
    uint8 advData[BEACON_ADVERT_SIZE];
    uint16 offset = 0;
    
    /* set the GAP Broadcaster role */
    GapSetMode(gap_role_broadcaster,
               gap_mode_discover_no,
               gap_mode_connect_no,
               gap_mode_bond_no,
               gap_mode_security_none);
    
    /* clear the existing advertisement data */
    LsStoreAdvScanData(0, NULL, ad_src_advertise);

    /* set the advertisement interval */
    GapSetAdvInterval(BEACON_ADVERTISING_INTERVAL_MIN, BEACON_ADVERTISING_INTERVAL_MAX);
    
    /* store the manufacturing data */
    advData[offset++] = AD_TYPE_MANUF;

    /* Apple company code, little endian */
    advData[offset++] = 0x4C;
    advData[offset++] = 0x00;
    
    advData[offset++] = 2;         /* Magic number */
    advData[offset++] = 0x15;      /* Length of the beacon payload */
    
    /* Beacon UUID */
    MemCopy(advData + offset, g_app_data.uuid, sizeof(g_app_data.uuid));
    offset += sizeof(g_app_data.uuid);

    /* Beacon major */
    advData[offset++] = WORD_MSB(g_app_data.major);
    advData[offset++] = WORD_LSB(g_app_data.major);
    
    /* Beacon minor */
    advData[offset++] = WORD_MSB(g_app_data.minor);
    advData[offset++] = WORD_LSB(g_app_data.minor);

    /* Beacon TX Power */
    advData[offset++] = g_app_data.txPower;

    /* store the advertisement data */
    LsStoreAdvScanData(BEACON_ADVERT_SIZE, advData, ad_src_advertise);
    
    /* Start broadcasting */
    LsStartStopAdvertise(TRUE, whitelist_disabled, ls_addr_type_random);
}
Esempio n. 3
0
static void gattSetAdvertParams(bool fast_connection,
                                                gap_mode_connect connect_mode)
{
    uint8 advert_data[MAX_ADV_DATA_LEN];
    uint16 length;
    uint32 adv_interval_min = RP_ADVERTISING_INTERVAL_MIN;
    uint32 adv_interval_max = RP_ADVERTISING_INTERVAL_MAX;
    int8 tx_power_level; /* Unsigned value */
    gap_mode_discover discover_mode = gap_mode_discover_limited;
    TYPED_BD_ADDR_T temp_addr;

    /* A variable to keep track of the data added to AdvData. The limit is
     * MAX_ADV_DATA_LEN. GAP layer will add AD Flags to AdvData which is 3
     * bytes. Refer BT Spec 4.0, Vol 3, Part C, Sec 11.1.3.
     */
    uint16 length_added_to_adv = 3;
    uint16 length_added_to_scan = 0;
    
    /* Tx power level value prefixed with 'Tx Power' AD Type */
    uint8 device_tx_power[TX_POWER_VALUE_LENGTH] = {
                AD_TYPE_TX_POWER};
    
    uint8 device_appearance[ATTR_LEN_DEVICE_APPEARANCE + 1] = {
                AD_TYPE_APPEARANCE,
                LE8_L(APPEARANCE_GENERAL_HID_VALUE),
                LE8_H(APPEARANCE_GENERAL_HID_VALUE)
        };

/* If privacy is enabled, reconnection address will be used as Initiator's 
 * address for directed advertisements. Otherwise, the bonded host address 
 * shall be used as Initiator's address.
 */
#ifdef __GAP_PRIVACY_SUPPORT__

    temp_addr.type = ls_addr_type_random;
    MemCopy(&temp_addr.addr, GapGetReconnectionAddress(), sizeof(BD_ADDR_T));

#else /* __GAP_PRIVACY_SUPPORT__ */

    temp_addr.type = ls_addr_type_public;
    MemCopy(&temp_addr.addr, &g_btcar_data.bonded_bd_addr.addr, sizeof(BD_ADDR_T));

#endif /* ! __GAP_PRIVACY_SUPPORT__ */

    if(fast_connection)
    {
        adv_interval_min = FC_ADVERTISING_INTERVAL_MIN;
        adv_interval_max = FC_ADVERTISING_INTERVAL_MAX;
    }

    if(g_btcar_data.bonded)
    {
        /* As the device is bonded, we don't want it to be discoverable any 
         * more
         */
        discover_mode = gap_mode_discover_no;
    }

    if((GapSetMode(gap_role_peripheral, discover_mode,
                   connect_mode, gap_mode_bond_yes,
                   gap_mode_security_unauthenticate) != ls_err_none) ||
       (connect_mode == gap_mode_connect_directed && 
                   GapSetAdvAddress(&temp_addr) 
                   != ls_err_none) ||
        /* Advertisement interval will be ignored for directed advertisement */
       (GapSetAdvInterval(adv_interval_min, adv_interval_max) 
                        != ls_err_none))
    {
        ReportPanic(app_panic_set_advert_params);
        return;
    }

    /* Reset existing advertising data as application is again going to add
     * data for undirected advertisements.
     */
    if(LsStoreAdvScanData(0, NULL, ad_src_advertise) != ls_err_none)
    {
        ReportPanic(app_panic_set_advert_data);
        return;
    }

    /* Reset existing scan response data as application is again going to add
     * data for undirected advertisements.
     */
    if(LsStoreAdvScanData(0, NULL, ad_src_scan_rsp) != ls_err_none)
    {
        ReportPanic(app_panic_set_scan_rsp_data);
        return;
    }

    /* Add to advData only if undirected advertisements are to be done. */
    if(connect_mode == gap_mode_connect_undirected)
    {
    
        /* Set up the advertising data. The GAP layer will automatically add the
         * AD Flags field so all we need to do here is add 16-bit supported 
         * services UUID and Complete Local Name type. Applications are free to
         * add any other AD types based upon the profile requirements and
         * subject to the maximum AD size of 31 octets.
         */

   
        /* Add 16-bit UUID list of the services supported by the device */
        length = GetSupported16BitUUIDServiceList(advert_data);

        /* Before adding data to the ADV_IND, increment 'lengthAddedToAdv' to
         * keep track of the total number of bytes added to ADV_IND. At the end
         * while adding the device name to the ADV_IND, this can be used to
         * verify whether the complete name can fit into the AdvData adhering to
         * the limit of 31 octets. In addition to the above populated fields, a
         * 'length' field will also be added to AdvData by GAP layer. Refer
         * BT 4.0 spec, Vol 3, Part C, Figure 11.1.
         */
        length_added_to_adv += (length + 1);
        if (LsStoreAdvScanData(length, advert_data,
                 ad_src_advertise) != ls_err_none)
        {
            ReportPanic(app_panic_set_advert_data);
            return;
        }

        length_added_to_adv += (sizeof(device_appearance) + 1);
        /* Add device appearance as advertisement data */
        if (LsStoreAdvScanData(sizeof(device_appearance), device_appearance, 
                              ad_src_advertise) != ls_err_none)
        {
            ReportPanic(app_panic_set_advert_data);
            return;
        }

        /* If 128-bit proprietary service UUID is added to the advData, there
         * will be no space left for any more data. So don't add the
         * TxPowerLevel to the advData.
         */

        /* Read tx power of the chip */
        if(LsReadTransmitPowerLevel(&tx_power_level) != ls_err_none)
        {
            /* Readin tx power failed */
            ReportPanic(app_panic_read_tx_pwr_level);
        }

        /* Add the read tx power level to g_device_tx_power 
         * Tx power level value is of 1 byte 
         */
        device_tx_power[TX_POWER_VALUE_LENGTH - 1] = (uint8 )tx_power_level;

        length_added_to_scan += TX_POWER_VALUE_LENGTH + 1;
        /* Add tx power value of device to the scan response data */
        if (LsStoreAdvScanData(TX_POWER_VALUE_LENGTH, device_tx_power, 
                              ad_src_scan_rsp) != ls_err_none)
        {
            ReportPanic(app_panic_set_scan_rsp_data);
            return;
        }
       
        addDeviceNameToAdvData(length_added_to_adv, length_added_to_scan);
    }
}
Esempio n. 4
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      gattSetAdvertParams
 *
 *  DESCRIPTION
 *      This function is used to set advertisement parameters.
 *
 *  PARAMETERS
 *      p_addr [in]             Bonded host address
 *      fast_connection [in]    TRUE:  Fast advertisements
 *                              FALSE: Slow advertisements
 *
 *  RETURNS
 *      Nothing
 *----------------------------------------------------------------------------*/
static void gattSetAdvertParams(TYPED_BD_ADDR_T *p_addr, bool fast_connection)
{
    uint8 advert_data[MAX_ADV_DATA_LEN];/* Advertisement packet */
    uint16 length;                      /* Length of advertisement packet */
    /* Advertisement interval, microseconds */
    uint32 adv_interval_min;
    uint32 adv_interval_max;

    /* Tx power level value prefixed with 'Tx Power' AD Type */
    /* Refer to BT4.0 specification, Vol3-part-C-Section-11.1.5 */ 
    uint8 device_tx_power[TX_POWER_VALUE_LENGTH] = {
                AD_TYPE_TX_POWER
                };

    /* Device appearance */
    uint8 device_appearance[ATTR_LEN_DEVICE_APPEARANCE + 1] = {
                AD_TYPE_APPEARANCE,
                WORD_LSB(APPEARANCE_APPLICATION_VALUE),
                WORD_MSB(APPEARANCE_APPLICATION_VALUE)
                };

    /* A variable to keep track of the data added to advert_data. The limit is 
     * MAX_ADV_DATA_LEN. GAP layer will add AD Flags to advert_data which is 3
     * bytes. Refer BT Spec 4.0, Vol 3, Part C, Sec 11.1.3:
     *
     * First byte is length
     * second byte is AD TYPE = 0x1
     * Third byte is Flags description 
     */
    uint16 length_added_to_adv = 3;

    if(fast_connection)
    {
        adv_interval_min = FC_ADVERTISING_INTERVAL_MIN;
        adv_interval_max = FC_ADVERTISING_INTERVAL_MAX;
    }

    if((GapSetMode(gap_role_peripheral, gap_mode_discover_general,
                        gap_mode_connect_undirected, 
                        gap_mode_bond_yes,
                        gap_mode_security_unauthenticate) != ls_err_none) ||
       (GapSetAdvInterval(adv_interval_min, adv_interval_max) 
                        != ls_err_none))
    {
        ReportPanic(app_panic_set_advert_params);
    }

    /* Add bonded device to white list.*/
    if(IsWhiteListEnabled())
    {
        /* Initial case when advertisements are started for Bonded host for 
         * 10 seconds. White list is configured with the Bonded host address
         */
        if(LsAddWhiteListDevice(p_addr)!= ls_err_none)
        {
            ReportPanic(app_panic_add_whitelist);
        }
    }

    /* Reset existing advertising data */
    if(LsStoreAdvScanData(0, NULL, ad_src_advertise) != ls_err_none)
    {
        ReportPanic(app_panic_set_advert_data);
    }

    /* Reset existing scan response data */
    if(LsStoreAdvScanData(0, NULL, ad_src_scan_rsp) != ls_err_none)
    {
        ReportPanic(app_panic_set_scan_rsp_data);
    }

    /* Setup ADVERTISEMENT DATA */

    /* Add UUID list of the services supported by the device */
    length = GetSupportedUUIDServiceList(advert_data);

    /* One added for Length field, which will be added to Adv Data by GAP 
     * layer 
     */
    length_added_to_adv += (length + 1);

    if (LsStoreAdvScanData(length, advert_data, 
                        ad_src_advertise) != ls_err_none)
    {
        ReportPanic(app_panic_set_advert_data);
    }

    /* One added for Length field, which will be added to Adv Data by GAP 
     * layer 
     */
    length_added_to_adv += (sizeof(device_appearance) + 1);

    /* Add device appearance to the advertisements */
    if (LsStoreAdvScanData(ATTR_LEN_DEVICE_APPEARANCE + 1, 
        device_appearance, ad_src_advertise) != ls_err_none)
    {
        ReportPanic(app_panic_set_advert_data);
    }

    /* Change the Radio and Adv tx params for CONFIG mode */
    
    /* Update the radio tx power level here */
    LsSetTransmitPowerLevel(RADIO_TX_POWER_CONFIG); 

    /* Update the adv tx power level here */
    device_tx_power[TX_POWER_VALUE_LENGTH - 1] = ADV_TX_POWER_CONFIG;
    
    /* NOTE: The 2 tx params above are reset to the tx_power_mode on disconnection */

    /* One added for Length field, it will be added to Adv Data by GAP layer */
    length_added_to_adv += (TX_POWER_VALUE_LENGTH + 1);

    /* Add tx power value of device to the advertising data */
    if (LsStoreAdvScanData(TX_POWER_VALUE_LENGTH, device_tx_power, 
                          ad_src_advertise) != ls_err_none)
    {
        ReportPanic(app_panic_set_advert_data);
    }

    addDeviceNameToAdvData(length_added_to_adv, 0);

}
Esempio n. 5
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      startAdvertising
 *
 *  DESCRIPTION
 *      This function is called to start advertisements.
 *
 *      Advertisement packet will contain Flags AD and Manufacturer-specific
 *      AD with Manufacturer id set to CSR and payload set to the value of
 *      the User Key 0. The payload size is set by the User Key 1.
 *
 *      +--------+-------------------------------------------------+
 *      |FLAGS AD|MANUFACTURER AD                                  |
 *      +--------+-------------------------------------------------+
 *       0      2 3
 *
 *  RETURNS
 *      Nothing.
 *
 *---------------------------------------------------------------------------*/
void startAdvertising(void)
{
    uint8 advData[MAX_ADVERT_PACKET_SIZE];
    uint16 offset = 0;
    uint8 filler;
    uint16 advInterval;
    uint8 advPayloadSize;
    ls_addr_type addressType = ls_addr_type_public;     /* use public address */
    
    /* initialise values from User CsKeys */
    
    /* read User key 0 for the payload filler */
    filler = (uint8)(CSReadUserKey(0) & 0x00FF);
    
    /* read User key 1 for the payload size */
    advPayloadSize = (uint8)(CSReadUserKey(1) & 0x00FF);
    
    /* range check */
    if((advPayloadSize < 1) || (advPayloadSize > MAX_ADVERT_PAYLOAD_SIZE))
    {
        /* revert to default payload size */
        advPayloadSize = DEFAULT_ADVERT_PAYLOAD_SIZE;
    }
    
    /* read User key 2 for the advertising interval */
    advInterval = CSReadUserKey(2);
    
    /* range check */
    if((advInterval < MIN_ADVERTISING_INTERVAL) ||
       (advInterval > MAX_ADVERTISING_INTERVAL))
    {
        /* revert to default advertising interval */
        advInterval = DEFAULT_ADVERTISING_INTERVAL;
    }
    
    /* read address type from User key 3 */
    if(CSReadUserKey(3))
    {
        /* use random address type */
        addressType = ls_addr_type_random;

        /* generate and set the random address */
        appSetRandomAddress();
    }

    /* set the GAP Broadcaster role */
    GapSetMode(gap_role_broadcaster,
               gap_mode_discover_no,
               gap_mode_connect_no,
               gap_mode_bond_no,
               gap_mode_security_none);
    
    /* clear the existing advertisement data, if any */
    LsStoreAdvScanData(0, NULL, ad_src_advertise);

    /* set the advertisement interval, API accepts the value in microseconds */
    GapSetAdvInterval(advInterval * MILLISECOND, advInterval * MILLISECOND);
    
    /* manufacturer-specific data */
    advData[0] = AD_TYPE_MANUF;

    /* CSR company code, little endian */
    advData[1] = 0x0A;
    advData[2] = 0x00;
    
    /* fill in the rest of the advertisement */
    for(offset = 0; offset < advPayloadSize; offset++)
    {
        advData[3 + offset] = filler;
    }

    /* store the advertisement data */
    LsStoreAdvScanData(advPayloadSize + 3, advData, ad_src_advertise);
    
    /* Start broadcasting */
    LsStartStopAdvertise(TRUE, whitelist_disabled, addressType);
}
static void gattSetAdvertParams(bool fast_connection)
{
    uint8 advert_data[MAX_ADV_DATA_LEN];
    uint16 length;
    uint32 adv_interval_min = RP_ADVERTISING_INTERVAL_MIN;
    uint32 adv_interval_max = RP_ADVERTISING_INTERVAL_MAX;

    int8 tx_power_level = 0xff; /* Signed value */

    /* Tx power level value prefixed with 'Tx Power' AD Type */
    uint8 device_tx_power[TX_POWER_VALUE_LENGTH] = {
                AD_TYPE_TX_POWER
                };

    uint8 device_appearance[ATTR_LEN_DEVICE_APPEARANCE + 1] = {
                AD_TYPE_APPEARANCE,
                LE8_L(APPEARANCE_HR_SENSOR_VALUE),
                LE8_H(APPEARANCE_HR_SENSOR_VALUE)
                };

    /* A variable to keep track of the data added to AdvData. The limit is
     * MAX_ADV_DATA_LEN. GAP layer will add AD Flags to AdvData which
     * is 3 bytes. Refer BT Spec 4.0, Vol 3, Part C, Sec 11.1.3.
     */
    uint16 length_added_to_adv = 3;

    if(fast_connection)
    {
        adv_interval_min = FC_ADVERTISING_INTERVAL_MIN;
        adv_interval_max = FC_ADVERTISING_INTERVAL_MAX;
    }

    /* In a Public Environment like Gym, there is a requirement for HR Sensor
     * to communicate with fitness machines even without having a bond. So,
     * for HR Sensor application we will not enforce bonding by calling SM
     * Slave Security Request. Though, we will set HR Sensor's security
     * capabilities to 'gap_mode_bond_yes' so that we accept bonding if the
     * collector (like Watch or Cell Phone) would like to bond.
     */

    if((GapSetMode(gap_role_peripheral, gap_mode_discover_general,
                        gap_mode_connect_undirected,
                        gap_mode_bond_yes,
                        gap_mode_security_unauthenticate) != ls_err_none) ||
       (GapSetAdvInterval(adv_interval_min, adv_interval_max)
                        != ls_err_none))
    {
        ReportPanic(app_panic_set_advert_params);
    }

    /* Add bonded device to white list.*/
    if((g_hr_data.enable_white_list == TRUE))
    {
        /* Initial case when advertisements are started for Bonded host for
         * 10 seconds. White list is configured with the Bonded host address
         */
        if(LsAddWhiteListDevice(&g_hr_data.bonded_bd_addr)!=
            ls_err_none)
        {
            ReportPanic(app_panic_add_whitelist);
        }
    }

    /* Reset existing advertising data */
    if(LsStoreAdvScanData(0, NULL, ad_src_advertise) != ls_err_none)
    {
        ReportPanic(app_panic_set_advert_data);
    }

    /* Reset existing scan response data */
    if(LsStoreAdvScanData(0, NULL, ad_src_scan_rsp) != ls_err_none)
    {
        ReportPanic(app_panic_set_scan_rsp_data);
    }

    /* Setup ADVERTISEMENT DATA */

    /* Add UUID list of the services supported by the device */
    length = GetSupported16BitUUIDServiceList(advert_data);

    /* One added for Length field, which will be added to Adv Data by GAP
     * layer
     */
    length_added_to_adv += (length + 1);

    if (LsStoreAdvScanData(length, advert_data,
                        ad_src_advertise) != ls_err_none)
    {
        ReportPanic(app_panic_set_advert_data);
    }

    /* One added for Length field, which will be added to Adv Data by GAP
     * layer
     */
    length_added_to_adv += (sizeof(device_appearance) + 1);

    /* Add device appearance to the advertisements */
    if (LsStoreAdvScanData(ATTR_LEN_DEVICE_APPEARANCE + 1,
        device_appearance, ad_src_advertise) != ls_err_none)
    {
        ReportPanic(app_panic_set_advert_data);
    }

    /* Read tx power of the chip */
    if(LsReadTransmitPowerLevel(&tx_power_level) != ls_err_none)
    {
        /* Reading tx power failed */
        ReportPanic(app_panic_read_tx_pwr_level);
    }

    /* Add the read tx power level to device_tx_power
      * Tx power level value is of 1 byte
      */
    device_tx_power[TX_POWER_VALUE_LENGTH - 1] = (uint8 )tx_power_level;

    /* One added for Length field, which will be added to Adv Data by GAP
     * layer
     */
    length_added_to_adv += (TX_POWER_VALUE_LENGTH + 1);

    /* Add tx power value of device to the advertising data */
    if (LsStoreAdvScanData(TX_POWER_VALUE_LENGTH, device_tx_power,
                          ad_src_advertise) != ls_err_none)
    {
        ReportPanic(app_panic_set_advert_data);
    }

    addDeviceNameToAdvData(length_added_to_adv, 0);

}