AllWize Library
AllWize_LoRaWAN.h
Go to the documentation of this file.
1 /*
2 
3 AllWize LoRaWAN Library
4 
5 This code is based on Adafruit's TinyLora Library and thus
6 
7 Copyright (C) 2015, 2016 Ideetron B.V.
8 Modified by Brent Rubell for Adafruit Industries.
9 Copyright (C) 2018-2021 by AllWize <github@allwize.io>
10 
11 This program is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
15 
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU Lesser General Public License for more details.
20 
21 You should have received a copy of the GNU Lesser General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 
24 */
25 
31 #pragma once
32 
33 #include <Arduino.h>
34 #include "AllWize.h"
35 
36 // Setting ALLWIZE_LORAWAN_REDUCE_SIZE to 1 reduced the payload by 9 bytes
37 // by merging the LoRaWAN MAC header and payload and WIZE headers
38 // The message is then sent using special C-Field 0x40
39 #ifndef ALLWIZE_LORAWAN_REDUCE_SIZE
40 #define ALLWIZE_LORAWAN_REDUCE_SIZE 1
41 #endif
42 
43 // Using invalid C-Field in Wize to encode the LoRaWAN MAC header
44 // c_field = 0x20 | (mac_header >> 4)
45 #define LORAWAN_C_FIELD_MASK 0x20
46 
47 // Unconfirmed data up
48 // [7..5] MType (010 unconfirmed up, 100 confirmed up,...)
49 // [4..2] RFU
50 // [1..0] Major
51 #define LORAWAN_MAC_HEADER 0x40
52 
53 // Message direction
54 // 0: uplink
55 // 1: downlink
56 #define LORAWAN_DIRECTION 0x00
57 
58 // Frame control
59 // [7] ADR
60 // [6] ADRACKReq
61 // [5] ACK
62 // [4] ClassB
63 // [3..0] FOptsLen
64 #define LORAWAN_FRAME_CONTROL 0x00
65 
66 class AllWize_LoRaWAN: public AllWize {
67 
68  public:
69 
70  AllWize_LoRaWAN(HardwareSerial * serial, uint8_t reset_gpio = GPIO_NONE, uint8_t config_gpio = GPIO_NONE): AllWize(serial, reset_gpio, config_gpio) {}
71  #if not defined(ARDUINO_ARCH_SAMD) && not defined(ARDUINO_ARCH_ESP32)
72  AllWize_LoRaWAN(SoftwareSerial * serial, uint8_t reset_gpio = GPIO_NONE, uint8_t config_gpio = GPIO_NONE): AllWize(serial, reset_gpio, config_gpio) {}
73  #endif
74  AllWize_LoRaWAN(uint8_t rx, uint8_t tx, uint8_t reset_gpio = GPIO_NONE, uint8_t config_gpio = GPIO_NONE): AllWize(rx, tx, reset_gpio, config_gpio) {}
75 
77  bool joinABP(uint8_t *DevAddr, uint8_t *AppSKey, uint8_t * NwkSKey);
78  bool send(uint8_t *Data, uint8_t Data_Length, uint8_t Frame_Port = 0x01);
79  uint16_t getFrameCounter();
80  void setFrameCounter(uint16_t value);
81 
82  protected:
83 
84  uint8_t _devaddr[4];
85  uint8_t _appskey[16];
86  uint8_t _nwkskey[16];
87  static const uint8_t S_Table[16][16];
88 
89  void Encrypt_Payload(uint8_t *Data, uint8_t Data_Length, uint16_t Frame_Counter, uint8_t Direction);
90  void Calculate_MIC(uint8_t *Data, uint8_t *Final_MIC, uint8_t Data_Length, uint16_t Frame_Counter, uint8_t Direction);
91  void Generate_Keys(uint8_t *K1, uint8_t *K2);
92  void Shift_Left(uint8_t *Data);
93  void XOR(uint8_t *New_Data, uint8_t *Old_Data);
94 
95  void AES_Encrypt(uint8_t *Data, const uint8_t *Key);
96  void AES_Add_Round_Key(uint8_t *Round_Key, uint8_t(*State)[4]);
97  uint8_t AES_Sub_Byte(uint8_t Byte);
98  void AES_Shift_Rows(uint8_t(*State)[4]);
99  void AES_Mix_Collums(uint8_t(*State)[4]);
100  void AES_Calculate_Round_Key(uint8_t Round, uint8_t *Round_Key);
101 
102 };
AllWize_LoRaWAN::_nwkskey
uint8_t _nwkskey[16]
Definition: AllWize_LoRaWAN.h:86
AllWize_LoRaWAN::AES_Sub_Byte
uint8_t AES_Sub_Byte(uint8_t Byte)
Function performs AES SubBytes step.
Definition: AllWize_LoRaWAN.cpp:624
AllWize_LoRaWAN::getFrameCounter
uint16_t getFrameCounter()
AllWize_LoRaWAN::AES_Encrypt
void AES_Encrypt(uint8_t *Data, const uint8_t *Key)
Function used to perform AES encryption.
Definition: AllWize_LoRaWAN.cpp:532
AllWize_LoRaWAN::_devaddr
uint8_t _devaddr[4]
Definition: AllWize_LoRaWAN.h:84
AllWize_LoRaWAN::AES_Calculate_Round_Key
void AES_Calculate_Round_Key(uint8_t Round, uint8_t *Round_Key)
Function performs AES Round Key Calculation.
Definition: AllWize_LoRaWAN.cpp:704
AllWize_LoRaWAN
Definition: AllWize_LoRaWAN.h:66
allwize_message_t
Definition: AllWize.h:54
AllWize_LoRaWAN::S_Table
static const uint8_t S_Table[16][16]
Definition: AllWize_LoRaWAN.h:87
AllWize_LoRaWAN::AllWize_LoRaWAN
AllWize_LoRaWAN(HardwareSerial *serial, uint8_t reset_gpio=GPIO_NONE, uint8_t config_gpio=GPIO_NONE)
Definition: AllWize_LoRaWAN.h:70
AllWize_LoRaWAN::Generate_Keys
void Generate_Keys(uint8_t *K1, uint8_t *K2)
Function used to generate keys for the MIC calculation.
Definition: AllWize_LoRaWAN.cpp:407
AllWize_LoRaWAN::Calculate_MIC
void Calculate_MIC(uint8_t *Data, uint8_t *Final_MIC, uint8_t Data_Length, uint16_t Frame_Counter, uint8_t Direction)
Function used to calculate the validity of data messages.
Definition: AllWize_LoRaWAN.cpp:250
AllWize_LoRaWAN::AllWize_LoRaWAN
AllWize_LoRaWAN(uint8_t rx, uint8_t tx, uint8_t reset_gpio=GPIO_NONE, uint8_t config_gpio=GPIO_NONE)
Definition: AllWize_LoRaWAN.h:74
AllWize_LoRaWAN::setFrameCounter
void setFrameCounter(uint16_t value)
AllWize_LoRaWAN::Shift_Left
void Shift_Left(uint8_t *Data)
Round-shifts data to the left.
Definition: AllWize_LoRaWAN.cpp:458
AllWize_LoRaWAN::AES_Add_Round_Key
void AES_Add_Round_Key(uint8_t *Round_Key, uint8_t(*State)[4])
Function performs AES AddRoundKey step.
Definition: AllWize_LoRaWAN.cpp:606
AllWize_LoRaWAN::AES_Shift_Rows
void AES_Shift_Rows(uint8_t(*State)[4])
Function performs AES ShiftRows step.
Definition: AllWize_LoRaWAN.cpp:643
GPIO_NONE
#define GPIO_NONE
Definition: AllWize.h:44
AllWize_LoRaWAN::read
allwize_message_t read()
Returns latest received message (rebuilds LoRaWan header if necessary)
Definition: AllWize_LoRaWAN.cpp:64
AllWize_LoRaWAN::send
bool send(uint8_t *Data, uint8_t Data_Length, uint8_t Frame_Port=0x01)
Function to assemble and send a LoRaWAN package.
Definition: AllWize_LoRaWAN.cpp:97
AllWize_LoRaWAN::Encrypt_Payload
void Encrypt_Payload(uint8_t *Data, uint8_t Data_Length, uint16_t Frame_Counter, uint8_t Direction)
Function used to encrypt and decrypt the data in a LoRaWAN data packet.
Definition: AllWize_LoRaWAN.cpp:179
AllWize_LoRaWAN::joinABP
bool joinABP(uint8_t *DevAddr, uint8_t *AppSKey, uint8_t *NwkSKey)
Stores the application and network keys for ABP activation.
Definition: AllWize_LoRaWAN.cpp:40
AllWize
Definition: AllWize.h:91
AllWize.h
AllWize_LoRaWAN::XOR
void XOR(uint8_t *New_Data, uint8_t *Old_Data)
Function to XOR two character arrays.
Definition: AllWize_LoRaWAN.cpp:491
AllWize_LoRaWAN::AES_Mix_Collums
void AES_Mix_Collums(uint8_t(*State)[4])
Function performs AES MixColumns step.
Definition: AllWize_LoRaWAN.cpp:675
AllWize_LoRaWAN::_appskey
uint8_t _appskey[16]
Definition: AllWize_LoRaWAN.h:85