/* This software is subject to the license described in the License.txt file included with this software distribution. You may not use this file except in compliance with this license. Copyright (c) Dynastream Innovations Inc. 2012 All rights reserved. */ #pragma once #define COMMON_REV 1.1 // Device Profile Revision Number public ref class CommonData { public: static const UCHAR START_COMMON_PAGE = 0x40; static const UCHAR PAGE70 = 70; static const UCHAR PAGE80 = 80; static const UCHAR PAGE81 = 81; static const UCHAR PAGE82 = 82; static const UCHAR PAGE83 = 83; static const UCHAR PAGE85 = 85; static const UCHAR PAGE86 = 86; static const UCHAR RESERVED = 0xFF; static const USHORT BATTERY_VOLTAGE_INVALID = 0xFFF; static const ULONG MAX_2SEC = (ULONG) 0xFFFFFF << 1; static const ULONG MAX_16SEC = (ULONG) 0xFFFFFF << 4; static const ULONG OPERATING_TIME_MASK = 0x00FFFFFF; static const UCHAR COMMAND_TYPE_DATA = 0x01; static const UCHAR COMMAND_TYPE_FS = 0x02; enum class BatStatus : UCHAR // Battery status definitions { NEW = 1, GOOD = 2, OK = 3, LOW = 4, CRITICAL = 5, INVALID = 7 }; enum class TimeResolution : UCHAR // Time resolution definitions { TWO = 2, // Time in interval of 2 seconds, up to 1.1 years rollover SIXTEEN = 16 // Time in interval of 16 seconds, up to 8.5 years rollover }; enum class DayOfWeek : UCHAR // defines the day of the week { SUNDAY = 0, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, INVALID }; enum class TotalSizeUnits : UCHAR { BIT = 0x00, BYTE = 0x80, BASE_UNIT = 0x08, KILO = 0x01, MEGA = 0x02, TERA = 0x03, }; enum class PairingStates : UCHAR { PAIRED = 0x00, UNPAIRED = 0x80, }; enum class ConnectionStates : UCHAR { CLOSED = 0x00, SEARCHING = 0x08, TRACKING = 0x10, }; enum class NetworkKeys : UCHAR { NETWORK_PUBLIC = 0x00, NETWORK_PRIVATE = 0x01, NETWORK_ANTPLUS = 0x02, NETWORK_ANTFS = 0x03, }; // Error handling // Flags indicate errors causing the exception ref class Error : public System::Exception{ public: BOOL bUndefPage; // Undefined page BOOL bBadReserved; // Invalid values on reserved fields BOOL bUndefBatStatus; // Undefined battery status value enum class Code : UCHAR // Error code definitions { UNDEF_COMMON_PAGE, UNDEF_BAT_STATUS, INVALID_RESERVED }; Error() { ClearFlags(); } Error(Code eCode1_) { ClearFlags(); SetFlags(eCode1_); } Error(Code eCode1_, Code eCode2_) { ClearFlags(); SetFlags(eCode1_); SetFlags(eCode2_); } private: void ClearFlags() { bUndefPage = FALSE; bBadReserved = FALSE; bUndefBatStatus = FALSE; } void SetFlags(Code eCode_) { switch(eCode_) { case Code::UNDEF_COMMON_PAGE: bUndefPage = TRUE; break; case Code::UNDEF_BAT_STATUS: bUndefBatStatus = TRUE; break; case Code::INVALID_RESERVED: bBadReserved = TRUE; break; default: break; } } }; public: //Request (page 70) UCHAR ucDescriptorByte1; UCHAR ucDescriptorByte2; UCHAR ucReqTransResp; UCHAR ucReqPageNum; UCHAR ucCommandType; //Manufacturer's Information (page 80) UCHAR ucHwVersion; // Hardware revision USHORT usMfgID; // Manufacturer ID USHORT usModelNum; // Model number // Product Information (Page 81) //Product Information (page 81) UCHAR ucSwVersion; // Software revision ULONG ulSerialNum; // Serial number // Battery Voltage (Page 82) //Battery Status (page 82) BOOL bBattPageEnabled; // variable to determine if the optional battery page is enabled ULONG ulOpTime; // Cumulative operating time since battery insertion (resolution specified by bit field) USHORT usBatVoltage256; // Battery voltage (1/256 V) BatStatus eBatStatus; // Battery status //Time and Date (page 83) TimeResolution eTimeResolution; // Resolution of cumulative operating time // Common Time Page (Page 83) BOOL bTimePageEnabled; // determines if this page is to be sent UCHAR ucSeconds; UCHAR ucMinutes; UCHAR ucHours; UCHAR ucDays; UCHAR ucMonth; UCHAR ucYears; DayOfWeek eDayOfWeek; //Memory Level (page 85) UCHAR ucPercentUsed; UCHAR ucTotalSizeExponent; UCHAR ucTotalSizeUnit; //Paired Devices (page 86) UCHAR ucPeripheralDeviceIndex; UCHAR ucTotalConnectedDevices; PairingStates ePairingState; ConnectionStates eConnectionState; NetworkKeys eNetworkKey; ULONG ulDeviceChannelId; // Error handling BOOL bValidation; // Turns validation on/off public: CommonData() { bValidation = FALSE; } ~CommonData() { } public: /************************************************************************** * CommonData::Encode * * Encodes common data * Exceptions are thrown when dealing with invalid data * * ucPageNum_: number of page to encode * pucTxBuffer_: pointer to the buffer that will store the encoded data * * returns: N/A * **************************************************************************/ void Encode(UCHAR ucPageNum_, UCHAR* pucTxBuffer_) { switch(ucPageNum_) { case PAGE70: pucTxBuffer_[0] = ucPageNum_; //Page Number (70) pucTxBuffer_[1] = RESERVED; pucTxBuffer_[2] = RESERVED; pucTxBuffer_[3] = ucDescriptorByte1; //First descriptor byte pucTxBuffer_[4] = ucDescriptorByte2; //Second descriptor byte pucTxBuffer_[5] = ucReqTransResp; //The requested transmission response pucTxBuffer_[6] = ucReqPageNum; //Request page number pucTxBuffer_[7] = ucCommandType; //Command type (Data Page or ANTFS Session) break; case PAGE80: pucTxBuffer_[0] = ucPageNum_; // Page number pucTxBuffer_[1] = RESERVED; pucTxBuffer_[2] = RESERVED; pucTxBuffer_[3] = ucHwVersion; // Hw revision pucTxBuffer_[4] = usMfgID & 0xFF; // Low byte of Mfg ID pucTxBuffer_[5] = (usMfgID >> 8) & 0xFF; // High byte of Mfg ID pucTxBuffer_[6] = usModelNum & 0xFF; // Low byte of Model Number pucTxBuffer_[7] = (usModelNum >> 8) & 0xFF; // High byte of Model Number break; case PAGE81: pucTxBuffer_[0] = ucPageNum_; // Page number pucTxBuffer_[1] = RESERVED; pucTxBuffer_[2] = RESERVED; pucTxBuffer_[3] = ucSwVersion; // Sw revision pucTxBuffer_[4] = ulSerialNum & 0xFF; // Serial number (bits 0-7) pucTxBuffer_[5] = (ulSerialNum >> 8) & 0xFF; // Serial number (bits 8-15) pucTxBuffer_[6] = (ulSerialNum >> 16) & 0xFF; // Serial number (bits 16-23) pucTxBuffer_[7] = (ulSerialNum >> 24) & 0xFF; // Serial number (bits 24-31) break; case PAGE82: pucTxBuffer_[0] = ucPageNum_; // Page number pucTxBuffer_[1] = RESERVED; pucTxBuffer_[2] = RESERVED; pucTxBuffer_[3] = ulOpTime & 0xFF; // Operating time (bits 0-7) pucTxBuffer_[4] = (ulOpTime >> 8) & 0xFF; // Operating time (bits 8-15) pucTxBuffer_[5] = (ulOpTime >> 16) & 0xFF; // Operating time (bits 16-23) pucTxBuffer_[6] = usBatVoltage256 & 0XFF; // Fractional battery voltage (1/256V) pucTxBuffer_[7] = (usBatVoltage256 >> 8) & 0x0F;// Coarse battery voltage (V) in bits 0-3 of bit field pucTxBuffer_[7] |= ((UCHAR)eBatStatus << 4) & 0x70;// Battery status in bits 4-6 of bit field if(eTimeResolution == TimeResolution::TWO) pucTxBuffer_[7] |= 0x80; // If using two second resolution, set msb break; case PAGE83: pucTxBuffer_[0] = ucPageNum_; // Page number pucTxBuffer_[1] = RESERVED; pucTxBuffer_[2] = ucSeconds; pucTxBuffer_[3] = ucMinutes; pucTxBuffer_[4] = ucHours; pucTxBuffer_[5] = ((UCHAR) eDayOfWeek << 5) & 0xE0; // day of week (bits 7-5) pucTxBuffer_[5] |= ucDays & 0x1F; // the & ensures clean bits pucTxBuffer_[6] = ucMonth; pucTxBuffer_[7] = ucYears; break; case PAGE85: pucTxBuffer_[0] = ucPageNum_; pucTxBuffer_[1] = RESERVED; pucTxBuffer_[2] = RESERVED; pucTxBuffer_[3] = RESERVED; pucTxBuffer_[4] = RESERVED; pucTxBuffer_[5] = ucPercentUsed; pucTxBuffer_[6] = ucTotalSizeExponent; pucTxBuffer_[7] = ucTotalSizeUnit; break; case PAGE86: pucTxBuffer_[0] = ucPageNum_; pucTxBuffer_[1] = ucPeripheralDeviceIndex; pucTxBuffer_[2] = ucTotalConnectedDevices; pucTxBuffer_[3] = (UCHAR)ePairingState; pucTxBuffer_[3] |= (UCHAR) eConnectionState; pucTxBuffer_[3] |= (UCHAR)eNetworkKey; pucTxBuffer_[4] = ulDeviceChannelId & 0xFF; pucTxBuffer_[5] = (ulDeviceChannelId >> 8) & 0xFF; pucTxBuffer_[6] = (ulDeviceChannelId >> 16) & 0xFF; pucTxBuffer_[7] = (ulDeviceChannelId >> 24) & 0xFF; break; default: break; } } /************************************************************************** * CommonData::Decode * * Decodes received Common Data Pages * Exceptions are thrown when dealing with invalid data * * pucRxBuffer_: pointer to the buffer containing the received data * * returns: N/A * **************************************************************************/ void Decode(UCHAR* pucRxBuffer_) { BOOL bUndefBatStatus = FALSE; switch(pucRxBuffer_[0]) { case PAGE70: ucDescriptorByte1 = pucRxBuffer_[3]; ucDescriptorByte2 = pucRxBuffer_[4]; ucReqTransResp = pucRxBuffer_[5]; ucReqPageNum = pucRxBuffer_[6]; ucCommandType = pucRxBuffer_[7]; break; case PAGE80: ucHwVersion = pucRxBuffer_[3]; // Hw revision usMfgID = pucRxBuffer_[4] | pucRxBuffer_[5] <<8; // Mfg ID usModelNum = pucRxBuffer_[6] | pucRxBuffer_[7] <<8; // Model number break; case PAGE81: ucSwVersion = pucRxBuffer_[3]; // Sw revision ulSerialNum = pucRxBuffer_[4] | pucRxBuffer_[5]<<8 | pucRxBuffer_[6]<<16 | pucRxBuffer_[7]<<24; // Serial number break; case PAGE82: ulOpTime = pucRxBuffer_[3] | pucRxBuffer_[4] << 8 | pucRxBuffer_[5] << 16; // Operating time usBatVoltage256 = pucRxBuffer_[6] | (pucRxBuffer_[7] & 0x0F) << 8; // Battery voltage if((pucRxBuffer_[7] & 0x70) == 0 || (pucRxBuffer_[7] & 0x70) == 0x60) bUndefBatStatus = TRUE; // Undefined battery status eBatStatus = (BatStatus) ((pucRxBuffer_[7] & 0x70) >> 4); // Battery status if(pucRxBuffer_[7] & 0x80) // Time resolution eTimeResolution = TimeResolution::TWO; else eTimeResolution = TimeResolution::SIXTEEN; break; case PAGE83: ucSeconds = pucRxBuffer_[2]; ucMinutes = pucRxBuffer_[3]; ucHours = pucRxBuffer_[4]; eDayOfWeek = (DayOfWeek) ((pucRxBuffer_[5] & 0xE0) >> 5); ucDays = pucRxBuffer_[5] & 0x1F; ucMonth = pucRxBuffer_[6]; ucYears = pucRxBuffer_[7]; break; case PAGE85: ucPercentUsed = pucRxBuffer_[5]; ucTotalSizeExponent = pucRxBuffer_[6]; ucTotalSizeUnit = pucRxBuffer_[7]; break; case PAGE86: ucPeripheralDeviceIndex = pucRxBuffer_[1]; ucTotalConnectedDevices = pucRxBuffer_[2]; ePairingState = (PairingStates)(pucRxBuffer_[3] & 0x80); eConnectionState = (ConnectionStates)(pucRxBuffer_[3] & 0x78); eNetworkKey = (NetworkKeys)(pucRxBuffer_[3] & 0x07); ulDeviceChannelId = pucRxBuffer_[4] | (pucRxBuffer_[5] << 8) | (pucRxBuffer_[6] << 16) | (pucRxBuffer_[7] << 24); default: break; } } /************************************************************************** * CommonData::IsBatteryVoltageInvalid * * Checks whether the battery voltage is set as invalid * * usBatVoltage256_: battery voltage (1/256 V) * * returns: N/A * **************************************************************************/ BOOL IsBatteryVoltageInvalid(USHORT usBatVoltage256_) { if((usBatVoltage256 >> 8) == BATTERY_VOLTAGE_INVALID) return TRUE; else return FALSE; } /************************************************************************** * CommonData::IsBatteryStatusInvalid * * Checks whether the battery status is set as invalid * * eBatStatus_: battery status code * * returns: N/A * **************************************************************************/ BOOL IsBatteryStatusInvalid(BatStatus eBatStatus_) { if(eBatStatus_ == BatStatus::INVALID) return TRUE; else return FALSE; } /************************************************************************** * CommonData::IsDayofWeekValid * * Checks whether the battery status is set as invalid * * eBatStatus_: battery status code * * returns: N/A * **************************************************************************/ BOOL IsDayOfWeekValid(DayOfWeek eDay_) { if (eDay_ == DayOfWeek::INVALID) return FALSE; else return TRUE; } };