tile_song_module.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /**
  2. * NOTICE
  3. *
  4. * Copyright 2020 Tile Inc. All Rights Reserved.
  5. * All code or other information included in the accompanying files ("Tile Source Material")
  6. * is PROPRIETARY information of Tile Inc. ("Tile") and access and use of the Tile Source Material
  7. * is subject to these terms. The Tile Source Material may only be used for demonstration purposes,
  8. * and may not be otherwise distributed or made available to others, including for commercial purposes.
  9. * Without limiting the foregoing , you understand and agree that no production use
  10. * of the Tile Source Material is allowed without a Tile ID properly obtained under a separate
  11. * agreement with Tile.
  12. * You also understand and agree that Tile may terminate the limited rights granted under these terms
  13. * at any time in its discretion.
  14. * All Tile Source Material is provided AS-IS without warranty of any kind.
  15. * Tile does not warrant that the Tile Source Material will be error-free or fit for your purposes.
  16. * Tile will not be liable for any damages resulting from your use of or inability to use
  17. * the Tile Source Material.
  18. *
  19. * Support: firmware_support@tile.com
  20. */
  21. /** @file tile_song_module.h
  22. ** @addtogroup TOA
  23. ** @{
  24. ** @brief Tile Song Module
  25. */
  26. #ifndef TILE_SONG_MODULE_H_
  27. #define TILE_SONG_MODULE_H_
  28. #include <stdint.h>
  29. #include "crypto/hmac_sha256.h"
  30. /**
  31. * @brief Tile Song numbers
  32. */
  33. enum TILE_SONG
  34. {
  35. TILE_SONG_1_CLICK = 0x00,
  36. TILE_SONG_FIND = 0x01,
  37. TILE_SONG_ACTIVE = 0x02,
  38. TILE_SONG_SLEEP = 0x03,
  39. TILE_SONG_WAKEUP = 0x04,
  40. TILE_SONG_FACTORY_TEST = 0x05,
  41. TILE_SONG_MYSTERY = 0x06,
  42. TILE_SONG_SILENT = 0x07,
  43. TILE_SONG_BUTTON = 0x08,
  44. TILE_SONG_WAKEUP_PART = 0x09,
  45. TILE_SONG_DT_SUCCESS = 0x0a,
  46. TILE_SONG_DT_FAILURE = 0x0b,
  47. TILE_SONG_2_CLICK = 0x0c,
  48. TILE_SONG_1_BIP = 0x0d,
  49. TILE_SONG_2_BIP = 0x0e,
  50. TILE_SONG_3_BIP = 0x0f,
  51. TILE_SONG_4_BIP = 0x10,
  52. TILE_SONG_5_BIP = 0x11,
  53. TILE_SONG_6_BIP = 0x12,
  54. TILE_SONG_7_BIP = 0x13,
  55. TILE_SONG_DT_HB = 0x14,
  56. TILE_SONG_MAX = 0x15,
  57. TILE_SONG_STOP = 0xFF
  58. };
  59. /**
  60. * Enumerate notes from C0 to B9
  61. *
  62. * Tile songs are created as a sequence of pairs,
  63. * (note, duration). Each value in the pair is one byte.
  64. * A song ends with the pair (REST, REST).
  65. */
  66. enum NOTES {
  67. REST = 0x00,
  68. C0, CS0, D0, DS0, E0, F0, FS0, G0, GS0, A0, AS0, B0,
  69. C1, CS1, D1, DS1, E1, F1, FS1, G1, GS1, A1, AS1, B1,
  70. C2, CS2, D2, DS2, E2, F2, FS2, G2, GS2, A2, AS2, B2,
  71. C3, CS3, D3, DS3, E3, F3, FS3, G3, GS3, A3, AS3, B3,
  72. C4, CS4, D4, DS4, E4, F4, FS4, G4, GS4, A4, AS4, B4,
  73. C5, CS5, D5, DS5, E5, F5, FS5, G5, GS5, A5, AS5, B5,
  74. C6, CS6, D6, DS6, E6, F6, FS6, G6, GS6, A6, AS6, B6,
  75. C7, CS7, D7, DS7, E7, F7, FS7, G7, GS7, A7, AS7, B7,
  76. C8, CS8, D8, DS8, E8, F8, FS8, G8, GS8, A8, AS8, B8,
  77. C9, CS9, D9, DS9, E9, F9, FS9, G9, GS9, A9, AS9, B9,
  78. };
  79. /**
  80. * @brief TILE_SONG_DURATION
  81. * Duration to play the Tile Song for.
  82. * The duration is in seconds and here are special values.
  83. */
  84. enum TILE_SONG_DURATION
  85. {
  86. TILE_SONG_DURATION_NOPLAY = 0x00, /**< Do not play anything */
  87. TILE_SONG_DURATION_ONCE = 0xFE, /**< Play the Song just once */
  88. TILE_SONG_DURATION_FOREVER = 0xFF /**< Play the song forever, till someone stops it */
  89. };
  90. #define SONG_METADATA_SIZE (sizeof(struct song_metadata_t))
  91. #define SONG_INFO_SIZE (sizeof(struct song_hdr_info_t))
  92. #define SONG_SECURITY_SIZE (sizeof(struct song_hdr_sec_t))
  93. #define SONG_HEADER_SIZE (SONG_INFO_SIZE + SONG_SECURITY_SIZE)
  94. #define SONG_HASH_SIZE 32 /**< Size of the song hash */
  95. #define SONG_SIG_SIZE 64 /**< Size of the song signature */
  96. #define SONG_CRC16_SIZE 2 /**< Size of the Block CRC */
  97. #define TILE_PROGRAMMABLE_SONG_LENGTH 1024 /**< Maximum length of the programmable song section in flash */
  98. #define TILE_SONG_BLOCK_SIZE 128 /**< Size of data in a data block */
  99. #define TILE_SONG_BUFFER_SIZE TILE_SONG_BLOCK_SIZE + SONG_CRC16_SIZE /**< Size of intermediate buffer for programming */
  100. #define TILE_SONG_VERSION 1 /**< Version field, to allow future format changes to take place */
  101. #define TILE_SONG_VALID 0xAA /**< Flag indicating a song is valid */
  102. /** @brief Song file header info portion */
  103. struct song_hdr_info_t
  104. {
  105. uint8_t song_format; ///< song_format is a Version Number that would describe the Tsong Format Variations
  106. 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.
  107. uint16_t song_id; ///< song_id is the Tile Assigned ID Number of this Song. See @ref TILE_SONG
  108. uint16_t song_size; ///< song_size represents the Song Payload Size, excluding any Security or Info Header.
  109. };
  110. /** @brief Song file header security info */
  111. struct song_hdr_sec_t
  112. {
  113. uint8_t hash[SONG_HASH_SIZE]; ///< A SHA-256 Hash Calculated using the Info Header and Song Payload.
  114. uint8_t sign[SONG_SIG_SIZE]; ///< Signature of the Song, calculated using the hash as input and Song Private Key with ECC Secp256k1 Curve.
  115. };
  116. /** @brief State of song programming */
  117. struct song_program_state_t
  118. {
  119. uint16_t pos; ///< accumulated number of bytes written for current Song
  120. uint8_t buf_pos; ///< accumulated number of bytes received for current block
  121. uint8_t state; ///< Song Programming State
  122. uint16_t file_size; ///< Total File Size of the current song being programmed
  123. uint32_t bank; ///< Memory Bank currently being used to program the Song
  124. sha256_ctx hash_ctx; ///< Current programmed Song Hash Calculation Context
  125. struct song_hdr_info_t info; ///< Current programmed Song Info Header
  126. struct song_hdr_sec_t sec; ///< Current programmed Song Security Header
  127. uint8_t cached_cid; ///< TOA CID of the current TPS session
  128. uint8_t block_dataSize; ///< datasize of the received block
  129. };
  130. /** @brief Metadata info stored in flash */
  131. struct song_metadata_t
  132. {
  133. uint8_t valid;
  134. uint8_t id;
  135. };
  136. /** @brief Cache for information related to the currently loaded song */
  137. struct song_info_cache_t
  138. {
  139. struct song_metadata_t curMeta;
  140. struct song_hdr_info_t curInfo;
  141. uint32_t curBank;
  142. };
  143. /**
  144. * Tile Programmable Songs module.
  145. *
  146. * Tile Lib supports the ability to update the find song over the air.
  147. */
  148. struct tile_song_tps_module_t {
  149. /**
  150. * Public key used for ECC signature verification
  151. * Generating ECC keys:
  152. * $ openssl ecparam -genkey -name secp256k1 -out k.perm
  153. * $ openssl ec -outform DER -in k.perm -noout -text
  154. */
  155. uint8_t *pub_key;
  156. /**
  157. * If set to 0, it means the programmable song is currently not playable
  158. */
  159. uint8_t useProgrammableSong;
  160. /**
  161. * Buffer used to receive TPS Song data
  162. */
  163. uint8_t tileSongBuffer[TILE_SONG_BUFFER_SIZE];
  164. /**
  165. * Cache for information related to the currently loaded song
  166. */
  167. struct song_info_cache_t song_info_cache;
  168. /**
  169. * Internal state used by TPS
  170. */
  171. struct song_program_state_t state;
  172. /**
  173. * Song Programming is starting.
  174. *
  175. */
  176. int (*begin)(void);
  177. /**
  178. * A TPS block has been received. Write to nonvolatile storage.
  179. * After writting, it is recommended to read back the data from flash in the tileSongBuffer.
  180. * The reason is TileLib will check the CRC again after this call returns (song_block_done is called).
  181. *
  182. */
  183. int (*block_ready)(void);
  184. /**
  185. * TPS has completed successfully
  186. */
  187. int (*complete)(void);
  188. };
  189. /**
  190. * Tile Song module.
  191. *
  192. * This module is used to allow the Tile app to play a song on the device.
  193. */
  194. struct tile_song_module {
  195. /**
  196. * Play song with given index number with strength from 0-3.
  197. */
  198. int (*play)(uint8_t number, uint8_t strength, uint8_t duration);
  199. /**
  200. * Stop all songs.
  201. */
  202. int (*stop)(void);
  203. /**
  204. * Optional TPS Module (set to NULL if not supported).
  205. */
  206. struct tile_song_tps_module_t* tps_module;
  207. };
  208. /**
  209. * Register the song module.
  210. */
  211. int tile_song_register(struct tile_song_module *module);
  212. /**
  213. * Call when the song programming begin command has completed.
  214. *
  215. * NOTE: Only required if TPS is supported.
  216. */
  217. void song_begin_done(uint8_t error);
  218. /**
  219. * Call when the song programming block ready command has completed.
  220. * tileSongBuffer is expected to contain the valid song block data when this function is called.
  221. * The reason is TileLib will check the CRC again in this function.
  222. * This allows the application to implement a read back of the data from flash to verify integrity.
  223. *
  224. * NOTE: Only required if TPS is supported.
  225. */
  226. void song_block_done(uint8_t error);
  227. /**
  228. * Call when the song programming complete command has completed.
  229. *
  230. * NOTE: Only required if TPS is supported.
  231. */
  232. void song_complete_done(uint8_t error);
  233. /** @} */
  234. #endif