Fork to see if I can get working

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

Fork of xDotBridge_update_test20180823 by Matt Briggs

Revision:
62:9751a8504c82
Parent:
61:8d9efd33cac9
Child:
63:e1efbe3402d9
diff -r 8d9efd33cac9 -r 9751a8504c82 xDotBridge/src/CommProtocolPeerBrute.cpp
--- a/xDotBridge/src/CommProtocolPeerBrute.cpp	Thu Mar 09 16:47:42 2017 -0700
+++ b/xDotBridge/src/CommProtocolPeerBrute.cpp	Tue Mar 14 08:32:55 2017 -0600
@@ -21,21 +21,34 @@
     logInfo("RX_SLEEP_TIME %f, timeOnAir %lu, nTimesToTx %lu", RX_SLEEP_TIME, TX_TIME, nTimesToTx);
 
     mIsTx = true; // default to TX
-//    mPrevDownLinkCnt = dot->getDownLinkCounter();
 }
 
 CmdResult CommProtocolPeerBrute::init()
 {
-    // FIXME add NVM stuff
-    dotDefaults();
+    CmdResult result;
+    if (dot == NULL) {
+        return cmdError;
+    }
+    result = readInfoFromNVM();
+    if (result != cmdSuccess) {
+        logInfo("Reverting to protocol defaults NVM Read failed");
+        mMemObj.setDefaults();
+    }
+    configForSavedNetwork();
 
+    writeInfoToNVM();
+
+    mPrevDownLinkCnt = dot->getDownLinkCounter();
     return cmdSuccess;
 }
-CmdResult CommProtocolPeerBrute::dotDefaults()
+CmdResult CommProtocolPeerBrute::configForSavedNetwork()
 {
-    // TODO add more error checking
-    logWarning("defaulting Dot configuration");
-    dot->resetConfig();
+    if (dot == NULL) {
+        return cmdError;
+    }
+
+//    logInfo("defaulting Dot configuration");
+//    dot->resetConfig();
 
     // Common Configuration
     dot->setAesEncryption(true);  // Enable encryption
@@ -43,7 +56,7 @@
     dot->setAck(0);  // Disable Ack
     dot->setClass("C"); // Set class C
     dot->setTxPower(TX_PWR);
-    dot->setPreserveSession(false); // TODO need to better handle counters
+    dot->setPreserveSession(false);
 
     // TODO break out in a utility function
     // update configuration if necessary
@@ -88,13 +101,37 @@
     // in PEER_TO_PEER mode there is no join request/response transaction
     // as long as both Dots are configured correctly, they should be able to communicate
 
-    // FIXME just using pairing keys for now
-    update_peer_to_peer_config(pair_network_address, pair_network_session_key, pair_data_session_key, tx_frequency, tx_datarate, tx_power);
+    update_peer_to_peer_config(mMemObj.mNetworkAddr, mMemObj.mNetworkSessionKey,
+            mMemObj.mDataSessionKey, tx_frequency, tx_datarate, tx_power);
     dot->saveConfig();
     return cmdSuccess;
 }
 CmdResult CommProtocolPeerBrute::configForPairingNetwork()
 {
+    if (dot == NULL) {
+        return cmdError;
+    }
+
+//    logInfo("defaulting Dot configuration");
+//    dot->resetConfig();
+
+    // Common Configuration
+    dot->setAesEncryption(true);  // Enable encryption
+    dot->setTxWait(false);
+    dot->setAck(0);  // Disable Ack
+    dot->setClass("C"); // Set class C
+    dot->setTxPower(TX_PWR);
+    dot->setPreserveSession(false);
+    // TODO break out in a utility function
+    // update configuration if necessary
+    logInfo("Setting up peer to peer configuration");
+    if (dot->getJoinMode() != mDot::PEER_TO_PEER) {
+        logInfo("changing network join mode to PEER_TO_PEER");
+        if (dot->setJoinMode(mDot::PEER_TO_PEER) != mDot::MDOT_OK) {
+            logError("failed to set network join mode to PEER_TO_PEER");
+        }
+    }
+
     uint8_t tx_power;
     uint8_t tx_datarate;
     uint32_t tx_frequency;
@@ -127,8 +164,7 @@
             break;
     }
     update_peer_to_peer_config(pair_network_address, pair_network_session_key, pair_data_session_key, tx_frequency, tx_datarate, tx_power);
