MIC Mismatch- Healtec esp32 + ttn + lps8

Hello,
I tried to connect Healtec esp32 lora v2 do ttn via Dragino LPS8
And - I can see messages on gateway bookmark, but when I tried to connect it in Aplication bookmark - it failed.
my sketch is:

#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>

#include <U8x8lib.h>

#define DISABLE_PING 0
#define DISABLE_BEACONS 0

static const u1_t PROGMEM APPEUI[8] = {0x7C, 0x0A, 0x89, 0x2B, 0x17, 0xAE, 0x48, 0x85};
void os_getArtEui(u1_t * buf) { memcpy_P(buf, APPEUI, 8);}

static const u1_t PROGMEM DEVEUI[8] = {0x9F, 0x48, 0x05, 0xD0, 0x7E, 0xD5, 0xB3, 0x73};
void os_getDevEui(u1_t * buf) { memcpy_P(buf, DEVEUI, 8);}

static const u1_t PROGMEM APPKEY[16] = {0x38, 0x3B, 0xD5, 0x7E, 0xB9, 0xA0, 0x0E, 0x60, 0xAA, 0x31, 0xE4, 0x1B, 0x9F, 0x44, 0xFB, 0xAE};

//static const u1_t PROGMEM APPKEY[16] = {0xAE, 0xFB, 0x44, 0x9F, 0x1B, 0xE4, 0x31, 0xAA, 0x60, 0x0E, 0xA0, 0xB9, 0x7E, 0xD5, 0x3B, 0x38};

void os_getDevKey(u1_t * buf) { memcpy_P(buf, APPKEY, 16);}

U8X8_SSD1306_128X64_NONAME_SW_I2C display_(/* clock=/ 15, / data=/ 4, / reset=*/ 16);

static uint8_t mydata = “00”;

static osjob_t sendjob;

const unsigned TX_INTERVAL = 60;

const lmic_pinmap lmic_pins = {
.nss = 18, // CS PIN
.rxtx = LMIC_UNUSED_PIN,
.rst = 14, // reset pin
.dio = {
26,
26,
26
}
};

void printHex2(unsigned v) {
v &= 0xff;
if (v < 16)
Serial.print(‘0’);
Serial.print(v, HEX);
}

