ble_ots_object.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. /**
  2. * Copyright (c) 2017 - 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 "ble_ots_object.h"
  41. #include <string.h>
  42. #include "ble_srv_common.h"
  43. #include "ble_ots.h"
  44. #define BLE_OTS_WRITE_REQUEST_REJECTED 0x80
  45. #define BLE_OTS_OBJECT_NOT_SELECTED 0x81
  46. #define BLE_OTS_CONCURRENCY_LIMIT_EXCEEDED 0x82
  47. #define BLE_OTS_OBJ_NAME_ALREADY_EXISTS 0x83
  48. #define BLE_SIZE_DATE_TIME 7
  49. uint32_t ble_ots_object_refresh_current(ble_ots_object_chars_t * p_ots_object_chars)
  50. {
  51. uint32_t err_code;
  52. ble_ots_object_t * p_obj;
  53. p_obj = p_ots_object_chars->p_ots->p_current_object;
  54. if (p_obj == NULL)
  55. {
  56. // Clear all characteristics
  57. return NRF_SUCCESS;
  58. }
  59. // obtain the largest necessary buffer
  60. typedef union {
  61. uint8_t type_buf[sizeof(ble_ots_obj_type_t)+sizeof(uint8_t)];
  62. uint8_t size_buf[2*sizeof(uint32_t)];
  63. uint8_t prop_buf[sizeof(uint32_t)];
  64. } buffer_t;
  65. buffer_t buffer;
  66. ble_gatts_value_t gatts_value;
  67. memset(&gatts_value, 0, sizeof(gatts_value));
  68. // name
  69. gatts_value.len = strlen((const char *)p_obj->name) + 1;
  70. gatts_value.p_value = p_obj->name;
  71. err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
  72. p_ots_object_chars->obj_name_handles.value_handle,
  73. &gatts_value);
  74. if (err_code != NRF_SUCCESS)
  75. {
  76. return err_code;
  77. }
  78. // type
  79. if (p_obj->type.len == sizeof(uint16_t))
  80. {
  81. gatts_value.len = uint16_encode(p_obj->type.param.type16, buffer.type_buf);
  82. gatts_value.p_value = buffer.type_buf;
  83. err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
  84. p_ots_object_chars->obj_type_handles.value_handle,
  85. &gatts_value);
  86. }
  87. else
  88. {
  89. gatts_value.len = uint16_encode(p_obj->type.param.type16, buffer.type_buf);
  90. gatts_value.p_value = p_obj->type.param.type128;
  91. err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
  92. p_ots_object_chars->obj_type_handles.value_handle,
  93. &gatts_value);
  94. }
  95. if (err_code != NRF_SUCCESS)
  96. {
  97. return err_code;
  98. }
  99. gatts_value.len = uint32_encode(p_obj->current_size, &buffer.size_buf[0]);
  100. gatts_value.len += uint32_encode(p_obj->alloc_len, &buffer.size_buf[gatts_value.len]);
  101. gatts_value.p_value = &buffer.size_buf[0];
  102. err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
  103. p_ots_object_chars->obj_size_handles.value_handle,
  104. &gatts_value);
  105. if (err_code != NRF_SUCCESS)
  106. {
  107. return err_code;
  108. }
  109. gatts_value.len = uint32_encode(p_obj->properties.raw, buffer.prop_buf);
  110. gatts_value.p_value = buffer.prop_buf;
  111. err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
  112. p_ots_object_chars->obj_properties_handles.value_handle,
  113. &gatts_value);
  114. if (err_code != NRF_SUCCESS)
  115. {
  116. return err_code;
  117. }
  118. return NRF_SUCCESS;
  119. }
  120. /**@brief Function for adding the object name characteristic.
  121. *
  122. * @param[in] p_ots_object_chars Pointer the the object characteristics.
  123. * @param[in] service_handle The service handle where the characteristic should be added.
  124. * @param[in] read_access The read security level for the characteristic.
  125. * @param[in] write_access The write security level for the characteristic.
  126. *
  127. * @return NRF_SUCCESS if the characteristic was successfully added, else a return code from
  128. * characteristic_add().
  129. */
  130. static uint32_t obj_name_char_add(ble_ots_object_chars_t * const p_ots_object_chars,
  131. uint16_t service_handle,
  132. security_req_t read_access,
  133. security_req_t write_access)
  134. {
  135. ble_add_char_params_t add_char_params;
  136. memset(&add_char_params, 0, sizeof(add_char_params));
  137. add_char_params.uuid = BLE_UUID_OTS_OBJECT_NAME;
  138. add_char_params.uuid_type = BLE_UUID_TYPE_BLE;
  139. add_char_params.max_len = BLE_OTS_NAME_MAX_SIZE;
  140. add_char_params.is_var_len = 1;
  141. add_char_params.char_props.read = 1;
  142. add_char_params.read_access = read_access;
  143. add_char_params.char_props.write = 0;
  144. return characteristic_add(service_handle,
  145. &add_char_params,
  146. &p_ots_object_chars->obj_name_handles);
  147. }
  148. /**@brief Function for adding the object type characteristic.
  149. *
  150. * @param[in] p_ots_object_chars Pointer the the object characteristics.
  151. * @param[in] service_handle The service handle where the characteristic should be added.
  152. * @param[in] read_access The read security level for the characteristic.
  153. *
  154. * @return NRF_SUCCESS if the characteristic was successfully added, else a return code from
  155. * characteristic_add().
  156. */
  157. static uint32_t obj_type_char_add(ble_ots_object_chars_t * const p_ots_object_chars,
  158. uint16_t service_handle,
  159. security_req_t read_access)
  160. {
  161. ble_add_char_params_t add_char_params;
  162. memset(&add_char_params, 0, sizeof(add_char_params));
  163. add_char_params.uuid = BLE_UUID_OTS_OBJECT_TYPE;
  164. add_char_params.uuid_type = BLE_UUID_TYPE_BLE;
  165. add_char_params.max_len = sizeof(ble_ots_obj_type_t);
  166. add_char_params.is_var_len = 1;
  167. add_char_params.char_props.read = 1;
  168. add_char_params.read_access = read_access;
  169. return characteristic_add(service_handle,
  170. &add_char_params,
  171. &p_ots_object_chars->obj_type_handles);
  172. }
  173. /**@brief Function for adding the object size characteristic.
  174. *
  175. * @param[in] p_ots_object_chars Pointer the the object characteristics.
  176. * @param[in] service_handle The service handle where the characteristic should be added.
  177. * @param[in] read_access The read security level for the characteristic.
  178. *
  179. * @return NRF_SUCCESS if the characteristic was successfully added, else a return code from
  180. * characteristic_add().
  181. */
  182. static uint32_t obj_size_char_add(ble_ots_object_chars_t * const p_ots_object_chars,
  183. uint16_t service_handle,
  184. security_req_t read_access)
  185. {
  186. ble_add_char_params_t add_char_params;
  187. memset(&add_char_params, 0, sizeof(add_char_params));
  188. add_char_params.uuid = BLE_UUID_OTS_OBJECT_SIZE;
  189. add_char_params.uuid_type = BLE_UUID_TYPE_BLE;
  190. add_char_params.max_len = NRF_BLE_OTS_SIZE_CHAR_LEN;
  191. add_char_params.is_var_len = 0;
  192. add_char_params.char_props.read = 1;
  193. add_char_params.read_access = read_access;
  194. return characteristic_add(service_handle,
  195. &add_char_params,
  196. &p_ots_object_chars->obj_size_handles);
  197. }
  198. /**@brief Function for adding the object properties characteristic.
  199. *
  200. * @param[in] p_ots_object_chars Pointer the the object characteristics.
  201. * @param[in] service_handle The service handle where the characteristic should be added.
  202. * @param[in] read_access The read security level for the characteristic.
  203. * @param[in] write_access The write security level for the characteristic.
  204. *
  205. * @return NRF_SUCCESS if the characteristic was successfully added, else a return code from
  206. * characteristic_add().
  207. */
  208. static uint32_t obj_prop_char_add(ble_ots_object_chars_t * const p_ots_object_chars,
  209. uint16_t service_handle,
  210. security_req_t read_access,
  211. security_req_t write_access)
  212. {
  213. ble_add_char_params_t add_char_params;
  214. memset(&add_char_params, 0, sizeof(add_char_params));
  215. add_char_params.uuid = BLE_UUID_OTS_OBJECT_PROPERTIES;
  216. add_char_params.uuid_type = BLE_UUID_TYPE_BLE;
  217. add_char_params.max_len = sizeof(uint32_t);
  218. add_char_params.is_var_len = 0;
  219. add_char_params.char_props.read = 1;
  220. add_char_params.read_access = read_access;
  221. add_char_params.is_defered_write = 1;
  222. add_char_params.write_access = write_access;
  223. return characteristic_add(service_handle,
  224. &add_char_params,
  225. &p_ots_object_chars->obj_properties_handles);
  226. }
  227. uint32_t ble_ots_object_representation_init(ble_ots_object_chars_t * p_ots_object_chars,
  228. ble_ots_object_chars_init_t * p_ots_object_chars_init)
  229. {
  230. if (p_ots_object_chars == NULL || p_ots_object_chars_init == NULL)
  231. {
  232. return NRF_ERROR_NULL;
  233. }
  234. uint32_t err_code;
  235. p_ots_object_chars->p_ots = p_ots_object_chars_init->p_ots;
  236. err_code = obj_name_char_add(p_ots_object_chars,
  237. p_ots_object_chars_init->p_ots->service_handle,
  238. p_ots_object_chars_init->name_read_access,
  239. p_ots_object_chars_init->name_write_access);
  240. if (err_code != NRF_SUCCESS)
  241. {
  242. return err_code;
  243. }
  244. err_code = obj_type_char_add(p_ots_object_chars,
  245. p_ots_object_chars_init->p_ots->service_handle,
  246. p_ots_object_chars_init->type_read_access);
  247. if (err_code != NRF_SUCCESS)
  248. {
  249. return err_code;
  250. }
  251. err_code = obj_size_char_add(p_ots_object_chars,
  252. p_ots_object_chars_init->p_ots->service_handle,
  253. p_ots_object_chars_init->size_read_access);
  254. if (err_code != NRF_SUCCESS)
  255. {
  256. return err_code;
  257. }
  258. err_code = obj_prop_char_add(p_ots_object_chars,
  259. p_ots_object_chars_init->p_ots->service_handle,
  260. p_ots_object_chars_init->properties_read_access,
  261. p_ots_object_chars_init->properties_write_access);
  262. if (err_code != NRF_SUCCESS)
  263. {
  264. return err_code;
  265. }
  266. return ble_ots_object_refresh_current(p_ots_object_chars);
  267. }
  268. uint32_t ble_ots_object_set_name(ble_ots_object_chars_t * p_ots_object_chars,
  269. ble_ots_object_t * p_object,
  270. const char * new_name)
  271. {
  272. if (p_ots_object_chars == NULL || p_object == NULL || new_name == NULL)
  273. {
  274. return NRF_ERROR_NULL;
  275. }
  276. strncpy((char *)p_object->name, new_name, BLE_OTS_NAME_MAX_SIZE);
  277. if (p_object == p_ots_object_chars->p_ots->p_current_object)
  278. {
  279. // update characteristic
  280. uint32_t err_code;
  281. ble_gatts_value_t gatts_value;
  282. memset(&gatts_value, 0, sizeof(gatts_value));
  283. gatts_value.len = strlen((const char *)p_object->name) + 1;
  284. gatts_value.p_value = p_object->name;
  285. err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
  286. p_ots_object_chars->obj_name_handles.value_handle,
  287. &gatts_value);
  288. if (err_code != NRF_SUCCESS)
  289. {
  290. return err_code;
  291. }
  292. }
  293. return NRF_SUCCESS;
  294. }
  295. uint32_t ble_ots_object_set_type(ble_ots_object_chars_t * p_ots_object_chars,
  296. ble_ots_object_t * p_object,
  297. ble_ots_obj_type_t * p_new_type)
  298. {
  299. if (p_ots_object_chars == NULL || p_object == NULL || p_new_type == NULL)
  300. {
  301. return NRF_ERROR_NULL;
  302. }
  303. if (p_new_type->len != sizeof(p_new_type->param.type16) && p_new_type->len != sizeof(p_new_type->param.type128))
  304. {
  305. return NRF_ERROR_INVALID_PARAM;
  306. }
  307. memcpy(&p_object->type, p_new_type, sizeof(ble_ots_obj_type_t));
  308. if (p_object == p_ots_object_chars->p_ots->p_current_object)
  309. {
  310. // update characteristic
  311. uint32_t err_code;
  312. uint8_t buffer[sizeof(p_new_type->param.type16)];
  313. ble_gatts_value_t gatts_value;
  314. memset(&gatts_value, 0, sizeof(gatts_value));
  315. if (p_object->type.len == sizeof(uint16_t))
  316. {
  317. gatts_value.len = uint16_encode(p_object->type.param.type16, buffer);
  318. gatts_value.p_value = buffer;
  319. err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
  320. p_ots_object_chars->obj_type_handles.value_handle,
  321. &gatts_value);
  322. }
  323. else
  324. {
  325. gatts_value.len = uint16_encode(p_object->type.param.type16, buffer);
  326. gatts_value.p_value = p_object->type.param.type128;
  327. err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
  328. p_ots_object_chars->obj_type_handles.value_handle,
  329. &gatts_value);
  330. }
  331. if (err_code != NRF_SUCCESS)
  332. {
  333. return err_code;
  334. }
  335. }
  336. return NRF_SUCCESS;
  337. }
  338. uint32_t ble_ots_object_set_current_size(ble_ots_object_chars_t * p_ots_object_chars,
  339. ble_ots_object_t * p_object,
  340. uint32_t new_current_size)
  341. {
  342. if (p_ots_object_chars == NULL || p_object == NULL)
  343. {
  344. return NRF_ERROR_NULL;
  345. }
  346. p_object->current_size = new_current_size;
  347. if (p_object == p_ots_object_chars->p_ots->p_current_object)
  348. {
  349. // update characteristic
  350. uint32_t err_code;
  351. uint8_t buffer[NRF_BLE_OTS_SIZE_CHAR_LEN];
  352. ble_gatts_value_t gatts_value;
  353. memset(&gatts_value, 0, sizeof(gatts_value));
  354. gatts_value.len = 0;
  355. gatts_value.len += uint32_encode(p_object->current_size, &buffer[gatts_value.len]);
  356. gatts_value.len += uint32_encode(p_object->alloc_len, &buffer[gatts_value.len]);
  357. gatts_value.p_value = &buffer[0];
  358. err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
  359. p_ots_object_chars->obj_size_handles.value_handle,
  360. &gatts_value);
  361. if (err_code != NRF_SUCCESS)
  362. {
  363. return err_code;
  364. }
  365. }
  366. return NRF_SUCCESS;
  367. }
  368. /**@brief Function for handling write on object properties meta data.
  369. *
  370. * @param[in] p_ots_object_chars Pointer the the object characteristics.
  371. * @param[in] p_ble_evt Pointer to the event received from BLE stack.
  372. */
  373. static uint32_t on_obj_properties_write(ble_ots_object_chars_t * p_ots_object_chars,
  374. ble_evt_t const * p_ble_evt)
  375. {
  376. ble_gatts_rw_authorize_reply_params_t write_authorize_reply;
  377. ble_gatts_evt_write_t const * p_write_evt;
  378. p_write_evt = &p_ble_evt->evt.gatts_evt.params.authorize_request.request.write;
  379. write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
  380. uint32_t raw_prop = uint32_decode(p_write_evt->data);
  381. if ((raw_prop & 0xFFFFFF80) != 0)
  382. {
  383. write_authorize_reply.params.write.gatt_status = BLE_OTS_WRITE_REQUEST_REJECTED;
  384. }
  385. else
  386. {
  387. p_ots_object_chars->p_ots->p_current_object->properties.raw = raw_prop;
  388. write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
  389. ble_ots_evt_t ble_ots_evt;
  390. ble_ots_evt.type = BLE_OTS_EVT_OBJECT;
  391. ble_ots_evt.evt.object_evt.type = BLE_OTS_OBJECT_EVT_PROPERTIES_CHANGED;
  392. ble_ots_evt.evt.object_evt.evt.p_object = p_ots_object_chars->p_ots->p_current_object;
  393. p_ots_object_chars->p_ots->evt_handler(p_ots_object_chars->p_ots, &ble_ots_evt);
  394. }
  395. return sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle, &write_authorize_reply);
  396. }
  397. uint32_t ble_ots_object_set_properties(ble_ots_object_chars_t * p_ots_object_chars,
  398. ble_ots_object_t * p_object,
  399. ble_ots_obj_properties_t * p_new_properties)
  400. {
  401. if (p_ots_object_chars == NULL || p_object == NULL)
  402. {
  403. return NRF_ERROR_NULL;
  404. }
  405. memcpy(&p_object->properties, p_new_properties, sizeof(ble_ots_obj_properties_t));
  406. if (p_object == p_ots_object_chars->p_ots->p_current_object)
  407. {
  408. // update characteristic
  409. uint32_t err_code;
  410. uint8_t buffer[sizeof(ble_ots_obj_properties_t)];
  411. ble_gatts_value_t gatts_value;
  412. memset(&gatts_value, 0, sizeof(gatts_value));
  413. gatts_value.len = uint32_encode(p_object->properties.raw, buffer);
  414. gatts_value.p_value = buffer;
  415. err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
  416. p_ots_object_chars->obj_properties_handles.value_handle,
  417. &gatts_value);
  418. if (err_code != NRF_SUCCESS)
  419. {
  420. return err_code;
  421. }
  422. }
  423. return NRF_SUCCESS;
  424. }
  425. /**@brief Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event.
  426. *
  427. * @param[in] p_ots_object_chars Pointer the the object characteristics.
  428. * @param[in] p_ble_evt Pointer to the event received from BLE stack.
  429. */
  430. static void on_rw_auth_req(ble_ots_object_chars_t * p_ots_object_chars, ble_evt_t const * p_ble_evt)
  431. {
  432. uint32_t err_code;
  433. ble_gatts_evt_rw_authorize_request_t const * p_authorize_request;
  434. p_authorize_request = &(p_ble_evt->evt.gatts_evt.params.authorize_request);
  435. if (p_authorize_request->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
  436. {
  437. if (p_authorize_request->request.write.handle == p_ots_object_chars->obj_name_handles.value_handle)
  438. {
  439. //err_code = on_name_prepare_write(p_ots_object_chars, p_ble_evt);
  440. // if (err_code != NRF_SUCCESS)
  441. // {
  442. // p_ots_object_chars->p_ots->error_handler(err_code);
  443. // }
  444. }
  445. else
  446. if (p_authorize_request->request.write.handle == p_ots_object_chars->obj_properties_handles.value_handle)
  447. {
  448. err_code = on_obj_properties_write(p_ots_object_chars, p_ble_evt);
  449. if (err_code != NRF_SUCCESS)
  450. {
  451. p_ots_object_chars->p_ots->error_handler(err_code);
  452. }
  453. }
  454. }
  455. }
  456. void ble_ots_object_on_ble_evt(ble_ots_object_chars_t * p_ots_chars, ble_evt_t const * p_ble_evt)
  457. {
  458. if ((p_ots_chars == NULL) || (p_ble_evt == NULL))
  459. {
  460. return;
  461. }
  462. // uint32_t err_code;
  463. switch (p_ble_evt->header.evt_id)
  464. {
  465. case BLE_GAP_EVT_CONNECTED:
  466. // err_code = ble_ots_object_refresh_current(p_ots_chars);
  467. // if (err_code != NRF_SUCCESS)
  468. // {
  469. // p_ots_chars->p_ots->error_handler(err_code);
  470. // }
  471. break;
  472. case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
  473. on_rw_auth_req(p_ots_chars, p_ble_evt);
  474. break;
  475. default:
  476. // No implementation needed.
  477. break;
  478. }
  479. }