Patched version of nrf51822 FOTA compatible driver, with GPTIO disabled, as it clashed with the mbed definitions...

Fork of nRF51822 by Nordic Semiconductor

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ble_dfu.c Source File

ble_dfu.c

00001 /* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
00002  *
00003  * The information contained herein is property of Nordic Semiconductor ASA.
00004  * Terms and conditions of usage are described in detail in NORDIC
00005  * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
00006  *
00007  * Licensees are granted free, non-transferable use of the information. NO
00008  * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
00009  * the file.
00010  *
00011  */
00012 
00013 #include "ble_dfu.h "
00014 #include "nrf_error.h"
00015 #include "ble_types.h"
00016 #include "ble_gatts.h"
00017 #include "app_util.h "
00018 #include "ble_srv_common.h "
00019 #include "nordic_common.h"
00020 #include <stdint.h>
00021 #include <string.h>
00022 #include <stddef.h>
00023 
00024 #define MAX_DFU_PKT_LEN         20                                              /**< Maximum length (in bytes) of the DFU Packet characteristic. */
00025 #define PKT_START_DFU_PARAM_LEN 2                                               /**< Length (in bytes) of the parameters for Packet Start DFU Request. */
00026 #define PKT_INIT_DFU_PARAM_LEN  2                                               /**< Length (in bytes) of the parameters for Packet Init DFU Request. */
00027 #define PKT_RCPT_NOTIF_REQ_LEN  3                                               /**< Length (in bytes) of the Packet Receipt Notification Request. */
00028 #define MAX_PKTS_RCPT_NOTIF_LEN 6                                               /**< Maximum length (in bytes) of the Packets Receipt Notification. */
00029 #define MAX_RESPONSE_LEN        7                                               /**< Maximum length (in bytes) of the response to a Control Point command. */
00030 #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. */
00031 
00032 enum
00033 {
00034     OP_CODE_START_DFU          = 1,                                             /**< Value of the Op code field for 'Start DFU' command.*/
00035     OP_CODE_RECEIVE_INIT       = 2,                                             /**< Value of the Op code field for 'Initialize DFU parameters' command.*/
00036     OP_CODE_RECEIVE_FW         = 3,                                             /**< Value of the Op code field for 'Receive firmware image' command.*/
00037     OP_CODE_VALIDATE           = 4,                                             /**< Value of the Op code field for 'Validate firmware' command.*/
00038     OP_CODE_ACTIVATE_N_RESET   = 5,                                             /**< Value of the Op code field for 'Activate & Reset' command.*/
00039     OP_CODE_SYS_RESET          = 6,                                             /**< Value of the Op code field for 'Reset System' command.*/
00040     OP_CODE_IMAGE_SIZE_REQ     = 7,                                             /**< Value of the Op code field for 'Report received image size' command.*/
00041     OP_CODE_PKT_RCPT_NOTIF_REQ = 8,                                             /**< Value of the Op code field for 'Request packet receipt notification.*/
00042     OP_CODE_RESPONSE           = 16,                                            /**< Value of the Op code field for 'Response.*/
00043     OP_CODE_PKT_RCPT_NOTIF     = 17                                             /**< Value of the Op code field for 'Packets Receipt Notification'.*/
00044 };
00045 
00046 static bool     m_is_dfu_service_initialized = false;                           /**< Variable to check if the DFU service was initialized by the application.*/
00047 static uint8_t  m_notif_buffer[MAX_NOTIF_BUFFER_LEN];                           /**< Buffer used for sending notifications to peer. */
00048 
00049 /**@brief       Function for adding DFU Packet characteristic to the BLE Stack.
00050  *
00051  * @param[in]   p_dfu DFU Service structure.
00052  *
00053  * @return      NRF_SUCCESS on success. Otherwise an error code.
00054  */
00055 static uint32_t dfu_pkt_char_add(ble_dfu_t * const p_dfu)
00056 {
00057     ble_gatts_char_md_t char_md;
00058     ble_gatts_attr_t    attr_char_value;
00059     ble_uuid_t          char_uuid;
00060     ble_gatts_attr_md_t attr_md;
00061 
00062     memset(&char_md, 0, sizeof(char_md));
00063 
00064     char_md.char_props.write_wo_resp = 1;
00065     char_md.p_char_user_desc         = NULL;
00066     char_md.p_char_pf                = NULL;
00067     char_md.p_user_desc_md           = NULL;
00068     char_md.p_cccd_md                = NULL;
00069     char_md.p_sccd_md                = NULL;
00070 
00071     char_uuid.type = p_dfu->uuid_type;
00072     char_uuid.uuid = BLE_DFU_PKT_CHAR_UUID;
00073 
00074     memset(&attr_md, 0, sizeof(attr_md));
00075 
00076     BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm);
00077     BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
00078 
00079     attr_md.vloc    = BLE_GATTS_VLOC_STACK;
00080     attr_md.rd_auth = 0;
00081     attr_md.wr_auth = 0;
00082     attr_md.vlen    = 1;
00083 
00084     memset(&attr_char_value, 0, sizeof(attr_char_value));
00085 
00086     attr_char_value.p_uuid    = &char_uuid;
00087     attr_char_value.p_attr_md = &attr_md;
00088     attr_char_value.init_len  = 0;
00089     attr_char_value.init_offs = 0;
00090     attr_char_value.max_len   = MAX_DFU_PKT_LEN;
00091     attr_char_value.p_value   = NULL;
00092 
00093     return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
00094                                            &char_md,
00095                                            &attr_char_value,
00096                                            &p_dfu->dfu_pkt_handles);
00097 }
00098 
00099 
00100 /**@brief       Function for adding DFU Revision characteristic to the BLE Stack.
00101  *
00102  * @param[in]   p_dfu DFU Service structure.
00103  *
00104  * @return      NRF_SUCCESS on success. Otherwise an error code.
00105  */
00106 static uint32_t dfu_rev_char_add(ble_dfu_t * const p_dfu, ble_dfu_init_t const * const p_dfu_init)
00107 {
00108     ble_gatts_char_md_t char_md;
00109     ble_gatts_attr_t    attr_char_value;
00110     ble_uuid_t          char_uuid;
00111     ble_gatts_attr_md_t attr_md;
00112 
00113     memset(&char_md, 0, sizeof(char_md));
00114 
00115     char_md.char_props.read          = 1;
00116     char_md.p_char_user_desc         = NULL;
00117     char_md.p_char_pf                = NULL;
00118     char_md.p_user_desc_md           = NULL;
00119     char_md.p_cccd_md                = NULL;
00120     char_md.p_sccd_md                = NULL;
00121 
00122     char_uuid.type = p_dfu->uuid_type;
00123     char_uuid.uuid = BLE_DFU_REV_CHAR_UUID;
00124 
00125     memset(&attr_md, 0, sizeof(attr_md));
00126 
00127     BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
00128     BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
00129 
00130     attr_md.vloc    = BLE_GATTS_VLOC_STACK;
00131     attr_md.rd_auth = 0;
00132     attr_md.wr_auth = 0;
00133     attr_md.vlen    = 1;
00134 
00135     memset(&attr_char_value, 0, sizeof(attr_char_value));
00136 
00137     attr_char_value.p_uuid    = &char_uuid;
00138     attr_char_value.p_attr_md = &attr_md;
00139     attr_char_value.init_len  = sizeof(uint16_t);
00140     attr_char_value.init_offs = 0;
00141     attr_char_value.max_len   = sizeof(uint16_t);
00142     attr_char_value.p_value   = (uint8_t *)&p_dfu_init->revision;
00143 
00144     return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
00145                                            &char_md,
00146                                            &attr_char_value,
00147                                            &p_dfu->dfu_rev_handles);
00148 }
00149 
00150 
00151 /**@brief       Function for adding DFU Control Point characteristic to the BLE Stack.
00152  *
00153  * @param[in]   p_dfu DFU Service structure.
00154  *
00155  * @return      NRF_SUCCESS on success. Otherwise an error code.
00156  */
00157 static uint32_t dfu_ctrl_pt_add(ble_dfu_t * const p_dfu)
00158 {
00159     ble_gatts_char_md_t char_md;
00160     ble_gatts_attr_t    attr_char_value;
00161     ble_uuid_t          char_uuid;
00162     ble_gatts_attr_md_t attr_md;
00163 
00164     memset(&char_md, 0, sizeof(char_md));
00165 
00166     char_md.char_props.write  = 1;
00167     char_md.char_props.notify = 1;
00168     char_md.p_char_user_desc  = NULL;
00169     char_md.p_char_pf         = NULL;
00170     char_md.p_user_desc_md    = NULL;
00171     char_md.p_cccd_md         = NULL;
00172     char_md.p_sccd_md         = NULL;
00173 
00174     char_uuid.type = p_dfu->uuid_type;
00175     char_uuid.uuid = BLE_DFU_CTRL_PT_UUID;
00176 
00177     memset(&attr_md, 0, sizeof(attr_md));
00178 
00179     BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm);
00180     BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
00181 
00182     attr_md.vloc    = BLE_GATTS_VLOC_STACK;
00183     attr_md.rd_auth = 0;
00184     attr_md.wr_auth = 1;
00185     attr_md.vlen    = 1;
00186 
00187     memset(&attr_char_value, 0, sizeof(attr_char_value));
00188 
00189     attr_char_value.p_uuid    = &char_uuid;
00190     attr_char_value.p_attr_md = &attr_md;
00191     attr_char_value.init_len  = 0;
00192     attr_char_value.init_offs = 0;
00193     attr_char_value.max_len   = BLE_L2CAP_MTU_DEF;
00194     attr_char_value.p_value   = NULL;
00195 
00196     return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
00197                                            &char_md,
00198                                            &attr_char_value,
00199                                            &p_dfu->dfu_ctrl_pt_handles);
00200 }
00201 
00202 
00203 /**@brief     Function for handling the @ref BLE_GAP_EVT_CONNECTED event from the S110 SoftDevice.
00204  *
00205  * @param[in] p_dfu     DFU Service Structure.
00206  * @param[in] p_ble_evt Pointer to the event received from BLE stack.
00207  */
00208 static void on_connect(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
00209 {
00210     p_dfu->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
00211 }
00212 
00213 
00214 /**@brief     Function for checking if the CCCD of DFU Control point is configured for Notification.
00215  *
00216  * @details   This function checks if the CCCD of DFU Control Point characteristic is configured
00217  *            for Notification by the DFU Controller.
00218  *
00219  * @param[in] p_dfu DFU Service structure.
00220  *
00221  * @return    True if the CCCD of DFU Control Point characteristic is configured for Notification.
00222  *            False otherwise.
00223  */
00224 static bool is_cccd_configured(ble_dfu_t * p_dfu)
00225 {
00226     // Check if the CCCDs are configured.
00227     uint16_t cccd_len = BLE_CCCD_VALUE_LEN;
00228     uint8_t  cccd_val_buf[BLE_CCCD_VALUE_LEN];
00229 
00230     // Check the CCCD Value of DFU Control Point.
00231     uint32_t err_code = sd_ble_gatts_value_get(p_dfu->dfu_ctrl_pt_handles.cccd_handle,
00232                                                0,
00233                                                &cccd_len,
00234                                                cccd_val_buf);
00235     if (err_code != NRF_SUCCESS)
00236     {
00237         if (p_dfu->error_handler != NULL)
00238         {
00239             p_dfu->error_handler(err_code);
00240         }
00241         return false;
00242     }
00243 
00244     return ble_srv_is_notification_enabled(cccd_val_buf);
00245 }
00246 
00247 
00248 /**@brief     Function for handling a Write event on the Control Point characteristic.
00249  *
00250  * @param[in] p_dfu             DFU Service Structure.
00251  * @param[in] p_ble_write_evt   Pointer to the write event received from BLE stack.
00252  *
00253  * @return    NRF_SUCCESS on successful processing of control point write. Otherwise an error code.
00254  */
00255 static uint32_t on_ctrl_pt_write(ble_dfu_t * p_dfu, ble_gatts_evt_write_t * p_ble_write_evt)
00256 {
00257     ble_gatts_rw_authorize_reply_params_t write_authorize_reply;
00258 
00259     write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
00260 
00261     if (!is_cccd_configured(p_dfu))
00262     {
00263         // Send an error response to the peer indicating that the CCCD is improperly configured.
00264         write_authorize_reply.params.write.gatt_status =
00265             BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR;
00266 
00267         return (sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &write_authorize_reply));
00268 
00269     }
00270     else
00271     {
00272         uint32_t err_code;
00273 
00274         write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
00275 
00276         err_code = (sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &write_authorize_reply));
00277 
00278         if (err_code != NRF_SUCCESS)
00279         {
00280             return err_code;
00281         }
00282     }
00283 
00284     ble_dfu_evt_t ble_dfu_evt;
00285 
00286     switch (p_ble_write_evt->data[0])
00287     {
00288         case OP_CODE_START_DFU:
00289             ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_START;
00290 
00291             if (p_ble_write_evt->len < PKT_START_DFU_PARAM_LEN)
00292             {
00293                 return ble_dfu_response_send(p_dfu,
00294                                              (ble_dfu_procedure_t) p_ble_write_evt->data[0],
00295                                              BLE_DFU_RESP_VAL_OPER_FAILED);
00296             }
00297 
00298             ble_dfu_evt.evt.ble_dfu_pkt_write.len    = 1;
00299             ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = &(p_ble_write_evt->data[1]);
00300 
00301             p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
00302             break;
00303 
00304         case OP_CODE_RECEIVE_INIT:
00305             ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_RECEIVE_INIT_DATA;
00306 
00307             if (p_ble_write_evt->len < PKT_INIT_DFU_PARAM_LEN)
00308             {
00309                 return ble_dfu_response_send(p_dfu,
00310                                              (ble_dfu_procedure_t) p_ble_write_evt->data[0],
00311                                              BLE_DFU_RESP_VAL_OPER_FAILED);
00312             }
00313             
00314             ble_dfu_evt.evt.ble_dfu_pkt_write.len    = 1;
00315             ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = &(p_ble_write_evt->data[1]);
00316 
00317             p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
00318             break;
00319 
00320         case OP_CODE_RECEIVE_FW:
00321             ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_RECEIVE_APP_DATA;
00322 
00323             p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
00324             break;
00325 
00326         case OP_CODE_VALIDATE:
00327             ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_VALIDATE;
00328 
00329             p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
00330             break;
00331 
00332         case OP_CODE_ACTIVATE_N_RESET:
00333             ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_ACTIVATE_N_RESET;
00334 
00335             p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
00336             break;
00337 
00338         case OP_CODE_SYS_RESET:
00339             ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_SYS_RESET;
00340 
00341             p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
00342             break;
00343 
00344         case OP_CODE_PKT_RCPT_NOTIF_REQ:
00345             if (p_ble_write_evt->len < PKT_RCPT_NOTIF_REQ_LEN)
00346             {
00347                 return (ble_dfu_response_send(p_dfu,
00348                                               BLE_DFU_PKT_RCPT_REQ_PROCEDURE,
00349                                               BLE_DFU_RESP_VAL_NOT_SUPPORTED));
00350             }
00351 
00352             ble_dfu_evt.evt.pkt_rcpt_notif_req.num_of_pkts =
00353                 uint16_decode(&(p_ble_write_evt->data[1]));
00354 
00355             if (ble_dfu_evt.evt.pkt_rcpt_notif_req.num_of_pkts == 0)
00356             {
00357                 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PKT_RCPT_NOTIF_DISABLED;
00358             }
00359             else
00360             {
00361                 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PKT_RCPT_NOTIF_ENABLED;
00362             }
00363 
00364             p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
00365 
00366             break;
00367 
00368         case OP_CODE_IMAGE_SIZE_REQ:
00369             ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_BYTES_RECEIVED_SEND;
00370 
00371             p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
00372             break;
00373 
00374         default:
00375             // Unsupported op code.
00376             return ble_dfu_response_send(p_dfu,
00377                                          (ble_dfu_procedure_t) p_ble_write_evt->data[0],
00378                                          BLE_DFU_RESP_VAL_NOT_SUPPORTED);
00379     }
00380     return NRF_SUCCESS;
00381 }
00382 
00383 
00384 /**@brief     Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event from the S110
00385  *            Stack.
00386  *
00387  * @param[in] p_dfu     DFU Service Structure.
00388  * @param[in] p_ble_evt Pointer to the event received from BLE stack.
00389  */
00390 static void on_rw_auth_req(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
00391 {
00392     ble_gatts_evt_rw_authorize_request_t * p_authorize_request;
00393 
00394     p_authorize_request = &(p_ble_evt->evt.gatts_evt.params.authorize_request);
00395 
00396     if (
00397         (p_authorize_request->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
00398         &&
00399         (p_authorize_request->request.write.handle == p_dfu->dfu_ctrl_pt_handles.value_handle)
00400        )
00401     {
00402         uint32_t err_code;
00403 
00404         err_code = on_ctrl_pt_write(p_dfu, &(p_authorize_request->request.write));
00405 
00406         if (err_code != NRF_SUCCESS && p_dfu->error_handler != NULL)
00407         {
00408             p_dfu->error_handler(err_code);
00409         }
00410     }
00411 }
00412 
00413 
00414 /**@brief     Function for handling the @ref BLE_GATTS_EVT_WRITE event from the S110 SoftDevice.
00415  *
00416  * @param[in] p_dfu     DFU Service Structure.
00417  * @param[in] p_ble_evt Pointer to the event received from BLE stack.
00418  */
00419 static void on_write(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
00420 {
00421     if (p_ble_evt->evt.gatts_evt.params.write.handle == p_dfu->dfu_pkt_handles.value_handle)
00422     {
00423         // DFU Packet written
00424 
00425         ble_dfu_evt_t ble_dfu_evt;
00426 
00427         ble_dfu_evt.ble_dfu_evt_type             = BLE_DFU_PACKET_WRITE;
00428         ble_dfu_evt.evt.ble_dfu_pkt_write.len    = p_ble_evt->evt.gatts_evt.params.write.len;
00429         ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = p_ble_evt->evt.gatts_evt.params.write.data;
00430 
00431         p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
00432     }
00433 }
00434 
00435 
00436 /**@brief     Function for handling the BLE_GAP_EVT_DISCONNECTED event from the S110 SoftDevice.
00437  *
00438  * @param[in] p_dfu     DFU Service Structure.
00439  * @param[in] p_ble_evt Pointer to the event received from BLE stack.
00440  */
00441 static void on_disconnect(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
00442 {
00443     p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID;
00444 }
00445 
00446 
00447 uint32_t ble_dfu_init(ble_dfu_t * p_dfu, ble_dfu_init_t * p_dfu_init)
00448 {
00449     if ((p_dfu == NULL) || (p_dfu_init == NULL) || (p_dfu_init->evt_handler == NULL))
00450     {
00451         return NRF_ERROR_NULL;
00452     }
00453 
00454     p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID;
00455 
00456     ble_uuid_t service_uuid;
00457     uint32_t   err_code;
00458 
00459     const ble_uuid128_t base_uuid128 =
00460     {
00461         {
00462             0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15,
00463             0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00
00464         }
00465     };
00466 
00467     service_uuid.uuid = BLE_DFU_SERVICE_UUID;
00468 
00469     err_code = sd_ble_uuid_vs_add(&base_uuid128, &(service_uuid.type));
00470     if (err_code != NRF_SUCCESS)
00471     {
00472         return err_code;
00473     }
00474 
00475     err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
00476                                         &service_uuid,
00477                                         &(p_dfu->service_handle));
00478     if (err_code != NRF_SUCCESS)
00479     {
00480         return err_code;
00481     }
00482 
00483     p_dfu->uuid_type = service_uuid.type;
00484 
00485     err_code = dfu_pkt_char_add(p_dfu);
00486     if (err_code != NRF_SUCCESS)
00487     {
00488         return err_code;
00489     }
00490 
00491     err_code = dfu_ctrl_pt_add(p_dfu);
00492     if (err_code != NRF_SUCCESS)
00493     {
00494         return err_code;
00495     }
00496 
00497     err_code = dfu_rev_char_add(p_dfu, p_dfu_init);
00498     if (err_code != NRF_SUCCESS)
00499     {
00500         return err_code;
00501     }
00502 
00503     p_dfu->evt_handler = p_dfu_init->evt_handler;
00504 
00505     if (p_dfu_init->error_handler != NULL)
00506     {
00507         p_dfu->error_handler = p_dfu_init->error_handler;
00508     }
00509 
00510     m_is_dfu_service_initialized = true;
00511 
00512     return NRF_SUCCESS;
00513 }
00514 
00515 
00516 void ble_dfu_on_ble_evt(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
00517 {
00518     if ((p_dfu == NULL) || (p_ble_evt == NULL))
00519     {
00520         return;
00521     }
00522 
00523     if (p_dfu->evt_handler != NULL)
00524     {
00525         switch (p_ble_evt->header.evt_id)
00526         {
00527             case BLE_GAP_EVT_CONNECTED:
00528                 on_connect(p_dfu, p_ble_evt);
00529                 break;
00530 
00531             case BLE_GATTS_EVT_WRITE:
00532                 on_write(p_dfu, p_ble_evt);
00533                 break;
00534 
00535             case BLE_GAP_EVT_DISCONNECTED:
00536                 on_disconnect(p_dfu, p_ble_evt);
00537                 break;
00538 
00539             case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
00540                 on_rw_auth_req(p_dfu, p_ble_evt);
00541                 break;
00542 
00543             default:
00544                 // No implementation needed.
00545                 break;
00546         }
00547     }
00548 }
00549 
00550 
00551 uint32_t ble_dfu_bytes_rcvd_report(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd)
00552 {
00553     if (p_dfu == NULL)
00554     {
00555         return NRF_ERROR_NULL;
00556     }
00557 
00558     if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized)
00559     {
00560         return NRF_ERROR_INVALID_STATE;
00561     }
00562 
00563     ble_gatts_hvx_params_t hvx_params;
00564     uint16_t               index = 0;
00565 
00566     // Encode the Op Code.
00567     m_notif_buffer[index++] = OP_CODE_RESPONSE;
00568 
00569     // Encode the Reqest Op Code.
00570     m_notif_buffer[index++] = OP_CODE_IMAGE_SIZE_REQ;
00571 
00572     // Encode the Response Value.
00573     m_notif_buffer[index++] = (uint8_t)BLE_DFU_RESP_VAL_SUCCESS;
00574 
00575     index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]);
00576 
00577     memset(&hvx_params, 0, sizeof(hvx_params));
00578 
00579     hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
00580     hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
00581     hvx_params.offset = 0;
00582     hvx_params.p_len  = &index;
00583     hvx_params.p_data = m_notif_buffer;
00584 
00585     return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
00586 }
00587 
00588 
00589 uint32_t ble_dfu_pkts_rcpt_notify(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd)
00590 {
00591     if (p_dfu == NULL)
00592     {
00593         return NRF_ERROR_NULL;
00594     }
00595 
00596     if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized)
00597     {
00598         return NRF_ERROR_INVALID_STATE;
00599     }
00600 
00601     ble_gatts_hvx_params_t hvx_params;
00602     uint16_t               index = 0;
00603 
00604     m_notif_buffer[index++] = OP_CODE_PKT_RCPT_NOTIF;
00605 
00606     index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]);
00607 
00608     memset(&hvx_params, 0, sizeof(hvx_params));
00609 
00610     hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
00611     hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
00612     hvx_params.offset = 0;
00613     hvx_params.p_len  = &index;
00614     hvx_params.p_data = m_notif_buffer;
00615 
00616     return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
00617 }
00618 
00619 
00620 uint32_t ble_dfu_response_send(ble_dfu_t         * p_dfu,
00621                                ble_dfu_procedure_t dfu_proc,
00622                                ble_dfu_resp_val_t  resp_val)
00623 {
00624     if (p_dfu == NULL)
00625     {
00626         return NRF_ERROR_NULL;
00627     }
00628 
00629     if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized)
00630     {
00631         return NRF_ERROR_INVALID_STATE;
00632     }
00633 
00634     ble_gatts_hvx_params_t hvx_params;
00635     uint16_t               index = 0;
00636 
00637     m_notif_buffer[index++] = OP_CODE_RESPONSE;
00638 
00639     // Encode the Request Op code
00640     m_notif_buffer[index++] = (uint8_t)dfu_proc;
00641 
00642     // Encode the Response Value.
00643     m_notif_buffer[index++] = (uint8_t)resp_val;
00644 
00645     memset(&hvx_params, 0, sizeof(hvx_params));
00646 
00647     hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
00648     hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
00649     hvx_params.offset = 0;
00650     hvx_params.p_len  = &index;
00651     hvx_params.p_data = m_notif_buffer;
00652 
00653     return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
00654 }