初始版本

This commit is contained in:
xiaozhengsheng
2025-08-19 09:49:41 +08:00
parent 10f1ddf1c1
commit 6df0f7d96e
2974 changed files with 1712873 additions and 54 deletions

View File

@@ -0,0 +1,78 @@
/*
* HMAC-SHA-224/256/384/512 implementation
* Last update: 06/15/2005
* Issue date: 06/15/2005
*
* Copyright (C) 2005 Olivier Gay <olivier.gay@a3.epfl.ch>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef HMAC_SHA2_H
#define HMAC_SHA2_H
#include "crypto/sha256.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
sha256_ctx ctx;
#if 0
sha256_ctx ctx_inside;
sha256_ctx ctx_outside;
#endif
#if 0
/* for hmac_reinit */
sha256_ctx ctx_inside_reinit;
sha256_ctx ctx_outside_reinit;
#endif
#if 0
unsigned char block_ipad[SHA256_BLOCK_SIZE];
unsigned char block_opad[SHA256_BLOCK_SIZE];
#endif
} hmac_sha256_ctx;
void hmac_sha256_init(hmac_sha256_ctx *ctx, const unsigned char *key,
unsigned int key_size);
/* void hmac_sha256_reinit(hmac_sha256_ctx *ctx); */
void hmac_sha256_update(hmac_sha256_ctx *ctx, const unsigned char *message,
unsigned int message_len);
void hmac_sha256_final(hmac_sha256_ctx *ctx, unsigned char *mac,
unsigned int mac_size);
void hmac_sha256_ogay(const unsigned char *key, unsigned int key_size,
const unsigned char *message, unsigned int message_len,
unsigned char *mac, unsigned mac_size);
#ifdef __cplusplus
}
#endif
#endif /* !HMAC_SHA2_H */

84
external/tile/tile_lib/crypto/sha256.h vendored Normal file
View File

@@ -0,0 +1,84 @@
/*
* FIPS 180-2 SHA-224/256/384/512 implementation
* Last update: 02/02/2007
* Issue date: 04/30/2005
*
* Copyright (C) 2005, 2007 Olivier Gay <olivier.gay@a3.epfl.ch>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef SHA2_H
#define SHA2_H
#include <stdint.h>
#define SHA224_DIGEST_SIZE ( 224 / 8)
#define SHA256_DIGEST_SIZE ( 256 / 8)
#define SHA384_DIGEST_SIZE ( 384 / 8)
#define SHA512_DIGEST_SIZE ( 512 / 8)
#define SHA256_BLOCK_SIZE ( 512 / 8)
#define SHA512_BLOCK_SIZE (1024 / 8)
#define SHA384_BLOCK_SIZE SHA512_BLOCK_SIZE
#define SHA224_BLOCK_SIZE SHA256_BLOCK_SIZE
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
unsigned int tot_len;
unsigned int len;
//unsigned char block[2 * SHA256_BLOCK_SIZE];
unsigned char block[SHA256_BLOCK_SIZE];
uint32_t h[8];
} sha256_ctx;
typedef sha256_ctx sha224_ctx;
void sha224_init(sha224_ctx *ctx);
void sha224_update(sha224_ctx *ctx, const unsigned char *message,
unsigned int len);
void sha224_final(sha224_ctx *ctx, unsigned char *digest);
void sha224(const unsigned char *message, unsigned int len,
unsigned char *digest);
void sha256_init(sha256_ctx * ctx);
void sha256_update(sha256_ctx *ctx, const unsigned char *message,
unsigned int len);
void sha256_final(sha256_ctx *ctx, unsigned char *digest);
void sha256(const unsigned char *message, unsigned int len,
unsigned char *digest);
#ifdef __cplusplus
}
#endif
#endif /* !SHA2_H */

View File

@@ -0,0 +1,82 @@
/**
* NOTICE
*
* Copyright 2017 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_button_driver.h
** @brief Tile Button driver
*/
#ifndef TILE_BUTTON_DRIVER_H_
#define TILE_BUTTON_DRIVER_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Button states
*/
enum TILE_BUTTON_STATES
{
TILE_BUTTON_PRESSED,
TILE_BUTTON_RELEASED,
};
/**
* Tile button driver.
*/
struct tile_button_driver
{
/**
* Read the state of the Tile button.
*
* @param[out] button_state State of the button. See TILE_BUTTON_STATES.
*
* @return See @ref TILE_ERROR_CODES.
*/
int (*read_state)(uint8_t *button_state);
};
/**
* Register the button module.
*
* @param[in] driver Driver for the Tile button.
*
* @return TILE_ERROR_SUCCESS.
*/
int tile_button_register(struct tile_button_driver *driver);
/**
* Call when the Tile button has been pressed.
*
* @return TILE_ERROR_SUCCESS.
*/
int tile_button_pressed(void);
#ifdef __cplusplus
}
#endif
#endif // TILE_BUTTON_DRIVER_H_

View File

@@ -0,0 +1,114 @@
/**
* 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_gap_driver.h
** @brief Tile GAP Driver interface. Provides TileLib Control over GAP functions, like connection,
** disconnection and connection parameters.
*/
#ifndef TILE_GAP_DRIVER_H_
#define TILE_GAP_DRIVER_H_
#include <stdint.h>
#define TILE_SERVICE_DATA_VERSION_0 0
#define TILE_SERVICE_DATA_VERSION_2 2
/**
* Connection parameters.
*/
struct tile_conn_params
{
uint16_t conn_interval;
uint16_t slave_latency;
uint16_t conn_sup_timeout;
};
struct tile_gap_driver
{
/**
* Time in 10ms increments before Tile disconnects if no client has
* authenticated. A value of 0 indicates that this feature is disabled.
* The value may be updated at any time, but will not clear a timer which
* is already running. The value is used after a connection is established.
*/
uint16_t authentication_timer_delay;
/**
* Memory space for current connection parameters.
*/
struct tile_conn_params conn_params;
/**
* Diagnostic info: counts the number of disconnections triggered by Auth Timer.
*/
uint16_t* auth_disconnect_count;
/**
* Disconnect from the currently connected device.
*
* @return See @ref TILE_ERROR_CODES.
*/
int (*gap_disconnect)(void);
};
/**
* Register the GAP driver with Tile Library.
*/
int tile_gap_register(struct tile_gap_driver *driver);
/**
* Call when a connection has been established.
*/
int tile_gap_connected(struct tile_conn_params *conn_params);
/**
* Call when a connection has been terminated.
*/
int tile_gap_disconnected(void);
/**
* Call when the connection parameters have been updated. This function will
* update the values contained in the driver structure.
*/
int tile_gap_params_updated(struct tile_conn_params *conn_params);
/***************************************************************************************
* @brief Get the advertising parameters to use from TileLib.
*
* @param[out] adv_interval pointer to write the Advertising Interval.
* @param[out] tile_service_uuid pointer to write the Service UUID to put in the list of 16-bit UUIDs and Service Data.
* @param[out] tile_service_data_length pointer to write the Service Data length.
* @param[out] tile_service_data pointer to write the Service Data. The required minimum available buffer size is TILE_SERVICE_DATA_MAX_LENGTH.
* @param[out] manuf pointer to indicate whether munufacturing data is available.
*
* @return See @ref TILE_ERROR_CODES.
*
****************************************************************************************
*/
int tile_gap_get_adv_params(uint16_t* adv_interval, uint16_t* tile_service_uuid, uint8_t* tile_service_data_length, uint8_t* tile_service_data, uint8_t* manuf);
#endif

View File

@@ -0,0 +1,54 @@
/**
* 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_random_driver.h
** @brief Tile Random Bytes Generation. Provides TileLib an interface to generate random numbers.
*/
#ifndef TILE_RANDOM_DRIVER_H_
#define TILE_RANDOM_DRIVER_H_
#include <stdint.h>
/**
* Tile random number driver
*/
struct tile_random_driver
{
/**
* Generate random bytes.
*
* @param[out] dst Buffer to write random bytes to.
* @param[in] length Number of random bytes to generate.
*
* @return See @ref TILE_ERROR_CODES.
*/
int (*random_bytes)(uint8_t *dst, uint8_t length);
};
/**
* Register the Tile random driver.
*/
int tile_random_register(struct tile_random_driver *driver);
#endif

View File

@@ -0,0 +1,89 @@
/**
* 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_timer_driver.h
** @brief Tile Timer Driver interface. Provides TileLib an interface to use timers.
*/
#ifndef TILE_TIMER_DRIVER_H_
#define TILE_TIMER_DRIVER_H_
#include <stdint.h>
/**
* Number of Tile ticks in one second. All Tile timer durations are
* specified in Tile ticks.
*/
#define TILE_TICKS_PER_SEC ((uint32_t)100)
/**
* IDs to associate with each Tile timer.
*/
enum TILE_TIMER_IDS
{
TILE_CONNECTION_TIMER,
TILE_AUTHENTICATION_TIMER,
TILE_TDT_DOUBLETAP_TIMER,
TILE_TDT_HDC_TIMER,
TILE_TCU_PARAM_UPDATE_TIMER,
TILE_TKA_TIMER1,
TILE_TKA_TIMER2,
TILE_TKA_TIMER3,
TILE_TEST_TIMER1,
TILE_TEST_TIMER2,
TILE_TEST_TIMER3,
TILE_TEST_TIMER4,
TILE_TEST_TIMER5,
TILE_TEST_TIMER6,
TILE_TEST_TIMER7,
TILE_TEST_TIMER8,
TILE_TILEID_COUNTER_TIMER,
TILE_MAX_TIMERS /* < Number of timers used by Tile Lib. */
};
struct tile_timer_driver
{
/**
* Start a timer. duration is in 10ms increments.
*/
int (*start)(uint8_t timer_id, uint32_t duration);
/**
* Cancel a timer.
*/
int (*cancel)(uint8_t timer_id);
};
/**
* Timer registration function.
*/
int tile_timer_register(struct tile_timer_driver *driver);
/**
* Call when a Tile timer has expired.
*/
int tile_timer_expired(uint8_t timer_id);
#endif // TILE_TIMER_DRIVER_H_

View File

