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 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 }
Generated on Tue Jul 12 2022 16:21:02 by
