Version 5.3.2; This version enabled _LOCALSERVER functionality: So when this parameter is set and the NwkSKey and AppSKey are set for a sensor in sensor.h the gateway will decode messages of nodes.

pull/42/head
platenspeler 2018-07-09 21:50:17 +02:00
rodzic 4fb6a406c8
commit 3ccb50554a
20 zmienionych plików z 623 dodań i 158 usunięć

Wyświetl plik

@ -1,6 +1,6 @@
# Single Channel LoRaWAN Gateway
Version 5.3.1, June 30, 2018
Version 5.3.2, July 07, 2018
Author: M. Westenberg (mw12554@hotmail.com)
Copyright: M. Westenberg (mw12554@hotmail.com)
@ -16,6 +16,16 @@ Maintained by Maarten Westenberg (mw12554@hotmail.com)
# Release Notes
New features in version 5.3.2 (July 07, 2018)
- Support for local decoding of sensor messages received by the gateway.
Use #define _LOCALSERVER 1, to enable this functionality. Also specify for each node that you want
to inspect the messages from the NwkSKey and AppSKey in the sensor.h file.
NOTE: the heap of the ESP32 is much larger than of the ESP8266. SO please be careful not to add too many
features to the "old" gateway modules
- As a result reworked the sensor functions and changes such as adding/changing DevAddrm NwkSKEY
and AppSKey parameters to several functions
- Several in-line documentaton enhancements and typos were fixed
New features in version 5.3.1 (June 30, 2018)
- Included support for T-Beam board including on board GPS sensor (_sensor.ino). #define GATEWAYNODE 1 will
turn the gateway into a node as well. Remember to set the address etc in ESP-sc-gway.h.

Wyświetl plik

@ -1,7 +1,7 @@
// 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
// Version 5.3.1 H
// Date: 2018-06-30
// Version 5.3.2 H
// Date: 2018-07-07
//
// Based on work done by Thomas Telkamp for Raspberry PI 1ch gateway and many others.
// Contibutions of Dorijan Morelj and Andreas Spies for OLED support.
@ -11,6 +11,8 @@
// which accompanies this distribution, and is available at
// https://opensource.org/licenses/mit-license.php
//
// NO WARRANTY OF ANY KIND IS PROVIDED
//
// Author: Maarten Westenberg (mw12554@hotmail.com)
//
// This file contains a number of compile-time settings that can be set on (=1) or off (=0)
@ -19,13 +21,13 @@
//
// ----------------------------------------------------------------------------------------
#define VERSION "V.5.3.1.H; 180630a"
#define VERSION "V.5.3.2.H; 1800707a"
// This value of DEBUG determines whether some parts of code get compiled.
// Also this is the initial value of debug parameter.
// The value can be changed using the admin webserver
// For operational use, set initial DEBUG vaulue 0
#define DEBUG 0
#define DEBUG 1
// Debug message will be put on Serial is this one is set.
// If set to 0, not USB Serial prints are done
@ -76,7 +78,7 @@
// connect with USB.
#define A_OTA 1
// We support two pin-out configurations out-of-the-box: HALLARD and COMPRESULT.
// We support a few pin-out configurations out-of-the-box: HALLARD, COMPRESULT and TTGO ESP32.
// If you use one of these two, just set the parameter to the right value.
// If your pin definitions are different, update the loraModem.h file to reflect these settings.
// 1: HALLARD
@ -185,6 +187,10 @@
//#define _THINGPORT <port> // e.g. 1700
//#define _THINGSERVER "<dns.server.com>" // Server URL of the LoRa-udp.js handler
// This defines whether or not we would use the gateway as
// as sort of backend system which decodes messages (see sensor.h file)
#define _LOCALSERVER 0 // See server definitions for decodes
// Gateway Ident definitions
#define _DESCRIPTION "ESP Gateway" // Name of the gateway
#define _EMAIL "mw12554@hotmail.com" // Owner
@ -233,28 +239,8 @@
// 2: Same as 1, but is nodes NOT in the nodes list below they are NOT
// forwarded or counted! (not yet fully implemented)
#define TRUSTED_NODES 1
#if TRUSTED_NODES >= 1
struct nodex {
uint32_t id;
char nm[32];
};
#define TRUSTED_DECODE 1
// Add all your named and trusted nodes to this list
nodex nodes[] = {
{ 0x260116BD , "lora-34 PIR node" }, // F=0
{ 0x26011152 , "lora-35 temp+humi node" }, // F=0
{ 0x2601148C , "lora-36 test node" }, // F=0
{ 0x26011B90 , "lora-39 temp DS18B20" }, // F=1
{ 0x260119A6 , "lora-40 airquality" }, // F=0
{ 0x2601117D , "lora-41 temp+humi SR04T" },
{ 0x26011514 , "lora-43 ch1, no sensors" }, // F=1
{ 0x26011D77 , "lora-45 not sensor" },
{ 0x2601160F , "lora-46 HTU21 metal case" }, // F=0
{ 0x26011E52 , "lora-53 gas sensor" }, // F=ALL
{ 0x02020441 , "lora-65 Waterproof temp humi" },// F=0
{ 0x26011999 , "lora-901 distance sensor" } // F=0
};
#endif
// Wifi definitions
// WPA is an array with SSID and password records. Set WPA size to number of entries in array

Wyświetl plik

