Пример #1
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      Nvm_Write
 *
 *  DESCRIPTION
 *      Erases the NVM memory.
 *
 *  RETURNS
 *      Nothing
 *
 
*----------------------------------------------------------------------------*/
extern void Nvm_Erase(void)
{
    sys_status result;

    /* NvmErase automatically enables the NVM before erasing */
    result = NvmErase(TRUE);

    /* Disable NVM after erasing */
    Nvm_Disable();

    /* If NvmErase fails, report panic */
    if(sys_status_success != result)
    {
        ReportPanic(app_panic_nvm_erase);
    }
}
Пример #2
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      Nvm_Read
 *
 *  DESCRIPTION
 *      Read words from the NVM Store after preparing the NVM to be readable.
 *      After the read operation, perform the actions necessary to save power
 *      on NVM.
 *
 *      Read words starting at the word offset, and store them in the supplied
 *      buffer.
 *
 *  PARAMETERS
 *      buffer [out]            Data read from NVM
 *      length [in]             Number of words of data to read
 *      offset [in]             Offset from which to start reading, in words
 *
 *  RETURNS
 *      Nothing
 *----------------------------------------------------------------------------*/
void Nvm_Read(uint16 *buffer, uint16 length, uint16 offset)
{
    sys_status result;

    /* Read from NVM. Firmware re-enables the NVM if it is disabled */
    result = NvmRead(buffer, length, offset);

    /* Disable NVM to save power after read operation */
    Nvm_Disable();

    /* Report panic if NVM read is not successful */
    if(sys_status_success != result)
    {
        ReportPanic(app_panic_nvm_read);
    }
}
Пример #3
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      Nvm_Write
 *
 *  DESCRIPTION
 *      Write words to the NVM Store after preparing the NVM to be writable. 
 *      After the write operation, perform the actions necessary to save power
 *      on NVM.
 *
 *      Write words from the supplied buffer into the NVM Store, starting at the
 *      word offset.
 *
 *  PARAMETERS
 *      buffer [in]             Data to write to NVM
 *      length [in]             Number of words of data to write
 *      offset [in]             Offset from which to start writing, in words
 *
 *  RETURNS
 *      Nothing
 *----------------------------------------------------------------------------*/
void Nvm_Write(uint16 *buffer, uint16 length, uint16 offset)
{
    sys_status result;          /* Function status */

    /* Write to NVM. Firmware re-enables the NVM if it is disabled */
    result = NvmWrite(buffer, length, offset);

    /* Disable NVM to save power after write operation */
    Nvm_Disable();

    /* Report panic if NVM write is not successful */
    if(sys_status_success != result)
    {
        ReportPanic(app_panic_nvm_write);
    }
}
Пример #4
0
void Nvm_Write(uint16* buffer, uint16 length, uint16 offset)
{
    sys_status result;

    /* If the NVM has been earlier disabled, firmware automatically enables
     * NVM before writing to it.
     */
    result = NvmWrite(buffer, length, offset);
    /* Disable NVM to save power after write operation */
    Nvm_Disable();
    /* PIO2 usage has to be toggled between LED operation and driving the NVM.
     * So, after the power to EEPROM is disabled, configure PIO2 to Pair LED
     * back again.
     */
    SetUpPairLED();

    /* If NvmWrite was a success, return */
    if(sys_status_success == result)
    {
        /* Write was successful. */
        return;
    }
#ifdef NVM_TYPE_FLASH
    else if(nvm_status_needs_erase == result)
    {
        /* The application already has a copy of NVM data in its variables,
         * so we can erase the NVM 
         */
        Nvm_Erase();

        /* Write back the NVM data. 
         * Please note that the following function writes data into NVM and 
         * should not fail. 
         */
         WriteApplicationAndServiceDataToNVM();
    }
#endif /* NVM_TYPE_FLASH */
    else
    {
        /* Irrecoverable error. Reset the chip. */
        ReportPanic(app_panic_nvm_write);
    }
}
Пример #5
0
void Nvm_Read(uint16* buffer, uint16 length, uint16 offset)
{
    sys_status result;

    /* If the NVM has been earlier disabled, firmware automatically enables
     * NVM before reading from it.
     */
    result = NvmRead(buffer, length, offset);
    /* Disable NVM to save power after read operation */
    Nvm_Disable();
    /* PIO2 usage has to be toggled between LED operation and driving the NVM.
     * So, after the power to EEPROM is disabled, configure PIO2 to Pair LED
     * back again.
     */
    SetUpPairLED();
    if(sys_status_success != result)
    {
        ReportPanic(app_panic_nvm_read);
    }

}
Пример #6
0
extern void Nvm_Write(uint16* buffer, uint16 length, uint16 offset)
{
    sys_status result;

    /* Write to NVM. Firmware re-enables the NVM if it is disabled */
    result = NvmWrite(buffer, length, offset);

    /* Disable NVM to save power after write operation */
    Nvm_Disable();

    /* If NvmWrite was a success, return */
    if(sys_status_success == result)
    {
        /* Write was successful. */
        return;
    }
#ifdef NVM_TYPE_FLASH
    else if(nvm_status_needs_erase == result)
    {
        /* The application already has a copy of NVM data in its variables,
         * so we can erase the NVM 
         */
        Nvm_Erase();

        /* Write back the NVM data. 
         * Please note that the following function writes data into NVM and 
         * should not fail. 
         */
         WriteApplicationAndServiceDataToNVM();
    }
#endif /* NVM_TYPE_FLASH */
    else
    {
        /* Irrecoverable error. Reset the chip. */
        ReportPanic(app_panic_nvm_write);
    }

}
Пример #7
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      appBuzzerTimerHandler
 *
 *  DESCRIPTION
 *      This function is used to stop the Buzzer at the expiry of 
 *      timer.
 *
 *  RETURNS
 *      Nothing.
 *
 *----------------------------------------------------------------------------*/