-    // TODO experiment if we need to save as I will need to save off previous settings to revert back
-//    dot->saveConfig();
+    dot->saveConfig(); // This is required for network settings to apply
     return cmdSuccess;
 }
 void CommProtocolPeerBrute::setTx(bool isTx)
@@ -147,26 +183,53 @@
     std::vector<uint8_t> key;
     key.reserve(16);
 
-    result = genEncypKey(key, 8);
+    // REPLACE WITH NETWORK ADDRESS
+//    result = genEncypKey(key, 8);
+//    if (result != cmdSuccess) {
+//        logError("Error generating network ID.");
+//        return cmdError;
+//    }
+//    if (dot->setNetworkId(key) != mDot::MDOT_OK) {
+//        logError("Error setting network ID.");
+//        return cmdError;
+//    }
+
+    result = genEncypKey(key, 4, false);
     if (result != cmdSuccess) {
-        logError("Error generating network ID.");
+        logError("Error generating network address.");
         return cmdError;
     }
-    dot->setNetworkId(key);
+    mMemObj.setNetworkAddr(key);
+//    if (dot->setNetworkAddress(key) != mDot::MDOT_OK) {
+//        logError("Error setting network address.");
+//        return cmdError;
+//    }
 
     result = genEncypKey(key, 16);
     if (result != cmdSuccess) {
         logError("Error generating network encryption keys.");
         return cmdError;
     }
-    dot->setNetworkKey(key);
+    mMemObj.setNetworkSessionKey(key);
+//    if (dot->setNetworkSessionKey(key) != mDot::MDOT_OK) {
+//        logError("Error setting network session key.");
+//        return cmdError;
+//    }
 
     result = genEncypKey(key, 16);
     if (result != cmdSuccess) {
         logError("Error generating data session encryption keys.");
         return cmdError;
     }
-    dot->setDataSessionKey(key);
+    mMemObj.setDataSessionKey(key);
+//    if (dot->setDataSessionKey(key) != mDot::MDOT_OK) {
+//        logError("Error setting data session key.");
+//        return cmdError;
+//    }
+
+    configForSavedNetwork();
+    writeInfoToNVM();
+    display_config();
 
     return cmdSuccess;
 }
@@ -252,7 +315,6 @@
     if (!msgPending) {
         return cmdTimeout;
     }
-    // TODO check request
 
     wait(1.0);  // Wait just a little so it is clear for requester that it is a pair message
     return sendPairAccepted();
@@ -280,20 +342,23 @@
     }
     logInfo("freq msg size %d", msg->size());
 
-    // Network ID
-    std::vector<uint8_t> *networkId = new std::vector<uint8_t>(dot->getNetworkId());
-    msg->insert(msg->end(),networkId->begin(), networkId->end());
-    delete networkId;
-    logInfo("netid msg size %d", msg->size());
+    // Network Address
+    std::vector<uint8_t> *networkAddr = new std::vector<uint8_t>;
+    mMemObj.getNetworkAddr(*networkAddr);
+    msg->insert(msg->end(),networkAddr->begin(), networkAddr->end());
+    delete networkAddr;
+    logInfo("netAddr msg size %d", msg->size());
 
