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:
61:8d9efd33cac9
Parent:
55:79ab0bbc5008
Child:
62:9751a8504c82
--- a/xDotBridge/src/CommProtocolPeerBrute.cpp	Mon Mar 06 15:16:58 2017 -0700
+++ b/xDotBridge/src/CommProtocolPeerBrute.cpp	Thu Mar 09 16:47:42 2017 -0700
@@ -21,8 +21,7 @@
     logInfo("RX_SLEEP_TIME %f, timeOnAir %lu, nTimesToTx %lu", RX_SLEEP_TIME, TX_TIME, nTimesToTx);
 
     mIsTx = true; // default to TX
-    mPrevDownLinkCnt = dot->getDownLinkCounter();
-//    dot = mDot::getInstance();
+//    mPrevDownLinkCnt = dot->getDownLinkCounter();
 }
 
 CmdResult CommProtocolPeerBrute::init()
@@ -30,6 +29,7 @@
     // FIXME add NVM stuff
     dotDefaults();
 
+    return cmdSuccess;
 }
 CmdResult CommProtocolPeerBrute::dotDefaults()
 {
@@ -43,7 +43,7 @@
     dot->setAck(0);  // Disable Ack
     dot->setClass("C"); // Set class C
     dot->setTxPower(TX_PWR);
-    dot->setPreserveSession(true); // TODO need to better handle counters
+    dot->setPreserveSession(false); // TODO need to better handle counters
 
     // TODO break out in a utility function
     // update configuration if necessary
@@ -93,6 +93,44 @@
     dot->saveConfig();
     return cmdSuccess;
 }
+CmdResult CommProtocolPeerBrute::configForPairingNetwork()
+{
+    uint8_t tx_power;
+    uint8_t tx_datarate;
+    uint32_t tx_frequency;
+    uint8_t frequency_band = dot->getFrequencyBand();
+    switch (frequency_band) {
+        case mDot::FB_EU868:
+            // 250kHz channels achieve higher throughput
+            // DR6 : SF7 @ 250kHz
+            // DR0 - DR5 (125kHz channels) available but much slower
+            tx_frequency = 869850000;
+            tx_datarate = mDot::DR6;
+            // the 869850000 frequency is 100% duty cycle if the total power is under 7 dBm - tx power 4 + antenna gain 3 = 7
+            tx_power = 4;
+            break;
+        case mDot::FB_US915:
+        case mDot::FB_AU915:
+        default:
+            // 500kHz channels achieve highest throughput
+            // DR8 : SF12 @ 500kHz
+            // DR9 : SF11 @ 500kHz
+            // DR10 : SF10 @ 500kHz
+            // DR11 : SF9 @ 500kHz
+            // DR12 : SF8 @ 500kHz
+            // DR13 : SF7 @ 500kHz
+            // DR0 - DR3 (125kHz channels) available but much slower
+            tx_frequency = 915500000;
+            tx_datarate = mDot::DR13;
+            // 915 bands have no duty cycle restrictions, set tx power to max
+            tx_power = 20;
+            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();
+    return cmdSuccess;
+}
 void CommProtocolPeerBrute::setTx(bool isTx)
 {
     mIsTx = isTx;
@@ -103,8 +141,34 @@
 }
 CmdResult CommProtocolPeerBrute::clearPair()
 {
-    logError("Not implemented yet!!!");
-    return cmdError;
+    CmdResult result;
+
+    // TODO generate possibly random channel for new pair
+    std::vector<uint8_t> key;
+    key.reserve(16);
+
+    result = genEncypKey(key, 8);
+    if (result != cmdSuccess) {
+        logError("Error generating network ID.");
+        return cmdError;
+    }
+    dot->setNetworkId(key);
+
+    result = genEncypKey(key, 16);
+    if (result != cmdSuccess) {
+        logError("Error generating network encryption keys.");
+        return cmdError;
+    }
+    dot->setNetworkKey(key);
+
+    result = genEncypKey(key, 16);
+    if (result != cmdSuccess) {
+        logError("Error generating data session encryption keys.");
+        return cmdError;
+    }
+    dot->setDataSessionKey(key);
+
+    return cmdSuccess;
 }
 
 // TX focused
@@ -126,8 +190,21 @@
     if (!dot->getNetworkJoinStatus()) {
         join_network();
     }
-    logError("Not implemented yet!!!");
-    return cmdError;
+    // Request Message
+    std::vector<uint8_t> msg;
+    msg.reserve(16);
+    // Flag 2 Bytes
+    msg.push_back(0xFE);
+    msg.push_back(0x01);
+    // EUI 8 Bytes
+    std::vector<uint8_t> eui(dot->getDeviceId());
+    msg.insert(msg.end(), eui.begin(), eui.end());
+    // Reserved 6 Bytes
+    for (uint8_t i=0;i<6;i++) {
+        msg.push_back(0x00);
+    }
+    dot->send(msg); // Can just send once since the RX should be always listening
+    return cmdSuccess;
 }
 
 // RX focused