@ -1,7 +1,7 @@
// 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
// Version 5.3.1
// Date: 2018-06-30
// Version 5.3.2
// Date: 2018-07-07
// Author: Maarten Westenberg (mw12554@hotmail.com)
//
// Based on work done by Thomas Telkamp for Raspberry PI 1-ch gateway and many others.
@ -11,6 +11,8 @@
// which accompanies this distribution, and is available at
// https://opensource.org/licenses/mit-license.php
//
// NO WARRANTY OF ANY KIND IS PROVIDED
//
// The protocols and specifications used for this 1ch gateway:
// 1. LoRA Specification version V1.0 and V1.1 for Gateway-Node communication
//
@ -53,6 +55,7 @@
// Local include files
#include "loraModem.h"
#include "loraFiles.h"
#include "sensor.h"
#include "oLED.h"
extern "C" {

Wyświetl plik

@ -1,7 +1,7 @@
// 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
// Version 5.3.1
// Date: 2018-06-30
// Version 5.3.2
// Date: 2018-07-07
//
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
// and many others.
@ -11,6 +11,8 @@
// which accompanies this distribution, and is available at
// https://opensource.org/licenses/mit-license.php
//
// NO WARRANTY OF ANY KIND IS PROVIDED
//
// Author: Maarten Westenberg (mw12554@hotmail.com)
//
// This file contains the LoRa filesystem specific code

Wyświetl plik

@ -1,7 +1,7 @@
// 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg
// Version 5.3.1
// Date: 2018-06-30
// Version 5.3.2
// Date: 2018-07-07
//
// Based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
// and many others.
@ -11,6 +11,8 @@
// which accompanies this distribution, and is available at
// https://opensource.org/licenses/mit-license.php
//
// NO WARRANTY OF ANY KIND IS PROVIDED
//
// Author: Maarten Westenberg
//
// This file contains the functions to do management over UDP

Wyświetl plik

@ -1,7 +1,7 @@
// 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
// Version 5.3.1
// Date: 2018-06-30
// Version 5.3.2
// Date: 2018-07-07
//
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
// and many others.
@ -11,6 +11,8 @@
// which accompanies this distribution, and is available at
// https://opensource.org/licenses/mit-license.php
//
// NO WARRANTY OF ANY KIND IS PROVIDED
//
// Author: Maarten Westenberg (mw12554@hotmail.com)
//
// This file contains the LoRa filesystem specific code
@ -34,6 +36,21 @@ void id_print (String id, String val) {
#endif
}
// ----------------------------------------------------------------------------
// INITCONFIG; Init the gateway configuration file
// Espcecially when calling SPIFFS.format() the gateway is left in an init
// which is not very well defined. This function will init some of the settings
// to well known settings.
// ----------------------------------------------------------------------------
int initConfig(struct espGwayConfig *c) {
(*c).ch = 0;
(*c).sf = SF8;
(*c).debug = 1;
(*c).pdebug = P_GUI;
(*c).cad = _CAD;
(*c).hop = false;
}
// ----------------------------------------------------------------------------
// Read the gateway configuration file
@ -52,6 +69,7 @@ int readConfig(const char *fn, struct espGwayConfig *c) {
Serial.print(F(" does not exist .. Formatting"));
#endif
SPIFFS.format();
initConfig(c);
return(-1);
}
@ -78,6 +96,7 @@ int readConfig(const char *fn, struct espGwayConfig *c) {
Serial.println(F("Formatting"));
#endif
SPIFFS.format();
initConfig(c);
f = SPIFFS.open(fn, "r");
tries = 0;
}
@ -209,15 +228,20 @@ int writeGwayCfg(const char *fn) {
}
// ----------------------------------------------------------------------------
// Write the configuration ad found in the espGwayConfig structure
// Write the configuration as found in the espGwayConfig structure
// to SPIFFS
// Parameters:
// fn; Filename
// c; struct config
// Returns:
// 1 when successful, -1 on error
// ----------------------------------------------------------------------------
int writeConfig(const char *fn, struct espGwayConfig *c) {
if (!SPIFFS.exists(fn)) {
Serial.print("WARNING:: writeConfig, file not exists, formatting ");
SPIFFS.format();
// XXX make all initial declarations here if config vars need to have a value
initConfig(c); // XXX make all initial declarations here if config vars need to have a value
Serial.println(fn);
}
File f = SPIFFS.open(fn, "w");
@ -256,12 +280,17 @@ int writeConfig(const char *fn, struct espGwayConfig *c) {
}
// ----------------------------------------------------------------------------
// Add a line with statitics to the log.
// Add a line with statistics to the log.
//
// We put the check in the function to protect against calling
// the function without STAT_LOG being proper defined
// ToDo: Store the fileNo and the fileRec in the status file to save for
// restarts
// Parameters:
// line; char array with characters to write to log
// cnt;
// Returns:
// <none>
// ----------------------------------------------------------------------------
void addLog(const unsigned char * line, int cnt)
{
@ -312,8 +341,10 @@ void addLog(const unsigned char * line, int cnt)
Serial.println(fn);
}
#endif
return; // If file open failed, return
}
int i;
#if DUSB>=1
if (( debug>=1 ) && ( pdebug & P_GUI )) {
Serial.print(F("addLog:: fileno="));
@ -322,8 +353,8 @@ void addLog(const unsigned char * line, int cnt)
Serial.print(gwayConfig.logFileRec);
Serial.print(F(": "));
int i;
for (i=0; i< 12; i++) { // The first 12 bytes contain non printble characters
for (i=0; i< 12; i++) { // The first 12 bytes contain non printable characters
Serial.print(line[i],HEX);
Serial.print(' ');
}
@ -333,12 +364,12 @@ void addLog(const unsigned char * line, int cnt)
}
#endif //DUSB
int i;
for (i=0; i< 12; i++) { // The first 12 bytes contain non printble characters
for (i=0; i< 12; i++) { // The first 12 bytes contain non printable characters
// f.print(line[i],HEX);
f.print('*');
}
f.write(&line[i], cnt-12); // write/append the line to the file
f.write(&(line[i]), cnt-12); // write/append the line to the file
f.print('\n');
f.close(); // Close the file after appending to it

Wyświetl plik

@ -1,7 +1,7 @@
// 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
// Version 5.3.1
// Date: 2018-06-30
// Version 5.3.2
// Date: 2018-07-07
//
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
// and many others.
@ -11,6 +11,8 @@
// which accompanies this distribution, and is available at
// https://opensource.org/licenses/mit-license.php
//
// NO WARRANTY OF ANY KIND IS PROVIDED
//
// Author: Maarten Westenberg (mw12554@hotmail.com)
//
// This file contains the LoRa modem specific code enabling to receive
@ -371,6 +373,15 @@ void hop() {
// UP function
// This is the "lowlevel" receive function called by stateMachine()
// dealing with the radio specific LoRa functions
//
// Parameters:
// Payload: uint8_t[] message. when message is read it is returned in payload.
// Returns:
// Length of payload received
//
// 9 bytes header
// followed by data N bytes
// 4 bytes MIC end
// ----------------------------------------------------------------------------
uint8_t receivePkt(uint8_t *payload)
{
@ -390,15 +401,11 @@ uint8_t receivePkt(uint8_t *payload)
{
#if DUSB>=1
if (( debug>=0) && ( pdebug & P_RADIO )) {
Serial.print(F("RxPkt:: Err CRC, ="));
Serial.print(F("rxPkt:: Err CRC, ="));
SerialTime();
Serial.println();
}
#endif
// Reset CRC flag 0x20
//writeRegister(REG_IRQ_FLAGS, (uint8_t)(IRQ_LORA_CRCERR_MASK | IRQ_LORA_RXDONE_MASK)); // 0x12; clear CRC (== 0x20) flag
//writeRegister(REG_IRQ_FLAGS_MASK, (uint8_t) 0x00);
//writeRegister(REG_IRQ_FLAGS, (uint8_t) 0xFF); // XXX 180324 done in state machine
return 0;
}
@ -409,7 +416,7 @@ uint8_t receivePkt(uint8_t *payload)
{
#if DUSB>=1
if (( debug>=0) && ( pdebug & P_RADIO )) {
Serial.println(F("RxPkt:: Err HEADER"));
Serial.println(F("rxPkt:: Err HEADER"));
}
#endif
// Reset VALID-HEADER flag 0x10
@ -423,7 +430,7 @@ uint8_t receivePkt(uint8_t *payload)
cp_nb_rx_ok++; // Receive OK statistics counter
if (readRegister(REG_FIFO_RX_CURRENT_ADDR) != readRegister(REG_FIFO_RX_BASE_AD)) {
if (debug>=1) {
if (( debug>=0 ) && ( pdebug & P_RADIO )) {
Serial.print(F("RX BASE <"));
Serial.print(readRegister(REG_FIFO_RX_BASE_AD));
Serial.print(F("> != RX CURRENT <"));
@ -460,6 +467,9 @@ uint8_t receivePkt(uint8_t *payload)
}
writeRegister(REG_IRQ_FLAGS, (uint8_t) 0xFF); // Reset ALL interrupts
// A long as DUSB is enabled, and RX debug messages are selected,
//the received packet is displayed on the output.
#if DUSB>=1
if (( debug>=0 ) && ( pdebug & P_RX )){
@ -482,23 +492,89 @@ uint8_t receivePkt(uint8_t *payload)
Serial.print(F(", len="));
Serial.print(receivedCount);
// If debug level 1 is specified, we display the content of the message as well
// We need to decode the message as well will it make any sense
if (debug>=1) { // Must be 1 for operational use
#if _TRUSTED_DECODE==2
int index; // The index of the codex struct to decode
String response="";
uint8_t data[receivedCount];
uint8_t DevAddr [4];
DevAddr[0] = payload[4];
DevAddr[1] = payload[3];
DevAddr[2] = payload[2];
DevAddr[3] = payload[1];
if ((index = inDecodes((char *)(payload+1))) >=0 ) {
Serial.print(F(", Ind="));
Serial.print(index);
//Serial.println();
}
else if (debug>=1) {
Serial.print(F(", No Index"));
Serial.println();
return(receivedCount);
}
// ------------------------------
Serial.print(F(", data="));
for (int i=0; i<receivedCount; i++) { data[i] = payload[i]; } // Copy array
//for (int i=0; i<receivedCount; i++) {
// if (payload[i]<=0xF) Serial.print('0');
// Serial.print(payload[i], HEX);
// Serial.print(' ');
//}
uint16_t frameCount=payload[7]*256 + payload[6];
// The message received has a length, but data starts at byte 9, and stops 4 bytes
// before the end since those are MIC bytes
uint8_t CodeLength = encodePacket((uint8_t *)(data + 9), receivedCount-9-4, (uint16_t)frameCount, DevAddr, decodes[index].appKey, 0);
Serial.print(F("- NEW fc="));
Serial.print(frameCount);
Serial.print(F(", addr="));
for (int i=0; i<4; i++) {
if (DevAddr[i]<=0xF) Serial.print('0');
Serial.print(DevAddr[i], HEX);
Serial.print(' ');
}
Serial.print(F(", len="));
Serial.print(CodeLength);
Serial.print(F(", data="));
for (int i=0; i<receivedCount; i++) {
if (data[i]<=0xF) Serial.print('0');
Serial.print(data[i], HEX);
Serial.print(' ');
}
#endif // _TRUSTED_DECODE
}
Serial.println();
if (debug>=2) Serial.flush();
}
#endif
#endif //DUSB
return(receivedCount);
}
writeRegister(REG_IRQ_FLAGS, (uint8_t) (
IRQ_LORA_RXDONE_MASK |
IRQ_LORA_RXTOUT_MASK |
IRQ_LORA_HEADER_MASK |
IRQ_LORA_CRCERR_MASK)); // 0x12; Clear RxDone IRQ_LORA_RXDONE_MASK
return 0;
}
} //receivePkt

Wyświetl plik

@ -1,7 +1,7 @@
// 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
// Version 5.3.1
// Date: 2018-06-30
// Version 5.3.2
// Date: 2018-07-07
//
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
// and many others.
@ -11,6 +11,8 @@
// which accompanies this distribution, and is available at
// https://opensource.org/licenses/mit-license.php
//
// NO WARRANTY OF ANY KIND IS PROVIDED
//
// Author: Maarten Westenberg (mw12554@hotmail.com)
//
// This file contains the state machine code enabling to receive

Wyświetl plik

@ -1,7 +1,7 @@
// 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
// Version 5.3.1
// Date: 2018-06-30
// Version 5.3.2
// Date: 2018-07-07
//
//
// All rights reserved. This program and the accompanying materials
@ -9,6 +9,8 @@
// which accompanies this distribution, and is available at
// https://opensource.org/licenses/mit-license.php
//
// NO WARRANTY OF ANY KIND IS PROVIDED
//
// Author: Maarten Westenberg (mw12554@hotmail.com)
//
// This file contains the ota code for the ESP Single Channel Gateway.

Wyświetl plik

@ -1,7 +1,7 @@
// 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg
// Verison 5.3.1
// Date: 2018-06-30
// Verison 5.3.2
// Date: 2018-07-07
//
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the MIT License

Wyświetl plik

@ -1,7 +1,7 @@
// 1-channel LoRa Gateway for ESP8266
// sensor.ino; 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg
// Verison 5.3.1
// Date: 2018-06-30
// Verison 5.3.2
// Date: 2018-07-07
//
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the MIT License
@ -21,13 +21,23 @@
// - The battery sensor works by connecting the VCC pin to A0 analog port
// ============================================================================
#if GATEWAYNODE==1
//#include "sensor.h" // Contains definitions for the sensor and TRUSTED info, ilcuded in ESP-sc-gway.ino
#include "LoRaCode.h"
#if _GPS==1
unsigned char DevAddr[4] = _DEVADDR ; // see ESP-sc-gway.h
// Only used by GPS sensor code
//
#if _GPS==1
// ----------------------------------------------------------------------------
// Smartdelay is a function to delay processing but in the loop get info
// from the GPS device
// ----------------------------------------------------------------------------
static void smartDelay(unsigned long ms)
{
unsigned long start = millis();
@ -37,10 +47,10 @@ static void smartDelay(unsigned long ms)
gps.encode(Serial1.read());
} while (millis() - start < ms);
}
#endif
#endif //_GPS
unsigned char DevAddr[4] = _DEVADDR ; // see ESP-sc-gway.h
// ----------------------------------------------------------------------------
@ -68,33 +78,50 @@ static int LoRaSensors(uint8_t *buf) {
uint8_t tchars = 1;
buf[0] = 0x86; // 134; User code <lCode + len==3 + Parity
#if DUSB>=1
if (debug>=0)
Serial.print(F("LoRaSensors:: "));
#endif
#if _BATTERY==1
#if DUSB>=1
if (debug>=0)
Serial.println(F("LoRaSensors:: Battery"));
Serial.print(F("Battery "));
#endif
buf[tchars] = 0x80; // 128; lCode code <battery>
buf[tchars+1] = 0x3F; // 63; lCode code <value>/30
tchars+=2;
#if defined(ARDUINO_ARCH_ESP8266) || defined(ESP32)
// For ESP there is no standard battery library
// What we do is to measure GPIO35 pin which has a 100K voltage divider
pinMode(35, INPUT);
#if defined(ESP32)
int devider=4095;
#else
int devider=1023;
#endif //ESP32
float volts=3.3 * analogRead(35) / 4095 * 2; // T_Beam connects to GPIO35
#else
// For ESP8266 no sensor defined
float volts=0;
#endif
tchars += lcode.eBattery(volts, buf + tchars);
#endif
#if _GPS==1
#if DUSB>=1
if (debug>=0)
Serial.println(F("LoRaSensors:: GPS"));
Serial.print(F("GPS "));
if (debug>=1) {
Serial.print("Latitude : ");
if (( debug>=1 ) && ( pdebug & P_MAIN )) {
Serial.print("\tLatitude : ");
Serial.println(gps.location.lat(), 5);
Serial.print("Longitude : ");
Serial.print("\tLongitude : ");
Serial.println(gps.location.lng(), 4);
Serial.print("Satellites: ");
Serial.print("\tSatellites: ");
Serial.println(gps.satellites.value());
Serial.print("Altitude : ");
Serial.print("\tAltitude : ");
Serial.print(gps.altitude.feet() / 3.2808);
Serial.println("M");
Serial.print("Time : ");
Serial.print("\tTime : ");
Serial.print(gps.time.hour());
Serial.print(":");
Serial.print(gps.time.minute());
@ -113,15 +140,19 @@ static int LoRaSensors(uint8_t *buf) {
}
// Assuming we have a value, put it in the buf
// The layout of thi message is specific to the user,
// The layout of this message is specific to the user,
// so adapt as needed.
tchars += lcode.eGpsL(gps.location.lat(), gps.location.lng(), gps.altitude.value(),
gps.satellites.value(), buf + tchars);
#endif
// If all sensor data is encoded, we encode the buffer
#if DUSB>=1
if (debug>=0)
Serial.println();
#endif
// If all sensor data is encoded, we encode the buffer
lcode.eMsg(buf, tchars); // Fill byte 0 with bytecount and Parity
return(tchars); // return the number of bytes added to payload
@ -215,9 +246,19 @@ static void generate_subkey(uint8_t *key, uint8_t *k1, uint8_t *k2) {
//
// cmac = aes128_encrypt(K, Block_A[i])
// ----------------------------------------------------------------------------
uint8_t encodePacket(uint8_t *Data, uint8_t DataLength, uint16_t FrameCount, uint8_t Direction) {
uint8_t encodePacket(uint8_t *Data, uint8_t DataLength, uint16_t FrameCount, uint8_t *DevAddr, uint8_t *AppSKey, uint8_t Direction) {
unsigned char AppSKey[16] = _APPSKEY ; // see ESP-sc-gway.h
#if DUSB>=1
if (debug>=2) {
Serial.print(F("encodePacket:: DevAddr="));
for (int i=0; i<4; i++ ) { Serial.print(DevAddr[i],HEX); Serial.print(' '); }
Serial.print(F("encodePacket:: AppSKey="));
for (int i=0; i<16; i++ ) { Serial.print(AppSKey[i],HEX); Serial.print(' '); }
Serial.println();
}
#endif
//unsigned char AppSKey[16] = _APPSKEY ; // see ESP-sc-gway.h
uint8_t i, j;
uint8_t Block_A[16];
uint8_t bLen=16; // Block length is 16 except for last block in message
@ -288,10 +329,10 @@ uint8_t encodePacket(uint8_t *Data, uint8_t DataLength, uint16_t FrameCount, uin
// MIC is cmac [0:3] of ( aes128_cmac(NwkSKey, B0 | Data )
//
// ----------------------------------------------------------------------------
uint8_t micPacket(uint8_t *data, uint8_t len, uint16_t FrameCount, uint8_t dir) {
uint8_t micPacket(uint8_t *data, uint8_t len, uint16_t FrameCount, uint8_t * NwkSKey, uint8_t dir) {
unsigned char NwkSKey[16] = _NWKSKEY ;
//uint8_t NwkSKey[16] = _NWKSKEY;
uint8_t Block_B[16];
uint8_t X[16];
uint8_t Y[16];
@ -365,7 +406,7 @@ uint8_t micPacket(uint8_t *data, uint8_t len, uint16_t FrameCount, uint8_t dir)
// ------------------------------------
// Step 4: If there is a rest Block, padd it
// Last block. We move step4 to the end as we need Y
// Last block. We move step 4 to the end as we need Y
// to compute the last block
//
if (restBits) {
@ -410,6 +451,7 @@ uint8_t micPacket(uint8_t *data, uint8_t len, uint16_t FrameCount, uint8_t dir)
// ----------------------------------------------------------------------------
static void checkMic(uint8_t *buf, uint8_t len, uint8_t *key) {
uint8_t cBuf[len+1];
uint8_t NwkSKey[16] = _NWKSKEY;
if (debug>=2) {
Serial.print(F("old="));
@ -423,7 +465,7 @@ static void checkMic(uint8_t *buf, uint8_t len, uint8_t *key) {
len -=4;
uint16_t FrameCount = ( cBuf[7] * 256 ) + cBuf[6];
len += micPacket(cBuf, len, FrameCount, 0);
len += micPacket(cBuf, len, FrameCount, NwkSKey, 0);
if (debug>=2) {
Serial.print(F("new="));
@ -433,8 +475,9 @@ static void checkMic(uint8_t *buf, uint8_t len, uint8_t *key) {
}
Serial.println();
}
// Mic is only checked, but len is not corrected
}
#endif
#endif //_CHECK_MIC
// ----------------------------------------------------------------------------
// SENSORPACKET
@ -469,6 +512,9 @@ int sensorPacket() {
uint8_t mlength = 0;
uint32_t tmst = micros();
struct LoraUp LUP;
uint8_t NwkSKey[16] = _NWKSKEY;
uint8_t AppSKey[16] = _APPSKEY;
uint8_t DevAddr[4] = _DEVADDR;
// Init the other LoraUp fields
LUP.sf = 8; // Send with SF8
@ -508,11 +554,34 @@ int sensorPacket() {
// See LoRa spec para 4.3.2
// You can add any byte string below based on you personal choice of sensors etc.
//
// Payload bytes in this example are encoded in the LoRaCode(c) format
uint8_t PayLength = LoRaSensors((uint8_t *)(LUP.payLoad + LUP.payLength));
#if DUSB>=1
if ((debug>=2) && (pdebug & P_RADIO )) {
Serial.print(F("old: "));
for (int i=0; i<PayLength; i++) {
Serial.print(LUP.payLoad[i],HEX);
Serial.print(' ');
}
Serial.println();
}
#endif
// we have to include the AES functions at this stage in order to generate LoRa Payload.
uint8_t CodeLength = encodePacket((uint8_t *)(LUP.payLoad + LUP.payLength), PayLength, (uint16_t)frameCount, 0);
uint8_t CodeLength = encodePacket((uint8_t *)(LUP.payLoad + LUP.payLength), PayLength, (uint16_t)frameCount, DevAddr, AppSKey, 0);
#if DUSB>=1
if ((debug>=2) && (pdebug & P_RADIO )) {
Serial.print(F("new: "));
for (int i=0; i<CodeLength; i++) {
Serial.print(LUP.payLoad[i],HEX);
Serial.print(' ');
}
Serial.println();
}
#endif
LUP.payLength += CodeLength; // length inclusive sensor data
@ -522,7 +591,18 @@ int sensorPacket() {
// Note: Until MIC is done correctly, TTN does not receive these messages
// The last 4 bytes are MIC bytes.
//
LUP.payLength += micPacket((uint8_t *)(LUP.payLoad), LUP.payLength, (uint16_t)frameCount, 0);
LUP.payLength += micPacket((uint8_t *)(LUP.payLoad), LUP.payLength, (uint16_t)frameCount, NwkSKey, 0);
#if DUSB>=1
if ((debug>=2) && (pdebug & P_RADIO )) {
Serial.print(F("mic: "));
for (int i=0; i<LUP.payLength; i++) {
Serial.print(LUP.payLoad[i],HEX);
Serial.print(' ');
}
Serial.println();
}
#endif
// So now our package is ready, and we can send it up through the gateway interface
// Note Be aware that the sensor message (which is bytes) in message will be
@ -531,6 +611,7 @@ int sensorPacket() {
int buff_index = buildPacket(tmst, buff_up, LUP, true);
frameCount++;
cp_nb_rx_rcv++;
// In order to save the memory, we only write the framecounter
// to EEPROM every 10 values. It also means that we will invalidate
@ -542,16 +623,37 @@ int sensorPacket() {
if (debug>0) Serial.println(F("sensorPacket:: ERROR buffer size too large"));
return(-1);
}
#ifdef _TTNSERVER
if (!sendUdp(ttnServer, _TTNPORT, buff_up, buff_index)) {
return(-1);
}
#endif
#ifdef _THINGSERVER
if (!sendUdp(thingServer, _THINGPORT, buff_up, buff_index)) {
return(-1);
}
#endif
#if DUSB>=1
// If all is right, we should after decoding (which is the same as encoding) get
// the original message back again.
if ((debug>=2) && (pdebug & P_RADIO )) {
CodeLength = encodePacket((uint8_t *)(LUP.payLoad + 9), PayLength, (uint16_t)frameCount-1, DevAddr, AppSKey, 0);
Serial.print(F("rev: "));
for (int i=0; i<CodeLength; i++) {
Serial.print(LUP.payLoad[i],HEX);
Serial.print(' ');
}
Serial.print(F(", addr="));
for (int i=0; i<4; i++) {
Serial.print(DevAddr[i],HEX);
Serial.print(' ');
}
Serial.println();
}
#endif
if (_cad) {
// Set the state to CAD scanning after sending a packet
_state = S_SCAN; // Inititialise scanner

Wyświetl plik

@ -1,7 +1,7 @@
// 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
// Version 5.3.1
// Date: 2018-06-30
// Version 5.3.2
// Date: 2018-07-07
//
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
// and many others.
@ -11,6 +11,8 @@
// which accompanies this distribution, and is available at
// https://opensource.org/licenses/mit-license.php
//
// NO WARRANTY OF ANY KIND IS PROVIDED
//
// Author: Maarten Westenberg (mw12554@hotmail.com)
//
// This file contains the state machine code enabling to receive

Wyświetl plik

@ -1,7 +1,7 @@
// 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
// Version 5.3.1
// Date: 2018-06-30
// Version 5.3.2
// Date: 2018-07-07
//
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
// and many others.
@ -11,6 +11,8 @@
// which accompanies this distribution, and is available at
// https://opensource.org/licenses/mit-license.php
//
// NO WARRANTY OF ANY KIND IS PROVIDED
//
// Author: Maarten Westenberg (mw12554@hotmail.com)
//
// This file contains the LoRa modem specific code enabling to receive
@ -213,12 +215,14 @@ int sendPacket(uint8_t *buf, uint8_t length)
// build a gateway message to send upstream (to the user somewhere on the web).
//
// parameters:
// tmst: Timestamp to include in the upstream message
// buff_up: The buffer that is generated for upstream
// message: The payload message to include in the the buff_up
// messageLength: The number of bytes received by the LoRa transceiver
// internal: Boolean value to indicate whether the local sensor is processed
// tmst: Timestamp to include in the upstream message
// buff_up: The buffer that is generated for upstream
// message: The payload message to include in the the buff_up
// messageLength: The number of bytes received by the LoRa transceiver
// internal: Boolean value to indicate whether the local sensor is processed
//
// returns:
// buff_index
// ----------------------------------------------------------------------------
int buildPacket(uint32_t tmst, uint8_t *buff_up, struct LoraUp LoraUp, bool internal)
{
@ -253,8 +257,41 @@ int buildPacket(uint32_t tmst, uint8_t *buff_up, struct LoraUp LoraUp, bool inte
}
#if STATISTICS >= 1
// Receive statistics
// Receive statistics, move old statistics down 1 position
// and fill the new top line with the latest received sensor values.
// This works fine for the sensor, EXCEPT when we decode data for _LOCALSERVER
//
for (int m=( MAX_STAT -1); m>0; m--) statr[m]=statr[m-1];
// From now on we can fill start[0] with sensor data
#if _LOCALSERVER==1
statr[0].datal=0;
int index;
if ((index = inDecodes((char *)(LoraUp.payLoad+1))) >=0 ) {
uint16_t frameCount=LoraUp.payLoad[7]*256 + LoraUp.payLoad[6];
for (int k=0; (k<LoraUp.payLength) && (k<23); k++) {
statr[0].data[k] = LoraUp.payLoad[k+9];
};
// XXX Check that k<23 when leaving the for loop
// XXX or we can not display in statr
uint8_t DevAddr[4];
DevAddr[0]= LoraUp.payLoad[4];
DevAddr[1]= LoraUp.payLoad[3];
DevAddr[2]= LoraUp.payLoad[2];
DevAddr[3]= LoraUp.payLoad[1];
statr[0].datal = encodePacket((uint8_t *)(statr[0].data),
LoraUp.payLength-9-4,
(uint16_t)frameCount,
DevAddr,
decodes[index].appKey,
0);
}
#endif //_LOCALSERVER
statr[0].tmst = now();
statr[0].ch= ifreq;
statr[0].prssi = prssi - rssicorr;
@ -267,17 +304,19 @@ int buildPacket(uint32_t tmst, uint8_t *buff_up, struct LoraUp LoraUp, bool inte
if ((message[4] != 0x26) || (message[1]==0x99)) {
Serial.print(F("addr="));
for (int i=messageLength; i>0; i--) {
if (message[i]<16) Serial.print('0');
if (message[i]<0x10) Serial.print('0');
Serial.print(message[i],HEX);
Serial.print(' ');
}
Serial.println();
}
}
#endif // DUSB
#endif //DUSB
statr[0].node = ( message[1]<<24 | message[2]<<16 | message[3]<<8 | message[4] );
#if STATISTICS >= 2
// Fill in the statistics that we will also need for the GUI.
// So
switch (statr[0].sf) {
case SF7: statc.sf7++; break;
case SF8: statc.sf8++; break;
@ -286,7 +325,7 @@ int buildPacket(uint32_t tmst, uint8_t *buff_up, struct LoraUp LoraUp, bool inte
case SF11: statc.sf11++; break;
case SF12: statc.sf12++; break;
}
#endif // STATISTICS >= 2
#endif //STATISTICS >= 2
#if STATISTICS >= 3
if (statr[0].ch == 0) switch (statr[0].sf) {
@ -315,9 +354,9 @@ int buildPacket(uint32_t tmst, uint8_t *buff_up, struct LoraUp LoraUp, bool inte
case SF11: statc.sf11_2++; break;
case SF12: statc.sf12_2++; break;
}
#endif // STATISTICS >= 3
#endif //STATISTICS >= 3
#endif // STATISTICS >= 2
#endif //STATISTICS >= 2
#if DUSB>=1
if (( debug>=2 ) && ( pdebug & P_RADIO )){
@ -382,8 +421,10 @@ int buildPacket(uint32_t tmst, uint8_t *buff_up, struct LoraUp LoraUp, bool inte
int encodedLen = base64_enc_len(messageLength); // max 341
#if DUSB>=1
if ((debug>=1) && (encodedLen>255)) {
Serial.println(F("buildPacket:: b64 error"));
Serial.print(F("buildPacket:: b64 err, len="));
Serial.println(encodedLen);
if (debug>=2) Serial.flush();
return(-1);
}
#endif // DUSB
base64_encode(b64, (char *) message, messageLength);// max 341
@ -523,7 +564,7 @@ int buildPacket(uint32_t tmst, uint8_t *buff_up, struct LoraUp LoraUp, bool inte
// ----------------------------------------------------------------------------
// UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP UP
// Receive a LoRa package over the air, LoRa
// Receive a LoRa package over the air, LoRa and deliver to server(s)
//
// Receive a LoRa message and fill the buff_up char buffer.
// returns values:
@ -546,7 +587,7 @@ int receivePacket()
// Take the timestamp as soon as possible, to have accurate reception timestamp
// TODO: tmst can jump if micros() overflow.
uint32_t tmst = (uint32_t) micros(); // Only microseconds, rollover in
uint32_t tmst = (uint32_t) micros(); // Only microseconds, rollover in 5X minutes
//lastTmst = tmst; // Following/according to spec
// Handle the physical data read from LoraUp
@ -563,9 +604,6 @@ int receivePacket()
return(-3);
}
#endif
LoraUp.payLength = 0;
LoraUp.payLoad[0] = 0x00;
// This is one of the potential problem areas.
// If possible, USB traffic should be left out of interrupt routines
@ -576,12 +614,76 @@ int receivePacket()
}
yield();
#endif
// Use our own defined server or a second well kon server
#ifdef _THINGSERVER
if (!sendUdp(thingServer, _THINGPORT, buff_up, build_index)) {
return(-2); // received a message
}
#endif
#if _LOCALSERVER==1
// Or special case, we do not use a local server to receive
// and decode the server. We use buildPacket() to call decode
// and use statr[0] information to store decoded message
//DecodePayload: para 4.3.1 of Lora 1.1 Spec
// MHDR
// 1 byte Payload[0]
// FHDR
// 4 byte Dev Addr Payload[1-4]
// 1 byte FCtrl Payload[5]
// 2 bytes FCnt Payload[6-7]
// = Optional 0 to 15 bytes Options
// FPort
// 1 bytes, 0x00 Payload[8]
// ------------
// +=9 BYTES HEADER
//
// FRMPayload
// N bytes (Payload )
//
// 4 bytes MIC trailer
int index=0;
if ((index = inDecodes((char *)(LoraUp.payLoad+1))) >=0 ) {
uint8_t DevAddr[4];
DevAddr[0]= LoraUp.payLoad[4];
DevAddr[1]= LoraUp.payLoad[3];
DevAddr[2]= LoraUp.payLoad[2];
DevAddr[3]= LoraUp.payLoad[1];
uint16_t frameCount=LoraUp.payLoad[7]*256 + LoraUp.payLoad[6];
#if DUSB>=1
Serial.print(F("receivePacket:: Ind="));
Serial.print(index);
Serial.print(F(", Len="));
Serial.print(LoraUp.payLength);
Serial.print(F(", A="));
for (int i=0; i<4; i++) {
if (DevAddr[i]<0x0F) Serial.print('0');
Serial.print(DevAddr[i],HEX);
//Serial.print(' ');
}
Serial.print(F(", Msg="));
for (int i=0; (i<statr[0].datal) && (i<23); i++) {
if (statr[0].data[i]<0x0F) Serial.print('0');
Serial.print(statr[0].data[i],HEX);
Serial.print(' ');
}
Serial.println();
}
else if (debug>=2) {
Serial.println(F("receivePacket:: No Index"));
}
#endif //DUSB
#endif // _LOCALSERVER
// Reset the message area
LoraUp.payLength = 0;
LoraUp.payLoad[0] = 0x00;
return(build_index);
}

Wyświetl plik

@ -1,7 +1,7 @@
// 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
// Version 5.3.1
// Date: 2018-06-31
// Version 5.3.2
// Date: 2018-07-07
//
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
// and many others.
@ -11,6 +11,8 @@
// which accompanies this distribution, and is available at
// https://opensource.org/licenses/mit-license.php
//
// NO WARRANTY OF ANY KIND IS PROVIDED
//
// Author: Maarten Westenberg (mw12554@hotmail.com)
//
// This file contains the utilities for time and other functions
@ -161,12 +163,12 @@ void SerialStat(uint8_t intr)
// ----------------------------------------------------------------------------
// SerialName(id, response)
// Check whether for address a (4 bytes in Unsigned Long) there is a name
// This function only works if TRUSTED_NODES is set
// This function only works if _TRUSTED_NODES is set
// ----------------------------------------------------------------------------
int SerialName(char * a, String& response)
{
#if TRUSTED_NODES>=1
#if _TRUSTED_NODES>=1
uint32_t id = ((a[0]<<24) | (a[1]<<16) | (a[2]<<8) | a[3]);
int i;
@ -191,4 +193,23 @@ int SerialName(char * a, String& response)
return(-1); // If no success OR is TRUSTED NODES not defined
}
// ----------------------------------------------------------------------------
// inDecodes(id)
// Find the id in Decodes array, and return the index of the item
// Parameters:
// id: The first field in the array (normally DevAddr id). Must be char[4]
// Returns:
// The index of the ID in the Array. Returns -1 if not found
// ----------------------------------------------------------------------------
int inDecodes(char * id) {
uint32_t ident = ((id[3]<<24) | (id[2]<<16) | (id[1]<<8) | id[0]);
int i;
for ( i=0; i< (sizeof(decodes)/sizeof(codex)); i++) {
if (ident == decodes[i].id) {
return(i);
}
}
return(-1);
}

Wyświetl plik

@ -1,7 +1,7 @@
// 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
// Version 5.3.1
// Date: 2018-06-30
// Version 5.3.2
// Date: 2018-07-07
//
// based on work done by many people and making use of several libraries.
//
@ -10,6 +10,8 @@
// which accompanies this distribution, and is available at
// https://opensource.org/licenses/mit-license.php
//
// NO WARRANTY OF ANY KIND IS PROVIDED
//
// Author: Maarten Westenberg (mw12554@hotmail.com)
//
// This file contains the webserver code for the ESP Single Channel Gateway.
@ -77,10 +79,14 @@ boolean YesNo(String s)
// ----------------------------------------------------------------------------
// WWWFILES
// WWWFILE
// This function will open a pop-up in the browser and then
// display the contents of a file in that window
// Output is sent to server.sendContent()
// Parameters:
// fn; String with filename
// Returns:
// <none>
// ----------------------------------------------------------------------------
void wwwFile(String fn) {
@ -91,7 +97,7 @@ void wwwFile(String fn) {
#endif
return;
}
#if DUSB>=1
#if DUSB>=2
else {
Serial.print(F("wwwButtons:: File existist= "));
Serial.println(fn);
@ -119,16 +125,17 @@ void wwwFile(String fn) {
// ----------------------------------------------------------------------------
// Button function Stat, display statistics
// This is a button on the top of the GUI screen.
// ----------------------------------------------------------------------------
void buttonStat()
{
Serial.print(F("Log"));
Serial.println();
//Serial.print(F("Log"));
//Serial.println();
printLog();
//printLog();
String response = "";
response+= "alert('Log');";
response+= "<script> confirm('Confirm Log'); </script>";
server.sendContent(response);
}
@ -136,6 +143,7 @@ void buttonStat()
// ----------------------------------------------------------------------------
// Button gunction Log displays logfiles.
// This is a button on the top of the GUI screen
// ----------------------------------------------------------------------------
void buttonLog()
{
@ -177,6 +185,11 @@ static void wwwButtons()
// results are sent back to the web client.
// Commands: DEBUG, ADDRESS, IP, CONFIG, GETTIME, SETTIME
// The webpage is completely built response and then printed on screen.
// Parameters:
// cmd: Contains a character array with the command to execute
// arg: Contains the parameter value of that command
// Returns:
// <none>
// ----------------------------------------------------------------------------
static void setVariables(const char *cmd, const char *arg) {
@ -329,7 +342,7 @@ static void openWebPage()
response += "<style>.thead {background-color:green; color:white;} ";
response += ".cell {border: 1px solid black;}";
response += ".config_table {max_width:100%; min-width:400px; width:95%; border:1px solid black; border-collapse:collapse;}";
response += ".config_table {max_width:100%; min-width:400px; width:98%; border:1px solid black; border-collapse:collapse;}";
response += "</style></HEAD><BODY>";
response +="<h1>ESP Gateway Config</h1>";
@ -774,6 +787,16 @@ static void statisticsData()
// ----------------------------------------------------------------------------
// SENSORDATA
// If enabled, display the sensorHistory on the current webserver Page.
// In this GUI section a number of statr[x] records are displayed such as:
//
// Time, The time the sensor message was received
// Node, the DevAddr or even Node name for Trusted nodes,
// Data (Localserver), when _LOCALSERVER is enabled contains decoded data
// C, Channel frequency on which the sensor was received
// Freq, The frequency of the channel
// SF, Spreading Factor
// pRSSI, Packet RSSI
//
// Parameters:
// - <none>
// Returns:
@ -789,6 +812,9 @@ static void sensorData()
response += "<tr>";
response += "<th class=\"thead\">Time</th>";
response += "<th class=\"thead\">Node</th>";
#if _LOCALSERVER==1
response += "<th class=\"thead\">Data</th>";
#endif
response += "<th class=\"thead\" style=\"width: 20px;\">C</th>";
response += "<th class=\"thead\">Freq</th>";
response += "<th class=\"thead\" style=\"width: 40px;\">SF</th>";
@ -806,16 +832,26 @@ static void sensorData()
response = "";
response += String() + "<tr><td class=\"cell\">";
response += String() + "<tr><td class=\"cell\">"; // Tmst
stringTime((statr[i].tmst), response); // XXX Change tmst not to be millis() dependent
response += "</td>";
response += String() + "<td class=\"cell\">";
if (SerialName((char *)(& (statr[i].node)), response) < 0) { // works with TRUSTED_NODES >= 1
printHEX((char *)(& (statr[i].node)),' ',response); // else
response += String() + "<td class=\"cell\">"; // Node
if (SerialName((char *)(& (statr[i].node)), response) < 0) { // works with TRUSTED_NODES >= 1
printHEX((char *)(& (statr[i].node)),' ',response); // else
}
response += "</td>";
#if _LOCALSERVER==1
response += String() + "<td class=\"cell\">"; // Data
for (int j=0; j<statr[i].datal; j++) {
if (statr[i].data[j] <0x10) response+= "0";
response += String(statr[i].data[j],HEX) + " ";
}
response += "</td>";
#endif
response += String() + "<td class=\"cell\">" + statr[i].ch + "</td>";
response += String() + "<td class=\"cell\">" + freqs[statr[i].ch] + "</td>";
response += String() + "<td class=\"cell\">" + statr[i].sf + "</td>";
@ -1000,6 +1036,7 @@ void setupWWW()
server.on("/FORMAT", []() {
Serial.print(F("FORMAT ..."));
SPIFFS.format(); // Normally disabled. Enable only when SPIFFS corrupt
initConfig(&gwayConfig);
Serial.println(F("DONE"));
});
@ -1260,9 +1297,10 @@ void setupWWW()
#endif
// Display Statistics
server.on("/STAT", []() {
server.sendHeader("Location", String("/"), true);
buttonStat();
server.send ( 302, "text/plain", "");
//server.sendHeader("Location", String("/"), true);
//server.send ( 302, "text/plain", "");
});
server.on("/LOG", []() {
server.sendHeader("Location", String("/"), true);

Wyświetl plik

@ -1,7 +1,7 @@
// 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
// Version 5.3.1
// Date: 2018-06-30
// Version 5.3.2
// Date: 2018-07-07
//
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
// and many others.
@ -11,6 +11,8 @@
// which accompanies this distribution, and is available at
// https://opensource.org/licenses/mit-license.php
//
// NO WARRANTY OF ANY KIND IS PROVIDED
//
// Author: Maarten Westenberg (mw12554@hotmail.com)
//
// This file contains a number of compile-time settings that can be set on (=1) or off (=0)

Wyświetl plik

@ -1,7 +1,7 @@
// 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
// Version 5.3.1
// Date: 2018-06-30
// Version 5.3.2
// Date: 2018-07-07
//
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
// and many other contributors.
@ -11,6 +11,8 @@
// which accompanies this distribution, and is available at
// https://opensource.org/licenses/mit-license.php
//
// NO WARRANTY OF ANY KIND IS PROVIDED
//
// Author: Maarten Westenberg (mw12554@hotmail.com)
//
// This file contains a number of compile-time settings and declarations that are
@ -254,7 +256,11 @@ struct stat_t {
#if RSSI==1
int8_t rssi; // XXX Can be < -128
#endif
int8_t prssi; // XXX Can be < -128
int8_t prssi; // XXX Can be < -128
#if _LOCALSERVER==1
uint8_t data[23]; // For memory purposes, only 23 chars
uint8_t datal; // Length of decoded message 1 char
#endif
} stat_t;
@ -294,6 +300,9 @@ struct stat_c statc;
// History of received uplink messages from nodes
struct stat_t statr[MAX_STAT];
#else // STATISTICS==0
struct stat_t statr[1]; // Always have at least one element to store in
#endif

Wyświetl plik

@ -1,16 +1,18 @@
// 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
// Version 5.3.1
// Date: 2018-06-30
// Version 5.3.2
// Date: 2018-07-07
//
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
// and many others.
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
// and many others.
//
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the MIT License
// which accompanies this distribution, and is available at
// https://opensource.org/licenses/mit-license.php
//
// NO WARRANTY OF ANY KIND IS PROVIDED
//
// Author: Maarten Westenberg (mw12554@hotmail.com)
//
// This file contains a number of compile-time settings and definitions for OLED support.

Wyświetl plik

@ -0,0 +1,80 @@
// sensor.h; 1-channel LoRa Gateway for ESP8266
// Copyright (c) 2016, 2017, 2018 Maarten Westenberg version for ESP8266
// Version 5.3.2
// Date: 2018-07-07
//
// based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
// and many other contributors.
//
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the MIT License
// which accompanies this distribution, and is available at
// https://opensource.org/licenses/mit-license.php
//
// NO WARRANTY OF ANY KIND IS PROVIDED
//
// Author: Maarten Westenberg (mw12554@hotmail.com)
//
// This file contains a number of compile-time settings and declarations that are
// specific to the LoRa rfm95, sx1276, sx1272 radio of the gateway.
//
//
// ------------------------------------------------------------------------------------
#if _TRUSTED_NODES >= 1
struct nodex {
uint32_t id; // This i sthe decide ID (coded in 4 bytes uint32_t
char nm[32];
};
// Add all your named and trusted nodes to this list
nodex nodes[] = {
{ 0x260116BD , "lora-34 PIR node" }, // F=0
{ 0x26011152 , "lora-35 temp+humi node" }, // F=0
{ 0x2601148C , "lora-36 test node" }, // F=0
{ 0x26011B90 , "lora-39 temp DS18B20" }, // F=1
{ 0x260119A6 , "lora-40 airquality" }, // F=0
{ 0x2601117D , "lora-41 temp+humi SR04T" },
{ 0x26011514 , "lora-43 ch1, no sensors" }, // F=1
{ 0x26011D77 , "lora-45 not sensor" },
{ 0x2601160F , "lora-46 HTU21 metal case" }, // F=0
{ 0x26011E71 , "lora-47 Dallas temperature" }, // F=0
{ 0x26011E52 , "lora-53 gas sensor" }, // F=ALL
{ 0x02020441 , "lora-65 Waterproof temp humi" }, // F=0
{ 0x26011b96 , "lora-50 Internal T-Beam gway" }, // F=0
{ 0x26011999 , "lora-901 distance sensor" } // F=0
};
#endif //_TRUSTED_NODES
#if _LOCALSERVER==1
struct codex {
uint32_t id; // This is the device ID (coded in 4 bytes uint32_t
char nm[32]; // A name string which is free to choose
uint8_t nwkKey[16]; // The Network Session Key
uint8_t appKey[16]; // The Application Session Key
};
// Sometimes we want to decode the sensor completely as we do in the TTN server
// This means that for all nodes we want to view the dara of, we need to provide
// he AppsSKey and the NwkSKey
// Definition of all nodes that we want to decode locally on the gateway.
//
codex decodes[] = {
{ 0x2601148C , "lora-36", // F=0
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x02, 0x02, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
},
{ 0x26011b96 , "lora-50", // F=0
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x02, 0x02, 0x04, 0x32, 0x00, 0x00, 0x00, 0x00, 0x54, 0x68, 0x69, 0x6E, 0x67, 0x73, 0x34, 0x55 }
},
{ 0x26011999 , "lora-901", // F=0
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x02, 0x02, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
}
};
#endif //_LOCALSERVER

Wyświetl plik

@ -1,6 +1,6 @@
# Single Channel LoRaWAN Gateway
Version 5.3.1, June 30, 2018
Version 5.3.2, July 07, 2018
Author: M. Westenberg (mw12554@hotmail.com)
Copyright: M. Westenberg (mw12554@hotmail.com)
@ -49,18 +49,11 @@ under the Gateway chapter.
## testing
This Gateway code has been tested on the following boards:
- Wemos D1 Mini + Hallard board with RFM95
- Wemos D1 Mini + Comresult board with RFM95
- TTGO T-Beam board, ESP32, SX1276, Battery and GPS
- TTGO ESP32 V1 board, SX1276 on EU868
- TTGO ESP32 V1 board, SX1278, OLED on 433MHz
The single channel gateway has been tested on a gateway with the Wemos D1 Mini, using a HopeRF RFM95W transceiver.
The LoRa nodes tested againts this gateway are:
- TeensyLC with HopeRF RFM95 radio
- Arduino Pro-Mini (default Atmega328 model, 8MHz 3.3V and 16MHz 3.3V)
- Arduino Pro-Mini (default Armega328 model, 8MHz 3.3V and 16MHz 3.3V)
- ESP8266 based nodes with RFM95 transceivers.
The code has been tested on at least 8 separate gateway boards both based on the Hallard and the Comresult boards.
@ -400,9 +393,9 @@ The following things are still on my wish list to make to the single channel gat
- Receive downstream message with commands from the server. These can be used to configure
the gateway through downlink messages (such as setting the SF)
- Support for ESP32 and RFM95 on 915 MHz
- Support for ESP32 and RFM95 on 433 MHz
- Use the SPIFFS for storing .css files
- Use the SPIFFS for storing node data (for later analysis)
- Look at CLass B and C support