Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of nRF51822 by
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 uint8_t cccd_val_buf[BLE_CCCD_VALUE_LEN]; 00228 ble_gatts_value_t gatts_value; 00229 00230 // Initialize value struct. 00231 memset(&gatts_value, 0, sizeof(gatts_value)); 00232 00233 gatts_value.len = BLE_CCCD_VALUE_LEN; 00234 gatts_value.offset = 0; 00235 gatts_value.p_value = cccd_val_buf; 00236 00237 // Check the CCCD Value of DFU Control Point. 00238 uint32_t err_code = sd_ble_gatts_value_get(p_dfu->conn_handle, 00239 p_dfu->dfu_ctrl_pt_handles.cccd_handle, 00240 &gatts_value); 00241 if (err_code != NRF_SUCCESS) 00242 { 00243 if (p_dfu->error_handler != NULL) 00244 { 00245 p_dfu->error_handler(err_code); 00246 } 00247 return false; 00248 } 00249 00250 return ble_srv_is_notification_enabled(cccd_val_buf); 00251 } 00252 00253 00254 /**@brief Function for handling a Write event on the Control Point characteristic. 00255 * 00256 * @param[in] p_dfu DFU Service Structure. 00257 * @param[in] p_ble_write_evt Pointer to the write event received from BLE stack. 00258 * 00259 * @return NRF_SUCCESS on successful processing of control point write. Otherwise an error code. 00260 */ 00261 static uint32_t on_ctrl_pt_write(ble_dfu_t * p_dfu, ble_gatts_evt_write_t * p_ble_write_evt) 00262 { 00263 ble_gatts_rw_authorize_reply_params_t write_authorize_reply; 00264 00265 write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; 00266 00267 if (!is_cccd_configured(p_dfu)) 00268 { 00269 // Send an error response to the peer indicating that the CCCD is improperly configured. 00270 write_authorize_reply.params.write.gatt_status = 00271 BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR; 00272 00273 return (sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &write_authorize_reply)); 00274 00275 } 00276 else 00277 { 00278 uint32_t err_code; 00279 00280 write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; 00281 00282 err_code = (sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &write_authorize_reply)); 00283 00284 if (err_code != NRF_SUCCESS) 00285 { 00286 return err_code; 00287 } 00288 } 00289 00290 ble_dfu_evt_t ble_dfu_evt; 00291 00292 switch (p_ble_write_evt->data[0]) 00293 { 00294 case OP_CODE_START_DFU: 00295 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_START; 00296 00297 if (p_ble_write_evt->len < PKT_START_DFU_PARAM_LEN) 00298 { 00299 return ble_dfu_response_send(p_dfu, 00300 (ble_dfu_procedure_t) p_ble_write_evt->data[0], 00301 BLE_DFU_RESP_VAL_OPER_FAILED); 00302 } 00303 00304 ble_dfu_evt.evt.ble_dfu_pkt_write.len = 1; 00305 ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = &(p_ble_write_evt->data[1]); 00306 00307 p_dfu->evt_handler(p_dfu, &ble_dfu_evt); 00308 break; 00309 00310 case OP_CODE_RECEIVE_INIT: 00311 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_RECEIVE_INIT_DATA; 00312 00313 if (p_ble_write_evt->len < PKT_INIT_DFU_PARAM_LEN) 00314 { 00315 return ble_dfu_response_send(p_dfu, 00316 (ble_dfu_procedure_t) p_ble_write_evt->data[0], 00317 BLE_DFU_RESP_VAL_OPER_FAILED); 00318 } 00319 00320 ble_dfu_evt.evt.ble_dfu_pkt_write.len = 1; 00321 ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = &(p_ble_write_evt->data[1]); 00322 00323 p_dfu->evt_handler(p_dfu, &ble_dfu_evt); 00324 break; 00325 00326 case OP_CODE_RECEIVE_FW: 00327 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_RECEIVE_APP_DATA; 00328 00329 p_dfu->evt_handler(p_dfu, &ble_dfu_evt); 00330 break; 00331 00332 case OP_CODE_VALIDATE: 00333 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_VALIDATE; 00334 00335 p_dfu->evt_handler(p_dfu, &ble_dfu_evt); 00336 break; 00337 00338 case OP_CODE_ACTIVATE_N_RESET: 00339 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_ACTIVATE_N_RESET; 00340 00341 p_dfu->evt_handler(p_dfu, &ble_dfu_evt); 00342 break; 00343 00344 case OP_CODE_SYS_RESET: 00345 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_SYS_RESET; 00346 00347 p_dfu->evt_handler(p_dfu, &ble_dfu_evt); 00348 break; 00349 00350 case OP_CODE_PKT_RCPT_NOTIF_REQ: 00351 if (p_ble_write_evt->len < PKT_RCPT_NOTIF_REQ_LEN) 00352 { 00353 return (ble_dfu_response_send(p_dfu, 00354 BLE_DFU_PKT_RCPT_REQ_PROCEDURE, 00355 BLE_DFU_RESP_VAL_NOT_SUPPORTED)); 00356 } 00357 00358 ble_dfu_evt.evt.pkt_rcpt_notif_req.num_of_pkts = 00359 uint16_decode(&(p_ble_write_evt->data[1])); 00360 00361 if (ble_dfu_evt.evt.pkt_rcpt_notif_req.num_of_pkts == 0) 00362 { 00363 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PKT_RCPT_NOTIF_DISABLED; 00364 } 00365 else 00366 { 00367 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PKT_RCPT_NOTIF_ENABLED; 00368 } 00369 00370 p_dfu->evt_handler(p_dfu, &ble_dfu_evt); 00371 00372 break; 00373 00374 case OP_CODE_IMAGE_SIZE_REQ: 00375 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_BYTES_RECEIVED_SEND; 00376 00377 p_dfu->evt_handler(p_dfu, &ble_dfu_evt); 00378 break; 00379 00380 default: 00381 // Unsupported op code. 00382 return ble_dfu_response_send(p_dfu, 00383 (ble_dfu_procedure_t) p_ble_write_evt->data[0], 00384 BLE_DFU_RESP_VAL_NOT_SUPPORTED); 00385 } 00386 return NRF_SUCCESS; 00387 } 00388 00389 00390 /**@brief Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event from the S110 00391 * Stack. 00392 * 00393 * @param[in] p_dfu DFU Service Structure. 00394 * @param[in] p_ble_evt Pointer to the event received from BLE stack. 00395 */ 00396 static void on_rw_authorize_req(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt) 00397 { 00398 ble_gatts_evt_rw_authorize_request_t * p_authorize_request; 00399 00400 p_authorize_request = &(p_ble_evt->evt.gatts_evt.params.authorize_request); 00401 00402 if ( 00403 (p_authorize_request->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) 00404 && 00405 (p_authorize_request->request.write.handle == p_dfu->dfu_ctrl_pt_handles.value_handle) 00406 && 00407 (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ) 00408 && 00409 (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) 00410 && 00411 (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL) 00412 ) 00413 { 00414 uint32_t err_code; 00415 00416 err_code = on_ctrl_pt_write(p_dfu, &(p_authorize_request->request.write)); 00417 00418 if (err_code != NRF_SUCCESS && p_dfu->error_handler != NULL) 00419 { 00420 p_dfu->error_handler(err_code); 00421 } 00422 } 00423 } 00424 00425 00426 /**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the S110 SoftDevice. 00427 * 00428 * @param[in] p_dfu DFU Service Structure. 00429 * @param[in] p_ble_evt Pointer to the event received from BLE stack. 00430 */ 00431 static void on_write(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt) 00432 { 00433 if (p_ble_evt->evt.gatts_evt.params.write.handle == p_dfu->dfu_pkt_handles.value_handle) 00434 { 00435 // DFU Packet written 00436 00437 ble_dfu_evt_t ble_dfu_evt; 00438 00439 ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PACKET_WRITE; 00440 ble_dfu_evt.evt.ble_dfu_pkt_write.len = p_ble_evt->evt.gatts_evt.params.write.len; 00441 ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = p_ble_evt->evt.gatts_evt.params.write.data; 00442 00443 p_dfu->evt_handler(p_dfu, &ble_dfu_evt); 00444 } 00445 } 00446 00447 00448 /**@brief Function for handling the BLE_GAP_EVT_DISCONNECTED event from the S110 SoftDevice. 00449 * 00450 * @param[in] p_dfu DFU Service Structure. 00451 * @param[in] p_ble_evt Pointer to the event received from BLE stack. 00452 */ 00453 static void on_disconnect(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt) 00454 { 00455 p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID; 00456 } 00457 00458 00459 uint32_t ble_dfu_init(ble_dfu_t * p_dfu, ble_dfu_init_t * p_dfu_init) 00460 { 00461 if ((p_dfu == NULL) || (p_dfu_init == NULL) || (p_dfu_init->evt_handler == NULL)) 00462 { 00463 return NRF_ERROR_NULL; 00464 } 00465 00466 p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID; 00467 00468 ble_uuid_t service_uuid; 00469 uint32_t err_code; 00470 00471 const ble_uuid128_t base_uuid128 = 00472 { 00473 { 00474 0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, 00475 0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00 00476 } 00477 }; 00478 00479 service_uuid.uuid = BLE_DFU_SERVICE_UUID; 00480 00481 err_code = sd_ble_uuid_vs_add(&base_uuid128, &(service_uuid.type)); 00482 if (err_code != NRF_SUCCESS) 00483 { 00484 return err_code; 00485 } 00486 00487 err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, 00488 &service_uuid, 00489 &(p_dfu->service_handle)); 00490 if (err_code != NRF_SUCCESS) 00491 { 00492 return err_code; 00493 } 00494 00495 p_dfu->uuid_type = service_uuid.type; 00496 00497 err_code = dfu_pkt_char_add(p_dfu); 00498 if (err_code != NRF_SUCCESS) 00499 { 00500 return err_code; 00501 } 00502 00503 err_code = dfu_ctrl_pt_add(p_dfu); 00504 if (err_code != NRF_SUCCESS) 00505 { 00506 return err_code; 00507 } 00508 00509 err_code = dfu_rev_char_add(p_dfu, p_dfu_init); 00510 if (err_code != NRF_SUCCESS) 00511 { 00512 return err_code; 00513 } 00514 00515 p_dfu->evt_handler = p_dfu_init->evt_handler; 00516 00517 if (p_dfu_init->error_handler != NULL) 00518 { 00519 p_dfu->error_handler = p_dfu_init->error_handler; 00520 } 00521 00522 m_is_dfu_service_initialized = true; 00523 00524 return NRF_SUCCESS; 00525 } 00526 00527 00528 void ble_dfu_on_ble_evt(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt) 00529 { 00530 if ((p_dfu == NULL) || (p_ble_evt == NULL)) 00531 { 00532 return; 00533 } 00534 00535 if (p_dfu->evt_handler != NULL) 00536 { 00537 switch (p_ble_evt->header.evt_id) 00538 { 00539 case BLE_GAP_EVT_CONNECTED: 00540 on_connect(p_dfu, p_ble_evt); 00541 break; 00542 00543 case BLE_GATTS_EVT_WRITE: 00544 on_write(p_dfu, p_ble_evt); 00545 break; 00546 00547 case BLE_GAP_EVT_DISCONNECTED: 00548 on_disconnect(p_dfu, p_ble_evt); 00549 break; 00550 00551 case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: 00552 on_rw_authorize_req(p_dfu, p_ble_evt); 00553 break; 00554 00555 default: 00556 // No implementation needed. 00557 break; 00558 } 00559 } 00560 } 00561 00562 00563 uint32_t ble_dfu_bytes_rcvd_report(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd) 00564 { 00565 if (p_dfu == NULL) 00566 { 00567 return NRF_ERROR_NULL; 00568 } 00569 00570 if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized) 00571 { 00572 return NRF_ERROR_INVALID_STATE; 00573 } 00574 00575 ble_gatts_hvx_params_t hvx_params; 00576 uint16_t index = 0; 00577 00578 // Encode the Op Code. 00579 m_notif_buffer[index++] = OP_CODE_RESPONSE; 00580 00581 // Encode the Reqest Op Code. 00582 m_notif_buffer[index++] = OP_CODE_IMAGE_SIZE_REQ; 00583 00584 // Encode the Response Value. 00585 m_notif_buffer[index++] = (uint8_t)BLE_DFU_RESP_VAL_SUCCESS; 00586 00587 index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]); 00588 00589 memset(&hvx_params, 0, sizeof(hvx_params)); 00590 00591 hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle; 00592 hvx_params.type = BLE_GATT_HVX_NOTIFICATION; 00593 hvx_params.offset = 0; 00594 hvx_params.p_len = &index; 00595 hvx_params.p_data = m_notif_buffer; 00596 00597 return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params); 00598 } 00599 00600 00601 uint32_t ble_dfu_pkts_rcpt_notify(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd) 00602 { 00603 if (p_dfu == NULL) 00604 { 00605 return NRF_ERROR_NULL; 00606 } 00607 00608 if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized) 00609 { 00610 return NRF_ERROR_INVALID_STATE; 00611 } 00612 00613 ble_gatts_hvx_params_t hvx_params; 00614 uint16_t index = 0; 00615 00616 m_notif_buffer[index++] = OP_CODE_PKT_RCPT_NOTIF; 00617 00618 index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]); 00619 00620 memset(&hvx_params, 0, sizeof(hvx_params)); 00621 00622 hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle; 00623 hvx_params.type = BLE_GATT_HVX_NOTIFICATION; 00624 hvx_params.offset = 0; 00625 hvx_params.p_len = &index; 00626 hvx_params.p_data = m_notif_buffer; 00627 00628 return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params); 00629 } 00630 00631 00632 uint32_t ble_dfu_response_send(ble_dfu_t * p_dfu, 00633 ble_dfu_procedure_t dfu_proc, 00634 ble_dfu_resp_val_t resp_val) 00635 { 00636 if (p_dfu == NULL) 00637 { 00638 return NRF_ERROR_NULL; 00639 } 00640 00641 if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized) 00642 { 00643 return NRF_ERROR_INVALID_STATE; 00644 } 00645 00646 ble_gatts_hvx_params_t hvx_params; 00647 uint16_t index = 0; 00648 00649 m_notif_buffer[index++] = OP_CODE_RESPONSE; 00650 00651 // Encode the Request Op code 00652 m_notif_buffer[index++] = (uint8_t)dfu_proc; 00653 00654 // Encode the Response Value. 00655 m_notif_buffer[index++] = (uint8_t)resp_val; 00656 00657 memset(&hvx_params, 0, sizeof(hvx_params)); 00658 00659 hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle; 00660 hvx_params.type = BLE_GATT_HVX_NOTIFICATION; 00661 hvx_params.offset = 0; 00662 hvx_params.p_len = &index; 00663 hvx_params.p_data = m_notif_buffer; 00664 00665 return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params); 00666 }
Generated on Tue Jul 12 2022 19:22:46 by
