conn_mw_ble_gatts.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. /**
  2. * Copyright (c) 2014 - 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_gatts_conn.h"
  41. #include "conn_mw_ble_gatts.h"
  42. #include "ble_serialization.h"
  43. uint32_t conn_mw_ble_gatts_service_add(uint8_t const * const p_rx_buf,
  44. uint32_t rx_buf_len,
  45. uint8_t * const p_tx_buf,
  46. uint32_t * const p_tx_buf_len)
  47. {
  48. SER_ASSERT_NOT_NULL(p_rx_buf);
  49. SER_ASSERT_NOT_NULL(p_tx_buf);
  50. SER_ASSERT_NOT_NULL(p_tx_buf_len);
  51. uint8_t type;
  52. ble_uuid_t uuid = {0};
  53. ble_uuid_t * p_uuid = &uuid;
  54. uint16_t handle;
  55. uint16_t * p_handle = &handle;
  56. uint32_t err_code = NRF_SUCCESS;
  57. uint32_t sd_err_code;
  58. err_code = ble_gatts_service_add_req_dec(p_rx_buf, rx_buf_len, &type, &p_uuid, &p_handle);
  59. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  60. sd_err_code = sd_ble_gatts_service_add(type, p_uuid, p_handle);
  61. err_code = ble_gatts_service_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle);
  62. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  63. return err_code;
  64. }
  65. uint32_t conn_mw_ble_gatts_characteristic_add(uint8_t const * const p_rx_buf,
  66. uint32_t rx_buf_len,
  67. uint8_t * const p_tx_buf,
  68. uint32_t * const p_tx_buf_len)
  69. {
  70. SER_ASSERT_NOT_NULL(p_rx_buf);
  71. SER_ASSERT_NOT_NULL(p_tx_buf);
  72. SER_ASSERT_NOT_NULL(p_tx_buf_len);
  73. uint16_t service_handle;
  74. //Preparing char_md
  75. ble_gatts_char_md_t char_md;
  76. uint8_t char_user_desc[BLE_GATTS_VAR_ATTR_LEN_MAX];
  77. ble_gatts_char_pf_t char_pf;
  78. ble_gatts_attr_md_t user_desc_md;
  79. ble_gatts_attr_md_t cccd_md;
  80. ble_gatts_attr_md_t sccd_md;
  81. char_md.char_user_desc_size = sizeof (char_user_desc);
  82. char_md.p_char_user_desc = char_user_desc;
  83. char_md.p_char_pf = &char_pf;
  84. char_md.p_user_desc_md = &user_desc_md;
  85. char_md.p_cccd_md = &cccd_md;
  86. char_md.p_sccd_md = &sccd_md;
  87. ble_gatts_char_md_t * p_char_md = &char_md;
  88. //Preparing attr_char_value
  89. ble_gatts_attr_t attr_char_value;
  90. ble_uuid_t uuid;
  91. ble_gatts_attr_md_t attr_md;
  92. uint8_t value[BLE_GATTS_VAR_ATTR_LEN_MAX];
  93. attr_char_value.p_uuid = &uuid;
  94. attr_char_value.p_attr_md = &attr_md;
  95. attr_char_value.init_len = sizeof (value);
  96. attr_char_value.p_value = value;
  97. ble_gatts_attr_t * p_attr_char_value = &attr_char_value;
  98. //Preparing handles
  99. ble_gatts_char_handles_t handles;
  100. ble_gatts_char_handles_t * p_handles = &handles;
  101. uint32_t err_code = NRF_SUCCESS;
  102. uint32_t sd_err_code;
  103. err_code = ble_gatts_characteristic_add_req_dec(p_rx_buf, rx_buf_len, &service_handle,
  104. &p_char_md, &p_attr_char_value, &p_handles);
  105. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  106. sd_err_code = sd_ble_gatts_characteristic_add(service_handle, p_char_md,
  107. p_attr_char_value, p_handles);
  108. err_code = ble_gatts_characteristic_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len,
  109. p_handles);
  110. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  111. return err_code;
  112. }
  113. uint32_t conn_mw_ble_gatts_include_add(uint8_t const * const p_rx_buf,
  114. uint32_t rx_buf_len,
  115. uint8_t * const p_tx_buf,
  116. uint32_t * const p_tx_buf_len)
  117. {
  118. SER_ASSERT_NOT_NULL(p_rx_buf);
  119. SER_ASSERT_NOT_NULL(p_tx_buf);
  120. SER_ASSERT_NOT_NULL(p_tx_buf_len);
  121. uint16_t service_handle;
  122. uint16_t inc_srvc_handle;
  123. uint16_t handle;
  124. uint16_t * p_handle = &handle;
  125. uint32_t err_code = NRF_SUCCESS;
  126. uint32_t sd_err_code;
  127. err_code = ble_gatts_include_add_req_dec(p_rx_buf, rx_buf_len, &service_handle,
  128. &inc_srvc_handle, &p_handle);
  129. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  130. sd_err_code = sd_ble_gatts_include_add(service_handle, inc_srvc_handle, p_handle);
  131. err_code = ble_gatts_include_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle);
  132. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  133. return err_code;
  134. }
  135. uint32_t conn_mw_ble_gatts_descriptor_add(uint8_t const * const p_rx_buf,
  136. uint32_t rx_buf_len,
  137. uint8_t * const p_tx_buf,
  138. uint32_t * const p_tx_buf_len)
  139. {
  140. SER_ASSERT_NOT_NULL(p_rx_buf);
  141. SER_ASSERT_NOT_NULL(p_tx_buf);
  142. SER_ASSERT_NOT_NULL(p_tx_buf_len);
  143. uint16_t char_handle;
  144. uint8_t attr_value[BLE_GATTS_VAR_ATTR_LEN_MAX];
  145. ble_uuid_t char_uuid;
  146. ble_gatts_attr_md_t metadata;
  147. ble_gatts_attr_t attr;
  148. ble_gatts_attr_t * p_attr = &attr;
  149. attr.p_uuid = &char_uuid;
  150. attr.p_attr_md = &metadata;
  151. attr.p_value = attr_value;
  152. attr.init_len = sizeof (attr_value);
  153. uint16_t handle;
  154. uint16_t * p_handle = &handle;
  155. uint32_t err_code = NRF_SUCCESS;
  156. uint32_t sd_err_code;
  157. err_code = ble_gatts_descriptor_add_req_dec(p_rx_buf, rx_buf_len, &char_handle, &p_attr,
  158. &p_handle);
  159. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  160. sd_err_code = sd_ble_gatts_descriptor_add(char_handle, p_attr, p_handle);
  161. err_code = ble_gatts_descriptor_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle);
  162. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  163. return err_code;
  164. }
  165. uint32_t conn_mw_ble_gatts_value_set(uint8_t const * const p_rx_buf,
  166. uint32_t rx_buf_len,
  167. uint8_t * const p_tx_buf,
  168. uint32_t * const p_tx_buf_len)
  169. {
  170. SER_ASSERT_NOT_NULL(p_rx_buf);
  171. SER_ASSERT_NOT_NULL(p_tx_buf);
  172. SER_ASSERT_NOT_NULL(p_tx_buf_len);
  173. uint16_t conn_handle;
  174. uint16_t handle;
  175. uint8_t attr_val_table[BLE_GATTS_VAR_ATTR_LEN_MAX];
  176. ble_gatts_value_t attr_val =
  177. {
  178. .len = sizeof (attr_val_table),
  179. .offset = 0,
  180. .p_value = attr_val_table
  181. };
  182. ble_gatts_value_t * p_attr_val = &attr_val;
  183. uint32_t err_code = NRF_SUCCESS;
  184. uint32_t sd_err_code;
  185. err_code = ble_gatts_value_set_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &handle, &p_attr_val);
  186. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  187. sd_err_code = sd_ble_gatts_value_set(conn_handle, handle, p_attr_val);
  188. err_code = ble_gatts_value_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_attr_val);
  189. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  190. return err_code;
  191. }
  192. uint32_t conn_mw_ble_gatts_value_get(uint8_t const * const p_rx_buf,
  193. uint32_t rx_buf_len,
  194. uint8_t * const p_tx_buf,
  195. uint32_t * const p_tx_buf_len)
  196. {
  197. SER_ASSERT_NOT_NULL(p_rx_buf);
  198. SER_ASSERT_NOT_NULL(p_tx_buf);
  199. SER_ASSERT_NOT_NULL(p_tx_buf_len);
  200. uint16_t conn_handle;
  201. uint16_t handle;
  202. uint8_t val[BLE_GATTS_VAR_ATTR_LEN_MAX];
  203. ble_gatts_value_t attr_value;
  204. ble_gatts_value_t * p_attr_value = &attr_value;
  205. attr_value.p_value = val;
  206. uint32_t err_code = NRF_SUCCESS;
  207. uint32_t sd_err_code;
  208. err_code = ble_gatts_value_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &handle, &p_attr_value);
  209. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  210. sd_err_code = sd_ble_gatts_value_get(conn_handle, handle, p_attr_value);
  211. err_code = ble_gatts_value_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_attr_value);
  212. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  213. return err_code;
  214. }
  215. uint32_t conn_mw_ble_gatts_hvx(uint8_t const * const p_rx_buf,
  216. uint32_t rx_buf_len,
  217. uint8_t * const p_tx_buf,
  218. uint32_t * const p_tx_buf_len)
  219. {
  220. SER_ASSERT_NOT_NULL(p_rx_buf);
  221. SER_ASSERT_NOT_NULL(p_tx_buf);
  222. SER_ASSERT_NOT_NULL(p_tx_buf_len);
  223. uint16_t conn_handle;
  224. uint8_t data[BLE_GATTS_VAR_ATTR_LEN_MAX];
  225. uint8_t * p_data = data;
  226. uint16_t len = sizeof data;
  227. uint16_t * p_len = &len;
  228. ble_gatts_hvx_params_t hvx_params;
  229. ble_gatts_hvx_params_t * p_hvx_params = &hvx_params;
  230. hvx_params.p_len = p_len;
  231. hvx_params.p_data = p_data;
  232. uint32_t err_code = NRF_SUCCESS;
  233. uint32_t sd_err_code;
  234. err_code = ble_gatts_hvx_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_hvx_params);
  235. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  236. sd_err_code = sd_ble_gatts_hvx(conn_handle, p_hvx_params);
  237. p_len = (p_hvx_params) ? p_hvx_params->p_len : NULL;
  238. err_code = ble_gatts_hvx_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_len);
  239. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  240. return err_code;
  241. }
  242. uint32_t conn_mw_ble_gatts_service_changed(uint8_t const * const p_rx_buf,
  243. uint32_t rx_buf_len,
  244. uint8_t * const p_tx_buf,
  245. uint32_t * const p_tx_buf_len)
  246. {
  247. SER_ASSERT_NOT_NULL(p_rx_buf);
  248. SER_ASSERT_NOT_NULL(p_tx_buf);
  249. SER_ASSERT_NOT_NULL(p_tx_buf_len);
  250. uint16_t conn_handle;
  251. uint16_t start_handle;
  252. uint16_t end_handle;
  253. uint32_t err_code = NRF_SUCCESS;
  254. uint32_t sd_err_code;
  255. err_code = ble_gatts_service_changed_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &start_handle,
  256. &end_handle);
  257. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  258. sd_err_code = sd_ble_gatts_service_changed(conn_handle, start_handle, end_handle);
  259. err_code = ble_gatts_service_changed_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
  260. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  261. return err_code;
  262. }
  263. uint32_t conn_mw_ble_gatts_rw_authorize_reply(uint8_t const * const p_rx_buf,
  264. uint32_t rx_buf_len,
  265. uint8_t * const p_tx_buf,
  266. uint32_t * const p_tx_buf_len)
  267. {
  268. SER_ASSERT_NOT_NULL(p_rx_buf);
  269. SER_ASSERT_NOT_NULL(p_tx_buf);
  270. SER_ASSERT_NOT_NULL(p_tx_buf_len);
  271. uint16_t conn_handle;
  272. uint8_t data[BLE_GATTS_VAR_ATTR_LEN_MAX];
  273. ble_gatts_rw_authorize_reply_params_t auth_params;
  274. ble_gatts_rw_authorize_reply_params_t * p_auth_params = &auth_params;
  275. auth_params.params.read.p_data = data;
  276. auth_params.params.read.len = sizeof (data);
  277. uint32_t err_code = NRF_SUCCESS;
  278. uint32_t sd_err_code;
  279. err_code = ble_gatts_rw_authorize_reply_req_dec(p_rx_buf, rx_buf_len, &conn_handle,
  280. &p_auth_params);
  281. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  282. sd_err_code = sd_ble_gatts_rw_authorize_reply(conn_handle, p_auth_params);
  283. err_code = ble_gatts_rw_authorize_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
  284. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  285. return err_code;
  286. }
  287. uint32_t conn_mw_ble_gatts_sys_attr_set(uint8_t const * const p_rx_buf,
  288. uint32_t rx_buf_len,
  289. uint8_t * const p_tx_buf,
  290. uint32_t * const p_tx_buf_len)
  291. {
  292. SER_ASSERT_NOT_NULL(p_rx_buf);
  293. SER_ASSERT_NOT_NULL(p_tx_buf);
  294. SER_ASSERT_NOT_NULL(p_tx_buf_len);
  295. uint16_t conn_handle;
  296. uint8_t sys_attr[BLE_GATTS_VAR_ATTR_LEN_MAX];
  297. uint8_t * p_sys_attr = sys_attr;
  298. uint16_t sys_attr_len = sizeof (sys_attr);
  299. uint32_t flags;
  300. uint32_t err_code = NRF_SUCCESS;
  301. uint32_t sd_err_code;
  302. err_code = ble_gatts_sys_attr_set_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_sys_attr,
  303. &sys_attr_len, &flags);
  304. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  305. sd_err_code = sd_ble_gatts_sys_attr_set(conn_handle, p_sys_attr, sys_attr_len, flags);
  306. err_code = ble_gatts_sys_attr_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
  307. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  308. return err_code;
  309. }
  310. uint32_t conn_mw_ble_gatts_sys_attr_get(uint8_t const * const p_rx_buf,
  311. uint32_t rx_buf_len,
  312. uint8_t * const p_tx_buf,
  313. uint32_t * const p_tx_buf_len)
  314. {
  315. SER_ASSERT_NOT_NULL(p_rx_buf);
  316. SER_ASSERT_NOT_NULL(p_tx_buf);
  317. SER_ASSERT_NOT_NULL(p_tx_buf_len);
  318. uint16_t conn_handle;
  319. uint8_t sys_attr[BLE_GATTS_VAR_ATTR_LEN_MAX];
  320. uint8_t * p_sys_attr = sys_attr;
  321. uint16_t sys_attr_len = sizeof (sys_attr);
  322. uint16_t * p_sys_attr_len = &sys_attr_len;
  323. uint32_t flags;
  324. uint32_t err_code = NRF_SUCCESS;
  325. uint32_t sd_err_code;
  326. err_code = ble_gatts_sys_attr_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_sys_attr,
  327. &p_sys_attr_len, &flags);
  328. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  329. sd_err_code = sd_ble_gatts_sys_attr_get(conn_handle, p_sys_attr, p_sys_attr_len, flags);
  330. err_code = ble_gatts_sys_attr_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_sys_attr,
  331. p_sys_attr_len);
  332. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  333. return err_code;
  334. }
  335. uint32_t conn_mw_ble_gatts_attr_get(uint8_t const * const p_rx_buf,
  336. uint32_t rx_buf_len,
  337. uint8_t * const p_tx_buf,
  338. uint32_t * const p_tx_buf_len)
  339. {
  340. SER_ASSERT_NOT_NULL(p_rx_buf);
  341. SER_ASSERT_NOT_NULL(p_tx_buf);
  342. SER_ASSERT_NOT_NULL(p_tx_buf_len);
  343. uint16_t handle;
  344. ble_gatts_attr_md_t md;
  345. ble_gatts_attr_md_t * p_md = &md;
  346. ble_uuid_t uuid;
  347. ble_uuid_t * p_uuid = &uuid;
  348. uint32_t err_code = NRF_SUCCESS;
  349. uint32_t sd_err_code;
  350. err_code = ble_gatts_attr_get_req_dec(p_rx_buf, rx_buf_len, &handle, &p_uuid, &p_md);
  351. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  352. sd_err_code = sd_ble_gatts_attr_get(handle, p_uuid, p_md);
  353. err_code = ble_gatts_attr_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_uuid, p_md);
  354. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  355. return err_code;
  356. }
  357. uint32_t conn_mw_ble_gatts_initial_user_handle_get(uint8_t const * const p_rx_buf,
  358. uint32_t rx_buf_len,
  359. uint8_t * const p_tx_buf,
  360. uint32_t * const p_tx_buf_len)
  361. {
  362. SER_ASSERT_NOT_NULL(p_rx_buf);
  363. SER_ASSERT_NOT_NULL(p_tx_buf);
  364. SER_ASSERT_NOT_NULL(p_tx_buf_len);
  365. uint16_t handle;
  366. uint16_t * p_handle = &handle;
  367. uint32_t err_code = NRF_SUCCESS;
  368. uint32_t sd_err_code;
  369. err_code = ble_gatts_initial_user_handle_get_req_dec(p_rx_buf, rx_buf_len, &p_handle);
  370. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  371. sd_err_code = sd_ble_gatts_initial_user_handle_get(p_handle);
  372. err_code = ble_gatts_initial_user_handle_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle);
  373. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  374. return err_code;
  375. }
  376. uint32_t conn_mw_ble_gatts_exchange_mtu_reply(uint8_t const * const p_rx_buf,
  377. uint32_t rx_buf_len,
  378. uint8_t * const p_tx_buf,
  379. uint32_t * const p_tx_buf_len)
  380. {
  381. SER_ASSERT_NOT_NULL(p_rx_buf);
  382. SER_ASSERT_NOT_NULL(p_tx_buf);
  383. SER_ASSERT_NOT_NULL(p_tx_buf_len);
  384. uint16_t conn_handle;
  385. uint16_t * p_conn_handle = &conn_handle;
  386. uint16_t server_rx_mtu;
  387. uint16_t * p_server_rx_mtu = &server_rx_mtu;
  388. uint32_t err_code = NRF_SUCCESS;
  389. uint32_t sd_err_code;
  390. err_code = ble_gatts_exchange_mtu_reply_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, p_server_rx_mtu);
  391. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  392. sd_err_code = sd_ble_gatts_exchange_mtu_reply(conn_handle, server_rx_mtu);
  393. err_code = ble_gatts_exchange_mtu_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
  394. SER_ASSERT(err_code == NRF_SUCCESS, err_code);
  395. return err_code;
  396. }