static void appBuzzerTimerHandler(timer_id tid)
{
    uint32 beep_timer = SHORT_BEEP_TIMER_VALUE;

    g_app_hw_data.buzzer_tid = TIMER_INVALID;

    switch(g_app_hw_data.beep_type)
    {
        case beep_short: /* FALLTHROUGH */
        case beep_long:
        {
            g_app_hw_data.beep_type = beep_off;

            /* Disable buzzer */
            PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE);
        }
        break;
        case beep_twice:
        {
            if(g_app_hw_data.beep_count == 0)
            {
                /* First beep sounded. Start the silent gap*/
                g_app_hw_data.beep_count = 1;

                /* Disable buzzer */
                PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE);

                /* Time gap between two beeps */
                beep_timer = BEEP_GAP_TIMER_VALUE;
            }
            else if(g_app_hw_data.beep_count == 1)
            {
                g_app_hw_data.beep_count = 2;

                /* Enable buzzer */
                PioEnablePWM(BUZZER_PWM_INDEX_0, TRUE);

                /* Start beep */
                beep_timer = SHORT_BEEP_TIMER_VALUE;
            }
            else
            {
                /* Two beeps have been sounded. Stop buzzer now*/
                g_app_hw_data.beep_count = 0;

                /* Disable buzzer */
                PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE);

                g_app_hw_data.beep_type = beep_off;
            }
        }
        break;
        case beep_thrice:
        {
            if(g_app_hw_data.beep_count == 0 ||
               g_app_hw_data.beep_count == 2)
            {
                /* First beep sounded. Start the silent gap*/
                g_app_hw_data.beep_count++;

                /* Disable buzzer */
                PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE);

                /* Time gap between two beeps */
                beep_timer = BEEP_GAP_TIMER_VALUE;
            }
            else if(g_app_hw_data.beep_count == 1 ||
                    g_app_hw_data.beep_count == 3)
            {
                g_app_hw_data.beep_count++;

                /* Enable buzzer */
                PioEnablePWM(BUZZER_PWM_INDEX_0, TRUE);

                beep_timer = SHORT_BEEP_TIMER_VALUE;
            }
            else
            {
                /* Two beeps have been sounded. Stop buzzer now*/
                g_app_hw_data.beep_count = 0;

                /* Disable buzzer */
                PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE);

                g_app_hw_data.beep_type = beep_off;
            }
        }
        break;
        default:
        {
            /* No such beep type */
            ReportPanic(app_panic_unexpected_beep_type);
            /* Though break statement will not be executed after panic but this
             * has been kept to avoid any confusion for default case.
             */
        }
        break;
    }

    if(g_app_hw_data.beep_type != beep_off)
    {
        /* start the timer */
        g_app_hw_data.buzzer_tid = TimerCreate(beep_timer, TRUE, 
                                               appBuzzerTimerHandler);
    }

}
Пример #8
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      SoundBuzzer
 *
 *  DESCRIPTION
 *      Function for sounding beeps.
 *
 *  RETURNS
 *      Nothing.
 *
 *----------------------------------------------------------------------------*/
