add files from nrf52832 bootloader project
This commit is contained in:
		@@ -0,0 +1,649 @@
 | 
			
		||||
/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "ble_dfu.h"
 | 
			
		||||
#include "ble_types.h"
 | 
			
		||||
#include "ble_gatts.h"
 | 
			
		||||
#include "ble_srv_common.h"
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include "sdk_common.h"
 | 
			
		||||
 | 
			
		||||
#define MAX_DFU_PKT_LEN         20                                              /**< Maximum length (in bytes) of the DFU Packet characteristic. */
 | 
			
		||||
#define PKT_START_DFU_PARAM_LEN 2                                               /**< Length (in bytes) of the parameters for Packet Start DFU Request. */
 | 
			
		||||
#define PKT_INIT_DFU_PARAM_LEN  2                                               /**< Length (in bytes) of the parameters for Packet Init DFU Request. */
 | 
			
		||||
#define PKT_RCPT_NOTIF_REQ_LEN  3                                               /**< Length (in bytes) of the Packet Receipt Notification Request. */
 | 
			
		||||
#define MAX_PKTS_RCPT_NOTIF_LEN 6                                               /**< Maximum length (in bytes) of the Packets Receipt Notification. */
 | 
			
		||||
#define MAX_RESPONSE_LEN        7                                               /**< Maximum length (in bytes) of the response to a Control Point command. */
 | 
			
		||||
#define MAX_NOTIF_BUFFER_LEN    MAX(MAX_PKTS_RCPT_NOTIF_LEN, MAX_RESPONSE_LEN)  /**< Maximum length (in bytes) of the buffer needed by DFU Service while sending notifications to peer. */
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
    OP_CODE_START_DFU          = 1,                                             /**< Value of the Op code field for 'Start DFU' command.*/
 | 
			
		||||
    OP_CODE_RECEIVE_INIT       = 2,                                             /**< Value of the Op code field for 'Initialize DFU parameters' command.*/
 | 
			
		||||
    OP_CODE_RECEIVE_FW         = 3,                                             /**< Value of the Op code field for 'Receive firmware image' command.*/
 | 
			
		||||
    OP_CODE_VALIDATE           = 4,                                             /**< Value of the Op code field for 'Validate firmware' command.*/
 | 
			
		||||
    OP_CODE_ACTIVATE_N_RESET   = 5,                                             /**< Value of the Op code field for 'Activate & Reset' command.*/
 | 
			
		||||
    OP_CODE_SYS_RESET          = 6,                                             /**< Value of the Op code field for 'Reset System' command.*/
 | 
			
		||||
    OP_CODE_IMAGE_SIZE_REQ     = 7,                                             /**< Value of the Op code field for 'Report received image size' command.*/
 | 
			
		||||
    OP_CODE_PKT_RCPT_NOTIF_REQ = 8,                                             /**< Value of the Op code field for 'Request packet receipt notification.*/
 | 
			
		||||
    OP_CODE_RESPONSE           = 16,                                            /**< Value of the Op code field for 'Response.*/
 | 
			
		||||
    OP_CODE_PKT_RCPT_NOTIF     = 17                                             /**< Value of the Op code field for 'Packets Receipt Notification'.*/
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static bool     m_is_dfu_service_initialized = false;                           /**< Variable to check if the DFU service was initialized by the application.*/
 | 
			
		||||
static uint8_t  m_notif_buffer[MAX_NOTIF_BUFFER_LEN];                           /**< Buffer used for sending notifications to peer. */
 | 
			
		||||
 | 
			
		||||
/**@brief       Function for adding DFU Packet characteristic to the BLE Stack.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   p_dfu DFU Service structure.
 | 
			
		||||
 *
 | 
			
		||||
 * @return      NRF_SUCCESS on success. Otherwise an error code.
 | 
			
		||||
 */
 | 
			
		||||
static uint32_t dfu_pkt_char_add(ble_dfu_t * const p_dfu)
 | 
			
		||||
{
 | 
			
		||||
    ble_gatts_char_md_t char_md;
 | 
			
		||||
    ble_gatts_attr_t    attr_char_value;
 | 
			
		||||
    ble_uuid_t          char_uuid;
 | 
			
		||||
    ble_gatts_attr_md_t attr_md;
 | 
			
		||||
 | 
			
		||||
    memset(&char_md, 0, sizeof(char_md));
 | 
			
		||||
 | 
			
		||||
    char_md.char_props.write_wo_resp = 1;
 | 
			
		||||
    char_md.p_char_user_desc         = NULL;
 | 
			
		||||
    char_md.p_char_pf                = NULL;
 | 
			
		||||
    char_md.p_user_desc_md           = NULL;
 | 
			
		||||
    char_md.p_cccd_md                = NULL;
 | 
			
		||||
    char_md.p_sccd_md                = NULL;
 | 
			
		||||
 | 
			
		||||
    char_uuid.type = p_dfu->uuid_type;
 | 
			
		||||
    char_uuid.uuid = BLE_DFU_PKT_CHAR_UUID;
 | 
			
		||||
 | 
			
		||||
    memset(&attr_md, 0, sizeof(attr_md));
 | 
			
		||||
 | 
			
		||||
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm);
 | 
			
		||||
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
 | 
			
		||||
 | 
			
		||||
    attr_md.vloc    = BLE_GATTS_VLOC_STACK;
 | 
			
		||||
    attr_md.rd_auth = 0;
 | 
			
		||||
    attr_md.wr_auth = 0;
 | 
			
		||||
    attr_md.vlen    = 1;
 | 
			
		||||
 | 
			
		||||
    memset(&attr_char_value, 0, sizeof(attr_char_value));
 | 
			
		||||
 | 
			
		||||
    attr_char_value.p_uuid    = &char_uuid;
 | 
			
		||||
    attr_char_value.p_attr_md = &attr_md;
 | 
			
		||||
    attr_char_value.init_len  = 0;
 | 
			
		||||
    attr_char_value.init_offs = 0;
 | 
			
		||||
    attr_char_value.max_len   = MAX_DFU_PKT_LEN;
 | 
			
		||||
    attr_char_value.p_value   = NULL;
 | 
			
		||||
 | 
			
		||||
    return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
 | 
			
		||||
                                           &char_md,
 | 
			
		||||
                                           &attr_char_value,
 | 
			
		||||
                                           &p_dfu->dfu_pkt_handles);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief       Function for adding DFU Revision characteristic to the BLE Stack.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   p_dfu DFU Service structure.
 | 
			
		||||
 *
 | 
			
		||||
 * @return      NRF_SUCCESS on success. Otherwise an error code.
 | 
			
		||||
 */
 | 
			
		||||
static uint32_t dfu_rev_char_add(ble_dfu_t * const p_dfu, ble_dfu_init_t const * const p_dfu_init)
 | 
			
		||||
{
 | 
			
		||||
    ble_gatts_char_md_t char_md;
 | 
			
		||||
    ble_gatts_attr_t    attr_char_value;
 | 
			
		||||
    ble_uuid_t          char_uuid;
 | 
			
		||||
    ble_gatts_attr_md_t attr_md;
 | 
			
		||||
 | 
			
		||||
    memset(&char_md, 0, sizeof(char_md));
 | 
			
		||||
 | 
			
		||||
    char_md.char_props.read          = 1;
 | 
			
		||||
    char_md.p_char_user_desc         = NULL;
 | 
			
		||||
    char_md.p_char_pf                = NULL;
 | 
			
		||||
    char_md.p_user_desc_md           = NULL;
 | 
			
		||||
    char_md.p_cccd_md                = NULL;
 | 
			
		||||
    char_md.p_sccd_md                = NULL;
 | 
			
		||||
 | 
			
		||||
    char_uuid.type = p_dfu->uuid_type;
 | 
			
		||||
    char_uuid.uuid = BLE_DFU_REV_CHAR_UUID;
 | 
			
		||||
 | 
			
		||||
    memset(&attr_md, 0, sizeof(attr_md));
 | 
			
		||||
 | 
			
		||||
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
 | 
			
		||||
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
 | 
			
		||||
 | 
			
		||||
    attr_md.vloc    = BLE_GATTS_VLOC_STACK;
 | 
			
		||||
    attr_md.rd_auth = 0;
 | 
			
		||||
    attr_md.wr_auth = 0;
 | 
			
		||||
    attr_md.vlen    = 1;
 | 
			
		||||
 | 
			
		||||
    memset(&attr_char_value, 0, sizeof(attr_char_value));
 | 
			
		||||
 | 
			
		||||
    attr_char_value.p_uuid    = &char_uuid;
 | 
			
		||||
    attr_char_value.p_attr_md = &attr_md;
 | 
			
		||||
    attr_char_value.init_len  = sizeof(uint16_t);
 | 
			
		||||
    attr_char_value.init_offs = 0;
 | 
			
		||||
    attr_char_value.max_len   = sizeof(uint16_t);
 | 
			
		||||
    attr_char_value.p_value   = (uint8_t *)&p_dfu_init->revision;
 | 
			
		||||
 | 
			
		||||
    return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
 | 
			
		||||
                                           &char_md,
 | 
			
		||||
                                           &attr_char_value,
 | 
			
		||||
                                           &p_dfu->dfu_rev_handles);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief       Function for adding DFU Control Point characteristic to the BLE Stack.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   p_dfu DFU Service structure.
 | 
			
		||||
 *
 | 
			
		||||
 * @return      NRF_SUCCESS on success. Otherwise an error code.
 | 
			
		||||
 */
 | 
			
		||||
static uint32_t dfu_ctrl_pt_add(ble_dfu_t * const p_dfu)
 | 
			
		||||
{
 | 
			
		||||
    ble_gatts_char_md_t char_md;
 | 
			
		||||
    ble_gatts_attr_t    attr_char_value;
 | 
			
		||||
    ble_uuid_t          char_uuid;
 | 
			
		||||
    ble_gatts_attr_md_t attr_md;
 | 
			
		||||
 | 
			
		||||
    memset(&char_md, 0, sizeof(char_md));
 | 
			
		||||
 | 
			
		||||
    char_md.char_props.write  = 1;
 | 
			
		||||
    char_md.char_props.notify = 1;
 | 
			
		||||
    char_md.p_char_user_desc  = NULL;
 | 
			
		||||
    char_md.p_char_pf         = NULL;
 | 
			
		||||
    char_md.p_user_desc_md    = NULL;
 | 
			
		||||
    char_md.p_cccd_md         = NULL;
 | 
			
		||||
    char_md.p_sccd_md         = NULL;
 | 
			
		||||
 | 
			
		||||
    char_uuid.type = p_dfu->uuid_type;
 | 
			
		||||
    char_uuid.uuid = BLE_DFU_CTRL_PT_UUID;
 | 
			
		||||
 | 
			
		||||
    memset(&attr_md, 0, sizeof(attr_md));
 | 
			
		||||
 | 
			
		||||
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm);
 | 
			
		||||
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
 | 
			
		||||
 | 
			
		||||
    attr_md.vloc    = BLE_GATTS_VLOC_STACK;
 | 
			
		||||
    attr_md.rd_auth = 0;
 | 
			
		||||
    attr_md.wr_auth = 1;
 | 
			
		||||
    attr_md.vlen    = 1;
 | 
			
		||||
 | 
			
		||||
    memset(&attr_char_value, 0, sizeof(attr_char_value));
 | 
			
		||||
 | 
			
		||||
    attr_char_value.p_uuid    = &char_uuid;
 | 
			
		||||
    attr_char_value.p_attr_md = &attr_md;
 | 
			
		||||
    attr_char_value.init_len  = 0;
 | 
			
		||||
    attr_char_value.init_offs = 0;
 | 
			
		||||
    attr_char_value.max_len   = BLE_GATT_ATT_MTU_DEFAULT;
 | 
			
		||||
    attr_char_value.p_value   = NULL;
 | 
			
		||||
 | 
			
		||||
    return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
 | 
			
		||||
                                           &char_md,
 | 
			
		||||
                                           &attr_char_value,
 | 
			
		||||
                                           &p_dfu->dfu_ctrl_pt_handles);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief     Function for handling the @ref BLE_GAP_EVT_CONNECTED event from the S110 SoftDevice.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] p_dfu     DFU Service Structure.
 | 
			
		||||
 * @param[in] p_ble_evt Pointer to the event received from BLE stack.
 | 
			
		||||
 */
 | 
			
		||||
