Skip to content

Commit

Permalink
init commit
Browse files Browse the repository at this point in the history
  • Loading branch information
kadirozdinc committed Jul 27, 2023
1 parent eb123a6 commit 39db783
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 18 deletions.
5 changes: 4 additions & 1 deletion src/arduino-rfm/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
// To define your LoRaWAN frequency band here
//#define AS_923
//#define AS_923_2
//#define EU_868
#define EU_868
//#define US_915
//#define AU_915

// If you dont define _CLASS_C_, CLASS_A mode will be on
#define _CLASS_C_

// Define max payload size used for this node
#define MAX_UPLINK_PAYLOAD_SIZE 220
#define MAX_DOWNLINK_PAYLOAD_SIZE 220
Expand Down
142 changes: 138 additions & 4 deletions src/arduino-rfm/LoRaMAC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "Config.h"
#include "Arduino.h"


/*
*****************************************************************************************
* FUNCTIONS
Expand All @@ -62,13 +63,14 @@
*****************************************************************************************
*/
void LORA_Cycle(sBuffer *Data_Tx, sBuffer *Data_Rx, RFM_command_t *RFM_Command, sLoRa_Session *Session_Data,
sLoRa_OTAA *OTAA_Data, sLoRa_Message *Message_Rx, sSettings *LoRa_Settings)
sLoRa_OTAA *OTAA_Data, sLoRa_Message *Message_Rx, sSettings *LoRa_Settings, msg_t *upMsg_Type)
{
Serial.println("cyclee..");
static const unsigned int Receive_Delay_1 = 1000;
static const unsigned int Receive_Delay_2 = 2000; // Receive_Delay_2 >= Receive_Delay_1 + RX1_Window
static const unsigned int RX1_Window = 1000;
static const unsigned int RX2_Window = 1000;

unsigned long prevTime = 0;
unsigned char rx1_ch = LoRa_Settings->Channel_Rx;
#ifdef US_915
Expand All @@ -87,8 +89,12 @@ void LORA_Cycle(sBuffer *Data_Tx, sBuffer *Data_Rx, RFM_command_t *RFM_Command,
pinMode(RFM_SWITCH,OUTPUT);
digitalWrite(RFM_SWITCH,0); //Rf switch inside RAK module change to Tx
#endif
//Lora send data
LORA_Send_Data(Data_Tx, Session_Data, LoRa_Settings);

//Lora send data & ack
if(*upMsg_Type == MSG_UP) LORA_Send_Data(Data_Tx, Session_Data, LoRa_Settings);
else if(*upMsg_Type == MSG_ACK) LORA_Send_ACK(Data_Tx, Session_Data, LoRa_Settings);


prevTime = millis();

#if (SAMR34)
Expand Down Expand Up @@ -133,6 +139,11 @@ void LORA_Cycle(sBuffer *Data_Tx, sBuffer *Data_Rx, RFM_command_t *RFM_Command,
return;
}

//
#ifdef _CLASS_C_
return;
#endif

// Class C open RX2 immediately after first rx window
if(LoRa_Settings->Mote_Class == CLASS_C){
#ifdef US_915
Expand Down Expand Up @@ -317,6 +328,129 @@ void LORA_Send_Data(sBuffer *Data_Tx, sLoRa_Session *Session_Data, sSettings *Lo
}
}

// send uplink message including ACK

void LORA_Send_ACK(sBuffer *Data_Tx, sLoRa_Session *Session_Data, sSettings *LoRa_Settings)
{
Serial.println("LoraMac send ack");
//Define variables
unsigned char i;

//Initialise RFM buffer
unsigned char RFM_Data[MAX_UPLINK_PAYLOAD_SIZE+65];
sBuffer RFM_Package = {&RFM_Data[0], 0x00};

//Initialise Message struct for a transmit message
sLoRa_Message Message;

Message.MAC_Header = 0x00;
Message.Frame_Port = 0x00; //set as MAC command
Message.Frame_Control = 0x00;

//Load device address from session data into the message
Message.DevAddr[0] = Session_Data->DevAddr[0];
Message.DevAddr[1] = Session_Data->DevAddr[1];
Message.DevAddr[2] = Session_Data->DevAddr[2];
Message.DevAddr[3] = Session_Data->DevAddr[3];

//Set up direction
Message.Direction = 0x00;

//Load the frame counter from the session data into the message
Message.Frame_Counter = *Session_Data->Frame_Counter;

//Set confirmation
//Unconfirmed
// if(LoRa_Settings->Confirm == 0x00)
// {
// Message.MAC_Header = Message.MAC_Header | 0x40;
// }
// //Confirmed
// else
// {
// Message.MAC_Header = Message.MAC_Header | 0x80;
// }
Message.MAC_Header = Message.MAC_Header | 0x40;

//Build the Radio Package
//Load mac header
RFM_Package.Data[0] = Message.MAC_Header;

//Load device address
RFM_Package.Data[1] = Message.DevAddr[3];
RFM_Package.Data[2] = Message.DevAddr[2];
RFM_Package.Data[3] = Message.DevAddr[1];
RFM_Package.Data[4] = Message.DevAddr[0];

//Load frame control
RFM_Package.Data[5] = (Message.Frame_Control | 0x20);

//Load frame counter
RFM_Package.Data[6] = (*Session_Data->Frame_Counter & 0x00FF);
RFM_Package.Data[7] = ((*Session_Data->Frame_Counter >> 8) & 0x00FF);

//Set data counter to 8
RFM_Package.Counter = 8;

//If there is data load the Frame_Port field
//Encrypt the data and load the data
if(Data_Tx->Counter > 0x00)
{
//Load Frame port field
//RFM_Data[8] = Message.Frame_Port;
RFM_Package.Data[8] = 0;

//Raise package counter
RFM_Package.Counter++;

//Encrypt the data
Encrypt_Payload(Data_Tx, Session_Data->AppSKey, &Message);

//Load Data
for(i = 0; i < Data_Tx->Counter; i++)
{
RFM_Package.Data[RFM_Package.Counter++] = Data_Tx->Data[i];
}


}

//Calculate MIC
Construct_Data_MIC(&RFM_Package, Session_Data, &Message);

//Load MIC in package
for(i = 0; i < 4; i++)
{
RFM_Package.Data[RFM_Package.Counter++] = Message.MIC[i];
}

//Send Package
RFM_Send_Package(&RFM_Package, LoRa_Settings);

//Raise Frame counter
if(*Session_Data->Frame_Counter != 0xFFFF)
{
//Raise frame counter
*Session_Data->Frame_Counter = *Session_Data->Frame_Counter + 1;
}
else
{
*Session_Data->Frame_Counter = 0x0000;
}

//Change channel for next message if hopping is activated
if(LoRa_Settings->Channel_Hopping == 0x01)
{
if(LoRa_Settings->Channel_Tx < 0x07)
{
LoRa_Settings->Channel_Tx++;
}
else
{
LoRa_Settings->Channel_Tx = 0x00;
}
}
}

/*
*****************************************************************************************
Expand Down
5 changes: 3 additions & 2 deletions src/arduino-rfm/LoRaMAC.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,17 @@
********************************************************************************************
*/

typedef enum {NO_RFM_COMMAND, NEW_RFM_COMMAND, RFM_COMMAND_DONE, JOIN} RFM_command_t;
typedef enum {NO_RFM_COMMAND, NEW_RFM_COMMAND, RFM_COMMAND_DONE, JOIN, NEW_ACK_COMMAND} RFM_command_t;

/*
*****************************************************************************************
* FUNCTION PROTOTYPES
*****************************************************************************************
*/

void LORA_Cycle(sBuffer *Data_Tx, sBuffer *Data_Rx, RFM_command_t *RFM_Command, sLoRa_Session *Session_Data, sLoRa_OTAA *OTAA_Data, sLoRa_Message *Message_Rx, sSettings *LoRa_Settings);
void LORA_Cycle(sBuffer *Data_Tx, sBuffer *Data_Rx, RFM_command_t *RFM_Command, sLoRa_Session *Session_Data, sLoRa_OTAA *OTAA_Data, sLoRa_Message *Message_Rx, sSettings *LoRa_Settings, msg_t *upMsg_Type);
void LORA_Send_Data(sBuffer *Data_Tx, sLoRa_Session *Session_Data, sSettings *LoRa_Settings);
void LORA_Send_ACK(sBuffer *Data_Tx, sLoRa_Session *Session_Data, sSettings *LoRa_Settings);
void LORA_Receive_Data(sBuffer *Data_Rx, sLoRa_Session *Session_Data, sLoRa_OTAA *OTAA_Data, sLoRa_Message *Message, sSettings *LoRa_Settings);
bool LORA_join_Accept(sBuffer *Data_Rx,sLoRa_Session *Session_Data, sLoRa_OTAA *OTAA_Data, sLoRa_Message *Message, sSettings *LoRa_Settings);
void LoRa_Send_JoinReq(sLoRa_OTAA *OTAA_Data, sSettings *LoRa_Settings);
Expand Down
2 changes: 2 additions & 0 deletions src/arduino-rfm/Struct.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ typedef enum {NO_RX, NEW_RX} rx_t;

typedef enum {NO_ACK, NEW_ACK} ack_t;

typedef enum {MSG_UP, MSG_ACK} msg_t;

#endif


79 changes: 68 additions & 11 deletions src/arduino-rfm/lorawan-arduino-rfm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
#include "lorawan-arduino-rfm.h"
#include "Conversions.h"

// define lora objet
LoRaWANClass lora;

LoRaWANClass::LoRaWANClass()
{
}
Expand Down Expand Up @@ -292,6 +295,8 @@ void LoRaWANClass::setDeviceClass(devclass_t dev_class)

void LoRaWANClass::sendUplink(char *data, unsigned int len, unsigned char confirm, unsigned char mport)
{
lora.setDeviceClass(CLASS_A); // start as class a device

if (currentChannel == MULTI)
{
randomChannel();
Expand All @@ -304,10 +309,29 @@ void LoRaWANClass::sendUplink(char *data, unsigned int len, unsigned char confir
LoRa_Settings.Mport = mport;
//Set new command for RFM
RFM_Command_Status = NEW_RFM_COMMAND;
upMsg_Type = MSG_UP;
Buffer_Tx.Counter = len;
memcpy(Buffer_Tx.Data, data, len);
}

void LoRaWANClass::sendACK()
{
char Str[10];
Serial.println("sendACK triggered!!");
lora.setDeviceClass(CLASS_A); // start as class a device

if (currentChannel == MULTI)
{
randomChannel();
}
//Set new command for RFM
RFM_Command_Status = NEW_RFM_COMMAND;
upMsg_Type = MSG_ACK;
sprintf(Str, "");
memcpy(Buffer_Tx.Data, Str, sizeof(Str));

}

void LoRaWANClass::setDataRate(unsigned char data_rate)
{
drate_common = data_rate;
Expand Down Expand Up @@ -408,51 +432,85 @@ bool LoRaWANClass::readAck(void)
return false;
}

void LoRaWANClass::switchToClassC(sSettings *LoRa_Settings)
{
lora.setDeviceClass(CLASS_C);
LoRa_Settings->Channel_Rx = CHRX2; // set Rx2 channel 868.500 MHZ
LoRa_Settings->Datarate_Rx = SF12BW125; //set RX2 datarate 12
RFM_Continuous_Receive(LoRa_Settings);
}

void LoRaWANClass::onMessage(void(*callback)(sBuffer *Data_Rx, bool isConfirmed, uint8_t fPort))
{
messageCallback = callback;
}

void LoRaWANClass::update(void)
{
//Type A mote transmit receive cycle
if ((RFM_Command_Status == NEW_RFM_COMMAND || RFM_Command_Status == JOIN) && LoRa_Settings.Mote_Class == CLASS_A)
{
//LoRaWAN TX/RX cycle
LORA_Cycle(&Buffer_Tx, &Buffer_Rx, &RFM_Command_Status, &Session_Data, &OTAA_Data, &Message_Rx, &LoRa_Settings);

if ((Message_Rx.Frame_Control & 0x20) > 0)
LORA_Cycle(&Buffer_Tx, &Buffer_Rx, &RFM_Command_Status, &Session_Data, &OTAA_Data, &Message_Rx, &LoRa_Settings, &upMsg_Type);
if ((Message_Rx.Frame_Control & 0x20) > 0){ // ack get only in RX1 window
Ack_Status = NEW_ACK;
Message_Rx.Frame_Control = 0; // clear ack bit after reading
}

if (Buffer_Rx.Counter != 0x00)
{
Rx_Status = NEW_RX;
bool isConfirmed = ((Message_Rx.MAC_Header & 0xE0)>>5) == 5 ? true : false ; // MType
uint8_t fPort = Message_Rx.Frame_Port;
if(lora.messageCallback) lora.messageCallback(&Buffer_Rx, isConfirmed, fPort);
Buffer_Rx.Counter = 0x00; // clear counter for the next cycle
Serial.println("Data received over RX1");

}

RFM_Command_Status = NO_RFM_COMMAND;

}

//Type C mote transmit and receive handling
if (LoRa_Settings.Mote_Class == CLASS_C)
{
//Transmit
//Transmit -> this will be never used in Class C since device start as class A all the time.
// in Class C mode we will only listen upcoming messages
if (RFM_Command_Status == NEW_RFM_COMMAND)
{
//LoRaWAN TX/RX cycle
LORA_Cycle(&Buffer_Tx, &Buffer_Rx, &RFM_Command_Status, &Session_Data, &OTAA_Data, &Message_Rx, &LoRa_Settings);
LORA_Cycle(&Buffer_Tx, &Buffer_Rx, &RFM_Command_Status, &Session_Data, &OTAA_Data, &Message_Rx, &LoRa_Settings,&upMsg_Type);
if (Buffer_Rx.Counter != 0x00)
{
Rx_Status = NEW_RX;
}
RFM_Command_Status = NO_RFM_COMMAND;
}

//Receive
if (digitalRead(RFM_pins.DIO0) == HIGH)
//Receive in Class C mode
if (digitalRead(RFM_pins.DIO0) == HIGH )
{
LORA_Receive_Data(&Buffer_Rx, &Session_Data, &OTAA_Data, &Message_Rx, &LoRa_Settings);
if (Buffer_Rx.Counter != 0x00)
{
Rx_Status = NEW_RX;
// MType 3:unconfirmed dwn / 5:confirmed dwn
bool isConfirmed = ((Message_Rx.MAC_Header & 0xE0)>>5) == 5 ? true : false ;
uint8_t fPort = Message_Rx.Frame_Port;
if(lora.messageCallback) lora.messageCallback(&Buffer_Rx, isConfirmed, fPort);
Buffer_Rx.Counter = 0x00; // clear counter for the next cycle
Serial.println("Data received over RX2");

}
}

RFM_Command_Status = NO_RFM_COMMAND;
}

#ifdef _CLASS_C_
lora.switchToClassC(&LoRa_Settings);
#endif

}

void LoRaWANClass::randomChannel()
Expand Down Expand Up @@ -485,5 +543,4 @@ void LoRaWANClass::setFrameCounter(unsigned int FrameCounter)
Frame_Counter_Tx = FrameCounter;
}

// define lora objet
LoRaWANClass lora;

Loading

0 comments on commit 39db783

Please sign in to comment.