@@ -164,14 +241,88 @@
 
 CmdResult CommProtocolPeerBrute::waitForPairing(float waitTime)
 {
-    logError("Not implemented yet!!!");
-    return cmdError;
+    float t = 0.0;
+    bool msgPending;
+    do {
+        listen(msgPending);
+        t += TX_TIME/1000.0;
+    }
+    while (t < waitTime && !msgPending);
+
+    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();
 }
 
 CmdResult CommProtocolPeerBrute::sendPairAccepted()
 {
-    logError("Not implemented yet!!!");
-    return cmdError;
+    bool sendResult;
+    // Request Message
+    std::vector<uint8_t> *msg = new std::vector<uint8_t>;
+    msg->reserve(34);
+    // Flag
+    msg->push_back(0xFD);
+    msg->push_back(0x02);
+    logInfo("flag msg size %d", msg->size());
+    // EUI
+    std::vector<uint8_t> *eui = new std::vector<uint8_t>(dot->getDeviceId());
+    msg->insert(msg->end(),eui->begin(), eui->end());
+    delete eui;
+    logInfo("eui msg size %d", msg->size());
+
+    // Reserved for Freq
+    for(uint8_t i=0;i<4;i++) {
+        msg->push_back(0x00);
+    }
+    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 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());
+
+    // Data session key
+    std::vector<uint8_t> *dataSessionKey = new std::vector<uint8_t>(dot->getDataSessionKey());
+    msg->insert(msg->end(),dataSessionKey->begin(), dataSessionKey->end());
+    delete dataSessionKey;
+
+    logInfo("msg size %d", msg->size());
+    // Only send once since requester should be listening always
+    sendResult = mDot::MDOT_OK == dot->send(*msg);
+    delete msg;
+    if (sendResult)
+        return cmdSuccess;
+    else
+        return cmdError;
+}
+
+CmdResult CommProtocolPeerBrute::waitForAccept(float waitTime)
+{
+    float t = 0.0;
+    bool msgPending = false;
+    do {
+        listen(msgPending);
+        t += TX_TIME/1000.0;
+    }
+    while (t < waitTime && !msgPending);
+
+    if (!msgPending) {
+        return cmdTimeout;
+    }
+    // TODO check request
+
+    return cmdSuccess;
 }
 
 // xDot Peer to Peer Specific
@@ -231,10 +382,13 @@
     return cmdSuccess;
 }
 
-CmdResult CommProtocolPeerBrute::genEncypKeys()
+CmdResult CommProtocolPeerBrute::genEncypKey(std::vector<uint8_t> &newKey, uint8_t keySize)
 {
-    logError("Not implemented yet!!!");
-    return cmdError;
+    newKey.clear();
+    for (uint8_t i=0;i<keySize; i++){
+        newKey.push_back(dot->getRadioRandom());
+    }
+    return cmdSuccess;
 }
 
 // NvmProtocolObj