Echo example of class C devices receiving downlink and sending as next uplink

Dependencies:   libmDot-mbed5 ISL29011

Committer:
jreiss
Date:
Thu Mar 07 14:12:55 2019 +0000
Revision:
36:18e6b0e367b6
Parent:
35:470b2b934241
Add ack received with two uplinks sent after join

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tesla_xudong 33:ff681aa203f3 1 #include "dot_util.h"
tesla_xudong 33:ff681aa203f3 2 #include "RadioEvent.h"
tesla_xudong 33:ff681aa203f3 3 #include <string.h>
tesla_xudong 33:ff681aa203f3 4 #if ACTIVE_EXAMPLE == CLASS_C_EXAMPLE
tesla_xudong 33:ff681aa203f3 5
tesla_xudong 33:ff681aa203f3 6 /////////////////////////////////////////////////////////////////////////////
tesla_xudong 33:ff681aa203f3 7 // -------------------- DOT LIBRARY REQUIRED ------------------------------//
tesla_xudong 33:ff681aa203f3 8 // * Because these example programs can be used for both mDot and xDot //
tesla_xudong 33:ff681aa203f3 9 // devices, the LoRa stack is not included. The libmDot library should //
tesla_xudong 33:ff681aa203f3 10 // be imported if building for mDot devices. The libxDot library //
tesla_xudong 33:ff681aa203f3 11 // should be imported if building for xDot devices. //
tesla_xudong 33:ff681aa203f3 12 // * https://developer.mbed.org/teams/MultiTech/code/libmDot-dev-mbed5/ //
tesla_xudong 33:ff681aa203f3 13 // * https://developer.mbed.org/teams/MultiTech/code/libmDot-mbed5/ //
tesla_xudong 33:ff681aa203f3 14 // * https://developer.mbed.org/teams/MultiTech/code/libxDot-dev-mbed5/ //
tesla_xudong 33:ff681aa203f3 15 // * https://developer.mbed.org/teams/MultiTech/code/libxDot-mbed5/ //
tesla_xudong 33:ff681aa203f3 16 /////////////////////////////////////////////////////////////////////////////
tesla_xudong 33:ff681aa203f3 17
tesla_xudong 33:ff681aa203f3 18 /////////////////////////////////////////////////////////////
tesla_xudong 33:ff681aa203f3 19 // * these options must match the settings on your gateway //
tesla_xudong 33:ff681aa203f3 20 // * edit their values to match your configuration //
tesla_xudong 33:ff681aa203f3 21 // * frequency sub band is only relevant for the 915 bands //
tesla_xudong 33:ff681aa203f3 22 // * either the network name and passphrase can be used or //
tesla_xudong 33:ff681aa203f3 23 // the network ID (8 bytes) and KEY (16 bytes) //
tesla_xudong 33:ff681aa203f3 24 /////////////////////////////////////////////////////////////
jreiss 36:18e6b0e367b6 25 //static std::string network_name = "iotlab01";
jreiss 36:18e6b0e367b6 26 //static std::string network_passphrase = "11223344";
jreiss 36:18e6b0e367b6 27 static uint8_t network_id[] = { 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11 };
jreiss 36:18e6b0e367b6 28 static uint8_t network_key[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 };
tesla_xudong 33:ff681aa203f3 29 static uint8_t frequency_sub_band = 4;
tesla_xudong 33:ff681aa203f3 30 static lora::NetworkType network_type = lora::PUBLIC_LORAWAN;
tesla_xudong 33:ff681aa203f3 31 static uint8_t join_delay = 6;
jreiss 36:18e6b0e367b6 32 static uint8_t ack = 1;
tesla_xudong 33:ff681aa203f3 33 static bool adr = true;
tesla_xudong 33:ff681aa203f3 34
tesla_xudong 33:ff681aa203f3 35 mDot* dot = NULL;
tesla_xudong 33:ff681aa203f3 36 lora::ChannelPlan* plan = NULL;
tesla_xudong 33:ff681aa203f3 37
tesla_xudong 33:ff681aa203f3 38 Serial pc(USBTX, USBRX);
tesla_xudong 33:ff681aa203f3 39
tesla_xudong 33:ff681aa203f3 40 #if defined(TARGET_XDOT_L151CC)
tesla_xudong 33:ff681aa203f3 41 I2C i2c(I2C_SDA, I2C_SCL);
tesla_xudong 33:ff681aa203f3 42 ISL29011 lux(i2c);
tesla_xudong 33:ff681aa203f3 43 #else
tesla_xudong 33:ff681aa203f3 44 AnalogIn lux(XBEE_AD0);
tesla_xudong 33:ff681aa203f3 45 #endif
tesla_xudong 33:ff681aa203f3 46
tesla_xudong 33:ff681aa203f3 47 std::string Last_RX;
tesla_xudong 33:ff681aa203f3 48
tesla_xudong 33:ff681aa203f3 49 class MyEvent : public mDotEvent
tesla_xudong 33:ff681aa203f3 50 {
tesla_xudong 33:ff681aa203f3 51
tesla_xudong 33:ff681aa203f3 52 public:
tesla_xudong 33:ff681aa203f3 53 MyEvent() {}
tesla_xudong 33:ff681aa203f3 54
tesla_xudong 33:ff681aa203f3 55 virtual ~MyEvent() {}
tesla_xudong 33:ff681aa203f3 56
tesla_xudong 33:ff681aa203f3 57
tesla_xudong 33:ff681aa203f3 58 virtual void MacEvent(LoRaMacEventFlags* flags, LoRaMacEventInfo* info) {
tesla_xudong 33:ff681aa203f3 59
tesla_xudong 33:ff681aa203f3 60 if (mts::MTSLog::getLogLevel() == mts::MTSLog::TRACE_LEVEL) {
tesla_xudong 33:ff681aa203f3 61 std::string msg = "OK";
tesla_xudong 33:ff681aa203f3 62 switch (info->Status) {
tesla_xudong 33:ff681aa203f3 63 case LORAMAC_EVENT_INFO_STATUS_ERROR:
tesla_xudong 33:ff681aa203f3 64 msg = "ERROR";
tesla_xudong 33:ff681aa203f3 65 break;
tesla_xudong 33:ff681aa203f3 66 case LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT:
tesla_xudong 33:ff681aa203f3 67 msg = "TX_TIMEOUT";
tesla_xudong 33:ff681aa203f3 68 break;
tesla_xudong 33:ff681aa203f3 69 case LORAMAC_EVENT_INFO_STATUS_RX_TIMEOUT:
tesla_xudong 33:ff681aa203f3 70 msg = "RX_TIMEOUT";
tesla_xudong 33:ff681aa203f3 71 break;
tesla_xudong 33:ff681aa203f3 72 case LORAMAC_EVENT_INFO_STATUS_RX_ERROR:
tesla_xudong 33:ff681aa203f3 73 msg = "RX_ERROR";
tesla_xudong 33:ff681aa203f3 74 break;
tesla_xudong 33:ff681aa203f3 75 case LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL:
tesla_xudong 33:ff681aa203f3 76 msg = "JOIN_FAIL";
tesla_xudong 33:ff681aa203f3 77 break;
tesla_xudong 33:ff681aa203f3 78 case LORAMAC_EVENT_INFO_STATUS_DOWNLINK_FAIL:
tesla_xudong 33:ff681aa203f3 79 msg = "DOWNLINK_FAIL";
tesla_xudong 33:ff681aa203f3 80 break;
tesla_xudong 33:ff681aa203f3 81 case LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL:
tesla_xudong 33:ff681aa203f3 82 msg = "ADDRESS_FAIL";
tesla_xudong 33:ff681aa203f3 83 break;
tesla_xudong 33:ff681aa203f3 84 case LORAMAC_EVENT_INFO_STATUS_MIC_FAIL:
tesla_xudong 33:ff681aa203f3 85 msg = "MIC_FAIL";
tesla_xudong 33:ff681aa203f3 86 break;
tesla_xudong 33:ff681aa203f3 87 default:
tesla_xudong 33:ff681aa203f3 88 break;
tesla_xudong 33:ff681aa203f3 89 }
tesla_xudong 33:ff681aa203f3 90 logTrace("Event: %s", msg.c_str());
tesla_xudong 33:ff681aa203f3 91
tesla_xudong 33:ff681aa203f3 92 logTrace("Flags Tx: %d Rx: %d RxData: %d RxSlot: %d LinkCheck: %d JoinAccept: %d",
tesla_xudong 33:ff681aa203f3 93 flags->Bits.Tx, flags->Bits.Rx, flags->Bits.RxData, flags->Bits.RxSlot, flags->Bits.LinkCheck, flags->Bits.JoinAccept);
tesla_xudong 33:ff681aa203f3 94 logTrace("Info: Status: %d ACK: %d Retries: %d TxDR: %d RxPort: %d RxSize: %d RSSI: %d SNR: %d Energy: %d Margin: %d Gateways: %d",
tesla_xudong 33:ff681aa203f3 95 info->Status, info->TxAckReceived, info->TxNbRetries, info->TxDatarate, info->RxPort, info->RxBufferSize,
tesla_xudong 33:ff681aa203f3 96 info->RxRssi, info->RxSnr, info->Energy, info->DemodMargin, info->NbGateways);
tesla_xudong 33:ff681aa203f3 97 }
tesla_xudong 33:ff681aa203f3 98
tesla_xudong 33:ff681aa203f3 99 if (flags->Bits.Rx) {
tesla_xudong 33:ff681aa203f3 100
tesla_xudong 33:ff681aa203f3 101 logDebug("Rx %d bytes", info->RxBufferSize);
tesla_xudong 33:ff681aa203f3 102 if (info->RxBufferSize > 0) {
tesla_xudong 33:ff681aa203f3 103 // print RX data as hexadecimal
tesla_xudong 33:ff681aa203f3 104 //printf("Rx data: %s\r\n", mts::Text::bin2hexString(info->RxBuffer, info->RxBufferSize).c_str());
tesla_xudong 33:ff681aa203f3 105
tesla_xudong 33:ff681aa203f3 106 // print RX data as string
tesla_xudong 33:ff681aa203f3 107 std::string rx((const char*)info->RxBuffer, info->RxBufferSize);
tesla_xudong 33:ff681aa203f3 108 //printf("Rx data: %s\r\n", rx.c_str());
tesla_xudong 33:ff681aa203f3 109 Last_RX = rx;
tesla_xudong 33:ff681aa203f3 110 }
tesla_xudong 33:ff681aa203f3 111 }
tesla_xudong 33:ff681aa203f3 112 }
tesla_xudong 33:ff681aa203f3 113 };
tesla_xudong 33:ff681aa203f3 114
tesla_xudong 33:ff681aa203f3 115
tesla_xudong 33:ff681aa203f3 116 char* vector2string(std::vector<uint8_t> var)
tesla_xudong 33:ff681aa203f3 117 {
tesla_xudong 33:ff681aa203f3 118 char* test = new char[var.size()];
tesla_xudong 33:ff681aa203f3 119
tesla_xudong 33:ff681aa203f3 120 std::copy(var.begin(),var.end(),test);
tesla_xudong 33:ff681aa203f3 121
tesla_xudong 33:ff681aa203f3 122 return test;
tesla_xudong 33:ff681aa203f3 123 }
tesla_xudong 33:ff681aa203f3 124
tesla_xudong 33:ff681aa203f3 125
tesla_xudong 33:ff681aa203f3 126
tesla_xudong 33:ff681aa203f3 127 void send_string(std::string data,mDot *dot)
tesla_xudong 33:ff681aa203f3 128 {
tesla_xudong 33:ff681aa203f3 129 int32_t ret;
tesla_xudong 33:ff681aa203f3 130 std::vector<uint8_t> sendData;
tesla_xudong 33:ff681aa203f3 131 int i;
tesla_xudong 33:ff681aa203f3 132
tesla_xudong 33:ff681aa203f3 133 for(i=0; i<data.size(); i++ )
tesla_xudong 33:ff681aa203f3 134 sendData.push_back( data[i] );
tesla_xudong 33:ff681aa203f3 135
tesla_xudong 33:ff681aa203f3 136
tesla_xudong 33:ff681aa203f3 137 ret = dot->send(sendData);
tesla_xudong 33:ff681aa203f3 138 if (ret != mDot::MDOT_OK) {
tesla_xudong 33:ff681aa203f3 139 logError("failed to send data to ");
tesla_xudong 33:ff681aa203f3 140 } else {
tesla_xudong 33:ff681aa203f3 141 logInfo("successfully sent data to ");
tesla_xudong 33:ff681aa203f3 142 }
tesla_xudong 33:ff681aa203f3 143
tesla_xudong 33:ff681aa203f3 144 }
tesla_xudong 33:ff681aa203f3 145
tesla_xudong 33:ff681aa203f3 146 std::string get_buffer;
tesla_xudong 33:ff681aa203f3 147
tesla_xudong 33:ff681aa203f3 148 void Uart_interrupt(){
tesla_xudong 33:ff681aa203f3 149
tesla_xudong 33:ff681aa203f3 150 char get_char;
tesla_xudong 33:ff681aa203f3 151 while(!pc.readable());
tesla_xudong 33:ff681aa203f3 152
tesla_xudong 33:ff681aa203f3 153 get_char=pc.getc();
tesla_xudong 33:ff681aa203f3 154 if (get_char!='-')
tesla_xudong 33:ff681aa203f3 155 {
tesla_xudong 33:ff681aa203f3 156 get_buffer=get_buffer+get_char;
tesla_xudong 33:ff681aa203f3 157 }
tesla_xudong 33:ff681aa203f3 158 else
tesla_xudong 33:ff681aa203f3 159 {
tesla_xudong 33:ff681aa203f3 160 send_string(get_buffer,dot);
tesla_xudong 33:ff681aa203f3 161 get_buffer.clear();
tesla_xudong 33:ff681aa203f3 162 }
tesla_xudong 33:ff681aa203f3 163
tesla_xudong 33:ff681aa203f3 164 }
tesla_xudong 33:ff681aa203f3 165
tesla_xudong 33:ff681aa203f3 166 int main() {
tesla_xudong 33:ff681aa203f3 167
tesla_xudong 33:ff681aa203f3 168 pc.baud(115200);
tesla_xudong 33:ff681aa203f3 169 pc.attach(&Uart_interrupt, SerialBase::RxIrq);
tesla_xudong 33:ff681aa203f3 170 // pc.attach(&Uart_send_interrupt, SerialBase::TxIrq);
tesla_xudong 33:ff681aa203f3 171 #if defined(TARGET_XDOT_L151CC)
tesla_xudong 33:ff681aa203f3 172 i2c.frequency(400000);
tesla_xudong 33:ff681aa203f3 173 #endif
tesla_xudong 33:ff681aa203f3 174
tesla_xudong 33:ff681aa203f3 175 // Custom event handler for automatically displaying RX data
tesla_xudong 33:ff681aa203f3 176 //RadioEvent events;
tesla_xudong 33:ff681aa203f3 177 MyEvent events;
tesla_xudong 33:ff681aa203f3 178 mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL);
tesla_xudong 33:ff681aa203f3 179
tesla_xudong 33:ff681aa203f3 180 #if CHANNEL_PLAN == CP_US915
tesla_xudong 33:ff681aa203f3 181 plan = new lora::ChannelPlan_US915();
tesla_xudong 33:ff681aa203f3 182 #elif CHANNEL_PLAN == CP_AU915
tesla_xudong 33:ff681aa203f3 183 plan = new lora::ChannelPlan_AU915();
tesla_xudong 33:ff681aa203f3 184 #elif CHANNEL_PLAN == CP_EU868
tesla_xudong 33:ff681aa203f3 185 plan = new lora::ChannelPlan_EU868();
tesla_xudong 33:ff681aa203f3 186 #elif CHANNEL_PLAN == CP_KR920
tesla_xudong 33:ff681aa203f3 187 plan = new lora::ChannelPlan_KR920();
tesla_xudong 33:ff681aa203f3 188 #elif CHANNEL_PLAN == CP_AS923
tesla_xudong 33:ff681aa203f3 189 plan = new lora::ChannelPlan_AS923();
tesla_xudong 33:ff681aa203f3 190 #elif CHANNEL_PLAN == CP_AS923_JAPAN
tesla_xudong 33:ff681aa203f3 191 plan = new lora::ChannelPlan_AS923_Japan();
tesla_xudong 33:ff681aa203f3 192 #elif CHANNEL_PLAN == CP_IN865
tesla_xudong 33:ff681aa203f3 193 plan = new lora::ChannelPlan_IN865();
tesla_xudong 33:ff681aa203f3 194 #endif
tesla_xudong 33:ff681aa203f3 195 assert(plan);
tesla_xudong 33:ff681aa203f3 196
tesla_xudong 33:ff681aa203f3 197 dot = mDot::getInstance(plan);
tesla_xudong 33:ff681aa203f3 198 assert(dot);
tesla_xudong 33:ff681aa203f3 199
tesla_xudong 33:ff681aa203f3 200 logInfo("mbed-os library version: %d", MBED_LIBRARY_VERSION);
tesla_xudong 33:ff681aa203f3 201
tesla_xudong 33:ff681aa203f3 202 // start from a well-known state
tesla_xudong 33:ff681aa203f3 203 logInfo("defaulting Dot configuration");
tesla_xudong 33:ff681aa203f3 204 dot->resetConfig();
tesla_xudong 33:ff681aa203f3 205 dot->resetNetworkSession();
tesla_xudong 33:ff681aa203f3 206
tesla_xudong 33:ff681aa203f3 207 // make sure library logging is turned on
tesla_xudong 33:ff681aa203f3 208 dot->setLogLevel(mts::MTSLog::INFO_LEVEL);
tesla_xudong 33:ff681aa203f3 209
tesla_xudong 33:ff681aa203f3 210 // attach the custom events handler
tesla_xudong 33:ff681aa203f3 211 dot->setEvents(&events);
tesla_xudong 33:ff681aa203f3 212
tesla_xudong 33:ff681aa203f3 213 // update configuration if necessary
tesla_xudong 33:ff681aa203f3 214 if (dot->getJoinMode() != mDot::OTA) {
tesla_xudong 33:ff681aa203f3 215 logInfo("changing network join mode to OTA");
tesla_xudong 33:ff681aa203f3 216 if (dot->setJoinMode(mDot::OTA) != mDot::MDOT_OK) {
tesla_xudong 33:ff681aa203f3 217 logError("failed to set network join mode to OTA");
tesla_xudong 33:ff681aa203f3 218 }
tesla_xudong 33:ff681aa203f3 219 }
tesla_xudong 33:ff681aa203f3 220 // in OTA and AUTO_OTA join modes, the credentials can be passed to the library as a name and passphrase or an ID and KEY
tesla_xudong 33:ff681aa203f3 221 // only one method or the other should be used!
tesla_xudong 33:ff681aa203f3 222 // network ID = crc64(network name)
tesla_xudong 33:ff681aa203f3 223 // network KEY = cmac(network passphrase)
jreiss 36:18e6b0e367b6 224 // update_ota_config_name_phrase(network_name, network_passphrase, frequency_sub_band, network_type, ack);
jreiss 36:18e6b0e367b6 225 update_ota_config_id_key(network_id, network_key, frequency_sub_band, network_type, ack);
tesla_xudong 33:ff681aa203f3 226
tesla_xudong 33:ff681aa203f3 227 // configure the Dot for class C operation
tesla_xudong 33:ff681aa203f3 228 // the Dot must also be configured on the gateway for class C
tesla_xudong 33:ff681aa203f3 229 // use the lora-query application to do this on a Conduit: http://www.multitech.net/developer/software/lora/lora-network-server/
tesla_xudong 33:ff681aa203f3 230 // to provision your Dot for class C operation with a 3rd party gateway, see the gateway or network provider documentation
tesla_xudong 33:ff681aa203f3 231 logInfo("changing network mode to class C");
tesla_xudong 33:ff681aa203f3 232 if (dot->setClass("C") != mDot::MDOT_OK) {
tesla_xudong 33:ff681aa203f3 233 logError("failed to set network mode to class C");
tesla_xudong 33:ff681aa203f3 234 }
tesla_xudong 33:ff681aa203f3 235
tesla_xudong 33:ff681aa203f3 236 // enable or disable Adaptive Data Rate
tesla_xudong 33:ff681aa203f3 237 dot->setAdr(adr);
tesla_xudong 33:ff681aa203f3 238
tesla_xudong 33:ff681aa203f3 239 // Configure the join delay
tesla_xudong 33:ff681aa203f3 240 dot->setJoinDelay(join_delay);
tesla_xudong 33:ff681aa203f3 241
tesla_xudong 33:ff681aa203f3 242 // save changes to configuration
tesla_xudong 33:ff681aa203f3 243 logInfo("saving configuration");
tesla_xudong 33:ff681aa203f3 244 if (!dot->saveConfig()) {
tesla_xudong 33:ff681aa203f3 245 logError("failed to save configuration");
tesla_xudong 33:ff681aa203f3 246 }
tesla_xudong 33:ff681aa203f3 247
tesla_xudong 33:ff681aa203f3 248 // display configuration
tesla_xudong 33:ff681aa203f3 249 display_config();
tesla_xudong 33:ff681aa203f3 250 // uint32_t ret;
tesla_xudong 33:ff681aa203f3 251 // uint16_t light;
tesla_xudong 33:ff681aa203f3 252 std::string tx_str;
tesla_xudong 33:ff681aa203f3 253 // uint8_t recv_from_uart;
tesla_xudong 33:ff681aa203f3 254
jreiss 36:18e6b0e367b6 255 std::vector<uint8_t> tx_data;
jreiss 36:18e6b0e367b6 256
jreiss 36:18e6b0e367b6 257 int count = 0;
jreiss 36:18e6b0e367b6 258
tesla_xudong 33:ff681aa203f3 259 while (true) {
tesla_xudong 33:ff681aa203f3 260
tesla_xudong 33:ff681aa203f3 261 // join network if not joined
tesla_xudong 33:ff681aa203f3 262 if (!dot->getNetworkJoinStatus()) {
tesla_xudong 33:ff681aa203f3 263 join_network();
jreiss 36:18e6b0e367b6 264 while (dot->getIsTransmitting()) ;
jreiss 36:18e6b0e367b6 265
jreiss 36:18e6b0e367b6 266 dot->setAck(1);
jreiss 36:18e6b0e367b6 267
jreiss 36:18e6b0e367b6 268 events.AckReceived = false;
jreiss 36:18e6b0e367b6 269
jreiss 36:18e6b0e367b6 270 while (!events.AckReceived) {
jreiss 36:18e6b0e367b6 271 send_string("start!",dot);
jreiss 36:18e6b0e367b6 272 }
jreiss 36:18e6b0e367b6 273
jreiss 36:18e6b0e367b6 274 events.AckReceived = false;
jreiss 36:18e6b0e367b6 275
jreiss 36:18e6b0e367b6 276 while (!events.AckReceived) {
jreiss 36:18e6b0e367b6 277 send_string(tx_str.c_str(),dot);
jreiss 36:18e6b0e367b6 278 }
jreiss 36:18e6b0e367b6 279
jreiss 36:18e6b0e367b6 280 dot->setAck(0);
jreiss 36:18e6b0e367b6 281 }
jreiss 35:470b2b934241 282
jreiss 36:18e6b0e367b6 283 if (!Last_RX.empty()) { // || count++ > 100) {
jreiss 36:18e6b0e367b6 284 count = 0;
jreiss 36:18e6b0e367b6 285
tesla_xudong 33:ff681aa203f3 286 tx_str=Last_RX;
tesla_xudong 33:ff681aa203f3 287 Last_RX.clear();
tesla_xudong 33:ff681aa203f3 288
tesla_xudong 33:ff681aa203f3 289 pc.printf("%s",tx_str.c_str());
jreiss 36:18e6b0e367b6 290 send_string(tx_str.c_str(),dot);
tesla_xudong 33:ff681aa203f3 291 }
tesla_xudong 33:ff681aa203f3 292
jreiss 35:470b2b934241 293 osDelay(100);
tesla_xudong 33:ff681aa203f3 294 }
tesla_xudong 33:ff681aa203f3 295 }
tesla_xudong 33:ff681aa203f3 296
tesla_xudong 33:ff681aa203f3 297 #endif
tesla_xudong 33:ff681aa203f3 298