@@ -0,0 +1,274 @@
/**
* 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_song_module.h
** @addtogroup TOA
** @{
** @brief Tile Song Module
*/
#ifndef TILE_SONG_MODULE_H_
#define TILE_SONG_MODULE_H_
#include <stdint.h>
#include "crypto/hmac_sha256.h"
/**
* @brief Tile Song numbers
*/
enum TILE_SONG
{
TILE_SONG_1_CLICK = 0x00,
TILE_SONG_FIND = 0x01,
TILE_SONG_ACTIVE = 0x02,
TILE_SONG_SLEEP = 0x03,
TILE_SONG_WAKEUP = 0x04,
TILE_SONG_FACTORY_TEST = 0x05,
TILE_SONG_MYSTERY = 0x06,
TILE_SONG_SILENT = 0x07,
TILE_SONG_BUTTON = 0x08,
TILE_SONG_WAKEUP_PART = 0x09,
TILE_SONG_DT_SUCCESS = 0x0a,
TILE_SONG_DT_FAILURE = 0x0b,
TILE_SONG_2_CLICK = 0x0c,
TILE_SONG_1_BIP = 0x0d,
TILE_SONG_2_BIP = 0x0e,
TILE_SONG_3_BIP = 0x0f,
TILE_SONG_4_BIP = 0x10,
TILE_SONG_5_BIP = 0x11,
TILE_SONG_6_BIP = 0x12,
TILE_SONG_7_BIP = 0x13,
TILE_SONG_DT_HB = 0x14,
TILE_SONG_MAX = 0x15,
TILE_SONG_STOP = 0xFF
};
/**
* Enumerate notes from C0 to B9
*
* Tile songs are created as a sequence of pairs,
* (note, duration). Each value in the pair is one byte.
* A song ends with the pair (REST, REST).
*/
enum NOTES {
REST = 0x00,
C0, CS0, D0, DS0, E0, F0, FS0, G0, GS0, A0, AS0, B0,
C1, CS1, D1, DS1, E1, F1, FS1, G1, GS1, A1, AS1, B1,
C2, CS2, D2, DS2, E2, F2, FS2, G2, GS2, A2, AS2, B2,
C3, CS3, D3, DS3, E3, F3, FS3, G3, GS3, A3, AS3, B3,
C4, CS4, D4, DS4, E4, F4, FS4, G4, GS4, A4, AS4, B4,
C5, CS5, D5, DS5, E5, F5, FS5, G5, GS5, A5, AS5, B5,
C6, CS6, D6, DS6, E6, F6, FS6, G6, GS6, A6, AS6, B6,
C7, CS7, D7, DS7, E7, F7, FS7, G7, GS7, A7, AS7, B7,
C8, CS8, D8, DS8, E8, F8, FS8, G8, GS8, A8, AS8, B8,
C9, CS9, D9, DS9, E9, F9, FS9, G9, GS9, A9, AS9, B9,
};
/**
* @brief TILE_SONG_DURATION
* Duration to play the Tile Song for.
* The duration is in seconds and here are special values.
*/
enum TILE_SONG_DURATION
{
TILE_SONG_DURATION_NOPLAY = 0x00, /**< Do not play anything */
TILE_SONG_DURATION_ONCE = 0xFE, /**< Play the Song just once */
TILE_SONG_DURATION_FOREVER = 0xFF /**< Play the song forever, till someone stops it */
};
#define SONG_METADATA_SIZE (sizeof(struct song_metadata_t))
#define SONG_INFO_SIZE (sizeof(struct song_hdr_info_t))
#define SONG_SECURITY_SIZE (sizeof(struct song_hdr_sec_t))
#define SONG_HEADER_SIZE (SONG_INFO_SIZE + SONG_SECURITY_SIZE)
#define SONG_HASH_SIZE 32 /**< Size of the song hash */
#define SONG_SIG_SIZE 64 /**< Size of the song signature */
#define SONG_CRC16_SIZE 2 /**< Size of the Block CRC */
#define TILE_PROGRAMMABLE_SONG_LENGTH 1024 /**< Maximum length of the programmable song section in flash */
#define TILE_SONG_BLOCK_SIZE 128 /**< Size of data in a data block */
#define TILE_SONG_BUFFER_SIZE TILE_SONG_BLOCK_SIZE + SONG_CRC16_SIZE /**< Size of intermediate buffer for programming */
#define TILE_SONG_VERSION 1 /**< Version field, to allow future format changes to take place */
#define TILE_SONG_VALID 0xAA /**< Flag indicating a song is valid */
/** @brief Song file header info portion */
struct song_hdr_info_t
{
uint8_t song_format; ///< song_format is a Version Number that would describe the Tsong Format Variations
uint8_t song_number; ///< song_number describes what the Type of Song being Programmed and what song_number to use for playing the Song using TOA_CMD_SONG command.
uint16_t song_id; ///< song_id is the Tile Assigned ID Number of this Song. See @ref TILE_SONG
uint16_t song_size; ///< song_size represents the Song Payload Size, excluding any Security or Info Header.
};
/** @brief Song file header security info */
struct song_hdr_sec_t
{
uint8_t hash[SONG_HASH_SIZE]; ///< A SHA-256 Hash Calculated using the Info Header and Song Payload.
uint8_t sign[SONG_SIG_SIZE]; ///< Signature of the Song, calculated using the hash as input and Song Private Key with ECC Secp256k1 Curve.
};
/** @brief State of song programming */
struct song_program_state_t
{
uint16_t pos; ///< accumulated number of bytes written for current Song
uint8_t buf_pos; ///< accumulated number of bytes received for current block
uint8_t state; ///< Song Programming State
uint16_t file_size; ///< Total File Size of the current song being programmed
uint32_t bank; ///< Memory Bank currently being used to program the Song
sha256_ctx hash_ctx; ///< Current programmed Song Hash Calculation Context
struct song_hdr_info_t info; ///< Current programmed Song Info Header
struct song_hdr_sec_t sec; ///< Current programmed Song Security Header
uint8_t cached_cid; ///< TOA CID of the current TPS session
uint8_t block_dataSize; ///< datasize of the received block
};
/** @brief Metadata info stored in flash */
struct song_metadata_t
{
uint8_t valid;
uint8_t id;
};
/** @brief Cache for information related to the currently loaded song */
struct song_info_cache_t
{
struct song_metadata_t curMeta;
struct song_hdr_info_t curInfo;
uint32_t curBank;
};
/**
* Tile Programmable Songs module.
*
* Tile Lib supports the ability to update the find song over the air.
*/
struct tile_song_tps_module_t {
/**
* Public key used for ECC signature verification
* Generating ECC keys:
* $ openssl ecparam -genkey -name secp256k1 -out k.perm
* $ openssl ec -outform DER -in k.perm -noout -text
*/
uint8_t *pub_key;
/**
* If set to 0, it means the programmable song is currently not playable
*/
uint8_t useProgrammableSong;
/**
* Buffer used to receive TPS Song data
*/
uint8_t tileSongBuffer[TILE_SONG_BUFFER_SIZE];
/**
* Cache for information related to the currently loaded song
*/
struct song_info_cache_t song_info_cache;
/**
* Internal state used by TPS
*/
struct song_program_state_t state;
/**
* Song Programming is starting.
*
*/
int (*begin)(void);
/**
* A TPS block has been received. Write to nonvolatile storage.
* After writting, it is recommended to read back the data from flash in the tileSongBuffer.
* The reason is TileLib will check the CRC again after this call returns (song_block_done is called).
*
*/
int (*block_ready)(void);
/**
* TPS has completed successfully
*/
int (*complete)(void);
};
/**
* Tile Song module.
*
* This module is used to allow the Tile app to play a song on the device.
*/
struct tile_song_module {
/**
* Play song with given index number with strength from 0-3.
*/
int (*play)(uint8_t number, uint8_t strength, uint8_t duration);
/**
* Stop all songs.
*/
int (*stop)(void);
/**
* Optional TPS Module (set to NULL if not supported).
*/
struct tile_song_tps_module_t* tps_module;
};
/**
* Register the song module.
*/
int tile_song_register(struct tile_song_module *module);
/**
* Call when the song programming begin command has completed.
*
* NOTE: Only required if TPS is supported.
*/
void song_begin_done(uint8_t error);
/**
* Call when the song programming block ready command has completed.
* tileSongBuffer is expected to contain the valid song block data when this function is called.
* The reason is TileLib will check the CRC again in this function.
* This allows the application to implement a read back of the data from flash to verify integrity.
*
* NOTE: Only required if TPS is supported.
*/
void song_block_done(uint8_t error);
/**
* Call when the song programming complete command has completed.
*
* NOTE: Only required if TPS is supported.
*/
void song_complete_done(uint8_t error);
/** @} */
#endif

View File

@@ -0,0 +1,83 @@
/**
* 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_tdg_module.h
** @brief Tile GATT Server Driver interface
*/
#ifndef TILE_TDG_MODULE_H_
#define TILE_TDG_MODULE_H_
#include <stdint.h>
#include "modules/tile_toa_module.h"
/**
* @defgroup tile_tdg Tile Diagnostics module
* @{
* @ingroup TOA
*
* @brief Tile Diagnostics module.
*
* @details This module is used by Tile Lib to send diagnostic information to the Tile
* data collection system. Consult with Tile for the proper format for
* diagnostic data, if it is to be automatically parsed by the Tile backend.
*/
struct tile_tdg_module {
/**
* Retrieve diagnostic information.
*
* This function should call @ref tdg_add_data for each diagnostic data
* field to be added, and then @ref tdg_finish when all data has been added.
*/
int (*get_diagnostics)(void);
uint8_t buffer[TOA_MPS];
uint8_t buffer_pos;
};
/**
* Register the TDG module.
*/
int tile_tdg_register(struct tile_tdg_module *module);
/**
* @brief Add diagnostic data.
* @details Should be called during the call to get_diagnostics.
* This function can be called multiple times, for each piece of diagnostic
* info that is to be added.
*
* @param[in] data Data to add to diagnostics.
* @param[in] length Length of data to add.
*/
int tdg_add_data(void *data, uint8_t length);
/**
* @brief Finish adding diagnostic data.
* @details Should be called during the call to
* get_diagnostics, after all data has been added.
*/
int tdg_finish(void);
/**@}*/
#endif

View File

@@ -0,0 +1,85 @@
/**
* 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_tdi_module.h
** @brief Tile Device Information Module. Provides TileLib Device specific information and unique numbers.
*/
#ifndef TILE_TDI_MODULE_H_
#define TILE_TDI_MODULE_H_
#include <stdint.h>
/**
* Tile Device Information module.
*
* This module is used by Tile Lib to allow the Tile app to read some
* information about the device in order to properly activate and authenticate
* with the device.
*/
struct tile_tdi_module
{
/**
* Tile ID -- 64-bit identifier for Tile Nodes.
* Example: {0x1a, 0x95, 0xd9, 0x97, 0xf0, 0xf2, 0x66, 0x07}.
*/
uint8_t *tile_id;
/**
* BLE MAC address -- 48-bit number. Points to the MAC address advertised Over The Air.
*/
uint8_t *bdaddr;
/**
* Firmware Version -- 10 8-bit ASCII characters (null terminaison accepted but not required)
* Format: "xx.xx.xx.x"
* Example: "02.00.00.0"
*/
char *firmware_version;
/**
* Model Number -- 10 8-bit ASCII characters (null terminaison accepted but not required)
* Format shall follow the following pattern: "XXXX YY.YY" with the following constraints:
* - "XXXX" uses 4 ASCII letters ('A' to 'Z') to describe the Vendor ID.
* - The Vendor ID is assigned by Tile.
* - A space character after "XXXX".
* - "YY.YY" uses 4 ASCII numbers ('0' to '9') and describes the Model ID.
* Example: "TEST 00.00".
*/
char *model_number;
/**
* Hardware Revision -- 5 8-bit ASCII characters (null terminaison accepted but not required)
* The character pattern is "YY.YY" and uses 4 ASCII numbers ('0' to '9').
* Example: "01.00".
*/
char *hardware_version;
/**
* Serial Number -- (TOA_MPS-1) bytes
*/
uint8_t *serial_num;
};
/**
* Register the TDI module with Tile Library.
*/
int tile_tdi_register(struct tile_tdi_module *module);
#endif // TILE_TDI_MODULE_H_

View File

@@ -0,0 +1,133 @@
/**
* NOTICE
*
* Copyright 2017 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_tdt_module.h
** @brief Tile Double Tap module
*/
#ifndef TILE_TDT_MODULE_H_
#define TILE_TDT_MODULE_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define TDT_HDC_IBEACON_DURATION 200 ///< in tens of miliseconds
#define TDT_HDC_ADVERTISING_STEP_DURATION 200 ///< Advertising step in tens of miliseconds
#define TDT_HDC_ADVERTISING_LAST_STEP_DURATION 100 ///< Advertising last step in tens of miliseconds
#define TDT_HDC_IBEACON_INTERVAL 40 ///< in 0.625 milisecond increments
#define TDT_HDC_ADVERTISING_INTERVAL 160 ///< in 0.625 milisecond increments
/**
* @brief TDT Local Config Struct
*/
typedef struct
{
uint16_t SE_LTF:1; ///< [0] Song Enable: LongTap Failure
uint16_t SE_LTS:1; ///< [1] Song Enable: LongTap Success
uint16_t SE_DTF:1; ///< [2] Song Enable: DoubleTap Failure
uint16_t SE_DTS:1; ///< [3] Song Enable: DoubleTap Success
uint16_t SE_STIF:1; ///< [4] Song Enable: SingleTapImmediate Failure
uint16_t SE_STIS:1; ///< [5] Song Enable: SingleTapImmediate Success
uint16_t SE_STDF:1; ///< [6] Song Enable: SingleTapDelayed Failure
uint16_t SE_STDS:1; ///< [7] Song Enable: SingleTapDelayed Success
uint16_t EN_DT:1; ///< [8] Enable: DoubleTap
uint16_t EN_LT:1; ///< [9] Enable: LongTap
uint16_t EN_STI:1; ///< [10] Enable: SingleTapImmediate
uint16_t EN_STD:1; ///< [11] Enable: SingleTapDelayed
uint16_t SS_Strength:2; ///< [12:13] Success Song Strength (0/1: Low; 2: Med; 3: High)
uint16_t FS_Strength:2; ///< [14:15] Fail Song Strength (0/1: Low; 2: Med; 3: High)
uint8_t Delay; ///< DoubleTap and LongTap detection delay: in units of 20 ms, plus an offset of 10ms.
uint8_t NotifDebounceDelay; ///< DoubleTap Notification Debouncing Delay: in units of 100ms. 0 means no debouncing.
} tdt_config_t;
/**
* Tile DoubleTap module.
*
* This module is used by Tile Lib to detect various types of button press.
* Furthermore, this module also supports the "TDT HDC" feature, which is used
* to advertise with a high duty cycle when a double tap is detected.
*/
struct tile_tdt_module
{
/**
* Configuration for TDT. Used internally by Tile Lib.
*/
tdt_config_t config;
/**
* Variables to support optional TDT HDC feature.
*/
uint8_t hdc_status;
/*** Diagnostic information ***/
uint16_t *single_tap;
uint8_t *long_tap;
uint16_t *double_tap_detect;
uint16_t *double_tap_notify;
uint16_t *double_tap_failure2;
/**
* Configuration was written by the app. Should be stored to NVM.
*/
int (*config_written)(tdt_config_t *config);
/**
* Called when a double tap is detected and the Tile should move into
* high duty cycle advertising.
*/
void (*hdc_cb)(void);
};
/**
* TDT_HDC_STATUS.
*
* Used by the TDT HDC optional feature (see @ref tile_tdt_module).
*/
enum TDT_HDC_STATUS
{
TDT_HDC_STATUS_NORMAL = 0x00, // Default state, Nothing special
TDT_HDC_STATUS_IBEACON = 0x01, // Advertise iBeacon
TDT_HDC_STATUS_FAST_ADV = 0x02, // Advertise fast
TDT_HDC_STATUS_FAST_ADV2 = 0x03, // Advertise fast
TDT_HDC_STATUS_FAST_ADV3 = 0x04, // Advertise fast
TDT_HDC_STATUS_FAST_ADV4 = 0x05, // Advertise fast
TDT_HDC_STATUS_FAST_ADV5 = 0x06, // Advertise fast
TDT_HDC_STATUS_NOTIFY = 0x07, // Send a TDT notification
};
/**
* Register TDT module
*/
int tile_tdt_register(struct tile_tdt_module *module);
#ifdef __cplusplus
}
#endif
#endif // TILE_TDT_MODULE_H_

View File

@@ -0,0 +1,52 @@
/**
* 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_test_module.h
** @brief Receive TEST commands over TOA
*/
#ifndef TILE_TEST_MODULE_H_
#define TILE_TEST_MODULE_H_
#include <stdint.h>
/**
* @brief All TEST commands/responses through this module will need a code
* greater than @ref TILE_TEST_MODULE_CODE_BASE.
*/
#define TILE_TEST_MODULE_CODE_BASE 0x80
struct tile_test_module
{
/**
* @brief Receive a TEST message
*/
int (*process)(uint8_t code, uint8_t *message, uint8_t length);
};
int tile_test_register(struct tile_test_module *module);
int tile_test_response(uint8_t code, uint8_t *response, uint8_t length);
#endif

View File

