ble_lls.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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 "sdk_common.h"
  45. #if NRF_MODULE_ENABLED(BLE_LLS)
  46. #include "ble_lls.h"
  47. #include <string.h>
  48. #include "ble_hci.h"
  49. #include "ble_srv_common.h"
  50. /**@brief Function for handling the Connect event.
  51. *
  52. * @param[in] p_lls Link Loss Service structure.
  53. * @param[in] p_ble_evt Event received from the BLE stack.
  54. */
  55. static void on_connect(ble_lls_t * p_lls, ble_evt_t const * p_ble_evt)
  56. {
  57. // Link reconnected, notify application with a no_alert event
  58. ble_lls_evt_t evt;
  59. p_lls->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
  60. evt.evt_type = BLE_LLS_EVT_LINK_LOSS_ALERT;
  61. evt.params.alert_level = BLE_CHAR_ALERT_LEVEL_NO_ALERT;
  62. p_lls->evt_handler(p_lls, &evt);
  63. }
  64. /**@brief Function for handling the Disconnect event.
  65. *
  66. * @param[in] p_lls Link Loss Service structure.
  67. * @param[in] p_ble_evt Event received from the BLE stack.
  68. */
  69. static void on_disconnect(ble_lls_t * p_lls, ble_evt_t const * p_ble_evt)
  70. {
  71. uint8_t reason = p_ble_evt->evt.gap_evt.params.disconnected.reason;
  72. if (reason == BLE_HCI_CONNECTION_TIMEOUT)
  73. {
  74. // Link loss detected, notify application
  75. uint32_t err_code;
  76. ble_lls_evt_t evt;
  77. evt.evt_type = BLE_LLS_EVT_LINK_LOSS_ALERT;
  78. err_code = ble_lls_alert_level_get(p_lls, &evt.params.alert_level);
  79. if (err_code == NRF_SUCCESS)
  80. {
  81. p_lls->evt_handler(p_lls, &evt);
  82. }
  83. else
  84. {
  85. if (p_lls->error_handler != NULL)
  86. {
  87. p_lls->error_handler(err_code);
  88. }
  89. }
  90. }
  91. }
  92. /**@brief Function for handling the Authentication Status event.
  93. *
  94. * @param[in] p_lls Link Loss Service structure.
  95. * @param[in] p_ble_evt Event received from the BLE stack.
  96. */
  97. static void on_auth_status(ble_lls_t * p_lls, ble_evt_t const * p_ble_evt)
  98. {
  99. if (p_ble_evt->evt.gap_evt.params.auth_status.auth_status == BLE_GAP_SEC_STATUS_SUCCESS)
  100. {
  101. ble_lls_evt_t evt;
  102. evt.evt_type = BLE_LLS_EVT_LINK_LOSS_ALERT;
  103. evt.params.alert_level = BLE_CHAR_ALERT_LEVEL_NO_ALERT;
  104. p_lls->evt_handler(p_lls, &evt);
  105. }
  106. }
  107. void ble_lls_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
  108. {
  109. ble_lls_t * p_lls = (ble_lls_t *)p_context;
  110. if (p_lls == NULL || p_ble_evt == NULL)
  111. {
  112. return;
  113. }
  114. switch (p_ble_evt->header.evt_id)
  115. {
  116. case BLE_GAP_EVT_CONNECTED:
  117. on_connect(p_lls, p_ble_evt);
  118. break;
  119. case BLE_GAP_EVT_DISCONNECTED:
  120. on_disconnect(p_lls, p_ble_evt);
  121. break;
  122. case BLE_GAP_EVT_AUTH_STATUS:
  123. on_auth_status(p_lls, p_ble_evt);
  124. break;
  125. default:
  126. // No implementation needed.
  127. break;
  128. }
  129. }
  130. uint32_t ble_lls_init(ble_lls_t * p_lls, const ble_lls_init_t * p_lls_init)
  131. {
  132. uint32_t err_code;
  133. ble_uuid_t ble_uuid;
  134. ble_add_char_params_t add_char_params;
  135. if (p_lls == NULL || p_lls_init == NULL)
  136. {
  137. return NRF_ERROR_NULL;
  138. }
  139. if (p_lls_init->evt_handler == NULL)
  140. {
  141. return NRF_ERROR_INVALID_PARAM;
  142. }
  143. // Initialize service structure
  144. p_lls->evt_handler = p_lls_init->evt_handler;
  145. p_lls->error_handler = p_lls_init->error_handler;
  146. // Add service
  147. BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_LINK_LOSS_SERVICE);
  148. err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
  149. &ble_uuid,
  150. &p_lls->service_handle);
  151. if (err_code != NRF_SUCCESS)
  152. {
  153. return err_code;
  154. }
  155. // Add alert level characteristic
  156. memset(&add_char_params, 0, sizeof(add_char_params));
  157. add_char_params.uuid = BLE_UUID_ALERT_LEVEL_CHAR;
  158. add_char_params.max_len = sizeof(uint8_t);
  159. add_char_params.char_props.read = 1;
  160. add_char_params.char_props.write = 1;
  161. add_char_params.write_access = p_lls_init->alert_level_wr_sec;
  162. add_char_params.read_access = p_lls_init->alert_level_rd_sec;
  163. add_char_params.init_len = sizeof(uint8_t);
  164. add_char_params.p_init_value = (uint8_t *) &(p_lls_init->initial_alert_level);
  165. return characteristic_add(p_lls->service_handle,
  166. &add_char_params,
  167. &p_lls->alert_level_handles);
  168. }
  169. uint32_t ble_lls_alert_level_get(ble_lls_t * p_lls, uint8_t * p_alert_level)
  170. {
  171. ble_gatts_value_t gatts_value;
  172. if (p_lls == NULL || p_alert_level == NULL)
  173. {
  174. return NRF_ERROR_NULL;
  175. }
  176. // Initialize value struct.
  177. memset(&gatts_value, 0, sizeof(gatts_value));
  178. gatts_value.len = sizeof(uint8_t);
  179. gatts_value.offset = 0;
  180. gatts_value.p_value = p_alert_level;
  181. return sd_ble_gatts_value_get(p_lls->conn_handle,
  182. p_lls->alert_level_handles.value_handle,
  183. &gatts_value);
  184. }
  185. #endif // NRF_MODULE_ENABLED(BLE_LLS)