extern void SoundBuzzer(buzzer_beep_type beep_type)
{
#ifdef ENABLE_BUZZER
    uint32 beep_timer = SHORT_BEEP_TIMER_VALUE;

    PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE);
    TimerDelete(g_app_hw_data.buzzer_tid);
    g_app_hw_data.buzzer_tid = TIMER_INVALID;
    g_app_hw_data.beep_count = 0;

    /* Store the beep type in some global variable. It will used on timer expiry
     * to check the type of beeps being sounded.
     */
    g_app_hw_data.beep_type = beep_type;

    switch(g_app_hw_data.beep_type)
    {
        case beep_off:
        {
            /* Don't do anything */
        }
        break;
        case beep_short:
            /* FALLTHROUGH */
        case beep_twice: /* Two short beeps will be sounded */
            /* FALLTHROUGH */
        case beep_thrice: /* Three short beeps will be sounded */
        {
            /* One short beep will be sounded */
            beep_timer = SHORT_BEEP_TIMER_VALUE;
        }
        break;
        
        case beep_long:
        {
            /* One long beep will be sounded */
            beep_timer = LONG_BEEP_TIMER_VALUE;
        }
        break;

        break;
        default:
        {
            /* No such beep type defined */
            ReportPanic(app_panic_unexpected_beep_type);
            /* Though break statement will not be executed after panic but this
             * has been kept to avoid any confusion for default case.
             */
        }
        break;
    }

    if(g_app_hw_data.beep_type != beep_off)
    {
        /* Initialize beep count to zero */
        g_app_hw_data.beep_count = 0;

        /* Enable buzzer */
        PioEnablePWM(BUZZER_PWM_INDEX_0, TRUE);

        TimerDelete(g_app_hw_data.buzzer_tid);
        g_app_hw_data.buzzer_tid = TimerCreate(beep_timer, TRUE, 
                                               appBuzzerTimerHandler);
    }
#endif /* ENABLE_BUZZER */
}
Пример #9
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      SoundBuzzer
 *
 *  DESCRIPTION
 *      This function is called to trigger beeps of different types, enumerated
 *      by 'buzzer_beep_type'.
 *
 *  PARAMETERS
 *      beep_type [in]          Type of beep required
 *
 *  RETURNS
 *      Nothing
 *----------------------------------------------------------------------------*/