@@ -0,0 +1,73 @@
/**
* 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_tmd_module.h
** @brief Tile Mode module interface. Controls Tile Mode.
*/
#ifndef TILE_TMD_MODULE_H_
#define TILE_TMD_MODULE_H_
#include <stdint.h>
/** \defgroup TMD Tile mode
* \ingroup TOA
* @{
*/
/**
* @brief TILE_MODE <br>
*/
enum TILE_MODE
{
TILE_MODE_MANUFACTURING = 0x0,
TILE_MODE_SHIPPING = 0x1,
TILE_MODE_ACTIVATED = 0x2
};
/** @} */
/**
* Tile Mode module.
*
* This module is used by Tile Lib to get and set the mode.
*/
struct tile_tmd_module
{
/**
* Get the current mode
*/
int (*get)(uint8_t *mode);
/**
* Set the mode. Value should be saved in NVM.
*/
int (*set)(uint8_t mode);
};
/**
* Register the TMD module
*/
int tile_tmd_register(struct tile_tmd_module *module);
#endif

View File

@@ -0,0 +1,334 @@
/**
* 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_toa_module.h
** @brief Tile Over-the-air API module
*/
#ifndef TILE_TOA_MODULE_H_
#define TILE_TOA_MODULE_H_
#include <stdint.h>
#include <stdbool.h>
/**
* @defgroup toa_module Tile Over-the-air API module
* @{
* @ingroup TOA
*/
/**
* @brief TOA Max Payload Size.
* This is the maximum Payload that can be carried by a TOA Command or Response.
* It excludes the TOA_CMD/TOA_RSP Code and excludes the MIC.
*/
#define TOA_MPS 14
#define TILE_SESSION_KEY_LEN 16
/**
* Session information for a TOA channel
*/
struct toa_channel_tag
{
uint8_t session_key[TILE_SESSION_KEY_LEN];
uint32_t nonceA;
uint32_t nonceT;
uint16_t state;
uint16_t check_delay;
uint16_t ack_delay;
};
typedef struct toa_channel_tag toa_channel_t; //!< Structure containing session information for a TOA channel
/**
* Tile Over-the-air API module.
*
* This module is used by Tile Lib in order to implement its over-the-air
* protocol.
*/
struct tile_toa_module
{
/**
* Tile ID -- 64-bit identifier for Tile Nodes.
* Example: {0x1a, 0x95, 0xd9, 0x97, 0xf0, 0xf2, 0x66, 0x07}.
*/
uint8_t* tile_id;
/**
* Auth Key -- 128-bit master key for Tile Nodes.
* Example: {0x14, 0x27, 0xe3, 0x03, 0xa2, 0x51, 0xc5, 0xb5, 0x07, 0x2a, 0xa9, 0x81, 0xa9, 0x42, 0x8a, 0x43}.
*/
uint8_t* auth_key;
/**
* Pointer to an array of @ref toa_channel_t structures. It is recommended
* to use 4 channels, but if memory is a constraint then the number can be
* decreased.
*/
toa_channel_t* channels;
/**
* Pointer to a buffer for queueing TOA messages.
*/
uint8_t* queue;
/**
* Size of buffer used for TOA queue. Recommended to be at least size
* 100 for one channel, and add 40 for each additional channel.
*/
uint16_t queue_size;
/**
* Number of channels contained in the channels array.
*/
uint8_t num_channels;
/**
* Diagnostic info: counts the mic failures
*/
uint8_t* mic_failure_count;
/**
* Diagnostic info: counts the authentication failures
*/
uint8_t* auth_failure_count;
/**
* Diagnostic info: counts the Number of successfull TOA Channel Open (with a successfull authentication)
*/
uint32_t* channel_open_count;
/**
* Diagnostic info: counts the number of TOA Authenticate Commands received
*/
uint32_t* authenticate_count;
/**
* Diagnostic info: counts the number of TOA channel close triggered by TKA
*/
uint16_t* tka_closed_channel_count;
/**
* Send a TOA Response.
* @param[in] data: Pointer to the TOA Response.
* @param[in] len: Length of the TOA Response.
*/
int (*send_response)(uint8_t *data, uint16_t len);
/**
* Optional callback called when an association is happenning (can be set to NULL).
* It is mostly needed for Commissioning Tiles using an Interim TileID, Key.
*
* @param[in] tile_id: 8-byte unique tile identification code.
* @param[in] tile_auth_key: 16-byte authentication key.
* @param[in] authorization_type: Pointer to authorization type.
*
* @param[out] authorization_type: set to the right value if an authorization is required (ie 1 for Button Press).
*
* @return See @ref TILE_ERROR_CODES.
*/
int (*associate)(uint8_t* tile_id, uint8_t* tile_auth_key, uint8_t* authorization_type);
};
/** \ingroup TOA
* @brief TOA feature error codes. Any feature which uses these error
* codes will return the error in a standard format. This format is:
*
* TOA Response | Error Response | Offending Command | Error Code | Additional Payload
* -------------|----------------|-------------------|------------|-------------------
* 1 Byte | 1 Byte | 1 Byte | 1 Byte | Varies. Up to TOA_MPS - 4 bytes.
*
* Example 1: Say a TOFU_CTL_CMD_RESUME command is sent at a bad time. Then, the Tile would
* respond with
* TOA_RSP_TOFU_CTL | TOFU_CTL_RSP_ERROR | TOFU_CTL_CMD_RESUME | TOA_ERROR_INVALID_STATE
* ------------------|----------------|---------------------|--------------------
* 1 Byte | 1 Byte | 1 Byte | 1 Byte
*
*/
enum TOA_FEATURE_ERROR_CODES
{
TOA_ERROR_OK = 0x00,
/**< This code is used when there's no error */
TOA_ERROR_UNSUPPORTED = 0x01,
/**< This code is used when the given command is not supported */
TOA_ERROR_PARAMETERS = 0x02,
/**< This code is used when the parameters to the command are invalid */
TOA_ERROR_SECURITY = 0x03,
/**< This code is used when the app has insufficient security privileges
* to execute the given command */
TOA_ERROR_INVALID_STATE = 0x04,
/**< This code is used when the given command cannot be executed in
* the current state of the Tile */
TOA_ERROR_MEM_READ = 0x05,
/**< This code is used when a memory read fail */
TOA_ERROR_MEM_WRITE = 0x06,
/**< This code is used when a memory write fails */
TOA_ERROR_DATA_LENGTH = 0x07,
/**< This code is used when a received data block is not the expected size */
TOA_ERROR_INVALID_SIZE = 0x08,
/**< This code is used when the app requests to write data of inappropriate size */
TOA_ERROR_SIGNATURE = 0x09,
/**< This code is used when a signature check fails */
TOA_ERROR_CRC = 0x0A,
/**< This code is used when a CRC check fails */
TOA_ERROR_CRC2 = 0x0B,
/**< This code is used when there are multiple CRC checks */
TOA_ERROR_HASH = 0x0C,
/**< This code is used when a hash check fails */
TOA_ERROR_PRODUCT_HEADER = 0x0D,
/**< This code is used when the product header is invalid. If this happens,
* the Tile is in a very bad state. */
TOA_ERROR_IMAGE_HEADER = 0x0E,
/**< This code is used when a received image header is invalid */
TOA_ERROR_SAME_IMAGE = 0x0F,
/**< This code is used when the image to send matches the image already on the Tile */
TOA_ERROR_INVALID_DATA = 0x10,
/**< This code is used when the data sent to the Tile is invalid */
TOA_ERROR_MEM_ERASE = 0x11,
/**< This code is used when a memory erase fails */
TOA_ERROR_RESOURCE_IN_USE = 0x12,
/**< This code is used when there is an attempt to access a resource in use by someone else */
};
/** \ingroup TOA
* @brief TOA Error Response Codes
*/
enum TOA_ERROR_CODES
{
TOA_RSP_ERROR_SECURITY = 0x01,
/**< Error Code sent by TOA Server when required security level for the command is not met (like authentication)
Format:
@ref TOA_RSP_ERROR_SECURITY Code | The TOA_CMD that failed
---------------------------------|-----------------------------
1 Byte | 1 Byte
*/
TOA_RSP_ERROR_UNSUPPORTED = 0x02,
/**< Error Code sent by TOA Server when an unsupported TOA Command is received
Format:
@ref TOA_RSP_ERROR_UNSUPPORTED Code | The TOA_CMD that failed
------------------------------------|-----------------------------
1 Byte | 1 Byte
*/
TOA_RSP_ERROR_PARAMETERS = 0x03,
/**< Error Code sent by TOA Server when a TOA Command with wrong parameters is received
Format:
@ref TOA_RSP_ERROR_PARAMETERS Code | The TOA_CMD that failed
-----------------------------------|------------------------------
1 Byte | 1 Byte
*/
TOA_RSP_ERROR_DROPPED_RSP = 0x04,
/**< Error Code sent by TOA Server when 1 or more Responses were dropped, most likely due to an overflow.<br>
The Client should close the connection when this happens.
Format:
@ref TOA_RSP_ERROR_DROPPED_RSP Code | The first TOA_RSP that was dropped
-------------------------------------|----------------------------------------
1 Byte | 1 Byte
*/
TOA_RSP_ERROR_NO_CID_AVAILABLE = 0x05,
/**< Error Code sent by a TOA Server when there are no CIDs available for allocation.
Format:
@ref TOA_RSP_ERROR_NO_CID_AVAILABLE | TOA_CMD_OPEN_CHANNEL
------------------------------------|--------------------------
1 Byte | 1 Byte
*/
TOA_RSP_ERROR_AUTHORIZATION = 0x06,
/**< Error Code sent by a TOA Server when the required authorization level for the command is not met
Format:
@ref TOA_RSP_ERROR_AUTHORIZATION Code | The TOA_CMD that failed | The required Authorization Type
--------------------------------------|------------------------------|--------------------------------
1 Byte | 1 Byte | 1 Byte (value 1 for Button Press)
*/
TOA_RSP_SERVICE_UNAVAILABLE = 0x07,
/**< Error Code sent by a TOA Server when the required service is unavailable (i.e. user trigger)
Format:
@ref TOA_RSP_SERVICE_UNAVAILABLE Code | The TOA_CMD that failed
--------------------------------------|-----------------------------
1 Byte | 1 Byte
*/
};
/**
* Register TOA module.
*/
int tile_toa_register(struct tile_toa_module *module);
/**
****************************************************************************************
* @brief The underlying TOA transport is ready.
* This is the case when TOA_RSP channel was enabled for notifications or indications.
*
* @param[in] ready 1 for ready, 0 for not ready.
*
****************************************************************************************
*/
void tile_toa_transport_ready(bool ready);
/**
****************************************************************************************
* @brief A TOA response was successfully sent to the TOA Client (and an other one can be sent).
*
****************************************************************************************
*/
void tile_toa_response_sent_ok(void);
/**
****************************************************************************************
* @brief An TOA Commands was received.
*
* @param[in] data pointer to data.
* @param[in] datalen number of bytes of data.
*
****************************************************************************************
*/
void tile_toa_command_received(const uint8_t* data, uint8_t datalen);
/**
****************************************************************************************
* @brief Send an Authorized Notification.
*
* @param[in] authorization_type The type of authorization (ie Button press).
* @param[in] authorization_time The time for which the authorization is valid.
*
****************************************************************************************
*/
int tile_toa_authorized(uint8_t authorization_type, uint16_t authorization_time);
/** @} */
#endif

View File

@@ -0,0 +1,81 @@
/**
* 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_tpi_module.h
** @brief Tile Private Identification API module
*/
#ifndef TILE_TPI_MODULE_H_
#define TILE_TPI_MODULE_H_
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Tile TPI API module.
*
* This module is used by Tile Lib in order to implement PrivateID
*/
struct tile_tpi_module
{
/**
* tileID_counter, Maintained by TileLib and persistently stored by the Application at each update.
*/
uint16_t* tileID_counter;
/**
* Tile Identity Key. Saved by the Application in persistent memory when the key is refreshed.
* 16 bytes.
*/
uint8_t* tileID_key;
/**
* Hashed TileID, Created by TileLib and to be accessed and used by the Application to advertise.
* 8 bytes.
*/
uint8_t* hashed_tileID;
/**
* The tileID_counter was incremented and its new value shall be saved into flash by the application.
* Also, Advertising Data need to be updated with the new hashed_tileID.
*/
int (*tileID_counter_updated)(void);
};
/**
****************************************************************************************
* @brief Register TPI Module.
*
* @param[in] module Pointer to the TPI Module struct.
*
****************************************************************************************
*/
int tile_tpi_register(struct tile_tpi_module *module);
#ifdef __cplusplus
}
#endif
#endif // TILE_TPI_MODULE_H_

125
external/tile/tile_lib/tile_lib.h vendored Normal file
View File

