Fork to see if I can get working
Dependencies: BufferedSerial OneWire WinbondSPIFlash libxDot-dev-mbed5-deprecated
Fork of xDotBridge_update_test20180823 by
xDotBridge/inc/CommProtocolPeerBrute.h
- Committer:
- mbriggs_vortex
- Date:
- 2017-11-29
- Revision:
- 100:0882cf295f8e
- Parent:
- 70:6b3ca63792c2
File content as of revision 100:0882cf295f8e:
/** * Library for LoRa Peer to Peer Brute Force Protocol */ #ifndef COMMPROTOCOLPEERBRUTE_H_ #define COMMPROTOCOLPEERBRUTE_H_ #include <inttypes.h> #include <vector> #include "../config.h" #include "mDot.h" // TODO make base class to allow different protocols to be used with easy // TODO wrap radio commands for error checking // TODO change to const static uint8_t pair_network_address[] = { 0x01, 0x00, 0x00, 0x00 }; // 0x00000000 reserved for multicast so use 1 static uint8_t pair_network_session_key[] = { 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04 }; static uint8_t pair_data_session_key[] = { 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04 }; const uint16_t PROTOCOL_NVM_START_ADDR = 0x1000; const uint16_t PROTOCOL_NVM_SIZE = 54; // Bytes const uint16_t PROTOCOL_FLAG = 0x5A00; const uint16_t PROTOCOL_REV = 0x0002; /** * @class NvmProtocolObj * @brief This convenience class implements helps storing protocol settings to non-volatile memory * * @details This class can translate to and from a byte array which can be stored then be easily stored * using any number of APIs. */ class NvmProtocolObj { public: /** * @brief NvmProtocolObj constructor * @details Initializes internal values with defaults */ NvmProtocolObj(); /** * @brief Set all internal variables to defaults. This is automatically called from constructor. */ void setDefaults(); /** * @brief Saves internal state from a byte array */ CmdResult toBytes(uint8_t *data, uint8_t &size); /** * @brief Loads internal state from a byte array. This byte array should typically have * previously generated by the toBytes function. */ CmdResult fromBytes(uint8_t *data, uint8_t size); /** * @brief Accessor for protocol flag */ uint16_t getProtocolFlag(); /** * @brief Checks if protocol flag is valid */ bool validProtocolFlag(); /** * @brief Accessor for protocol rev */ uint16_t getProtocolRev(); /** * @brief Checks if the revision of the protocol matches */ bool validProtocolRev(); /** * @brief Accessor for network address. Note value is returned via parameter. * @param addr A STL vector which will be set to 4 byte address */ void getNetworkAddr(std::vector<uint8_t> &addr); /** * @brief A setter for network address * @param addr The network address to be stored. This value should be 4 bytes. */ void setNetworkAddr(const std::vector<uint8_t> &addr); /** * @brief Accessor for network session key. Value return via parameter * @param key A STL Vector which will be set with 16 byte key */ void getNetworkSessionKey(std::vector<uint8_t> &key); /** * @brief A setter for network session key * * @param key The network session key to be stored. This value should be 16 bytes. */ void setNetworkSessionKey(const std::vector<uint8_t> &key); /** * @brief Accessor for data session key. Value return via parameter * @param key A STL Vector which will be set with 16 byte key */ void getDataSessionKey(std::vector<uint8_t> &key); /** * @brief A setter for data session key * @param key The network session key to be stored. This value should be 16 bytes. */ void setDataSessionKey(const std::vector<uint8_t> &key); /** * @brief A accessor for logical address */ uint16_t getLogicalAddr(); /** * @brief A setter for logical address * @param in Value for logical address */ void setLogicalAddr(uint16_t in); /** * @brief A accessor for LastMsgSeq */ uint32_t getLastMsgSeq(); /** * @brief A setter for LastMsgSeq * @param in Value for ter for LastMsgSeq */ void setLastMsgSeq(uint32_t in); /** * @brief A convenience method which increments LastMsgSeq */ void incLastMsgSeq(); // TODO some day make these private with setters and getters uint8_t mNetworkAddr[4]; uint8_t mNetworkSessionKey[16]; uint8_t mDataSessionKey[16]; private: uint16_t mProtocolFlag; uint16_t mProtocolRev; uint32_t mFreq; uint16_t mLogicalAddr; uint32_t mSeqNum; }; /** * @class CommProtocolPeerBrute * @brief This class implements a peer-to-peer (P2P) brute force protocol. * * @details The protocol consists of at a minimum one transmitter (TX) and one * receiver (RX) which communicate via the 900MHz LoRa modulation. The concept * is that the RX is cycling on and off thus only listening for a small period * of time. Since we are not relying on a common time-base or other * synchronization mechanism the TX simply transmits for a duration long enough * guarantee that the RX will have at least one receive window during that time * period. Hence the name brute since the TX is just transmitting plenty for * the RX to hear it. * * The following should be implemented outside of the class: * - Power settings? * - What to do with the msgs which are received * - When to send messages * - When to sleep * */ class CommProtocolPeerBrute { public: /** * @brief CommProtocolPeerBrute constructor * * @details Just initialized internal variables does not configure devices. * Should call init before other functions are called. * * On Entry: * * On Exit: * Internal variables are set to a known state but further initialization is required * * @return */ CommProtocolPeerBrute(); /** * Attempts to read values from NVM (xDot's eeprom) if failure saves defaults. Then * configures radio with settings. * @return Success unless radio configuration error */ CmdResult init(); /** * @brief Initialize radio with stored network network settings * * @return Returns the result of all the radio commands */ CmdResult configForSavedNetwork(); /** * @brief Sets weather this object is configured as a TX or RX * * @param isTx if true then configured as transmitter if false then configured as receiver. */ void setTx(bool isTx); /** * @brief Returns weather this object is configured as a TX or RX * @return Returns true if TX */ bool isTx(); /** * @brief Returns weather this object is configured as a TX or RX * @return Returns true if RX */ bool isRx() {return !isTx();} /** * @brief This will clear the security pairs and channel info for pair * * @details This will clear both the value in RAM as well as the value stored in EEPROM for security and * clarity purposes. If RX this command will automatically trigger the generation of new security keys and * pair specific parameters. * * @return Returns status of all commands completed */ CmdResult clearPair(); // TX focused /** * @brief Accessor sequence number * @return Integer value */ uint32_t getSeqNum(); /** * @brief Transmit the msg attached * * @details TODO figure out what information is wrapped by the LoRaWAN stuff implemented by * Multitech Systems * * @param msg A STL vector of uint8_t * @return Returns status of all commands completed */ CmdResult send (const std::vector<uint8_t> &msg); /** * @brief Transmit an alert per documentation * * @details Sends EUI, uint16 data, alert seqNum * * @param data Input data to send * @return if transmission is successful (note no ACK checked) */ CmdResult sendAlert (uint16_t data); /** * @brief This function sends a request to pair with a RX. If successful a pair accept message is received. * * @return Returns status of all commands completed */ CmdResult sendPairReq(); // RX focused /** * @brief This function enables the RX hardware of a radio. Note the listen time is defined internally by the protocol * * @param msgPending This boolean is return by reference. If true then during the listen window a msg was received. * @return Returns status of all commands completed */ CmdResult listen (bool &msgPending); /** * @brief Returns the last message received via listening * * @param msg This STL vector of uint8_t is returned by reference with msg contents. * @return Returns status of all commands completed */ CmdResult recv (std::vector<uint8_t> &msg); /** * @brief Attempts to parse and return the last message received * * @details If the message is too short or if the flag is not correct will return an error. * * @param eui 4 byte value returned * @param data Data field from alert message * @param seqNum Transmitter's sequence number * @return Returns status of all commands completed */ CmdResult recvAlert (std::vector<uint8_t> &eui, uint16_t &data, uint32_t &seqNum); /** * @brief This function enables the radio to listen for pair requests. * @param waitTime The maximum time which radio waits for pair requests * * TODO determine if it is important to know who is paired * * @return If pair message received then cmdSucess is returned otherwise * timeout is returned. */ CmdResult waitForPairing(float waitTime); /** * @brief Send a pair accept message. This message contains all the information for TX to properly send * msgs to RX in P2P mode. * @return Returns status of all commands completed */ CmdResult sendPairAccepted(); /** * * @param waitTime * @return */ CmdResult waitForAccept(float waitTime); // xDot Peer to Peer Specific /** * Convenience function to get the internal downlink count from radio * @return Number of downlink msgs */ uint32_t getDLC(); /** * Convenience function to get the internal uplink count from radio * @return Number of uplink msgs */ uint32_t getULC(); /** * Resets both uplink and downlink counters (1 and 0 respectively). * @return */ CmdResult resetCounters(); // TODO maybe this should be private CmdResult configForPairingNetwork(); void printDotConfig(); private: NvmProtocolObj mMemObj; bool mIsTx; uint32_t mPrevDownLinkCnt; /** * @brief Reads baseboard information from non-volatile memory (NVM) * * @details This data is read from the xDot's internal EEPROM. This * method is called from init(). The following * is stored: * 1. Peer Brute Storage code word * 2. 8-bit protocol version * 3. 16-bit Baseboard serial number * 4. 4 Byte network address * 5. 16 Byte network session key * 6. 16 Byte data session key * 7. 4 Byte DLC * 8. 4 Byte ULC * * TODO add memory map information * * @return CmdResult */ CmdResult readInfoFromNVM(); /** * @brief Stores baseboard information to non-volatile memory (NVM) * * @details This method is called during special configuration events like first time boot or factory reset. * * TODO add memory map information * * @return CmdResult */ CmdResult writeInfoToNVM(); /** * Generates new encryption keys for radio * @return */ CmdResult genEncypKey(std::vector<uint8_t> &newKey, uint8_t keySize, bool allowZero); CmdResult genEncypKey(std::vector<uint8_t> &newKey, uint8_t keySize); }; #endif