kopia lustrzana https://github.com/pjalocha/esp32-ogn-tracker
Process requests for device status
rodzic
670043d468
commit
ff20127a6a
|
@ -64,21 +64,25 @@ class LoRaWANnode
|
||||||
|
|
||||||
// uint8_t TxMAC[16];
|
// uint8_t TxMAC[16];
|
||||||
// uint8_t TxMACs;
|
// uint8_t TxMACs;
|
||||||
static const size_t MaxPacketSize = 64; // [bytes]
|
static const size_t MaxPacketSize = 63; // [bytes]
|
||||||
uint8_t Packet[MaxPacketSize]; // generic packet for storage/processing
|
uint8_t Packet[MaxPacketSize]; // generic packet for storage/processing
|
||||||
|
|
||||||
|
uint8_t TxBattLevel; // battery level to be transmitted in the DevStatusAns
|
||||||
|
uint8_t TxOptLen;
|
||||||
|
uint8_t TxOpt[15]; // MAC commands/options to be transmitted
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LoRaWANnode() { Reset(); }
|
LoRaWANnode() { Reset(); TxOptLen=0; TxBattLevel=0xFF; }
|
||||||
|
|
||||||
void Reset(void)
|
void Reset(void)
|
||||||
{ State=0; DevNonce=0; JoinNonce=0;
|
{ State=0; DevNonce=0; JoinNonce=0;
|
||||||
LastTx=0; TxCount=0; LastRx=0; RxCount=0; RxSilent=0; Flags=0; LastSaved=0;
|
LastTx=0; TxCount=0; LastRx=0; RxCount=0; RxSilent=0; Flags=0; LastSaved=0;
|
||||||
setCRC(); }
|
setCRC(); }
|
||||||
|
|
||||||
void Reset(uint64_t MAC, uint8_t *AppKey=0)
|
void Reset(uint64_t MAC, uint8_t *NewKey=0)
|
||||||
{ AppEUI=0x70B3D57ED0035895; // set OGN application
|
{ AppEUI=0x70B3D57ED0035895; // set OGN application
|
||||||
DevEUI=MAC; // set DevEUI from MAC
|
DevEUI=MAC; // set DevEUI from MAC
|
||||||
if(AppKey) memcpy(this->AppKey, AppKey, 16); // set the AppKey
|
if(NewKey) memcpy(AppKey, NewKey, 16); // set the AppKey
|
||||||
Reset(); } // reset to not-joined state
|
Reset(); } // reset to not-joined state
|
||||||
|
|
||||||
void Disconnect(void)
|
void Disconnect(void)
|
||||||
|
@ -155,8 +159,8 @@ class LoRaWANnode
|
||||||
|
|
||||||
int procJoinAccept(const RFM_LoRa_RxPacket &RxPacket)
|
int procJoinAccept(const RFM_LoRa_RxPacket &RxPacket)
|
||||||
{ int Ret=procJoinAccept(RxPacket.Byte, RxPacket.Len); if(Ret<0) return Ret;
|
{ int Ret=procJoinAccept(RxPacket.Byte, RxPacket.Len); if(Ret<0) return Ret;
|
||||||
RxSNR = RxPacket.SNR;
|
RxSNR = RxPacket.SNR; // store the SNR of the join-accept
|
||||||
RxRSSI = RxPacket.RSSI;
|
RxRSSI = RxPacket.RSSI; // store the RSSI
|
||||||
return Ret; }
|
return Ret; }
|
||||||
|
|
||||||
int procJoinAccept(const uint8_t *PktData, int PktLen) // process Join-Accept packet (5sec after Join-Request)
|
int procJoinAccept(const uint8_t *PktData, int PktLen) // process Join-Accept packet (5sec after Join-Request)
|
||||||
|
@ -175,7 +179,8 @@ class LoRaWANnode
|
||||||
RxDelay = Packet[12];
|
RxDelay = Packet[12];
|
||||||
State = 2; // State = accepted on network
|
State = 2; // State = accepted on network
|
||||||
UpCount = 0;
|
UpCount = 0;
|
||||||
DnCount = 0;
|
DnCount = 0xFFFFFFFF;
|
||||||
|
TxOptLen = 0;
|
||||||
#ifdef WITH_PRINTF
|
#ifdef WITH_PRINTF
|
||||||
printf("Accept[%d] ", PktLen-4);
|
printf("Accept[%d] ", PktLen-4);
|
||||||
for(int Idx=0; Idx<PktLen-4; Idx++)
|
for(int Idx=0; Idx<PktLen-4; Idx++)
|
||||||
|
@ -192,10 +197,13 @@ class LoRaWANnode
|
||||||
int PktLen=0;
|
int PktLen=0;
|
||||||
Packet[PktLen++] = Type<<5; // packet-type
|
Packet[PktLen++] = Type<<5; // packet-type
|
||||||
PktLen+=writeInt(Packet+PktLen, DevAddr, 4); // Device Address
|
PktLen+=writeInt(Packet+PktLen, DevAddr, 4); // Device Address
|
||||||
uint8_t Ctrl=0; // Frame Control
|
uint8_t Ctrl=0x00; // Frame Control
|
||||||
if(TxACK) { Ctrl|=0x20; TxACK=0; } // if there is ACK to be transmitted
|
if(TxACK) { Ctrl|=0x20; TxACK=0; } // if there is ACK to be transmitted
|
||||||
Packet[PktLen++] = Ctrl; // Frame Control: ADR | ADR-ACK-Req | ACK | ClassB | FOptsLen[4]
|
Packet[PktLen++] = Ctrl | TxOptLen; // Frame Control: ADR | ADR-ACK-Req | ACK | ClassB | FOptsLen[4]
|
||||||
PktLen+=writeInt(Packet+PktLen, UpCount, 2); // uplink frame counter
|
PktLen+=writeInt(Packet+PktLen, UpCount, 2); // uplink frame counter
|
||||||
|
for(int Idx=0; Idx<TxOptLen; Idx++) // add options, MAC replies
|
||||||
|
Packet[PktLen++]=TxOpt[Idx];
|
||||||
|
TxOptLen=0;
|
||||||
Packet[PktLen++] = Port; // port
|
Packet[PktLen++] = Port; // port
|
||||||
LoRaMacPayloadEncrypt(Data, DataLen, AppSesKey, DevAddr, 0, UpCount, Packet+PktLen); PktLen+=DataLen; // copy+encrypt user data
|
LoRaMacPayloadEncrypt(Data, DataLen, AppSesKey, DevAddr, 0, UpCount, Packet+PktLen); PktLen+=DataLen; // copy+encrypt user data
|
||||||
uint32_t MIC=0;
|
uint32_t MIC=0;
|
||||||
|
@ -211,13 +219,14 @@ class LoRaWANnode
|
||||||
|
|
||||||
int procRxData(const RFM_LoRa_RxPacket &RxPacket)
|
int procRxData(const RFM_LoRa_RxPacket &RxPacket)
|
||||||
{ int Ret=procRxData(RxPacket.Byte, RxPacket.Len); if(Ret<0) return Ret;
|
{ int Ret=procRxData(RxPacket.Byte, RxPacket.Len); if(Ret<0) return Ret;
|
||||||
RxSNR += (RxPacket.SNR-RxSNR+1)/2;
|
RxSNR += (RxPacket.SNR-RxSNR+1)/2; // average the SNR
|
||||||
RxRSSI += (RxPacket.RSSI-RxRSSI+1)/2;
|
RxRSSI += (RxPacket.RSSI-RxRSSI+1)/2; // average the RSSI
|
||||||
return Ret; }
|
return Ret; }
|
||||||
|
|
||||||
int procRxData(const uint8_t *PktData, int PktLen)
|
int procRxData(const uint8_t *PktData, int PktLen)
|
||||||
{ if(PktLen<12) return -1;
|
{ if(PktLen<12) return -1;
|
||||||
uint8_t Type = PktData[0]>>5; if(Type!=3 && Type!=5) return -1; // Frame Type: 3=unconfirmed data downlink, 5=confirmed data downlink
|
uint8_t Type = PktData[0]>>5; // Frame Type
|
||||||
|
if(Type!=3 && Type!=5) return -1; // Frame Type: 3=unconfirmed data downlink, 5=confirmed data downlink
|
||||||
uint32_t Addr=readInt<uint32_t>(PktData+1, 4); // device address
|
uint32_t Addr=readInt<uint32_t>(PktData+1, 4); // device address
|
||||||
if(Addr!=DevAddr) return 0; // check if packet is for us (it could be for somebody else)
|
if(Addr!=DevAddr) return 0; // check if packet is for us (it could be for somebody else)
|
||||||
uint8_t Ctrl = PktData[5]; // Frame Control: ADR | RFU | ACK | FPending | FOptLen[4]
|
uint8_t Ctrl = PktData[5]; // Frame Control: ADR | RFU | ACK | FPending | FOptLen[4]
|
||||||
|
@ -253,8 +262,30 @@ class LoRaWANnode
|
||||||
// }
|
// }
|
||||||
return DataLen; }
|
return DataLen; }
|
||||||
|
|
||||||
void procRxOpt(const uint8_t *Opt, uint8_t Len) // process the options
|
void procRxOpt(const uint8_t *Opt, uint8_t OptLen) // process the options
|
||||||
{ }
|
{ if(OptLen==0) return;
|
||||||
|
for(uint8_t Idx=0; Idx<OptLen; Idx++)
|
||||||
|
{ uint8_t Cmd=Opt[Idx];
|
||||||
|
if(Cmd==0x03) // LinkADRReq
|
||||||
|
{ TxOpt[TxOptLen++]=0x03; // LinkADRAns
|
||||||
|
TxOpt[TxOptLen++]=0x00; // negative 0x00 or positive 0x07 on all requested changes ?
|
||||||
|
Idx+=4; continue; } // skip the actual data for this command
|
||||||
|
if(Cmd==0x06) // DevStatusReq
|
||||||
|
{ TxOpt[TxOptLen++]=0x06; // DevStatusAns
|
||||||
|
TxOpt[TxOptLen++]=TxBattLevel; // battery level: 0=ext. power, 1..254=level, 255=not available
|
||||||
|
TxOpt[TxOptLen++]=(RxSNR>>2)&0x3F; // Rx SNR
|
||||||
|
continue; }
|
||||||
|
break; }
|
||||||
|
// #ifdef WITH_PRINTF
|
||||||
|
printf("RxOpt: [%d] ", OptLen);
|
||||||
|
for(int Idx=0; Idx<OptLen; Idx++)
|
||||||
|
printf("%02X", Opt[Idx]);
|
||||||
|
printf(" => [%d] ", TxOptLen);
|
||||||
|
for(int Idx=0; Idx<TxOptLen; Idx++)
|
||||||
|
printf("%02X", TxOpt[Idx]);
|
||||||
|
printf("\n");
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
// { Format_String(CONS_UART_Write, "LoRaWAN Opt: ");
|
// { Format_String(CONS_UART_Write, "LoRaWAN Opt: ");
|
||||||
// for(uint8_t Idx=0; Idx<Len; Idx++)
|
// for(uint8_t Idx=0; Idx<Len; Idx++)
|
||||||
// Format_Hex(CONS_UART_Write, Opt[Idx]);
|
// Format_Hex(CONS_UART_Write, Opt[Idx]);
|
||||||
|
|
Ładowanie…
Reference in New Issue