@@ -0,0 +1,125 @@
/**
* 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
*/
#ifndef TILE_LIB_H_
#define TILE_LIB_H_
/** @defgroup tile_lib Tile Library API
* @{
* @ingroup TOA
* @brief Tile Library Api
*/
/**
* @brief Tile Service UUIDs.
* These are 16-bit UUIDs.
*/
#define TILE_SHIPPING_UUID 0xFEEC /** Advertised by Tiles in Shipping Mode. */
#define TILE_ACTIVATED_UUID 0xFEED /** Advertised by Tiles in Activated Mode. */
#define TILE_SERVICE_UUID TILE_ACTIVATED_UUID /** Used to declare Tile Gatt Service. */
#define TILE_SVC_BASE_UUID { 0xC0, 0x91, 0xC4, 0x8D, 0xBD, 0xE7, 0x60, 0xBA, 0xDD, 0xF4, 0xD6, 0x35, 0x00, 0x00, 0x41, 0x9D }
#define TILE_TOA_CMD_UUID { 0xC0, 0x91, 0xC4, 0x8D, 0xBD, 0xE7, 0x60, 0xBA, 0xDD, 0xF4, 0xD6, 0x35, 0x18, 0x00, 0x41, 0x9D }
#define TILE_TOA_RSP_UUID { 0xC0, 0x91, 0xC4, 0x8D, 0xBD, 0xE7, 0x60, 0xBA, 0xDD, 0xF4, 0xD6, 0x35, 0x19, 0x00, 0x41, 0x9D }
#define TILE_TILEID_CHAR_UUID { 0xC0, 0x91, 0xC4, 0x8D, 0xBD, 0xE7, 0x60, 0xBA, 0xDD, 0xF4, 0xD6, 0x35, 0x07, 0x00, 0x41, 0x9D }
#define TILE_DEFAULT_ADV_INT_ACTIVATED 3200 // In 0.625 ms Units
#define TILE_DEFAULT_ADV_INT_SHIPPING 160 // In 0.625 ms Units
/**
* TOA Command and Response characteristics lengths in octets.
*/
#define TILE_TOA_CMD_CHAR_LEN 20
#define TILE_TOA_RSP_CHAR_LEN 20
/**
* Attribute ID's associated with each Tile attribute.
*/
enum TILE_CHARACTERISTICS
{
TILE_TOA_CMD_CHAR,
TILE_TOA_RSP_CHAR,
TILE_TOA_RSP_CCCD,
TILE_ID_CHAR,
TILE_NUM_ATTRS
};
/**
* Length, in bytes, of the Tile ID.
*/
#define TILE_ID_LEN 8
/**
* Length, in bytes, of the hashed_tileID.
*/
#define TILE_HASHED_TILEID_LEN 8
/**
* Length, in bytes, of the Tile authentication key.
*/
#define TILE_AUTH_KEY_LEN 16
/**
* Length, in bytes, of the Tile identity key.
*/
#define TILEID_KEY_LEN 16
/**
* Length of the Tile firmware version string.
*/
#define TILE_FIRMWARE_VERSION_LEN 10
/**
* Length of the Tile model number string.
*/
#define TILE_MODEL_NUMBER_LEN 10
/**
* Length of the Tile hardware version string.
*/
#define TILE_HARDWARE_VERSION_LEN 5
/**
* Length of the Tile BDADDR.
*/
#define TILE_BDADDR_LEN 6
#define TILE_SERVICE_DATA_MAX_LENGTH 10
/**
* @brief Error codes returned by Tile Lib functions
*/
enum TILE_ERROR_CODES
{
TILE_ERROR_SUCCESS = 0,
TILE_ERROR_NOT_INITIALIZED,
TILE_ERROR_ILLEGAL_SERVICE,
TILE_ERROR_ILLEGAL_PARAM,
TILE_ERROR_ILLEGAL_OPERATION,
TILE_ERROR_BUFFER_TOO_SMALL,
TILE_ERROR_TERMINAL,
TILE_ERROR_REENTRANCY,
TILE_ERROR_NUM_TOA_CHANNELS,
};
/**@}*/
#endif

BIN
external/tile/tile_lib/tile_lib.lib vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,46 @@
/**
* 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_assert.h
** @brief Define a standard Tile assert interface
*/
#include "sdk_common.h"
#if NRF_MODULE_ENABLED(TILE_SUPPORT)
#include "tile_assert.h"
#include "app_util_platform.h"
#include "nrf_log.h"
#include "nrf_nvic.h"
/* @brief Tile Assert Interface
* @details Reset the MCU
*/
void tile_assert(bool cond, uint32_t line, const char file[], const char func[], bool ignore)
{
if(!cond)
{
NRF_LOG_WARNING("System reset");
NRF_BREAKPOINT_COND;
(void) sd_nvic_SystemReset();
}
}
#endif // NRF_MODULE_ENABLED(TILE_SUPPORT)

View File

@@ -0,0 +1,37 @@
/**
* 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_assert.h
** @brief Define a standard Tile assert interface
*/
#ifndef TILE_ASSERT_H_
#define TILE_ASSERT_H_
#include <stdint.h>
#include <stdbool.h>
void tile_assert(bool cond, uint32_t line, const char file[], const char func[], bool ignore);
#define TILE_ASSERT(cond) tile_assert(cond, __LINE__, __FILE__, __func__, false)
#define TILE_ASSERT_IGNORE(cond) tile_assert(cond, __LINE__, __FILE__, __func__, true)
#endif

View File

@@ -0,0 +1,144 @@
/**
* 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_bdaddr.c
** @brief
** Use part of TileId, modified to make it Public Random Mac Addr compatible, is used as BdAddr
** FYI on BLE Mac Address Types : https://devzone.nordicsemi.com/f/nordic-q-a/27012/how-to-distinguish-between-random-and-public-gap-addresses
*/
/*******************************************************************************
* Includes
******************************************************************************/
#include "sdk_common.h"
#if NRF_MODULE_ENABLED(TILE_SUPPORT)
#include "tile_bdaddr.h"
#include "tile_assert/tile_assert.h"
#include "tile_storage/tile_storage.h"
#include "tile_config.h"
#include "tile_tmd_module.h"
#include "tile_toa_module.h"
#include "nrf_log.h"
#include "ble_gap.h"
/*******************************************************************************
* Macro Definitions
******************************************************************************/
/*******************************************************************************
* Global variables
******************************************************************************/
/* @brief Should contain currently used MacAddr value
* Used to assign to member of tdi_module
*/
uint8_t bdaddr[BLE_GAP_ADDR_LEN];
/* @brief Used when switching from Act->Manu or Shipping->Manu before a reboot
* Contains default MacAddr value provided by Nordic FICR register
* No need to save in Flash
*/
uint8_t default_bdaddr[BLE_GAP_ADDR_LEN];
/***********************************************************************
* Local functions
***********************************************************************/
/***********************************************************************
* Global functions
***********************************************************************/
/**
* @brief Update destination bdaddr from source bdaddr array
*/
void update_default_bdaddr(uint8_t* dest_bdaddr, uint8_t* source_bdaddr)
{
/* Select new Addr Value */
for(uint8_t i=0; i<BLE_GAP_ADDR_LEN; i++)
{
dest_bdaddr[i] = source_bdaddr[BLE_GAP_ADDR_LEN-1-i];
}
}
/**
* @brief Update MacAddr value from first 6 bytes of TileId
* We need to use Nordic Set API to update the value used in advertising
*/
void set_tileid_macAddr(void)
{
NRF_LOG_INFO("set_tileid_macAddr\n");
/********** Update MacAddr used while advertising using Nordic API ************/
ble_gap_addr_t addr;
/* Select new Addr Type */
addr.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC;
/* Select new Addr Value from Tile Id */
update_default_bdaddr(addr.addr, tile_checked->tile_id);
/* Make it RANDOM STATIC to match addr_type, by setting first 2 bits high, else set function will return error */
addr.addr[BLE_GAP_ADDR_LEN-1] |= 0xC0;
/* Need to set the updated Mac Addr using API, so that ble_advdata_encode() can use the updated value
* sd_ble_gap_addr_get() will now start returning updated value, till a power cycle
* At boot, sd_ble_gap_addr_get() will return default value again
*/
(void) sd_ble_gap_addr_set(&addr);
/************ Update Internal bdaddr value, used by tdi module *************/
update_default_bdaddr(bdaddr, addr.addr);
/****************************************************************************/
}
/**
* @brief Obtain default Mac Address from FICR register
*/
void get_default_macAddr(void)
{
/* Obtain Default MacAddr from FICR register */
ble_gap_addr_t addr;
(void) sd_ble_gap_addr_get(&addr);
/* Store value in global variable */
update_default_bdaddr(default_bdaddr, addr.addr);
/* Update Internal bdaddr value, used by tdi module */
for(uint8_t i=0; i<BLE_GAP_ADDR_LEN; i++)
{
bdaddr[i] = default_bdaddr[i];
}
}
/**
* @brief Set the Mac Address to be used internally by tdi module and to be used for Advertising
* Select this based on the MacAddress Mechanism configured for that Product, and based on the Tile mode
*/
void set_new_macAddr(void)
{
set_tileid_macAddr();
}
#endif // NRF_MODULE_ENABLED(TILE_SUPPORT)

View File

@@ -0,0 +1,34 @@
/**
* NOTICE
*
* Copyright 2017 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_bdaddr.h
** @brief Contains APIs to decide BdAddr to be used
*/
#ifndef TILE_BDADDR_H_
#define TILE_BDADDR_H_
#include <stdint.h>
#include <stdbool.h>
void get_default_macAddr(void);
void set_new_macAddr(void);
#endif

99
external/tile/tile_shim/tile_config.h vendored Normal file
View File

@@ -0,0 +1,99 @@
/**
* 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_config.h
** @brief Configuration for Tile functionality
*/
#ifndef TILE_CONFIG_H_
#define TILE_CONFIG_H_
/* You need valid Tile Node Credentials [interim_tile_id, interim_tile_key] in order to access Tile Network.
* Without valid Tile Node credentials, your prototype will not interoperate with the Tile Network or Tile Mobile Application.
* Follow this link to get Tile Node credentials for your prototype: https://www.thetileapp.com/en-us/platform-business-solutions
* Then fill interim_tile_id and interim_tile_key with the numbers provided to you by Tile and comment out the warning.
*/
#define INTERIM_TILE_ID {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#define INTERIM_AUTH_KEY {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#if !defined(INTERIM_TILE_ID) && !defined(INTERIM_AUTH_KEY)
#warning Did you get your Tile Node credentials from Tile?
#endif // !defined(INTERIM_TILE_ID) && !defined(INTERIM_AUTH_KEY)
/* Model Number Format shall follow the following pattern: "XXXX YY.YY" with the following constraints:
* - "XXXX" uses 4 ASCII letters ('A' to 'Z') to describe the Vendor ID.
* - The Vendor ID is assigned by Tile. Contact firmware_support@tile.com if you don't have one (required before Mass Production).
* - A space character after "XXXX".
* - "YY.YY" uses 4 ASCII numbers ('0' to '9') and describes the Model ID.
* Example: "TEST 00.00".
*/
#define TILE_MODEL_NUMBER "TEST 02.00"
/* HW Version character pattern is "YY.YY" and uses 4 ASCII numbers ('0' to '9').
* Example: "01.00".
* You are free to use any number that is convenient for your product, providing it satisfies the character pattern.
*/
#define TILE_HARDWARE_VERSION "00.01"
/* Firmware Version format shall follow the following pattern: "AA.BB.CC.D"
* - "AA" Firmware Compatibility Number. For a given number, all Firmware binaries are considered compatible.
* This means the CPU is the same and the HW is compatible.
* - "BB" TileLib Version. For a given version, TileLib API compatibility is maintained.
* - "CC" Build Version. This number is incremented for each build.
* - "D" Reserved
*/
#define TILE_FIRMWARE_VERSION "01.04.00.0"
#define TILE_DEFAULT_MODE TILE_MODE_SHIPPING
#define TILE_ENABLE_PLAYER 1
/* Button used for reverse ring. */
/* Also for wakeup when in shipping mode, if sleep is implemented (not implemented in example project) */
#define TILE_BUTTON BUTTON_2
/**
* @brief Number of TOA channels supported
*/
#define NUM_TOA_CHANNELS 3
/**
* @brief Diagnostic Version
*/
#define DIAGNOSTIC_VERSION 80
#define DEFAULT_TDT_CONFIG (tdt_config_t) { \
.Delay = 45, \
.EN_DT = true, \
.EN_STI = true, \
.SE_DTF = true, \
.SE_DTS = true, \
.FS_Strength = 1, \
.SS_Strength = 1, \
}
/**
* @brief Size of the TOA message buffer
*/
#define TOA_QUEUE_BUFFER_SIZE (100 + 40 * (NUM_TOA_CHANNELS - 1))
#endif

View File

@@ -0,0 +1,649 @@
/**
* 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)

View File

@@ -0,0 +1,78 @@
/**
* 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.h
* @brief Support for features in Tile Lib
*/
#ifndef TILE_FEATURES_H_
#define TILE_FEATURES_H_
#include "app_timer.h"
#include "tile_gatt_db/tile_gatt_db.h"
#include "drivers/tile_timer_driver.h"
#include "modules/tile_test_module.h"
typedef struct
{
tile_gatt_db_t service;
uint16_t conn_handle;
} tile_ble_env_t;
enum CUSTOM_EVENTS
{
NOTIFICATION_WRITTEN_EVT
};
struct my_evt
{
uint8_t type;
};
enum TILE_APP_TEST_CMDS
{
TEST_CMD_REBOOT = TILE_TEST_MODULE_CODE_BASE,
TEST_CMD_STORAGE,
};
/**
* @brief Types of reboots which can be triggered by \ref TEST_CMD_REBOOT
*/
enum TEST_REBOOT
{
TEST_CMD_REBOOT_RESET = 0x00,
TEST_CMD_REBOOT_WATCHDOG = 0x01,
TEST_CMD_REBOOT_MEMORY_FAULT = 0x02,
TEST_CMD_REBOOT_OTHER = 0x03,
TEST_CMD_REBOOT_ASSERT = 0x04,
TEST_CMD_REBOOT_DURING_FLASH = 0x05,
};
extern tile_ble_env_t tile_ble_env;
extern app_timer_id_t tile_timer_id[TILE_MAX_TIMERS];
void tile_features_init(void);
void tile_button_was_pressed(void);
int tile_read_button_state(uint8_t *button_state);
void tile_update_tileID_char(void);
#endif

View File

