Fork to see if I can get working

Dependencies:   BufferedSerial OneWire WinbondSPIFlash libxDot-dev-mbed5-deprecated

Fork of xDotBridge_update_test20180823 by Matt Briggs

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CommProtocolPeerBrute.h Source File

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