extern void SoundBuzzer(buzzer_beep_type beep_type)
{
    /* Duration of beep */
    uint32 beep_timer = SHORT_BEEP_TIMER_VALUE;

    /* Disable the buzzer and stop the buzzer timer. */
    PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE);
    if (g_buzz_data.buzzer_tid != TIMER_INVALID)
    {
        TimerDelete(g_buzz_data.buzzer_tid);
        g_buzz_data.buzzer_tid = TIMER_INVALID;
    }

    /* Reset the beeper state */
    g_buzz_data.beep_count = 0;

    /* Store the beep type. It will be used on timer expiry to check the type of
     * beep being sounded.
     */
    g_buzz_data.beep_type = beep_type;

    switch(g_buzz_data.beep_type)
    {
        case buzzer_beep_off:
        {
            /* Don't do anything */
        }
        break;

        case buzzer_beep_short: /* One short beep will be sounded */
            /* FALLTHROUGH */
        case buzzer_beep_twice: /* Two short beeps will be sounded */
            /* FALLTHROUGH */
        case buzzer_beep_thrice: /* Three short beeps will be sounded */
        {
            beep_timer = SHORT_BEEP_TIMER_VALUE;
        }
        break;

        case buzzer_beep_long:
        {
            /* One long beep will be sounded */
            beep_timer = LONG_BEEP_TIMER_VALUE;
        }
        break;

        default:
        {
            /* No such beep type defined */
            ReportPanic(app_panic_unexpected_beep_type);
        }
        break;
    }

    if(g_buzz_data.beep_type != buzzer_beep_off)
    {
        /* Enable buzzer */
        PioEnablePWM(BUZZER_PWM_INDEX_0, TRUE);

        /* Start the buzzer timer */
        g_buzz_data.buzzer_tid = TimerCreate(beep_timer, TRUE, 
                                             appBuzzerTimerHandler);
    }

}
Пример #10
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      appBuzzerTimerHandler
 *
 *  DESCRIPTION
 *      This function is used to stop the Buzzer at the expiry of timer.
 *
 *  PARAMETERS
 *      tid [in]                ID of expired timer (unused)
 *
 *  RETURNS
 *      Nothing
 *----------------------------------------------------------------------------*/