@@ -0,0 +1,203 @@
/**
* 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_gatt_db.c
* @brief Set up the Tile GATT service
*/
#include "sdk_common.h"
#if NRF_MODULE_ENABLED(TILE_SUPPORT)
#include "tile_gatt_db.h"
#include "app_error.h"
#include "ble.h"
#include "tile_lib.h"
#include <stdint.h>
uint16_t tile_get_adv_uuid(void);
/**
* @brief Initialize Tile GATT database
*
* @param[out] p_service Service structure. Will be populated with handles.
*/
void tile_gatt_db_init(tile_gatt_db_t *p_service)
{
uint32_t err_code;
/* Add Tile service */
ble_uuid_t ble_uuid;
BLE_UUID_BLE_ASSIGN(ble_uuid, TILE_ACTIVATED_UUID);
/* Add Tile base UUID */
uint8_t ble_type;
ble_uuid128_t base_uuid = TILE_SVC_BASE_UUID;
err_code = sd_ble_uuid_vs_add(&base_uuid, &ble_type);
APP_ERROR_CHECK(err_code);
err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_service->service_handle);
APP_ERROR_CHECK(err_code);
/**************************
* Tile ID characteristic *
**************************/
ble_uuid_t tile_id_uuid =
{
.uuid = 0x0007,
.type = ble_type
};
ble_gatts_char_md_t tile_id_char_md =
{
.char_props =
{
.read = 1, /* Tile ID is read only */
}
};
ble_gatts_attr_md_t tile_id_attr_md =
{
.read_perm = {1,1}, /* Sec mode open */
.vloc = BLE_GATTS_VLOC_STACK /* Allocate the value in the SoftDevice */
};
uint8_t id[8] = {0};
ble_gatts_attr_t tile_id_value =
{
.p_uuid = &tile_id_uuid, /* Tile ID UUID */
.p_attr_md = &tile_id_attr_md, /* Attribute metadata */
.init_len = TILE_ID_LEN, /* Initial length */
.init_offs = 0, /* No offset */
.max_len = TILE_ID_LEN, /* Maximum length */
.p_value = id /* Zero array as initial value */
};
ble_gatts_char_handles_t char_handles;
err_code = sd_ble_gatts_characteristic_add(p_service->service_handle,
&tile_id_char_md,
&tile_id_value,
&char_handles);
APP_ERROR_CHECK(err_code);
/* Save handle */
p_service->characteristic_handles[TILE_ID_CHAR] = char_handles.value_handle;
/**************************
* TOA CMD characteristic *
**************************/
ble_uuid_t toa_cmd_uuid =
{
.uuid = 0x18,
.type = ble_type
};
ble_gatts_char_md_t toa_cmd_char_md =
{
.char_props =
{
.write_wo_resp = 1, /* TOA CMD is write w/o response */
}
};
ble_gatts_attr_md_t toa_cmd_attr_md =
{
.write_perm = {1,1}, /* Sec mode open */
.vlen = 1, /* This is a variable length attribute */
.vloc = BLE_GATTS_VLOC_STACK /* Allocate the value in the SoftDevice */
};
ble_gatts_attr_t toa_cmd_value =
{
.p_uuid = &toa_cmd_uuid, /* TOA CMD UUID */
.p_attr_md = &toa_cmd_attr_md, /* Attribute metadata */
.init_len = 0, /* Initially zero length */
.init_offs = 0, /* No offset */
.max_len = TILE_TOA_CMD_CHAR_LEN, /* Maximum length */
.p_value = NULL /* No initial value */
};
err_code = sd_ble_gatts_characteristic_add(p_service->service_handle,
&toa_cmd_char_md,
&toa_cmd_value,
&char_handles);
APP_ERROR_CHECK(err_code);
/* Save value handle */
p_service->characteristic_handles[TILE_TOA_CMD_CHAR] = char_handles.value_handle;
/**************************
* TOA RSP characteristic *
**************************/
ble_uuid_t toa_rsp_uuid =
{
.uuid = 0x19,
.type = ble_type
};
ble_gatts_attr_md_t toa_rsp_cccd_md =
{
.read_perm = {1,1}, /* Sec mode open */
.write_perm = {1,1}, /* Sec mode open */
.vloc = BLE_GATTS_VLOC_STACK /* Value stored in SoftDevice */
};
ble_gatts_char_md_t toa_rsp_char_md = {
.char_props =
{
.notify = 1, /* TOA RSP uses notifications */
},
.p_cccd_md = &toa_rsp_cccd_md
};
ble_gatts_attr_md_t toa_rsp_attr_md =
{
.read_perm = {1,1}, /* Sec mode open */
.vlen = 1, /* Variable length attribute */
.vloc = BLE_GATTS_VLOC_STACK /* Value stored in SoftDevice */
};
ble_gatts_attr_t toa_rsp_value =
{
.p_uuid = &toa_rsp_uuid, /* TOA RSP UUID */
.p_attr_md = &toa_rsp_attr_md, /* Attribute metadata */
.init_len = 0, /* Initially zero length */
.init_offs = 0, /* No offset */
.max_len = TILE_TOA_CMD_CHAR_LEN, /* Maximum length */
.p_value = NULL /* No initial value */
};
err_code = sd_ble_gatts_characteristic_add(p_service->service_handle,
&toa_rsp_char_md,
&toa_rsp_value,
&char_handles);
APP_ERROR_CHECK(err_code);
p_service->characteristic_handles[TILE_TOA_RSP_CHAR] = char_handles.value_handle;
p_service->characteristic_handles[TILE_TOA_RSP_CCCD] = char_handles.cccd_handle;
}
#endif // NRF_MODULE_ENABLED(TILE_SUPPORT)

View File

@@ -0,0 +1,41 @@
/**
* 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_service.h
* @brief Set up the Tile service
*/
#ifndef TILE_GATT_DB_H_
#define TILE_GATT_DB_H_
#include <stdint.h>
#include "tile_lib.h"
typedef struct
{
uint16_t service_handle;
uint16_t characteristic_handles[TILE_NUM_ATTRS];
} tile_gatt_db_t;
void tile_gatt_db_init(tile_gatt_db_t *p_service);
#endif

View File