-    // Network key
-    std::vector<uint8_t> *networkKey = new std::vector<uint8_t>(dot->getNetworkKey());
-    msg->insert(msg->end(),networkKey->begin(), networkKey->end());
-    delete networkKey;
-    logInfo("netKey msg size %d", msg->size());
+    // Network session key
+    std::vector<uint8_t> *networkSessionKey = new std::vector<uint8_t>;
+    mMemObj.getNetworkSessionKey(*networkSessionKey);
+    msg->insert(msg->end(),networkSessionKey->begin(), networkSessionKey->end());
+    delete networkSessionKey;
+    logInfo("netSessionKey msg size %d", msg->size());
 
     // Data session key
-    std::vector<uint8_t> *dataSessionKey = new std::vector<uint8_t>(dot->getDataSessionKey());
+    std::vector<uint8_t> *dataSessionKey = new std::vector<uint8_t>;
+    mMemObj.getDataSessionKey(*dataSessionKey);
     msg->insert(msg->end(),dataSessionKey->begin(), dataSessionKey->end());
     delete dataSessionKey;
 
@@ -320,7 +385,27 @@
     if (!msgPending) {
         return cmdTimeout;
     }
-    // TODO check request
+
+    std::vector<uint8_t> acceptMsg;
+    dot->recv(acceptMsg);
+    if (acceptMsg[0] != 0xFD || acceptMsg[1] != 0x02) {
+        logError("Invalid accept message flag.");
+        return cmdError;
+    }
+
+    std::vector<uint8_t> *netAddr = new std::vector<uint8_t>(acceptMsg.begin()+0x0E, acceptMsg.begin()+0x12);
+    mMemObj.setNetworkAddr(*netAddr);
+    delete netAddr;
+
+    std::vector<uint8_t> *netSessionKey = new std::vector<uint8_t>(acceptMsg.begin()+0x12, acceptMsg.begin()+0x22);
+    mMemObj.setNetworkSessionKey(*netSessionKey);
+    delete netSessionKey;
+
+    std::vector<uint8_t> *dataSessionKey = new std::vector<uint8_t>(acceptMsg.begin()+0x22, acceptMsg.begin()+0x32);
+    mMemObj.setDataSessionKey(*dataSessionKey);
+    delete dataSessionKey;
+
+    writeInfoToNVM();
 
     return cmdSuccess;
 }
@@ -340,7 +425,6 @@
 
 CmdResult CommProtocolPeerBrute::readInfoFromNVM()
 {
-    // TODO store / retrieve network keys
     bool nvmReadResult;
     uint8_t *data = new uint8_t [PROTOCOL_NVM_SIZE];
 
@@ -354,12 +438,12 @@
     if (!mMemObj.validProtocolFlag()) {
         logWarning("Invalid Protocol Flag.  Using default values.");
         mMemObj.setDefaults();
-        dotDefaults();
+        return cmdError;
     }
     else if (!mMemObj.validProtocolRev()) {
         logWarning("Invalid Protocol Rev.  Using default values.");
         mMemObj.setDefaults();
-        dotDefaults();
+        return cmdError;
     }
     return cmdSuccess;
 }
@@ -384,9 +468,18 @@
 
 CmdResult CommProtocolPeerBrute::genEncypKey(std::vector<uint8_t> &newKey, uint8_t keySize)
 {
+    return genEncypKey(newKey, keySize, true); // Default allow zero
+}
+CmdResult CommProtocolPeerBrute::genEncypKey(std::vector<uint8_t> &newKey, uint8_t keySize, bool allowZero)
+{
     newKey.clear();
     for (uint8_t i=0;i<keySize; i++){
-        newKey.push_back(dot->getRadioRandom());
+        if (allowZero) {
+            newKey.push_back(dot->getRadioRandom() & 0xFF);
+        }
+        else {
+            newKey.push_back((dot->getRadioRandom() % 254) + 1);
+        }
     }
     return cmdSuccess;
 }
@@ -400,6 +493,10 @@
 {
     mProtocolFlag = PROTOCOL_FLAG;
     mProtocolRev = PROTOCOL_REV;
+    mFreq = 915500000;
+    std::memset(mNetworkAddr, 0x00, sizeof(mNetworkAddr));
+    std::memset(mNetworkSessionKey, 0x00, sizeof(mNetworkSessionKey));
+    std::memset(mDataSessionKey, 0x00, sizeof(mDataSessionKey));
     mLogicalAddr = 0x00000000;
     mSeqNum = 0x00000000;
 }