void onEvent(ev_t ev) {
Serial.print(os_getTime());
Serial.print(": ");
switch (ev) {
case EV_JOINING:
Serial.println(F(“EV_JOINING”));
break;

case EV_JOINED:
Serial.println(F(“EV_JOINED”)); {
u4_t netid = 0;
devaddr_t devaddr = 0;
u1_t nwkKey[16];
u1_t artKey[16];
LMIC_getSessionKeys( & netid, & devaddr, nwkKey, artKey);
Serial.print("netid: ");
Serial.println(netid, DEC);
Serial.print("devaddr: ");
Serial.println(devaddr, HEX);
Serial.print(“AppSKey: “);
for (size_t i = 0; i < sizeof(artKey); ++i) {
if (i != 0)
Serial.print(” “);
printHex2(artKey[i]);
}
Serial.println(””);
Serial.print("NwkSKey: “);
for (size_t i = 0; i < sizeof(nwkKey); ++i) {
if (i != 0)
Serial.print(” ");
printHex2(nwkKey[i]);
}
Serial.println();
display_.drawString(0, 5, “Network Joined”);
}
// Disable link check validation (automatically enabled
// during join, but because slow data rates change max TX
// size, we don’t use it in this example.
LMIC_setLinkCheckMode(0);
break;
case EV_JOIN_FAILED:
Serial.println(F(“EV_JOIN_FAILED”));
break;
case EV_REJOIN_FAILED:
Serial.println(F(“EV_REJOIN_FAILED”));
break;
break;
case EV_TXCOMPLETE:
Serial.println(F(“EV_TXCOMPLETE (includes waiting for RX windows)”));
display_.drawString(0, 3, “Data Sent”);
if (LMIC.txrxFlags & TXRX_ACK)
Serial.println(F(“Received ack”));
if (LMIC.dataLen) {
Serial.print(F(“Received “));
Serial.print(LMIC.dataLen);
Serial.println(F(” bytes of payload”));

  display_.drawString(0, 4, "Data received");
  Serial.println(F("Data is "));

  // Change the following codes to process incoming data !!
  for (int counter = 0; counter < LMIC.dataLen; counter++) {
    Serial.print(LMIC.frame[LMIC.dataBeg + counter], HEX);
  }
  Serial.println(F(" "));

}
  else
    display_.drawString(0, 4, "                   ");
// Schedule next transmission
os_setTimedCallback( & sendjob, os_getTime() + sec2osticks(TX_INTERVAL), do_send);
break;

case EV_LOST_TSYNC:
Serial.println(F(“EV_LOST_TSYNC”));
break;
case EV_RESET:
Serial.println(F(“EV_RESET”));
break;
case EV_RXCOMPLETE:
// data received in ping slot
Serial.println(F(“EV_RXCOMPLETE”));
break;
case EV_LINK_DEAD:
Serial.println(F(“EV_LINK_DEAD”));
break;
case EV_LINK_ALIVE:
Serial.println(F(“EV_LINK_ALIVE”));
break;
case EV_TXSTART:
Serial.println(F(“EV_TXSTART”));
break;
case EV_TXCANCELED:
Serial.println(F(“EV_TXCANCELED”));
break;
case EV_JOIN_TXCOMPLETE:
Serial.println(F(“EV_JOIN_TXCOMPLETE: no JoinAccept”));
break;

default:
Serial.print(F("Unknown event: "));
Serial.println((unsigned) ev);
break;
}
}

void do_send(osjob_t * j) {
display_.clear();
display_.drawString(0, 0, “TTGO ESP32 LoRa Test”);
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F(“OP_TXRXPEND, not sending”));
} else {
// Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, mydata, sizeof(mydata) - 1, 0);
Serial.println(F(“Packet queued”));
display_.drawString(0, 2, “Packet Queued”);
}
// Next TX is scheduled after TX_COMPLETE event.
}

void setup() {
delay(5000);
while (!Serial)
;
Serial.begin(9600);
Serial.println(F(“Starting”));
display_.begin();
display_.setFont(u8x8_font_pxplusibmcgathin_r);
display_.drawString(0, 0, “TTGO ESP32 LoRa Test”);
#ifdef CFG_in868
Serial.println(F(“Module Configured for Inidian LoRa band (865-867 MHz)”));
display_.drawString(0, 1, “Using IN866 Band”);
#endif
// LMIC init
os_init();
// Reset the MAC state. Session and pending data transfers will be discarded.
LMIC_reset();
LMIC_setClockError(MAX_CLOCK_ERROR * 5 / 100);
do_send( & sendjob);
}

void loop() {
//os_runloop_once();
do_send( & sendjob);
delay(5000);
}

And result in gateway message is like below:

“data”: {
“@type”: “type.googleapis.com/ttn.lorawan.v3.GatewayUplinkMessage”,
“message”: {
“raw_payload”: “AHK4ANB+1bNwFtsfAAujBACFUITGZ/o=”,
“payload”: {
“m_hdr”: {},
“mic”: “hMZn+g==”,
“join_request_payload”: {
“join_eui”: “70B3D57ED000B872”,
“dev_eui”: “0004A30B001FDB16”,
“dev_nonce”: “5085”
}
},

I see that join_eui and dev_eui are different and I have no idea why.
I tried to set those values to new device in app but I’m receiving message: “MIC mismatch” - probably that AppKey is incorrect - but I have no idea how to reach proper one.

That looks like someone else’s device. I’m glad you can’t get the AppKey and there is a MIC mismatch, otherwise you would have hijacked a session for hardware that is not yours.

1 Like

Additionally, when you do organise a set of EUI’s + AppKey, you need to change the TX_INTERVAL to something far greater than 60 seconds as it is likely in breach of local laws as well as definitely being in breach of the TTN Fair Use Policy.

1 Like