ble_srv_common.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /**
  2. * Copyright (c) 2012 - 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. /* Attention!
  41. * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
  42. * qualification listings, this section of source code must not be modified.
  43. */
  44. #include "ble_srv_common.h"
  45. #include <string.h>
  46. #include "nordic_common.h"
  47. #include "app_error.h"
  48. #include "ble.h"
  49. bool ble_srv_is_notification_enabled(uint8_t const * p_encoded_data)
  50. {
  51. uint16_t cccd_value = uint16_decode(p_encoded_data);
  52. return ((cccd_value & BLE_GATT_HVX_NOTIFICATION) != 0);
  53. }
  54. bool ble_srv_is_indication_enabled(uint8_t const * p_encoded_data)
  55. {
  56. uint16_t cccd_value = uint16_decode(p_encoded_data);
  57. return ((cccd_value & BLE_GATT_HVX_INDICATION) != 0);
  58. }
  59. uint8_t ble_srv_report_ref_encode(uint8_t * p_encoded_buffer,
  60. const ble_srv_report_ref_t * p_report_ref)
  61. {
  62. uint8_t len = 0;
  63. p_encoded_buffer[len++] = p_report_ref->report_id;
  64. p_encoded_buffer[len++] = p_report_ref->report_type;
  65. APP_ERROR_CHECK_BOOL(len == BLE_SRV_ENCODED_REPORT_REF_LEN);
  66. return len;
  67. }
  68. void ble_srv_ascii_to_utf8(ble_srv_utf8_str_t * p_utf8, char * p_ascii)
  69. {
  70. p_utf8->length = (uint16_t)strlen(p_ascii);
  71. p_utf8->p_str = (uint8_t *)p_ascii;
  72. }
  73. /**@brief Function for setting security requirements of a characteristic.
  74. *
  75. * @param[in] level required security level.
  76. * @param[out] p_perm Characteristic security requirements.
  77. *
  78. * @return encoded security level and security mode.
  79. */
  80. static inline void set_security_req(security_req_t level, ble_gap_conn_sec_mode_t * p_perm)
  81. {
  82. BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(p_perm);
  83. switch (level)
  84. {
  85. case SEC_NO_ACCESS:
  86. BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(p_perm);
  87. break;
  88. case SEC_OPEN:
  89. BLE_GAP_CONN_SEC_MODE_SET_OPEN(p_perm);
  90. break;
  91. case SEC_JUST_WORKS:
  92. BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(p_perm);
  93. break;
  94. case SEC_MITM:
  95. BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(p_perm);
  96. break;
  97. case SEC_SIGNED:
  98. BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(p_perm);
  99. break;
  100. case SEC_SIGNED_MITM:
  101. BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(p_perm);
  102. break;
  103. }
  104. return;
  105. }
  106. uint32_t characteristic_add(uint16_t service_handle,
  107. ble_add_char_params_t * p_char_props,
  108. ble_gatts_char_handles_t * p_char_handle)
  109. {
  110. ble_gatts_char_md_t char_md;
  111. ble_gatts_attr_t attr_char_value;
  112. ble_uuid_t char_uuid;
  113. ble_gatts_attr_md_t attr_md;
  114. ble_gatts_attr_md_t user_descr_attr_md;
  115. ble_gatts_attr_md_t cccd_md;
  116. if (p_char_props->uuid_type == 0)
  117. {
  118. char_uuid.type = BLE_UUID_TYPE_BLE;
  119. }
  120. else
  121. {
  122. char_uuid.type = p_char_props->uuid_type;
  123. }
  124. char_uuid.uuid = p_char_props->uuid;
  125. memset(&attr_md, 0, sizeof(ble_gatts_attr_md_t));
  126. set_security_req(p_char_props->read_access, &attr_md.read_perm);
  127. set_security_req(p_char_props->write_access, & attr_md.write_perm);
  128. attr_md.rd_auth = (p_char_props->is_defered_read ? 1 : 0);
  129. attr_md.wr_auth = (p_char_props->is_defered_write ? 1 : 0);
  130. attr_md.vlen = (p_char_props->is_var_len ? 1 : 0);
  131. attr_md.vloc = (p_char_props->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK);
  132. memset(&char_md, 0, sizeof(ble_gatts_char_md_t));
  133. if ((p_char_props->char_props.notify == 1)||(p_char_props->char_props.indicate == 1))
  134. {
  135. memset(&cccd_md, 0, sizeof(cccd_md));
  136. set_security_req(p_char_props->cccd_write_access, &cccd_md.write_perm);
  137. BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
  138. cccd_md.vloc = BLE_GATTS_VLOC_STACK;
  139. char_md.p_cccd_md = &cccd_md;
  140. }
  141. char_md.char_props = p_char_props->char_props;
  142. char_md.char_ext_props = p_char_props->char_ext_props;
  143. memset(&attr_char_value, 0, sizeof(ble_gatts_attr_t));
  144. attr_char_value.p_uuid = &char_uuid;
  145. attr_char_value.p_attr_md = &attr_md;
  146. attr_char_value.max_len = p_char_props->max_len;
  147. if (p_char_props->p_init_value != NULL)
  148. {
  149. attr_char_value.init_len = p_char_props->init_len;
  150. attr_char_value.p_value = p_char_props->p_init_value;
  151. }
  152. if (p_char_props->p_user_descr != NULL)
  153. {
  154. memset(&user_descr_attr_md, 0, sizeof(ble_gatts_attr_md_t));
  155. char_md.char_user_desc_max_size = p_char_props->p_user_descr->max_size;
  156. char_md.char_user_desc_size = p_char_props->p_user_descr->size;
  157. char_md.p_char_user_desc = p_char_props->p_user_descr->p_char_user_desc;
  158. char_md.p_user_desc_md = &user_descr_attr_md;
  159. set_security_req(p_char_props->p_user_descr->read_access, &user_descr_attr_md.read_perm);
  160. set_security_req(p_char_props->p_user_descr->write_access, &user_descr_attr_md.write_perm);
  161. user_descr_attr_md.rd_auth = (p_char_props->p_user_descr->is_defered_read ? 1 : 0);
  162. user_descr_attr_md.wr_auth = (p_char_props->p_user_descr->is_defered_write ? 1 : 0);
  163. user_descr_attr_md.vlen = (p_char_props->p_user_descr->is_var_len ? 1 : 0);
  164. user_descr_attr_md.vloc = (p_char_props->p_user_descr->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK);
  165. }
  166. if (p_char_props->p_presentation_format != NULL)
  167. {
  168. char_md.p_char_pf = p_char_props->p_presentation_format;
  169. }
  170. return sd_ble_gatts_characteristic_add(service_handle,
  171. &char_md,
  172. &attr_char_value,
  173. p_char_handle);
  174. }
  175. uint32_t descriptor_add(uint16_t char_handle,
  176. ble_add_descr_params_t * p_descr_props,
  177. uint16_t * p_descr_handle)
  178. {
  179. ble_gatts_attr_t descr_params;
  180. ble_uuid_t desc_uuid;
  181. ble_gatts_attr_md_t attr_md;
  182. memset(&descr_params, 0, sizeof(descr_params));
  183. if (p_descr_props->uuid_type == 0)
  184. {
  185. desc_uuid.type = BLE_UUID_TYPE_BLE;
  186. }
  187. else
  188. {
  189. desc_uuid.type = p_descr_props->uuid_type;
  190. }
  191. desc_uuid.uuid = p_descr_props->uuid;
  192. descr_params.p_uuid = &desc_uuid;
  193. set_security_req(p_descr_props->read_access, &attr_md.read_perm);
  194. set_security_req(p_descr_props->write_access,&attr_md.write_perm);
  195. attr_md.rd_auth = (p_descr_props->is_defered_read ? 1 : 0);
  196. attr_md.wr_auth = (p_descr_props->is_defered_write ? 1 : 0);
  197. attr_md.vlen = (p_descr_props->is_var_len ? 1 : 0);
  198. attr_md.vloc = (p_descr_props->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK);
  199. descr_params.p_attr_md = &attr_md;
  200. descr_params.init_len = p_descr_props->init_len;
  201. descr_params.init_offs = p_descr_props->init_offs;
  202. descr_params.max_len = p_descr_props->max_len;
  203. descr_params.p_value = p_descr_props->p_value;
  204. return sd_ble_gatts_descriptor_add(char_handle, &descr_params, p_descr_handle);
  205. }