Patched version of nrf51822 FOTA compatible driver, with GPTIO disabled, as it clashed with the mbed definitions...
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 17:56:12 by 1.7.2