@@ -0,0 +1,624 @@
/**
* NOTICE
*
* Copyright 2019 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_player.c
* @brief Tile player for Nordic Platform
*/
#include "sdk_common.h"
#if NRF_MODULE_ENABLED(TILE_SUPPORT)
#include "tile_config.h"
#include "tile_lib.h"
uint8_t g_FindActivate_SongPlayed = 0;
#if TILE_ENABLE_PLAYER
#include <stdint.h>
#include <stdbool.h>
#include "tile_player.h"
#include "tile_storage/tile_storage.h"
#include "tile_service/tile_service.h"
#include "tile_features/tile_features.h"
#include "app_timer.h"
#include "nrf_drv_gpiote.h"
#include "nrf_drv_timer.h"
#include "nrf_drv_ppi.h"
#include "nrfx_ppi.h"
#include "nrf_log.h"
static nrf_ppi_channel_t ppi_channel1;
uint32_t compare_evt_addr1;
uint32_t gpiote_task_addr1;
/* Set PIN_PIEZO for toggle on timer event */
nrf_drv_gpiote_out_config_t config1 = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false);
/* Convert a frequency into number of microseconds for a half-pulse */
#define CONV(n) (1000000 / (n) / 2)
uint8_t g_inbetween = 0;
/* Some defines for accessing the note array properly */
#define NOTE_ARRAY_BASE_NOTE (C3)
#define NOTE_ARRAY_MAX_NOTE (B8)
#define NOTE_ARRAY_INDEX(n) ((int) (n) - NOTE_ARRAY_BASE_NOTE)
/* Values for setting the PWM to the correct frequency for each note.
* For our implementation, we only store the notes useful to us, which
* is the range from C3 to B8 */
static const uint16_t notes[] = {
[NOTE_ARRAY_INDEX(C3)] = CONV(131),
[NOTE_ARRAY_INDEX(CS3)] = CONV(138),
[NOTE_ARRAY_INDEX(D3)] = CONV(147),
[NOTE_ARRAY_INDEX(DS3)] = CONV(156),
[NOTE_ARRAY_INDEX(E3)] = CONV(165),
[NOTE_ARRAY_INDEX(F3)] = CONV(175),
[NOTE_ARRAY_INDEX(FS3)] = CONV(185),
[NOTE_ARRAY_INDEX(G3)] = CONV(196),
[NOTE_ARRAY_INDEX(GS3)] = CONV(208),
[NOTE_ARRAY_INDEX(A3)] = CONV(220),
[NOTE_ARRAY_INDEX(AS3)] = CONV(233),
[NOTE_ARRAY_INDEX(B3)] = CONV(247),
[NOTE_ARRAY_INDEX(C4)] = CONV(262),
[NOTE_ARRAY_INDEX(CS4)] = CONV(277),
[NOTE_ARRAY_INDEX(D4)] = CONV(294),
[NOTE_ARRAY_INDEX(DS4)] = CONV(311),
[NOTE_ARRAY_INDEX(E4)] = CONV(330),
[NOTE_ARRAY_INDEX(F4)] = CONV(349),
[NOTE_ARRAY_INDEX(FS4)] = CONV(370),
[NOTE_ARRAY_INDEX(G4)] = CONV(392),
[NOTE_ARRAY_INDEX(GS4)] = CONV(415),
[NOTE_ARRAY_INDEX(A4)] = CONV(440),
[NOTE_ARRAY_INDEX(AS4)] = CONV(466),
[NOTE_ARRAY_INDEX(B4)] = CONV(494),
[NOTE_ARRAY_INDEX(C5)] = CONV(523),
[NOTE_ARRAY_INDEX(CS5)] = CONV(554),
[NOTE_ARRAY_INDEX(D5)] = CONV(587),
[NOTE_ARRAY_INDEX(DS5)] = CONV(622),
[NOTE_ARRAY_INDEX(E5)] = CONV(659),
[NOTE_ARRAY_INDEX(F5)] = CONV(698),
[NOTE_ARRAY_INDEX(FS5)] = CONV(740),
[NOTE_ARRAY_INDEX(G5)] = CONV(784),
[NOTE_ARRAY_INDEX(GS5)] = CONV(831),
[NOTE_ARRAY_INDEX(A5)] = CONV(880),
[NOTE_ARRAY_INDEX(AS5)] = CONV(932),
[NOTE_ARRAY_INDEX(B5)] = CONV(988),
[NOTE_ARRAY_INDEX(C6)] = CONV(1047),
[NOTE_ARRAY_INDEX(CS6)] = CONV(1109),
[NOTE_ARRAY_INDEX(D6)] = CONV(1175),
[NOTE_ARRAY_INDEX(DS6)] = CONV(1245),
[NOTE_ARRAY_INDEX(E6)] = CONV(1319),
[NOTE_ARRAY_INDEX(F6)] = CONV(1397),
[NOTE_ARRAY_INDEX(FS6)] = CONV(1480),
[NOTE_ARRAY_INDEX(G6)] = CONV(1568),
[NOTE_ARRAY_INDEX(GS6)] = CONV(1661),
[NOTE_ARRAY_INDEX(A6)] = CONV(1760),
[NOTE_ARRAY_INDEX(AS6)] = CONV(1865),
[NOTE_ARRAY_INDEX(B6)] = CONV(1976),
[NOTE_ARRAY_INDEX(C7)] = CONV(2093),
[NOTE_ARRAY_INDEX(CS7)] = CONV(2217),
[NOTE_ARRAY_INDEX(D7)] = CONV(2349),
[NOTE_ARRAY_INDEX(DS7)] = CONV(2489),
[NOTE_ARRAY_INDEX(E7)] = CONV(2637),
[NOTE_ARRAY_INDEX(F7)] = CONV(2794),
[NOTE_ARRAY_INDEX(FS7)] = CONV(2960),
[NOTE_ARRAY_INDEX(G7)] = CONV(3136),
[NOTE_ARRAY_INDEX(GS7)] = CONV(3322),
[NOTE_ARRAY_INDEX(A7)] = CONV(3520),
[NOTE_ARRAY_INDEX(AS7)] = CONV(3729),
[NOTE_ARRAY_INDEX(B7)] = CONV(3951),
[NOTE_ARRAY_INDEX(C8)] = CONV(4186),
[NOTE_ARRAY_INDEX(CS8)] = CONV(4435),
[NOTE_ARRAY_INDEX(D8)] = CONV(4699),
[NOTE_ARRAY_INDEX(DS8)] = CONV(4978),
[NOTE_ARRAY_INDEX(E8)] = CONV(5274),
[NOTE_ARRAY_INDEX(F8)] = CONV(5588),
[NOTE_ARRAY_INDEX(FS8)] = CONV(5920),
[NOTE_ARRAY_INDEX(G8)] = CONV(6272),
[NOTE_ARRAY_INDEX(GS8)] = CONV(6645),
[NOTE_ARRAY_INDEX(A8)] = CONV(7040),
[NOTE_ARRAY_INDEX(AS8)] = CONV(7459),
[NOTE_ARRAY_INDEX(B8)] = CONV(7902),
};
const uint8_t FixedSong0[] = { C3, 1, REST, REST }; // Click Song
const uint8_t FixedSong1[] = {
D5, 3, FS5, 3, D5, 3, FS5, 3, D5, 3, FS5, 3, D5, 3, FS5, 3, D5, 3, FS5, 6,
REST, 3, D6, 13, FS5, 13, G5, 13,
A5, 13, D6, 9, REST, 4, A5, 6,
REST, 6, A6, 6, REST, 6, A5, 6, REST, 19, FS6, 3,
A6, 3, FS6, 3, A6, 3, FS6, 3, A6, 3, REST, 6, D6, 3, FS6, 3, D6, 3, FS6, 3,
D6, 3, FS6, 3, REST, 6, G5, 3, B5, 3, G5, 3, B5, 3, G5, 3, B5, 3, G5, 3,
B5, 3, G5, 3, B5, 6, REST, 3, G6, 13, B5, 13,
C6, 13, D6, 13, G6, 9,
REST, 4, D6, 6, REST, 6, D7, 6, REST, 6, D6, 6,
REST, 19, B6, 3, D7, 3, B6, 3, D7, 3,
B6, 3, D7, 3, B6, 3, D7, 6, REST, 22, A5, 3,
CS6, 3, A5, 3, CS6, 3, A5, 3, CS6, 3, A5, 3, CS6, 3, A5, 3, CS6, 6, REST, 3, A6, 13,
CS6, 13, D6, 13, E6, 13,
A6, 9, REST, 4, E6, 6, REST, 6, E7, 6,
REST, 6, E6, 6, REST, 19, CS7, 3,
E7, 3, CS7, 3, E7, 3, CS7, 3, E7, 3, REST, 6, A6, 3, CS7, 3, A6, 3, CS7, 3,
A6, 3, CS7, 3, REST, 6, D6, 3, FS6, 3, D6, 3, FS6, 3, D6, 3, FS6, 3, D6, 3,
FS6, 3, D6, 3, FS6, 6, REST, 3, D7, 13, FS6, 13,
G6, 13, A6, 13, D7, 9,
REST, 4, A6, 6, REST, 6, A7, 6, REST, 6, A6, 6,
REST, 19, FS7, 3, A7, 3, FS7, 3, A7, 3,
FS7, 3, A7, 3, FS7, 3, A7, 6, REST, 11,
REST, REST, REST, REST
};
const uint8_t FixedSong2[] = { // Active Song
A5, 5, REST, 7, A6, 2, REST, 11, A5, 2, REST, 23, A5, 2, REST, 11, A6, 2, REST, 11, A5, 2, REST, 23, D6, 13, FS5, 13, G5, 13, A5, 13, D5, 26, D6, 14, REST, REST
};
const uint8_t FixedSong3[] = { // Sleep Song
A6, 38, D6, 13, G6, 13, FS6, 13, D6, 13, A5, 10, REST, 3, D5, 5, REST, 7, D6, 2, REST, 11, D5, 2, REST, 23, D5, 2, REST, 11, D6, 2, REST, 11, D3, 2, REST, 1, REST, REST
};
const uint8_t FixedSong4[] = { // Wake Song
D5,38,
A5,13,
FS5,13,
G5,13,
A5,13,
D6,10,
REST,3, A5,5,
REST,7, A6,2,
REST,11, A5,2,
REST,23, A5,2,
REST,11, A6,2,
REST,11, A5,2,
REST, REST };
const uint8_t FixedSong5[] = { FS7,250, FS7,250, FS7,250, FS7,250, REST, REST }; /* Factory Song: For factory test song - 10 seconds of F#7 at 2960Hz */
const uint8_t FixedSong6[] = { C8,1, CS8,1, D8,1, DS8,1, E8,1, F8,1, REST, REST };
const uint8_t FixedSong7[] = { REST, REST }; /* Silent Song */
const uint8_t FixedSong8[] = { REST, REST }; /* Button Song: currently silent */
const uint8_t FixedSong9[] = { A5, 2, REST,11, A6, 2, REST, 11, A5, 2, REST,REST }; /* WakePart Song */
const uint8_t FixedSong10[] = { FS4, 3, REST,10, D5, 11, REST, 2, A5, 3, REST, 10, D6, 12, REST,REST }; /* double tap success Song */
const uint8_t FixedSong11[] = { GS4, 3, REST,10, GS5, 11, REST, 2, D4, 3, REST, 10, GS3, 12, REST,1, REST,REST }; /* double tap failure Song */
const uint8_t FixedSong12[] = { /*C3, 1, REST, 10, C3, 1,*/ REST, REST }; /* 2 clicks song */
const uint8_t FixedSong13[] = { D5, 30, REST, REST }; /* 1 bip Song */
const uint8_t FixedSong14[] = { D5, 30, REST,11, D5, 30, REST, REST }; /* 2 bip Song */
const uint8_t FixedSong15[] = { D5, 30, REST,11, D5, 30, REST,11, D5, 30, REST, REST }; /* 3 bip Song */
const uint8_t FixedSong16[] = { D5, 30, REST,11, D5, 30, REST,11, D5, 30, REST,11, D5, 30, REST, REST }; /* 4 bip Song */
const uint8_t FixedSong17[] = { D5, 30, REST,11, D5, 30, REST,11, D5, 30, REST,11, D5, 30, REST,11, D5, 30, REST, REST }; /* 5 bip Song */
const uint8_t FixedSong18[] = { D5, 30, REST,11, D5, 30, REST,11, D5, 30, REST,11, D5, 30, REST,11, D5, 30, REST,11, D5, 30, REST, REST }; /* 6 bip Song */
const uint8_t FixedSong19[] = { D5, 30, REST,11, D5, 30, REST,11, D5, 30, REST,11, D5, 30, REST,11, D5, 30, REST,11, D5, 30, REST,11, D5, 30, REST, REST }; /* 7 bip Song */
const uint8_t *tile_song_array[] = {
FixedSong0,
FixedSong1,
FixedSong2,
FixedSong3,
FixedSong4,
FixedSong5,
FixedSong6,
FixedSong7,
FixedSong8,
FixedSong9,
FixedSong10,
FixedSong11,
FixedSong12,
FixedSong13,
FixedSong14,
FixedSong15,
FixedSong16,
FixedSong17,
FixedSong18,
FixedSong19,
};
static uint8_t startup_sequence = 0;
static nrf_drv_timer_t player_timer = NRF_DRV_TIMER_INSTANCE(PLAYER_TIMER_ID);
APP_TIMER_DEF(song_timer_id);
APP_TIMER_DEF(song_timer_loop);
static void NextNote(void);
static void StartupPlayer(void);
static song_t current_song = {0};
static song_t next_song = {0};
static uint8_t song_loop_flag = 1;
static void song_timer_handler(void *p_context)
{
/* TODO: guard against calling NextNote when song is not playing */
if(startup_sequence)
{
StartupPlayer();
}
else
{
NextNote();
}
}
/**
* @brief song_duration_timeout_handler
* This is the interrupt handler for the song duration timer.
* The idea is that the variable song_loop_flag is set to 1 to ensure
* normal song_done() operation at all times. It is only set to 0 if
* The song is requested to play forever. If it is requested to play for a
* fixed duration, the timer allows the song_loop_flag to stay 0 until it times out.
*/
static void song_duration_timeout_handler(void *p_context)
{
song_loop_flag = 1;
}
/**
* @brief Player Boot Config
* Allocate ppi Channels for Player once at Boot:
* Call once at Boot, so we don't keep on assigning it again and again:
* There are limited number of channels, and every channel alloc from same place does not alloc a new channel
* It returns error: channel already allocated and moves on without apparent immediate problem, but assigned channels can go out of context,
* allocate more than needed channels, and then stop playing song/advertise in some scenarios
* So do not call alloc again and again
*/
void tile_boot_config_player(void)
{
nrfx_err_t err_code;
/* Initialize the gpiote driver if it isn't already */
if(!nrf_drv_gpiote_is_init())
{
err_code = nrf_drv_gpiote_init();
APP_ERROR_CHECK(err_code);
}
err_code = nrf_drv_ppi_channel_alloc(&ppi_channel1);
NRF_LOG_INFO("ppi channel 1 alloc gave %u, &ppi_channel1: 0x%08x",err_code,&ppi_channel1);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_gpiote_out_init(PIN_PIEZO, &config1);
APP_ERROR_CHECK(err_code);
}
/**
* @brief Configure PPI/GPIOTE for the layer
*/
static void ConfigureBuzzer()
{
uint32_t compare_evt_addr;
uint32_t gpiote_task_addr;
nrf_ppi_channel_t ppi_channel;
(void) nrf_drv_ppi_channel_alloc(&ppi_channel);
/* Set PIN_PIEZO for toggle on timer event */
nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false);
(void) nrf_drv_gpiote_out_init(PIN_PIEZO, &config);
/* Tie timer events to piezo toggle */
compare_evt_addr = nrf_drv_timer_event_address_get(&player_timer, NRF_TIMER_EVENT_COMPARE0);
gpiote_task_addr = nrf_drv_gpiote_out_task_addr_get(PIN_PIEZO);
(void) nrf_drv_ppi_channel_assign(ppi_channel, compare_evt_addr, gpiote_task_addr);
(void) nrf_drv_ppi_channel_enable(ppi_channel);
}
/**
* @brief Set the GPIO Player PIN as an Out PIN and Start Song after delay
*/
static void StartupPlayer()
{
startup_sequence = 0;
/* This is the start of the Find Default Song*/
if (current_song.p_firstNote == tile_song_array[TILE_SONG_FIND])
{
g_FindActivate_SongPlayed = 1;
}
/* find length of the song */
if (current_song.duration == TILE_SONG_DURATION_ONCE)
{
song_loop_flag = 1;
}
else if (current_song.duration == TILE_SONG_DURATION_FOREVER)
{
song_loop_flag = 0;
}
else
{
/* Create the timer for Song Loop */
NRF_LOG_INFO("Song Request received for duration - %d", current_song.duration);
song_loop_flag = 0;
(void) app_timer_start(song_timer_loop, APP_TIMER_TICKS(current_song.duration * 1000), NULL);
}
nrf_gpio_pin_clear(PIN_PIEZO);
nrf_drv_gpiote_out_task_enable(PIN_PIEZO);
(void) app_timer_start(song_timer_id, APP_TIMER_TICKS(10), NULL);
}
/**
* @brief Set the GPIO Player PIN to default state
*/
static void ShutdownPlayer()
{
nrf_drv_gpiote_out_task_disable(PIN_PIEZO);
nrf_gpio_pin_clear(PIN_PIEZO);
}
/**
* @brief Nordic SDK requires an interrupt handler for Timer1, even though we do not need one
*/
void timer_dummy_handler(nrf_timer_event_t event_type, void * p_context){}
/**
* @brief Function called at the end of a song.
* Will start enqueued song if any, otherwise shut everything Off and notify application.
*/
static void SongDone(void)
{
NRF_LOG_INFO("Song Done");
ShutdownPlayer();
(void) app_timer_stop(song_timer_loop);
g_inbetween = 0;
if(NULL != next_song.p_firstNote)
{
/* Start enqueued Song */
current_song = next_song;
memset(&next_song,0,sizeof(song_t));
startup_sequence = 1;
/* Give 200 ms between songs */
(void) app_timer_start(song_timer_id, APP_TIMER_TICKS(200), NULL);
}
else
{
/* Shut everything Off */
nrf_drv_timer_disable(&player_timer);
(void) app_timer_stop(song_timer_id);
UninitPlayer();
/********************************************************/
memset(&current_song,0,sizeof(song_t));
if (g_FindActivate_SongPlayed == 1)
{
if( (nrf_fstorage_is_busy(&app_data_bank0) == false) && (nrf_fstorage_is_busy(&app_data_bank1) == false) ) // If flash activity on-going, wait
{
if (BLE_CONN_HANDLE_INVALID == tile_ble_env.conn_handle) // Disconnected
{
/* These will auto clear to 0 because of reboot, but still add it for logical purposes */
g_FindActivate_SongPlayed = 0;
}
}
}
}
}
/**
* @brief Play the next Note
*/
static void NextNote(void)
{
uint8_t note = *current_song.p_currentNote++;
uint8_t duration = *current_song.p_currentNote++;
tile_unchecked->piezoMs += duration;
nrf_drv_timer_disable(&player_timer);
if(REST == note && REST == duration)
{
NRF_LOG_INFO("Song Duration: %d\r\n",tile_unchecked->piezoMs);
if(song_loop_flag == 1)
{
/* End of song reached */
SongDone();
return;
}
else
{
if (g_inbetween == 0)
{
NRF_LOG_INFO("song loop len is Non0, g_inbetween is 0");
/* Give 200 ms between songs*/
(void) app_timer_start(song_timer_id, APP_TIMER_TICKS(200), NULL);
current_song.p_currentNote -=2;
g_inbetween = 1;
}
else
{
NRF_LOG_INFO("song loop len is Non0, g_inbetween is 1");
/* Start one more loop */
current_song.p_currentNote = current_song.p_firstNote;
note = *current_song.p_currentNote++;
duration = *current_song.p_currentNote++;
tile_unchecked->piezoMs += duration;
g_inbetween = 0;
}
}
}
/* We come here if we are in the middle of a song, or we are starting a new loop */
if(REST == note)
{
/* reached a rest, disable the piezo pin and put it down */
nrf_drv_gpiote_out_task_disable(PIN_PIEZO);
nrf_gpio_pin_clear(PIN_PIEZO);
}
else
{
/* reached a note, set the Piezo Pin to toggle at the proper frequency */
nrf_drv_timer_clear(&player_timer);
nrf_drv_timer_extended_compare(&player_timer, GPIOTE_SOUND_CHANNEL, nrf_drv_timer_us_to_ticks(&player_timer, notes[NOTE_ARRAY_INDEX(note)]), NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);
nrf_drv_gpiote_out_task_enable(PIN_PIEZO);
if (nrf_drv_timer_is_enabled(&player_timer) == 0)
nrf_drv_timer_enable(&player_timer);
}
if (g_inbetween == 0)
{
(void) app_timer_start(song_timer_id, APP_TIMER_TICKS(duration*10), NULL);
}
}
/**
* @brief Initialize the Tile player
*/
void InitPlayer(void)
{
/* The Tile player uses GPIOTE to toggle the piezo pin, and
* Timer1 triggers the toggle using PPI */
nrf_drv_timer_config_t timer_config = NRF_DRV_TIMER_DEFAULT_CONFIG;
/* Configure timer */
(void) nrf_drv_timer_init(&player_timer, &timer_config, timer_dummy_handler);
ConfigureBuzzer();
/* Create the timer for switching frequencies */
(void) app_timer_create(&song_timer_id, APP_TIMER_MODE_SINGLE_SHOT, song_timer_handler);
/* Create the timer for Song Loop */
(void) app_timer_create(&song_timer_loop, APP_TIMER_MODE_SINGLE_SHOT, song_duration_timeout_handler);
}
/**
* @brief Uninitialize the Tile player, for Power Save reasons
* nrfx timer consumes ~0.5 mA current on Average
*/
void UninitPlayer(void)
{
ret_code_t err_code;
NRF_LOG_INFO("UninitPlayer");
/* Do not call nrf_drv_ppi_uninit() or nrf_drv_gpiote_uninit() as they are used by other modules */
nrf_drv_timer_uninit(&player_timer);
err_code = nrf_drv_ppi_channel_disable(ppi_channel1);
if (err_code != 0)
NRF_LOG_INFO("ppi channel 1 disable gave error %u",err_code);
// No Need to assert if Disable failed
}
/**
* @brief Play a song. Queue song if necessary
*/
int PlaySong(uint8_t number, uint8_t strength, uint8_t duration)
{
NRF_LOG_INFO("Play Song Request received");
if(strength == 0 || duration == 0)
{
return TILE_ERROR_SUCCESS;
}
if(number < ARRAY_SIZE(tile_song_array))
{
if((NULL != current_song.p_firstNote) && (NULL == next_song.p_firstNote))
{
/* A song is currently playing but there is NO enqueued song */
/* SO enqueue the song */
NRF_LOG_INFO("Enqueue Default song");
next_song = (song_t) { tile_song_array[number], tile_song_array[number], duration};
}
else if(NULL == current_song.p_firstNote)
{
/* no song is currently playing, start it right away */
InitPlayer();
song_loop_flag = 1;
NRF_LOG_INFO("Play Default song");
current_song = (song_t) { tile_song_array[number], tile_song_array[number], duration};
startup_sequence = 1;
StartupPlayer();
}
else
{
/* If queue is full, ignore */
}
}
return TILE_ERROR_SUCCESS;
}
/**
* @brief Stop currently playing song and remove enqueued songs
*/
int StopSong(void)
{
/* Destroy the queue */
if(next_song.p_firstNote != NULL)
{
memset(&next_song,0,sizeof(song_t));
}
/* Turn off the songs */
if(current_song.p_firstNote != NULL)
{
song_loop_flag = 1;
SongDone();
}
return TILE_ERROR_SUCCESS;
}
/**
* @brief Return whether a song is playing or not
*/
bool SongPlaying(void)
{
return current_song.p_firstNote != NULL;
}
/**
* @brief Return whether a Find song is playing or not
*/
bool CheckFindSong(void)
{
/*Return true if the current song note matches to the TILE_SONG_FIND note*/
if ( (current_song.p_firstNote != NULL) &&
(current_song.p_firstNote == tile_song_array[TILE_SONG_FIND]) )
{
return true;
}
return false;
}
#else
void InitPlayer(void){}
void UninitPlayer(void){}
int PlaySong(uint8_t number, uint8_t strength, uint8_t duration){return TILE_ERROR_SUCCESS;}
int StopSong(void){return TILE_ERROR_SUCCESS;}
bool SongPlaying(void){return false;}
void tile_boot_config_player(void){}
#endif // TILE_ENABLE_PLAYER
#endif // NRF_MODULE_ENABLED(TILE_SUPPORT)

