antPlus_Geocache.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. /*
  2. This software is subject to the license described in the License.txt file
  3. included with this software distribution. You may not use this file except in compliance
  4. with this license.
  5. Copyright (c) Dynastream Innovations Inc. 2012
  6. All rights reserved.
  7. */
  8. #pragma once
  9. #include "types.h"
  10. #define Geocache_REV 1.0 // Device Profile Revision Number
  11. public ref class Geocache
  12. {
  13. public:
  14. // Channel Parameters
  15. static const UCHAR DEVICE_TYPE = 19;
  16. static const UCHAR TX_TYPE_SENSOR = 5;
  17. static const UCHAR TX_TYPE_DISPLAY = 0;
  18. static const UCHAR RF_CHANNEL = 57;
  19. static const USHORT MESG_4HZ_PERIOD = 8192; // 4Hz
  20. static const USHORT MESG_P5HZ_PERIOD = 65535; // 0.5Hz
  21. static const UCHAR MESG_4HZ_TIMEOUT = (4 * 30); // 4Hz * 30secs
  22. static const UCHAR MESG_REQ_RESP_ACK = 0x81;
  23. static const UCHAR MESG_REQ_RESP_BROADCAST = 0x01;
  24. static const UCHAR MESG_WAIT_REQ = 5;
  25. // Data Pages
  26. static const UCHAR PAGE_0 = 0;
  27. static const UCHAR PAGE_1 = 1;
  28. static const UCHAR PAGE_2 = 2;
  29. static const UCHAR PAGE_3 = 3;
  30. static const UCHAR PAGE_32 = 32;
  31. static const UCHAR PAGE_AUTHENTICATION = 32;
  32. static const UCHAR START_PROG_PAGES = 2; // Page0 + Page1
  33. // Acknowledged Messages
  34. static const UCHAR ACK_FAIL = 0;
  35. static const UCHAR ACK_SUCCESS = 1;
  36. // Reserved/invalid/special values
  37. static const UCHAR RESERVED = 0xFF;
  38. // Bit Masks
  39. static const UCHAR BYTE_MASK = 0xFF;
  40. static const UCHAR UPPER_NIBBLE_MASK = 0xF0;
  41. static const UCHAR LOWER_NIBBLE_MASK = 0x0F;
  42. static const UCHAR NEGATIVE_BYTE_MASK = 0x80;
  43. static const UCHAR REMOVE_SIGNED_BIT_MASK = 0x7F;
  44. static const ULONG NEGATIVE_LONG_MASK = 0xF0000000;
  45. // Bit shifts
  46. static const UCHAR NIBBLE_SHIFT = 4;
  47. static const UCHAR BYTE_SHIFT = 8;
  48. static const UCHAR LATLON_BYTE_2_SHIFT = 8;
  49. static const UCHAR LATLON_BYTE_3_SHIFT = 16;
  50. static const UCHAR LATLON_BYTE_4_SHIFT = 24;
  51. // Scale and offset Factors
  52. static const USHORT TIME_SCALE_FACTOR = 1024;
  53. static const DOUBLE SEMI_CIRCLE_CONVERSION = System::Math::Pow(2.0, 31) / 180; // conversion to semicircles from degrees
  54. static const UCHAR ID_LEN = 9; // not including the NULL
  55. static const UCHAR TXT_LEN = 90;
  56. static const UCHAR AUTH_LEN = 41; // Page 2-31 Data ID Types
  57. static const UCHAR DEFAULT_ID = 0x00; // 'Space' (0x20)
  58. static const UCHAR DEFAULT_TOT_PAGES = 0xFF; // 0xFF used to indicate UnProgrammed Geocache
  59. static const ULONG DEFAULT_PIN = 0xFFFFFFFF; //
  60. static const UCHAR HINT_CHARS_PER_PAGE = 6; // 6 Characters per Programmable 'Hint' Page
  61. // Programmable Page Definitions
  62. static const UCHAR PROGRAMMABLE_PAGES = 31;
  63. static const UCHAR DATA_ID_LATITUDE = 0;
  64. static const UCHAR DATA_ID_LONGITUDE = 1;
  65. static const UCHAR DATA_ID_HINT = 2;
  66. static const UCHAR DATA_ID_PIN = 3;
  67. static const UCHAR DATA_ID_LOGGED_VISITS = 4;
  68. // Error handling
  69. // Flags indicate errors causing the exception
  70. ref class Error : public System::Exception{
  71. public:
  72. BOOL bBadReserved; // Invalid values on reserved fields
  73. BOOL bUndefPage; // Undefined page
  74. enum class Code : UCHAR // Error code definitions
  75. {
  76. INVALID_RESERVED, // Invalid value in reserved field
  77. UNDEF_PAGE, // Undefined data page
  78. };
  79. Error()
  80. {
  81. ClearFlags();
  82. }
  83. Error(Code eCode1_)
  84. {
  85. ClearFlags();
  86. SetFlags(eCode1_);
  87. }
  88. Error(Code eCode1_, Code eCode2_)
  89. {
  90. ClearFlags();
  91. SetFlags(eCode1_);
  92. SetFlags(eCode2_);
  93. }
  94. private:
  95. void ClearFlags()
  96. {
  97. bBadReserved = FALSE;
  98. bUndefPage = FALSE;
  99. }
  100. void SetFlags(Code eCode_)
  101. {
  102. switch(eCode_)
  103. {
  104. case Code::INVALID_RESERVED:
  105. bBadReserved = TRUE;
  106. break;
  107. case Code::UNDEF_PAGE:
  108. bUndefPage = TRUE;
  109. break;
  110. default:
  111. break;
  112. }
  113. }
  114. };
  115. public:
  116. USHORT usMessagePeriod; // Dynamic Message Period (0.5Hz Beacon, 4Hz Communicating w/ GPS)
  117. UCHAR ucReceivedPageNum; // Incoming (RX) Page Number
  118. // Geocache Data Page 0
  119. // Geocache ID (9 6-bit ASCII Digits == ASCII - 0x20)
  120. array<UCHAR, 1>^ cID;
  121. // Geocache Data Page 1
  122. ULONG ulPIN; // Geocache PIN
  123. UCHAR ucTotalPages; // Total # of Pages Programmed (Including PAGE_1)
  124. // Geocache Data Page(s) 2..31
  125. BOOL bPINRequest; // GPS Request for PAGE_1 (PIN)
  126. BOOL b4HzRotation; // Begin 4Hz Page Rotation
  127. BOOL bPageRequest; // GPS 'Specific' Page Request
  128. BOOL bAckResponseRequest; // GPS Requests Acknowledged Reponse
  129. UCHAR ucRequestedPageNum; // Requested Page Number
  130. BOOL bLatitudeEnabled;
  131. BOOL bLongitudeEnabled;
  132. BOOL bHintEnabled;
  133. BOOL bLoggedVisitsEnabled;
  134. // GPS Total 'Programming' Pages
  135. UCHAR ucProgTotalPages;
  136. // GPS Current 'Programing' Page
  137. UCHAR ucCurrProgPage;
  138. // Geocache Page 'Programming' Status
  139. array<BOOL, 1>^ bPageProg;
  140. // Geocache Page 'Read' Status
  141. array<BOOL, 1>^ bPageRead;
  142. // Geocache Data Page(s) 2..31 - Raw [Byte] Data
  143. array<UCHAR, 2>^ ucProgPages;
  144. // Geocache Data ID 0 - Latitude (SemiCircles)
  145. SLONG slLatitude_SC;
  146. // Geocache Data ID 1 - Longitude (SemiCircles)
  147. SLONG slLongitude_SC;
  148. // Geocache Data ID 2 - "Hint"
  149. array<UCHAR, 1>^ cHint;
  150. UCHAR ucHintStartPage;
  151. UCHAR ucNumHintPages;
  152. // Geocache Data ID 4 - Logged Visits
  153. UCHAR ucLoggedVisitPage;
  154. ULONG ulLastVisitTimestamp;
  155. USHORT usNumVisits;
  156. UCHAR ucSeconds;
  157. UCHAR ucMinutes;
  158. UCHAR ucHours;
  159. UCHAR ucDays;
  160. UCHAR ucMonth;
  161. UCHAR ucYears;
  162. // Geocache Data Page 32 - Authentication Token (Hash of GPS Serial Number and Nonce)
  163. array <UCHAR, 1>^ ucAuthToken;
  164. ULONG ulSerialNum;
  165. USHORT usNonce;
  166. public:
  167. Geocache()
  168. {
  169. //initialize variables to invalid if possible, otherwise 0
  170. slLatitude_SC = 0;
  171. slLongitude_SC = 0;
  172. cID = gcnew array<UCHAR>(10);
  173. cHint = gcnew array<UCHAR>(180);
  174. ucAuthToken = gcnew array<UCHAR>(7);
  175. ucProgPages = gcnew array<UCHAR,2>(32,8);
  176. bPageRead = gcnew array<BOOL>(83);
  177. bPageProg = gcnew array<BOOL>(32);
  178. }
  179. ~Geocache()
  180. {
  181. }
  182. public:
  183. /**************************************************************************
  184. * Geocache::Decode
  185. *
  186. * Decodes all main data pages and calibration pages
  187. * Exceptions are thrown when dealing with non compliant pages
  188. *
  189. * pucRxBuffer_: pointer to the buffer containing the received data
  190. *
  191. * returns: N/A
  192. *
  193. **************************************************************************/
  194. void Decode(UCHAR* pucRxBuffer_)
  195. {
  196. UCHAR ucPageNum = pucRxBuffer_[0];
  197. UCHAR ucDataID;
  198. static UCHAR ucHintOffset;
  199. switch(ucPageNum)
  200. {
  201. case PAGE_0:
  202. // Unpack the Geocache ID
  203. cID[0] = ((pucRxBuffer_[1] >> 2) & 0x3F);
  204. cID[1] = ((pucRxBuffer_[1] << 4) & 0x30) + ((pucRxBuffer_[2] >> 4) & 0x0F);
  205. cID[2] = ((pucRxBuffer_[2] << 2) & 0x3C) + ((pucRxBuffer_[3] >> 6) & 0x03);
  206. cID[3] = ((pucRxBuffer_[3] >> 0) & 0x3F);
  207. cID[4] = ((pucRxBuffer_[4] >> 2) & 0x3F);
  208. cID[5] = ((pucRxBuffer_[4] << 4) & 0x30) + ((pucRxBuffer_[5] >> 4) & 0x0F);
  209. cID[6] = ((pucRxBuffer_[5] << 2) & 0x3C) + ((pucRxBuffer_[6] >> 6) & 0x03);
  210. cID[7] = ((pucRxBuffer_[6] >> 0) & 0x3F);
  211. cID[8] = ((pucRxBuffer_[7] >> 2) & 0x3F);
  212. break;
  213. case PAGE_1:
  214. // decode PIN and Number of Pages
  215. ulPIN = (pucRxBuffer_[2] << 0) + (pucRxBuffer_[3] << 8) +
  216. (pucRxBuffer_[4] << 16) + (pucRxBuffer_[5] << 24) ;
  217. ucTotalPages = pucRxBuffer_[6];
  218. ucHintStartPage = 0;
  219. break;
  220. case PAGE_32:
  221. // decode Authentication Token
  222. ucAuthToken[0] = pucRxBuffer_[1];
  223. ucAuthToken[1] = pucRxBuffer_[2];
  224. ucAuthToken[2] = pucRxBuffer_[3];
  225. ucAuthToken[3] = pucRxBuffer_[4];
  226. ucAuthToken[4] = pucRxBuffer_[5];
  227. ucAuthToken[5] = pucRxBuffer_[6];
  228. ucAuthToken[6] = pucRxBuffer_[7];
  229. break;
  230. default:
  231. ucProgPages[ucPageNum,0] = pucRxBuffer_[0];
  232. ucProgPages[ucPageNum,1] = pucRxBuffer_[1];
  233. ucProgPages[ucPageNum,2] = pucRxBuffer_[2];
  234. ucProgPages[ucPageNum,3] = pucRxBuffer_[3];
  235. ucProgPages[ucPageNum,4] = pucRxBuffer_[4];
  236. ucProgPages[ucPageNum,5] = pucRxBuffer_[5];
  237. ucProgPages[ucPageNum,6] = pucRxBuffer_[6];
  238. ucProgPages[ucPageNum,7] = pucRxBuffer_[7];
  239. ucDataID = pucRxBuffer_[1];
  240. switch (ucDataID)
  241. {
  242. case DATA_ID_LATITUDE:
  243. bLatitudeEnabled = TRUE;
  244. slLatitude_SC = (long)((pucRxBuffer_[2]) | // Latitude in semicirles
  245. (pucRxBuffer_[3] << LATLON_BYTE_2_SHIFT) |
  246. (pucRxBuffer_[4] << LATLON_BYTE_3_SHIFT) |
  247. (pucRxBuffer_[5] << LATLON_BYTE_4_SHIFT));
  248. break;
  249. case DATA_ID_LONGITUDE:
  250. bLongitudeEnabled = TRUE;
  251. slLongitude_SC = (long)((pucRxBuffer_[2]) | // Longitude in semicirles
  252. (pucRxBuffer_[3] << LATLON_BYTE_2_SHIFT) |
  253. (pucRxBuffer_[4] << LATLON_BYTE_3_SHIFT) |
  254. (pucRxBuffer_[5] << LATLON_BYTE_4_SHIFT));
  255. break;
  256. case DATA_ID_HINT :
  257. bHintEnabled = TRUE;
  258. if (ucHintStartPage == 0) ucHintStartPage = ucPageNum; // First Hint Page
  259. ucHintOffset = (ucPageNum - ucHintStartPage) * HINT_CHARS_PER_PAGE;; // Offset # of Chars into Hint Array
  260. cHint[ucHintOffset + 0] = pucRxBuffer_[2];
  261. cHint[ucHintOffset + 1] = pucRxBuffer_[3];
  262. cHint[ucHintOffset + 2] = pucRxBuffer_[4];
  263. cHint[ucHintOffset + 3] = pucRxBuffer_[5];
  264. cHint[ucHintOffset + 4] = pucRxBuffer_[6];
  265. cHint[ucHintOffset + 5] = pucRxBuffer_[7];
  266. break;
  267. case DATA_ID_LOGGED_VISITS :
  268. bLoggedVisitsEnabled = TRUE;
  269. ucLoggedVisitPage = ucPageNum;
  270. ulLastVisitTimestamp = (pucRxBuffer_[2]) + // Last Visit Timestamp
  271. (pucRxBuffer_[3] << 8) +
  272. (pucRxBuffer_[4] << 16) +
  273. (pucRxBuffer_[5] << 24);
  274. usNumVisits = (pucRxBuffer_[6]) + (pucRxBuffer_[7] << 8); // Number of Visits
  275. break;
  276. default :
  277. break;
  278. }
  279. break;
  280. }
  281. }
  282. /**************************************************************************
  283. * Geocache::GetPageData
  284. *
  285. * Gets the Geocache Page Data :
  286. *
  287. * Exceptions are thrown when dealing with invalid data
  288. *
  289. * ucPageNum_: number of page to encode
  290. * pucTxBuffer_: pointer to the buffer that will store the encoded data
  291. *
  292. * returns: N/A
  293. *
  294. **************************************************************************/
  295. void GetPageData(UCHAR ucPageNum_, UCHAR* pucTxBuffer_)
  296. {
  297. switch (ucPageNum_)
  298. {
  299. case PAGE_0 :
  300. pucTxBuffer_[0] = ucPageNum_;
  301. pucTxBuffer_[1] = ((cID[0] << 2) & 0xFC) | ((cID[1] >> 4) & 0x03);
  302. pucTxBuffer_[2] = ((cID[1] << 4) & 0xF0) | ((cID[2] >> 2) & 0x0F);
  303. pucTxBuffer_[3] = ((cID[2] << 6) & 0xC0) | ((cID[3] >> 0) & 0x3F);
  304. pucTxBuffer_[4] = ((cID[4] << 2) & 0xFC) | ((cID[5] >> 4) & 0x03);
  305. pucTxBuffer_[5] = ((cID[5] << 4) & 0xF0) | ((cID[6] >> 2) & 0x0F);
  306. pucTxBuffer_[6] = ((cID[6] << 6) & 0xC0) | ((cID[7] >> 0) & 0x3F);
  307. pucTxBuffer_[7] = ((cID[8] << 2) & 0xFC);
  308. break;
  309. case PAGE_1 :
  310. pucTxBuffer_[0] = ucPageNum_;
  311. pucTxBuffer_[1] = RESERVED;
  312. pucTxBuffer_[2] = ulPIN & 0xFF; // PIN (bits 0-7)
  313. pucTxBuffer_[3] = (ulPIN >> 8) & 0xFF; // PIN (bits 8-15)
  314. pucTxBuffer_[4] = (ulPIN >> 16) & 0xFF; // PIN (bits 16-23)
  315. pucTxBuffer_[5] = (ulPIN >> 24) & 0xFF; // PIN (bits 24-31)
  316. pucTxBuffer_[6] = ucTotalPages;
  317. pucTxBuffer_[7] = 0xFF; // RESERVED
  318. break;
  319. case PAGE_32 :
  320. pucTxBuffer_[0] = ucPageNum_;
  321. pucTxBuffer_[1] = ucAuthToken[0];
  322. pucTxBuffer_[2] = ucAuthToken[1];
  323. pucTxBuffer_[3] = ucAuthToken[2];
  324. pucTxBuffer_[4] = ucAuthToken[3];
  325. pucTxBuffer_[5] = ucAuthToken[4];
  326. pucTxBuffer_[6] = ucAuthToken[5];
  327. pucTxBuffer_[7] = ucAuthToken[6];
  328. break;
  329. default : // Programmable Page Data
  330. pucTxBuffer_[0] = ucPageNum_;
  331. pucTxBuffer_[1] = ucProgPages[ucPageNum_,1];
  332. pucTxBuffer_[2] = ucProgPages[ucPageNum_,2];
  333. pucTxBuffer_[3] = ucProgPages[ucPageNum_,3];
  334. pucTxBuffer_[4] = ucProgPages[ucPageNum_,4];
  335. pucTxBuffer_[5] = ucProgPages[ucPageNum_,5];
  336. pucTxBuffer_[6] = ucProgPages[ucPageNum_,6];
  337. pucTxBuffer_[7] = ucProgPages[ucPageNum_,7];
  338. break;
  339. }
  340. }
  341. /**************************************************************************
  342. * Geocache::GenerateAuthRequestPage
  343. *
  344. * Generate Auth (Request) Page Data :
  345. *
  346. * Exceptions are thrown when dealing with invalid data
  347. *
  348. * pucTxBuffer_: pointer to the buffer that will store the encoded data
  349. *
  350. * returns: N/A
  351. *
  352. **************************************************************************/
  353. void GenerateAuthRequestPage(UCHAR* pucTxBuffer_)
  354. {
  355. ulSerialNum = 0x33221100;
  356. usNonce = rand();
  357. pucTxBuffer_[0] = PAGE_32;
  358. pucTxBuffer_[1] = RESERVED;
  359. pucTxBuffer_[2] = usNonce & 0xFF; // Nonce (bits 0-7)
  360. pucTxBuffer_[3] = (usNonce >> 8) & 0xFF; // Nonce (bits 8-15)
  361. pucTxBuffer_[4] = ulSerialNum & 0xFF; // SerialNum (bits 0-7)
  362. pucTxBuffer_[5] = (ulSerialNum >> 8) & 0xFF; // SerialNumIN (bits 8-15)
  363. pucTxBuffer_[6] = (ulSerialNum >> 16) & 0xFF; // SerialNum (bits 16-23)
  364. pucTxBuffer_[7] = (ulSerialNum >> 24) & 0xFF; // SerialNum (bits 24-31)
  365. }
  366. /**************************************************************************
  367. * Geocache::GenerateProgPageData
  368. *
  369. * Generate the Geocache 'Programmable' data pages (2..31) from UI Values :
  370. *
  371. * Exceptions are thrown when dealing with invalid data
  372. *
  373. * returns: N/A
  374. *
  375. **************************************************************************/
  376. void GenerateProgPages(void)
  377. {
  378. UCHAR ucHintOffset;
  379. UCHAR ucPageCount = START_PROG_PAGES;
  380. if (bLatitudeEnabled)
  381. {
  382. ucProgPages[ucPageCount,0] = ucPageCount;
  383. ucProgPages[ucPageCount,1] = DATA_ID_LATITUDE;
  384. ucProgPages[ucPageCount,2] = slLatitude_SC & BYTE_MASK; // Latitude in semicircles
  385. ucProgPages[ucPageCount,3] = (slLatitude_SC >> LATLON_BYTE_2_SHIFT) & BYTE_MASK;
  386. ucProgPages[ucPageCount,4] = (slLatitude_SC >> LATLON_BYTE_3_SHIFT) & BYTE_MASK;
  387. ucProgPages[ucPageCount,5] = (slLatitude_SC >> LATLON_BYTE_4_SHIFT) & BYTE_MASK;
  388. ucPageCount++;
  389. }
  390. if (bLongitudeEnabled)
  391. {
  392. ucProgPages[ucPageCount,0] = ucPageCount;
  393. ucProgPages[ucPageCount,1] = DATA_ID_LONGITUDE;
  394. ucProgPages[ucPageCount,2] = slLongitude_SC & BYTE_MASK; // Longitude in semicircles
  395. ucProgPages[ucPageCount,3] = (slLongitude_SC >> LATLON_BYTE_2_SHIFT) & BYTE_MASK;
  396. ucProgPages[ucPageCount,4] = (slLongitude_SC >> LATLON_BYTE_3_SHIFT) & BYTE_MASK;
  397. ucProgPages[ucPageCount,5] = (slLongitude_SC >> LATLON_BYTE_4_SHIFT) & BYTE_MASK;
  398. ucPageCount++;
  399. }
  400. if (bLoggedVisitsEnabled)
  401. {
  402. ucProgPages[ucPageCount,0] = ucPageCount;
  403. ucProgPages[ucPageCount,1] = DATA_ID_LOGGED_VISITS;
  404. ucProgPages[ucPageCount,2] = ulLastVisitTimestamp & 0xFF; // Last Visit Timestamp (bits 0-7)
  405. ucProgPages[ucPageCount,3] = (ulLastVisitTimestamp >> 8) & 0xFF; // Last Visit Timestamp (bits 8-15)
  406. ucProgPages[ucPageCount,4] = (ulLastVisitTimestamp >> 16) & 0xFF; // Last Visit Timestamp (bits 16-23)
  407. ucProgPages[ucPageCount,5] = (ulLastVisitTimestamp >> 24) & 0xFF; // Last Visit Timestamp (bits 24-31)
  408. ucProgPages[ucPageCount,6] = usNumVisits & 0xFF; // Number of Visits (bits 0-7)
  409. ucProgPages[ucPageCount,7] = (usNumVisits >> 8) & 0xFF; // Number of Visits (bits 8-15)
  410. ucPageCount++;
  411. }
  412. if (bHintEnabled)
  413. {
  414. ucHintStartPage = ucPageCount;
  415. for (UCHAR ucHintPage=ucHintStartPage; ucHintPage<(ucHintStartPage+ucNumHintPages); ucHintPage++)
  416. {
  417. ucHintOffset = (ucHintPage - ucHintStartPage) * HINT_CHARS_PER_PAGE;; // Offset # of Chars into Hint Array
  418. ucProgPages[ucHintPage,0] = ucHintPage;
  419. ucProgPages[ucHintPage,1] = DATA_ID_HINT;
  420. ucProgPages[ucHintPage,2] = cHint[ucHintOffset + 0];
  421. ucProgPages[ucHintPage,3] = cHint[ucHintOffset + 1];
  422. ucProgPages[ucHintPage,4] = cHint[ucHintOffset + 2];
  423. ucProgPages[ucHintPage,5] = cHint[ucHintOffset + 3];
  424. ucProgPages[ucHintPage,6] = cHint[ucHintOffset + 4];
  425. ucProgPages[ucHintPage,7] = cHint[ucHintOffset + 5];
  426. ucPageCount++;
  427. }
  428. }
  429. ucTotalPages = ucPageCount;
  430. // Initialize (remaining) Programmable Page 'Store' - to RESERVED [0xFF]
  431. for (; ucPageCount<32; ucPageCount++)
  432. {
  433. ucProgPages[ucPageCount,0] = ucPageCount;
  434. ucProgPages[ucPageCount,1] = RESERVED;
  435. ucProgPages[ucPageCount,2] = RESERVED;
  436. ucProgPages[ucPageCount,3] = RESERVED;
  437. ucProgPages[ucPageCount,4] = RESERVED;
  438. ucProgPages[ucPageCount,5] = RESERVED;
  439. ucProgPages[ucPageCount,6] = RESERVED;
  440. ucProgPages[ucPageCount,7] = RESERVED;
  441. }
  442. }
  443. /**************************************************************************
  444. * Geocache::UpdateLoggedVisitPage()
  445. *
  446. * Updates the Geocache Logged Visit Page from values :
  447. *
  448. * Exceptions are thrown when dealing with invalid data
  449. *
  450. * returns: N/A
  451. *
  452. **************************************************************************/
  453. void UpdateLoggedVisitPage(void)
  454. {
  455. if (bLoggedVisitsEnabled)
  456. {
  457. ucProgPages[ucLoggedVisitPage,0] = ucLoggedVisitPage;
  458. ucProgPages[ucLoggedVisitPage,1] = DATA_ID_LOGGED_VISITS;
  459. ucProgPages[ucLoggedVisitPage,1] = DATA_ID_LOGGED_VISITS;
  460. ucProgPages[ucLoggedVisitPage,2] = ulLastVisitTimestamp & 0xFF; // Last Visit Timestamp (bits 0-7)
  461. ucProgPages[ucLoggedVisitPage,3] = (ulLastVisitTimestamp >> 8) & 0xFF; // Last Visit Timestamp (bits 8-15)
  462. ucProgPages[ucLoggedVisitPage,4] = (ulLastVisitTimestamp >> 16) & 0xFF; // Last Visit Timestamp (bits 16-23)
  463. ucProgPages[ucLoggedVisitPage,5] = (ulLastVisitTimestamp >> 24) & 0xFF; // Last Visit Timestamp (bits 24-31)
  464. ucProgPages[ucLoggedVisitPage,6] = usNumVisits & 0xFF; // Number of Visits (bits 0-7)
  465. ucProgPages[ucLoggedVisitPage,7] = (usNumVisits >> 8) & 0xFF; // Number of Visits (bits 8-15)
  466. }
  467. }
  468. /**************************************************************************
  469. * Geocache::EnabledProgPages
  470. *
  471. * Determines which Programmable Pages (Data IDs) are Present
  472. *
  473. * Exceptions are thrown when dealing with invalid data
  474. *
  475. * returns: N/A
  476. *
  477. **************************************************************************/
  478. void EnabledProgPages(void)
  479. {
  480. UCHAR ucDataID;
  481. UCHAR ucPageCount;
  482. bLatitudeEnabled = FALSE;
  483. bLongitudeEnabled = FALSE;
  484. bHintEnabled = FALSE;
  485. bLoggedVisitsEnabled = FALSE;
  486. for(ucPageCount=START_PROG_PAGES; ucPageCount<=ucTotalPages; ucPageCount++)
  487. {
  488. ucDataID = ucProgPages[ucPageCount,1];
  489. switch (ucDataID)
  490. {
  491. case DATA_ID_LATITUDE:
  492. bLatitudeEnabled = TRUE;
  493. break;
  494. case DATA_ID_LONGITUDE:
  495. bLongitudeEnabled = TRUE;
  496. break;
  497. case DATA_ID_HINT :
  498. bHintEnabled = TRUE;
  499. break;
  500. case DATA_ID_LOGGED_VISITS :
  501. bLoggedVisitsEnabled = TRUE;
  502. break;
  503. default :
  504. break;
  505. }
  506. }
  507. }
  508. /**************************************************************************
  509. * Geocache::InitSensor
  510. *
  511. * Initialize the Geocache Sensor
  512. * - PAGE_0 to 'Programmable' data pages (2..31) from UI Values :
  513. *
  514. * Exceptions are thrown when dealing with invalid data
  515. *
  516. * returns: N/A
  517. *
  518. **************************************************************************/
  519. void InitSensor(void)
  520. {
  521. // Initialize PAGE_0 (ID set to default value)
  522. for (UCHAR i=0; i<ID_LEN; i++) cID[i] = DEFAULT_ID;
  523. // Initialize PAGE_1 (PIN set to RESERVED)
  524. ulPIN = DEFAULT_PIN;
  525. // Initialize Programmable Page 'Store' - to RESERVED [0xFF]
  526. for (UCHAR ucPageCount=0; ucPageCount<32; ucPageCount++)
  527. {
  528. ucProgPages[ucPageCount,0] = ucPageCount;
  529. ucProgPages[ucPageCount,1] = RESERVED;
  530. ucProgPages[ucPageCount,2] = RESERVED;
  531. ucProgPages[ucPageCount,3] = RESERVED;
  532. ucProgPages[ucPageCount,4] = RESERVED;
  533. ucProgPages[ucPageCount,5] = RESERVED;
  534. ucProgPages[ucPageCount,6] = RESERVED;
  535. ucProgPages[ucPageCount,7] = RESERVED;
  536. }
  537. }
  538. /**************************************************************************
  539. * Geocache::InitDisplay
  540. *
  541. * Initialize the Geocache Display
  542. * - PAGE_0 to 'Programmable' data pages (2..31) from UI Values :
  543. *
  544. * Exceptions are thrown when dealing with invalid data
  545. *
  546. * returns: N/A
  547. *
  548. **************************************************************************/
  549. void InitDisplay(void)
  550. {
  551. // Initialize PageRead Status to FALSE
  552. for (UCHAR i=0; i<=82; i++) bPageRead[i] = FALSE;
  553. // Initialize PageProg Status to FALSE
  554. for (UCHAR i=0; i<32; i++) bPageProg[i] = FALSE;
  555. // Initialize PAGE_0 (ID set to default value)
  556. for (UCHAR i=0; i<ID_LEN; i++) cID[i] = DEFAULT_ID;
  557. // Initialize PAGE_1
  558. ulPIN = DEFAULT_PIN;
  559. ucTotalPages = DEFAULT_TOT_PAGES;
  560. bLatitudeEnabled = FALSE;
  561. slLatitude_SC = 0xFFFFFFFF;
  562. bLongitudeEnabled = FALSE;
  563. slLongitude_SC = 0xFFFFFFFF;
  564. bHintEnabled = FALSE;
  565. bLoggedVisitsEnabled = FALSE;
  566. ulLastVisitTimestamp = 0xFFFFFFFF;
  567. usNumVisits = 0xFFFF;
  568. // Initialize Programmable Page 'Store' - to RESERVED [0xFF]
  569. for (UCHAR ucPageCount=0; ucPageCount<32; ucPageCount++)
  570. {
  571. ucProgPages[ucPageCount,0] = ucPageCount;
  572. ucProgPages[ucPageCount,1] = RESERVED;
  573. ucProgPages[ucPageCount,2] = RESERVED;
  574. ucProgPages[ucPageCount,3] = RESERVED;
  575. ucProgPages[ucPageCount,4] = RESERVED;
  576. ucProgPages[ucPageCount,5] = RESERVED;
  577. ucProgPages[ucPageCount,6] = RESERVED;
  578. ucProgPages[ucPageCount,7] = RESERVED;
  579. }
  580. }
  581. };