// Parse LoRa class B device beacon (RX2) downlink message
// https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5038744/
void parseLoraMsg() {
    int i;
    Serial.println(F("PHYPayload MHDR:"));
    Serial.print(F("MType: "));
    Serial.print((rxPacket[0] & B11100000) >> 5);
    Serial.print("\t");
    Serial.print(F("RFU: "));
    Serial.print((rxPacket[0] & B00011100) >> 2);
    Serial.print("\t");
    Serial.print(F("Major: "));
    Serial.println(rxPacket[0] & B00000011);
    Serial.println(F("MACPayload FHDR: "));
    Serial.print(F("DevAddr: "));
    for (i = 1; i < 5; i++) {
      Serial.print(rxPacket[i]);
    }
    Serial.println("");
    Serial.print(F("FCtrl:\tADR: "));
    Serial.print((rxPacket[5] & B10000000) >> 7);
    Serial.print(F(" ADRAckReq: "));
    Serial.print((rxPacket[5] & B01000000) >> 6);
    Serial.print(F(" ACK: "));
    Serial.print((rxPacket[5] & B00100000) >> 5);
    Serial.print(F(" RFU: "));
    Serial.print((rxPacket[5] & B00010000) >> 4);
    Serial.print(F(" FOptsLen: "));
    uint8_t foptslen = rxPacket[5] & B00001111;
    Serial.println(foptslen);
    Serial.print(F("FCnt: "));
    Serial.print(rxPacket[6]);
    Serial.print(rxPacket[7]);
    if (foptslen > 0) {
      Serial.println("");
      Serial.print(F("FOpts: (MACCommand(s) byte 1: CID, bytes 2-4: Args) "));
      for (i = 8; i < (8 + foptslen); i++) {
        Serial.print(rxPacket[i]);
      }
      foptslen = i;
    }
    else {
      foptslen = 8;
    }
    Serial.println("");
    Serial.print(F("FPort: "));
    Serial.print(rxPacket[foptslen]);
}

https://teknokoodiradio.vuodatus.net/lue/2017/12/monitoring-lorawan-rx2-869-525-mhz-downlink-channel