Peer to Peer example
Dependencies: libmDot-dev-mbed2-deprecated mbed-rtos mbed
Fork of mDot_LoRa_PEER_TO_PEER by
This example will setup a peer to peer node, copy program to two dots Uplink packets will be sent every 5 seconds, however communication is half-duplex An mDot cannot receive while transmitting
This example also demonstrates asynchronous receive through libmDot using the event framework.
Received packets will be sent to the Serial port on pins 2 and 3 baud rate for serial ports is set to 115200
main.cpp@8:3336880e91d6, 2016-08-17 (annotated)
- Committer:
- jreiss
- Date:
- Wed Aug 17 18:40:06 2016 +0000
- Revision:
- 8:3336880e91d6
- Parent:
- 7:30602a4a9902
update libmDot to 2.0.2; Remove RxBuffer delete in MacEvent RxDone which is now done within library
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mfiore | 0:5ec8b39fcf53 | 1 | #include "mbed.h" |
mfiore | 0:5ec8b39fcf53 | 2 | #include "mDot.h" |
jreiss | 5:1ad91719506b | 3 | #include "mDotEvent.h" |
mfiore | 4:ac599fe6bc41 | 4 | #include "MTSLog.h" |
mfiore | 0:5ec8b39fcf53 | 5 | #include <string> |
mfiore | 0:5ec8b39fcf53 | 6 | #include <vector> |
mfiore | 4:ac599fe6bc41 | 7 | #include <algorithm> |
mfiore | 0:5ec8b39fcf53 | 8 | |
jreiss | 6:ebaf55285f73 | 9 | // This example will setup a peer to peer node, copy program to two dots |
jreiss | 7:30602a4a9902 | 10 | // Uplink packets will be sent every 5 seconds, however communication is half-duplex |
jreiss | 7:30602a4a9902 | 11 | // An mDot cannot receive while transmitting |
jreiss | 5:1ad91719506b | 12 | // Received packets will be sent to the Serial port on pins 2 and 3 |
jreiss | 5:1ad91719506b | 13 | // baud rate for serial ports is set to 115200 |
jreiss | 5:1ad91719506b | 14 | |
jreiss | 5:1ad91719506b | 15 | |
jreiss | 5:1ad91719506b | 16 | Serial _serial(XBEE_DOUT, XBEE_DIN); |
jreiss | 5:1ad91719506b | 17 | Serial debug(USBTX, USBRX); |
jreiss | 5:1ad91719506b | 18 | |
jreiss | 6:ebaf55285f73 | 19 | static uint8_t config_network_addr[] = { 0x01, 0x02, 0x03, 0x04 }; |
jreiss | 6:ebaf55285f73 | 20 | static uint8_t config_network_nskey[] = { 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04 }; |
jreiss | 6:ebaf55285f73 | 21 | static uint8_t config_network_dskey[] = { 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04 }; |
jreiss | 6:ebaf55285f73 | 22 | |
jreiss | 5:1ad91719506b | 23 | // Custom event handler for receiving Class C packets |
jreiss | 5:1ad91719506b | 24 | |
jreiss | 5:1ad91719506b | 25 | class RadioEvent : public mDotEvent |
jreiss | 5:1ad91719506b | 26 | { |
jreiss | 5:1ad91719506b | 27 | |
jreiss | 5:1ad91719506b | 28 | |
jreiss | 5:1ad91719506b | 29 | public: |
jreiss | 5:1ad91719506b | 30 | RadioEvent() {} |
jreiss | 5:1ad91719506b | 31 | |
jreiss | 5:1ad91719506b | 32 | virtual ~RadioEvent() {} |
jreiss | 5:1ad91719506b | 33 | |
jreiss | 5:1ad91719506b | 34 | /*! |
jreiss | 5:1ad91719506b | 35 | * MAC layer event callback prototype. |
jreiss | 5:1ad91719506b | 36 | * |
jreiss | 5:1ad91719506b | 37 | * \param [IN] flags Bit field indicating the MAC events occurred |
jreiss | 5:1ad91719506b | 38 | * \param [IN] info Details about MAC events occurred |
jreiss | 5:1ad91719506b | 39 | */ |
jreiss | 5:1ad91719506b | 40 | virtual void MacEvent(LoRaMacEventFlags* flags, LoRaMacEventInfo* info) { |
mfiore | 0:5ec8b39fcf53 | 41 | |
jreiss | 5:1ad91719506b | 42 | if (mts::MTSLog::getLogLevel() == mts::MTSLog::TRACE_LEVEL) { |
jreiss | 5:1ad91719506b | 43 | std::string msg = "OK"; |
jreiss | 5:1ad91719506b | 44 | switch (info->Status) { |
jreiss | 5:1ad91719506b | 45 | case LORAMAC_EVENT_INFO_STATUS_ERROR: |
jreiss | 5:1ad91719506b | 46 | msg = "ERROR"; |
jreiss | 5:1ad91719506b | 47 | break; |
jreiss | 5:1ad91719506b | 48 | case LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT: |
jreiss | 5:1ad91719506b | 49 | msg = "TX_TIMEOUT"; |
jreiss | 5:1ad91719506b | 50 | break; |
jreiss | 5:1ad91719506b | 51 | case LORAMAC_EVENT_INFO_STATUS_RX_TIMEOUT: |
jreiss | 5:1ad91719506b | 52 | msg = "RX_TIMEOUT"; |
jreiss | 5:1ad91719506b | 53 | break; |
jreiss | 5:1ad91719506b | 54 | case LORAMAC_EVENT_INFO_STATUS_RX_ERROR: |
jreiss | 5:1ad91719506b | 55 | msg = "RX_ERROR"; |
jreiss | 5:1ad91719506b | 56 | break; |
jreiss | 5:1ad91719506b | 57 | case LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL: |
jreiss | 5:1ad91719506b | 58 | msg = "JOIN_FAIL"; |
jreiss | 5:1ad91719506b | 59 | break; |
jreiss | 5:1ad91719506b | 60 | case LORAMAC_EVENT_INFO_STATUS_DOWNLINK_FAIL: |
jreiss | 5:1ad91719506b | 61 | msg = "DOWNLINK_FAIL"; |
jreiss | 5:1ad91719506b | 62 | break; |
jreiss | 5:1ad91719506b | 63 | case LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL: |
jreiss | 5:1ad91719506b | 64 | msg = "ADDRESS_FAIL"; |
jreiss | 5:1ad91719506b | 65 | break; |
jreiss | 5:1ad91719506b | 66 | case LORAMAC_EVENT_INFO_STATUS_MIC_FAIL: |
jreiss | 5:1ad91719506b | 67 | msg = "MIC_FAIL"; |
jreiss | 5:1ad91719506b | 68 | break; |
jreiss | 5:1ad91719506b | 69 | default: |
jreiss | 5:1ad91719506b | 70 | break; |
jreiss | 5:1ad91719506b | 71 | } |
jreiss | 5:1ad91719506b | 72 | logTrace("Event: %s", msg.c_str()); |
jreiss | 5:1ad91719506b | 73 | |
jreiss | 5:1ad91719506b | 74 | logTrace("Flags Tx: %d Rx: %d RxData: %d RxSlot: %d LinkCheck: %d JoinAccept: %d", |
jreiss | 5:1ad91719506b | 75 | flags->Bits.Tx, flags->Bits.Rx, flags->Bits.RxData, flags->Bits.RxSlot, flags->Bits.LinkCheck, flags->Bits.JoinAccept); |
jreiss | 5:1ad91719506b | 76 | logTrace("Info: Status: %d ACK: %d Retries: %d TxDR: %d RxPort: %d RxSize: %d RSSI: %d SNR: %d Energy: %d Margin: %d Gateways: %d", |
jreiss | 5:1ad91719506b | 77 | info->Status, info->TxAckReceived, info->TxNbRetries, info->TxDatarate, info->RxPort, info->RxBufferSize, |
jreiss | 5:1ad91719506b | 78 | info->RxRssi, info->RxSnr, info->Energy, info->DemodMargin, info->NbGateways); |
jreiss | 5:1ad91719506b | 79 | } |
jreiss | 5:1ad91719506b | 80 | |
jreiss | 5:1ad91719506b | 81 | if (flags->Bits.Rx) { |
jreiss | 6:ebaf55285f73 | 82 | |
jreiss | 5:1ad91719506b | 83 | logDebug("Rx %d bytes", info->RxBufferSize); |
jreiss | 5:1ad91719506b | 84 | if (info->RxBufferSize > 0) { |
jreiss | 6:ebaf55285f73 | 85 | |
jreiss | 5:1ad91719506b | 86 | for (int i = 0; i < info->RxBufferSize; i++) { |
jreiss | 5:1ad91719506b | 87 | _serial.putc(info->RxBuffer[i]); |
jreiss | 5:1ad91719506b | 88 | } |
jreiss | 5:1ad91719506b | 89 | } |
jreiss | 5:1ad91719506b | 90 | } |
jreiss | 5:1ad91719506b | 91 | } |
jreiss | 5:1ad91719506b | 92 | }; |
jreiss | 5:1ad91719506b | 93 | |
jreiss | 5:1ad91719506b | 94 | |
jreiss | 5:1ad91719506b | 95 | int main() |
jreiss | 5:1ad91719506b | 96 | { |
mfiore | 0:5ec8b39fcf53 | 97 | int32_t ret; |
mfiore | 0:5ec8b39fcf53 | 98 | mDot* dot; |
mfiore | 0:5ec8b39fcf53 | 99 | std::vector<uint8_t> data; |
mfiore | 4:ac599fe6bc41 | 100 | std::string data_str = "hello!"; |
jreiss | 5:1ad91719506b | 101 | |
jreiss | 5:1ad91719506b | 102 | RadioEvent events; |
jreiss | 5:1ad91719506b | 103 | |
jreiss | 5:1ad91719506b | 104 | debug.baud(115200); |
jreiss | 5:1ad91719506b | 105 | _serial.baud(115200); |
jreiss | 5:1ad91719506b | 106 | |
mfiore | 0:5ec8b39fcf53 | 107 | // get a mDot handle |
mfiore | 0:5ec8b39fcf53 | 108 | dot = mDot::getInstance(); |
jreiss | 5:1ad91719506b | 109 | |
jreiss | 5:1ad91719506b | 110 | // Set custom events handler for receiving Class C packets |
jreiss | 5:1ad91719506b | 111 | dot->setEvents(&events); |
jreiss | 5:1ad91719506b | 112 | |
mfiore | 0:5ec8b39fcf53 | 113 | // print library version information |
mfiore | 0:5ec8b39fcf53 | 114 | logInfo("version: %s", dot->getId().c_str()); |
mfiore | 0:5ec8b39fcf53 | 115 | |
jreiss | 6:ebaf55285f73 | 116 | //******************************************* |
jreiss | 6:ebaf55285f73 | 117 | // configuration |
jreiss | 6:ebaf55285f73 | 118 | //******************************************* |
jreiss | 6:ebaf55285f73 | 119 | // reset to default config so we know what state we're in |
jreiss | 6:ebaf55285f73 | 120 | dot->resetConfig(); |
jreiss | 5:1ad91719506b | 121 | |
jreiss | 6:ebaf55285f73 | 122 | dot->setLogLevel(mts::MTSLog::TRACE_LEVEL); |
jreiss | 5:1ad91719506b | 123 | |
jreiss | 6:ebaf55285f73 | 124 | // set up the mDot with our network information: Network Address and Session Keys must match on each device |
jreiss | 6:ebaf55285f73 | 125 | // these can all be saved in NVM so they don't need to be set every time - see mDot::saveConfig() |
jreiss | 6:ebaf55285f73 | 126 | std::vector<uint8_t> temp; |
jreiss | 5:1ad91719506b | 127 | |
jreiss | 6:ebaf55285f73 | 128 | for (int i = 0; i < 4; i++) { |
jreiss | 6:ebaf55285f73 | 129 | temp.push_back(config_network_addr[i]); |
jreiss | 6:ebaf55285f73 | 130 | } |
jreiss | 6:ebaf55285f73 | 131 | |
jreiss | 6:ebaf55285f73 | 132 | logInfo("setting network addr"); |
jreiss | 6:ebaf55285f73 | 133 | if ((ret = dot->setNetworkAddress(temp)) != mDot::MDOT_OK) { |
jreiss | 6:ebaf55285f73 | 134 | logError("failed to set network name %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
jreiss | 6:ebaf55285f73 | 135 | } |
jreiss | 5:1ad91719506b | 136 | |
jreiss | 6:ebaf55285f73 | 137 | temp.clear(); |
jreiss | 6:ebaf55285f73 | 138 | for (int i = 0; i < 16; i++) { |
jreiss | 6:ebaf55285f73 | 139 | temp.push_back(config_network_nskey[i]); |
jreiss | 6:ebaf55285f73 | 140 | } |
jreiss | 5:1ad91719506b | 141 | |
jreiss | 6:ebaf55285f73 | 142 | logInfo("setting network password"); |
jreiss | 6:ebaf55285f73 | 143 | if ((ret = dot->setNetworkSessionKey(temp)) != mDot::MDOT_OK) { |
jreiss | 6:ebaf55285f73 | 144 | logError("failed to set network password %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
jreiss | 6:ebaf55285f73 | 145 | } |
mfiore | 1:f2e840f754c8 | 146 | |
jreiss | 6:ebaf55285f73 | 147 | temp.clear(); |
jreiss | 6:ebaf55285f73 | 148 | for (int i = 0; i < 16; i++) { |
jreiss | 6:ebaf55285f73 | 149 | temp.push_back(config_network_dskey[i]); |
jreiss | 6:ebaf55285f73 | 150 | } |
jreiss | 5:1ad91719506b | 151 | |
jreiss | 6:ebaf55285f73 | 152 | logInfo("setting network password"); |
jreiss | 6:ebaf55285f73 | 153 | if ((ret = dot->setDataSessionKey(temp)) != mDot::MDOT_OK) { |
jreiss | 6:ebaf55285f73 | 154 | logError("failed to set network password %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
jreiss | 6:ebaf55285f73 | 155 | } |
jreiss | 6:ebaf55285f73 | 156 | |
jreiss | 6:ebaf55285f73 | 157 | logInfo("setting TX frequency"); |
jreiss | 6:ebaf55285f73 | 158 | if ((ret = dot->setTxFrequency(915500000)) != mDot::MDOT_OK) { |
jreiss | 6:ebaf55285f73 | 159 | logError("failed to set TX frequency %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
jreiss | 6:ebaf55285f73 | 160 | } |
jreiss | 5:1ad91719506b | 161 | |
jreiss | 6:ebaf55285f73 | 162 | // a higher spreading factor allows for longer range but lower throughput |
jreiss | 6:ebaf55285f73 | 163 | // in the 915 (US) frequency band, DR8-DR13 |
jreiss | 6:ebaf55285f73 | 164 | logInfo("setting TX spreading factor"); |
jreiss | 6:ebaf55285f73 | 165 | if ((ret = dot->setTxDataRate(mDot::DR13)) != mDot::MDOT_OK) { |
jreiss | 6:ebaf55285f73 | 166 | logError("failed to set TX datarate %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
jreiss | 6:ebaf55285f73 | 167 | } |
jreiss | 5:1ad91719506b | 168 | |
jreiss | 6:ebaf55285f73 | 169 | // set join mode to AUTO_OTA so the mDot doesn't have to rejoin after sleeping |
jreiss | 6:ebaf55285f73 | 170 | logInfo("setting join mode to AUTO_OTA"); |
jreiss | 6:ebaf55285f73 | 171 | if ((ret = dot->setJoinMode(mDot::PEER_TO_PEER)) != mDot::MDOT_OK) { |
jreiss | 6:ebaf55285f73 | 172 | logError("failed to set join mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
jreiss | 6:ebaf55285f73 | 173 | } |
jreiss | 5:1ad91719506b | 174 | |
jreiss | 6:ebaf55285f73 | 175 | // save this configuration to the mDot's NVM |
jreiss | 6:ebaf55285f73 | 176 | logInfo("saving config"); |
jreiss | 6:ebaf55285f73 | 177 | if (! dot->saveConfig()) { |
jreiss | 6:ebaf55285f73 | 178 | logError("failed to save configuration"); |
jreiss | 6:ebaf55285f73 | 179 | } |
jreiss | 5:1ad91719506b | 180 | |
mfiore | 1:f2e840f754c8 | 181 | //******************************************* |
mfiore | 1:f2e840f754c8 | 182 | // end of configuration |
mfiore | 1:f2e840f754c8 | 183 | //******************************************* |
mfiore | 0:5ec8b39fcf53 | 184 | |
mfiore | 0:5ec8b39fcf53 | 185 | // format data for sending to the gateway |
mfiore | 0:5ec8b39fcf53 | 186 | for (std::string::iterator it = data_str.begin(); it != data_str.end(); it++) |
mfiore | 0:5ec8b39fcf53 | 187 | data.push_back((uint8_t) *it); |
mfiore | 0:5ec8b39fcf53 | 188 | |
jreiss | 5:1ad91719506b | 189 | while(true) { |
jreiss | 6:ebaf55285f73 | 190 | // send the data |
jreiss | 6:ebaf55285f73 | 191 | if ((ret = dot->send(data)) != mDot::MDOT_OK) { |
jreiss | 6:ebaf55285f73 | 192 | logError("failed to send %d:%s", ret, mDot::getReturnCodeString(ret).c_str()); |
jreiss | 6:ebaf55285f73 | 193 | } else { |
jreiss | 6:ebaf55285f73 | 194 | logInfo("successfully sent data to peer"); |
jreiss | 5:1ad91719506b | 195 | } |
jreiss | 5:1ad91719506b | 196 | |
jreiss | 6:ebaf55285f73 | 197 | wait(5.0); |
mfiore | 0:5ec8b39fcf53 | 198 | } |
mfiore | 0:5ec8b39fcf53 | 199 | |
mfiore | 0:5ec8b39fcf53 | 200 | return 0; |
mfiore | 0:5ec8b39fcf53 | 201 | } |