antplus_weight.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  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. #define WEIGHT_SCALE_REV 1.5.0
  10. // User Profile Class
  11. public ref class WeightScaleUserProfile
  12. {
  13. public:
  14. static const USHORT PROFILE_UNDEF = 0xFFFF;
  15. static const USHORT PROFILE_SCALE_MIN = 0x0000;
  16. static const USHORT PROFILE_SCALE_MAX = 0x000F;
  17. static const USHORT PROFILE_DISPLAY_STAT_MIN = 0x0010;
  18. static const USHORT PROFILE_DISPLAY_STAT_MAX = 0x00FF;
  19. static const USHORT PROFILE_DISPLAY_PERS_MIN = 0x0100;
  20. static const USHORT PROFILE_DISPLAY_PERS_MAX = 0xFFFE;
  21. static const USHORT PROFILE_DISPLAY_MIN = 0x0010;
  22. static const USHORT PROFILE_DISPLAY_MAX = 0xFFFE;
  23. static const UCHAR GENDER_SHIFT = 7;
  24. static const UCHAR GENDER_FEMALE = 0x00;
  25. static const UCHAR GENDER_MALE = 0x01;
  26. static const UCHAR GENDER_UNDEF = 0x00;
  27. static const UCHAR AGE_MASK = 0x7F;
  28. static const UCHAR AGE_UNDEF = 0x00;
  29. static const UCHAR HEIGHT_UNDEF = 0x00;
  30. static const BOOL IS_ATHLETE = TRUE;
  31. static const BOOL NOT_ATHLETE = FALSE;
  32. // Descriptive Bit Field
  33. static const UCHAR DESCR_RESERVED = 0x00;
  34. static const UCHAR DESCR_MASK = 0x07;
  35. static const UCHAR ACTIVITY_ATHLETE_MASK = 0x080;
  36. static const UCHAR ACTIVITY_ATHLETE_SHIFT = 7;
  37. static const UCHAR ACTIVITY_SHIFT = 0;
  38. static const UCHAR ACTIVITY_INVALID = ((UCHAR) 0x00 << ACTIVITY_SHIFT);
  39. static const UCHAR ACTIVITY_CHILD = ((UCHAR) 0x01 << ACTIVITY_SHIFT);
  40. static const UCHAR ACTIVITY_SEDENTARY = ((UCHAR) 0x02 << ACTIVITY_SHIFT);
  41. static const UCHAR ACTIVITY_LOW = ((UCHAR) 0x03 << ACTIVITY_SHIFT);
  42. static const UCHAR ACTIVITY_MEDIUM = ((UCHAR) 0x04 << ACTIVITY_SHIFT);
  43. static const UCHAR ACTIVITY_HIGH = ((UCHAR) 0x05 << ACTIVITY_SHIFT);
  44. static const UCHAR ACTIVITY_INTENSE = ((UCHAR) 0x06 << ACTIVITY_SHIFT);
  45. static const UCHAR ACTIVITY_RESERVED = ((UCHAR) 0x07 << ACTIVITY_SHIFT);
  46. // Priorities
  47. static const UCHAR PRIORITY_SCALE = 1;
  48. static const UCHAR PRIORITY_DISPLAY = 2;
  49. static const UCHAR PRIORITY_WATCH = 3;
  50. static const UCHAR PRIORITY_UNDEF = 0;
  51. public:
  52. USHORT usID;
  53. UCHAR ucGender;
  54. UCHAR ucAge;
  55. UCHAR ucHeight;
  56. UCHAR ucDescription;
  57. UCHAR ucPriority;
  58. BOOL bAthlete;
  59. WeightScaleUserProfile()
  60. {
  61. usID = PROFILE_UNDEF;
  62. ucGender = GENDER_UNDEF;
  63. ucAge = AGE_UNDEF;
  64. ucHeight = HEIGHT_UNDEF;
  65. ucDescription = ACTIVITY_INVALID;
  66. bAthlete = NOT_ATHLETE;
  67. this->SetPriority();
  68. }
  69. WeightScaleUserProfile(USHORT usID_, UCHAR ucGender_, UCHAR ucAge_, UCHAR ucHeight_, UCHAR ucDescription_, UCHAR ucPriority_, BOOL bAthlete_)
  70. {
  71. usID = usID_;
  72. ucGender = ucGender_;
  73. ucAge = ucAge_;
  74. ucHeight = ucHeight_;
  75. ucDescription = ucDescription_;
  76. ucPriority = ucPriority_;
  77. bAthlete = bAthlete_;
  78. }
  79. ~WeightScaleUserProfile()
  80. {
  81. //delete this;
  82. }
  83. static void copyProfile(WeightScaleUserProfile^ Src, WeightScaleUserProfile^ Dst)
  84. {
  85. Dst->usID = Src->usID;
  86. Dst->ucAge = Src->ucAge;
  87. Dst->ucGender = Src->ucGender;
  88. Dst->ucHeight = Src->ucHeight;
  89. Dst->ucDescription = Src->ucDescription;
  90. Dst->ucPriority = Src->ucPriority;
  91. Dst->bAthlete = Src->bAthlete;
  92. }
  93. static BOOL isEqual(WeightScaleUserProfile^ Src, WeightScaleUserProfile^ Dst)
  94. {
  95. BOOL bEqual = TRUE;
  96. if(Dst->usID != Src->usID)
  97. bEqual = FALSE;
  98. if(Dst->ucAge != Src->ucAge)
  99. bEqual = FALSE;
  100. if(Dst->ucGender != Src->ucGender)
  101. bEqual = FALSE;
  102. if(Dst->ucHeight != Src->ucHeight)
  103. bEqual = FALSE;
  104. if(Dst->ucDescription != Src->ucDescription)
  105. bEqual = FALSE;
  106. if(Dst->bAthlete != Src->bAthlete)
  107. bEqual = FALSE;
  108. return bEqual;
  109. }
  110. void SetDefaultValues()
  111. {
  112. usID = PROFILE_UNDEF;
  113. ucGender = GENDER_UNDEF;
  114. ucAge = AGE_UNDEF;
  115. ucHeight = HEIGHT_UNDEF;
  116. ucDescription = ACTIVITY_INVALID;
  117. ucPriority = PRIORITY_SCALE;
  118. bAthlete = NOT_ATHLETE;
  119. this->SetPriority();
  120. }
  121. void SetPriority()
  122. {
  123. if(usID == PROFILE_UNDEF)
  124. ucPriority = PRIORITY_UNDEF;
  125. else if(usID <= PROFILE_SCALE_MAX)
  126. ucPriority = PRIORITY_SCALE;
  127. else if(usID <= PROFILE_DISPLAY_STAT_MAX)
  128. ucPriority = PRIORITY_DISPLAY;
  129. else if(usID <= PROFILE_DISPLAY_PERS_MAX)
  130. ucPriority = PRIORITY_WATCH;
  131. }
  132. };
  133. // Capabilities Class
  134. public ref class WeightScaleCapabilities
  135. {
  136. public:
  137. static const UCHAR RESERVED = 0x00;
  138. static const UCHAR SCALE_SELECTED_SHIFT = 0; // bit 0
  139. static const UCHAR SCALE_SELECTED = ((UCHAR) 0x01 << SCALE_SELECTED_SHIFT);
  140. static const UCHAR SCALE_UNSELECTED = ((UCHAR) 0x00 << SCALE_SELECTED_SHIFT);
  141. static const UCHAR SCALE_SELECTED_MASK = 0x01;
  142. static const UCHAR SCALE_EXCHANGE_SHIFT = 1; // bit 1
  143. static const UCHAR SCALE_EXCHANGE = ((UCHAR) 0x01 << SCALE_EXCHANGE_SHIFT);
  144. static const UCHAR SCALE_NO_EXCHANGE = ((UCHAR) 0x00 << SCALE_EXCHANGE_SHIFT);
  145. static const UCHAR SCALE_EXCHANGE_MASK = 0x02;
  146. static const UCHAR ANTFS_SHIFT = 2; // bit 2
  147. static const UCHAR ANTFS = ((UCHAR) 0x01 << ANTFS_SHIFT);
  148. static const UCHAR NO_ANTFS = ((UCHAR) 0x00 << ANTFS_SHIFT);
  149. static const UCHAR ANTFS_MASK = 0x04;
  150. static const UCHAR DISPLAY_EXCHANGE_SHIFT = 7; // bit 7
  151. static const UCHAR DISPLAY_EXCHANGE = ((UCHAR) 0x00 << DISPLAY_EXCHANGE_SHIFT);
  152. static const UCHAR DISPLAY_NO_EXCHANGE = ((UCHAR) 0x01 << DISPLAY_EXCHANGE_SHIFT);
  153. static const UCHAR DISPLAY_EXCHANGE_MASK = 0x80;
  154. enum class DeviceClass : UCHAR
  155. {
  156. SIMPLE_SCALE,
  157. ADVANCED_SCALE,
  158. SIMPLE_DISPLAY,
  159. ADVANCED_DISPLAY
  160. };
  161. public:
  162. BOOL bScaleSet;
  163. BOOL bAntfs;
  164. BOOL bScaleExchange;
  165. BOOL bDisplayExchange;
  166. UCHAR ucCapabilities;
  167. WeightScaleCapabilities(DeviceClass eType)
  168. {
  169. SetDefault(eType);
  170. }
  171. ~WeightScaleCapabilities()
  172. {
  173. //delete this;
  174. }
  175. // Default settings
  176. void SetDefault(DeviceClass eType)
  177. {
  178. bScaleSet = FALSE; // No user profile set initially
  179. bAntfs = FALSE; // Future capability, currently unsupported
  180. switch(eType)
  181. {
  182. default: // Treat any invalid config as a simple scale
  183. case DeviceClass::SIMPLE_SCALE:
  184. bScaleExchange = FALSE; // Simple scale does not support profile exchange
  185. bDisplayExchange = FALSE; // Initially, we do not know if the display supports profile exchange
  186. break;
  187. case DeviceClass::ADVANCED_SCALE:
  188. bScaleExchange = TRUE; // Simple scale does not support profile exchange
  189. bDisplayExchange = FALSE; // Initially, we do not know if the display supports profile exchange
  190. break;
  191. case DeviceClass::SIMPLE_DISPLAY:
  192. bScaleExchange = FALSE; // Initially, we do not know if the scale supports profile exchange
  193. bDisplayExchange = FALSE; // Simple display does not support profile exchange
  194. break;
  195. case DeviceClass::ADVANCED_DISPLAY:
  196. bScaleExchange = FALSE; // Initially, we do not know if the scale supports profile exchange
  197. bDisplayExchange = TRUE; // Advanced display supports profile exchange
  198. break;
  199. }
  200. encode(this);
  201. }
  202. static void encode(WeightScaleCapabilities^ capab)
  203. {
  204. capab->ucCapabilities = ((UCHAR) capab->bScaleSet << SCALE_SELECTED_SHIFT);
  205. capab->ucCapabilities |= ((UCHAR) capab->bScaleExchange << SCALE_EXCHANGE_SHIFT);
  206. capab->ucCapabilities |= ((UCHAR) capab->bAntfs << ANTFS_SHIFT);
  207. capab->ucCapabilities |= ((UCHAR) !(capab->bDisplayExchange) << DISPLAY_EXCHANGE_SHIFT); // Note support for profile exchange in the display is indicated by 0!
  208. }
  209. static void decode(WeightScaleCapabilities^ capab)
  210. {
  211. capab->bScaleSet = (BOOL) ((capab->ucCapabilities & SCALE_SELECTED_MASK) >> SCALE_SELECTED_SHIFT);
  212. capab->bScaleExchange = (BOOL) ((capab->ucCapabilities & SCALE_EXCHANGE_MASK) >> SCALE_EXCHANGE_SHIFT);
  213. capab->bAntfs = (BOOL) ((capab->ucCapabilities & ANTFS_MASK) >> ANTFS_SHIFT);
  214. capab->bDisplayExchange = (BOOL) !((capab->ucCapabilities & DISPLAY_EXCHANGE_MASK) >> DISPLAY_EXCHANGE_SHIFT);
  215. }
  216. };
  217. // Weight Scale Class
  218. public ref class WeightScale
  219. {
  220. public:
  221. // Channel parameters
  222. static const UCHAR DEVICE_TYPE = 0x77;
  223. static const UCHAR TX_TYPE = 0x05;
  224. static const USHORT MSG_PERIOD = 8192; // 4Hz
  225. // Data pages
  226. static const UCHAR PAGE_BODY_WEIGHT = 0x01;
  227. static const UCHAR PAGE_BODY_COMPOSITION = 0x02;
  228. static const UCHAR PAGE_METABOLIC_INFO = 0x03;
  229. static const UCHAR PAGE_BODY_MASS = 0x04;
  230. static const UCHAR PAGE_USER_PROFILE = 0x3A;
  231. // Body weight
  232. static const UCHAR RESERVED = 0xFF;
  233. static const USHORT WEIGHT_INVALID = 0xFFFF;
  234. static const USHORT WEIGHT_COMPUTING = 0xFFFE;
  235. static const UCHAR MASS_INVALID = 0xFF;
  236. static const UCHAR MASS_COMPUTING = 0xFF;
  237. // Interleaving requirements
  238. static const UCHAR INTERVAL_COMMON = 21; // Pages 80, 81 required every 21 messages
  239. // Type of device
  240. enum class DeviceClass : UCHAR
  241. {
  242. SCALE,
  243. DISPLAY
  244. };
  245. // Error handling
  246. // Flags indicate errors causing the exception
  247. ref class Error : public System::Exception{
  248. public:
  249. BOOL bUndefPage; // Undefined page
  250. BOOL bBadReserved; // Invalid values on reserved fields
  251. enum class Code : UCHAR // Error code definitions
  252. {
  253. UNDEF_PAGE,
  254. INVALID_RESERVED
  255. };
  256. Error()
  257. {
  258. ClearFlags();
  259. }
  260. Error(Code eCode1_)
  261. {
  262. ClearFlags();
  263. SetFlags(eCode1_);
  264. }
  265. Error(Code eCode1_, Code eCode2_)
  266. {
  267. ClearFlags();
  268. SetFlags(eCode1_);
  269. SetFlags(eCode2_);
  270. }
  271. private:
  272. void ClearFlags()
  273. {
  274. bUndefPage = FALSE;
  275. bBadReserved = FALSE;
  276. }
  277. void SetFlags(Code eCode_)
  278. {
  279. switch(eCode_)
  280. {
  281. case Code::UNDEF_PAGE:
  282. bUndefPage = TRUE;
  283. break;
  284. case Code::INVALID_RESERVED:
  285. bBadReserved = TRUE;
  286. break;
  287. default:
  288. break;
  289. }
  290. }
  291. };
  292. public:
  293. DeviceClass eType; // Type of device (eg. sensor, display)
  294. // Page 1
  295. USHORT usBodyWeight100; // Body weight (1/100kg)
  296. // Page 2
  297. USHORT usHydrationP100; // Hydration (0.01%)
  298. USHORT usBodyFatP100; // Body fat (0.01%)
  299. // Page 3
  300. USHORT usActiveMetRate4; // Active metabolic rate (1/4 kcal)
  301. USHORT usBasalMetRate4; // Basal metabolic rate (1/4 kcal)
  302. // Page 4
  303. USHORT usMuscleMass100; // Muscle mass (1/100kg)
  304. UCHAR ucBoneMass10; // Bone mass (1/10kg)
  305. // User profiles
  306. WeightScaleUserProfile^ uprofActive; // Active user profile
  307. WeightScaleUserProfile^ uprofScale; // Scale user profile
  308. WeightScaleUserProfile^ uprofDisplay; // Display user profile
  309. // Capabilities
  310. WeightScaleCapabilities^ capabScale; // Scale capabilities
  311. WeightScaleCapabilities^ capabDisplay; // Display capabilities
  312. // Error handling
  313. BOOL bValidation; // Turns validation on/off
  314. public:
  315. WeightScale(DeviceClass eType_)
  316. {
  317. eType = eType_;
  318. uprofActive = gcnew WeightScaleUserProfile();
  319. uprofScale = gcnew WeightScaleUserProfile();
  320. uprofDisplay = gcnew WeightScaleUserProfile();
  321. capabScale = gcnew WeightScaleCapabilities(WeightScaleCapabilities::DeviceClass::ADVANCED_SCALE);
  322. capabDisplay = gcnew WeightScaleCapabilities(WeightScaleCapabilities::DeviceClass::ADVANCED_DISPLAY);
  323. bValidation = FALSE;
  324. }
  325. ~WeightScale()
  326. {
  327. }
  328. public:
  329. /**************************************************************************
  330. * Decode
  331. *
  332. * Decodes all defined weight scale pages:
  333. * - Body weight
  334. * - User profile
  335. * Exceptions are thrown when dealing with non compliant pages
  336. *
  337. * pucRxBuffer_: pointer to the buffer containing the received data
  338. *
  339. * returns: N/A
  340. *
  341. **************************************************************************/
  342. void Decode(UCHAR* pucRxBuffer_)
  343. {
  344. switch(pucRxBuffer_[0])
  345. {
  346. case PAGE_BODY_WEIGHT: // Received from scale
  347. uprofScale->usID = (USHORT) pucRxBuffer_[1];
  348. uprofScale->usID |= (((USHORT) pucRxBuffer_[2]) << 8);
  349. capabScale->ucCapabilities = pucRxBuffer_[3];
  350. usBodyWeight100 = (USHORT) pucRxBuffer_[6];
  351. usBodyWeight100 |= (((USHORT) pucRxBuffer_[7]) << 8);
  352. WeightScaleCapabilities::decode(capabScale);
  353. break;
  354. case PAGE_BODY_COMPOSITION:
  355. uprofScale->usID = (USHORT) pucRxBuffer_[1];
  356. uprofScale->usID |= (((USHORT) pucRxBuffer_[2]) << 8);
  357. usHydrationP100 = (USHORT) pucRxBuffer_[4];
  358. usHydrationP100 |= (((USHORT) pucRxBuffer_[5]) << 8);
  359. usBodyFatP100 = (USHORT) pucRxBuffer_[6];
  360. usBodyFatP100 |= (((USHORT) pucRxBuffer_[7]) << 8);
  361. if(bValidation)
  362. {
  363. if(pucRxBuffer_[3] != RESERVED)
  364. throw gcnew Error(Error::Code::INVALID_RESERVED); // Error: Invalid reserved field
  365. }
  366. break;
  367. case PAGE_METABOLIC_INFO:
  368. uprofScale->usID = (USHORT) pucRxBuffer_[1];
  369. uprofScale->usID |= (((USHORT) pucRxBuffer_[2]) << 8);
  370. usActiveMetRate4 = (USHORT) pucRxBuffer_[4];
  371. usActiveMetRate4 |= (((USHORT) pucRxBuffer_[5]) << 8);
  372. usBasalMetRate4 = (USHORT) pucRxBuffer_[6];
  373. usBasalMetRate4 |= (((USHORT) pucRxBuffer_[7]) << 8);
  374. if(bValidation)
  375. {
  376. if(pucRxBuffer_[3] != RESERVED)
  377. throw gcnew Error(Error::Code::INVALID_RESERVED); // Error: Invalid reserved field
  378. }
  379. break;
  380. case PAGE_BODY_MASS:
  381. uprofScale->usID = (USHORT) pucRxBuffer_[1];
  382. uprofScale->usID |= (((USHORT) pucRxBuffer_[2]) << 8);
  383. usMuscleMass100 = (USHORT) pucRxBuffer_[5];
  384. usMuscleMass100 |= (((USHORT) pucRxBuffer_[6]) << 8);
  385. ucBoneMass10 = (UCHAR) pucRxBuffer_[7];
  386. if(bValidation)
  387. {
  388. if(pucRxBuffer_[3] != RESERVED || pucRxBuffer_[4] != RESERVED)
  389. throw gcnew Error(Error::Code::INVALID_RESERVED); // Error: Invalid reserved field
  390. }
  391. break;
  392. case PAGE_USER_PROFILE:
  393. if(eType == DeviceClass::SCALE) // Profile received from display
  394. {
  395. uprofDisplay->usID = (ULONG) pucRxBuffer_[1]; // Profile ID (low byte)
  396. uprofDisplay->usID |= (((ULONG) pucRxBuffer_[2]) << 8); // Profile ID (high byte)
  397. capabDisplay->ucCapabilities = pucRxBuffer_[3]; // Capabilities
  398. uprofDisplay->ucGender = pucRxBuffer_[5] >> WeightScaleUserProfile::GENDER_SHIFT; // Gender
  399. uprofDisplay->ucAge = pucRxBuffer_[5] & WeightScaleUserProfile::AGE_MASK; // Age
  400. uprofDisplay->ucHeight = pucRxBuffer_[6]; // Height
  401. // Decode the athlete bit
  402. if (pucRxBuffer_[7] & WeightScaleUserProfile::ACTIVITY_ATHLETE_MASK)
  403. uprofDisplay->bAthlete = TRUE;
  404. else
  405. uprofDisplay->bAthlete = FALSE;
  406. uprofDisplay->ucDescription = pucRxBuffer_[7] & WeightScaleUserProfile::DESCR_MASK; // Activity level
  407. WeightScaleCapabilities::decode(capabDisplay); // Decode display capabilities
  408. if(bValidation)
  409. {
  410. if(pucRxBuffer_[4] != RESERVED)
  411. throw gcnew Error(Error::Code::INVALID_RESERVED); // Error: Invalid reserved field
  412. }
  413. }
  414. else if(eType == DeviceClass::DISPLAY) // Profile received from scale
  415. {
  416. uprofScale->usID = (ULONG) pucRxBuffer_[1];
  417. uprofScale->usID |= (((ULONG) pucRxBuffer_[2]) << 8);
  418. capabScale->ucCapabilities = pucRxBuffer_[3];
  419. uprofScale->ucGender = pucRxBuffer_[5] >> WeightScaleUserProfile::GENDER_SHIFT;
  420. uprofScale->ucAge = pucRxBuffer_[5] & WeightScaleUserProfile::AGE_MASK;
  421. uprofScale->ucHeight = pucRxBuffer_[6];
  422. if (pucRxBuffer_[7] & WeightScaleUserProfile::ACTIVITY_ATHLETE_MASK)
  423. uprofScale->bAthlete = TRUE;
  424. else
  425. uprofScale->bAthlete = FALSE;
  426. uprofDisplay->ucDescription = pucRxBuffer_[7] & WeightScaleUserProfile::DESCR_MASK;
  427. WeightScaleCapabilities::decode(capabScale);
  428. }
  429. if(bValidation)
  430. {
  431. if(pucRxBuffer_[4] != RESERVED)
  432. throw gcnew Error(Error::Code::INVALID_RESERVED); // Error: Invalid reserved field
  433. }
  434. break;
  435. default:
  436. if(bValidation)
  437. throw gcnew Error(Error::Code::UNDEF_PAGE); // Error: Undefined page
  438. break;
  439. }
  440. }
  441. /**************************************************************************
  442. * Encode
  443. *
  444. * Encodes main weight scale data pages:
  445. * - Body Weight
  446. * - User Profile
  447. *
  448. * Exceptions are thrown when dealing with invalid data
  449. *
  450. * ucPageNum_: number of page to encode
  451. * pucTxBuffer_: pointer to the buffer that will store the encoded data
  452. *
  453. * returns: N/A
  454. *
  455. **************************************************************************/
  456. void Encode(UCHAR ucPageNum_, UCHAR* pucTxBuffer_)
  457. {
  458. switch(ucPageNum_)
  459. {
  460. case PAGE_BODY_WEIGHT:
  461. pucTxBuffer_[0] = ucPageNum_;
  462. pucTxBuffer_[1] = (UCHAR) uprofActive->usID; // Active user profile ID (low byte)
  463. pucTxBuffer_[2] = (UCHAR) (uprofActive->usID >> 8); // Active user profile ID (high byte)
  464. if(eType == DeviceClass::SCALE)
  465. {
  466. WeightScaleCapabilities::encode(capabScale); // Encode scale capabilities
  467. pucTxBuffer_[3] = capabScale->ucCapabilities; // Scale capabilities
  468. }
  469. pucTxBuffer_[4] = RESERVED;
  470. pucTxBuffer_[5] = RESERVED;
  471. pucTxBuffer_[6] = (UCHAR) usBodyWeight100; // Body weight in 1/100 kg (low byte)
  472. pucTxBuffer_[7] = (UCHAR) (usBodyWeight100 >> 8); // Body weight in 1/100 kg (high byte)
  473. break;
  474. case PAGE_BODY_COMPOSITION:
  475. pucTxBuffer_[0] = ucPageNum_;
  476. pucTxBuffer_[1] = (UCHAR) uprofActive->usID; // Active user profile ID (low byte)
  477. pucTxBuffer_[2] = (UCHAR) (uprofActive->usID >> 8); // Active user profile ID (high byte)
  478. pucTxBuffer_[3] = RESERVED;
  479. pucTxBuffer_[4] = (UCHAR) usHydrationP100; // % Hydration in intervals of 0.01% (low byte)
  480. pucTxBuffer_[5] = (UCHAR) (usHydrationP100 >> 8); // % Hydration in intervals of 0.01% (high byte)
  481. pucTxBuffer_[6] = (UCHAR) usBodyFatP100; // % Body fat in intervals of 0.01% (low byte)
  482. pucTxBuffer_[7] = (UCHAR) (usBodyFatP100 >> 8); // % Body fat in intervals of 0.01% (high byte)
  483. break;
  484. case PAGE_METABOLIC_INFO:
  485. pucTxBuffer_[0] = ucPageNum_;
  486. pucTxBuffer_[1] = (UCHAR) uprofActive->usID; // Active user profile ID (low byte)
  487. pucTxBuffer_[2] = (UCHAR) (uprofActive->usID >> 8); // Active user profile ID (high byte)
  488. pucTxBuffer_[3] = RESERVED;
  489. pucTxBuffer_[4] = (UCHAR) usActiveMetRate4; // Active metabolic rate in kJ (low byte)
  490. pucTxBuffer_[5] = (UCHAR) (usActiveMetRate4 >> 8); // Active metabolic rate in kJ (high byte)
  491. pucTxBuffer_[6] = (UCHAR) usBasalMetRate4; // Basal metabolic rate in kJ (low byte)
  492. pucTxBuffer_[7] = (UCHAR) (usBasalMetRate4 >> 8); // Basal metabolic rate in kJ (high byte)
  493. break;
  494. case PAGE_BODY_MASS:
  495. pucTxBuffer_[0] = ucPageNum_;
  496. pucTxBuffer_[1] = (UCHAR) uprofActive->usID; // Active user profile ID (low byte)
  497. pucTxBuffer_[2] = (UCHAR) (uprofActive->usID >> 8); // Active user profile ID (high byte)
  498. pucTxBuffer_[3] = RESERVED;
  499. pucTxBuffer_[4] = RESERVED;
  500. pucTxBuffer_[5] = (UCHAR) usMuscleMass100; // Muscle mass in 1/100 kg (low byte)
  501. pucTxBuffer_[6] = (UCHAR) (usMuscleMass100 >> 8); // Muscle mass in 1/100 kg (high byte)
  502. pucTxBuffer_[7] = ucBoneMass10; // Bone mass in 1/10kg
  503. break;
  504. case PAGE_USER_PROFILE:
  505. pucTxBuffer_[0] = ucPageNum_;
  506. pucTxBuffer_[1] = (UCHAR) uprofActive->usID; // Active user profile ID (low byte)
  507. pucTxBuffer_[2] = (UCHAR) (uprofActive->usID >> 8); // Active user profile ID (high byte)
  508. if(eType == DeviceClass::SCALE)
  509. {
  510. WeightScaleCapabilities::encode(capabScale); // Encode scale capabilities
  511. pucTxBuffer_[3] = capabScale->ucCapabilities; // Scale capabilities
  512. }
  513. else if(eType == DeviceClass::DISPLAY)
  514. {
  515. WeightScaleCapabilities::encode(capabDisplay); // Encode display capabilities
  516. pucTxBuffer_[3] = capabDisplay->ucCapabilities; // Display capabilities
  517. }
  518. pucTxBuffer_[4] = RESERVED;
  519. pucTxBuffer_[5] = uprofActive->ucGender << WeightScaleUserProfile::GENDER_SHIFT; // Gender
  520. pucTxBuffer_[5] |= (uprofActive->ucAge & WeightScaleUserProfile::AGE_MASK); // Age
  521. pucTxBuffer_[6] = uprofActive->ucHeight; // Height
  522. pucTxBuffer_[7] = uprofActive->ucDescription & WeightScaleUserProfile::DESCR_MASK; // Description bit field
  523. pucTxBuffer_[7] |= (uprofActive->bAthlete << WeightScaleUserProfile::ACTIVITY_ATHLETE_SHIFT); // Athlete bit
  524. break;
  525. default:
  526. if(bValidation)
  527. throw gcnew Error(Error::Code::UNDEF_PAGE); // Error: Undefined page
  528. break;
  529. }
  530. }
  531. };