View File

@@ -0,0 +1,54 @@
/**
* 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
*/
#ifndef TILE_PLAYER_H
#define TILE_PLAYER_H
#include <stdint.h>
#include <stdbool.h>
extern uint8_t g_FindActivate_SongPlayed;
#include "modules/tile_song_module.h"
#include "boards.h"
#define PIN_PIEZO ARDUINO_13_PIN
#define GPIOTE_SOUND_CHANNEL ((nrf_timer_cc_channel_t) 0) /**< PPI channel to use for connecting timer to piezo output */
#define PLAYER_TIMER_ID 1 /**< Timer ID to use with the player */
void InitPlayer(void);
void UninitPlayer(void);
int PlaySong(uint8_t number, uint8_t strength, uint8_t duration);
int StopSong(void);
bool SongPlaying(void);
void tile_boot_config_player(void);
bool CheckFindSong(void);
typedef struct song_info
{
const uint8_t *p_firstNote; // pointer to start of song
const uint8_t *p_currentNote; // pointer to current note
uint8_t duration;
}song_t;
#endif

View File

@@ -0,0 +1,257 @@
/**
* 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_service.c
* @brief Core functionality for Tile Lib
*/
#include "sdk_common.h"
#if NRF_MODULE_ENABLED(TILE_SUPPORT)
#include "ble_hci.h"
#include "nrf_delay.h"
#include "app_timer.h"
#include "app_scheduler.h"
#include "boards.h"
#include "nrf_sdh_ble.h"
#include "nrf_log.h"
#include "nrf_drv_ppi.h"
#include "nrf_drv_rng.h"
#include "tile_service/tile_service.h"
#include "tile_config.h"
#include "tile_features/tile_features.h"
#include "tile_gatt_db/tile_gatt_db.h"
#include "tile_storage/tile_storage.h"
#include "tile_assert/tile_assert.h"
#include "tile_player/tile_player.h"
// TileLib includes
#include "tile_lib.h"
#include "drivers/tile_gap_driver.h"
#include "drivers/tile_timer_driver.h"
#include "modules/tile_tmd_module.h"
#include "modules/tile_toa_module.h"
#include <stdbool.h>
#include <string.h>
/*******************************************************************************
* Forward declarations
******************************************************************************/
static void tile_timer_timeout_handler(void *p_context);
/*******************************************************************************
* Defines & types
******************************************************************************/
#define APP_BLE_TILE_OBSERVER_PRIO 3
/*******************************************************************************
* Global variables
******************************************************************************/
static app_timer_t tile_timer_data[TILE_MAX_TIMERS] = { 0 };
/*******************************************************************************
* Local variables
******************************************************************************/
/*******************************************************************************
* Functions
******************************************************************************/
/**
* @brief Initialize Tile BLE service
*/
void tile_service_init(void)
{
nrf_drv_rng_config_t rng_config = NRF_DRV_RNG_DEFAULT_CONFIG;
/* Initialize Tile timers */
for(int i = 0; i < TILE_MAX_TIMERS; i++)
{
tile_timer_id[i] = &tile_timer_data[i];
/* We use one universal timeout handler with p_context containing the timer ID for dispatch to the shim */
(void) app_timer_create(&tile_timer_id[i], APP_TIMER_MODE_SINGLE_SHOT, tile_timer_timeout_handler);
}
tile_storage_init(); // Initialize storage before initializing features
tile_features_init();
tile_ble_env.conn_handle = BLE_CONN_HANDLE_INVALID;
/* Audio Config */
nrfx_err_t err_code = nrf_drv_ppi_init();
APP_ERROR_CHECK(err_code);
tile_boot_config_player();
/* Register Tile Service Characteristics */
tile_gatt_db_init(&tile_ble_env.service);
/* Initialize RNG driver */
err_code = nrf_drv_rng_init(&rng_config);
APP_ERROR_CHECK(err_code);
/* Register a handler for BLE events */
NRF_SDH_BLE_OBSERVER(m_ble_observer2, APP_BLE_TILE_OBSERVER_PRIO, tile_on_ble_evt, NULL);
/* Play Tile Wakeup Song when Tile Service Inits and the Tile Node is not activated.
This may be disabled depending on the application requirements */
if(TILE_MODE_ACTIVATED != tile_checked->mode)
{
(void) PlaySong(TILE_SONG_WAKEUP, 3, TILE_SONG_DURATION_ONCE);
}
}
/**
* @brief Handle Tile BLE events
*
* @param[in] p_evt Event forwarded from BLE stack.
*/
void tile_on_ble_evt(ble_evt_t const * p_evt, void * p_context)
{
struct tile_conn_params params;
uint16_t handle;
switch (p_evt->header.evt_id)
{
case BLE_GAP_EVT_DISCONNECTED:
tile_ble_env.conn_handle = BLE_CONN_HANDLE_INVALID;
tile_unchecked->disconnect_count++;
(void) tile_gap_disconnected();
/********************************
After disconnect, initialize the advertising payload,
This is done in case the Tile Mode changes between Shipping and Advertising, it reflects in the advertising payload.
If we advertise 0xFEEC, instead of 0xFEED, this will cause discoverability issues in following cases:
a. Community Find
b. Access Points
c. If owner tries to discover activated Tiles on another phone, from same account.
Phone from where Tile was activated might still be able to connect as it may read the Mac address and not the advertising payload.
If we advertise 0xFEED, instead of 0xFEEC, this will cause issues after decommissioning, and we will not be able to commission/activate again
********************************/
break; // BLE_GAP_EVT_DISCONNECTED
case BLE_GAP_EVT_CONNECTED:
/* Save connection handle */
tile_ble_env.conn_handle = p_evt->evt.gap_evt.conn_handle;
tile_unchecked->connection_count++;
if(TILE_MODE_ACTIVATED != tile_checked->mode)
{
// when the Tile is not activated, the Interim TileID, Key is used.
memcpy(tile_checked->tile_id, interim_tile_id, TILE_ID_LEN);
memcpy(tile_checked->tile_auth_key, interim_tile_key, TILE_AUTH_KEY_LEN);
}
// Update the TileID Char
tile_update_tileID_char();
/* Tell Tile Lib about the connection */
params.conn_interval = p_evt->evt.gap_evt.params.connected.conn_params.max_conn_interval;
params.slave_latency = p_evt->evt.gap_evt.params.connected.conn_params.slave_latency;
params.conn_sup_timeout = p_evt->evt.gap_evt.params.connected.conn_params.conn_sup_timeout;
(void) tile_gap_connected(&params);
break; // BLE_GAP_EVT_CONNECTED
case BLE_GAP_EVT_CONN_PARAM_UPDATE:
params = (struct tile_conn_params)
{
.conn_interval = p_evt->evt.gap_evt.params.conn_param_update.conn_params.max_conn_interval,
.slave_latency = p_evt->evt.gap_evt.params.conn_param_update.conn_params.slave_latency,
.conn_sup_timeout = p_evt->evt.gap_evt.params.conn_param_update.conn_params.conn_sup_timeout,
};
(void) tile_gap_params_updated(&params);
break;
case BLE_GATTS_EVT_WRITE:
// Find which ID is associated with the handle
handle = p_evt->evt.gatts_evt.params.write.handle;
for(int i = 0; i < TILE_NUM_ATTRS; i++)
{
if(handle == tile_ble_env.service.characteristic_handles[i])
{
if (i == TILE_TOA_RSP_CCCD)
{
tile_toa_transport_ready(p_evt->evt.gatts_evt.params.write.data[0]); // initialite RSP
}
else if (i == TILE_TOA_CMD_CHAR)
{
// Tell Tile Lib about the write
tile_toa_command_received(p_evt->evt.gatts_evt.params.write.data,p_evt->evt.gatts_evt.params.write.len);
break; // Break from the loop
}
else
{
// Error Case
TILE_ASSERT(0);
}
}
}
break;
case BLE_GATTS_EVT_HVN_TX_COMPLETE:
tile_toa_response_sent_ok();
break;
default:
break;
}
}
/*******************************************************************************
* Local functions
******************************************************************************/
/**
* @brief Timer handler for Tile timers
*/
static void tile_timer_timeout_handler(void *p_context)
{
(void) tile_timer_expired((uint32_t)p_context & 0xFF);
}
/**
* @brief Retrieve correct 16-bit UUID to advertise and interval on the Tile mode
*/
void tile_get_adv_params(uint16_t* uuid, uint16_t* interval)
{
if(TILE_MODE_ACTIVATED == tile_checked->mode)
{
*uuid = TILE_ACTIVATED_UUID;
*interval = tile_checked->adv_int;
}
else
{
*uuid = TILE_SHIPPING_UUID;
*interval = TILE_DEFAULT_ADV_INT_SHIPPING;
}
}
#endif // NRF_MODULE_ENABLED(TILE_SUPPORT)

View File

@@ -0,0 +1,55 @@
/**
* NOTICE
*
* Copyright 2017 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_service.h"
* @brief Core functionality for Tile Lib
*/
#ifndef TILE_SERVICE_H_
#define TILE_SERVICE_H_
#include "ble.h"
#include "tile_lib.h"
/** @defgroup TOA Tile Over-the-air API
* @{
* @ingroup ext_ble_lib
* @brief Tile Over-the-air Api: defines Tile communication protocol over the air
*/
/**
* @brief Initialize Tile service. Store advertising data configuration from the application.
* @note This function must be called before @ref ble_advertising_init
*/
void tile_service_init(void);
void tile_on_ble_evt(ble_evt_t const * p_evt, void * p_context);
void tile_get_adv_params(uint16_t* uuid, uint16_t* interval);
uint16_t tile_get_adv_uuid(void);
/**
* @}
*/
#endif // TILE_SERVICE_H_

View File

