123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649 |
- /**
- * NOTICE
- *
- * Copyright 2020 Tile Inc. All Rights Reserved.
- * All code or other information included in the accompanying files ("Tile Source Material")
- * is PROPRIETARY information of Tile Inc. ("Tile") and access and use of the Tile Source Material
- * is subject to these terms. The Tile Source Material may only be used for demonstration purposes,
- * and may not be otherwise distributed or made available to others, including for commercial purposes.
- * Without limiting the foregoing , you understand and agree that no production use
- * of the Tile Source Material is allowed without a Tile ID properly obtained under a separate
- * agreement with Tile.
- * You also understand and agree that Tile may terminate the limited rights granted under these terms
- * at any time in its discretion.
- * All Tile Source Material is provided AS-IS without warranty of any kind.
- * Tile does not warrant that the Tile Source Material will be error-free or fit for your purposes.
- * Tile will not be liable for any damages resulting from your use of or inability to use
- * the Tile Source Material.
- *
- * Support: firmware_support@tile.com
- */
- /**
- * @file tile_features.c
- * @brief Support for features in Tile Lib
- */
- #include "sdk_common.h"
- #if NRF_MODULE_ENABLED(TILE_SUPPORT)
- #include "nrf_drv_rng.h"
- #include "ble.h"
- #include "ble_hci.h"
- #include "nrf_delay.h"
- #include "app_timer.h"
- #include "app_scheduler.h"
- #include "app_button.h"
- #include <string.h>
- #include "nrf_log.h"
- #include "nrf_log_ctrl.h"
- // TileLib includes
- #include "tile_config.h"
- #include "tile_features.h"
- #include "tile_lib.h"
- #include "drivers/tile_gap_driver.h"
- #include "drivers/tile_timer_driver.h"
- #include "drivers/tile_button_driver.h"
- #include "drivers/tile_random_driver.h"
- #include "modules/tile_tdi_module.h"
- #include "modules/tile_toa_module.h"
- #include "modules/tile_tmd_module.h"
- #include "modules/tile_tpi_module.h"
- #include "modules/tile_tdt_module.h"
- #include "modules/tile_tdg_module.h"
- #include "tile_storage/tile_storage.h"
- #include "tile_player/tile_player.h"
- #include "tile_assert/tile_assert.h"
- #include "tile_bdaddr/tile_bdaddr.h"
- /*******************************************************************************
- * Global variables
- ******************************************************************************/
- tile_ble_env_t tile_ble_env;
- app_timer_id_t tile_timer_id[TILE_MAX_TIMERS];
- const char tile_model_number[] = TILE_MODEL_NUMBER;
- const char tile_hw_version[] = TILE_HARDWARE_VERSION;
- /*******************************************************************************
- * Local variables
- ******************************************************************************/
- static toa_channel_t tile_toa_channels[NUM_TOA_CHANNELS] __attribute__((section("retention_mem_area0"), zero_init));
- static uint8_t toa_queue_buffer[TOA_QUEUE_BUFFER_SIZE];
- /*******************************************************************************
- * Forward declarations
- ******************************************************************************/
- void advertising_update(void);
- /* gap module*/
- static int tile_disconnect(void);
- /* timer module*/
- static int tile_timer_start(uint8_t timer_id, uint32_t duration);
- static int tile_timer_cancel(uint8_t timer_id);
- /* random module*/
- static int tile_random_bytes(uint8_t *dst, uint8_t len);
- /* toa module*/
- static int tile_send_toa_response(uint8_t *data, uint16_t len);
- static int tile_associate(uint8_t* tile_id, uint8_t* tile_auth_key, uint8_t* authorization_type);
- /* tmd module*/
- static int tile_mode_set(uint8_t mode);
- static int tile_mode_get(uint8_t *mode);
- /* tdg module*/
- static int tile_get_diagnostics_cb(void);
- /* song module*/
- // Refer tile_player.c
- /* test module*/
- static void test_process_reboot(uint8_t reboot_type);
- static void test_process_storage(uint8_t test_type, uint8_t *payload, uint8_t payload_length);
- static int test_process(uint8_t code, uint8_t *data, uint8_t datalen);
- /* button driver */
- int tile_read_button_state(uint8_t *button_state);
- static void tile_hdc_cb(void);
- static int tile_hdc_config_written(tdt_config_t *config);
- /* TPI module */
- static int tile_tileID_counter_updated(void);
- /*******************************************************************************
- * Defines & types
- ******************************************************************************/
- /*******************************************************************************
- * Tile configuration structures
- ******************************************************************************/
- /* gap register struct */
- static struct tile_gap_driver gap_driver =
- {
- .gap_disconnect = tile_disconnect,
- .auth_disconnect_count = &tile_persist.unchecked.s.auth_disconnect_count,
- };
- /* timer driver struct */
- struct tile_timer_driver timer_driver =
- {
- .start = tile_timer_start,
- .cancel = tile_timer_cancel,
- };
- /* random driver struct */
- static struct tile_random_driver random_driver =
- {
- .random_bytes = tile_random_bytes,
- };
- /* device information struct */
- struct tile_tdi_module tdi_module =
- {
- .tile_id = tile_persist.checked.s.tile_id,
- .model_number = tile_persist.checked.s.model_number,
- .hardware_version = tile_persist.checked.s.hardware_version,
- .bdaddr = bdaddr, // RAM Variable, Not stored in Flash
- .firmware_version = TILE_FIRMWARE_VERSION,
- };
- /* tile over the air struct */
- struct tile_toa_module toa_module =
- {
- .tile_id = tile_persist.checked.s.tile_id,
- .auth_key = tile_persist.checked.s.tile_auth_key,
- .channels = tile_toa_channels,
- .queue = toa_queue_buffer,
- .queue_size = TOA_QUEUE_BUFFER_SIZE,
- .num_channels = NUM_TOA_CHANNELS,
- .mic_failure_count = &tile_persist.unchecked.s.micFailures,
- .auth_failure_count = &tile_persist.unchecked.s.auth_fail_count,
- .channel_open_count = &tile_persist.unchecked.s.toa_channel_open_count,
- .authenticate_count = &tile_persist.unchecked.s.toa_authenticate_count,
- .tka_closed_channel_count = &tile_persist.unchecked.s.tka_closed_channel_count,
- .send_response = tile_send_toa_response,
- .associate = tile_associate
- };
- /* tile mode struct */
- struct tile_tmd_module tmd_module =
- {
- .get = tile_mode_get,
- .set = tile_mode_set,
- };
- /* tile mode struct */
- static struct tile_tdg_module tdg_module =
- {
- .get_diagnostics = tile_get_diagnostics_cb,
- };
- /* tile song module struct */
- static struct tile_song_module song_module =
- {
- .play = PlaySong,
- .stop = StopSong
- };
- /* tile test module struct */
- static struct tile_test_module test_module =
- {
- .process = test_process,
- };
- /* tile button driver struct */
- static struct tile_button_driver button_driver =
- {
- .read_state = tile_read_button_state,
- };
- struct tile_tpi_module tpi_module =
- {
- .tileID_key = tile_persist.checked.s.tileIDkey,
- .hashed_tileID = tile_env.hashedTileID,
- .tileID_counter = &tile_persist.unchecked.s.tileIDcounter,
- .tileID_counter_updated = tile_tileID_counter_updated,
- };
- /* tile double tap struct */
- struct tile_tdt_module tdt_module =
- {
- .hdc_status = TDT_HDC_STATUS_NORMAL,
- .single_tap = NULL,
- .long_tap = NULL,
- .double_tap_detect = NULL,
- .double_tap_notify = NULL,
- .double_tap_failure2 = NULL,
- .hdc_cb = tile_hdc_cb,
- .config_written = tile_hdc_config_written,
- };
- /*******************************************************************************
- * Functions
- ******************************************************************************/
- void tile_features_init(void)
- {
- /****************************************************************/
- /**** Minimum Features required for TileLib Interoperability ****/
- /****************************************************************/
- /* Initialize GAP driver */
- (void) tile_gap_register(&gap_driver);
-
- /* Initialize timer driver */
- (void) tile_timer_register(&timer_driver);
- /* Initialize random driver */
- (void) tile_random_register(&random_driver);
- /* Initialize device information module */
- /* Obtain default Bdaddr from device register at 0x100000A4*/
- get_default_macAddr();
- set_new_macAddr();
- (void) tile_tdi_register(&tdi_module);
- /* Initialize tile over the air module */
- (void) tile_toa_register(&toa_module);
- /* Initialize tile mode module */
- (void) tile_tmd_register(&tmd_module);
- /* Initialize button driver module */
- (void) tile_button_register(&button_driver);
- /* Initialize tile PrivateID module */
- (void) tile_tpi_register(&tpi_module);
-
- /* Initialize tile double tap module */
- memcpy(&tdt_module.config, &tile_checked->tdt_configuration, sizeof(tdt_config_t));
- (void) tile_tdt_register(&tdt_module);
- /****************************************************************/
- /**** Additional Features ****/
- /****************************************************************/
- /* Initialize tile diagnbostics module */
- (void) tile_tdg_register(&tdg_module);
- /* Initialize song module */
- (void) tile_song_register(&song_module);
- /* Initialize test module */
- (void) tile_test_register(&test_module);
- }
- /*******************************************************************************
- * Callback functions for Tile Lib
- ******************************************************************************/
- /***************************** gap module *******************************/
- /**
- * @brief Disconnect current connection
- */
- static int tile_disconnect(void)
- {
- if(BLE_CONN_HANDLE_INVALID == tile_ble_env.conn_handle)
- {
- return TILE_ERROR_ILLEGAL_OPERATION;
- }
- (void) sd_ble_gap_disconnect(tile_ble_env.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
- return TILE_ERROR_SUCCESS;
- }
- /**
- * @brief Update the TileID Char
- */
- void tile_update_tileID_char(void)
- {
- ret_code_t err_code;
- ble_gatts_value_t gatts_value;
- // Initialize value struct.
- memset(&gatts_value, 0, sizeof(gatts_value));
- gatts_value.len = TILE_ID_LEN;
- gatts_value.offset = 0;
- gatts_value.p_value = tile_persist.checked.s.tile_id;
- // Update database
- err_code = sd_ble_gatts_value_set(tile_ble_env.conn_handle, tile_ble_env.service.characteristic_handles[TILE_ID_CHAR], &gatts_value);
- APP_ERROR_CHECK(err_code);
- return;
- }
- /************************************************************************/
- /***************************** timer module *****************************/
- /**
- * @brief Start a Tile timer
- *
- * @param[in] timer_id ID for timer, as specified by Tile Lib
- * @param[in] duration Duration (in 10ms increments) for the timer
- */
- static int tile_timer_start(uint8_t timer_id, uint32_t duration)
- {
- ret_code_t err_code;
- if(duration < 1)
- {
- duration++;
- }
- /* The new timer takes priority, so stop any existing timer */
- err_code = app_timer_stop(tile_timer_id[timer_id]);
- APP_ERROR_CHECK(err_code);
-
- err_code = app_timer_start(tile_timer_id[timer_id], APP_TIMER_TICKS((uint64_t) duration * 10), (void *)(uint32_t)timer_id);
- APP_ERROR_CHECK(err_code);
- return TILE_ERROR_SUCCESS;
- }
- /**
- * @brief Cancel a Tile timer
- *
- * @param[in] timer_id ID for timer, as specified by Tile Lib
- */
- static int tile_timer_cancel(uint8_t timer_id)
- {
- uint32_t err_code = app_timer_stop(tile_timer_id[timer_id]);
- err_code = (err_code == NRF_SUCCESS) ? TILE_ERROR_SUCCESS : err_code;
- return (int) err_code;
- }
- /************************************************************************/
- /****************************random module *******************************/
- /**
- * @brief Generate some random bytes
- *
- * @param[out] dst Destination address for the random bytes
- * @param[in] len Number of bytes requested
- */
- static int tile_random_bytes(uint8_t *dst, uint8_t len)
- {
- uint8_t num;
- uint32_t err_code;
- /* Check if enough random bytes are available */
- nrf_drv_rng_bytes_available(&num);
- while(num < len)
- {
- /* Wait for enough random bytes to be available */
- nrf_delay_us(200);
- nrf_drv_rng_bytes_available(&num);
- }
- /* Copy over random bytes */
- err_code = nrf_drv_rng_rand(dst, len);
- err_code = (err_code == NRF_SUCCESS) ? TILE_ERROR_SUCCESS : err_code;
- return (int) err_code;
- }
- /************************************************************************/
- /***************************** tpi module *******************************/
- /**
- * @brief Update TileID counter for TPI generation
- *
- * @param[out] int TILE_ERROR_TYPE
- */
- static int tile_tileID_counter_updated(void)
- {
- if((BLE_CONN_HANDLE_INVALID == tile_ble_env.conn_handle))
- {
- advertising_update();
- }
- return TILE_ERROR_SUCCESS;
- }
- /************************************************************************/
- /***************************** toa module *******************************/
- /**
- * @brief Send notification on a characteristic in TOA_RSP
- *
- * @param[in] data Data to set attribute to.
- * @param[in] len Length of data.
- */
- static int tile_send_toa_response(uint8_t *data, uint16_t len)
- {
- ret_code_t err_code;
- if(BLE_CONN_HANDLE_INVALID == tile_ble_env.conn_handle)
- {
- return TILE_ERROR_ILLEGAL_OPERATION;
- }
- uint16_t handle = tile_ble_env.service.characteristic_handles[TILE_TOA_RSP_CHAR];
- ble_gatts_hvx_params_t hvx_params =
- {
- .handle = handle,
- .type = BLE_GATT_HVX_NOTIFICATION,
- .offset = 0,
- .p_len = &len,
- .p_data = data
- };
- err_code = sd_ble_gatts_hvx(tile_ble_env.conn_handle, &hvx_params);
- APP_ERROR_CHECK(err_code);
- return TILE_ERROR_SUCCESS;
- };
- /**
- * @brief Set the new Tile Id/Auth Key during Commissioning Process if in Shipping Modes
- */
- static int tile_associate(uint8_t* tile_id, uint8_t* tile_auth_key, uint8_t* authorization_type)
- {
- int retcode = TOA_ERROR_OK;
- #ifdef INTERIM_TILE_ID
- if(TILE_MODE_SHIPPING == tile_checked->mode)
- {
- memcpy(tile_checked->tile_id, tile_id, sizeof(tile_checked->tile_id));
- memcpy(tile_checked->tile_auth_key, tile_auth_key, sizeof(tile_checked->tile_auth_key));
- // Update the TileID Char
- tile_update_tileID_char();
- NRF_LOG_INFO("tile_associate in Shipping Mode Successful\r\n");
- }
- else // Do not allow to set new Tile id/Auth key for an already Activated Tile. We should never come here ideally
- {
- retcode = TOA_RSP_SERVICE_UNAVAILABLE;
- NRF_LOG_INFO("tile_associate in Activated Mode Not Allowed, returning TOA_RSP_SERVICE_UNAVAILABLE \r\n");
- }
- return retcode;
- #else
- return retcode;
- #endif
- }
- /************************************************************************/
- /***************************** mode module *******************************/
- /**
- * @brief Set the mode of the device.
- *
- * @param[in] mode Mode, as specified by the TMD module.
- */
- static int tile_mode_set(uint8_t mode)
- {
- if(TILE_MODE_ACTIVATED != mode)
- {
- /* Disregard any mode besides Shipping and Activated
- * If mode being set is not Activated, Make it Shipping
- */
- mode = TILE_MODE_SHIPPING;
- /* When the Tile is not activated, the Interim TileID, Key is used. */
- memcpy(tile_checked->tile_id, interim_tile_id, 8);
- memcpy(tile_checked->tile_auth_key, interim_tile_key, 16);
- // Update the TileID Char
- tile_update_tileID_char();
- }
- tile_checked->mode = mode;
- set_new_macAddr();
- // tile_set_params_for_mode();
- tile_store_app_data();
- return TILE_ERROR_SUCCESS;
- }
- /**
- * @brief Get the current mode of the device.
- *
- * @param[out] mode Mode, as specified by the TMD module.
- */
- static int tile_mode_get(uint8_t *mode)
- {
- *mode = tile_checked->mode;
- return TILE_ERROR_SUCCESS;
- }
- /************************************************************************/
- /***************************** tdg module *******************************/
- static int tile_get_diagnostics_cb(void)
- {
- uint8_t version = DIAGNOSTIC_VERSION;
- (void) tdg_add_data(&version, 1);
- (void) tdg_add_data(&tile_checked->mode, 1);
- (void) tdg_add_data(&tile_unchecked->reset_count, 1);
- (void) tdg_add_data(&tile_unchecked->piezoMs, 4);
- (void) tdg_add_data(&tile_unchecked->connection_count, 3);
- (void) tdg_add_data(&tile_unchecked->auth_fail_count, 1);
- (void) tdg_add_data(&tile_unchecked->micFailures, 1);
- (void) tdg_add_data(&tile_unchecked->disconnect_count, 3);
- (void) tdg_add_data(&tile_unchecked->toa_channel_open_count, 3);
- (void) tdg_add_data(&tile_unchecked->toa_authenticate_count, 3);
- (void) tdg_add_data(&tile_unchecked->tka_closed_channel_count, 2);
- (void) tdg_add_data(&tile_unchecked->auth_disconnect_count, 2);
- (void) tdg_finish();
- return TILE_ERROR_SUCCESS;
- }
- /************************************************************************/
- /***************************** song module ******************************/
- // Refer tile_player.c
- /************************************************************************/
- void tile_button_was_pressed(void)
- {
- /* Abort SONG if Find Song is currently playing*/
- if (CheckFindSong())
- {
- (void) StopSong();
- }
- if(TILE_MODE_ACTIVATED == tile_checked->mode)
- {
- // Forward to TileLib
- (void) tile_button_pressed();
- }
- else
- {
- /* Play the right Song according to Mode */
- if(TILE_MODE_SHIPPING == tile_checked->mode)
- {
- (void) PlaySong(TILE_SONG_WAKEUP_PART, 3, TILE_SONG_DURATION_ONCE);
- }
- }
- }
- int tile_read_button_state(uint8_t *button_state)
- {
- bool is_button_pushed = app_button_is_pushed(0);
-
-
- /* pin is pulled high */
- if(true == is_button_pushed)
- {
- *button_state = TILE_BUTTON_PRESSED;
- }
- else
- {
- *button_state = TILE_BUTTON_RELEASED;
- }
-
- return TILE_ERROR_SUCCESS;
- };
- void tile_hdc_cb(void)
- {
- /* Currently Disconnected, Update Advertising Data and Parameters based on the TDT State */
- if(BLE_CONN_HANDLE_INVALID == tile_ble_env.conn_handle)
- {
- advertising_update();
- }
- };
- int tile_hdc_config_written(tdt_config_t *config)
- {
- return TILE_ERROR_SUCCESS;
- };
- /***************************** test module ******************************/
- static int test_process(uint8_t code, uint8_t *data, uint8_t datalen)
- {
- switch(code) {
- case TEST_CMD_REBOOT:
- test_process_reboot(data[0]);
- break;
- case TEST_CMD_STORAGE:
- test_process_storage(data[0], data+1, datalen-1);
- break;
- default:
- break;
- }
- return TILE_ERROR_SUCCESS;
- }
- static void test_process_reboot(uint8_t reboot_type)
- {
- switch(reboot_type) {
- case TEST_CMD_REBOOT_RESET:
- (void) sd_nvic_SystemReset();
- break;
- case TEST_CMD_REBOOT_WATCHDOG:
- while(1);
- //break;
- case TEST_CMD_REBOOT_MEMORY_FAULT:
- *((uint8_t*)0xFFFFFFFF) = 0;
- break;
- case TEST_CMD_REBOOT_OTHER:
- /* ? */
- break;
- case TEST_CMD_REBOOT_ASSERT:
- TILE_ASSERT(0);
- /* TODO */
- break;
- case TEST_CMD_REBOOT_DURING_FLASH:
- /* TODO */
- break;
- }
- }
- static void test_process_storage(uint8_t test_type, uint8_t *payload, uint8_t payload_length)
- {
- /* TODO */
- }
- /************************************************************************/
- #endif // NRF_MODULE_ENABLED(TILE_SUPPORT)
|