tile_service.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /**
  2. * NOTICE
  3. *
  4. * Copyright 2020 Tile Inc. All Rights Reserved.
  5. * All code or other information included in the accompanying files ("Tile Source Material")
  6. * is PROPRIETARY information of Tile Inc. ("Tile") and access and use of the Tile Source Material
  7. * is subject to these terms. The Tile Source Material may only be used for demonstration purposes,
  8. * and may not be otherwise distributed or made available to others, including for commercial purposes.
  9. * Without limiting the foregoing , you understand and agree that no production use
  10. * of the Tile Source Material is allowed without a Tile ID properly obtained under a separate
  11. * agreement with Tile.
  12. * You also understand and agree that Tile may terminate the limited rights granted under these terms
  13. * at any time in its discretion.
  14. * All Tile Source Material is provided AS-IS without warranty of any kind.
  15. * Tile does not warrant that the Tile Source Material will be error-free or fit for your purposes.
  16. * Tile will not be liable for any damages resulting from your use of or inability to use
  17. * the Tile Source Material.
  18. *
  19. * Support: firmware_support@tile.com
  20. */
  21. /**
  22. * @file tile_service.c
  23. * @brief Core functionality for Tile Lib
  24. */
  25. #include "sdk_common.h"
  26. #if NRF_MODULE_ENABLED(TILE_SUPPORT)
  27. #include "ble_hci.h"
  28. #include "nrf_delay.h"
  29. #include "app_timer.h"
  30. #include "app_scheduler.h"
  31. #include "boards.h"
  32. #include "nrf_sdh_ble.h"
  33. #include "nrf_log.h"
  34. #include "nrf_drv_ppi.h"
  35. #include "nrf_drv_rng.h"
  36. #include "tile_service/tile_service.h"
  37. #include "tile_config.h"
  38. #include "tile_features/tile_features.h"
  39. #include "tile_gatt_db/tile_gatt_db.h"
  40. #include "tile_storage/tile_storage.h"
  41. #include "tile_assert/tile_assert.h"
  42. #include "tile_player/tile_player.h"
  43. // TileLib includes
  44. #include "tile_lib.h"
  45. #include "drivers/tile_gap_driver.h"
  46. #include "drivers/tile_timer_driver.h"
  47. #include "modules/tile_tmd_module.h"
  48. #include "modules/tile_toa_module.h"
  49. #include <stdbool.h>
  50. #include <string.h>
  51. /*******************************************************************************
  52. * Forward declarations
  53. ******************************************************************************/
  54. static void tile_timer_timeout_handler(void *p_context);
  55. /*******************************************************************************
  56. * Defines & types
  57. ******************************************************************************/
  58. #define APP_BLE_TILE_OBSERVER_PRIO 3
  59. /*******************************************************************************
  60. * Global variables
  61. ******************************************************************************/
  62. static app_timer_t tile_timer_data[TILE_MAX_TIMERS] = { 0 };
  63. /*******************************************************************************
  64. * Local variables
  65. ******************************************************************************/
  66. /*******************************************************************************
  67. * Functions
  68. ******************************************************************************/
  69. /**
  70. * @brief Initialize Tile BLE service
  71. */
  72. void tile_service_init(void)
  73. {
  74. nrf_drv_rng_config_t rng_config = NRF_DRV_RNG_DEFAULT_CONFIG;
  75. /* Initialize Tile timers */
  76. for(int i = 0; i < TILE_MAX_TIMERS; i++)
  77. {
  78. tile_timer_id[i] = &tile_timer_data[i];
  79. /* We use one universal timeout handler with p_context containing the timer ID for dispatch to the shim */
  80. (void) app_timer_create(&tile_timer_id[i], APP_TIMER_MODE_SINGLE_SHOT, tile_timer_timeout_handler);
  81. }
  82. tile_storage_init(); // Initialize storage before initializing features
  83. tile_features_init();
  84. tile_ble_env.conn_handle = BLE_CONN_HANDLE_INVALID;
  85. /* Audio Config */
  86. nrfx_err_t err_code = nrf_drv_ppi_init();
  87. APP_ERROR_CHECK(err_code);
  88. tile_boot_config_player();
  89. /* Register Tile Service Characteristics */
  90. tile_gatt_db_init(&tile_ble_env.service);
  91. /* Initialize RNG driver */
  92. err_code = nrf_drv_rng_init(&rng_config);
  93. APP_ERROR_CHECK(err_code);
  94. /* Register a handler for BLE events */
  95. NRF_SDH_BLE_OBSERVER(m_ble_observer2, APP_BLE_TILE_OBSERVER_PRIO, tile_on_ble_evt, NULL);
  96. /* Play Tile Wakeup Song when Tile Service Inits and the Tile Node is not activated.
  97. This may be disabled depending on the application requirements */
  98. if(TILE_MODE_ACTIVATED != tile_checked->mode)
  99. {
  100. (void) PlaySong(TILE_SONG_WAKEUP, 3, TILE_SONG_DURATION_ONCE);
  101. }
  102. }
  103. /**
  104. * @brief Handle Tile BLE events
  105. *
  106. * @param[in] p_evt Event forwarded from BLE stack.
  107. */
  108. void tile_on_ble_evt(ble_evt_t const * p_evt, void * p_context)
  109. {
  110. struct tile_conn_params params;
  111. uint16_t handle;
  112. switch (p_evt->header.evt_id)
  113. {
  114. case BLE_GAP_EVT_DISCONNECTED:
  115. tile_ble_env.conn_handle = BLE_CONN_HANDLE_INVALID;
  116. tile_unchecked->disconnect_count++;
  117. (void) tile_gap_disconnected();
  118. /********************************
  119. After disconnect, initialize the advertising payload,
  120. This is done in case the Tile Mode changes between Shipping and Advertising, it reflects in the advertising payload.
  121. If we advertise 0xFEEC, instead of 0xFEED, this will cause discoverability issues in following cases:
  122. a. Community Find
  123. b. Access Points
  124. c. If owner tries to discover activated Tiles on another phone, from same account.
  125. Phone from where Tile was activated might still be able to connect as it may read the Mac address and not the advertising payload.
  126. If we advertise 0xFEED, instead of 0xFEEC, this will cause issues after decommissioning, and we will not be able to commission/activate again
  127. ********************************/
  128. break; // BLE_GAP_EVT_DISCONNECTED
  129. case BLE_GAP_EVT_CONNECTED:
  130. /* Save connection handle */
  131. tile_ble_env.conn_handle = p_evt->evt.gap_evt.conn_handle;
  132. tile_unchecked->connection_count++;
  133. if(TILE_MODE_ACTIVATED != tile_checked->mode)
  134. {
  135. // when the Tile is not activated, the Interim TileID, Key is used.
  136. memcpy(tile_checked->tile_id, interim_tile_id, TILE_ID_LEN);
  137. memcpy(tile_checked->tile_auth_key, interim_tile_key, TILE_AUTH_KEY_LEN);
  138. }
  139. // Update the TileID Char
  140. tile_update_tileID_char();
  141. /* Tell Tile Lib about the connection */
  142. params.conn_interval = p_evt->evt.gap_evt.params.connected.conn_params.max_conn_interval;
  143. params.slave_latency = p_evt->evt.gap_evt.params.connected.conn_params.slave_latency;
  144. params.conn_sup_timeout = p_evt->evt.gap_evt.params.connected.conn_params.conn_sup_timeout;
  145. (void) tile_gap_connected(&params);
  146. break; // BLE_GAP_EVT_CONNECTED
  147. case BLE_GAP_EVT_CONN_PARAM_UPDATE:
  148. params = (struct tile_conn_params)
  149. {
  150. .conn_interval = p_evt->evt.gap_evt.params.conn_param_update.conn_params.max_conn_interval,
  151. .slave_latency = p_evt->evt.gap_evt.params.conn_param_update.conn_params.slave_latency,
  152. .conn_sup_timeout = p_evt->evt.gap_evt.params.conn_param_update.conn_params.conn_sup_timeout,
  153. };
  154. (void) tile_gap_params_updated(&params);
  155. break;
  156. case BLE_GATTS_EVT_WRITE:
  157. // Find which ID is associated with the handle
  158. handle = p_evt->evt.gatts_evt.params.write.handle;
  159. for(int i = 0; i < TILE_NUM_ATTRS; i++)
  160. {
  161. if(handle == tile_ble_env.service.characteristic_handles[i])
  162. {
  163. if (i == TILE_TOA_RSP_CCCD)
  164. {
  165. tile_toa_transport_ready(p_evt->evt.gatts_evt.params.write.data[0]); // initialite RSP
  166. }
  167. else if (i == TILE_TOA_CMD_CHAR)
  168. {
  169. // Tell Tile Lib about the write
  170. tile_toa_command_received(p_evt->evt.gatts_evt.params.write.data,p_evt->evt.gatts_evt.params.write.len);
  171. break; // Break from the loop
  172. }
  173. else
  174. {
  175. // Error Case
  176. TILE_ASSERT(0);
  177. }
  178. }
  179. }
  180. break;
  181. case BLE_GATTS_EVT_HVN_TX_COMPLETE:
  182. tile_toa_response_sent_ok();
  183. break;
  184. default:
  185. break;
  186. }
  187. }
  188. /*******************************************************************************
  189. * Local functions
  190. ******************************************************************************/
  191. /**
  192. * @brief Timer handler for Tile timers
  193. */
  194. static void tile_timer_timeout_handler(void *p_context)
  195. {
  196. (void) tile_timer_expired((uint32_t)p_context & 0xFF);
  197. }
  198. /**
  199. * @brief Retrieve correct 16-bit UUID to advertise and interval on the Tile mode
  200. */
  201. void tile_get_adv_params(uint16_t* uuid, uint16_t* interval)
  202. {
  203. if(TILE_MODE_ACTIVATED == tile_checked->mode)
  204. {
  205. *uuid = TILE_ACTIVATED_UUID;
  206. *interval = tile_checked->adv_int;
  207. }
  208. else
  209. {
  210. *uuid = TILE_SHIPPING_UUID;
  211. *interval = TILE_DEFAULT_ADV_INT_SHIPPING;
  212. }
  213. }
  214. #endif // NRF_MODULE_ENABLED(TILE_SUPPORT)