nrf_ble_bms.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. /**
  2. * Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. #include <string.h>
  41. #include "nrf_ble_bms.h"
  42. #include "ble_srv_common.h"
  43. #define NRF_LOG_MODULE_NAME ble_bms
  44. #include "nrf_log.h"
  45. NRF_LOG_MODULE_REGISTER();
  46. /*@brief Check if a returned error code is NRF_SUCCESS, and call the error handler if not.
  47. *
  48. * @param[in] err_code Error code that should be checked.
  49. * @param[in] err_handler Error handler that should be called.
  50. */
  51. static void error_check(ret_code_t err_code, ble_srv_error_handler_t err_handler)
  52. {
  53. if (err_code != NRF_SUCCESS)
  54. {
  55. err_handler(err_code);
  56. }
  57. }
  58. /**@brief Function for adding the Bond Management Control Point characteristic.
  59. *
  60. * @param[in] p_bms Bond Management Service structure.
  61. * @param[in] p_bms_init Information needed to initialize the service.
  62. *
  63. * @return NRF_SUCCESS on success, otherwise an error code returned by @ref characteristic_add.
  64. */
  65. static ret_code_t ctrlpt_char_add(nrf_ble_bms_t * p_bms, nrf_ble_bms_init_t const * p_bms_init)
  66. {
  67. ble_add_char_params_t add_char_params;
  68. memset(&add_char_params, 0, sizeof(add_char_params));
  69. add_char_params.uuid = BLE_UUID_BMS_CTRLPT;
  70. add_char_params.char_props.write = 1;
  71. add_char_params.is_defered_write = true;
  72. add_char_params.is_var_len = true;
  73. add_char_params.max_len = NRF_BLE_BMS_CTRLPT_MAX_LEN;
  74. add_char_params.read_access = SEC_NO_ACCESS;
  75. add_char_params.write_access = p_bms_init->bms_ctrlpt_sec_req;
  76. if (p_bms_init->p_qwr != NULL)
  77. {
  78. add_char_params.char_ext_props.reliable_wr = 1;
  79. }
  80. return characteristic_add(p_bms->service_handle, &add_char_params, &p_bms->ctrlpt_handles);
  81. }
  82. /**@brief Forward an authorization request to the application, if necessary.
  83. *
  84. * @param[in] p_bms Bond Management Service structure.
  85. * @param[in] p_ctrlpt Pointer to the received Control Point value.
  86. */
  87. static void ctrlpt_auth(nrf_ble_bms_t * p_bms, nrf_ble_bms_ctrlpt_t * p_ctrlpt)
  88. {
  89. nrf_ble_bms_features_t * p_feature = &p_bms->feature;
  90. p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_ALLOWED;
  91. /* Check if the authorization feature is enabled for this op code. */
  92. if ((
  93. (p_ctrlpt->op_code == NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY) &&
  94. (p_feature->delete_requesting_auth)
  95. ) ||
  96. (
  97. (p_ctrlpt->op_code == NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY) &&
  98. (p_feature->delete_all_auth)
  99. ) ||
  100. (
  101. (p_ctrlpt->op_code == NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY) &&
  102. (p_feature->delete_all_but_requesting_auth)
  103. )
  104. )
  105. {
  106. if (p_bms->evt_handler != NULL)
  107. {
  108. nrf_ble_bms_evt_t bms_evt;
  109. memset(&bms_evt, 0, sizeof(bms_evt));
  110. bms_evt.evt_type = NRF_BLE_BMS_EVT_AUTH;
  111. bms_evt.auth_code.len = p_ctrlpt->auth_code.len;
  112. memcpy(bms_evt.auth_code.code, p_ctrlpt->auth_code.code, p_ctrlpt->auth_code.len);
  113. p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_PENDING;
  114. p_bms->evt_handler(p_bms, &bms_evt);
  115. }
  116. else
  117. {
  118. p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_DENIED;
  119. }
  120. }
  121. }
  122. /**@brief Decode an incoming Control Point write.
  123. *
  124. * @param[in] p_rcvd_val Received write value.
  125. * @param[in] len Value length.
  126. * @param[out] p_ctrlpt Decoded control point structure.
  127. *
  128. * @retval NRF_ERROR_INVALID_LENGTH The supplied value length is invalid.
  129. * @retval NRF_ERROR_NOT_SUPPORTED The supplied op code is not supported.
  130. * @retval NRF_SUCCESS Operation successful.
  131. */
  132. static ret_code_t ctrlpt_decode(uint8_t const * p_rcvd_val,
  133. uint16_t len,
  134. nrf_ble_bms_ctrlpt_t * p_ctrlpt)
  135. {
  136. uint16_t pos = 0;
  137. VERIFY_TRUE(len >= NRF_BLE_BMS_CTRLPT_MIN_LEN, NRF_ERROR_INVALID_LENGTH);
  138. VERIFY_TRUE(len <= NRF_BLE_BMS_CTRLPT_MAX_LEN, NRF_ERROR_INVALID_LENGTH);
  139. p_ctrlpt->op_code = (nrf_ble_bms_op_t) p_rcvd_val[pos++];
  140. p_ctrlpt->auth_code.len = (len - pos);
  141. memcpy(p_ctrlpt->auth_code.code, &(p_rcvd_val[pos]), p_ctrlpt->auth_code.len);
  142. return NRF_SUCCESS;
  143. }
  144. /**@brief Function for performing an operation requested through the Control Point.
  145. *
  146. * @param[in] p_bms Bond Management Service structure.
  147. * @param[in] op_code Op code to execute.
  148. */
  149. static void ctrlpt_execute(nrf_ble_bms_t * p_bms, nrf_ble_bms_op_t op_code)
  150. {
  151. switch (op_code)
  152. {
  153. case NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY:
  154. /* Delete single bond */
  155. p_bms->bond_callbacks.delete_requesting(p_bms);
  156. break; // NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY
  157. case NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY:
  158. /* Delete all bonds */
  159. p_bms->bond_callbacks.delete_all(p_bms);
  160. break; // NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY
  161. case NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY:
  162. /* Delete all but current bond */
  163. p_bms->bond_callbacks.delete_all_except_requesting(p_bms);
  164. break; // NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY
  165. default:
  166. /* No implemementation needed. */
  167. break;
  168. }
  169. }
  170. /*@brief Validate an incoming Control Point write.
  171. *
  172. * @param[in] op_code Received op code.
  173. * @param[in] p_feature Supported features.
  174. *
  175. * @returns True if the op code is supported, or false.
  176. */
  177. static bool ctrlpt_validate(nrf_ble_bms_ctrlpt_t * p_ctrlpt, nrf_ble_bms_features_t * p_feature)
  178. {
  179. switch (p_ctrlpt->op_code)
  180. {
  181. case NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY:
  182. if (p_feature->delete_requesting || p_feature->delete_requesting_auth)
  183. {
  184. return true;
  185. }
  186. break;
  187. case NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY:
  188. if (p_feature->delete_all || p_feature->delete_all_auth)
  189. {
  190. return true;
  191. }
  192. break;
  193. case NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY:
  194. if (p_feature->delete_all_but_requesting || p_feature->delete_all_but_requesting_auth)
  195. {
  196. return true;
  197. }
  198. break;
  199. default:
  200. /* No implementation needed. */
  201. break;
  202. }
  203. return false;
  204. }
  205. /**@brief Function for processing a write to the Control Point.
  206. *
  207. * @param[in] p_bms Bond Management Service structure.
  208. * @param[in] p_rcvd_val Received write value.
  209. * @param[in] len Value length.
  210. * @param[out] p_ctrlpt Decoded control point structure.
  211. */
  212. static uint16_t ctrlpt_process(nrf_ble_bms_t * p_bms,
  213. uint8_t const * p_rcvd_val,
  214. uint16_t len,
  215. nrf_ble_bms_ctrlpt_t * p_ctrlpt)
  216. {
  217. ret_code_t err_code;
  218. /* Decode operation */
  219. err_code = ctrlpt_decode(p_rcvd_val, len, p_ctrlpt);
  220. if (err_code != NRF_SUCCESS)
  221. {
  222. NRF_LOG_ERROR("Control point write: Operation failed.");
  223. return NRF_BLE_BMS_OPERATION_FAILED;
  224. }
  225. /* Verify that the operation is allowed. */
  226. if (!ctrlpt_validate(p_ctrlpt, &p_bms->feature))
  227. {
  228. NRF_LOG_ERROR("Control point write: Invalid op code.");
  229. return NRF_BLE_BMS_OPCODE_NOT_SUPPORTED;
  230. }
  231. /* Request authorization */
  232. ctrlpt_auth(p_bms, p_ctrlpt);
  233. if (p_bms->auth_status != NRF_BLE_BMS_AUTH_STATUS_ALLOWED)
  234. {
  235. NRF_LOG_ERROR("Control point long write: Invalid auth.");
  236. return BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION;
  237. }
  238. return BLE_GATT_STATUS_SUCCESS;
  239. }
  240. /**@brief Function for encoding the Bond Management Feature characteristic.
  241. *
  242. * @param[in] p_bms Bond Management Service structure.
  243. * @param[out] p_encoded_feature Encoded features.
  244. *
  245. * @return Size of the encoded feature.
  246. */
  247. static uint8_t feature_encode(nrf_ble_bms_features_t const * p_feature, uint8_t * p_encoded_feature)
  248. {
  249. uint32_t data = 0;
  250. if (p_feature->delete_all_auth)
  251. {
  252. data |= NRF_BLE_BMS_ALL_BONDS_LE_AUTH_CODE;
  253. }
  254. if (p_feature->delete_all_but_requesting_auth)
  255. {
  256. data |= NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_LE_AUTH_CODE;
  257. }
  258. if (p_feature->delete_all_but_requesting)
  259. {
  260. data |= NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_LE;
  261. }
  262. if (p_feature->delete_all)
  263. {
  264. data |= NRF_BLE_BMS_ALL_BONDS_LE;
  265. }
  266. if (p_feature->delete_requesting_auth)
  267. {
  268. data |= NRF_BLE_BMS_REQUESTING_DEVICE_LE_AUTH_CODE;
  269. }
  270. if (p_feature->delete_requesting)
  271. {
  272. data |= NRF_BLE_BMS_REQUESTING_DEVICE_LE;
  273. }
  274. return (uint24_encode(data, p_encoded_feature));
  275. }
  276. /**@brief Function for adding the Bond Management Feature characteristic.
  277. *
  278. * @param[in] p_bms Bond Management Service structure.
  279. * @param[in] p_bms_init Information needed to initialize the service.
  280. *
  281. * @return NRF_SUCCESS on success, otherwise an error code returned by @ref characteristic_add.
  282. */
  283. static ret_code_t feature_char_add(nrf_ble_bms_t * p_bms, nrf_ble_bms_init_t const * p_bms_init)
  284. {
  285. uint8_t encoded_feature[NRF_BLE_BMS_FEATURE_LEN];
  286. uint8_t init_value_len;
  287. ble_add_char_params_t add_char_params;
  288. nrf_ble_bms_features_t * p_feature = &p_bms->feature;
  289. if ((p_feature->delete_all_auth) ||
  290. (p_feature->delete_all_but_requesting_auth) ||
  291. (p_feature->delete_requesting_auth))
  292. {
  293. VERIFY_PARAM_NOT_NULL(p_bms_init->evt_handler);
  294. }
  295. if ((p_feature->delete_requesting_auth) ||
  296. (p_feature->delete_requesting))
  297. {
  298. VERIFY_PARAM_NOT_NULL(p_bms_init->bond_callbacks.delete_requesting);
  299. }
  300. if ((p_feature->delete_all) ||
  301. (p_feature->delete_all_auth))
  302. {
  303. VERIFY_PARAM_NOT_NULL(p_bms_init->bond_callbacks.delete_all);
  304. }
  305. if ((p_feature->delete_all_but_requesting) ||
  306. (p_feature->delete_all_but_requesting_auth))
  307. {
  308. VERIFY_PARAM_NOT_NULL(p_bms_init->bond_callbacks.delete_all_except_requesting);
  309. }
  310. init_value_len = feature_encode(&p_bms->feature, encoded_feature);
  311. memset(&add_char_params, 0, sizeof(add_char_params));
  312. add_char_params.uuid = BLE_UUID_BMS_FEATURE;
  313. add_char_params.char_props.read = true;
  314. add_char_params.max_len = init_value_len;
  315. add_char_params.p_init_value = encoded_feature;
  316. add_char_params.init_len = init_value_len;
  317. add_char_params.read_access = p_bms_init->bms_feature_sec_req;
  318. add_char_params.write_access = SEC_NO_ACCESS;
  319. return characteristic_add(p_bms->service_handle, &add_char_params, &p_bms->feature_handles);
  320. }
  321. /**@brief Handle a write event to the Bond Management Service Control Point.
  322. *
  323. * @param[in] p_bms Bond Management Service structure.
  324. * @param[in] p_evt_write WRITE event to be handled.
  325. */
  326. static void on_ctrlpt_write(nrf_ble_bms_t * p_bms,
  327. ble_gatts_evt_write_t const * p_evt_write,
  328. ble_gatts_authorize_params_t * p_auth_params)
  329. {
  330. ret_code_t err_code;
  331. nrf_ble_bms_ctrlpt_t ctrlpt;
  332. err_code = ctrlpt_process(p_bms, p_evt_write->data, p_evt_write->len, &ctrlpt);
  333. if (err_code != NRF_SUCCESS)
  334. {
  335. p_auth_params->gatt_status = err_code;
  336. p_auth_params->update = 0;
  337. return;
  338. }
  339. p_auth_params->gatt_status = BLE_GATT_STATUS_SUCCESS;
  340. p_auth_params->update = 1;
  341. NRF_LOG_INFO("Control point write: Success");
  342. /* Execute the requested operation. */
  343. ctrlpt_execute(p_bms, ctrlpt.op_code);
  344. }
  345. /**@brief Authorize WRITE request event handler.
  346. *
  347. * @details Handles WRITE events from the BLE stack.
  348. *
  349. * @param[in] p_bms Bond Management Service structure.
  350. * @param[in] p_gatts_evt GATTS Event received from the BLE stack.
  351. *
  352. */
  353. static void on_rw_auth_req(nrf_ble_bms_t * p_bms, ble_gatts_evt_t const * p_gatts_evt)
  354. {
  355. ret_code_t err_code;
  356. ble_gatts_rw_authorize_reply_params_t auth_reply;
  357. ble_gatts_evt_rw_authorize_request_t const * p_auth_req =
  358. &p_gatts_evt->params.authorize_request;
  359. memset(&auth_reply, 0, sizeof(auth_reply));
  360. if ((p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) &&
  361. (p_auth_req->request.write.op == BLE_GATTS_OP_WRITE_REQ) &&
  362. (p_auth_req->request.write.handle == p_bms->ctrlpt_handles.value_handle))
  363. {
  364. auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
  365. on_ctrlpt_write(p_bms, &p_auth_req->request.write, &auth_reply.params.write);
  366. /* Send authorization reply */
  367. err_code = sd_ble_gatts_rw_authorize_reply(p_bms->conn_handle, &auth_reply);
  368. error_check(err_code, p_bms->error_handler);
  369. }
  370. }
  371. /**@brief Handle authorization request events from the Queued Write module.
  372. *
  373. * @param[in] p_bms Bond Management Service structure.
  374. * @param[in] p_qwr Queued Write Structure.
  375. * @param[in] p_evt Event received from the Queued Writes module.
  376. *
  377. * @retval BLE_GATT_STATUS_SUCCESS If the received event is accepted.
  378. * @retval BLE_BMS_OPCODE_OPERATION_FAILED If the received event is not relevant for any of this module's attributes.
  379. * @retval BLE_BMS_OPCODE_NOT_SUPPORTED If the received opcode is not supported.
  380. * @retval BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION If the application handler returns that the authorization code is not valid.
  381. */
  382. uint16_t on_qwr_auth_req(nrf_ble_bms_t * p_bms, nrf_ble_qwr_t * p_qwr, nrf_ble_qwr_evt_t * p_evt)
  383. {
  384. ret_code_t err_code;
  385. uint16_t len = NRF_BLE_BMS_CTRLPT_MAX_LEN;
  386. uint8_t mem_buffer[NRF_BLE_BMS_CTRLPT_MAX_LEN];
  387. nrf_ble_bms_ctrlpt_t ctrlpt;
  388. err_code = nrf_ble_qwr_value_get(p_qwr, p_evt->attr_handle, mem_buffer, &len);
  389. if (err_code != NRF_SUCCESS)
  390. {
  391. NRF_LOG_ERROR("Control point write: Operation failed.");
  392. return NRF_BLE_BMS_OPERATION_FAILED;
  393. }
  394. return ctrlpt_process(p_bms, mem_buffer, len, &ctrlpt);
  395. }
  396. /**@brief Handle execute write events to from the Queued Write module.
  397. *
  398. * @param[in] p_bms Bond Management Service structure.
  399. * @param[in] p_qwr Queued Write Structure.
  400. * @param[in] p_evt Event received from the Queued Writes module.
  401. *
  402. * @retval BLE_GATT_STATUS_SUCCESS If the received event is accepted.
  403. * @retval BLE_BMS_OPCODE_OPERATION_FAILED If the received event is not relevant for any of this module's attributes.
  404. * @retval BLE_BMS_OPCODE_NOT_SUPPORTED If the received opcode is not supported.
  405. */
  406. uint16_t on_qwr_exec_write(nrf_ble_bms_t * p_bms, nrf_ble_qwr_t * p_qwr, nrf_ble_qwr_evt_t * p_evt)
  407. {
  408. ret_code_t err_code;
  409. uint16_t len = NRF_BLE_BMS_CTRLPT_MAX_LEN;
  410. uint8_t mem_buffer[NRF_BLE_BMS_CTRLPT_MAX_LEN];
  411. nrf_ble_bms_ctrlpt_t ctrlpt;
  412. ble_gatts_value_t ctrlpt_value;
  413. ctrlpt_value.len = NRF_BLE_BMS_CTRLPT_MAX_LEN;
  414. ctrlpt_value.offset = 0;
  415. ctrlpt_value.p_value = mem_buffer;
  416. const uint16_t ctrlpt_handle = p_bms->ctrlpt_handles.value_handle;
  417. err_code = sd_ble_gatts_value_get(p_bms->conn_handle, ctrlpt_handle, &ctrlpt_value);
  418. if (err_code != NRF_SUCCESS)
  419. {
  420. NRF_LOG_ERROR("Control point write: Operation failed.");
  421. return NRF_BLE_BMS_OPERATION_FAILED;
  422. }
  423. /* Decode operation */
  424. err_code = ctrlpt_decode(ctrlpt_value.p_value, len, &ctrlpt);
  425. if (err_code != NRF_SUCCESS)
  426. {
  427. NRF_LOG_ERROR("Control point write: Operation failed.");
  428. return NRF_BLE_BMS_OPERATION_FAILED;
  429. }
  430. /* Execute the requested operation. */
  431. ctrlpt_execute(p_bms, ctrlpt.op_code);
  432. /* Reset authorization status */
  433. p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_DENIED;
  434. return BLE_GATT_STATUS_SUCCESS;
  435. }
  436. uint16_t nrf_ble_bms_on_qwr_evt(nrf_ble_bms_t * p_bms,
  437. nrf_ble_qwr_t * p_qwr,
  438. nrf_ble_qwr_evt_t * p_evt)
  439. {
  440. VERIFY_TRUE(p_bms != NULL, (NRF_BLE_QWR_REJ_REQUEST_ERR_CODE));
  441. VERIFY_TRUE(p_qwr != NULL, (NRF_BLE_QWR_REJ_REQUEST_ERR_CODE));
  442. VERIFY_TRUE(p_evt != NULL, (NRF_BLE_QWR_REJ_REQUEST_ERR_CODE));
  443. VERIFY_TRUE(p_evt->attr_handle == p_bms->ctrlpt_handles.value_handle,
  444. (NRF_BLE_QWR_REJ_REQUEST_ERR_CODE));
  445. if (p_evt->evt_type == NRF_BLE_QWR_EVT_AUTH_REQUEST)
  446. {
  447. return on_qwr_auth_req(p_bms, p_qwr, p_evt);
  448. }
  449. else if ((p_evt->evt_type == NRF_BLE_QWR_EVT_EXECUTE_WRITE) &&
  450. (p_bms->auth_status == NRF_BLE_BMS_AUTH_STATUS_ALLOWED))
  451. {
  452. return on_qwr_exec_write(p_bms, p_qwr, p_evt);
  453. }
  454. return BLE_GATT_STATUS_SUCCESS;
  455. }
  456. void nrf_ble_bms_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
  457. {
  458. VERIFY_PARAM_NOT_NULL_VOID(p_context);
  459. VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt);
  460. nrf_ble_bms_t * p_bms = (nrf_ble_bms_t *)p_context;
  461. switch (p_ble_evt->header.evt_id)
  462. {
  463. case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
  464. on_rw_auth_req(p_bms, &p_ble_evt->evt.gatts_evt);
  465. break;
  466. default:
  467. break;
  468. }
  469. }
  470. ret_code_t nrf_ble_bms_set_conn_handle(nrf_ble_bms_t * p_bms, uint16_t conn_handle)
  471. {
  472. VERIFY_PARAM_NOT_NULL(p_bms);
  473. p_bms->conn_handle = conn_handle;
  474. return NRF_SUCCESS;
  475. }
  476. ret_code_t nrf_ble_bms_init(nrf_ble_bms_t * p_bms, nrf_ble_bms_init_t * p_bms_init)
  477. {
  478. ret_code_t err_code;
  479. ble_uuid_t ble_uuid;
  480. VERIFY_PARAM_NOT_NULL(p_bms_init);
  481. VERIFY_PARAM_NOT_NULL(p_bms);
  482. // Add service
  483. BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BMS_SERVICE);
  484. p_bms->evt_handler = p_bms_init->evt_handler;
  485. p_bms->error_handler = p_bms_init->error_handler;
  486. p_bms->feature = p_bms_init->feature;
  487. p_bms->bond_callbacks = p_bms_init->bond_callbacks;
  488. p_bms->conn_handle = BLE_CONN_HANDLE_INVALID;
  489. err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
  490. &ble_uuid,
  491. &p_bms->service_handle);
  492. VERIFY_SUCCESS(err_code);
  493. err_code = feature_char_add(p_bms, p_bms_init);
  494. VERIFY_SUCCESS(err_code);
  495. err_code = ctrlpt_char_add(p_bms, p_bms_init);
  496. VERIFY_SUCCESS(err_code);
  497. if (p_bms_init->p_qwr != NULL)
  498. {
  499. return nrf_ble_qwr_attr_register(p_bms_init->p_qwr, p_bms->ctrlpt_handles.value_handle);
  500. }
  501. NRF_LOG_INFO("Init complete.");
  502. return NRF_SUCCESS;
  503. }
  504. ret_code_t nrf_ble_bms_auth_response(nrf_ble_bms_t * p_bms, bool authorize)
  505. {
  506. VERIFY_PARAM_NOT_NULL(p_bms);
  507. VERIFY_TRUE(p_bms->auth_status == NRF_BLE_BMS_AUTH_STATUS_PENDING, NRF_ERROR_INVALID_STATE);
  508. if (authorize)
  509. {
  510. p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_ALLOWED;
  511. }
  512. else
  513. {
  514. p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_DENIED;
  515. }
  516. return NRF_SUCCESS;
  517. }