To get started with Seeed Tiny BLE, include detecting motion, button and battery level.

Dependencies:   BLE_API eMPL_MPU6050 mbed nRF51822

Committer:
yihui
Date:
Wed Apr 22 07:47:17 2015 +0000
Revision:
1:fc2f9d636751
update libraries; ; delete nRF51822/nordic-sdk/components/gpiote/app_gpiote.c to solve GPIOTE_IRQHandler multiply defined issue. temperarily change nRF51822 library to folder

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yihui 1:fc2f9d636751 1 /* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
yihui 1:fc2f9d636751 2 *
yihui 1:fc2f9d636751 3 * The information contained herein is property of Nordic Semiconductor ASA.
yihui 1:fc2f9d636751 4 * Terms and conditions of usage are described in detail in NORDIC
yihui 1:fc2f9d636751 5 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
yihui 1:fc2f9d636751 6 *
yihui 1:fc2f9d636751 7 * Licensees are granted free, non-transferable use of the information. NO
yihui 1:fc2f9d636751 8 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
yihui 1:fc2f9d636751 9 * the file.
yihui 1:fc2f9d636751 10 *
yihui 1:fc2f9d636751 11 */
yihui 1:fc2f9d636751 12
yihui 1:fc2f9d636751 13 #include "ble_dfu.h"
yihui 1:fc2f9d636751 14 #include "nrf_error.h"
yihui 1:fc2f9d636751 15 #include "ble_types.h"
yihui 1:fc2f9d636751 16 #include "ble_gatts.h"
yihui 1:fc2f9d636751 17 #include "app_util.h"
yihui 1:fc2f9d636751 18 #include "ble_srv_common.h"
yihui 1:fc2f9d636751 19 #include "nordic_common.h"
yihui 1:fc2f9d636751 20 #include <stdint.h>
yihui 1:fc2f9d636751 21 #include <string.h>
yihui 1:fc2f9d636751 22 #include <stddef.h>
yihui 1:fc2f9d636751 23
yihui 1:fc2f9d636751 24 #define MAX_DFU_PKT_LEN 20 /**< Maximum length (in bytes) of the DFU Packet characteristic. */
yihui 1:fc2f9d636751 25 #define PKT_START_DFU_PARAM_LEN 2 /**< Length (in bytes) of the parameters for Packet Start DFU Request. */
yihui 1:fc2f9d636751 26 #define PKT_INIT_DFU_PARAM_LEN 2 /**< Length (in bytes) of the parameters for Packet Init DFU Request. */
yihui 1:fc2f9d636751 27 #define PKT_RCPT_NOTIF_REQ_LEN 3 /**< Length (in bytes) of the Packet Receipt Notification Request. */
yihui 1:fc2f9d636751 28 #define MAX_PKTS_RCPT_NOTIF_LEN 6 /**< Maximum length (in bytes) of the Packets Receipt Notification. */
yihui 1:fc2f9d636751 29 #define MAX_RESPONSE_LEN 7 /**< Maximum length (in bytes) of the response to a Control Point command. */
yihui 1:fc2f9d636751 30 #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. */
yihui 1:fc2f9d636751 31
yihui 1:fc2f9d636751 32 enum
yihui 1:fc2f9d636751 33 {
yihui 1:fc2f9d636751 34 OP_CODE_START_DFU = 1, /**< Value of the Op code field for 'Start DFU' command.*/
yihui 1:fc2f9d636751 35 OP_CODE_RECEIVE_INIT = 2, /**< Value of the Op code field for 'Initialize DFU parameters' command.*/
yihui 1:fc2f9d636751 36 OP_CODE_RECEIVE_FW = 3, /**< Value of the Op code field for 'Receive firmware image' command.*/
yihui 1:fc2f9d636751 37 OP_CODE_VALIDATE = 4, /**< Value of the Op code field for 'Validate firmware' command.*/
yihui 1:fc2f9d636751 38 OP_CODE_ACTIVATE_N_RESET = 5, /**< Value of the Op code field for 'Activate & Reset' command.*/
yihui 1:fc2f9d636751 39 OP_CODE_SYS_RESET = 6, /**< Value of the Op code field for 'Reset System' command.*/
yihui 1:fc2f9d636751 40 OP_CODE_IMAGE_SIZE_REQ = 7, /**< Value of the Op code field for 'Report received image size' command.*/
yihui 1:fc2f9d636751 41 OP_CODE_PKT_RCPT_NOTIF_REQ = 8, /**< Value of the Op code field for 'Request packet receipt notification.*/
yihui 1:fc2f9d636751 42 OP_CODE_RESPONSE = 16, /**< Value of the Op code field for 'Response.*/
yihui 1:fc2f9d636751 43 OP_CODE_PKT_RCPT_NOTIF = 17 /**< Value of the Op code field for 'Packets Receipt Notification'.*/
yihui 1:fc2f9d636751 44 };
yihui 1:fc2f9d636751 45
yihui 1:fc2f9d636751 46 static bool m_is_dfu_service_initialized = false; /**< Variable to check if the DFU service was initialized by the application.*/
yihui 1:fc2f9d636751 47 static uint8_t m_notif_buffer[MAX_NOTIF_BUFFER_LEN]; /**< Buffer used for sending notifications to peer. */
yihui 1:fc2f9d636751 48
yihui 1:fc2f9d636751 49 /**@brief Function for adding DFU Packet characteristic to the BLE Stack.
yihui 1:fc2f9d636751 50 *
yihui 1:fc2f9d636751 51 * @param[in] p_dfu DFU Service structure.
yihui 1:fc2f9d636751 52 *
yihui 1:fc2f9d636751 53 * @return NRF_SUCCESS on success. Otherwise an error code.
yihui 1:fc2f9d636751 54 */
yihui 1:fc2f9d636751 55 static uint32_t dfu_pkt_char_add(ble_dfu_t * const p_dfu)
yihui 1:fc2f9d636751 56 {
yihui 1:fc2f9d636751 57 ble_gatts_char_md_t char_md;
yihui 1:fc2f9d636751 58 ble_gatts_attr_t attr_char_value;
yihui 1:fc2f9d636751 59 ble_uuid_t char_uuid;
yihui 1:fc2f9d636751 60 ble_gatts_attr_md_t attr_md;
yihui 1:fc2f9d636751 61
yihui 1:fc2f9d636751 62 memset(&char_md, 0, sizeof(char_md));
yihui 1:fc2f9d636751 63
yihui 1:fc2f9d636751 64 char_md.char_props.write_wo_resp = 1;
yihui 1:fc2f9d636751 65 char_md.p_char_user_desc = NULL;
yihui 1:fc2f9d636751 66 char_md.p_char_pf = NULL;
yihui 1:fc2f9d636751 67 char_md.p_user_desc_md = NULL;
yihui 1:fc2f9d636751 68 char_md.p_cccd_md = NULL;
yihui 1:fc2f9d636751 69 char_md.p_sccd_md = NULL;
yihui 1:fc2f9d636751 70
yihui 1:fc2f9d636751 71 char_uuid.type = p_dfu->uuid_type;
yihui 1:fc2f9d636751 72 char_uuid.uuid = BLE_DFU_PKT_CHAR_UUID;
yihui 1:fc2f9d636751 73
yihui 1:fc2f9d636751 74 memset(&attr_md, 0, sizeof(attr_md));
yihui 1:fc2f9d636751 75
yihui 1:fc2f9d636751 76 BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm);
yihui 1:fc2f9d636751 77 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
yihui 1:fc2f9d636751 78
yihui 1:fc2f9d636751 79 attr_md.vloc = BLE_GATTS_VLOC_STACK;
yihui 1:fc2f9d636751 80 attr_md.rd_auth = 0;
yihui 1:fc2f9d636751 81 attr_md.wr_auth = 0;
yihui 1:fc2f9d636751 82 attr_md.vlen = 1;
yihui 1:fc2f9d636751 83
yihui 1:fc2f9d636751 84 memset(&attr_char_value, 0, sizeof(attr_char_value));
yihui 1:fc2f9d636751 85
yihui 1:fc2f9d636751 86 attr_char_value.p_uuid = &char_uuid;
yihui 1:fc2f9d636751 87 attr_char_value.p_attr_md = &attr_md;
yihui 1:fc2f9d636751 88 attr_char_value.init_len = 0;
yihui 1:fc2f9d636751 89 attr_char_value.init_offs = 0;
yihui 1:fc2f9d636751 90 attr_char_value.max_len = MAX_DFU_PKT_LEN;
yihui 1:fc2f9d636751 91 attr_char_value.p_value = NULL;
yihui 1:fc2f9d636751 92
yihui 1:fc2f9d636751 93 return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
yihui 1:fc2f9d636751 94 &char_md,
yihui 1:fc2f9d636751 95 &attr_char_value,
yihui 1:fc2f9d636751 96 &p_dfu->dfu_pkt_handles);
yihui 1:fc2f9d636751 97 }
yihui 1:fc2f9d636751 98
yihui 1:fc2f9d636751 99
yihui 1:fc2f9d636751 100 /**@brief Function for adding DFU Revision characteristic to the BLE Stack.
yihui 1:fc2f9d636751 101 *
yihui 1:fc2f9d636751 102 * @param[in] p_dfu DFU Service structure.
yihui 1:fc2f9d636751 103 *
yihui 1:fc2f9d636751 104 * @return NRF_SUCCESS on success. Otherwise an error code.
yihui 1:fc2f9d636751 105 */
yihui 1:fc2f9d636751 106 static uint32_t dfu_rev_char_add(ble_dfu_t * const p_dfu, ble_dfu_init_t const * const p_dfu_init)
yihui 1:fc2f9d636751 107 {
yihui 1:fc2f9d636751 108 ble_gatts_char_md_t char_md;
yihui 1:fc2f9d636751 109 ble_gatts_attr_t attr_char_value;
yihui 1:fc2f9d636751 110 ble_uuid_t char_uuid;
yihui 1:fc2f9d636751 111 ble_gatts_attr_md_t attr_md;
yihui 1:fc2f9d636751 112
yihui 1:fc2f9d636751 113 memset(&char_md, 0, sizeof(char_md));
yihui 1:fc2f9d636751 114
yihui 1:fc2f9d636751 115 char_md.char_props.read = 1;
yihui 1:fc2f9d636751 116 char_md.p_char_user_desc = NULL;
yihui 1:fc2f9d636751 117 char_md.p_char_pf = NULL;
yihui 1:fc2f9d636751 118 char_md.p_user_desc_md = NULL;
yihui 1:fc2f9d636751 119 char_md.p_cccd_md = NULL;
yihui 1:fc2f9d636751 120 char_md.p_sccd_md = NULL;
yihui 1:fc2f9d636751 121
yihui 1:fc2f9d636751 122 char_uuid.type = p_dfu->uuid_type;
yihui 1:fc2f9d636751 123 char_uuid.uuid = BLE_DFU_REV_CHAR_UUID;
yihui 1:fc2f9d636751 124
yihui 1:fc2f9d636751 125 memset(&attr_md, 0, sizeof(attr_md));
yihui 1:fc2f9d636751 126
yihui 1:fc2f9d636751 127 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
yihui 1:fc2f9d636751 128 BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
yihui 1:fc2f9d636751 129
yihui 1:fc2f9d636751 130 attr_md.vloc = BLE_GATTS_VLOC_STACK;
yihui 1:fc2f9d636751 131 attr_md.rd_auth = 0;
yihui 1:fc2f9d636751 132 attr_md.wr_auth = 0;
yihui 1:fc2f9d636751 133 attr_md.vlen = 1;
yihui 1:fc2f9d636751 134
yihui 1:fc2f9d636751 135 memset(&attr_char_value, 0, sizeof(attr_char_value));
yihui 1:fc2f9d636751 136
yihui 1:fc2f9d636751 137 attr_char_value.p_uuid = &char_uuid;
yihui 1:fc2f9d636751 138 attr_char_value.p_attr_md = &attr_md;
yihui 1:fc2f9d636751 139 attr_char_value.init_len = sizeof(uint16_t);
yihui 1:fc2f9d636751 140 attr_char_value.init_offs = 0;
yihui 1:fc2f9d636751 141 attr_char_value.max_len = sizeof(uint16_t);
yihui 1:fc2f9d636751 142 attr_char_value.p_value = (uint8_t *)&p_dfu_init->revision;
yihui 1:fc2f9d636751 143
yihui 1:fc2f9d636751 144 return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
yihui 1:fc2f9d636751 145 &char_md,
yihui 1:fc2f9d636751 146 &attr_char_value,
yihui 1:fc2f9d636751 147 &p_dfu->dfu_rev_handles);
yihui 1:fc2f9d636751 148 }
yihui 1:fc2f9d636751 149
yihui 1:fc2f9d636751 150
yihui 1:fc2f9d636751 151 /**@brief Function for adding DFU Control Point characteristic to the BLE Stack.
yihui 1:fc2f9d636751 152 *
yihui 1:fc2f9d636751 153 * @param[in] p_dfu DFU Service structure.
yihui 1:fc2f9d636751 154 *
yihui 1:fc2f9d636751 155 * @return NRF_SUCCESS on success. Otherwise an error code.
yihui 1:fc2f9d636751 156 */
yihui 1:fc2f9d636751 157 static uint32_t dfu_ctrl_pt_add(ble_dfu_t * const p_dfu)
yihui 1:fc2f9d636751 158 {
yihui 1:fc2f9d636751 159 ble_gatts_char_md_t char_md;
yihui 1:fc2f9d636751 160 ble_gatts_attr_t attr_char_value;
yihui 1:fc2f9d636751 161 ble_uuid_t char_uuid;
yihui 1:fc2f9d636751 162 ble_gatts_attr_md_t attr_md;
yihui 1:fc2f9d636751 163
yihui 1:fc2f9d636751 164 memset(&char_md, 0, sizeof(char_md));
yihui 1:fc2f9d636751 165
yihui 1:fc2f9d636751 166 char_md.char_props.write = 1;
yihui 1:fc2f9d636751 167 char_md.char_props.notify = 1;
yihui 1:fc2f9d636751 168 char_md.p_char_user_desc = NULL;
yihui 1:fc2f9d636751 169 char_md.p_char_pf = NULL;
yihui 1:fc2f9d636751 170 char_md.p_user_desc_md = NULL;
yihui 1:fc2f9d636751 171 char_md.p_cccd_md = NULL;
yihui 1:fc2f9d636751 172 char_md.p_sccd_md = NULL;
yihui 1:fc2f9d636751 173
yihui 1:fc2f9d636751 174 char_uuid.type = p_dfu->uuid_type;
yihui 1:fc2f9d636751 175 char_uuid.uuid = BLE_DFU_CTRL_PT_UUID;
yihui 1:fc2f9d636751 176
yihui 1:fc2f9d636751 177 memset(&attr_md, 0, sizeof(attr_md));
yihui 1:fc2f9d636751 178
yihui 1:fc2f9d636751 179 BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm);
yihui 1:fc2f9d636751 180 BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
yihui 1:fc2f9d636751 181
yihui 1:fc2f9d636751 182 attr_md.vloc = BLE_GATTS_VLOC_STACK;
yihui 1:fc2f9d636751 183 attr_md.rd_auth = 0;
yihui 1:fc2f9d636751 184 attr_md.wr_auth = 1;
yihui 1:fc2f9d636751 185 attr_md.vlen = 1;
yihui 1:fc2f9d636751 186
yihui 1:fc2f9d636751 187 memset(&attr_char_value, 0, sizeof(attr_char_value));
yihui 1:fc2f9d636751 188
yihui 1:fc2f9d636751 189 attr_char_value.p_uuid = &char_uuid;
yihui 1:fc2f9d636751 190 attr_char_value.p_attr_md = &attr_md;
yihui 1:fc2f9d636751 191 attr_char_value.init_len = 0;
yihui 1:fc2f9d636751 192 attr_char_value.init_offs = 0;
yihui 1:fc2f9d636751 193 attr_char_value.max_len = BLE_L2CAP_MTU_DEF;
yihui 1:fc2f9d636751 194 attr_char_value.p_value = NULL;
yihui 1:fc2f9d636751 195
yihui 1:fc2f9d636751 196 return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
yihui 1:fc2f9d636751 197 &char_md,
yihui 1:fc2f9d636751 198 &attr_char_value,
yihui 1:fc2f9d636751 199 &p_dfu->dfu_ctrl_pt_handles);
yihui 1:fc2f9d636751 200 }
yihui 1:fc2f9d636751 201
yihui 1:fc2f9d636751 202
yihui 1:fc2f9d636751 203 /**@brief Function for handling the @ref BLE_GAP_EVT_CONNECTED event from the S110 SoftDevice.
yihui 1:fc2f9d636751 204 *
yihui 1:fc2f9d636751 205 * @param[in] p_dfu DFU Service Structure.
yihui 1:fc2f9d636751 206 * @param[in] p_ble_evt Pointer to the event received from BLE stack.
yihui 1:fc2f9d636751 207 */
yihui 1:fc2f9d636751 208 static void on_connect(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
yihui 1:fc2f9d636751 209 {
yihui 1:fc2f9d636751 210 p_dfu->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
yihui 1:fc2f9d636751 211 }
yihui 1:fc2f9d636751 212
yihui 1:fc2f9d636751 213
yihui 1:fc2f9d636751 214 /**@brief Function for checking if the CCCD of DFU Control point is configured for Notification.
yihui 1:fc2f9d636751 215 *
yihui 1:fc2f9d636751 216 * @details This function checks if the CCCD of DFU Control Point characteristic is configured
yihui 1:fc2f9d636751 217 * for Notification by the DFU Controller.
yihui 1:fc2f9d636751 218 *
yihui 1:fc2f9d636751 219 * @param[in] p_dfu DFU Service structure.
yihui 1:fc2f9d636751 220 *
yihui 1:fc2f9d636751 221 * @return True if the CCCD of DFU Control Point characteristic is configured for Notification.
yihui 1:fc2f9d636751 222 * False otherwise.
yihui 1:fc2f9d636751 223 */
yihui 1:fc2f9d636751 224 static bool is_cccd_configured(ble_dfu_t * p_dfu)
yihui 1:fc2f9d636751 225 {
yihui 1:fc2f9d636751 226 // Check if the CCCDs are configured.
yihui 1:fc2f9d636751 227 uint16_t cccd_len = BLE_CCCD_VALUE_LEN;
yihui 1:fc2f9d636751 228 uint8_t cccd_val_buf[BLE_CCCD_VALUE_LEN];
yihui 1:fc2f9d636751 229
yihui 1:fc2f9d636751 230 // Check the CCCD Value of DFU Control Point.
yihui 1:fc2f9d636751 231 uint32_t err_code = sd_ble_gatts_value_get(p_dfu->dfu_ctrl_pt_handles.cccd_handle,
yihui 1:fc2f9d636751 232 0,
yihui 1:fc2f9d636751 233 &cccd_len,
yihui 1:fc2f9d636751 234 cccd_val_buf);
yihui 1:fc2f9d636751 235 if (err_code != NRF_SUCCESS)
yihui 1:fc2f9d636751 236 {
yihui 1:fc2f9d636751 237 if (p_dfu->error_handler != NULL)
yihui 1:fc2f9d636751 238 {
yihui 1:fc2f9d636751 239 p_dfu->error_handler(err_code);
yihui 1:fc2f9d636751 240 }
yihui 1:fc2f9d636751 241 return false;
yihui 1:fc2f9d636751 242 }
yihui 1:fc2f9d636751 243
yihui 1:fc2f9d636751 244 return ble_srv_is_notification_enabled(cccd_val_buf);
yihui 1:fc2f9d636751 245 }
yihui 1:fc2f9d636751 246
yihui 1:fc2f9d636751 247
yihui 1:fc2f9d636751 248 /**@brief Function for handling a Write event on the Control Point characteristic.
yihui 1:fc2f9d636751 249 *
yihui 1:fc2f9d636751 250 * @param[in] p_dfu DFU Service Structure.
yihui 1:fc2f9d636751 251 * @param[in] p_ble_write_evt Pointer to the write event received from BLE stack.
yihui 1:fc2f9d636751 252 *
yihui 1:fc2f9d636751 253 * @return NRF_SUCCESS on successful processing of control point write. Otherwise an error code.
yihui 1:fc2f9d636751 254 */
yihui 1:fc2f9d636751 255 static uint32_t on_ctrl_pt_write(ble_dfu_t * p_dfu, ble_gatts_evt_write_t * p_ble_write_evt)
yihui 1:fc2f9d636751 256 {
yihui 1:fc2f9d636751 257 ble_gatts_rw_authorize_reply_params_t write_authorize_reply;
yihui 1:fc2f9d636751 258
yihui 1:fc2f9d636751 259 write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
yihui 1:fc2f9d636751 260
yihui 1:fc2f9d636751 261 if (!is_cccd_configured(p_dfu))
yihui 1:fc2f9d636751 262 {
yihui 1:fc2f9d636751 263 // Send an error response to the peer indicating that the CCCD is improperly configured.
yihui 1:fc2f9d636751 264 write_authorize_reply.params.write.gatt_status =
yihui 1:fc2f9d636751 265 BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR;
yihui 1:fc2f9d636751 266
yihui 1:fc2f9d636751 267 return (sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &write_authorize_reply));
yihui 1:fc2f9d636751 268
yihui 1:fc2f9d636751 269 }
yihui 1:fc2f9d636751 270 else
yihui 1:fc2f9d636751 271 {
yihui 1:fc2f9d636751 272 uint32_t err_code;
yihui 1:fc2f9d636751 273
yihui 1:fc2f9d636751 274 write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
yihui 1:fc2f9d636751 275
yihui 1:fc2f9d636751 276 err_code = (sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &write_authorize_reply));
yihui 1:fc2f9d636751 277
yihui 1:fc2f9d636751 278 if (err_code != NRF_SUCCESS)
yihui 1:fc2f9d636751 279 {
yihui 1:fc2f9d636751 280 return err_code;
yihui 1:fc2f9d636751 281 }
yihui 1:fc2f9d636751 282 }
yihui 1:fc2f9d636751 283
yihui 1:fc2f9d636751 284 ble_dfu_evt_t ble_dfu_evt;
yihui 1:fc2f9d636751 285
yihui 1:fc2f9d636751 286 switch (p_ble_write_evt->data[0])
yihui 1:fc2f9d636751 287 {
yihui 1:fc2f9d636751 288 case OP_CODE_START_DFU:
yihui 1:fc2f9d636751 289 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_START;
yihui 1:fc2f9d636751 290
yihui 1:fc2f9d636751 291 if (p_ble_write_evt->len < PKT_START_DFU_PARAM_LEN)
yihui 1:fc2f9d636751 292 {
yihui 1:fc2f9d636751 293 return ble_dfu_response_send(p_dfu,
yihui 1:fc2f9d636751 294 (ble_dfu_procedure_t) p_ble_write_evt->data[0],
yihui 1:fc2f9d636751 295 BLE_DFU_RESP_VAL_OPER_FAILED);
yihui 1:fc2f9d636751 296 }
yihui 1:fc2f9d636751 297
yihui 1:fc2f9d636751 298 ble_dfu_evt.evt.ble_dfu_pkt_write.len = 1;
yihui 1:fc2f9d636751 299 ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = &(p_ble_write_evt->data[1]);
yihui 1:fc2f9d636751 300
yihui 1:fc2f9d636751 301 p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
yihui 1:fc2f9d636751 302 break;
yihui 1:fc2f9d636751 303
yihui 1:fc2f9d636751 304 case OP_CODE_RECEIVE_INIT:
yihui 1:fc2f9d636751 305 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_RECEIVE_INIT_DATA;
yihui 1:fc2f9d636751 306
yihui 1:fc2f9d636751 307 if (p_ble_write_evt->len < PKT_INIT_DFU_PARAM_LEN)
yihui 1:fc2f9d636751 308 {
yihui 1:fc2f9d636751 309 return ble_dfu_response_send(p_dfu,
yihui 1:fc2f9d636751 310 (ble_dfu_procedure_t) p_ble_write_evt->data[0],
yihui 1:fc2f9d636751 311 BLE_DFU_RESP_VAL_OPER_FAILED);
yihui 1:fc2f9d636751 312 }
yihui 1:fc2f9d636751 313
yihui 1:fc2f9d636751 314 ble_dfu_evt.evt.ble_dfu_pkt_write.len = 1;
yihui 1:fc2f9d636751 315 ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = &(p_ble_write_evt->data[1]);
yihui 1:fc2f9d636751 316
yihui 1:fc2f9d636751 317 p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
yihui 1:fc2f9d636751 318 break;
yihui 1:fc2f9d636751 319
yihui 1:fc2f9d636751 320 case OP_CODE_RECEIVE_FW:
yihui 1:fc2f9d636751 321 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_RECEIVE_APP_DATA;
yihui 1:fc2f9d636751 322
yihui 1:fc2f9d636751 323 p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
yihui 1:fc2f9d636751 324 break;
yihui 1:fc2f9d636751 325
yihui 1:fc2f9d636751 326 case OP_CODE_VALIDATE:
yihui 1:fc2f9d636751 327 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_VALIDATE;
yihui 1:fc2f9d636751 328
yihui 1:fc2f9d636751 329 p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
yihui 1:fc2f9d636751 330 break;
yihui 1:fc2f9d636751 331
yihui 1:fc2f9d636751 332 case OP_CODE_ACTIVATE_N_RESET:
yihui 1:fc2f9d636751 333 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_ACTIVATE_N_RESET;
yihui 1:fc2f9d636751 334
yihui 1:fc2f9d636751 335 p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
yihui 1:fc2f9d636751 336 break;
yihui 1:fc2f9d636751 337
yihui 1:fc2f9d636751 338 case OP_CODE_SYS_RESET:
yihui 1:fc2f9d636751 339 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_SYS_RESET;
yihui 1:fc2f9d636751 340
yihui 1:fc2f9d636751 341 p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
yihui 1:fc2f9d636751 342 break;
yihui 1:fc2f9d636751 343
yihui 1:fc2f9d636751 344 case OP_CODE_PKT_RCPT_NOTIF_REQ:
yihui 1:fc2f9d636751 345 if (p_ble_write_evt->len < PKT_RCPT_NOTIF_REQ_LEN)
yihui 1:fc2f9d636751 346 {
yihui 1:fc2f9d636751 347 return (ble_dfu_response_send(p_dfu,
yihui 1:fc2f9d636751 348 BLE_DFU_PKT_RCPT_REQ_PROCEDURE,
yihui 1:fc2f9d636751 349 BLE_DFU_RESP_VAL_NOT_SUPPORTED));
yihui 1:fc2f9d636751 350 }
yihui 1:fc2f9d636751 351
yihui 1:fc2f9d636751 352 ble_dfu_evt.evt.pkt_rcpt_notif_req.num_of_pkts =
yihui 1:fc2f9d636751 353 uint16_decode(&(p_ble_write_evt->data[1]));
yihui 1:fc2f9d636751 354
yihui 1:fc2f9d636751 355 if (ble_dfu_evt.evt.pkt_rcpt_notif_req.num_of_pkts == 0)
yihui 1:fc2f9d636751 356 {
yihui 1:fc2f9d636751 357 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PKT_RCPT_NOTIF_DISABLED;
yihui 1:fc2f9d636751 358 }
yihui 1:fc2f9d636751 359 else
yihui 1:fc2f9d636751 360 {
yihui 1:fc2f9d636751 361 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PKT_RCPT_NOTIF_ENABLED;
yihui 1:fc2f9d636751 362 }
yihui 1:fc2f9d636751 363
yihui 1:fc2f9d636751 364 p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
yihui 1:fc2f9d636751 365
yihui 1:fc2f9d636751 366 break;
yihui 1:fc2f9d636751 367
yihui 1:fc2f9d636751 368 case OP_CODE_IMAGE_SIZE_REQ:
yihui 1:fc2f9d636751 369 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_BYTES_RECEIVED_SEND;
yihui 1:fc2f9d636751 370
yihui 1:fc2f9d636751 371 p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
yihui 1:fc2f9d636751 372 break;
yihui 1:fc2f9d636751 373
yihui 1:fc2f9d636751 374 default:
yihui 1:fc2f9d636751 375 // Unsupported op code.
yihui 1:fc2f9d636751 376 return ble_dfu_response_send(p_dfu,
yihui 1:fc2f9d636751 377 (ble_dfu_procedure_t) p_ble_write_evt->data[0],
yihui 1:fc2f9d636751 378 BLE_DFU_RESP_VAL_NOT_SUPPORTED);
yihui 1:fc2f9d636751 379 }
yihui 1:fc2f9d636751 380 return NRF_SUCCESS;
yihui 1:fc2f9d636751 381 }
yihui 1:fc2f9d636751 382
yihui 1:fc2f9d636751 383
yihui 1:fc2f9d636751 384 /**@brief Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event from the S110
yihui 1:fc2f9d636751 385 * Stack.
yihui 1:fc2f9d636751 386 *
yihui 1:fc2f9d636751 387 * @param[in] p_dfu DFU Service Structure.
yihui 1:fc2f9d636751 388 * @param[in] p_ble_evt Pointer to the event received from BLE stack.
yihui 1:fc2f9d636751 389 */
yihui 1:fc2f9d636751 390 static void on_rw_auth_req(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
yihui 1:fc2f9d636751 391 {
yihui 1:fc2f9d636751 392 ble_gatts_evt_rw_authorize_request_t * p_authorize_request;
yihui 1:fc2f9d636751 393
yihui 1:fc2f9d636751 394 p_authorize_request = &(p_ble_evt->evt.gatts_evt.params.authorize_request);
yihui 1:fc2f9d636751 395
yihui 1:fc2f9d636751 396 if (
yihui 1:fc2f9d636751 397 (p_authorize_request->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
yihui 1:fc2f9d636751 398 &&
yihui 1:fc2f9d636751 399 (p_authorize_request->request.write.handle == p_dfu->dfu_ctrl_pt_handles.value_handle)
yihui 1:fc2f9d636751 400 )
yihui 1:fc2f9d636751 401 {
yihui 1:fc2f9d636751 402 uint32_t err_code;
yihui 1:fc2f9d636751 403
yihui 1:fc2f9d636751 404 err_code = on_ctrl_pt_write(p_dfu, &(p_authorize_request->request.write));
yihui 1:fc2f9d636751 405
yihui 1:fc2f9d636751 406 if (err_code != NRF_SUCCESS && p_dfu->error_handler != NULL)
yihui 1:fc2f9d636751 407 {
yihui 1:fc2f9d636751 408 p_dfu->error_handler(err_code);
yihui 1:fc2f9d636751 409 }
yihui 1:fc2f9d636751 410 }
yihui 1:fc2f9d636751 411 }
yihui 1:fc2f9d636751 412
yihui 1:fc2f9d636751 413
yihui 1:fc2f9d636751 414 /**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the S110 SoftDevice.
yihui 1:fc2f9d636751 415 *
yihui 1:fc2f9d636751 416 * @param[in] p_dfu DFU Service Structure.
yihui 1:fc2f9d636751 417 * @param[in] p_ble_evt Pointer to the event received from BLE stack.
yihui 1:fc2f9d636751 418 */
yihui 1:fc2f9d636751 419 static void on_write(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
yihui 1:fc2f9d636751 420 {
yihui 1:fc2f9d636751 421 if (p_ble_evt->evt.gatts_evt.params.write.handle == p_dfu->dfu_pkt_handles.value_handle)
yihui 1:fc2f9d636751 422 {
yihui 1:fc2f9d636751 423 // DFU Packet written
yihui 1:fc2f9d636751 424
yihui 1:fc2f9d636751 425 ble_dfu_evt_t ble_dfu_evt;
yihui 1:fc2f9d636751 426
yihui 1:fc2f9d636751 427 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PACKET_WRITE;
yihui 1:fc2f9d636751 428 ble_dfu_evt.evt.ble_dfu_pkt_write.len = p_ble_evt->evt.gatts_evt.params.write.len;
yihui 1:fc2f9d636751 429 ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = p_ble_evt->evt.gatts_evt.params.write.data;
yihui 1:fc2f9d636751 430
yihui 1:fc2f9d636751 431 p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
yihui 1:fc2f9d636751 432 }
yihui 1:fc2f9d636751 433 }
yihui 1:fc2f9d636751 434
yihui 1:fc2f9d636751 435
yihui 1:fc2f9d636751 436 /**@brief Function for handling the BLE_GAP_EVT_DISCONNECTED event from the S110 SoftDevice.
yihui 1:fc2f9d636751 437 *
yihui 1:fc2f9d636751 438 * @param[in] p_dfu DFU Service Structure.
yihui 1:fc2f9d636751 439 * @param[in] p_ble_evt Pointer to the event received from BLE stack.
yihui 1:fc2f9d636751 440 */
yihui 1:fc2f9d636751 441 static void on_disconnect(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
yihui 1:fc2f9d636751 442 {
yihui 1:fc2f9d636751 443 p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID;
yihui 1:fc2f9d636751 444 }
yihui 1:fc2f9d636751 445
yihui 1:fc2f9d636751 446
yihui 1:fc2f9d636751 447 uint32_t ble_dfu_init(ble_dfu_t * p_dfu, ble_dfu_init_t * p_dfu_init)
yihui 1:fc2f9d636751 448 {
yihui 1:fc2f9d636751 449 if ((p_dfu == NULL) || (p_dfu_init == NULL) || (p_dfu_init->evt_handler == NULL))
yihui 1:fc2f9d636751 450 {
yihui 1:fc2f9d636751 451 return NRF_ERROR_NULL;
yihui 1:fc2f9d636751 452 }
yihui 1:fc2f9d636751 453
yihui 1:fc2f9d636751 454 p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID;
yihui 1:fc2f9d636751 455
yihui 1:fc2f9d636751 456 ble_uuid_t service_uuid;
yihui 1:fc2f9d636751 457 uint32_t err_code;
yihui 1:fc2f9d636751 458
yihui 1:fc2f9d636751 459 const ble_uuid128_t base_uuid128 =
yihui 1:fc2f9d636751 460 {
yihui 1:fc2f9d636751 461 {
yihui 1:fc2f9d636751 462 0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15,
yihui 1:fc2f9d636751 463 0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00
yihui 1:fc2f9d636751 464 }
yihui 1:fc2f9d636751 465 };
yihui 1:fc2f9d636751 466
yihui 1:fc2f9d636751 467 service_uuid.uuid = BLE_DFU_SERVICE_UUID;
yihui 1:fc2f9d636751 468
yihui 1:fc2f9d636751 469 err_code = sd_ble_uuid_vs_add(&base_uuid128, &(service_uuid.type));
yihui 1:fc2f9d636751 470 if (err_code != NRF_SUCCESS)
yihui 1:fc2f9d636751 471 {
yihui 1:fc2f9d636751 472 return err_code;
yihui 1:fc2f9d636751 473 }
yihui 1:fc2f9d636751 474
yihui 1:fc2f9d636751 475 err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
yihui 1:fc2f9d636751 476 &service_uuid,
yihui 1:fc2f9d636751 477 &(p_dfu->service_handle));
yihui 1:fc2f9d636751 478 if (err_code != NRF_SUCCESS)
yihui 1:fc2f9d636751 479 {
yihui 1:fc2f9d636751 480 return err_code;
yihui 1:fc2f9d636751 481 }
yihui 1:fc2f9d636751 482
yihui 1:fc2f9d636751 483 p_dfu->uuid_type = service_uuid.type;
yihui 1:fc2f9d636751 484
yihui 1:fc2f9d636751 485 err_code = dfu_pkt_char_add(p_dfu);
yihui 1:fc2f9d636751 486 if (err_code != NRF_SUCCESS)
yihui 1:fc2f9d636751 487 {
yihui 1:fc2f9d636751 488 return err_code;
yihui 1:fc2f9d636751 489 }
yihui 1:fc2f9d636751 490
yihui 1:fc2f9d636751 491 err_code = dfu_ctrl_pt_add(p_dfu);
yihui 1:fc2f9d636751 492 if (err_code != NRF_SUCCESS)
yihui 1:fc2f9d636751 493 {
yihui 1:fc2f9d636751 494 return err_code;
yihui 1:fc2f9d636751 495 }
yihui 1:fc2f9d636751 496
yihui 1:fc2f9d636751 497 err_code = dfu_rev_char_add(p_dfu, p_dfu_init);
yihui 1:fc2f9d636751 498 if (err_code != NRF_SUCCESS)
yihui 1:fc2f9d636751 499 {
yihui 1:fc2f9d636751 500 return err_code;
yihui 1:fc2f9d636751 501 }
yihui 1:fc2f9d636751 502
yihui 1:fc2f9d636751 503 p_dfu->evt_handler = p_dfu_init->evt_handler;
yihui 1:fc2f9d636751 504
yihui 1:fc2f9d636751 505 if (p_dfu_init->error_handler != NULL)
yihui 1:fc2f9d636751 506 {
yihui 1:fc2f9d636751 507 p_dfu->error_handler = p_dfu_init->error_handler;
yihui 1:fc2f9d636751 508 }
yihui 1:fc2f9d636751 509
yihui 1:fc2f9d636751 510 m_is_dfu_service_initialized = true;
yihui 1:fc2f9d636751 511
yihui 1:fc2f9d636751 512 return NRF_SUCCESS;
yihui 1:fc2f9d636751 513 }
yihui 1:fc2f9d636751 514
yihui 1:fc2f9d636751 515
yihui 1:fc2f9d636751 516 void ble_dfu_on_ble_evt(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
yihui 1:fc2f9d636751 517 {
yihui 1:fc2f9d636751 518 if ((p_dfu == NULL) || (p_ble_evt == NULL))
yihui 1:fc2f9d636751 519 {
yihui 1:fc2f9d636751 520 return;
yihui 1:fc2f9d636751 521 }
yihui 1:fc2f9d636751 522
yihui 1:fc2f9d636751 523 if (p_dfu->evt_handler != NULL)
yihui 1:fc2f9d636751 524 {
yihui 1:fc2f9d636751 525 switch (p_ble_evt->header.evt_id)
yihui 1:fc2f9d636751 526 {
yihui 1:fc2f9d636751 527 case BLE_GAP_EVT_CONNECTED:
yihui 1:fc2f9d636751 528 on_connect(p_dfu, p_ble_evt);
yihui 1:fc2f9d636751 529 break;
yihui 1:fc2f9d636751 530
yihui 1:fc2f9d636751 531 case BLE_GATTS_EVT_WRITE:
yihui 1:fc2f9d636751 532 on_write(p_dfu, p_ble_evt);
yihui 1:fc2f9d636751 533 break;
yihui 1:fc2f9d636751 534
yihui 1:fc2f9d636751 535 case BLE_GAP_EVT_DISCONNECTED:
yihui 1:fc2f9d636751 536 on_disconnect(p_dfu, p_ble_evt);
yihui 1:fc2f9d636751 537 break;
yihui 1:fc2f9d636751 538
yihui 1:fc2f9d636751 539 case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
yihui 1:fc2f9d636751 540 on_rw_auth_req(p_dfu, p_ble_evt);
yihui 1:fc2f9d636751 541 break;
yihui 1:fc2f9d636751 542
yihui 1:fc2f9d636751 543 default:
yihui 1:fc2f9d636751 544 // No implementation needed.
yihui 1:fc2f9d636751 545 break;
yihui 1:fc2f9d636751 546 }
yihui 1:fc2f9d636751 547 }
yihui 1:fc2f9d636751 548 }
yihui 1:fc2f9d636751 549
yihui 1:fc2f9d636751 550
yihui 1:fc2f9d636751 551 uint32_t ble_dfu_bytes_rcvd_report(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd)
yihui 1:fc2f9d636751 552 {
yihui 1:fc2f9d636751 553 if (p_dfu == NULL)
yihui 1:fc2f9d636751 554 {
yihui 1:fc2f9d636751 555 return NRF_ERROR_NULL;
yihui 1:fc2f9d636751 556 }
yihui 1:fc2f9d636751 557
yihui 1:fc2f9d636751 558 if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized)
yihui 1:fc2f9d636751 559 {
yihui 1:fc2f9d636751 560 return NRF_ERROR_INVALID_STATE;
yihui 1:fc2f9d636751 561 }
yihui 1:fc2f9d636751 562
yihui 1:fc2f9d636751 563 ble_gatts_hvx_params_t hvx_params;
yihui 1:fc2f9d636751 564 uint16_t index = 0;
yihui 1:fc2f9d636751 565
yihui 1:fc2f9d636751 566 // Encode the Op Code.
yihui 1:fc2f9d636751 567 m_notif_buffer[index++] = OP_CODE_RESPONSE;
yihui 1:fc2f9d636751 568
yihui 1:fc2f9d636751 569 // Encode the Reqest Op Code.
yihui 1:fc2f9d636751 570 m_notif_buffer[index++] = OP_CODE_IMAGE_SIZE_REQ;
yihui 1:fc2f9d636751 571
yihui 1:fc2f9d636751 572 // Encode the Response Value.
yihui 1:fc2f9d636751 573 m_notif_buffer[index++] = (uint8_t)BLE_DFU_RESP_VAL_SUCCESS;
yihui 1:fc2f9d636751 574
yihui 1:fc2f9d636751 575 index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]);
yihui 1:fc2f9d636751 576
yihui 1:fc2f9d636751 577 memset(&hvx_params, 0, sizeof(hvx_params));
yihui 1:fc2f9d636751 578
yihui 1:fc2f9d636751 579 hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
yihui 1:fc2f9d636751 580 hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
yihui 1:fc2f9d636751 581 hvx_params.offset = 0;
yihui 1:fc2f9d636751 582 hvx_params.p_len = &index;
yihui 1:fc2f9d636751 583 hvx_params.p_data = m_notif_buffer;
yihui 1:fc2f9d636751 584
yihui 1:fc2f9d636751 585 return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
yihui 1:fc2f9d636751 586 }
yihui 1:fc2f9d636751 587
yihui 1:fc2f9d636751 588
yihui 1:fc2f9d636751 589 uint32_t ble_dfu_pkts_rcpt_notify(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd)
yihui 1:fc2f9d636751 590 {
yihui 1:fc2f9d636751 591 if (p_dfu == NULL)
yihui 1:fc2f9d636751 592 {
yihui 1:fc2f9d636751 593 return NRF_ERROR_NULL;
yihui 1:fc2f9d636751 594 }
yihui 1:fc2f9d636751 595
yihui 1:fc2f9d636751 596 if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized)
yihui 1:fc2f9d636751 597 {
yihui 1:fc2f9d636751 598 return NRF_ERROR_INVALID_STATE;
yihui 1:fc2f9d636751 599 }
yihui 1:fc2f9d636751 600
yihui 1:fc2f9d636751 601 ble_gatts_hvx_params_t hvx_params;
yihui 1:fc2f9d636751 602 uint16_t index = 0;
yihui 1:fc2f9d636751 603
yihui 1:fc2f9d636751 604 m_notif_buffer[index++] = OP_CODE_PKT_RCPT_NOTIF;
yihui 1:fc2f9d636751 605
yihui 1:fc2f9d636751 606 index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]);
yihui 1:fc2f9d636751 607
yihui 1:fc2f9d636751 608 memset(&hvx_params, 0, sizeof(hvx_params));
yihui 1:fc2f9d636751 609
yihui 1:fc2f9d636751 610 hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
yihui 1:fc2f9d636751 611 hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
yihui 1:fc2f9d636751 612 hvx_params.offset = 0;
yihui 1:fc2f9d636751 613 hvx_params.p_len = &index;
yihui 1:fc2f9d636751 614 hvx_params.p_data = m_notif_buffer;
yihui 1:fc2f9d636751 615
yihui 1:fc2f9d636751 616 return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
yihui 1:fc2f9d636751 617 }
yihui 1:fc2f9d636751 618
yihui 1:fc2f9d636751 619
yihui 1:fc2f9d636751 620 uint32_t ble_dfu_response_send(ble_dfu_t * p_dfu,
yihui 1:fc2f9d636751 621 ble_dfu_procedure_t dfu_proc,
yihui 1:fc2f9d636751 622 ble_dfu_resp_val_t resp_val)
yihui 1:fc2f9d636751 623 {
yihui 1:fc2f9d636751 624 if (p_dfu == NULL)
yihui 1:fc2f9d636751 625 {
yihui 1:fc2f9d636751 626 return NRF_ERROR_NULL;
yihui 1:fc2f9d636751 627 }
yihui 1:fc2f9d636751 628
yihui 1:fc2f9d636751 629 if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized)
yihui 1:fc2f9d636751 630 {
yihui 1:fc2f9d636751 631 return NRF_ERROR_INVALID_STATE;
yihui 1:fc2f9d636751 632 }
yihui 1:fc2f9d636751 633
yihui 1:fc2f9d636751 634 ble_gatts_hvx_params_t hvx_params;
yihui 1:fc2f9d636751 635 uint16_t index = 0;
yihui 1:fc2f9d636751 636
yihui 1:fc2f9d636751 637 m_notif_buffer[index++] = OP_CODE_RESPONSE;
yihui 1:fc2f9d636751 638
yihui 1:fc2f9d636751 639 // Encode the Request Op code
yihui 1:fc2f9d636751 640 m_notif_buffer[index++] = (uint8_t)dfu_proc;
yihui 1:fc2f9d636751 641
yihui 1:fc2f9d636751 642 // Encode the Response Value.
yihui 1:fc2f9d636751 643 m_notif_buffer[index++] = (uint8_t)resp_val;
yihui 1:fc2f9d636751 644
yihui 1:fc2f9d636751 645 memset(&hvx_params, 0, sizeof(hvx_params));
yihui 1:fc2f9d636751 646
yihui 1:fc2f9d636751 647 hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
yihui 1:fc2f9d636751 648 hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
yihui 1:fc2f9d636751 649 hvx_params.offset = 0;
yihui 1:fc2f9d636751 650 hvx_params.p_len = &index;
yihui 1:fc2f9d636751 651 hvx_params.p_data = m_notif_buffer;
yihui 1:fc2f9d636751 652
yihui 1:fc2f9d636751 653 return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
yihui 1:fc2f9d636751 654 }