Two way data over LoRaWAN using Multitech mDot

Dependencies:   libmDot-mbed5

This is example firmware for the Multitech mDot. It demonstrates how to:

  • Do two-way data.
  • Sleep aggressively and only wake up when the wake-up pin is triggered.
  • Handle errors, retries and duty cycle errors.
  • Cache data in non-volatile storage.

Based on mbed OS 5.1, hard faults against mbed OS 5.3 unfortunately. Can be compiled with GCC and ARMCC (but not IAR).

To do a new transmission, short pin D6 / PA_1.

Committer:
Jan Jongboom
Date:
Wed Jan 04 13:45:49 2017 +0000
Revision:
4:0fd5e5e121ea
Parent:
2:ff17ce021cfb
Retry OTA join when fails during startup

Who changed what in which revision?

UserRevisionLine numberNew contents of line
janjongboom 0:20fbd6f66b11 1 #ifndef DISPENSER_PARSE_KEYS_H
janjongboom 0:20fbd6f66b11 2 #define DISPENSER_PARSE_KEYS_H
janjongboom 0:20fbd6f66b11 3
janjongboom 0:20fbd6f66b11 4 #include "mDot.h"
janjongboom 0:20fbd6f66b11 5
janjongboom 0:20fbd6f66b11 6 class ParseKeys {
janjongboom 0:20fbd6f66b11 7 public:
Jan Jongboom 2:ff17ce021cfb 8 static bool initializePersonalized(mDot* dot, const char* aDevAddr, const char* aNwkSKey, const char* aAppSKey) {
janjongboom 0:20fbd6f66b11 9 int32_t ret;
janjongboom 0:20fbd6f66b11 10
janjongboom 0:20fbd6f66b11 11 // parse devkey
janjongboom 0:20fbd6f66b11 12 std::vector<uint8_t> loriot_nwk_skey(16);
janjongboom 0:20fbd6f66b11 13 for (uint8_t ni = 0; ni < 16; ni++)
janjongboom 0:20fbd6f66b11 14 {
janjongboom 0:20fbd6f66b11 15 const char hex[] = { '0', 'x', aNwkSKey[ni * 2], aNwkSKey[ni * 2 + 1], '\0' };
janjongboom 0:20fbd6f66b11 16 loriot_nwk_skey[ni] = strtoul(hex, NULL, 16);
janjongboom 0:20fbd6f66b11 17 }
janjongboom 0:20fbd6f66b11 18
janjongboom 0:20fbd6f66b11 19 // parse appkey
janjongboom 0:20fbd6f66b11 20 std::vector<uint8_t> loriot_app_skey(16);
janjongboom 0:20fbd6f66b11 21 for (uint8_t ai = 0; ai < 16; ai++)
janjongboom 0:20fbd6f66b11 22 {
janjongboom 0:20fbd6f66b11 23 const char hex[] = { '0', 'x', aAppSKey[ai * 2], aAppSKey[ai * 2 + 1], '\0' };
janjongboom 0:20fbd6f66b11 24 loriot_app_skey[ai] = strtoul(hex, NULL, 16);
janjongboom 0:20fbd6f66b11 25 }
janjongboom 0:20fbd6f66b11 26
janjongboom 0:20fbd6f66b11 27 // parse dev addr
janjongboom 0:20fbd6f66b11 28 std::vector<uint8_t> loriot_dev_addr(4);
janjongboom 0:20fbd6f66b11 29 for (uint8_t ai = 0; ai < 4; ai++)
janjongboom 0:20fbd6f66b11 30 {
janjongboom 0:20fbd6f66b11 31 const char hex[] = { '0', 'x', aDevAddr[ai * 2], aDevAddr[ai * 2 + 1], '\0' };
janjongboom 0:20fbd6f66b11 32 loriot_dev_addr[ai] = strtoul(hex, NULL, 16);
janjongboom 0:20fbd6f66b11 33 }
janjongboom 0:20fbd6f66b11 34
Jan Jongboom 2:ff17ce021cfb 35 // set join mode to MANUAL so the mDot doesn't have to rejoin after sleeping
Jan Jongboom 2:ff17ce021cfb 36 logInfo("setting join mode to MANUAL");
Jan Jongboom 2:ff17ce021cfb 37 if ((ret = dot->setJoinMode(mDot::MANUAL)) != mDot::MDOT_OK) {
Jan Jongboom 2:ff17ce021cfb 38 logError("failed to set join mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
Jan Jongboom 2:ff17ce021cfb 39 }
Jan Jongboom 2:ff17ce021cfb 40
janjongboom 0:20fbd6f66b11 41 logInfo("setting network address");
janjongboom 0:20fbd6f66b11 42 if ((ret = dot->setNetworkAddress(loriot_dev_addr)) != mDot::MDOT_OK) {
janjongboom 0:20fbd6f66b11 43 logError("failed to set network address %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
janjongboom 0:20fbd6f66b11 44 return false;
janjongboom 0:20fbd6f66b11 45 }
janjongboom 0:20fbd6f66b11 46
janjongboom 0:20fbd6f66b11 47 logInfo("setting network session key");
janjongboom 0:20fbd6f66b11 48 if ((ret = dot->setNetworkSessionKey(loriot_nwk_skey)) != mDot::MDOT_OK) {
janjongboom 0:20fbd6f66b11 49 logError("failed to set network session key %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
janjongboom 0:20fbd6f66b11 50 return false;
janjongboom 0:20fbd6f66b11 51 }
janjongboom 0:20fbd6f66b11 52
janjongboom 0:20fbd6f66b11 53 logInfo("setting app session key");
janjongboom 0:20fbd6f66b11 54 if ((ret = dot->setDataSessionKey(loriot_app_skey)) != mDot::MDOT_OK) {
janjongboom 0:20fbd6f66b11 55 logError("failed to set app session key %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
janjongboom 0:20fbd6f66b11 56 return false;
janjongboom 0:20fbd6f66b11 57 }
janjongboom 0:20fbd6f66b11 58
janjongboom 0:20fbd6f66b11 59 return true;
janjongboom 0:20fbd6f66b11 60 }
Jan Jongboom 2:ff17ce021cfb 61
Jan Jongboom 2:ff17ce021cfb 62 static bool initializeOta(mDot* dot, const char* aAppEui, const char* aAppKey) {
Jan Jongboom 2:ff17ce021cfb 63 int32_t ret;
Jan Jongboom 2:ff17ce021cfb 64
Jan Jongboom 2:ff17ce021cfb 65 // parse app key
Jan Jongboom 2:ff17ce021cfb 66 std::vector<uint8_t> loriot_app_key(16);
Jan Jongboom 2:ff17ce021cfb 67 for (uint8_t ni = 0; ni < 16; ni++)
Jan Jongboom 2:ff17ce021cfb 68 {
Jan Jongboom 2:ff17ce021cfb 69 const char hex[] = { '0', 'x', aAppKey[ni * 2], aAppKey[ni * 2 + 1], '\0' };
Jan Jongboom 2:ff17ce021cfb 70 loriot_app_key[ni] = strtoul(hex, NULL, 16);
Jan Jongboom 2:ff17ce021cfb 71 }
Jan Jongboom 2:ff17ce021cfb 72
Jan Jongboom 2:ff17ce021cfb 73 // parse app eui
Jan Jongboom 2:ff17ce021cfb 74 std::vector<uint8_t> loriot_app_eui(8);
Jan Jongboom 2:ff17ce021cfb 75 for (uint8_t ai = 0; ai < 8; ai++)
Jan Jongboom 2:ff17ce021cfb 76 {
Jan Jongboom 2:ff17ce021cfb 77 const char hex[] = { '0', 'x', aAppEui[ai * 2], aAppEui[ai * 2 + 1], '\0' };
Jan Jongboom 2:ff17ce021cfb 78 loriot_app_eui[ai] = strtoul(hex, NULL, 16);
Jan Jongboom 2:ff17ce021cfb 79 }
Jan Jongboom 2:ff17ce021cfb 80
Jan Jongboom 2:ff17ce021cfb 81 // set join mode to OTA so the mDot doesn't have to rejoin after sleeping
Jan Jongboom 2:ff17ce021cfb 82 logInfo("setting join mode to OTA");
Jan Jongboom 2:ff17ce021cfb 83 if ((ret = dot->setJoinMode(mDot::OTA)) != mDot::MDOT_OK) {
Jan Jongboom 2:ff17ce021cfb 84 logError("failed to set join mode %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
Jan Jongboom 2:ff17ce021cfb 85 }
Jan Jongboom 2:ff17ce021cfb 86
Jan Jongboom 2:ff17ce021cfb 87 logInfo("setting network id");
Jan Jongboom 2:ff17ce021cfb 88 if ((ret = dot->setNetworkId(loriot_app_eui)) != mDot::MDOT_OK) {
Jan Jongboom 2:ff17ce021cfb 89 logError("failed to set network id %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
Jan Jongboom 2:ff17ce021cfb 90 return false;
Jan Jongboom 2:ff17ce021cfb 91 }
Jan Jongboom 2:ff17ce021cfb 92
Jan Jongboom 2:ff17ce021cfb 93 logInfo("setting network key");
Jan Jongboom 2:ff17ce021cfb 94 if ((ret = dot->setNetworkKey(loriot_app_key)) != mDot::MDOT_OK) {
Jan Jongboom 2:ff17ce021cfb 95 logError("failed to set network key %d:%s", ret, mDot::getReturnCodeString(ret).c_str());
Jan Jongboom 2:ff17ce021cfb 96 return false;
Jan Jongboom 2:ff17ce021cfb 97 }
Jan Jongboom 2:ff17ce021cfb 98
Jan Jongboom 2:ff17ce021cfb 99 return true;
Jan Jongboom 2:ff17ce021cfb 100 }
janjongboom 0:20fbd6f66b11 101 };
janjongboom 0:20fbd6f66b11 102
janjongboom 0:20fbd6f66b11 103 #endif // DISPENSER_PARSE_KEYS_H