static void on_connect(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
 | 
			
		||||
{
 | 
			
		||||
    p_dfu->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief     Function for checking if the CCCD of DFU Control point is configured for Notification.
 | 
			
		||||
 *
 | 
			
		||||
 * @details   This function checks if the CCCD of DFU Control Point characteristic is configured
 | 
			
		||||
 *            for Notification by the DFU Controller.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] p_dfu DFU Service structure.
 | 
			
		||||
 *
 | 
			
		||||
 * @return    True if the CCCD of DFU Control Point characteristic is configured for Notification.
 | 
			
		||||
 *            False otherwise.
 | 
			
		||||
 */
 | 
			
		||||
static bool is_cccd_configured(ble_dfu_t * p_dfu)
 | 
			
		||||
{
 | 
			
		||||
    // Check if the CCCDs are configured.
 | 
			
		||||
    uint8_t  cccd_val_buf[BLE_CCCD_VALUE_LEN];
 | 
			
		||||
    ble_gatts_value_t gatts_value;
 | 
			
		||||
 | 
			
		||||
    // Initialize value struct.
 | 
			
		||||
    memset(&gatts_value, 0, sizeof(gatts_value));
 | 
			
		||||
 | 
			
		||||
    gatts_value.len     = BLE_CCCD_VALUE_LEN;
 | 
			
		||||
    gatts_value.offset  = 0;
 | 
			
		||||
    gatts_value.p_value = cccd_val_buf;
 | 
			
		||||
 | 
			
		||||
    // Check the CCCD Value of DFU Control Point.
 | 
			
		||||
    uint32_t err_code = sd_ble_gatts_value_get(p_dfu->conn_handle,
 | 
			
		||||
                                               p_dfu->dfu_ctrl_pt_handles.cccd_handle,
 | 
			
		||||
                                               &gatts_value);
 | 
			
		||||
    if (err_code != NRF_SUCCESS)
 | 
			
		||||
    {
 | 
			
		||||
        if (p_dfu->error_handler != NULL)
 | 
			
		||||
        {
 | 
			
		||||
            p_dfu->error_handler(err_code);
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ble_srv_is_notification_enabled(cccd_val_buf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief     Function for handling a Write event on the Control Point characteristic.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] p_dfu             DFU Service Structure.
 | 
			
		||||
 * @param[in] p_ble_write_evt   Pointer to the write event received from BLE stack.
 | 
			
		||||
 *
 | 
			
		||||
 * @return    NRF_SUCCESS on successful processing of control point write. Otherwise an error code.
 | 
			
		||||
 */
 | 
			
		||||
static uint32_t on_ctrl_pt_write(ble_dfu_t * p_dfu, ble_gatts_evt_write_t * p_ble_write_evt)
 | 
			
		||||
{
 | 
			
		||||
    ble_gatts_rw_authorize_reply_params_t auth_reply;
 | 
			
		||||
 | 
			
		||||
    auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
 | 
			
		||||
    auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
 | 
			
		||||
    auth_reply.params.write.update = 1;
 | 
			
		||||
    auth_reply.params.write.offset = p_ble_write_evt->offset;
 | 
			
		||||
    auth_reply.params.write.len = p_ble_write_evt->len;
 | 
			
		||||
    auth_reply.params.write.p_data = p_ble_write_evt->data;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if (!is_cccd_configured(p_dfu))
 | 
			
		||||
    {
 | 
			
		||||
        // Send an error response to the peer indicating that the CCCD is improperly configured.
 | 
			
		||||
        auth_reply.params.write.gatt_status =
 | 
			
		||||
            BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR;
 | 
			
		||||
 | 
			
		||||
        return (sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &auth_reply));
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        uint32_t err_code;
 | 
			
		||||
 | 
			
		||||
        auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
 | 
			
		||||
 | 
			
		||||
        err_code = (sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &auth_reply));
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ble_dfu_evt_t ble_dfu_evt;
 | 
			
		||||
 | 
			
		||||
    switch (p_ble_write_evt->data[0])
 | 
			
		||||
    {
 | 
			
		||||
        case OP_CODE_START_DFU:
 | 
			
		||||
            ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_START;
 | 
			
		||||
 | 
			
		||||
            if (p_ble_write_evt->len < PKT_START_DFU_PARAM_LEN)
 | 
			
		||||
            {
 | 
			
		||||
                return ble_dfu_response_send(p_dfu,
 | 
			
		||||
                                             (ble_dfu_procedure_t) p_ble_write_evt->data[0],
 | 
			
		||||
                                             BLE_DFU_RESP_VAL_OPER_FAILED);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ble_dfu_evt.evt.ble_dfu_pkt_write.len    = 1;
 | 
			
		||||
            ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = &(p_ble_write_evt->data[1]);
 | 
			
		||||
 | 
			
		||||
            p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case OP_CODE_RECEIVE_INIT:
 | 
			
		||||
            ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_RECEIVE_INIT_DATA;
 | 
			
		||||
 | 
			
		||||
            if (p_ble_write_evt->len < PKT_INIT_DFU_PARAM_LEN)
 | 
			
		||||
            {
 | 
			
		||||
                return ble_dfu_response_send(p_dfu,
 | 
			
		||||
                                             (ble_dfu_procedure_t) p_ble_write_evt->data[0],
 | 
			
		||||
                                             BLE_DFU_RESP_VAL_OPER_FAILED);
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            ble_dfu_evt.evt.ble_dfu_pkt_write.len    = 1;
 | 
			
		||||
            ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = &(p_ble_write_evt->data[1]);
 | 
			
		||||
 | 
			
		||||
            p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case OP_CODE_RECEIVE_FW:
 | 
			
		||||
            ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_RECEIVE_APP_DATA;
 | 
			
		||||
 | 
			
		||||
            p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case OP_CODE_VALIDATE:
 | 
			
		||||
            ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_VALIDATE;
 | 
			
		||||
 | 
			
		||||
            p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case OP_CODE_ACTIVATE_N_RESET:
 | 
			
		||||
            ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_ACTIVATE_N_RESET;
 | 
			
		||||
 | 
			
		||||
            p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case OP_CODE_SYS_RESET:
 | 
			
		||||
            ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_SYS_RESET;
 | 
			
		||||
 | 
			
		||||
            p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case OP_CODE_PKT_RCPT_NOTIF_REQ:
 | 
			
		||||
            if (p_ble_write_evt->len < PKT_RCPT_NOTIF_REQ_LEN)
 | 
			
		||||
            {
 | 
			
		||||
                return (ble_dfu_response_send(p_dfu,
 | 
			
		||||
                                              BLE_DFU_PKT_RCPT_REQ_PROCEDURE,
 | 
			
		||||
                                              BLE_DFU_RESP_VAL_NOT_SUPPORTED));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ble_dfu_evt.evt.pkt_rcpt_notif_req.num_of_pkts =
 | 
			
		||||
                uint16_decode(&(p_ble_write_evt->data[1]));
 | 
			
		||||
 | 
			
		||||
            if (ble_dfu_evt.evt.pkt_rcpt_notif_req.num_of_pkts == 0)
 | 
			
		||||
            {
 | 
			
		||||
                ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PKT_RCPT_NOTIF_DISABLED;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PKT_RCPT_NOTIF_ENABLED;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
 | 
			
		||||
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case OP_CODE_IMAGE_SIZE_REQ:
 | 
			
		||||
            ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_BYTES_RECEIVED_SEND;
 | 
			
		||||
 | 
			
		||||
            p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            // Unsupported op code.
 | 
			
		||||
            return ble_dfu_response_send(p_dfu,
 | 
			
		||||
                                         (ble_dfu_procedure_t) p_ble_write_evt->data[0],
 | 
			
		||||
                                         BLE_DFU_RESP_VAL_NOT_SUPPORTED);
 | 
			
		||||
    }
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief     Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event from the S110
 | 
			
		||||
 *            Stack.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] p_dfu     DFU Service Structure.
 | 
			
		||||
 * @param[in] p_ble_evt Pointer to the event received from BLE stack.
 | 
			
		||||
 */
 | 
			
		||||
static void on_rw_authorize_req(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
 | 
			
		||||
{
 | 
			
		||||
    ble_gatts_evt_rw_authorize_request_t * p_authorize_request;
 | 
			
		||||
 | 
			
		||||
    p_authorize_request = &(p_ble_evt->evt.gatts_evt.params.authorize_request);
 | 
			
		||||
 | 
			
		||||
    if (
 | 
			
		||||
        (p_authorize_request->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
 | 
			
		||||
        &&
 | 
			
		||||
        (p_authorize_request->request.write.handle == p_dfu->dfu_ctrl_pt_handles.value_handle)
 | 
			
		||||
        && 
 | 
			
		||||
        (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ)
 | 
			
		||||
        &&
 | 
			
		||||
        (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)
 | 
			
		||||
        &&
 | 
			
		||||
        (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)
 | 
			
		||||
       )
 | 
			
		||||
    {
 | 
			
		||||
        uint32_t err_code;
 | 
			
		||||
 | 
			
		||||
        err_code = on_ctrl_pt_write(p_dfu, &(p_authorize_request->request.write));
 | 
			
		||||
 | 
			
		||||
        if (err_code != NRF_SUCCESS && p_dfu->error_handler != NULL)
 | 
			
		||||
        {
 | 
			
		||||
            p_dfu->error_handler(err_code);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief     Function for handling the @ref BLE_GATTS_EVT_WRITE event from the S110 SoftDevice.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] p_dfu     DFU Service Structure.
 | 
			
		||||
 * @param[in] p_ble_evt Pointer to the event received from BLE stack.
 | 
			
		||||
 */
 | 
			
		||||
static void on_write(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
 | 
			
		||||
{
 | 
			
		||||
    if (p_ble_evt->evt.gatts_evt.params.write.handle == p_dfu->dfu_pkt_handles.value_handle)
 | 
			
		||||
    {
 | 
			
		||||
        // DFU Packet written
 | 
			
		||||
 | 
			
		||||
        ble_dfu_evt_t ble_dfu_evt;
 | 
			
		||||
 | 
			
		||||
        ble_dfu_evt.ble_dfu_evt_type             = BLE_DFU_PACKET_WRITE;
 | 
			
		||||
        ble_dfu_evt.evt.ble_dfu_pkt_write.len    = p_ble_evt->evt.gatts_evt.params.write.len;
 | 
			
		||||
        ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = p_ble_evt->evt.gatts_evt.params.write.data;
 | 
			
		||||
 | 
			
		||||
        p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief     Function for handling the BLE_GAP_EVT_DISCONNECTED event from the S110 SoftDevice.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in] p_dfu     DFU Service Structure.
 | 
			
		||||
 * @param[in] p_ble_evt Pointer to the event received from BLE stack.
 | 
			
		||||
 */
 | 
			
		||||
static void on_disconnect(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
 | 
			
		||||
{
 | 
			
		||||
    p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t ble_dfu_init(ble_dfu_t * p_dfu, ble_dfu_init_t * p_dfu_init)
 | 
			
		||||
{
 | 
			
		||||
    if ((p_dfu == NULL) || (p_dfu_init == NULL) || (p_dfu_init->evt_handler == NULL))
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID;
 | 
			
		||||
 | 
			
		||||
    ble_uuid_t service_uuid;
 | 
			
		||||
    uint32_t   err_code;
 | 
			
		||||
 | 
			
		||||
    const ble_uuid128_t base_uuid128 =
 | 
			
		||||
    {
 | 
			
		||||
        {
 | 
			
		||||
            0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15,
 | 
			
		||||
            0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    service_uuid.uuid = BLE_DFU_SERVICE_UUID;
 | 
			
		||||
 | 
			
		||||
    err_code = sd_ble_uuid_vs_add(&base_uuid128, &(service_uuid.type));
 | 
			
		||||
    VERIFY_SUCCESS(err_code);
 | 
			
		||||
 | 
			
		||||
    err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
 | 
			
		||||
                                        &service_uuid,
 | 
			
		||||
                                        &(p_dfu->service_handle));
 | 
			
		||||
    VERIFY_SUCCESS(err_code);
 | 
			
		||||
 | 
			
		||||
    p_dfu->uuid_type = service_uuid.type;
 | 
			
		||||
 | 
			
		||||
    err_code = dfu_pkt_char_add(p_dfu);
 | 
			
		||||
    VERIFY_SUCCESS(err_code);
 | 
			
		||||
 | 
			
		||||
    err_code = dfu_ctrl_pt_add(p_dfu);
 | 
			
		||||
    VERIFY_SUCCESS(err_code);
 | 
			
		||||
 | 
			
		||||
    err_code = dfu_rev_char_add(p_dfu, p_dfu_init);
 | 
			
		||||
    VERIFY_SUCCESS(err_code);
 | 
			
		||||
 | 
			
		||||
    p_dfu->evt_handler = p_dfu_init->evt_handler;
 | 
			
		||||
 | 
			
		||||
    if (p_dfu_init->error_handler != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        p_dfu->error_handler = p_dfu_init->error_handler;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_is_dfu_service_initialized = true;
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void ble_dfu_on_ble_evt(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
 | 
			
		||||
{
 | 
			
		||||
    if ((p_dfu == NULL) || (p_ble_evt == NULL))
 | 
			
		||||
    {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (p_dfu->evt_handler != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        switch (p_ble_evt->header.evt_id)
 | 
			
		||||
        {
 | 
			
		||||
            case BLE_GAP_EVT_CONNECTED:
 | 
			
		||||
                on_connect(p_dfu, p_ble_evt);
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case BLE_GATTS_EVT_WRITE:
 | 
			
		||||
                on_write(p_dfu, p_ble_evt);
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case BLE_GAP_EVT_DISCONNECTED:
 | 
			
		||||
                on_disconnect(p_dfu, p_ble_evt);
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
 | 
			
		||||
                on_rw_authorize_req(p_dfu, p_ble_evt);
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                // No implementation needed.
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t ble_dfu_bytes_rcvd_report(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd)
 | 
			
		||||
{
 | 
			
		||||
    if (p_dfu == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_INVALID_STATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ble_gatts_hvx_params_t hvx_params;
 | 
			
		||||
    uint16_t               index = 0;
 | 
			
		||||
 | 
			
		||||
    // Encode the Op Code.
 | 
			
		||||
    m_notif_buffer[index++] = OP_CODE_RESPONSE;
 | 
			
		||||
 | 
			
		||||
    // Encode the Reqest Op Code.
 | 
			
		||||
    m_notif_buffer[index++] = OP_CODE_IMAGE_SIZE_REQ;
 | 
			
		||||
 | 
			
		||||
    // Encode the Response Value.
 | 
			
		||||
    m_notif_buffer[index++] = (uint8_t)BLE_DFU_RESP_VAL_SUCCESS;
 | 
			
		||||
 | 
			
		||||
    index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]);
 | 
			
		||||
 | 
			
		||||
    memset(&hvx_params, 0, sizeof(hvx_params));
 | 
			
		||||
 | 
			
		||||
    hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
 | 
			
		||||
    hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
 | 
			
		||||
    hvx_params.offset = 0;
 | 
			
		||||
    hvx_params.p_len  = &index;
 | 
			
		||||
    hvx_params.p_data = m_notif_buffer;
 | 
			
		||||
 | 
			
		||||
    return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t ble_dfu_pkts_rcpt_notify(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd)
 | 
			
		||||
{
 | 
			
		||||
    if (p_dfu == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_INVALID_STATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ble_gatts_hvx_params_t hvx_params;
 | 
			
		||||
    uint16_t               index = 0;
 | 
			
		||||
 | 
			
		||||
    m_notif_buffer[index++] = OP_CODE_PKT_RCPT_NOTIF;
 | 
			
		||||
 | 
			
		||||
    index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]);
 | 
			
		||||
 | 
			
		||||
    memset(&hvx_params, 0, sizeof(hvx_params));
 | 
			
		||||
 | 
			
		||||
    hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
 | 
			
		||||
    hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
 | 
			
		||||
    hvx_params.offset = 0;
 | 
			
		||||
    hvx_params.p_len  = &index;
 | 
			
		||||
    hvx_params.p_data = m_notif_buffer;
 | 
			
		||||
 | 
			
		||||
    return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t ble_dfu_response_send(ble_dfu_t         * p_dfu,
 | 
			
		||||
                               ble_dfu_procedure_t dfu_proc,
 | 
			
		||||
                               ble_dfu_resp_val_t  resp_val)
 | 
			
		||||
{
 | 
			
		||||
    if (p_dfu == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_INVALID_STATE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ble_gatts_hvx_params_t hvx_params;
 | 
			
		||||
    uint16_t               index = 0;
 | 
			
		||||
 | 
			
		||||
    m_notif_buffer[index++] = OP_CODE_RESPONSE;
 | 
			
		||||
 | 
			
		||||
    // Encode the Request Op code
 | 
			
		||||
    m_notif_buffer[index++] = (uint8_t)dfu_proc;
 | 
			
		||||
 | 
			
		||||
    // Encode the Response Value.
 | 
			
		||||
    m_notif_buffer[index++] = (uint8_t)resp_val;
 | 
			
		||||
 | 
			
		||||
    memset(&hvx_params, 0, sizeof(hvx_params));
 | 
			
		||||
 | 
			
		||||
    hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
 | 
			
		||||
    hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
 | 
			
		||||
    hvx_params.offset = 0;
 | 
			
		||||
    hvx_params.p_len  = &index;
 | 
			
		||||
    hvx_params.p_data = m_notif_buffer;
 | 
			
		||||
 | 
			
		||||
    return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,239 @@
 | 
			
		||||
/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**@file
 | 
			
		||||
 *
 | 
			
		||||
 * @defgroup ble_sdk_srv_dfu Device Firmware Update Service
 | 
			
		||||
 * @{
 | 
			
		||||
 * @ingroup  ble_sdk_srv
 | 
			
		||||
 * @brief    Device Firmware Update Service
 | 
			
		||||
 *
 | 
			
		||||
 * @details  The Device Firmware Update (DFU) service is a GATT based service that can be used for
 | 
			
		||||
 *           performing firmware updates over BLE. Note that this implementation uses vendor
 | 
			
		||||
 *           specific UUIDs for service and characteristics and is intended to demonstrate the
 | 
			
		||||
 *           firmware updates over BLE. Refer @ref bledfu_transport_bleservice and @ref
 | 
			
		||||
 *            bledfu_transport_bleprofile for more information on the service and profile respectively.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef BLE_DFU_H__
 | 
			
		||||
#define BLE_DFU_H__
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "ble_gatts.h"
 | 
			
		||||
#include "ble_gap.h"
 | 
			
		||||
#include "ble.h"
 | 
			
		||||
#include "ble_srv_common.h"
 | 
			
		||||
 | 
			
		||||
#define BLE_DFU_SERVICE_UUID                 0x1530                       /**< The UUID of the DFU Service. */
 | 
			
		||||
#define BLE_DFU_PKT_CHAR_UUID                0x1532                       /**< The UUID of the DFU Packet Characteristic. */
 | 
			
		||||
#define BLE_DFU_CTRL_PT_UUID                 0x1531                       /**< The UUID of the DFU Control Point. */
 | 
			
		||||
#define BLE_DFU_STATUS_REP_UUID              0x1533                       /**< The UUID of the DFU Status Report Characteristic. */
 | 
			
		||||
#define BLE_DFU_REV_CHAR_UUID                0x1534                       /**< The UUID of the DFU Revision Characteristic. */
 | 
			
		||||
 | 
			
		||||
/**@brief   DFU Event type.
 | 
			
		||||
 *
 | 
			
		||||
 * @details This enumeration contains the types of events that will be received from the DFU Service.
 | 
			
		||||
 */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    BLE_DFU_START,                                                      /**< The event indicating that the peer wants the application to prepare for a new firmware update. */
 | 
			
		||||
    BLE_DFU_RECEIVE_INIT_DATA,                                          /**< The event indicating that the peer wants the application to prepare to receive init parameters. */
 | 
			
		||||
    BLE_DFU_RECEIVE_APP_DATA,                                           /**< The event indicating that the peer wants the application to prepare to receive the new firmware image. */
 | 
			
		||||
    BLE_DFU_VALIDATE,                                                   /**< The event indicating that the peer wants the application to validate the newly received firmware image. */
 | 
			
		||||
    BLE_DFU_ACTIVATE_N_RESET,                                           /**< The event indicating that the peer wants the application to undergo activate new firmware and restart with new valid application */
 | 
			
		||||
    BLE_DFU_SYS_RESET,                                                  /**< The event indicating that the peer wants the application to undergo a reset and start the currently valid application image.*/
 | 
			
		||||
    BLE_DFU_PKT_RCPT_NOTIF_ENABLED,                                     /**< The event indicating that the peer has enabled packet receipt notifications. It is the responsibility of the application to call @ref ble_dfu_pkts_rcpt_notify each time the number of packets indicated by num_of_pkts field in @ref ble_dfu_evt_t is received.*/
 | 
			
		||||
    BLE_DFU_PKT_RCPT_NOTIF_DISABLED,                                    /**< The event indicating that the peer has disabled the packet receipt notifications.*/
 | 
			
		||||
    BLE_DFU_PACKET_WRITE,                                               /**< The event indicating that the peer has written a value to the 'DFU Packet' characteristic. The data received from the peer will be present in the @ref BLE_DFU_PACKET_WRITE element contained within @ref ble_dfu_evt_t.*/
 | 
			
		||||
    BLE_DFU_BYTES_RECEIVED_SEND                                         /**< The event indicating that the peer is requesting for the number of bytes of firmware data last received by the application. It is the responsibility of the application to call @ref ble_dfu_pkts_rcpt_notify in response to this event. */
 | 
			
		||||
} ble_dfu_evt_type_t;
 | 
			
		||||
 | 
			
		||||
/**@brief   DFU Procedure type.
 | 
			
		||||
 *
 | 
			
		||||
 * @details This enumeration contains the types of DFU procedures.
 | 
			
		||||
 */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    BLE_DFU_START_PROCEDURE        = 1,                                 /**< DFU Start procedure.*/
 | 
			
		||||
    BLE_DFU_INIT_PROCEDURE         = 2,                                 /**< DFU Initialization procedure.*/
 | 
			
		||||
    BLE_DFU_RECEIVE_APP_PROCEDURE  = 3,                                 /**< Firmware receiving procedure.*/
 | 
			
		||||
    BLE_DFU_VALIDATE_PROCEDURE     = 4,                                 /**< Firmware image validation procedure .*/
 | 
			
		||||
    BLE_DFU_PKT_RCPT_REQ_PROCEDURE = 8                                  /**< Packet receipt notification request procedure. */
 | 
			
		||||
} ble_dfu_procedure_t;
 | 
			
		||||
 | 
			
		||||
/**@brief   DFU Response value type.
 | 
			
		||||
 */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    BLE_DFU_RESP_VAL_SUCCESS = 1,                                       /**< Success.*/
 | 
			
		||||
    BLE_DFU_RESP_VAL_INVALID_STATE,                                     /**< Invalid state.*/
 | 
			
		||||
    BLE_DFU_RESP_VAL_NOT_SUPPORTED,                                     /**< Operation not supported.*/
 | 
			
		||||
    BLE_DFU_RESP_VAL_DATA_SIZE,                                         /**< Data size exceeds limit.*/
 | 
			
		||||
    BLE_DFU_RESP_VAL_CRC_ERROR,                                         /**< CRC Error.*/
 | 
			
		||||
    BLE_DFU_RESP_VAL_OPER_FAILED                                        /**< Operation failed.*/
 | 
			
		||||
} ble_dfu_resp_val_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief   DFU Packet structure.
 | 
			
		||||
 *
 | 
			
		||||
 * @details This structure contains the value of the DFU Packet characteristic as written by the
 | 
			
		||||
 *          peer and the length of the value written. It will be filled by the DFU Service when the
 | 
			
		||||
 *          peer writes to the DFU Packet characteristic.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *                    p_data;                                /**< Pointer to the received packet. This will point to a word aligned memory location.*/
 | 
			
		||||
    uint8_t                      len;                                   /**< Length of the packet received. */
 | 
			
		||||
} ble_dfu_pkt_write_t;
 | 
			
		||||
 | 
			
		||||
/**@brief   Packet receipt notification request structure.
 | 
			
		||||
 *
 | 
			
		||||
 * @details This structure contains the contents of the packet receipt notification request
 | 
			
		||||
 *          sent by the DFU Controller.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    uint16_t                     num_of_pkts;                           /**< The number of packets of firmware data to be received by application before sending the next Packet Receipt Notification to the peer. */
 | 
			
		||||
} ble_pkt_rcpt_notif_req_t;
 | 
			
		||||
 | 
			
		||||
/**@brief   DFU Event structure.
 | 
			
		||||
 *
 | 
			
		||||
 * @details This structure contains the event generated by the DFU Service based on the data
 | 
			
		||||
 *          received from the peer.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    ble_dfu_evt_type_t           ble_dfu_evt_type;                      /**< Type of the event.*/
 | 
			
		||||
    union
 | 
			
		||||
    {
 | 
			
		||||
        ble_dfu_pkt_write_t      ble_dfu_pkt_write;                     /**< The DFU packet received. This field is when the @ref ble_dfu_evt_type field is set to @ref BLE_DFU_PACKET_WRITE.*/
 | 
			
		||||
        ble_pkt_rcpt_notif_req_t pkt_rcpt_notif_req;                    /**< Packet receipt notification request. This field is when the @ref ble_dfu_evt_type field is set to @ref BLE_DFU_PKT_RCPT_NOTIF_ENABLED.*/
 | 
			
		||||
    } evt;
 | 
			
		||||
} ble_dfu_evt_t;
 | 
			
		||||
 | 
			
		||||
// Forward declaration of the ble_dfu_t type.
 | 
			
		||||
typedef struct ble_dfu_s ble_dfu_t;
 | 
			
		||||
 | 
			
		||||
/**@brief DFU Service event handler type. */
 | 
			
		||||
typedef void (*ble_dfu_evt_handler_t) (ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt);
 | 
			
		||||
 | 
			
		||||
/**@brief   DFU service structure.
 | 
			
		||||
 *
 | 
			
		||||
 * @details This structure contains status information related to the service.
 | 
			
		||||
 */
 | 
			
		||||
struct ble_dfu_s
 | 
			
		||||
{
 | 
			
		||||
    uint16_t                     conn_handle;                           /**< Handle of the current connection (as provided by the SoftDevice). This will be BLE_CONN_HANDLE_INVALID when not in a connection. */
 | 
			
		||||
    uint16_t                     revision;                              /**< Handle of DFU Service (as provided by the SoftDevice). */
 | 
			
		||||
    uint16_t                     service_handle;                        /**< Handle of DFU Service (as provided by the SoftDevice). */
 | 
			
		||||
    uint8_t                      uuid_type;                             /**< UUID type assigned for DFU Service by the SoftDevice. */
 | 
			
		||||
    ble_gatts_char_handles_t     dfu_pkt_handles;                       /**< Handles related to the DFU Packet characteristic. */
 | 
			
		||||
    ble_gatts_char_handles_t     dfu_ctrl_pt_handles;                   /**< Handles related to the DFU Control Point characteristic. */
 | 
			
		||||
    ble_gatts_char_handles_t     dfu_status_rep_handles;                /**< Handles related to the DFU Status Report characteristic. */
 | 
			
		||||
    ble_gatts_char_handles_t     dfu_rev_handles;                       /**< Handles related to the DFU Revision characteristic. */
 | 
			
		||||
    ble_dfu_evt_handler_t        evt_handler;                           /**< The event handler to be called when an event is to be sent to the application.*/
 | 
			
		||||
    ble_srv_error_handler_t      error_handler;                         /**< Function to be called in case of an error. */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**@brief      DFU service initialization structure.
 | 
			
		||||
 *
 | 
			
		||||
 * @details    This structure contains the initialization information for the DFU Service. The
 | 
			
		||||
 *             application needs to fill this structure and pass it to the DFU Service using the
 | 
			
		||||
 *             @ref ble_dfu_init function.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    uint16_t                     revision;                              /**< Revision number to be exposed by the DFU service. */
 | 
			
		||||
    ble_dfu_evt_handler_t        evt_handler;                           /**< Event handler to be called for handling events in the Device Firmware Update Service. */
 | 
			
		||||
    ble_srv_error_handler_t      error_handler;                         /**< Function to be called in case of an error. */
 | 
			
		||||
} ble_dfu_init_t;
 | 
			
		||||
 | 
			
		||||
/**@brief      Function for handling a BLE event.
 | 
			
		||||
 *
 | 
			
		||||
 * @details    The DFU service expects the application to call this function each time an event
 | 
			
		||||
 *             is received from the SoftDevice. This function processes the event, if it is
 | 
			
		||||
 *             relevant for the DFU service and calls the DFU event handler of the application if
 | 
			
		||||
 *             necessary.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]  p_dfu        Pointer to the DFU service structure.
 | 
			
		||||
 * @param[in]  p_ble_evt    Pointer to the event received from SoftDevice.
 | 
			
		||||
 */
 | 
			
		||||
void ble_dfu_on_ble_evt(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt);
 | 
			
		||||
 | 
			
		||||
/**@brief      Function for initializing the DFU service.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[out] p_dfu        Device Firmware Update service structure. This structure will have to be
 | 
			
		||||
 *                          supplied by the application. It will be initialized by this function,
 | 
			
		||||
 *                          and will later be used to identify the service instance.
 | 
			
		||||
 * @param[in]  p_dfu_init   Information needed to initialize the service.
 | 
			
		||||
 *
 | 
			
		||||
 * @return     NRF_SUCCESS if the DFU service and its characteristics were successfully added to the
 | 
			
		||||
 *             SoftDevice. Otherwise an error code.
 | 
			
		||||
 *             This function returns NRF_ERROR_NULL if the value of evt_handler in p_dfu_init
 | 
			
		||||
 *             structure provided is NULL or if the pointers supplied as input are NULL.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t ble_dfu_init(ble_dfu_t * p_dfu, ble_dfu_init_t * p_dfu_init);
 | 
			
		||||
 | 
			
		||||
/**@brief       Function for sending response to a control point command.
 | 
			
		||||
 *
 | 
			
		||||
 * @details     This function will encode a DFU Control Point response using the given input
 | 
			
		||||
 *              parameters and will send a notification of the same to the peer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   p_dfu       Pointer to the DFU service structure.
 | 
			
		||||
 * @param[in]   dfu_proc    Procedure for which this response is to be sent.
 | 
			
		||||
 * @param[in]   resp_val    Response value.
 | 
			
		||||
 *
 | 
			
		||||
 * @return      NRF_SUCCESS if the DFU Service has successfully requested the SoftDevice to
 | 
			
		||||
 *              send the notification. Otherwise an error code.
 | 
			
		||||
 *              This function returns NRF_ERROR_INVALID_STATE if the device is not connected to a
 | 
			
		||||
 *              peer or if the DFU service is not initialized or if the notification of the DFU
 | 
			
		||||
 *              Status Report characteristic was not enabled by the peer. It returns NRF_ERROR_NULL
 | 
			
		||||
 *              if the pointer p_dfu is NULL.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t ble_dfu_response_send(ble_dfu_t *          p_dfu,
 | 
			
		||||
                               ble_dfu_procedure_t  dfu_proc,
 | 
			
		||||
                               ble_dfu_resp_val_t   resp_val);
 | 
			
		||||
 | 
			
		||||
/**@brief      Function for notifying the peer about the number of bytes of firmware data received.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]  p_dfu                      Pointer to the DFU service structure.
 | 
			
		||||
 * @param[in]  num_of_firmware_bytes_rcvd Number of bytes.
 | 
			
		||||
 *
 | 
			
		||||
 * @return     NRF_SUCCESS if the DFU Service has successfully requested the SoftDevice to send
 | 
			
		||||
 *             the notification. Otherwise an error code.
 | 
			
		||||
 *             This function returns NRF_ERROR_INVALID_STATE if the device is not connected to a
 | 
			
		||||
 *             peer or if the DFU service is not initialized or if the notification of the DFU
 | 
			
		||||
 *             Status Report characteristic was not enabled by the peer. It returns NRF_ERROR_NULL
 | 
			
		||||
 *             if the pointer p_dfu is NULL.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t ble_dfu_bytes_rcvd_report(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd);
 | 
			
		||||
 | 
			
		||||
/**@brief      Function for sending Packet Receipt Notification to the peer.
 | 
			
		||||
 *
 | 
			
		||||
 *             This function will encode the number of bytes received as input parameter into a
 | 
			
		||||
 *             notification of the control point characteristic and send it to the peer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]  p_dfu                      Pointer to the DFU service structure.
 | 
			
		||||
 * @param[in]  num_of_firmware_bytes_rcvd Number of bytes of firmware image received.
 | 
			
		||||
 *
 | 
			
		||||
 * @return     NRF_SUCCESS if the DFU Service has successfully requested the SoftDevice to send
 | 
			
		||||
 *             the notification. Otherwise an error code.
 | 
			
		||||
 *             This function returns NRF_ERROR_INVALID_STATE if the device is not connected to a
 | 
			
		||||
 *             peer or if the DFU service is not initialized or if the notification of the DFU
 | 
			
		||||
 *             Status Report characteristic was not enabled by the peer. It returns NRF_ERROR_NULL
 | 
			
		||||
 *             if the pointer p_dfu is NULL.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t ble_dfu_pkts_rcpt_notify(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd);
 | 
			
		||||
 | 
			
		||||
#endif // BLE_DFU_H__
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
@@ -0,0 +1,277 @@
 | 
			
		||||
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Attention! 
 | 
			
		||||
*  To maintain compliance with Nordic Semiconductor ASA<53>s Bluetooth profile 
 | 
			
		||||
*  qualification listings, this section of source code must not be modified.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "ble_dis.h"
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "app_error.h"
 | 
			
		||||
#include "ble_gatts.h"
 | 
			
		||||
#include "nordic_common.h"
 | 
			
		||||
#include "ble_srv_common.h"
 | 
			
		||||
#include "app_util.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define BLE_DIS_SYS_ID_LEN 8  /**< Length of System ID Characteristic Value. */
 | 
			
		||||
#define BLE_DIS_PNP_ID_LEN 7  /**< Length of Pnp ID Characteristic Value. */
 | 
			
		||||
 | 
			
		||||
static uint16_t                 service_handle;
 | 
			
		||||
static ble_gatts_char_handles_t manufact_name_handles;
 | 
			
		||||
static ble_gatts_char_handles_t model_num_handles;
 | 
			
		||||
static ble_gatts_char_handles_t serial_num_handles;
 | 
			
		||||
static ble_gatts_char_handles_t hw_rev_handles;
 | 
			
		||||
static ble_gatts_char_handles_t fw_rev_handles;
 | 
			
		||||
static ble_gatts_char_handles_t sw_rev_handles;
 | 
			
		||||
static ble_gatts_char_handles_t sys_id_handles;
 | 
			
		||||
static ble_gatts_char_handles_t reg_cert_data_list_handles;
 | 
			
		||||
static ble_gatts_char_handles_t pnp_id_handles;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Function for encoding a System ID.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[out]  p_encoded_buffer   Buffer where the encoded data will be written.
 | 
			
		||||
 * @param[in]   p_sys_id           System ID to be encoded.
 | 
			
		||||
 */
 | 
			
		||||
static void sys_id_encode(uint8_t * p_encoded_buffer, const ble_dis_sys_id_t * p_sys_id)
 | 
			
		||||
{
 | 
			
		||||
    APP_ERROR_CHECK_BOOL(p_sys_id != NULL);
 | 
			
		||||
    APP_ERROR_CHECK_BOOL(p_encoded_buffer != NULL);
 | 
			
		||||
 | 
			
		||||
    p_encoded_buffer[0] = (p_sys_id->manufacturer_id & 0x00000000FF);
 | 
			
		||||
    p_encoded_buffer[1] = (p_sys_id->manufacturer_id & 0x000000FF00) >> 8;
 | 
			
		||||
    p_encoded_buffer[2] = (p_sys_id->manufacturer_id & 0x0000FF0000) >> 16;
 | 
			
		||||
    p_encoded_buffer[3] = (p_sys_id->manufacturer_id & 0x00FF000000) >> 24;
 | 
			
		||||
    p_encoded_buffer[4] = (p_sys_id->manufacturer_id & 0xFF00000000) >> 32;
 | 
			
		||||
 | 
			
		||||
    p_encoded_buffer[5] = (p_sys_id->organizationally_unique_id & 0x0000FF);
 | 
			
		||||
    p_encoded_buffer[6] = (p_sys_id->organizationally_unique_id & 0x00FF00) >> 8;
 | 
			
		||||
    p_encoded_buffer[7] = (p_sys_id->organizationally_unique_id & 0xFF0000) >> 16;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Function for encoding a PnP ID.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[out]  p_encoded_buffer   Buffer where the encoded data will be written.
 | 
			
		||||
 * @param[in]   p_pnp_id           PnP ID to be encoded.
 | 
			
		||||
 */
 | 
			
		||||
static void pnp_id_encode(uint8_t * p_encoded_buffer, const ble_dis_pnp_id_t * p_pnp_id)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t len = 0;
 | 
			
		||||
 | 
			
		||||
    APP_ERROR_CHECK_BOOL(p_pnp_id != NULL);
 | 
			
		||||
    APP_ERROR_CHECK_BOOL(p_encoded_buffer != NULL);
 | 
			
		||||
 | 
			
		||||
    p_encoded_buffer[len++] = p_pnp_id->vendor_id_source;
 | 
			
		||||
 | 
			
		||||
    len += uint16_encode(p_pnp_id->vendor_id, &p_encoded_buffer[len]);
 | 
			
		||||
    len += uint16_encode(p_pnp_id->product_id, &p_encoded_buffer[len]);
 | 
			
		||||
    len += uint16_encode(p_pnp_id->product_version, &p_encoded_buffer[len]);
 | 
			
		||||
 | 
			
		||||
    APP_ERROR_CHECK_BOOL(len == BLE_DIS_PNP_ID_LEN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Function for adding the Characteristic.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   uuid           UUID of characteristic to be added.
 | 
			
		||||
 * @param[in]   p_char_value   Initial value of characteristic to be added.
 | 
			
		||||
 * @param[in]   char_len       Length of initial value. This will also be the maximum value.
 | 
			
		||||
 * @param[in]   dis_attr_md    Security settings of characteristic to be added.
 | 
			
		||||
 * @param[out]  p_handles      Handles of new characteristic.
 | 
			
		||||
 *
 | 
			
		||||
 * @return      NRF_SUCCESS on success, otherwise an error code.
 | 
			
		||||
 */
 | 
			
		||||
static uint32_t char_add(uint16_t                        uuid,
 | 
			
		||||
                         uint8_t                       * p_char_value,
 | 
			
		||||
                         uint16_t                        char_len,
 | 
			
		||||
                         const ble_srv_security_mode_t * dis_attr_md,
 | 
			
		||||
                         ble_gatts_char_handles_t      * p_handles)
 | 
			
		||||
{
 | 
			
		||||
    ble_uuid_t          ble_uuid;
 | 
			
		||||
    ble_gatts_char_md_t char_md;
 | 
			
		||||
    ble_gatts_attr_t    attr_char_value;
 | 
			
		||||
    ble_gatts_attr_md_t attr_md;
 | 
			
		||||
 | 
			
		||||
    APP_ERROR_CHECK_BOOL(p_char_value != NULL);
 | 
			
		||||
    APP_ERROR_CHECK_BOOL(char_len > 0);
 | 
			
		||||
 | 
			
		||||
    // The ble_gatts_char_md_t structure uses bit fields. So we reset the memory to zero.
 | 
			
		||||
    memset(&char_md, 0, sizeof(char_md));
 | 
			
		||||
 | 
			
		||||
    char_md.char_props.read  = 1;
 | 
			
		||||
    char_md.p_char_user_desc = NULL;
 | 
			
		||||
    char_md.p_char_pf        = NULL;
 | 
			
		||||
    char_md.p_user_desc_md   = NULL;
 | 
			
		||||
    char_md.p_cccd_md        = NULL;
 | 
			
		||||
    char_md.p_sccd_md        = NULL;
 | 
			
		||||
 | 
			
		||||
    BLE_UUID_BLE_ASSIGN(ble_uuid, uuid);
 | 
			
		||||
 | 
			
		||||
    memset(&attr_md, 0, sizeof(attr_md));
 | 
			
		||||
 | 
			
		||||
    attr_md.read_perm  = dis_attr_md->read_perm;
 | 
			
		||||
    attr_md.write_perm = dis_attr_md->write_perm;
 | 
			
		||||
    attr_md.vloc       = BLE_GATTS_VLOC_STACK;
 | 
			
		||||
    attr_md.rd_auth    = 0;
 | 
			
		||||
    attr_md.wr_auth    = 0;
 | 
			
		||||
    attr_md.vlen       = 0;
 | 
			
		||||
 | 
			
		||||
    memset(&attr_char_value, 0, sizeof(attr_char_value));
 | 
			
		||||
 | 
			
		||||
    attr_char_value.p_uuid    = &ble_uuid;
 | 
			
		||||
    attr_char_value.p_attr_md = &attr_md;
 | 
			
		||||
    attr_char_value.init_len  = char_len;
 | 
			
		||||
    attr_char_value.init_offs = 0;
 | 
			
		||||
    attr_char_value.max_len   = char_len;
 | 
			
		||||
    attr_char_value.p_value   = p_char_value;
 | 
			
		||||
 | 
			
		||||
    return sd_ble_gatts_characteristic_add(service_handle, &char_md, &attr_char_value, p_handles);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t ble_dis_init(const ble_dis_init_t * p_dis_init)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t   err_code;
 | 
			
		||||
    ble_uuid_t ble_uuid;
 | 
			
		||||
 | 
			
		||||
    // Add service
 | 
			
		||||
    BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_DEVICE_INFORMATION_SERVICE);
 | 
			
		||||
 | 
			
		||||
    err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &service_handle);
 | 
			
		||||
    if (err_code != NRF_SUCCESS)
 | 
			
		||||
    {
 | 
			
		||||
        return err_code;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Add characteristics
 | 
			
		||||
    if (p_dis_init->manufact_name_str.length > 0)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = char_add(BLE_UUID_MANUFACTURER_NAME_STRING_CHAR,
 | 
			
		||||
                            p_dis_init->manufact_name_str.p_str,
 | 
			
		||||
                            p_dis_init->manufact_name_str.length,
 | 
			
		||||
                            &p_dis_init->dis_attr_md,
 | 
			
		||||
                            &manufact_name_handles);
 | 
			
		||||
        if (err_code != NRF_SUCCESS)
 | 
			
		||||
        {
 | 
			
		||||
            return err_code;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (p_dis_init->model_num_str.length > 0)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = char_add(BLE_UUID_MODEL_NUMBER_STRING_CHAR,
 | 
			
		||||
                            p_dis_init->model_num_str.p_str,
 | 
			
		||||
                            p_dis_init->model_num_str.length,
 | 
			
		||||
                            &p_dis_init->dis_attr_md,
 | 
			
		||||
                            &model_num_handles);
 | 
			
		||||
        if (err_code != NRF_SUCCESS)
 | 
			
		||||
        {
 | 
			
		||||
            return err_code;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (p_dis_init->serial_num_str.length > 0)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = char_add(BLE_UUID_SERIAL_NUMBER_STRING_CHAR,
 | 
			
		||||
                            p_dis_init->serial_num_str.p_str,
 | 
			
		||||
                            p_dis_init->serial_num_str.length,
 | 
			
		||||
                            &p_dis_init->dis_attr_md,
 | 
			
		||||
                            &serial_num_handles);
 | 
			
		||||
        if (err_code != NRF_SUCCESS)
 | 
			
		||||
        {
 | 
			
		||||
            return err_code;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (p_dis_init->hw_rev_str.length > 0)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = char_add(BLE_UUID_HARDWARE_REVISION_STRING_CHAR,
 | 
			
		||||
                            p_dis_init->hw_rev_str.p_str,
 | 
			
		||||
                            p_dis_init->hw_rev_str.length,
 | 
			
		||||
                            &p_dis_init->dis_attr_md,
 | 
			
		||||
                            &hw_rev_handles);
 | 
			
		||||
        if (err_code != NRF_SUCCESS)
 | 
			
		||||
        {
 | 
			
		||||
            return err_code;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (p_dis_init->fw_rev_str.length > 0)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = char_add(BLE_UUID_FIRMWARE_REVISION_STRING_CHAR,
 | 
			
		||||
                            p_dis_init->fw_rev_str.p_str,
 | 
			
		||||
                            p_dis_init->fw_rev_str.length,
 | 
			
		||||
                            &p_dis_init->dis_attr_md,
 | 
			
		||||
                            &fw_rev_handles);
 | 
			
		||||
        if (err_code != NRF_SUCCESS)
 | 
			
		||||
        {
 | 
			
		||||
            return err_code;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (p_dis_init->sw_rev_str.length > 0)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = char_add(BLE_UUID_SOFTWARE_REVISION_STRING_CHAR,
 | 
			
		||||
                            p_dis_init->sw_rev_str.p_str,
 | 
			
		||||
                            p_dis_init->sw_rev_str.length,
 | 
			
		||||
                            &p_dis_init->dis_attr_md,
 | 
			
		||||
                            &sw_rev_handles);
 | 
			
		||||
        if (err_code != NRF_SUCCESS)
 | 
			
		||||
        {
 | 
			
		||||
            return err_code;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (p_dis_init->p_sys_id != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        uint8_t encoded_sys_id[BLE_DIS_SYS_ID_LEN];
 | 
			
		||||
 | 
			
		||||
        sys_id_encode(encoded_sys_id, p_dis_init->p_sys_id);
 | 
			
		||||
        err_code = char_add(BLE_UUID_SYSTEM_ID_CHAR,
 | 
			
		||||
                            encoded_sys_id,
 | 
			
		||||
                            BLE_DIS_SYS_ID_LEN,
 | 
			
		||||
                            &p_dis_init->dis_attr_md,
 | 
			
		||||
                            &sys_id_handles);
 | 
			
		||||
        if (err_code != NRF_SUCCESS)
 | 
			
		||||
        {
 | 
			
		||||
            return err_code;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (p_dis_init->p_reg_cert_data_list != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = char_add(BLE_UUID_IEEE_REGULATORY_CERTIFICATION_DATA_LIST_CHAR,
 | 
			
		||||
                            p_dis_init->p_reg_cert_data_list->p_list,
 | 
			
		||||
                            p_dis_init->p_reg_cert_data_list->list_len,
 | 
			
		||||
                            &p_dis_init->dis_attr_md,
 | 
			
		||||
                            ®_cert_data_list_handles);
 | 
			
		||||
        if (err_code != NRF_SUCCESS)
 | 
			
		||||
        {
 | 
			
		||||
            return err_code;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (p_dis_init->p_pnp_id != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        uint8_t encoded_pnp_id[BLE_DIS_PNP_ID_LEN];
 | 
			
		||||
 | 
			
		||||
        pnp_id_encode(encoded_pnp_id, p_dis_init->p_pnp_id);
 | 
			
		||||
        err_code = char_add(BLE_UUID_PNP_ID_CHAR,
 | 
			
		||||
                            encoded_pnp_id,
 | 
			
		||||
                            BLE_DIS_PNP_ID_LEN,
 | 
			
		||||
                            &p_dis_init->dis_attr_md,
 | 
			
		||||
                            &pnp_id_handles);
 | 
			
		||||
        if (err_code != NRF_SUCCESS)
 | 
			
		||||
        {
 | 
			
		||||
            return err_code;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,98 @@
 | 
			
		||||
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * @defgroup ble_sdk_srv_dis Device Information Service
 | 
			
		||||
 * @{
 | 
			
		||||
 * @ingroup ble_sdk_srv
 | 
			
		||||
 * @brief Device Information Service module.
 | 
			
		||||
 *
 | 
			
		||||
 * @details This module implements the Device Information Service.
 | 
			
		||||
 *          During initialization it adds the Device Information Service to the BLE stack database.
 | 
			
		||||
 *          It then encodes the supplied information, and adds the curresponding characteristics.
 | 
			
		||||
 *
 | 
			
		||||
 * @note Attention! 
 | 
			
		||||
 *  To maintain compliance with Nordic Semiconductor ASA Bluetooth profile 
 | 
			
		||||
 *  qualification listings, this section of source code must not be modified.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef BLE_DIS_H__
 | 
			
		||||
#define BLE_DIS_H__
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "ble_srv_common.h"
 | 
			
		||||
 | 
			
		||||
/** @defgroup DIS_VENDOR_ID_SRC_VALUES Vendor ID Source values  
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
#define BLE_DIS_VENDOR_ID_SRC_BLUETOOTH_SIG   1                 /**< Vendor ID assigned by Bluetooth SIG. */
 | 
			
		||||
#define BLE_DIS_VENDOR_ID_SRC_USB_IMPL_FORUM  2                 /**< Vendor ID assigned by USB Implementer's Forum. */
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
/**@brief System ID parameters */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    uint64_t manufacturer_id;                                   /**< Manufacturer ID. Only 5 LSOs shall be used. */
 | 
			
		||||
    uint32_t organizationally_unique_id;                        /**< Organizationally unique ID. Only 3 LSOs shall be used. */
 | 
			
		||||
} ble_dis_sys_id_t;
 | 
			
		||||
 | 
			
		||||
/**@brief IEEE 11073-20601 Regulatory Certification Data List Structure */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *  p_list;                                          /**< Pointer the byte array containing the encoded opaque structure based on IEEE 11073-20601 specification. */
 | 
			
		||||
    uint8_t    list_len;                                        /**< Length of the byte array. */
 | 
			
		||||
} ble_dis_reg_cert_data_list_t;
 | 
			
		||||
 | 
			
		||||
/**@brief PnP ID parameters */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    uint8_t  vendor_id_source;                                  /**< Vendor ID Source. see @ref DIS_VENDOR_ID_SRC_VALUES. */
 | 
			
		||||
    uint16_t vendor_id;                                         /**< Vendor ID. */
 | 
			
		||||
    uint16_t product_id;                                        /**< Product ID. */
 | 
			
		||||
    uint16_t product_version;                                   /**< Product Version. */
 | 
			
		||||
} ble_dis_pnp_id_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Device Information Service init structure. This contains all possible characteristics 
 | 
			
		||||
 *        needed for initialization of the service.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    ble_srv_utf8_str_t             manufact_name_str;           /**< Manufacturer Name String. */
 | 
			
		||||
    ble_srv_utf8_str_t             model_num_str;               /**< Model Number String. */
 | 
			
		||||
    ble_srv_utf8_str_t             serial_num_str;              /**< Serial Number String. */
 | 
			
		||||
    ble_srv_utf8_str_t             hw_rev_str;                  /**< Hardware Revision String. */
 | 
			
		||||
    ble_srv_utf8_str_t             fw_rev_str;                  /**< Firmware Revision String. */
 | 
			
		||||
    ble_srv_utf8_str_t             sw_rev_str;                  /**< Software Revision String. */
 | 
			
		||||
    ble_dis_sys_id_t *             p_sys_id;                    /**< System ID. */
 | 
			
		||||
    ble_dis_reg_cert_data_list_t * p_reg_cert_data_list;        /**< IEEE 11073-20601 Regulatory Certification Data List. */
 | 
			
		||||
    ble_dis_pnp_id_t *             p_pnp_id;                    /**< PnP ID. */
 | 
			
		||||
    ble_srv_security_mode_t        dis_attr_md;                 /**< Initial Security Setting for Device Information Characteristics. */
 | 
			
		||||
} ble_dis_init_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Function for initializing the Device Information Service.
 | 
			
		||||
 *
 | 
			
		||||
 * @details This call allows the application to initialize the device information service. 
 | 
			
		||||
 *          It adds the DIS service and DIS characteristics to the database, using the initial
 | 
			
		||||
 *          values supplied through the p_dis_init parameter. Characteristics which are not to be
 | 
			
		||||
 *          added, shall be set to NULL in p_dis_init.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   p_dis_init   The structure containing the values of characteristics needed by the
 | 
			
		||||
 *                           service.
 | 
			
		||||
 *
 | 
			
		||||
 * @return      NRF_SUCCESS on successful initialization of service.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t ble_dis_init(const ble_dis_init_t * p_dis_init);
 | 
			
		||||
 | 
			
		||||
#endif // BLE_DIS_H__
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
							
								
								
									
										761
									
								
								nRF5_SDK_11.0.0_89a8197/components/ble/common/ble_advdata.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										761
									
								
								nRF5_SDK_11.0.0_89a8197/components/ble/common/ble_advdata.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,761 @@
 | 
			
		||||
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "ble_advdata.h"
 | 
			
		||||
#include "ble_gap.h"
 | 
			
		||||
#include "ble_srv_common.h"
 | 
			
		||||
#include "sdk_common.h"
 | 
			
		||||
 | 
			
		||||
// NOTE: For now, Security Manager Out of Band Flags (OOB) are omitted from the advertising data.
 | 
			
		||||
 | 
			
		||||
// Types of LE Bluetooth Device Address AD type
 | 
			
		||||
#define AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC 0UL
 | 
			
		||||
#define AD_TYPE_BLE_DEVICE_ADDR_TYPE_RANDOM 1UL
 | 
			
		||||
 | 
			
		||||
static uint32_t tk_value_encode(ble_advdata_tk_value_t * p_tk_value,
 | 
			
		||||
                                uint8_t                * p_encoded_data,
 | 
			
		||||
                                uint16_t               * p_offset,
 | 
			
		||||
                                uint16_t                 max_size)
 | 
			
		||||
{
 | 
			
		||||
    int8_t i;
 | 
			
		||||
 | 
			
		||||
    // Check for buffer overflow.
 | 
			
		||||
    if (((*p_offset) + AD_TYPE_TK_VALUE_SIZE) > max_size)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_DATA_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Encode LE Role.
 | 
			
		||||
    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_TK_VALUE_DATA_SIZE);
 | 
			
		||||
    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
 | 
			
		||||
    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE;
 | 
			
		||||
    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
 | 
			
		||||
 | 
			
		||||
    for (i = AD_TYPE_TK_VALUE_DATA_SIZE - 1; i >= 0; i--, (*p_offset)++)
 | 
			
		||||
    {
 | 
			
		||||
        p_encoded_data[*p_offset] = p_tk_value->tk[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t le_role_encode(ble_advdata_le_role_t   le_role,
 | 
			
		||||
                               uint8_t               * p_encoded_data,
 | 
			
		||||
                               uint16_t              * p_offset,
 | 
			
		||||
                               uint16_t                max_size)
 | 
			
		||||
{
 | 
			
		||||
    // Check for buffer overflow.
 | 
			
		||||
    if (((*p_offset) + AD_TYPE_LE_ROLE_SIZE) > max_size)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_DATA_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Encode LE Role.
 | 
			
		||||
    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_LE_ROLE_DATA_SIZE);
 | 
			
		||||
    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
 | 
			
		||||
    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_LE_ROLE;
 | 
			
		||||
    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
 | 
			
		||||
    switch(le_role)
 | 
			
		||||
    {
 | 
			
		||||
        case BLE_ADVDATA_ROLE_ONLY_PERIPH:
 | 
			
		||||
            p_encoded_data[*p_offset] = 0;
 | 
			
		||||
            break;
 | 
			
		||||
        case BLE_ADVDATA_ROLE_ONLY_CENTRAL:
 | 
			
		||||
            p_encoded_data[*p_offset] = 1;
 | 
			
		||||
            break;
 | 
			
		||||
        case BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED:
 | 
			
		||||
            p_encoded_data[*p_offset] = 2;
 | 
			
		||||
            break;
 | 
			
		||||
        case BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED:
 | 
			
		||||
            p_encoded_data[*p_offset] = 3;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            return NRF_ERROR_INVALID_PARAM;
 | 
			
		||||
    }
 | 
			
		||||
    *p_offset += AD_TYPE_LE_ROLE_DATA_SIZE;
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t ble_device_addr_encode(uint8_t  * p_encoded_data,
 | 
			
		||||
                                       uint16_t * p_offset,
 | 
			
		||||
                                       uint16_t   max_size)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
    ble_gap_addr_t device_addr;
 | 
			
		||||
 | 
			
		||||
    // Check for buffer overflow.
 | 
			
		||||
    if (((*p_offset) + AD_TYPE_BLE_DEVICE_ADDR_SIZE) > max_size)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_DATA_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Get BLE address
 | 
			
		||||
    err_code = sd_ble_gap_addr_get(&device_addr);
 | 
			
		||||
    VERIFY_SUCCESS(err_code);
 | 
			
		||||
 | 
			
		||||
    // Encode LE Bluetooth Device Address
 | 
			
		||||
    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE +
 | 
			
		||||
                                               AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE);
 | 
			
		||||
    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
 | 
			
		||||
    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS;
 | 
			
		||||
    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
 | 
			
		||||
    memcpy(&p_encoded_data[*p_offset], &device_addr.addr[0], BLE_GAP_ADDR_LEN);
 | 
			
		||||
    *p_offset                 += BLE_GAP_ADDR_LEN;
 | 
			
		||||
    if(BLE_GAP_ADDR_TYPE_PUBLIC == device_addr.addr_type)
 | 
			
		||||
    {
 | 
			
		||||
        p_encoded_data[*p_offset] = AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        p_encoded_data[*p_offset] = AD_TYPE_BLE_DEVICE_ADDR_TYPE_RANDOM;
 | 
			
		||||
    }
 | 
			
		||||
    *p_offset += AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE;
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t name_encode(const ble_advdata_t * p_advdata,
 | 
			
		||||
                            uint8_t             * p_encoded_data,
 | 
			
		||||
                            uint16_t            * p_offset,
 | 
			
		||||
                            uint16_t              max_size)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
    uint16_t rem_adv_data_len;
 | 
			
		||||
    uint16_t actual_length;
 | 
			
		||||
    uint8_t  adv_data_format;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Validate parameters
 | 
			
		||||
    if((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) && (0 == p_advdata->short_name_len))
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_INVALID_PARAM;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Check for buffer overflow.
 | 
			
		||||
    if ( (((*p_offset) + ADV_AD_DATA_OFFSET) > max_size) ||
 | 
			
		||||
         ( (BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) &&
 | 
			
		||||
           (((*p_offset) + ADV_AD_DATA_OFFSET + p_advdata->short_name_len) > max_size)))
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_DATA_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rem_adv_data_len = max_size - (*p_offset) - ADV_AD_DATA_OFFSET;
 | 
			
		||||
    actual_length    = rem_adv_data_len;
 | 
			
		||||
 | 
			
		||||
    // Get GAP device name and length
 | 
			
		||||
    err_code = sd_ble_gap_device_name_get(&p_encoded_data[(*p_offset) + ADV_AD_DATA_OFFSET],
 | 
			
		||||
                                          &actual_length);
 | 
			
		||||
    VERIFY_SUCCESS(err_code);
 | 
			
		||||
    
 | 
			
		||||
    // Check if device intend to use short name and it can fit available data size.
 | 
			
		||||
    if ((p_advdata->name_type == BLE_ADVDATA_FULL_NAME) && (actual_length <= rem_adv_data_len))
 | 
			
		||||
    {
 | 
			
		||||
        // Complete device name can fit, setting Complete Name in Adv Data.
 | 
			
		||||
        adv_data_format = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        // Else short name needs to be used. Or application has requested use of short name.
 | 
			
		||||
        adv_data_format = BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME;
 | 
			
		||||
 | 
			
		||||
        // If application has set a preference on the short name size, it needs to be considered,
 | 
			
		||||
        // else fit what can be fit.
 | 
			
		||||
        if ((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) &&
 | 
			
		||||
                (p_advdata->short_name_len <= rem_adv_data_len))
 | 
			
		||||
        {
 | 
			
		||||
            // Short name fits available size.
 | 
			
		||||
            actual_length = p_advdata->short_name_len;
 | 
			
		||||
        }
 | 
			
		||||
        // Else whatever can fit the data buffer will be packed.
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            actual_length = rem_adv_data_len;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // There is only 1 byte intended to encode length which is (actual_length + ADV_AD_TYPE_FIELD_SIZE)
 | 
			
		||||
    if(actual_length > (0x00FF - ADV_AD_TYPE_FIELD_SIZE))
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_DATA_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Complete name field in encoded data.
 | 
			
		||||
    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + actual_length);
 | 
			
		||||
    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
 | 
			
		||||
    p_encoded_data[*p_offset]  = adv_data_format;
 | 
			
		||||
    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
 | 
			
		||||
    *p_offset                 += actual_length;
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static uint32_t appearance_encode(uint8_t  * p_encoded_data,
 | 
			
		||||
                                  uint16_t * p_offset,
 | 
			
		||||
                                  uint16_t   max_size)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
    uint16_t appearance;
 | 
			
		||||
 | 
			
		||||
    // Check for buffer overflow.
 | 
			
		||||
    if (((*p_offset) + AD_TYPE_APPEARANCE_SIZE) > max_size)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_DATA_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Get GAP appearance field.
 | 
			
		||||
    err_code = sd_ble_gap_appearance_get(&appearance);
 | 
			
		||||
    VERIFY_SUCCESS(err_code);
 | 
			
		||||
 | 
			
		||||
    // Encode Length, AD Type and Appearance.
 | 
			
		||||
    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_APPEARANCE_DATA_SIZE);
 | 
			
		||||
    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
 | 
			
		||||
    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_APPEARANCE;
 | 
			
		||||
    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
 | 
			
		||||
    *p_offset                 += uint16_encode(appearance, &p_encoded_data[*p_offset]);
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t flags_encode(int8_t     flags,
 | 
			
		||||
                             uint8_t  * p_encoded_data,
 | 
			
		||||
                             uint16_t * p_offset,
 | 
			
		||||
                             uint16_t   max_size)
 | 
			
		||||
{
 | 
			
		||||
    // Check for buffer overflow.
 | 
			
		||||
    if (((*p_offset) + AD_TYPE_FLAGS_SIZE) > max_size)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_DATA_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Encode flags.
 | 
			
		||||
    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_FLAGS_DATA_SIZE);
 | 
			
		||||
    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
 | 
			
		||||
    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_FLAGS;
 | 
			
		||||
    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
 | 
			
		||||
    p_encoded_data[*p_offset]  = flags;
 | 
			
		||||
    *p_offset                 += AD_TYPE_FLAGS_DATA_SIZE;
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t sec_mgr_oob_flags_encode(uint8_t    oob_flags,
 | 
			
		||||
                                         uint8_t  * p_encoded_data,
 | 
			
		||||
                                         uint16_t * p_offset,
 | 
			
		||||
                                         uint16_t   max_size)
 | 
			
		||||
{
 | 
			
		||||
    // Check for buffer overflow.
 | 
			
		||||
    if (((*p_offset) + AD_TYPE_OOB_FLAGS_SIZE) > max_size)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_DATA_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Encode flags.
 | 
			
		||||
    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_OOB_FLAGS_DATA_SIZE);
 | 
			
		||||
    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
 | 
			
		||||
    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS;
 | 
			
		||||
    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
 | 
			
		||||
    p_encoded_data[*p_offset]  = oob_flags;
 | 
			
		||||
    *p_offset                 += AD_TYPE_OOB_FLAGS_DATA_SIZE;
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t tx_power_level_encode(int8_t     tx_power_level,
 | 
			
		||||
                                      uint8_t  * p_encoded_data,
 | 
			
		||||
                                      uint16_t * p_offset,
 | 
			
		||||
                                      uint16_t   max_size)
 | 
			
		||||
{
 | 
			
		||||
    // Check for buffer overflow.
 | 
			
		||||
    if (((*p_offset) + AD_TYPE_TX_POWER_LEVEL_SIZE) > max_size)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_DATA_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Encode TX Power Level.
 | 
			
		||||
    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE +
 | 
			
		||||
                                                  AD_TYPE_TX_POWER_LEVEL_DATA_SIZE);
 | 
			
		||||
    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
 | 
			
		||||
    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_TX_POWER_LEVEL;
 | 
			
		||||
    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
 | 
			
		||||
    p_encoded_data[*p_offset]  = tx_power_level;
 | 
			
		||||
    *p_offset                 += AD_TYPE_TX_POWER_LEVEL_DATA_SIZE;
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static uint32_t uuid_list_sized_encode(const ble_advdata_uuid_list_t * p_uuid_list,
 | 
			
		||||
                                       uint8_t                         adv_type,
 | 
			
		||||
                                       uint8_t                         uuid_size,
 | 
			
		||||
                                       uint8_t                       * p_encoded_data,
 | 
			
		||||
                                       uint16_t                      * p_offset,
 | 
			
		||||
                                       uint16_t                        max_size)
 | 
			
		||||
{
 | 
			
		||||
    int      i;
 | 
			
		||||
    bool     is_heading_written = false;
 | 
			
		||||
    uint16_t start_pos          = *p_offset;
 | 
			
		||||
    uint16_t length;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < p_uuid_list->uuid_cnt; i++)
 | 
			
		||||
    {
 | 
			
		||||
        uint32_t   err_code;
 | 
			
		||||
        uint8_t    encoded_size;
 | 
			
		||||
        ble_uuid_t uuid = p_uuid_list->p_uuids[i];
 | 
			
		||||
        
 | 
			
		||||
        // Find encoded uuid size.
 | 
			
		||||
        err_code = sd_ble_uuid_encode(&uuid, &encoded_size, NULL);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
 | 
			
		||||
        // Check size.
 | 
			
		||||
        if (encoded_size == uuid_size)
 | 
			
		||||
        {
 | 
			
		||||
            uint8_t heading_bytes = (is_heading_written) ? 0 : ADV_AD_DATA_OFFSET;
 | 
			
		||||
            
 | 
			
		||||
            // Check for buffer overflow
 | 
			
		||||
            if (((*p_offset) + encoded_size + heading_bytes) > max_size)
 | 
			
		||||
            {
 | 
			
		||||
                return NRF_ERROR_DATA_SIZE;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!is_heading_written)
 | 
			
		||||
            {
 | 
			
		||||
                // Write AD structure heading.
 | 
			
		||||
                *p_offset                 += ADV_LENGTH_FIELD_SIZE;
 | 
			
		||||
                p_encoded_data[*p_offset]  = adv_type;
 | 
			
		||||
                *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
 | 
			
		||||
                is_heading_written         = true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Write UUID.
 | 
			
		||||
            err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &p_encoded_data[*p_offset]);
 | 
			
		||||
            VERIFY_SUCCESS(err_code);
 | 
			
		||||
            *p_offset += encoded_size;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (is_heading_written)
 | 
			
		||||
    {
 | 
			
		||||
        // Write length.
 | 
			
		||||
        length = (*p_offset) - (start_pos + ADV_LENGTH_FIELD_SIZE);
 | 
			
		||||
        // There is only 1 byte intended to encode length
 | 
			
		||||
        if(length > 0x00FF)
 | 
			
		||||
        {
 | 
			
		||||
            return NRF_ERROR_DATA_SIZE;
 | 
			
		||||
        }
 | 
			
		||||
        p_encoded_data[start_pos] = (uint8_t)length;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static uint32_t uuid_list_encode(const ble_advdata_uuid_list_t * p_uuid_list,
 | 
			
		||||
                                 uint8_t                         adv_type_16,
 | 
			
		||||
                                 uint8_t                         adv_type_128,
 | 
			
		||||
                                 uint8_t                       * p_encoded_data,
 | 
			
		||||
                                 uint16_t                      * p_offset,
 | 
			
		||||
                                 uint16_t                        max_size)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
 | 
			
		||||
    // Encode 16 bit UUIDs.
 | 
			
		||||
    err_code = uuid_list_sized_encode(p_uuid_list,
 | 
			
		||||
                                      adv_type_16,
 | 
			
		||||
                                      sizeof(uint16_le_t),
 | 
			
		||||
                                      p_encoded_data,
 | 
			
		||||
                                      p_offset,
 | 
			
		||||
                                      max_size);
 | 
			
		||||
    VERIFY_SUCCESS(err_code);
 | 
			
		||||
 | 
			
		||||
    // Encode 128 bit UUIDs.
 | 
			
		||||
    err_code = uuid_list_sized_encode(p_uuid_list,
 | 
			
		||||
                                      adv_type_128,
 | 
			
		||||
                                      sizeof(ble_uuid128_t),
 | 
			
		||||
                                      p_encoded_data,
 | 
			
		||||
                                      p_offset,
 | 
			
		||||
                                      max_size);
 | 
			
		||||
    VERIFY_SUCCESS(err_code);
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static uint32_t conn_int_check(const ble_advdata_conn_int_t *p_conn_int)
 | 
			
		||||
{
 | 
			
		||||
    // Check Minimum Connection Interval.
 | 
			
		||||
    if ((p_conn_int->min_conn_interval < 0x0006) ||
 | 
			
		||||
        (
 | 
			
		||||
            (p_conn_int->min_conn_interval > 0x0c80) &&
 | 
			
		||||
            (p_conn_int->min_conn_interval != 0xffff)
 | 
			
		||||
        )
 | 
			
		||||
       )
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_INVALID_PARAM;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Check Maximum Connection Interval.
 | 
			
		||||
    if ((p_conn_int->max_conn_interval < 0x0006) || 
 | 
			
		||||
        (
 | 
			
		||||
            (p_conn_int->max_conn_interval > 0x0c80) && 
 | 
			
		||||
            (p_conn_int->max_conn_interval != 0xffff)
 | 
			
		||||
        )
 | 
			
		||||
       )
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_INVALID_PARAM;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Make sure Minimum Connection Interval is not bigger than Maximum Connection Interval.
 | 
			
		||||
    if ((p_conn_int->min_conn_interval != 0xffff) &&
 | 
			
		||||
        (p_conn_int->max_conn_interval != 0xffff) &&
 | 
			
		||||
        (p_conn_int->min_conn_interval > p_conn_int->max_conn_interval)
 | 
			
		||||
        )
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_INVALID_PARAM;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static uint32_t conn_int_encode(const ble_advdata_conn_int_t * p_conn_int,
 | 
			
		||||
                                uint8_t                      * p_encoded_data,
 | 
			
		||||
                                uint16_t                     * p_offset,
 | 
			
		||||
                                uint16_t                       max_size)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
 | 
			
		||||
    // Check for buffer overflow.
 | 
			
		||||
    if (((*p_offset) + AD_TYPE_CONN_INT_SIZE) > max_size)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_DATA_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Check parameters.
 | 
			
		||||
    err_code = conn_int_check(p_conn_int);
 | 
			
		||||
    VERIFY_SUCCESS(err_code);
 | 
			
		||||
 | 
			
		||||
    // Encode Length and AD Type.
 | 
			
		||||
    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_CONN_INT_DATA_SIZE);
 | 
			
		||||
    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
 | 
			
		||||
    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE;
 | 
			
		||||
    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
 | 
			
		||||
 | 
			
		||||
    // Encode Minimum and Maximum Connection Intervals.
 | 
			
		||||
    *p_offset += uint16_encode(p_conn_int->min_conn_interval, &p_encoded_data[*p_offset]);
 | 
			
		||||
    *p_offset += uint16_encode(p_conn_int->max_conn_interval, &p_encoded_data[*p_offset]);
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static uint32_t manuf_specific_data_encode(const ble_advdata_manuf_data_t * p_manuf_sp_data,
 | 
			
		||||
                                           uint8_t                        * p_encoded_data,
 | 
			
		||||
                                           uint16_t                       * p_offset,
 | 
			
		||||
                                           uint16_t                         max_size)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t data_size = AD_TYPE_MANUF_SPEC_DATA_ID_SIZE + p_manuf_sp_data->data.size;
 | 
			
		||||
 | 
			
		||||
    // Check for buffer overflow.
 | 
			
		||||
    if (((*p_offset) + ADV_AD_DATA_OFFSET + data_size) > max_size)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_DATA_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // There is only 1 byte intended to encode length which is (data_size + ADV_AD_TYPE_FIELD_SIZE)
 | 
			
		||||
    if(data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE))
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_DATA_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Encode Length and AD Type.
 | 
			
		||||
    p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + data_size);
 | 
			
		||||
    *p_offset                 += ADV_LENGTH_FIELD_SIZE;
 | 
			
		||||
    p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA;
 | 
			
		||||
    *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
 | 
			
		||||
    
 | 
			
		||||
    // Encode Company Identifier.
 | 
			
		||||
    *p_offset += uint16_encode(p_manuf_sp_data->company_identifier, &p_encoded_data[*p_offset]);
 | 
			
		||||
    
 | 
			
		||||
    // Encode additional manufacturer specific data.
 | 
			
		||||
    if (p_manuf_sp_data->data.size > 0)
 | 
			
		||||
    {
 | 
			
		||||
        if (p_manuf_sp_data->data.p_data == NULL)
 | 
			
		||||
        {
 | 
			
		||||
            return NRF_ERROR_INVALID_PARAM;
 | 
			
		||||
        }
 | 
			
		||||
        memcpy(&p_encoded_data[*p_offset], p_manuf_sp_data->data.p_data, p_manuf_sp_data->data.size);
 | 
			
		||||
        *p_offset += p_manuf_sp_data->data.size;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Implemented only for 16-bit UUIDs
 | 
			
		||||
static uint32_t service_data_encode(const ble_advdata_t * p_advdata,
 | 
			
		||||
                                    uint8_t             * p_encoded_data,
 | 
			
		||||
                                    uint16_t            * p_offset,
 | 
			
		||||
                                    uint16_t              max_size)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t i;
 | 
			
		||||
 | 
			
		||||
    // Check parameter consistency.
 | 
			
		||||
    if (p_advdata->p_service_data_array == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_INVALID_PARAM;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < p_advdata->service_data_count; i++)
 | 
			
		||||
    {
 | 
			
		||||
        ble_advdata_service_data_t * p_service_data;
 | 
			
		||||
        uint32_t                     data_size;
 | 
			
		||||
 | 
			
		||||
        p_service_data = &p_advdata->p_service_data_array[i];
 | 
			
		||||
        // For now implemented only for 16-bit UUIDs
 | 
			
		||||
        data_size      = AD_TYPE_SERV_DATA_16BIT_UUID_SIZE + p_service_data->data.size;
 | 
			
		||||
 | 
			
		||||
        // There is only 1 byte intended to encode length which is (data_size + ADV_AD_TYPE_FIELD_SIZE)
 | 
			
		||||
        if(data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE))
 | 
			
		||||
        {
 | 
			
		||||
            return NRF_ERROR_DATA_SIZE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Encode Length and AD Type.
 | 
			
		||||
        p_encoded_data[*p_offset]  = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + data_size);
 | 
			
		||||
        *p_offset                 += ADV_LENGTH_FIELD_SIZE;
 | 
			
		||||
        p_encoded_data[*p_offset]  = BLE_GAP_AD_TYPE_SERVICE_DATA;
 | 
			
		||||
        *p_offset                 += ADV_AD_TYPE_FIELD_SIZE;
 | 
			
		||||
 | 
			
		||||
        // Encode service 16-bit UUID.
 | 
			
		||||
        *p_offset += uint16_encode(p_service_data->service_uuid, &p_encoded_data[*p_offset]);
 | 
			
		||||
 | 
			
		||||
        // Encode additional service data.
 | 
			
		||||
        if (p_service_data->data.size > 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (p_service_data->data.p_data == NULL)
 | 
			
		||||
            {
 | 
			
		||||
                return NRF_ERROR_INVALID_PARAM;
 | 
			
		||||
            }
 | 
			
		||||
            memcpy(&p_encoded_data[*p_offset], p_service_data->data.p_data, p_service_data->data.size);
 | 
			
		||||
            *p_offset += p_service_data->data.size;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t adv_data_encode(ble_advdata_t const * const p_advdata,
 | 
			
		||||
                         uint8_t             * const p_encoded_data,
 | 
			
		||||
                         uint16_t            * const p_len)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code = NRF_SUCCESS;
 | 
			
		||||
    uint16_t max_size = *p_len;
 | 
			
		||||
    *p_len = 0;
 | 
			
		||||
 | 
			
		||||
    //Encode Security Manager OOB Flags
 | 
			
		||||
    if (p_advdata->p_sec_mgr_oob_flags != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = sec_mgr_oob_flags_encode(*p_advdata->p_sec_mgr_oob_flags,
 | 
			
		||||
                                             p_encoded_data,
 | 
			
		||||
                                             p_len,
 | 
			
		||||
                                             max_size);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
    }
 | 
			
		||||
		
 | 
			
		||||
    // Encode Security Manager TK value
 | 
			
		||||
    if (NULL != p_advdata->p_tk_value)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = tk_value_encode(p_advdata->p_tk_value, p_encoded_data, p_len, max_size);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Encode LE Role
 | 
			
		||||
    if (BLE_ADVDATA_ROLE_NOT_PRESENT != p_advdata->le_role)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = le_role_encode(p_advdata->le_role, p_encoded_data, p_len, max_size);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Encode LE Bluetooth Device Address
 | 
			
		||||
    if (p_advdata->include_ble_device_addr)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = ble_device_addr_encode(p_encoded_data, p_len, max_size);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Encode appearance.
 | 
			
		||||
    if (p_advdata->include_appearance)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = appearance_encode(p_encoded_data, p_len, max_size);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //Encode Flags
 | 
			
		||||
    if(p_advdata->flags != 0 )
 | 
			
		||||
    {
 | 
			
		||||
        err_code = flags_encode(p_advdata->flags, p_encoded_data, p_len, max_size);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
    } 
 | 
			
		||||
 | 
			
		||||
    // Encode TX power level.
 | 
			
		||||
    if (p_advdata->p_tx_power_level != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = tx_power_level_encode(*p_advdata->p_tx_power_level,
 | 
			
		||||
                                         p_encoded_data,
 | 
			
		||||
                                         p_len,
 | 
			
		||||
                                         max_size);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Encode 'more available' uuid list.
 | 
			
		||||
    if (p_advdata->uuids_more_available.uuid_cnt > 0)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = uuid_list_encode(&p_advdata->uuids_more_available,
 | 
			
		||||
                                    BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE,
 | 
			
		||||
                                    BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE,
 | 
			
		||||
                                    p_encoded_data,
 | 
			
		||||
                                    p_len,
 | 
			
		||||
                                    max_size);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Encode 'complete' uuid list.
 | 
			
		||||
    if (p_advdata->uuids_complete.uuid_cnt > 0)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = uuid_list_encode(&p_advdata->uuids_complete,
 | 
			
		||||
                                    BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE,
 | 
			
		||||
                                    BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE,
 | 
			
		||||
                                    p_encoded_data,
 | 
			
		||||
                                    p_len,
 | 
			
		||||
                                    max_size);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Encode 'solicited service' uuid list.
 | 
			
		||||
    if (p_advdata->uuids_solicited.uuid_cnt > 0)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = uuid_list_encode(&p_advdata->uuids_solicited,
 | 
			
		||||
                                    BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT,
 | 
			
		||||
                                    BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT,
 | 
			
		||||
                                    p_encoded_data,
 | 
			
		||||
                                    p_len,
 | 
			
		||||
                                    max_size);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Encode Slave Connection Interval Range.
 | 
			
		||||
    if (p_advdata->p_slave_conn_int != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = conn_int_encode(p_advdata->p_slave_conn_int, p_encoded_data, p_len, max_size);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Encode Manufacturer Specific Data.
 | 
			
		||||
    if (p_advdata->p_manuf_specific_data != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = manuf_specific_data_encode(p_advdata->p_manuf_specific_data,
 | 
			
		||||
                                              p_encoded_data,
 | 
			
		||||
                                              p_len,
 | 
			
		||||
                                              max_size);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Encode Service Data.
 | 
			
		||||
    if (p_advdata->service_data_count > 0)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = service_data_encode(p_advdata, p_encoded_data, p_len, max_size);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Encode name. WARNING: it is encoded last on purpose since too long device name is truncated.
 | 
			
		||||
    if (p_advdata->name_type != BLE_ADVDATA_NO_NAME)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = name_encode(p_advdata, p_encoded_data, p_len, max_size);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return err_code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static uint32_t advdata_check(const ble_advdata_t * p_advdata)
 | 
			
		||||
{
 | 
			
		||||
    // Flags must be included in advertising data, and the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag must be set.
 | 
			
		||||
    if (
 | 
			
		||||
        ((p_advdata->flags & BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) == 0)
 | 
			
		||||
       )
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_INVALID_PARAM;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static uint32_t srdata_check(const ble_advdata_t * p_srdata)
 | 
			
		||||
{
 | 
			
		||||
    // Flags shall not be included in the scan response data.
 | 
			
		||||
    if (p_srdata->flags)
 | 
			
		||||
    {
 | 
			
		||||
        return NRF_ERROR_INVALID_PARAM;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NRF_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t ble_advdata_set(const ble_advdata_t * p_advdata, const ble_advdata_t * p_srdata)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t  err_code;
 | 
			
		||||
    uint16_t  len_advdata = BLE_GAP_ADV_MAX_SIZE;
 | 
			
		||||
    uint16_t  len_srdata  = BLE_GAP_ADV_MAX_SIZE;
 | 
			
		||||
    uint8_t   encoded_advdata[BLE_GAP_ADV_MAX_SIZE];
 | 
			
		||||
    uint8_t   encoded_srdata[BLE_GAP_ADV_MAX_SIZE];
 | 
			
		||||
    uint8_t * p_encoded_advdata;
 | 
			
		||||
    uint8_t * p_encoded_srdata;
 | 
			
		||||
 | 
			
		||||
    // Encode advertising data (if supplied).
 | 
			
		||||
    if (p_advdata != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = advdata_check(p_advdata);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
 | 
			
		||||
        err_code = adv_data_encode(p_advdata, encoded_advdata, &len_advdata);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
        p_encoded_advdata = encoded_advdata;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        p_encoded_advdata = NULL;
 | 
			
		||||
        len_advdata = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Encode scan response data (if supplied).
 | 
			
		||||
    if (p_srdata != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        err_code = srdata_check(p_srdata);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
 | 
			
		||||
        err_code = adv_data_encode(p_srdata, encoded_srdata, &len_srdata);
 | 
			
		||||
        VERIFY_SUCCESS(err_code);
 | 
			
		||||
        p_encoded_srdata = encoded_srdata;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        p_encoded_srdata = NULL;
 | 
			
		||||
        len_srdata = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Pass encoded advertising data and/or scan response data to the stack.
 | 
			
		||||
    return sd_ble_gap_adv_data_set(p_encoded_advdata, len_advdata, p_encoded_srdata, len_srdata);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										212
									
								
								nRF5_SDK_11.0.0_89a8197/components/ble/common/ble_advdata.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								nRF5_SDK_11.0.0_89a8197/components/ble/common/ble_advdata.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,212 @@
 | 
			
		||||
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * @defgroup ble_sdk_lib_advdata Advertising and Scan Response Data Encoder
 | 
			
		||||
 * @{
 | 
			
		||||
 * @ingroup ble_sdk_lib
 | 
			
		||||
 * @brief Functions for encoding data in the Advertising and Scan Response Data format,
 | 
			
		||||
 *        and for passing the data to the stack.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef BLE_ADVDATA_H__
 | 
			
		||||
#define BLE_ADVDATA_H__
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "ble.h"
 | 
			
		||||
#include "app_util.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define ADV_LENGTH_FIELD_SIZE              1UL                                 /**< Advertising Data and Scan Response format contains 1 octet for the length. */
 | 
			
		||||
#define ADV_AD_TYPE_FIELD_SIZE             1UL                                 /**< Advertising Data and Scan Response format contains 1 octet for the AD type. */
 | 
			
		||||
#define ADV_AD_DATA_OFFSET                 (ADV_LENGTH_FIELD_SIZE + \
 | 
			
		||||
                                            ADV_AD_TYPE_FIELD_SIZE)            /**< Offset for the AD data field of the Advertising Data and Scan Response format. */
 | 
			
		||||
#define AD_TYPE_TK_VALUE_DATA_SIZE         (sizeof(ble_advdata_tk_value_t))    /**< Data size (in octets) of the Security Manager TK value AD type. */
 | 
			
		||||
#define AD_TYPE_TK_VALUE_SIZE              (ADV_AD_DATA_OFFSET + \
 | 
			
		||||
                                            AD_TYPE_TK_VALUE_DATA_SIZE)        /**< Size (in octets) of the Security Manager TK value AD type. */
 | 
			
		||||
#define AD_TYPE_LE_ROLE_DATA_SIZE          1UL                                 /**< Data size (in octets) of the LE Bluetooth Device Address AD type. */
 | 
			
		||||
#define AD_TYPE_LE_ROLE_SIZE               (ADV_AD_DATA_OFFSET + \
 | 
			
		||||
                                            AD_TYPE_LE_ROLE_DATA_SIZE)         /**< Size (in octets) of the LE Bluetooth Device Address AD type. */
 | 
			
		||||
#define AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE  1UL                                 /**< Data size (in octets) of the Address type of the LE Bluetooth Device Address AD type. */
 | 
			
		||||
#define AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE  (BLE_GAP_ADDR_LEN + \
 | 
			
		||||
                                            AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE) /**< Data size (in octets) of the LE Bluetooth Device Address AD type. */
 | 
			
		||||
#define AD_TYPE_BLE_DEVICE_ADDR_SIZE       (ADV_AD_DATA_OFFSET + \
 | 
			
		||||
                                            AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE) /**< Size (in octets) of the LE Bluetooth Device Address AD type. */
 | 
			
		||||
#define AD_TYPE_APPEARANCE_DATA_SIZE       2UL                                 /**< Data size (in octets) of the Appearance AD type. */
 | 
			
		||||
#define AD_TYPE_APPEARANCE_SIZE            (ADV_AD_DATA_OFFSET + \
 | 
			
		||||
                                            AD_TYPE_APPEARANCE_DATA_SIZE)      /**< Size (in octets) of the Appearance AD type. */
 | 
			
		||||
#define AD_TYPE_FLAGS_DATA_SIZE            1UL                                 /**< Data size (in octets) of the Flags AD type. */
 | 
			
		||||
#define AD_TYPE_FLAGS_SIZE                 (ADV_AD_DATA_OFFSET + \
 | 
			
		||||
                                            AD_TYPE_FLAGS_DATA_SIZE)           /**< Size (in octets) of the Flags AD type. */
 | 
			
		||||
#define AD_TYPE_TX_POWER_LEVEL_DATA_SIZE   1UL                                 /**< Data size (in octets) of the TX Power Level AD type. */
 | 
			
		||||
#define AD_TYPE_TX_POWER_LEVEL_SIZE        (ADV_AD_DATA_OFFSET + \
 | 
			
		||||
                                            AD_TYPE_TX_POWER_LEVEL_DATA_SIZE)  /**< Size (in octets) of the TX Power Level AD type. */
 | 
			
		||||
#define AD_TYPE_CONN_INT_DATA_SIZE         4UL                                 /**< Data size (in octets) of the Slave Connection Interval Range AD type. */
 | 
			
		||||
#define AD_TYPE_CONN_INT_SIZE              (ADV_AD_DATA_OFFSET + \
 | 
			
		||||
                                            AD_TYPE_CONN_INT_DATA_SIZE)        /**< Data size (in octets) of the Slave Connection Interval Range AD type. */
 | 
			
		||||
#define AD_TYPE_MANUF_SPEC_DATA_ID_SIZE    2UL                                 /**< Size (in octets) of the Company Identifier Code, which is a part of the Manufacturer Specific Data AD type. */
 | 
			
		||||
#define AD_TYPE_SERV_DATA_16BIT_UUID_SIZE  2UL                                 /**< Size (in octets) of the 16-bit UUID, which is a part of the Service Data AD type. */
 | 
			
		||||
#define AD_TYPE_OOB_FLAGS_DATA_SIZE        1UL                                 /**< Data size (in octets) of the Security Manager OOB Flags AD type. */
 | 
			
		||||
#define AD_TYPE_OOB_FLAGS_SIZE             (ADV_AD_DATA_OFFSET + \
 | 
			
		||||
                                            AD_TYPE_OOB_FLAGS_DATA_SIZE)       /**< Size (in octets) of the Security Manager OOB Flags AD type. */
 | 
			
		||||
 | 
			
		||||
#define AD_TYPE_SEC_MGR_OOB_FLAG_SET                   1U                      /**< Security Manager OOB Flag set. Flag selection is done using _POS defines */
 | 
			
		||||
#define AD_TYPE_SEC_MGR_OOB_FLAG_CLEAR                 0U                      /**< Security Manager OOB Flag clear. Flag selection is done using _POS defines */
 | 
			
		||||
#define AD_TYPE_SEC_MGR_OOB_FLAG_OOB_DATA_PRESENT_POS  0UL                     /**< Security Manager OOB Data Present Flag position. */
 | 
			
		||||
#define AD_TYPE_SEC_MGR_OOB_FLAG_OOB_LE_SUPPORTED_POS  1UL                     /**< Security Manager OOB Low Energy Supported Flag position. */
 | 
			
		||||
#define AD_TYPE_SEC_MGR_OOB_FLAG_SIM_LE_AND_EP_POS     2UL                     /**< Security Manager OOB Simultaneous LE and BR/EDR to Same Device Capable Flag position. */
 | 
			
		||||
#define AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_PUBLIC        0UL                     /**< Security Manager OOB Public Address type. */
 | 
			
		||||
#define AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_RANDOM        1UL                     /**< Security Manager OOB Random Address type. */
 | 
			
		||||
#define AD_TYPE_SEC_MGR_OOB_FLAG_ADDRESS_TYPE_POS      3UL                     /**< Security Manager OOB Address type Flag (0 = Public Address, 1 = Random Address) position. */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Security Manager TK value. */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  uint8_t tk[BLE_GAP_SEC_KEY_LEN];   /**< Array containing TK value. */
 | 
			
		||||
} ble_advdata_tk_value_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Advertising data LE Role types. This enumeration contains the options available for the LE role inside
 | 
			
		||||
 *        the advertising data. */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    BLE_ADVDATA_ROLE_NOT_PRESENT = 0,                                 /**< LE Role AD structure not present. */
 | 
			
		||||
    BLE_ADVDATA_ROLE_ONLY_PERIPH,                                     /**< Only Peripheral Role supported. */
 | 
			
		||||
    BLE_ADVDATA_ROLE_ONLY_CENTRAL,                                    /**< Only Central Role supported. */
 | 
			
		||||
    BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED,                           /**< Peripheral and Central Role supported. Peripheral Role preferred for connection establishment. */
 | 
			
		||||
    BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED                           /**< Peripheral and Central Role supported. Central Role preferred for connection establishment */
 | 
			
		||||
} ble_advdata_le_role_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Advertising data name type. This enumeration contains the options available for the device name inside
 | 
			
		||||
 *        the advertising data. */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    BLE_ADVDATA_NO_NAME,                                              /**< Include no device name in advertising data. */
 | 
			
		||||
    BLE_ADVDATA_SHORT_NAME,                                           /**< Include short device name in advertising data. */
 | 
			
		||||
    BLE_ADVDATA_FULL_NAME                                             /**< Include full device name in advertising data. */
 | 
			
		||||
} ble_advdata_name_type_t;
 | 
			
		||||
 | 
			
		||||
/**@brief UUID list type. */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    uint16_t                     uuid_cnt;                            /**< Number of UUID entries. */
 | 
			
		||||
    ble_uuid_t *                 p_uuids;                             /**< Pointer to UUID array entries. */
 | 
			
		||||
} ble_advdata_uuid_list_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Connection interval range structure. */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    uint16_t                     min_conn_interval;                   /**< Minimum connection interval, in units of 1.25 ms, range 6 to 3200 (7.5 ms to 4 s). */
 | 
			
		||||
    uint16_t                     max_conn_interval;                   /**< Maximum connection interval, in units of 1.25 ms, range 6 to 3200 (7.5 ms to 4 s). The value 0xFFFF indicates no specific maximum. */
 | 
			
		||||
} ble_advdata_conn_int_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Manufacturer specific data structure. */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    uint16_t                     company_identifier;                  /**< Company identifier code. */
 | 
			
		||||
    uint8_array_t                data;                                /**< Additional manufacturer specific data. */
 | 
			
		||||
} ble_advdata_manuf_data_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Service data structure. */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    uint16_t                     service_uuid;                        /**< Service UUID. */
 | 
			
		||||
    uint8_array_t                data;                                /**< Additional service data. */
 | 
			
		||||
} ble_advdata_service_data_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Advertising data structure. This structure contains all options and data needed for encoding and
 | 
			
		||||
 *        setting the advertising data. */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    ble_advdata_name_type_t      name_type;                           /**< Type of device name. */
 | 
			
		||||
    uint8_t                      short_name_len;                      /**< Length of short device name (if short type is specified). */
 | 
			
		||||
    bool                         include_appearance;                  /**< Determines if Appearance shall be included. */
 | 
			
		||||
    uint8_t                      flags;                               /**< Advertising data Flags field. */
 | 
			
		||||
    int8_t *                     p_tx_power_level;                    /**< TX Power Level field. */
 | 
			
		||||
    ble_advdata_uuid_list_t      uuids_more_available;                /**< List of UUIDs in the 'More Available' list. */
 | 
			
		||||
    ble_advdata_uuid_list_t      uuids_complete;                      /**< List of UUIDs in the 'Complete' list. */
 | 
			
		||||
    ble_advdata_uuid_list_t      uuids_solicited;                     /**< List of solicited UUIDs. */
 | 
			
		||||
    ble_advdata_conn_int_t *     p_slave_conn_int;                    /**< Slave Connection Interval Range. */
 | 
			
		||||
    ble_advdata_manuf_data_t *   p_manuf_specific_data;               /**< Manufacturer specific data. */
 | 
			
		||||
    ble_advdata_service_data_t * p_service_data_array;                /**< Array of Service data structures. */
 | 
			
		||||
    uint8_t                      service_data_count;                  /**< Number of Service data structures. */
 | 
			
		||||
    bool                         include_ble_device_addr;             /**< Determines if LE Bluetooth Device Address shall be included. */
 | 
			
		||||
    ble_advdata_le_role_t        le_role;                             /**< LE Role field. Included when different from @ref BLE_ADVDATA_ROLE_NOT_PRESENT. @warning This field can be used only for NFC. For BLE advertising, set it to NULL. */
 | 
			
		||||
    ble_advdata_tk_value_t *     p_tk_value;                          /**< Security Manager TK value field. Included when different from NULL. @warning This field can be used only for NFC. For BLE advertising, set it to NULL.*/
 | 
			
		||||
    uint8_t *                    p_sec_mgr_oob_flags;                 /**< Security Manager Out Of Band Flags field. Included when different from NULL. @warning This field can be used only for NFC. For BLE advertising, set it to NULL.*/
 | 
			
		||||
} ble_advdata_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Function for encoding data in the Advertising and Scan Response data format
 | 
			
		||||
 *        (AD structures).
 | 
			
		||||
 *
 | 
			
		||||
 * @details This function encodes data into the Advertising and Scan Response data format
 | 
			
		||||
 *          (AD structures) based on the selections in the supplied structures. This function can be used to
 | 
			
		||||
 *          create a payload of Advertising packet or Scan Response packet, or a payload of NFC
 | 
			
		||||
 *          message intended for initiating the Out-of-Band pairing.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]      p_advdata       Pointer to the structure for specifying the content of encoded data.
 | 
			
		||||
 * @param[out]     p_encoded_data  Pointer to the buffer where encoded data will be returned.
 | 
			
		||||
 * @param[in,out]  p_len           \c in: Size of \p p_encoded_data buffer.
 | 
			
		||||
 *                                 \c out: Length of encoded data.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS             If the operation was successful.
 | 
			
		||||
 * @retval NRF_ERROR_INVALID_PARAM If the operation failed because a wrong parameter was provided in \p p_advdata.
 | 
			
		||||
 * @retval NRF_ERROR_DATA_SIZE     If the operation failed because not all the requested data could fit into the
 | 
			
		||||
 *                                 provided buffer or some encoded AD structure is too long and its
 | 
			
		||||
 *                                 length cannot be encoded with one octet.
 | 
			
		||||
 *
 | 
			
		||||
 * @warning This API may override the application's request to use the long name and use a short name
 | 
			
		||||
 * instead. This truncation will occur in case the long name does not fit the provided buffer size.
 | 
			
		||||
 * The application can specify a preferred short name length if truncation is required.
 | 
			
		||||
 * For example, if the complete device name is ABCD_HRMonitor, the application can specify the short name
 | 
			
		||||
 * length to be 8, so that the short device name appears as ABCD_HRM instead of ABCD_HRMo or ABCD_HRMoni
 | 
			
		||||
 * if the available size for the short name is 9 or 12 respectively, to have a more appropriate short name.
 | 
			
		||||
 * However, it should be noted that this is just a preference that the application can specify, and
 | 
			
		||||
 * if the preference is too large to fit in the provided buffer, the name can be truncated further.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t adv_data_encode(ble_advdata_t const * const p_advdata,
 | 
			
		||||
                         uint8_t             * const p_encoded_data,
 | 
			
		||||
                         uint16_t            * const p_len);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for encoding and setting the advertising data and/or scan response data.
 | 
			
		||||
 *
 | 
			
		||||
 * @details This function encodes advertising data and/or scan response data based on the selections
 | 
			
		||||
 *          in the supplied structures, and passes the encoded data to the stack.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   p_advdata   Structure for specifying the content of the advertising data.
 | 
			
		||||
 *                          Set to NULL if advertising data is not to be set.
 | 
			
		||||
 * @param[in]   p_srdata    Structure for specifying the content of the scan response data.
 | 
			
		||||
 *                          Set to NULL if scan response data is not to be set.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval NRF_SUCCESS             If the operation was successful.
 | 
			
		||||
 * @retval NRF_ERROR_INVALID_PARAM If the operation failed because a wrong parameter was provided in \p p_advdata.
 | 
			
		||||
 * @retval NRF_ERROR_DATA_SIZE     If the operation failed because not all the requested data could fit into the
 | 
			
		||||
 *                                 advertising packet. The maximum size of the advertisement packet
 | 
			
		||||
 *                                 is @ref BLE_GAP_ADV_MAX_SIZE.
 | 
			
		||||
 *
 | 
			
		||||
 * @warning This API may override the application's request to use the long name and use a short name
 | 
			
		||||
 * instead. This truncation will occur in case the long name does not fit the provided buffer size.
 | 
			
		||||
 * The application can specify a preferred short name length if truncation is required.
 | 
			
		||||
 * For example, if the complete device name is ABCD_HRMonitor, the application can specify the short name
 | 
			
		||||
 * length to be 8, so that the short device name appears as ABCD_HRM instead of ABCD_HRMo or ABCD_HRMoni
 | 
			
		||||
 * if the available size for the short name is 9 or 12 respectively, to have a more appropriate short name.
 | 
			
		||||
 * However, it should be noted that this is just a preference that the application can specify, and
 | 
			
		||||
 * if the preference is too large to fit in the provided buffer, the name can be truncated further.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t ble_advdata_set(const ble_advdata_t * p_advdata, const ble_advdata_t * p_srdata);
 | 
			
		||||
 | 
			
		||||
#endif // BLE_ADVDATA_H__
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
							
								
								
									
										323
									
								
								nRF5_SDK_11.0.0_89a8197/components/ble/common/ble_conn_params.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										323
									
								
								nRF5_SDK_11.0.0_89a8197/components/ble/common/ble_conn_params.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,323 @@
 | 
			
		||||
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "ble_conn_params.h"
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include "nordic_common.h"
 | 
			
		||||
#include "ble_hci.h"
 | 
			
		||||
#include "app_timer.h"
 | 
			
		||||
#include "ble_srv_common.h"
 | 
			
		||||
#include "app_util.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static ble_conn_params_init_t m_conn_params_config;     /**< Configuration as specified by the application. */
 | 
			
		||||
static ble_gap_conn_params_t  m_preferred_conn_params;  /**< Connection parameters preferred by the application. */
 | 
			
		||||
static uint8_t                m_update_count;           /**< Number of Connection Parameter Update messages that has currently been sent. */
 | 
			
		||||
static uint16_t               m_conn_handle;            /**< Current connection handle. */
 | 
			
		||||
static ble_gap_conn_params_t  m_current_conn_params;    /**< Connection parameters received in the most recent Connect event. */
 | 
			
		||||
APP_TIMER_DEF(m_conn_params_timer_id);                  /**< Connection parameters timer. */
 | 
			
		||||
 | 
			
		||||
static bool m_change_param = false;
 | 
			
		||||
 | 
			
		||||
static bool is_conn_params_ok(ble_gap_conn_params_t * p_conn_params)
 | 
			
		||||
{
 | 
			
		||||
    // Check if interval is within the acceptable range.
 | 
			
		||||
    // NOTE: Using max_conn_interval in the received event data because this contains
 | 
			
		||||
    //       the client's connection interval.
 | 
			
		||||
    if (
 | 
			
		||||
        (p_conn_params->max_conn_interval >= m_preferred_conn_params.min_conn_interval)
 | 
			
		||||
        && 
 | 
			
		||||
        (p_conn_params->max_conn_interval <= m_preferred_conn_params.max_conn_interval)
 | 
			
		||||
       )
 | 
			
		||||
    {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void update_timeout_handler(void * p_context)
 | 
			
		||||
{
 | 
			
		||||
    UNUSED_PARAMETER(p_context);
 | 
			
		||||
 | 
			
		||||
    if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
 | 
			
		||||
    {
 | 
			
		||||
        // Check if we have reached the maximum number of attempts
 | 
			
		||||
        m_update_count++;
 | 
			
		||||
        if (m_update_count <= m_conn_params_config.max_conn_params_update_count)
 | 
			
		||||
        {
 | 
			
		||||
            uint32_t err_code;
 | 
			
		||||
 | 
			
		||||
            // Parameters are not ok, send connection parameters update request.
 | 
			
		||||
            err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params);
 | 
			
		||||
            if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
 | 
			
		||||
            {
 | 
			
		||||
                m_conn_params_config.error_handler(err_code);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            m_update_count = 0;
 | 
			
		||||
 | 
			
		||||
            // Negotiation failed, disconnect automatically if this has been configured
 | 
			
		||||
            if (m_conn_params_config.disconnect_on_fail)
 | 
			
		||||
            {
 | 
			
		||||
                uint32_t err_code;
 | 
			
		||||
 | 
			
		||||
                err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
 | 
			
		||||
                if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
 | 
			
		||||
                {
 | 
			
		||||
                    m_conn_params_config.error_handler(err_code);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Notify the application that the procedure has failed
 | 
			
		||||
            if (m_conn_params_config.evt_handler != NULL)
 | 
			
		||||
            {
 | 
			
		||||
                ble_conn_params_evt_t evt;
 | 
			
		||||
 | 
			
		||||
                evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED;
 | 
			
		||||
                m_conn_params_config.evt_handler(&evt);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t ble_conn_params_init(const ble_conn_params_init_t * p_init)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
 | 
			
		||||
    m_conn_params_config = *p_init;
 | 
			
		||||
    m_change_param = false;
 | 
			
		||||
    if (p_init->p_conn_params != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        m_preferred_conn_params = *p_init->p_conn_params;
 | 
			
		||||
 | 
			
		||||
        // Set the connection params in stack
 | 
			
		||||
        err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params);
 | 
			
		||||
        if (err_code != NRF_SUCCESS)
 | 
			
		||||
        {
 | 
			
		||||
            return err_code;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        // Fetch the connection params from stack
 | 
			
		||||
        err_code = sd_ble_gap_ppcp_get(&m_preferred_conn_params);
 | 
			
		||||
        if (err_code != NRF_SUCCESS)
 | 
			
		||||
        {
 | 
			
		||||
            return err_code;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_conn_handle  = BLE_CONN_HANDLE_INVALID;
 | 
			
		||||
    m_update_count = 0;
 | 
			
		||||
 | 
			
		||||
    return app_timer_create(&m_conn_params_timer_id,
 | 
			
		||||
                            APP_TIMER_MODE_SINGLE_SHOT,
 | 
			
		||||
                            update_timeout_handler);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t ble_conn_params_stop(void)
 | 
			
		||||
{
 | 
			
		||||
    return app_timer_stop(m_conn_params_timer_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void conn_params_negotiation(void)
 | 
			
		||||
{
 | 
			
		||||
    // Start negotiation if the received connection parameters are not acceptable
 | 
			
		||||
    if (!is_conn_params_ok(&m_current_conn_params))
 | 
			
		||||
    {
 | 
			
		||||
        uint32_t err_code;
 | 
			
		||||
        uint32_t timeout_ticks;
 | 
			
		||||
 | 
			
		||||
        if (m_change_param)
 | 
			
		||||
        {
 | 
			
		||||
            // Notify the application that the procedure has failed
 | 
			
		||||
            if (m_conn_params_config.evt_handler != NULL)
 | 
			
		||||
            {
 | 
			
		||||
                ble_conn_params_evt_t evt;
 | 
			
		||||
 | 
			
		||||
                evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED;
 | 
			
		||||
                m_conn_params_config.evt_handler(&evt);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            if (m_update_count == 0)
 | 
			
		||||
            {
 | 
			
		||||
                // First connection parameter update
 | 
			
		||||
                timeout_ticks = m_conn_params_config.first_conn_params_update_delay;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                timeout_ticks = m_conn_params_config.next_conn_params_update_delay;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            err_code = app_timer_start(m_conn_params_timer_id, timeout_ticks, NULL);
 | 
			
		||||
            if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
 | 
			
		||||
            {
 | 
			
		||||
                m_conn_params_config.error_handler(err_code);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        // Notify the application that the procedure has succeded
 | 
			
		||||
        if (m_conn_params_config.evt_handler != NULL)
 | 
			
		||||
        {
 | 
			
		||||
            ble_conn_params_evt_t evt;
 | 
			
		||||
 | 
			
		||||
            evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED;
 | 
			
		||||
            m_conn_params_config.evt_handler(&evt);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    m_change_param = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void on_connect(ble_evt_t * p_ble_evt)
 | 
			
		||||
{
 | 
			
		||||
    // Save connection parameters
 | 
			
		||||
    m_conn_handle         = p_ble_evt->evt.gap_evt.conn_handle;
 | 
			
		||||
    m_current_conn_params = p_ble_evt->evt.gap_evt.params.connected.conn_params;
 | 
			
		||||
    m_update_count        = 0;  // Connection parameter negotiation should re-start every connection
 | 
			
		||||
 | 
			
		||||
    // Check if we shall handle negotiation on connect
 | 
			
		||||
    if (m_conn_params_config.start_on_notify_cccd_handle == BLE_GATT_HANDLE_INVALID)
 | 
			
		||||
    {
 | 
			
		||||
        conn_params_negotiation();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void on_disconnect(ble_evt_t * p_ble_evt)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
 | 
			
		||||
    m_conn_handle = BLE_CONN_HANDLE_INVALID;
 | 
			
		||||
 | 
			
		||||
    // Stop timer if running
 | 
			
		||||
    m_update_count = 0; // Connection parameters updates should happen during every connection
 | 
			
		||||
 | 
			
		||||
    err_code = app_timer_stop(m_conn_params_timer_id);
 | 
			
		||||
    if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
 | 
			
		||||
    {
 | 
			
		||||
        m_conn_params_config.error_handler(err_code);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void on_write(ble_evt_t * p_ble_evt)
 | 
			
		||||
{
 | 
			
		||||
    ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
 | 
			
		||||
 | 
			
		||||
    // Check if this the correct CCCD
 | 
			
		||||
    if (
 | 
			
		||||
        (p_evt_write->handle == m_conn_params_config.start_on_notify_cccd_handle)
 | 
			
		||||
        &&
 | 
			
		||||
        (p_evt_write->len == 2)
 | 
			
		||||
       )
 | 
			
		||||
    {
 | 
			
		||||
        // Check if this is a 'start notification'
 | 
			
		||||
        if (ble_srv_is_notification_enabled(p_evt_write->data))
 | 
			
		||||
        {
 | 
			
		||||
            // Do connection parameter negotiation if necessary
 | 
			
		||||
            conn_params_negotiation();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            uint32_t err_code;
 | 
			
		||||
 | 
			
		||||
            // Stop timer if running
 | 
			
		||||
            err_code = app_timer_stop(m_conn_params_timer_id);
 | 
			
		||||
            if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
 | 
			
		||||
            {
 | 
			
		||||
                m_conn_params_config.error_handler(err_code);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void on_conn_params_update(ble_evt_t * p_ble_evt)
 | 
			
		||||
{
 | 
			
		||||
    // Copy the parameters
 | 
			
		||||
    m_current_conn_params = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params;
 | 
			
		||||
 | 
			
		||||
    conn_params_negotiation();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void ble_conn_params_on_ble_evt(ble_evt_t * p_ble_evt)
 | 
			
		||||
{
 | 
			
		||||
    switch (p_ble_evt->header.evt_id)
 | 
			
		||||
    {
 | 
			
		||||
        case BLE_GAP_EVT_CONNECTED:
 | 
			
		||||
            on_connect(p_ble_evt);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case BLE_GAP_EVT_DISCONNECTED:
 | 
			
		||||
            on_disconnect(p_ble_evt);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case BLE_GATTS_EVT_WRITE:
 | 
			
		||||
            on_write(p_ble_evt);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case BLE_GAP_EVT_CONN_PARAM_UPDATE:
 | 
			
		||||
            on_conn_params_update(p_ble_evt);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            // No implementation needed.
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t ble_conn_params_change_conn_params(ble_gap_conn_params_t * new_params)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t err_code;
 | 
			
		||||
 | 
			
		||||
    m_preferred_conn_params = *new_params;
 | 
			
		||||
    // Set the connection params in stack
 | 
			
		||||
    err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params);
 | 
			
		||||
    if (err_code == NRF_SUCCESS)
 | 
			
		||||
    {
 | 
			
		||||
        if (!is_conn_params_ok(&m_current_conn_params))
 | 
			
		||||
        {
 | 
			
		||||
            m_change_param = true;
 | 
			
		||||
            err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params);
 | 
			
		||||
            m_update_count = 1;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            // Notify the application that the procedure has succeded
 | 
			
		||||
            if (m_conn_params_config.evt_handler != NULL)
 | 
			
		||||
            {
 | 
			
		||||
                ble_conn_params_evt_t evt;
 | 
			
		||||
 | 
			
		||||
                evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED;
 | 
			
		||||
                m_conn_params_config.evt_handler(&evt);
 | 
			
		||||
            }
 | 
			
		||||
            err_code = NRF_SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return err_code;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										111
									
								
								nRF5_SDK_11.0.0_89a8197/components/ble/common/ble_conn_params.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								nRF5_SDK_11.0.0_89a8197/components/ble/common/ble_conn_params.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,111 @@
 | 
			
		||||
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * @defgroup ble_sdk_lib_conn_params Connection Parameters Negotiation
 | 
			
		||||
 * @{
 | 
			
		||||
 * @ingroup ble_sdk_lib
 | 
			
		||||
 * @brief Module for initiating and executing a connection parameters negotiation procedure.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef BLE_CONN_PARAMS_H__
 | 
			
		||||
#define BLE_CONN_PARAMS_H__
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "ble.h"
 | 
			
		||||
#include "ble_srv_common.h"
 | 
			
		||||
 | 
			
		||||
/**@brief Connection Parameters Module event type. */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    BLE_CONN_PARAMS_EVT_FAILED   ,                                  /**< Negotiation procedure failed. */
 | 
			
		||||
    BLE_CONN_PARAMS_EVT_SUCCEEDED                                   /**< Negotiation procedure succeeded. */
 | 
			
		||||
} ble_conn_params_evt_type_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Connection Parameters Module event. */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    ble_conn_params_evt_type_t evt_type;                            /**< Type of event. */
 | 
			
		||||
} ble_conn_params_evt_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Connection Parameters Module event handler type. */
 | 
			
		||||
typedef void (*ble_conn_params_evt_handler_t) (ble_conn_params_evt_t * p_evt);
 | 
			
		||||
 | 
			
		||||
/**@brief Connection Parameters Module init structure. This contains all options and data needed for
 | 
			
		||||
 *        initialization of the connection parameters negotiation module. */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    ble_gap_conn_params_t *       p_conn_params;                    /**< Pointer to the connection parameters desired by the application. When calling ble_conn_params_init, if this parameter is set to NULL, the connection parameters will be fetched from host. */
 | 
			
		||||
    uint32_t                      first_conn_params_update_delay;   /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (in number of timer ticks). */
 | 
			
		||||
    uint32_t                      next_conn_params_update_delay;    /**< Time between each call to sd_ble_gap_conn_param_update after the first (in number of timer ticks). Recommended value 30 seconds as per BLUETOOTH SPECIFICATION Version 4.0. */
 | 
			
		||||
    uint8_t                       max_conn_params_update_count;     /**< Number of attempts before giving up the negotiation. */
 | 
			
		||||
    uint16_t                      start_on_notify_cccd_handle;      /**< If procedure is to be started when notification is started, set this to the handle of the corresponding CCCD. Set to BLE_GATT_HANDLE_INVALID if procedure is to be started on connect event. */
 | 
			
		||||
    bool                          disconnect_on_fail;               /**< Set to TRUE if a failed connection parameters update shall cause an automatic disconnection, set to FALSE otherwise. */
 | 
			
		||||
    ble_conn_params_evt_handler_t evt_handler;                      /**< Event handler to be called for handling events in the Connection Parameters. */
 | 
			
		||||
    ble_srv_error_handler_t       error_handler;                    /**< Function to be called in case of an error. */
 | 
			
		||||
} ble_conn_params_init_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Function for initializing the Connection Parameters module.
 | 
			
		||||
 *
 | 
			
		||||
 * @note If the negotiation procedure should be triggered when notification/indication of 
 | 
			
		||||
 *       any characteristic is enabled by the peer, then this function must be called after
 | 
			
		||||
 *       having initialized the services.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   p_init  This contains information needed to initialize this module.
 | 
			
		||||
 *
 | 
			
		||||
 * @return      NRF_SUCCESS on successful initialization, otherwise an error code.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t ble_conn_params_init(const ble_conn_params_init_t * p_init);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for stopping the Connection Parameters module.
 | 
			
		||||
 *
 | 
			
		||||
 * @details This function is intended to be used by the application to clean up the connection
 | 
			
		||||
 *          parameters update module. This will stop the connection parameters update timer if
 | 
			
		||||
 *          running, thereby preventing any impending connection parameters update procedure. This
 | 
			
		||||
 *          function must be called by the application when it needs to clean itself up (for
 | 
			
		||||
 *          example, before disabling the bluetooth SoftDevice) so that an unwanted timer expiry
 | 
			
		||||
 *          event can be avoided.
 | 
			
		||||
 *
 | 
			
		||||
 * @return      NRF_SUCCESS on successful initialization, otherwise an error code.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t ble_conn_params_stop(void);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for changing the current connection parameters to a new set.
 | 
			
		||||
 *
 | 
			
		||||
 *  @details Use this function to change the connection parameters to a new set of parameter 
 | 
			
		||||
 *       (ie different from the ones given at init of the module).
 | 
			
		||||
 *       This function is usefull for scenario where most of the time the application
 | 
			
		||||
 *       needs a relatively big connection interval, and just sometimes, for a temporary
 | 
			
		||||
 *       period requires shorter connection interval, for example to transfer a higher
 | 
			
		||||
 *       amount of data.
 | 
			
		||||
 *       If the given parameters does not match the current connection's parameters
 | 
			
		||||
 *       this function initiates a new negotiation.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   new_params  This contains the new connections parameters to setup.
 | 
			
		||||
 *
 | 
			
		||||
 * @return      NRF_SUCCESS on successful initialization, otherwise an error code.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t ble_conn_params_change_conn_params(ble_gap_conn_params_t *new_params);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for handling the Application's BLE Stack events.
 | 
			
		||||
 *
 | 
			
		||||
 * @details Handles all events from the BLE stack that are of interest to this module.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   p_ble_evt  The event received from the BLE stack.
 | 
			
		||||
 */
 | 
			
		||||
void ble_conn_params_on_ble_evt(ble_evt_t * p_ble_evt);
 | 
			
		||||
 | 
			
		||||
#endif // BLE_CONN_PARAMS_H__
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
							
								
								
									
										197
									
								
								nRF5_SDK_11.0.0_89a8197/components/ble/common/ble_srv_common.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								nRF5_SDK_11.0.0_89a8197/components/ble/common/ble_srv_common.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,197 @@
 | 
			
		||||
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Attention!
 | 
			
		||||
*  To maintain compliance with Nordic Semiconductor ASA<53>s Bluetooth profile
 | 
			
		||||
*  qualification listings, this section of source code must not be modified.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "ble_srv_common.h"
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "nordic_common.h"
 | 
			
		||||
#include "app_error.h"
 | 
			
		||||
#include "ble.h"
 | 
			
		||||
 | 
			
		||||
uint8_t ble_srv_report_ref_encode(uint8_t                    * p_encoded_buffer,
 | 
			
		||||
                                  const ble_srv_report_ref_t * p_report_ref)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t len = 0;
 | 
			
		||||
 | 
			
		||||
    p_encoded_buffer[len++] = p_report_ref->report_id;
 | 
			
		||||
    p_encoded_buffer[len++] = p_report_ref->report_type;
 | 
			
		||||
 | 
			
		||||
    APP_ERROR_CHECK_BOOL(len == BLE_SRV_ENCODED_REPORT_REF_LEN);
 | 
			
		||||
    return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void ble_srv_ascii_to_utf8(ble_srv_utf8_str_t * p_utf8, char * p_ascii)
 | 
			
		||||
{
 | 
			
		||||
    p_utf8->length = (uint16_t)strlen(p_ascii);
 | 
			
		||||
    p_utf8->p_str  = (uint8_t *)p_ascii;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Function for setting security requirements of a characteristic.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]  level   required security level.
 | 
			
		||||
 * @param[out] p_perm  Characteristic security requirements.
 | 
			
		||||
 *
 | 
			
		||||
 * @return     encoded security level and security mode.
 | 
			
		||||
 */
 | 
			
		||||
static inline void set_security_req(security_req_t level, ble_gap_conn_sec_mode_t * p_perm)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(p_perm);
 | 
			
		||||
    switch (level)
 | 
			
		||||
    {
 | 
			
		||||
        case SEC_NO_ACCESS:
 | 
			
		||||
            BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(p_perm);
 | 
			
		||||
        break;
 | 
			
		||||
        case SEC_OPEN:
 | 
			
		||||
            BLE_GAP_CONN_SEC_MODE_SET_OPEN(p_perm);
 | 
			
		||||
        break;
 | 
			
		||||
        case SEC_JUST_WORKS:
 | 
			
		||||
            BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(p_perm);
 | 
			
		||||
        break;
 | 
			
		||||
        case SEC_MITM:
 | 
			
		||||
            BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(p_perm);
 | 
			
		||||
        break;
 | 
			
		||||
        case SEC_SIGNED:
 | 
			
		||||
            BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(p_perm);
 | 
			
		||||
        break;
 | 
			
		||||
        case SEC_SIGNED_MITM:
 | 
			
		||||
            BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(p_perm);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t characteristic_add(uint16_t                   service_handle,
 | 
			
		||||
                            ble_add_char_params_t *    p_char_props,
 | 
			
		||||
                            ble_gatts_char_handles_t * p_char_handle)
 | 
			
		||||
{
 | 
			
		||||
    ble_gatts_char_md_t char_md;
 | 
			
		||||
    ble_gatts_attr_t    attr_char_value;
 | 
			
		||||
    ble_uuid_t          char_uuid;
 | 
			
		||||
    ble_gatts_attr_md_t attr_md;
 | 
			
		||||
    ble_gatts_attr_md_t user_descr_attr_md;
 | 
			
		||||
    ble_gatts_attr_md_t cccd_md;
 | 
			
		||||
 | 
			
		||||
    if (p_char_props->uuid_type == 0)
 | 
			
		||||
    {
 | 
			
		||||
        char_uuid.type = BLE_UUID_TYPE_BLE;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        char_uuid.type = p_char_props->uuid_type;
 | 
			
		||||
    }
 | 
			
		||||
    char_uuid.uuid = p_char_props->uuid;
 | 
			
		||||
 | 
			
		||||
    memset(&attr_md, 0, sizeof(ble_gatts_attr_md_t));
 | 
			
		||||
    set_security_req(p_char_props->read_access, &attr_md.read_perm);
 | 
			
		||||
    set_security_req(p_char_props->write_access, & attr_md.write_perm);
 | 
			
		||||
    attr_md.rd_auth    = (p_char_props->is_defered_read ? 1 : 0);
 | 
			
		||||
    attr_md.wr_auth    = (p_char_props->is_defered_write ? 1 : 0);
 | 
			
		||||
    attr_md.vlen       = (p_char_props->is_var_len ? 1 : 0);
 | 
			
		||||
    attr_md.vloc       = (p_char_props->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    memset(&char_md, 0, sizeof(ble_gatts_char_md_t));
 | 
			
		||||
    if ((p_char_props->char_props.notify == 1)||(p_char_props->char_props.indicate == 1))
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        memset(&cccd_md, 0, sizeof(cccd_md));
 | 
			
		||||
        set_security_req(p_char_props->cccd_write_access, &cccd_md.write_perm);
 | 
			
		||||
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
 | 
			
		||||
 | 
			
		||||
        cccd_md.vloc       = BLE_GATTS_VLOC_STACK;
 | 
			
		||||
 | 
			
		||||
        char_md.p_cccd_md  = &cccd_md;
 | 
			
		||||
    }
 | 
			
		||||
    char_md.char_props = p_char_props->char_props;
 | 
			
		||||
 | 
			
		||||
    memset(&attr_char_value, 0, sizeof(ble_gatts_attr_t));
 | 
			
		||||
    attr_char_value.p_uuid    = &char_uuid;
 | 
			
		||||
    attr_char_value.p_attr_md = &attr_md;
 | 
			
		||||
    attr_char_value.max_len   = p_char_props->max_len;
 | 
			
		||||
    if (p_char_props->p_init_value != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        attr_char_value.init_len  = p_char_props->init_len;
 | 
			
		||||
        attr_char_value.p_value   = p_char_props->p_init_value;
 | 
			
		||||
    }
 | 
			
		||||
    if (p_char_props->p_user_descr != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        memset(&user_descr_attr_md, 0, sizeof(ble_gatts_attr_md_t));
 | 
			
		||||
        char_md.char_user_desc_max_size = p_char_props->p_user_descr->max_size;
 | 
			
		||||
        char_md.char_user_desc_size     = p_char_props->p_user_descr->size;
 | 
			
		||||
        char_md.p_char_user_desc        = p_char_props->p_user_descr->p_char_user_desc;
 | 
			
		||||
 | 
			
		||||
        char_md.p_user_desc_md          = &user_descr_attr_md;
 | 
			
		||||
 | 
			
		||||
        set_security_req(p_char_props->p_user_descr->read_access, &user_descr_attr_md.read_perm);
 | 
			
		||||
        set_security_req(p_char_props->p_user_descr->write_access, &user_descr_attr_md.write_perm);
 | 
			
		||||
 | 
			
		||||
        user_descr_attr_md.rd_auth      = (p_char_props->p_user_descr->is_defered_read ? 1 : 0);
 | 
			
		||||
        user_descr_attr_md.wr_auth      = (p_char_props->p_user_descr->is_defered_write ? 1 : 0);
 | 
			
		||||
        user_descr_attr_md.vlen         = (p_char_props->p_user_descr->is_var_len ? 1 : 0);
 | 
			
		||||
        user_descr_attr_md.vloc         = (p_char_props->p_user_descr->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK);
 | 
			
		||||
    }
 | 
			
		||||
    if (p_char_props->p_presentation_format != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        char_md.p_char_pf = p_char_props->p_presentation_format;
 | 
			
		||||
    }
 | 
			
		||||
    return sd_ble_gatts_characteristic_add(service_handle,
 | 
			
		||||
                                           &char_md,
 | 
			
		||||
                                           &attr_char_value,
 | 
			
		||||
                                           p_char_handle);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint32_t descriptor_add(uint16_t                   char_handle,
 | 
			
		||||
                        ble_add_descr_params_t *   p_descr_props,
 | 
			
		||||
                        uint16_t *                 p_descr_handle)
 | 
			
		||||
{
 | 
			
		||||
    ble_gatts_attr_t    descr_params;
 | 
			
		||||
    ble_uuid_t          desc_uuid;
 | 
			
		||||
    ble_gatts_attr_md_t attr_md;
 | 
			
		||||
 | 
			
		||||
    memset(&descr_params, 0, sizeof(descr_params));
 | 
			
		||||
    if (p_descr_props->uuid_type == 0)
 | 
			
		||||
    {
 | 
			
		||||
        desc_uuid.type = BLE_UUID_TYPE_BLE;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        desc_uuid.type = p_descr_props->uuid_type;
 | 
			
		||||
    }
 | 
			
		||||
    desc_uuid.uuid = p_descr_props->uuid;
 | 
			
		||||
    descr_params.p_uuid = &desc_uuid;
 | 
			
		||||
 | 
			
		||||
    set_security_req(p_descr_props->read_access, &attr_md.read_perm);
 | 
			
		||||
    set_security_req(p_descr_props->write_access,&attr_md.write_perm);
 | 
			
		||||
 | 
			
		||||
    attr_md.rd_auth        = (p_descr_props->is_defered_read ? 1 : 0);
 | 
			
		||||
    attr_md.wr_auth        = (p_descr_props->is_defered_write ? 1 : 0);
 | 
			
		||||
    attr_md.vlen           = (p_descr_props->is_var_len ? 1 : 0);
 | 
			
		||||
    attr_md.vloc           = (p_descr_props->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK);
 | 
			
		||||
    descr_params.p_attr_md = &attr_md;
 | 
			
		||||
 | 
			
		||||
    descr_params.init_len  = p_descr_props->init_len;
 | 
			
		||||
    descr_params.init_offs = p_descr_props->init_offs;
 | 
			
		||||
    descr_params.max_len   = p_descr_props->max_len;
 | 
			
		||||
    descr_params.p_value   = p_descr_props->p_value;
 | 
			
		||||
 | 
			
		||||
    return sd_ble_gatts_descriptor_add(char_handle, &descr_params, p_descr_handle);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										367
									
								
								nRF5_SDK_11.0.0_89a8197/components/ble/common/ble_srv_common.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								nRF5_SDK_11.0.0_89a8197/components/ble/common/ble_srv_common.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,367 @@
 | 
			
		||||
/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * The information contained herein is property of Nordic Semiconductor ASA.
 | 
			
		||||
 * Terms and conditions of usage are described in detail in NORDIC
 | 
			
		||||
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensees are granted free, non-transferable use of the information. NO
 | 
			
		||||
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 | 
			
		||||
 * the file.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * @defgroup ble_sdk_srv_common Common service definitions
 | 
			
		||||
 * @{
 | 
			
		||||
 * @ingroup ble_sdk_srv
 | 
			
		||||
 * @brief Constants, type definitions, and functions that are common to all services.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef BLE_SRV_COMMON_H__
 | 
			
		||||
#define BLE_SRV_COMMON_H__
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include "ble_types.h"
 | 
			
		||||
#include "app_util.h"
 | 
			
		||||
#include "ble.h"
 | 
			
		||||
#include "ble_gap.h"
 | 
			
		||||
#include "ble_gatt.h"
 | 
			
		||||
 | 
			
		||||
/** @defgroup UUID_SERVICES Service UUID definitions
 | 
			
		||||
 * @{ */
 | 
			
		||||
#define BLE_UUID_ALERT_NOTIFICATION_SERVICE                      0x1811     /**< Alert Notification service UUID. */
 | 
			
		||||
#define BLE_UUID_BATTERY_SERVICE                                 0x180F     /**< Battery service UUID. */
 | 
			
		||||
#define BLE_UUID_BLOOD_PRESSURE_SERVICE                          0x1810     /**< Blood Pressure service UUID. */
 | 
			
		||||
#define BLE_UUID_CURRENT_TIME_SERVICE                            0x1805     /**< Current Time service UUID. */
 | 
			
		||||
#define BLE_UUID_CYCLING_SPEED_AND_CADENCE                       0x1816     /**< Cycling Speed and Cadence service UUID. */
 | 
			
		||||
#define BLE_UUID_LOCATION_AND_NAVIGATION_SERVICE                 0x1819     /**< Location and Navigation service UUID. */
 | 
			
		||||
#define BLE_UUID_DEVICE_INFORMATION_SERVICE                      0x180A     /**< Device Information service UUID. */
 | 
			
		||||
#define BLE_UUID_GLUCOSE_SERVICE                                 0x1808     /**< Glucose service UUID. */
 | 
			
		||||
#define BLE_UUID_HEALTH_THERMOMETER_SERVICE                      0x1809     /**< Health Thermometer service UUID. */
 | 
			
		||||
#define BLE_UUID_HEART_RATE_SERVICE                              0x180D     /**< Heart Rate service UUID. */
 | 
			
		||||
#define BLE_UUID_HUMAN_INTERFACE_DEVICE_SERVICE                  0x1812     /**< Human Interface Device service UUID. */
 | 
			
		||||
#define BLE_UUID_IMMEDIATE_ALERT_SERVICE                         0x1802     /**< Immediate Alert service UUID. */
 | 
			
		||||
#define BLE_UUID_LINK_LOSS_SERVICE                               0x1803     /**< Link Loss service UUID. */
 | 
			
		||||
#define BLE_UUID_NEXT_DST_CHANGE_SERVICE                         0x1807     /**< Next Dst Change service UUID. */
 | 
			
		||||
#define BLE_UUID_PHONE_ALERT_STATUS_SERVICE                      0x180E     /**< Phone Alert Status service UUID. */
 | 
			
		||||
#define BLE_UUID_REFERENCE_TIME_UPDATE_SERVICE                   0x1806     /**< Reference Time Update service UUID. */
 | 
			
		||||
#define BLE_UUID_RUNNING_SPEED_AND_CADENCE                       0x1814     /**< Running Speed and Cadence service UUID. */
 | 
			
		||||
#define BLE_UUID_SCAN_PARAMETERS_SERVICE                         0x1813     /**< Scan Parameters service UUID. */
 | 
			
		||||
#define BLE_UUID_TX_POWER_SERVICE                                0x1804     /**< TX Power service UUID. */
 | 
			
		||||
#define BLE_UUID_IPSP_SERVICE                                    0x1820     /**< Internet Protocol Support service UUID. */
 | 
			
		||||
#define BLE_UUID_BMS_SERVICE                                     0x181E     /**< BOND MANAGEMENT service UUID*/
 | 
			
		||||
#define BLE_UUID_CGM_SERVICE                                     0x181F     /**< Contiunous Glucose Monitoring service UUID*/
 | 
			
		||||
#define BLE_UUID_PLX_SERVICE                                     0x1822     /**< Pulse Oximeter Service UUID*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
/** @defgroup UUID_CHARACTERISTICS Characteristic UUID definitions
 | 
			
		||||
 * @{ */
 | 
			
		||||
#define BLE_UUID_REMOVABLE_CHAR                                  0x2A3A     /**< Removable characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_SERVICE_REQUIRED_CHAR                           0x2A3B     /**< Service Required characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_ALERT_CATEGORY_ID_CHAR                          0x2A43     /**< Alert Category Id characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_ALERT_CATEGORY_ID_BIT_MASK_CHAR                 0x2A42     /**< Alert Category Id Bit Mask characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_ALERT_LEVEL_CHAR                                0x2A06     /**< Alert Level characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR           0x2A44     /**< Alert Notification Control Point characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_ALERT_STATUS_CHAR                               0x2A3F     /**< Alert Status characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_BATTERY_LEVEL_CHAR                              0x2A19     /**< Battery Level characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_BLOOD_PRESSURE_FEATURE_CHAR                     0x2A49     /**< Blood Pressure Feature characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_BLOOD_PRESSURE_MEASUREMENT_CHAR                 0x2A35     /**< Blood Pressure Measurement characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_BODY_SENSOR_LOCATION_CHAR                       0x2A38     /**< Body Sensor Location characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_BOOT_KEYBOARD_INPUT_REPORT_CHAR                 0x2A22     /**< Boot Keyboard Input Report characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_BOOT_KEYBOARD_OUTPUT_REPORT_CHAR                0x2A32     /**< Boot Keyboard Output Report characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_BOOT_MOUSE_INPUT_REPORT_CHAR                    0x2A33     /**< Boot Mouse Input Report characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_CURRENT_TIME_CHAR                               0x2A2B     /**< Current Time characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_DATE_TIME_CHAR                                  0x2A08     /**< Date Time characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_DAY_DATE_TIME_CHAR                              0x2A0A     /**< Day Date Time characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_DAY_OF_WEEK_CHAR                                0x2A09     /**< Day Of Week characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_DST_OFFSET_CHAR                                 0x2A0D     /**< Dst Offset characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_EXACT_TIME_256_CHAR                             0x2A0C     /**< Exact Time 256 characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_FIRMWARE_REVISION_STRING_CHAR                   0x2A26     /**< Firmware Revision String characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_GLUCOSE_FEATURE_CHAR                            0x2A51     /**< Glucose Feature characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_GLUCOSE_MEASUREMENT_CHAR                        0x2A18     /**< Glucose Measurement characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_GLUCOSE_MEASUREMENT_CONTEXT_CHAR                0x2A34     /**< Glucose Measurement Context characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_HARDWARE_REVISION_STRING_CHAR                   0x2A27     /**< Hardware Revision String characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_HEART_RATE_CONTROL_POINT_CHAR                   0x2A39     /**< Heart Rate Control Point characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_HEART_RATE_MEASUREMENT_CHAR                     0x2A37     /**< Heart Rate Measurement characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_HID_CONTROL_POINT_CHAR                          0x2A4C     /**< Hid Control Point characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_HID_INFORMATION_CHAR                            0x2A4A     /**< Hid Information characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_IEEE_REGULATORY_CERTIFICATION_DATA_LIST_CHAR    0x2A2A     /**< IEEE Regulatory Certification Data List characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_INTERMEDIATE_CUFF_PRESSURE_CHAR                 0x2A36     /**< Intermediate Cuff Pressure characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_INTERMEDIATE_TEMPERATURE_CHAR                   0x2A1E     /**< Intermediate Temperature characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_LOCAL_TIME_INFORMATION_CHAR                     0x2A0F     /**< Local Time Information characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_MANUFACTURER_NAME_STRING_CHAR                   0x2A29     /**< Manufacturer Name String characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_MEASUREMENT_INTERVAL_CHAR                       0x2A21     /**< Measurement Interval characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_MODEL_NUMBER_STRING_CHAR                        0x2A24     /**< Model Number String characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_UNREAD_ALERT_CHAR                               0x2A45     /**< Unread Alert characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_NEW_ALERT_CHAR                                  0x2A46     /**< New Alert characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_PNP_ID_CHAR                                     0x2A50     /**< PNP Id characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_PROTOCOL_MODE_CHAR                              0x2A4E     /**< Protocol Mode characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_RECORD_ACCESS_CONTROL_POINT_CHAR                0x2A52     /**< Record Access Control Point characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_REFERENCE_TIME_INFORMATION_CHAR                 0x2A14     /**< Reference Time Information characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_REPORT_CHAR                                     0x2A4D     /**< Report characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_REPORT_MAP_CHAR                                 0x2A4B     /**< Report Map characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_RINGER_CONTROL_POINT_CHAR                       0x2A40     /**< Ringer Control Point characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_RINGER_SETTING_CHAR                             0x2A41     /**< Ringer Setting characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_SCAN_INTERVAL_WINDOW_CHAR                       0x2A4F     /**< Scan Interval Window characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_SCAN_REFRESH_CHAR                               0x2A31     /**< Scan Refresh characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_SERIAL_NUMBER_STRING_CHAR                       0x2A25     /**< Serial Number String characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_SOFTWARE_REVISION_STRING_CHAR                   0x2A28     /**< Software Revision String characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR               0x2A47     /**< Supported New Alert Category characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR            0x2A48     /**< Supported Unread Alert Category characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_SYSTEM_ID_CHAR                                  0x2A23     /**< System Id characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_TEMPERATURE_MEASUREMENT_CHAR                    0x2A1C     /**< Temperature Measurement characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_TEMPERATURE_TYPE_CHAR                           0x2A1D     /**< Temperature Type characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_TIME_ACCURACY_CHAR                              0x2A12     /**< Time Accuracy characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_TIME_SOURCE_CHAR                                0x2A13     /**< Time Source characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_TIME_UPDATE_CONTROL_POINT_CHAR                  0x2A16     /**< Time Update Control Point characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_TIME_UPDATE_STATE_CHAR                          0x2A17     /**< Time Update State characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_TIME_WITH_DST_CHAR                              0x2A11     /**< Time With Dst characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_TIME_ZONE_CHAR                                  0x2A0E     /**< Time Zone characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_TX_POWER_LEVEL_CHAR                             0x2A07     /**< TX Power Level characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_CSC_FEATURE_CHAR                                0x2A5C     /**< Cycling Speed and Cadence Feature characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_CSC_MEASUREMENT_CHAR                            0x2A5B     /**< Cycling Speed and Cadence Measurement characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_RSC_FEATURE_CHAR                                0x2A54     /**< Running Speed and Cadence Feature characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_SC_CTRLPT_CHAR                                  0x2A55     /**< Speed and Cadence Control Point UUID. */
 | 
			
		||||
#define BLE_UUID_RSC_MEASUREMENT_CHAR                            0x2A53     /**< Running Speed and Cadence Measurement characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_SENSOR_LOCATION_CHAR                            0x2A5D     /**< Sensor Location characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_EXTERNAL_REPORT_REF_DESCR                       0x2907     /**< External Report Reference descriptor UUID. */
 | 
			
		||||
#define BLE_UUID_REPORT_REF_DESCR                                0x2908     /**< Report Reference descriptor UUID. */
 | 
			
		||||
#define BLE_UUID_LN_FEATURE_CHAR                                 0x2A6A     /**< Location Navigation Service, Feature characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_LN_POSITION_QUALITY_CHAR                        0x2A69     /**< Location Navigation Service, Position quality UUID. */
 | 
			
		||||
#define BLE_UUID_LN_LOCATION_AND_SPEED_CHAR                      0x2A67     /**< Location Navigation Service, Location and Speed characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_LN_NAVIGATION_CHAR                              0x2A68     /**< Location Navigation Service, Navigation characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_LN_CONTROL_POINT_CHAR                           0x2A6B     /**< Location Navigation Service, Control point characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_BMS_CTRLPT                                      0x2AA4     /**< BMS Control Point characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_BMS_FEATURE                                     0x2AA5     /**< BMS Feature characteristic UUID. */
 | 
			
		||||
#define BLE_UUID_CGM_MEASUREMENT                                 0x2AA7     /**< CGM Service, Measurement characteristic UUID*/
 | 
			
		||||
#define BLE_UUID_CGM_FEATURE                                     0x2AA8     /**< CGM Service, Feature characteristic UUID*/
 | 
			
		||||
#define BLE_UUID_CGM_STATUS                                      0x2AA9     /**< CGM Service, Status characteristic UUID*/
 | 
			
		||||
#define BLE_UUID_CGM_SESSION_START_TIME                          0x2AAA     /**< CGM Service, session start time characteristic UUID*/
 | 
			
		||||
#define BLE_UUID_CGM_SESSION_RUN_TIME                            0x2AAB     /**< CGM Service, session run time characteristic UUID*/
 | 
			
		||||
#define BLE_UUID_CGM_SPECIFIC_OPS_CTRLPT                         0x2AAC     /**< CGM Service, specific ops ctrlpt characteristic UUID*/
 | 
			
		||||
#define BLE_UUID_PLX_SPOT_CHECK_MEAS                             0x2A5E     /**< PLX Service, spot check measurement characteristic UUID*/
 | 
			
		||||
#define BLE_UUID_PLX_CONTINUOUS_MEAS                             0x2A5F     /**< PLX Service, continuous measurement characteristic UUID*/
 | 
			
		||||
#define BLE_UUID_PLX_FEATURES                                    0x2A60     /**< PLX Service, feature characteristic UUID*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
/** @defgroup ALERT_LEVEL_VALUES Definitions for the Alert Level characteristic values
 | 
			
		||||
 * @{ */
 | 
			
		||||
#define BLE_CHAR_ALERT_LEVEL_NO_ALERT                            0x00       /**< No Alert. */
 | 
			
		||||
#define BLE_CHAR_ALERT_LEVEL_MILD_ALERT                          0x01       /**< Mild Alert. */
 | 
			
		||||
#define BLE_CHAR_ALERT_LEVEL_HIGH_ALERT                          0x02       /**< High Alert. */
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
#define BLE_SRV_ENCODED_REPORT_REF_LEN                           2          /**< The length of an encoded Report Reference Descriptor. */
 | 
			
		||||
#define BLE_CCCD_VALUE_LEN                                       2          /**< The length of a CCCD value. */
 | 
			
		||||
 | 
			
		||||
/**@brief Type definition for error handler function that will be called in case of an error in
 | 
			
		||||
 *        a service or a service library module. */
 | 
			
		||||
typedef void (*ble_srv_error_handler_t) (uint32_t nrf_error);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Value of a Report Reference descriptor. 
 | 
			
		||||
 *
 | 
			
		||||
 * @details This is mapping information that maps the parent characteristic to the Report ID(s) and
 | 
			
		||||
 *          Report Type(s) defined within a Report Map characteristic.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    uint8_t report_id;                                  /**< Non-zero value if there is more than one instance of the same Report Type */
 | 
			
		||||
    uint8_t report_type;                                /**< Type of Report characteristic (see @ref BLE_HIDS_REPORT_TYPE) */
 | 
			
		||||
} ble_srv_report_ref_t;
 | 
			
		||||
 | 
			
		||||
/**@brief UTF-8 string data type.
 | 
			
		||||
 *
 | 
			
		||||
 * @note The type can only hold a pointer to the string data (i.e. not the actual data).
 | 
			
		||||
 */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    uint16_t  length;                                   /**< String length. */
 | 
			
		||||
    uint8_t * p_str;                                    /**< String data. */
 | 
			
		||||
} ble_srv_utf8_str_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Security settings structure.
 | 
			
		||||
 * @details This structure contains the security options needed during initialization of the
 | 
			
		||||
 *          service.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    ble_gap_conn_sec_mode_t read_perm;                  /**< Read permissions. */
 | 
			
		||||
    ble_gap_conn_sec_mode_t write_perm;                 /**< Write permissions. */
 | 
			
		||||
} ble_srv_security_mode_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Security settings structure.
 | 
			
		||||
 * @details This structure contains the security options needed during initialization of the
 | 
			
		||||
 *          service. It can be used when the characteristics contains a CCCD.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    ble_gap_conn_sec_mode_t cccd_write_perm;            /**< Write permissions for Client Characteristic Configuration Descriptor. */
 | 
			
		||||
    ble_gap_conn_sec_mode_t read_perm;                  /**< Read permissions. */
 | 
			
		||||
    ble_gap_conn_sec_mode_t write_perm;                 /**< Write permissions. */
 | 
			
		||||
} ble_srv_cccd_security_mode_t;
 | 
			
		||||
 | 
			
		||||
/**@brief Function for decoding a CCCD value, and then testing if notification is
 | 
			
		||||
 *        enabled.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   p_encoded_data   Buffer where the encoded CCCD is stored.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval      TRUE If notification is enabled.
 | 
			
		||||
 * @retval      FALSE Otherwise.
 | 
			
		||||
 */
 | 
			
		||||
static __INLINE bool ble_srv_is_notification_enabled(uint8_t const * p_encoded_data)
 | 
			
		||||
{
 | 
			
		||||
    uint16_t cccd_value = uint16_decode(p_encoded_data);
 | 
			
		||||
    return ((cccd_value & BLE_GATT_HVX_NOTIFICATION) != 0);
 | 
			
		||||
}
 | 
			
		||||
    
 | 
			
		||||
/**@brief Function for decoding a CCCD value, and then testing if indication is
 | 
			
		||||
 *        enabled.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   p_encoded_data   Buffer where the encoded CCCD is stored.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval      TRUE If indication is enabled.
 | 
			
		||||
 * @retval      FALSE Otherwise.
 | 
			
		||||
 */
 | 
			
		||||
static __INLINE bool ble_srv_is_indication_enabled(uint8_t const * p_encoded_data)
 | 
			
		||||
{
 | 
			
		||||
    uint16_t cccd_value = uint16_decode(p_encoded_data);
 | 
			
		||||
    return ((cccd_value & BLE_GATT_HVX_INDICATION) != 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**@brief Function for encoding a Report Reference Descriptor.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   p_encoded_buffer  The buffer of the encoded data.
 | 
			
		||||
 * @param[in]   p_report_ref      Report Reference value to be encoded.
 | 
			
		||||
 *
 | 
			
		||||
 * @return      Length of the encoded data.
 | 
			
		||||
 */
 | 
			
		||||
uint8_t ble_srv_report_ref_encode(uint8_t *                    p_encoded_buffer,
 | 
			
		||||
                                  const ble_srv_report_ref_t * p_report_ref);
 | 
			
		||||
 | 
			
		||||
/**@brief Function for making a UTF-8 structure refer to an ASCII string.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[out]  p_utf8   UTF-8 structure to be set.
 | 
			
		||||
 * @param[in]   p_ascii  ASCII string to be referred to.
 | 
			
		||||
 */
 | 
			
		||||
void ble_srv_ascii_to_utf8(ble_srv_utf8_str_t * p_utf8, char * p_ascii);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Security Access enumeration.
 | 
			
		||||
 * @details This enumeration gives the possible requirements for accessing a characteristic value.
 | 
			
		||||
 */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    SEC_NO_ACCESS    = 0,            /**< Not possible to access. */
 | 
			
		||||
    SEC_OPEN         = 1,            /**< Access open. */
 | 
			
		||||
    SEC_JUST_WORKS   = 2,            /**< Access possible with 'Just Works' security at least. */
 | 
			
		||||
    SEC_MITM         = 3,            /**< Access possible with 'MITM' security at least. */
 | 
			
		||||
    SEC_SIGNED       = 4,            /**< Access possible with 'signed' security at least. */
 | 
			
		||||
    SEC_SIGNED_MITM  = 5             /**< Access possible with 'signed and MITM' security at least. */
 | 
			
		||||
}security_req_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Characteristic User Descriptor parameters.
 | 
			
		||||
 * @details This structure contains the parameters for User Descriptor.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    uint16_t               max_size;                      /**< Maximum size of the user descriptor*/
 | 
			
		||||
    uint16_t               size;                          /**< Size of the user descriptor*/
 | 
			
		||||
    uint8_t                *p_char_user_desc;             /**< User descriptor content, pointer to a UTF-8 encoded string (non-NULL terminated)*/
 | 
			
		||||
    bool                   is_var_len;                    /**< Indicates if the user descriptor has variable length.*/
 | 
			
		||||
    ble_gatt_char_props_t  char_props;                    /**< user descriptor properties.*/
 | 
			
		||||
    bool                   is_defered_read;               /**< Indicate if deferred read operations are supported.*/
 | 
			
		||||
    bool                   is_defered_write;              /**< Indicate if deferred write operations are supported.*/
 | 
			
		||||
    security_req_t         read_access;                   /**< Security requirement for reading the user descriptor.*/
 | 
			
		||||
    security_req_t         write_access;                  /**< Security requirement for writing the user descriptor.*/
 | 
			
		||||
    bool                   is_value_user;                 /**< Indicate if the content of the characteristic is to be stored in the application (user) or in the stack.*/
 | 
			
		||||
}ble_add_char_user_desc_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Add characteristic parameters structure.
 | 
			
		||||
 * @details This structure contains the parameters needed to use the @ref characteristic_add function.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    uint16_t                    uuid;                     /**< Characteristic UUID (16 bits UUIDs).*/
 | 
			
		||||
    uint8_t                     uuid_type;                /**< Base UUID. If 0, the Bluetooth SIG UUID will be used. Otherwise, this should be a value returned by @ref sd_ble_uuid_vs_add when adding the base UUID.*/
 | 
			
		||||
    uint16_t                    max_len;                  /**< Maximum length of the characteristic value.*/
 | 
			
		||||
    uint16_t                    init_len;                 /**< Initial length of the characteristic value.*/
 | 
			
		||||
    uint8_t *                   p_init_value;             /**< Initial encoded value of the characteristic.*/
 | 
			
		||||
    bool                        is_var_len;               /**< Indicates if the characteristic value has variable length.*/
 | 
			
		||||
    ble_gatt_char_props_t       char_props;               /**< Characteristic properties.*/
 | 
			
		||||
    bool                        is_defered_read;          /**< Indicate if deferred read operations are supported.*/
 | 
			
		||||
    bool                        is_defered_write;         /**< Indicate if deferred write operations are supported.*/
 | 
			
		||||
    security_req_t              read_access;              /**< Security requirement for reading the characteristic value.*/
 | 
			
		||||
    security_req_t              write_access;             /**< Security requirement for writing the characteristic value.*/
 | 
			
		||||
    security_req_t              cccd_write_access;        /**< Security requirement for writing the characteristic's CCCD.*/
 | 
			
		||||
    bool                        is_value_user;            /**< Indicate if the content of the characteristic is to be stored in the application (user) or in the stack.*/
 | 
			
		||||
    ble_add_char_user_desc_t    *p_user_descr;            /**< Pointer to user descriptor if needed*/
 | 
			
		||||
    ble_gatts_char_pf_t         *p_presentation_format;   /**< Pointer to characteristic format if needed*/
 | 
			
		||||
} ble_add_char_params_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Add descriptor parameters structure.
 | 
			
		||||
 * @details This structure contains the parameters needed to use the @ref descriptor_add function.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    uint16_t       uuid;                     /**< descriptor UUID (16 bits UUIDs).*/
 | 
			
		||||
    uint8_t        uuid_type;                /**< Base UUID. If 0, the Bluetooth SIG UUID will be used. Otherwise, this should be a value returned by @ref sd_ble_uuid_vs_add when adding the base UUID.*/
 | 
			
		||||
    bool           is_defered_read;          /**< Indicate if deferred read operations are supported.*/
 | 
			
		||||
    bool           is_defered_write;         /**< Indicate if deferred write operations are supported.*/
 | 
			
		||||
    bool           is_var_len;               /**< Indicates if the descriptor value has variable length.*/
 | 
			
		||||
    security_req_t read_access;              /**< Security requirement for reading the descriptor value.*/
 | 
			
		||||
    security_req_t write_access;             /**< Security requirement for writing the descriptor value.*/
 | 
			
		||||
    bool           is_value_user;            /**< Indicate if the content of the characteristic is to be stored in the application (user) or in the stack.*/
 | 
			
		||||
    uint16_t       init_len;                 /**< Initial descriptor value length in bytes. */
 | 
			
		||||
    uint16_t       init_offs;                /**< Initial descriptor value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */
 | 
			
		||||
    uint16_t       max_len;                  /**< Maximum descriptor value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */
 | 
			
		||||
    uint8_t*       p_value;                  /**< Pointer to the value of the descriptor*/
 | 
			
		||||
} ble_add_descr_params_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Function for adding a characteristic to a given service. 
 | 
			
		||||
 *
 | 
			
		||||
 * If no pointer is given for the initial value,
 | 
			
		||||
 * the initial length parameter will be ignored and the initial length will be 0.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]  service_handle Handle of the service to which the characteristic is to be added.
 | 
			
		||||
 * @param[in]  p_char_props   Information needed to add the characteristic.
 | 
			
		||||
 * @param[out] p_char_handle  Handle of the added characteristic.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval      NRF_SUCCESS If the characteristic was added successfully. Otherwise, an error code is returned.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t characteristic_add(uint16_t                   service_handle,
 | 
			
		||||
                            ble_add_char_params_t *    p_char_props,
 | 
			
		||||
                            ble_gatts_char_handles_t * p_char_handle);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**@brief Function for adding a characteristic's descriptor to a given characteristic.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]  char_handle    Handle of the characteristic to which the descriptor is to be added, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
 | 
			
		||||
 * @param[in]  p_descr_props  Information needed to add the descriptor.
 | 
			
		||||
 * @param[out] p_descr_handle Handle of the added descriptor.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval      NRF_SUCCESS If the characteristic was added successfully. Otherwise, an error code is returned.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t descriptor_add(uint16_t                   char_handle,
 | 
			
		||||
                        ble_add_descr_params_t *   p_descr_props,
 | 
			
		||||
                        uint16_t *                 p_descr_handle);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // BLE_SRV_COMMON_H__
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
		Reference in New Issue
	
	Block a user