@@ -0,0 +1,365 @@
/**
* NOTICE
*
* Copyright 2019 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_storage.c
* @brief Tile storage system
*/
#include "sdk_common.h"
#if NRF_MODULE_ENABLED(TILE_SUPPORT)
#include "tile_storage.h"
#include "tile_lib.h"
#include "tile_config.h"
#include "modules/tile_tmd_module.h"
#include "crc16.h"
#include "nrf_fstorage.h"
#include "nrf_soc.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "app_error.h"
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
/*******************************************************************************
* Global variables
******************************************************************************/
struct tile_persist_tag tile_persist __attribute__( (section("NoInit")) );
struct tile_checked_tag * const tile_checked = &tile_persist.checked.s;
struct tile_unchecked_tag * const tile_unchecked = &tile_persist.unchecked.s;
struct tile_env_tag tile_env;
/*******************************************************************************
* Local variables
******************************************************************************/
static volatile bool write_in_progress = false;
static volatile bool write_one_more_time = false;
const uint8_t interim_tile_id[8] = INTERIM_TILE_ID;
const uint8_t interim_tile_key[16] = INTERIM_AUTH_KEY;
/*******************************************************************************
* Forward declarations
******************************************************************************/
uint16_t tile_get_adv_uuid(void);
static void tile_app_on_flash_evt(nrf_fstorage_evt_t * evt);
static int compare_versions(uint8_t v1, uint8_t v2);
static struct tile_persist_tag * active_app_data_bank(void);
/*******************************************************************************
* Flash region configuration
******************************************************************************/
NRF_FSTORAGE_DEF(nrf_fstorage_t app_data_bank0) = {
.start_addr = APP_DATA_BANK0_ADDRESS,
.end_addr = (APP_DATA_BANK0_ADDRESS + APP_DATA_NUM_PAGES * PAGE_SIZE),
.evt_handler = tile_app_on_flash_evt,
};
NRF_FSTORAGE_DEF(nrf_fstorage_t app_data_bank1) = {
.start_addr = APP_DATA_BANK1_ADDRESS,
.end_addr = (APP_DATA_BANK1_ADDRESS + APP_DATA_NUM_PAGES * PAGE_SIZE),
.evt_handler = tile_app_on_flash_evt,
};
/*******************************************************************************
* Global functions
******************************************************************************/
/**@brief Sleep until an event is received. */
static void power_manage(void)
{
#ifdef SOFTDEVICE_PRESENT
(void) sd_app_evt_wait();
#else
__WFE();
#endif
}
void wait_for_flash_ready(nrf_fstorage_t const * p_fstorage)
{
/* While fstorage is busy, sleep and wait for an event. */
while (nrf_fstorage_is_busy(p_fstorage))
{
power_manage();
}
}
#if 0
/**@brief Helper function to obtain the last address on the last page of the on-chip flash that
* can be used to write user data.
*/
static uint32_t nrf5_flash_end_addr_get()
{
uint32_t const bootloader_addr = NRF_UICR->NRFFW[0];
uint32_t const page_sz = NRF_FICR->CODEPAGESIZE;
uint32_t const code_sz = NRF_FICR->CODESIZE;
return (bootloader_addr != 0xFFFFFFFF ?
bootloader_addr : (code_sz * page_sz));
}
#endif
/**@brief This function initializes two banks to be used in ping-pong manner in the Flash memory for usage by Tile Service.
* Purpose of two banks is to provide a back-up in case memory storage fails at some point in time
* This function checks for RAM and flash memory validity.
* a) If RAM data is valid, it stores the data in the newer bank in flash.
* b) If neither RAM nor flash is valid, it initializes the data to default values and stores in flash.
* This should happen only at very first boot
* c) If RAM data is not valid, but flash is, it gets latest data from flash, copies it to RAM, and updates newer flash bank
*/
void tile_storage_init(void)
{
ret_code_t ret;
ret = nrf_fstorage_init(&app_data_bank0, &nrf_fstorage_sd, NULL);
APP_ERROR_CHECK(ret);
ret = nrf_fstorage_init(&app_data_bank1, &nrf_fstorage_sd, NULL);
APP_ERROR_CHECK(ret);
/* Check if RAM is still okay. Read from flash if not. */
if(PERSIST_SIGNATURE == tile_persist.signature
&& tile_persist.crc == crc16_compute(tile_persist.checked.d, sizeof(tile_persist.checked.d), NULL))
{
/* RAM checks out. No need to load from flash. */
}
else
{
// Determine current tile_persist bank
struct tile_persist_tag *p = active_app_data_bank();
if(NULL == p)
{
// Initialize to sane values
memset(&tile_persist, 0, sizeof(tile_persist));
tile_checked->mode = TILE_MODE_SHIPPING;
tile_checked->tdt_configuration = DEFAULT_TDT_CONFIG;
memcpy(tile_checked->model_number, tile_model_number, TILE_MODEL_NUMBER_LEN);
memcpy(tile_checked->hardware_version, tile_hw_version, TILE_HARDWARE_VERSION_LEN);
}
else
{
memcpy(&tile_persist, p, sizeof(tile_persist));
}
}
tile_unchecked->reset_count++;
tile_store_app_data();
}
/**
* @brief Save tile_persist to flash
*/
void tile_store_app_data(void)
{
ret_code_t ret;
/* Compute CRC, to ensure most up-to-date version remains in RAM */
tile_persist.crc = crc16_compute(tile_persist.checked.d, sizeof(tile_persist.checked.d), NULL);
if(write_in_progress)
{
write_one_more_time = true;
return;
}
write_in_progress = true;
write_one_more_time = false;
/* Update bank and ID */
tile_checked->bank = !tile_checked->bank;
tile_checked->id++;
tile_checked->version = CHECKED_STRUCTURE_VERSION;
tile_persist.signature = PERSIST_SIGNATURE;
/* Recompute CRC, to account for bank switch */
tile_persist.crc = crc16_compute(tile_persist.checked.d, sizeof(tile_persist.checked.d), NULL);
/* Save */
if(0 == tile_checked->bank)
{
ret = nrf_fstorage_erase(&app_data_bank0, app_data_bank0.start_addr, APP_DATA_NUM_PAGES, NULL);
APP_ERROR_CHECK(ret);
ret = nrf_fstorage_write(&app_data_bank0, app_data_bank0.start_addr, &tile_persist, sizeof(tile_persist), NULL);
APP_ERROR_CHECK(ret);
//wait_for_flash_ready(&app_data_bank1);
}
else
{
ret = nrf_fstorage_erase(&app_data_bank1, app_data_bank1.start_addr, APP_DATA_NUM_PAGES, NULL);
APP_ERROR_CHECK(ret);
ret = nrf_fstorage_write(&app_data_bank1, app_data_bank1.start_addr, &tile_persist, sizeof(tile_persist), NULL);
APP_ERROR_CHECK(ret);
//wait_for_flash_ready(&app_data_bank1);
}
}
/*******************************************************************************
* Fstorage callbacks
******************************************************************************/
/**
* @brief Callback for flash activity not initiated by Tile Lib.
*/
static void tile_app_on_flash_evt(nrf_fstorage_evt_t * evt)
{
if (evt->result != NRF_SUCCESS)
{
NRF_LOG_INFO("--> Event received: ERROR while executing an fstorage operation.");
return;
}
if(NRF_FSTORAGE_EVT_WRITE_RESULT == evt->id)
{
NRF_LOG_DEBUG("Fstorage Write Event Callback\n");
write_in_progress = false;
if(write_one_more_time)
{
tile_store_app_data();
}
}
else if (NRF_FSTORAGE_EVT_ERASE_RESULT == evt->id)
{
NRF_LOG_DEBUG("Fstorage Erase Event Callback\n");
}
}
/*******************************************************************************
* Local functions
******************************************************************************/
/**
* @brief Compare 1-byte cyclic version counters
*
* We will define v1 < v2 if the difference (v2 - v1) mod 0x100
* is less than 0x80 (this is equivalent to having v2 - v1 come out
* positive in signed, 8-bit, 2's-complement arithmetic).
*
* @return 1 if v1 > v2, 0 if v1 = v2, and -1 if v1 < v2
*/
static int compare_versions(uint8_t v1, uint8_t v2)
{
/*
* This returns (v1 > v2) - (v1 < v2), i.e.
* 1 if v1 > v2, 0 if v1 = v2, and -1 if v1 < v2
*/
return (((v2 - v1) & 0xFF) > 0x80) - (((v2 - v1) & 0xFF) < 0x80);
}
/**
* @brief Decide which bank is active, based on the validity of the banks and their IDs
*
* @param[in] valid0 True if bank 0 is valid.
* @param[in] valid1 True if bank 1 is valid.
* @param[in] id0 ID of bank 0.
* @param[in] id1 ID of bank 1.
*
* @return 0 if bank 0 is the active bank, 1 if bank 1 is the active bank, and
* -1 if neither bank is valid.
*/
static int active_bank(bool valid0, bool valid1, uint8_t id0, uint8_t id1)
{
if(valid0 && valid1)
{
if(compare_versions(id0, id1) >= 0)
{
return 0;
}
else
{
return 1;
}
}
else if(valid0)
{
return 0;
}
else if(valid1)
{
return 1;
}
else
{
return -1;
}
}
/**
* @brief Find the active tile_checked bank.
*
* @return A pointer to the active tile_checked structure in flash, or NULL if
* there is no active bank.
*/
static struct tile_persist_tag * active_app_data_bank(void)
{
struct tile_persist_tag *p0 = (void*)APP_DATA_BANK0_ADDRESS;
struct tile_persist_tag *p1 = (void*)APP_DATA_BANK1_ADDRESS;
bool p0_valid = false;
bool p1_valid = false;
if(PERSIST_SIGNATURE == p0->signature
&& 0 == p0->checked.s.bank
&& p0->crc == crc16_compute(p0->checked.d, sizeof(p0->checked.d), NULL))
{
p0_valid = true;
}
if(PERSIST_SIGNATURE == p1->signature
&& 1 == p1->checked.s.bank
&& p1->crc == crc16_compute(p1->checked.d, sizeof(p1->checked.d), NULL))
{
p1_valid = true;
}
int bank = active_bank(p0_valid, p1_valid, p0->checked.s.id, p1->checked.s.id);
if(bank < 0)
{
return NULL;
}
else if(0 == bank)
{
return p0;
}
else if(1 == bank)
{
return p1;
}
else
{
/* Assert! We don't expect any other value to be returned. */
return NULL;
}
}
#endif // NRF_MODULE_ENABLED(TILE_SUPPORT)

View File

@@ -0,0 +1,168 @@
/**
* NOTICE
*
* Copyright 2016 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_storage.h
* @brief Tile storage system
*/
#ifndef TILE_STORAGE_H_
#define TILE_STORAGE_H_
#include <stdint.h>
#include "tile_lib.h"
#include "nrf_fstorage_sd.h"
#include "tile_tdt_module.h"
#include "ble_gap.h"
/*****************************************/
/* Copied from nordic14, TO DO: find correct definitions for Nordic 15.2 */
#define PAGE_SIZE 4096
/* These addresses should be the two pages directly before the default bootloader location */
#define APP_DATA_BANK0_ADDRESS 0x76000
#define APP_DATA_BANK1_ADDRESS 0x77000
#define APP_DATA_NUM_PAGES 1
/****************************************/
#define DEFAULT_ADVERTISING_INTERVAL 160
#define PERSIST_SIGNATURE 0xA5A5
#define CHECKED_SIZE 128
#define UNCHECKED_SIZE 256
#define CHECKED_STRUCTURE_VERSION_1 1
#define CHECKED_STRUCTURE_VERSION_2 2
#define CHECKED_STRUCTURE_VERSION_3 3
#define CHECKED_STRUCTURE_VERSION_4 4
#define CHECKED_STRUCTURE_VERSION CHECKED_STRUCTURE_VERSION_1
extern nrf_fstorage_t app_data_bank0;
extern nrf_fstorage_t app_data_bank1;
extern uint8_t bdaddr[BLE_GAP_ADDR_LEN];
extern const uint8_t interim_tile_id[];
extern const uint8_t interim_tile_key[];
extern const char tile_model_number[];
extern const char tile_hw_version[];
struct tile_checked_tag
{
/**************************************************************************************************/
/*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ****/
/*** THIS STRUCTURE IS SAVED TO FLASH AND RETRIEVED AFTER TOFU ****/
/*** THIS MEANS STUFF SHOULD NOT BE MODIFIED BUT ONLY AT THE END TO MAINTAIN COMPATIBILITY ****/
/**************************************************************************************************/
uint16_t version;
uint8_t id;
uint8_t bank;
uint8_t mode;
uint16_t adv_int;
tdt_config_t tdt_configuration;
uint8_t tile_id[TILE_ID_LEN];
uint8_t tile_auth_key[TILE_AUTH_KEY_LEN];
char model_number[TILE_MODEL_NUMBER_LEN];
char hardware_version[TILE_HARDWARE_VERSION_LEN];
uint8_t bdaddr[TILE_BDADDR_LEN];
uint8_t tileIDkey[TILEID_KEY_LEN];
};
struct tile_unchecked_tag
{
/**************************************************************************************************/
/*** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING ****/
/*** THIS STRUCTURE IS SAVED TO FLASH AND RETRIEVED AFTER TOFU ****/
/*** THIS MEANS STUFF SHOULD NOT BE MODIFIED BUT ONLY AT THE END TO MAINTAIN COMPATIBILITY ****/
/**************************************************************************************************/
// Activity tracking
uint32_t connection_count; /**< number of connections */
uint32_t disconnect_count; /**< Number of disconnections */
uint8_t auth_fail_count; /**< authentication failures count */
uint8_t micFailures; /**< mic failures */
uint8_t reset_count; /**< Reset Count */
uint32_t piezoMs; /**< time for which piezo was active in '10 ms' units */
// TOA Activity monitoring
uint32_t toa_channel_open_count; /**< Number of successfull TOA Channel Open (with a successfull authentication) */
uint32_t toa_authenticate_count; /**< number of TOA Authenticate Commands received */
uint16_t tka_closed_channel_count; /**< number of TOA Channel close triggered by TKA */
uint16_t auth_disconnect_count; /**< number of disconnections triggered by Auth Timer */
//Counter for private ID
uint16_t tileIDcounter; /**< Counter used for PrivateID */
};
struct tile_persist_tag
{
uint16_t crc;
uint16_t signature;
union
{
struct tile_checked_tag s;
uint8_t d[CHECKED_SIZE-4]; /* -4 for CRC + signature */
} checked __attribute__ ((aligned (4)));
union
{
struct tile_unchecked_tag s;
uint8_t d[UNCHECKED_SIZE];
} unchecked __attribute__ ((aligned (4)));
};
/**
* @brief Persistent structure, which is saved to flash. Does not need to be
* accessed directly. Access elements with tile_checked and tile_unchecked.
*/
extern struct tile_persist_tag tile_persist;
/**
* @brief CRC checked portion of persistent data.
*/
extern struct tile_checked_tag * const tile_checked;
/**
* @brief Non-CRC portion of persistent data. This get reinitialized when
* the CRC of the checked portion fails.
*/
extern struct tile_unchecked_tag * const tile_unchecked;
/**
* @brief Tile environment data. Lost at reboot.
*/
struct tile_env_tag
{
uint16_t last_reset_reason; ///> Contains the reason for the last reset
uint8_t authorized;
uint8_t hashedTileID[TILE_HASHED_TILEID_LEN];
};
extern struct tile_env_tag tile_env;
void tile_storage_init(void);
void tile_store_app_data(void);
#endif