static void appBuzzerTimerHandler(timer_id tid)
{
    /* Duration of next timer */
    uint32 beep_timer = SHORT_BEEP_TIMER_VALUE;

    /* The buzzer timer has just expired, so reset the timer ID */
    g_buzz_data.buzzer_tid = TIMER_INVALID;

    switch(g_buzz_data.beep_type)
    {
        case buzzer_beep_short: /* FALLTHROUGH */
        case buzzer_beep_long:
        {
            g_buzz_data.beep_type = buzzer_beep_off;

            /* Disable buzzer */
            PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE);
        }
        break;

        case buzzer_beep_twice:
        {
            if(g_buzz_data.beep_count == 0)
            {
                /* First beep sounded. Increment the beep count and start the
                 * silent gap.
                 */
                g_buzz_data.beep_count = 1;

                /* Disable buzzer */
                PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE);

                /* Time gap between two beeps */
                beep_timer = BEEP_GAP_TIMER_VALUE;
            }
            else if(g_buzz_data.beep_count == 1)
            {
                /* Sound the second beep and increment the beep count. */
                g_buzz_data.beep_count = 2;

                /* Enable buzzer */
                PioEnablePWM(BUZZER_PWM_INDEX_0, TRUE);

                /* Start another short beep */
                beep_timer = SHORT_BEEP_TIMER_VALUE;
            }
            else
            {
                /* Two beeps have been sounded. Stop buzzer now and reset the 
                 * beep count.
                 */
                g_buzz_data.beep_count = 0;

                /* Disable buzzer */
                PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE);

                g_buzz_data.beep_type = buzzer_beep_off;
            }
        }
        break;

        case buzzer_beep_thrice:
        {
            if(g_buzz_data.beep_count == 0 ||
               g_buzz_data.beep_count == 2)
            {
                /* Start the silent gap*/
                ++g_buzz_data.beep_count;

                /* Disable buzzer */
                PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE);

                /* Time gap between two beeps */
                beep_timer = BEEP_GAP_TIMER_VALUE;
            }
            else if(g_buzz_data.beep_count == 1 ||
                    g_buzz_data.beep_count == 3)
            {
                /* Start the beep sounding part. */
                ++g_buzz_data.beep_count;

                /* Enable buzzer */
                PioEnablePWM(BUZZER_PWM_INDEX_0, TRUE);

                beep_timer = SHORT_BEEP_TIMER_VALUE;
            }
            else
            {
                /* Three beeps have been sounded. Stop the buzzer. */
                g_buzz_data.beep_count = 0;

                /* Disable buzzer */
                PioEnablePWM(BUZZER_PWM_INDEX_0, FALSE);

                g_buzz_data.beep_type = buzzer_beep_off;
            }
        }
        break;

        default:
        {
            /* No such beep type */
            ReportPanic(app_panic_unexpected_beep_type);
        }
        break;
    }

    if(g_buzz_data.beep_type != buzzer_beep_off)
    {
        /* Start the timer */
        g_buzz_data.buzzer_tid = TimerCreate(beep_timer, TRUE, 
                                               appBuzzerTimerHandler);
    }
}
Пример #11
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);
    }
}
Пример #12
0
static void addDeviceNameToAdvData(uint16 adv_data_len, uint16 scan_data_len)
{

    uint8 *p_device_name = NULL;
    uint16 device_name_adtype_len;

    /* Read device name along with AD Type and its length */
    p_device_name = GapGetNameAndLength(&device_name_adtype_len);

    /* Increment device_name_length by one to account for length field
     * which will be added by the GAP layer. 
     */

    /* Check if Complete Device Name can fit in remaining advData space */
    if((device_name_adtype_len + 1) <= (MAX_ADV_DATA_LEN - adv_data_len))
    {
        /* Add complete device name to Advertisement data */
        p_device_name[0] = AD_TYPE_LOCAL_NAME_COMPLETE;
        
        /* Add Complete Device Name to Advertisement Data */
        if (LsStoreAdvScanData(device_name_adtype_len , p_device_name, 
                      ad_src_advertise) != ls_err_none)
        {
            ReportPanic(app_panic_set_advert_data);
            return;
        }

    }
    /* Check if Complete Device Name can fit in Scan response message */
    else if((device_name_adtype_len + 1) <= (MAX_ADV_DATA_LEN - scan_data_len)) 
    {
        /* Add complete device name to scan response data */
        p_device_name[0] = AD_TYPE_LOCAL_NAME_COMPLETE;
        
        /* Add Complete Device Name to Scan Response Data */
        if (LsStoreAdvScanData(device_name_adtype_len , p_device_name, 
                      ad_src_scan_rsp) != ls_err_none)
        {
            ReportPanic(app_panic_set_scan_rsp_data);
            return;
        }

    }
    /* Check if Shortened Device Name can fit in remaining advData space */
    else if((MAX_ADV_DATA_LEN - adv_data_len) >=
            (SHORTENED_DEV_NAME_LEN + 2)) /* Added 2 for Length and AD type
                                           * added by GAP layer
                                           */
    {
        /* Add shortened device name to Advertisement data */
        p_device_name[0] = AD_TYPE_LOCAL_NAME_SHORT;

       if (LsStoreAdvScanData(SHORTENED_DEV_NAME_LEN , p_device_name, 
                      ad_src_advertise) != ls_err_none)
        {
            ReportPanic(app_panic_set_advert_data);
            return;
        }

    }
    else /* Add device name to remaining Scan reponse data space */
    {
        /* Add as much as can be stored in Scan Response data */
        p_device_name[0] = AD_TYPE_LOCAL_NAME_SHORT;

       if (LsStoreAdvScanData(MAX_ADV_DATA_LEN - scan_data_len, 
                                    p_device_name, 
                                    ad_src_scan_rsp) != ls_err_none)
        {
            ReportPanic(app_panic_set_scan_rsp_data);
            return;
        }

    }

}
Пример #13
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      gattSetAdvertParams
 *
 *  DESCRIPTION
 *      This function is used to set advertisement parameters 
 *
 *  RETURNS
 *      Nothing.
 *
 *---------------------------------------------------------------------------*/
static void gattSetAdvertParams(bool fast_connection)
{
    uint8 advert_data[MAX_ADV_DATA_LEN];
    uint16 length;

    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_UNKNOWN_VALUE),
                LE8_H(APPEARANCE_UNKNOWN_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;

    /* 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 (CsrMeshStoreUserAdvData(length, advert_data, 
                                       ad_src_advertise) != TRUE)
    {
        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 (CsrMeshStoreUserAdvData(ATTR_LEN_DEVICE_APPEARANCE + 1, 
        device_appearance, ad_src_advertise) != TRUE)
    {
        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 (CsrMeshStoreUserAdvData(TX_POWER_VALUE_LENGTH, device_tx_power, 
                          ad_src_advertise) != TRUE)
    {
        ReportPanic(app_panic_set_advert_data);
    }

    addDeviceNameToAdvData(length_added_to_adv, 0);

}
Пример #14
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);

}
Пример #15
0
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);

}