@@ -410,9 +507,13 @@
     }
 
     mProtocolFlag   = *((uint16_t *) (data));
-    mProtocolRev    = *((uint16_t *) (data+2));
-    mLogicalAddr    = *((uint32_t *) (data+4));
-    mSeqNum         = *((uint32_t *) (data+6));
+    mProtocolRev    = *((uint16_t *) (data+0x02));
+    mFreq           = *((uint32_t *) (data+0x04));
+    std::memcpy(&mNetworkAddr,        data+0x08, 4);
+    std::memcpy(&mNetworkSessionKey,  data+0x10, 16);
+    std::memcpy(&mDataSessionKey,     data+0x20, 16);
+    mLogicalAddr    = *((uint32_t *) (data+0x30));
+    mSeqNum         = *((uint32_t *) (data+0x32));
 
     return cmdSuccess;
 }
@@ -421,8 +522,12 @@
 
     *((uint16_t *) (data))   = mProtocolFlag;
     *((uint16_t *) (data+2)) = mProtocolRev;
-    *((uint32_t *) (data+4)) = mLogicalAddr;
-    *((uint32_t *) (data+6)) = mSeqNum;
+    *((uint32_t *) (data+0x04)) = mFreq;
+    std::memcpy(data+0x08, &mNetworkAddr, 4);
+    std::memcpy(data+0x10, &mNetworkSessionKey, 16);
+    std::memcpy(data+0x20, &mDataSessionKey, 16);
+    *((uint32_t *) (data+0x30)) = mLogicalAddr;
+    *((uint32_t *) (data+0x32)) = mSeqNum;
 
     size = PROTOCOL_NVM_SIZE;
 
@@ -444,6 +549,51 @@
 {
     return mProtocolRev == PROTOCOL_REV;
 }
+void NvmProtocolObj::getNetworkAddr(std::vector<uint8_t> &addr)
+{
+    addr.clear();
+    addr.assign(mNetworkAddr, mNetworkAddr+sizeof(mNetworkAddr));
+}
+void NvmProtocolObj::setNetworkAddr(const std::vector<uint8_t> &addr)
+{
+    if (addr.size() > sizeof(mNetworkAddr)) {
+        // TODO log error
+        return;
+    }
+    for (uint8_t i=0; i < sizeof(mNetworkAddr); i++) {
+        mNetworkAddr[i] = addr[i];
+    }
+}
+void NvmProtocolObj::getNetworkSessionKey(std::vector<uint8_t> &key)
+{
+    key.clear();
+    key.assign(mNetworkSessionKey, mNetworkSessionKey+sizeof(mNetworkSessionKey));
+}
+void NvmProtocolObj::setNetworkSessionKey(const std::vector<uint8_t> &key)
+{
+    if (key.size() > sizeof(mNetworkSessionKey)) {
+        // TODO log error
+        return;
+    }
+    for (uint8_t i=0; i < sizeof(mNetworkSessionKey); i++) {
+        mNetworkSessionKey[i] = key[i];
+    }
+}
+void NvmProtocolObj::getDataSessionKey(std::vector<uint8_t> &key)
+{
+    key.clear();
+    key.assign(mDataSessionKey, mDataSessionKey+sizeof(mDataSessionKey));
+}
+void NvmProtocolObj::setDataSessionKey(const std::vector<uint8_t> &key)
+{
+    if (key.size() > sizeof(mDataSessionKey)) {
+        // TODO log error
+        return;
+    }
+    for (uint8_t i=0; i < sizeof(mDataSessionKey); i++) {
+        mDataSessionKey[i] = key[i];
+    }
+}
 uint16_t NvmProtocolObj::getLogicalAddr()
 {
     return mLogicalAddr;