Fork to see if I can get working
Dependencies: BufferedSerial OneWire WinbondSPIFlash libxDot-dev-mbed5-deprecated
Fork of xDotBridge_update_test20180823 by
CommProtocolPeerBrute.h
00001 /** 00002 * Library for LoRa Peer to Peer Brute Force Protocol 00003 */ 00004 00005 #ifndef COMMPROTOCOLPEERBRUTE_H_ 00006 #define COMMPROTOCOLPEERBRUTE_H_ 00007 00008 #include <inttypes.h> 00009 #include <vector> 00010 #include "../config.h" 00011 #include "mDot.h" 00012 00013 // TODO make base class to allow different protocols to be used with easy 00014 // TODO wrap radio commands for error checking 00015 00016 // TODO change to const 00017 static uint8_t pair_network_address[] = { 0x01, 0x00, 0x00, 0x00 }; // 0x00000000 reserved for multicast so use 1 00018 static uint8_t pair_network_session_key[] = { 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04 }; 00019 static uint8_t pair_data_session_key[] = { 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04 }; 00020 00021 const uint16_t PROTOCOL_NVM_START_ADDR = 0x1000; 00022 const uint16_t PROTOCOL_NVM_SIZE = 54; // Bytes 00023 const uint16_t PROTOCOL_FLAG = 0x5A00; 00024 const uint16_t PROTOCOL_REV = 0x0002; 00025 00026 /** 00027 * @class NvmProtocolObj 00028 * @brief This convenience class implements helps storing protocol settings to non-volatile memory 00029 * 00030 * @details This class can translate to and from a byte array which can be stored then be easily stored 00031 * using any number of APIs. 00032 */ 00033 class NvmProtocolObj { 00034 public: 00035 /** 00036 * @brief NvmProtocolObj constructor 00037 * @details Initializes internal values with defaults 00038 */ 00039 NvmProtocolObj(); 00040 00041 /** 00042 * @brief Set all internal variables to defaults. This is automatically called from constructor. 00043 */ 00044 void setDefaults(); 00045 00046 /** 00047 * @brief Saves internal state from a byte array 00048 */ 00049 CmdResult toBytes(uint8_t *data, uint8_t &size); 00050 00051 /** 00052 * @brief Loads internal state from a byte array. This byte array should typically have 00053 * previously generated by the toBytes function. 00054 */ 00055 CmdResult fromBytes(uint8_t *data, uint8_t size); 00056 00057 /** 00058 * @brief Accessor for protocol flag 00059 */ 00060 uint16_t getProtocolFlag(); 00061 00062 /** 00063 * @brief Checks if protocol flag is valid 00064 */ 00065 bool validProtocolFlag(); 00066 00067 /** 00068 * @brief Accessor for protocol rev 00069 */ 00070 uint16_t getProtocolRev(); 00071 00072 /** 00073 * @brief Checks if the revision of the protocol matches 00074 */ 00075 bool validProtocolRev(); 00076 00077 /** 00078 * @brief Accessor for network address. Note value is returned via parameter. 00079 * @param addr A STL vector which will be set to 4 byte address 00080 */ 00081 void getNetworkAddr(std::vector<uint8_t> &addr); 00082 00083 /** 00084 * @brief A setter for network address 00085 * @param addr The network address to be stored. This value should be 4 bytes. 00086 */ 00087 void setNetworkAddr(const std::vector<uint8_t> &addr); 00088 00089 /** 00090 * @brief Accessor for network session key. Value return via parameter 00091 * @param key A STL Vector which will be set with 16 byte key 00092 */ 00093 void getNetworkSessionKey(std::vector<uint8_t> &key); 00094 00095 /** 00096 * @brief A setter for network session key 00097 * 00098 * @param key The network session key to be stored. This value should be 16 bytes. 00099 */ 00100 void setNetworkSessionKey(const std::vector<uint8_t> &key); 00101 00102 /** 00103 * @brief Accessor for data session key. Value return via parameter 00104 * @param key A STL Vector which will be set with 16 byte key 00105 */ 00106 void getDataSessionKey(std::vector<uint8_t> &key); 00107 00108 /** 00109 * @brief A setter for data session key 00110 * @param key The network session key to be stored. This value should be 16 bytes. 00111 */ 00112 void setDataSessionKey(const std::vector<uint8_t> &key); 00113 00114 /** 00115 * @brief A accessor for logical address 00116 */ 00117 uint16_t getLogicalAddr(); 00118 00119 /** 00120 * @brief A setter for logical address 00121 * @param in Value for logical address 00122 */ 00123 void setLogicalAddr(uint16_t in); 00124 00125 /** 00126 * @brief A accessor for LastMsgSeq 00127 */ 00128 uint32_t getLastMsgSeq(); 00129 00130 /** 00131 * @brief A setter for LastMsgSeq 00132 * @param in Value for ter for LastMsgSeq 00133 */ 00134 void setLastMsgSeq(uint32_t in); 00135 00136 /** 00137 * @brief A convenience method which increments LastMsgSeq 00138 */ 00139 void incLastMsgSeq(); 00140 00141 // TODO some day make these private with setters and getters 00142 uint8_t mNetworkAddr[4]; 00143 uint8_t mNetworkSessionKey[16]; 00144 uint8_t mDataSessionKey[16]; 00145 private: 00146 uint16_t mProtocolFlag; 00147 uint16_t mProtocolRev; 00148 uint32_t mFreq; 00149 uint16_t mLogicalAddr; 00150 uint32_t mSeqNum; 00151 }; 00152 00153 /** 00154 * @class CommProtocolPeerBrute 00155 * @brief This class implements a peer-to-peer (P2P) brute force protocol. 00156 * 00157 * @details The protocol consists of at a minimum one transmitter (TX) and one 00158 * receiver (RX) which communicate via the 900MHz LoRa modulation. The concept 00159 * is that the RX is cycling on and off thus only listening for a small period 00160 * of time. Since we are not relying on a common time-base or other 00161 * synchronization mechanism the TX simply transmits for a duration long enough 00162 * guarantee that the RX will have at least one receive window during that time 00163 * period. Hence the name brute since the TX is just transmitting plenty for 00164 * the RX to hear it. 00165 * 00166 * The following should be implemented outside of the class: 00167 * - Power settings? 00168 * - What to do with the msgs which are received 00169 * - When to send messages 00170 * - When to sleep 00171 * 00172 */ 00173 class CommProtocolPeerBrute 00174 { 00175 public: 00176 /** 00177 * @brief CommProtocolPeerBrute constructor 00178 * 00179 * @details Just initialized internal variables does not configure devices. 00180 * Should call init before other functions are called. 00181 * 00182 * On Entry: 00183 * 00184 * On Exit: 00185 * Internal variables are set to a known state but further initialization is required 00186 * 00187 * @return 00188 */ 00189 CommProtocolPeerBrute(); 00190 00191 /** 00192 * Attempts to read values from NVM (xDot's eeprom) if failure saves defaults. Then 00193 * configures radio with settings. 00194 * @return Success unless radio configuration error 00195 */ 00196 CmdResult init(); 00197 00198 /** 00199 * @brief Initialize radio with stored network network settings 00200 * 00201 * @return Returns the result of all the radio commands 00202 */ 00203 CmdResult configForSavedNetwork(); 00204 00205 /** 00206 * @brief Sets weather this object is configured as a TX or RX 00207 * 00208 * @param isTx if true then configured as transmitter if false then configured as receiver. 00209 */ 00210 void setTx(bool isTx); 00211 00212 /** 00213 * @brief Returns weather this object is configured as a TX or RX 00214 * @return Returns true if TX 00215 */ 00216 bool isTx(); 00217 00218 /** 00219 * @brief Returns weather this object is configured as a TX or RX 00220 * @return Returns true if RX 00221 */ 00222 bool isRx() {return !isTx();} 00223 00224 /** 00225 * @brief This will clear the security pairs and channel info for pair 00226 * 00227 * @details This will clear both the value in RAM as well as the value stored in EEPROM for security and 00228 * clarity purposes. If RX this command will automatically trigger the generation of new security keys and 00229 * pair specific parameters. 00230 * 00231 * @return Returns status of all commands completed 00232 */ 00233 CmdResult clearPair(); 00234 00235 // TX focused 00236 /** 00237 * @brief Accessor sequence number 00238 * @return Integer value 00239 */ 00240 uint32_t getSeqNum(); 00241 /** 00242 * @brief Transmit the msg attached 00243 * 00244 * @details TODO figure out what information is wrapped by the LoRaWAN stuff implemented by 00245 * Multitech Systems 00246 * 00247 * @param msg A STL vector of uint8_t 00248 * @return Returns status of all commands completed 00249 */ 00250 CmdResult send (const std::vector<uint8_t> &msg); 00251 00252 /** 00253 * @brief Transmit an alert per documentation 00254 * 00255 * @details Sends EUI, uint16 data, alert seqNum 00256 * 00257 * @param data Input data to send 00258 * @return if transmission is successful (note no ACK checked) 00259 */ 00260 CmdResult sendAlert (uint16_t data); 00261 00262 /** 00263 * @brief This function sends a request to pair with a RX. If successful a pair accept message is received. 00264 * 00265 * @return Returns status of all commands completed 00266 */ 00267 CmdResult sendPairReq(); 00268 00269 // RX focused 00270 /** 00271 * @brief This function enables the RX hardware of a radio. Note the listen time is defined internally by the protocol 00272 * 00273 * @param msgPending This boolean is return by reference. If true then during the listen window a msg was received. 00274 * @return Returns status of all commands completed 00275 */ 00276 CmdResult listen (bool &msgPending); 00277 00278 /** 00279 * @brief Returns the last message received via listening 00280 * 00281 * @param msg This STL vector of uint8_t is returned by reference with msg contents. 00282 * @return Returns status of all commands completed 00283 */ 00284 CmdResult recv (std::vector<uint8_t> &msg); 00285 00286 /** 00287 * @brief Attempts to parse and return the last message received 00288 * 00289 * @details If the message is too short or if the flag is not correct will return an error. 00290 * 00291 * @param eui 4 byte value returned 00292 * @param data Data field from alert message 00293 * @param seqNum Transmitter's sequence number 00294 * @return Returns status of all commands completed 00295 */ 00296 CmdResult recvAlert (std::vector<uint8_t> &eui, uint16_t &data, uint32_t &seqNum); 00297 00298 /** 00299 * @brief This function enables the radio to listen for pair requests. 00300 * @param waitTime The maximum time which radio waits for pair requests 00301 * 00302 * TODO determine if it is important to know who is paired 00303 * 00304 * @return If pair message received then cmdSucess is returned otherwise 00305 * timeout is returned. 00306 */ 00307 CmdResult waitForPairing(float waitTime); 00308 00309 /** 00310 * @brief Send a pair accept message. This message contains all the information for TX to properly send 00311 * msgs to RX in P2P mode. 00312 * @return Returns status of all commands completed 00313 */ 00314 CmdResult sendPairAccepted(); 00315 00316 /** 00317 * 00318 * @param waitTime 00319 * @return 00320 */ 00321 CmdResult waitForAccept (float waitTime); 00322 00323 // xDot Peer to Peer Specific 00324 /** 00325 * Convenience function to get the internal downlink count from radio 00326 * @return Number of downlink msgs 00327 */ 00328 uint32_t getDLC(); 00329 00330 /** 00331 * Convenience function to get the internal uplink count from radio 00332 * @return Number of uplink msgs 00333 */ 00334 uint32_t getULC(); 00335 00336 /** 00337 * Resets both uplink and downlink counters (1 and 0 respectively). 00338 * @return 00339 */ 00340 CmdResult resetCounters(); 00341 00342 // TODO maybe this should be private 00343 CmdResult configForPairingNetwork(); 00344 void printDotConfig(); 00345 00346 private: 00347 NvmProtocolObj mMemObj; 00348 bool mIsTx; 00349 uint32_t mPrevDownLinkCnt; 00350 00351 /** 00352 * @brief Reads baseboard information from non-volatile memory (NVM) 00353 * 00354 * @details This data is read from the xDot's internal EEPROM. This 00355 * method is called from init(). The following 00356 * is stored: 00357 * 1. Peer Brute Storage code word 00358 * 2. 8-bit protocol version 00359 * 3. 16-bit Baseboard serial number 00360 * 4. 4 Byte network address 00361 * 5. 16 Byte network session key 00362 * 6. 16 Byte data session key 00363 * 7. 4 Byte DLC 00364 * 8. 4 Byte ULC 00365 * 00366 * TODO add memory map information 00367 * 00368 * @return CmdResult 00369 */ 00370 CmdResult readInfoFromNVM(); 00371 00372 /** 00373 * @brief Stores baseboard information to non-volatile memory (NVM) 00374 * 00375 * @details This method is called during special configuration events like first time boot or factory reset. 00376 * 00377 * TODO add memory map information 00378 * 00379 * @return CmdResult 00380 */ 00381 CmdResult writeInfoToNVM(); 00382 00383 /** 00384 * Generates new encryption keys for radio 00385 * @return 00386 */ 00387 CmdResult genEncypKey(std::vector<uint8_t> &newKey, uint8_t keySize, bool allowZero); 00388 CmdResult genEncypKey(std::vector<uint8_t> &newKey, uint8_t keySize); 00389 00390 }; 00391 00392 00393 #endif
Generated on Fri Jul 15 2022 14:36:45 by 1.7.2