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-2020 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 };
void AES_Shift_Rows(uint8_t(*State)[4])
Function performs AES ShiftRows step.
allwize_message_t read()
Returns latest received message (rebuilds LoRaWan header if necessary)
void Generate_Keys(uint8_t *K1, uint8_t *K2)
Function used to generate keys for the MIC calculation.
void XOR(uint8_t *New_Data, uint8_t *Old_Data)
Function to XOR two character arrays.
void Shift_Left(uint8_t *Data)
Round-shifts data to the left.
uint8_t _nwkskey[16]
uint8_t _appskey[16]
void AES_Encrypt(uint8_t *Data, const uint8_t *Key)
Function used to perform AES encryption.
bool send(uint8_t *Data, uint8_t Data_Length, uint8_t Frame_Port=0x01)
Function to assemble and send a LoRaWAN package.
uint8_t _devaddr[4]
bool joinABP(uint8_t *DevAddr, uint8_t *AppSKey, uint8_t *NwkSKey)
Stores the application and network keys for ABP activation.
#define GPIO_NONE
Definition: AllWize.h:44
void AES_Mix_Collums(uint8_t(*State)[4])
Function performs AES MixColumns step.
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.
static const uint8_t S_Table[16][16]
AllWize(HardwareSerial *serial, uint8_t reset_gpio=GPIO_NONE, uint8_t config_gpio=GPIO_NONE)
AllWize object constructor.
Definition: AllWize.cpp:40
uint8_t AES_Sub_Byte(uint8_t Byte)
Function performs AES SubBytes step.
void AES_Add_Round_Key(uint8_t *Round_Key, uint8_t(*State)[4])
Function performs AES AddRoundKey step.
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.
AllWize_LoRaWAN(uint8_t rx, uint8_t tx, uint8_t reset_gpio=GPIO_NONE, uint8_t config_gpio=GPIO_NONE)
uint16_t getFrameCounter()
AllWize_LoRaWAN(HardwareSerial *serial, uint8_t reset_gpio=GPIO_NONE, uint8_t config_gpio=GPIO_NONE)
void AES_Calculate_Round_Key(uint8_t Round, uint8_t *Round_Key)
Function performs AES Round Key Calculation.
void setFrameCounter(uint16_t value)