Artem-Darius Weber 1 year ago
commit fe8b297048

2
.gitignore vendored

@ -0,0 +1,2 @@
cybergarden-sensor/.vscode
cybergarden-aggregator/.vscode

@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

@ -8,7 +8,10 @@
#define ECC_LENGTH 4
#define TOTAL_LENGTH (MSG_LENGTH + ECC_LENGTH)
bool TransmissionModule::receive(uint8_t &sensor_id, MeasureData &data) {
bool TransmissionModule::receive(uint8_t &sensor_id, MeasureData &data)
{
uint8_t buf[TOTAL_LENGTH];
if (!transmitterModule->receive(buf, TOTAL_LENGTH)) {
return false;
@ -20,7 +23,30 @@ bool TransmissionModule::receive(uint8_t &sensor_id, MeasureData &data) {
}
sensor_id = msg[0];
memcpy((void *) &data, msg+1, 4);
size_t posn, len, inc = 5;
cipher->clear();
cipher->setKey(encryptionKey, key_size);
cipher->setIV(iv, iv_size);
memset(buffer, 0xBA, sizeof(buffer));
for (posn = 0; posn < auth_size; posn += inc) {
len = auth_size - posn;
if (len > inc)
len = inc;
cipher->addAuthData(authdata + posn, len);
}
size_t data_size = 4;
for (posn = 0; posn < data_size; posn += inc) {
len = data_size - posn;
if (len > inc)
len = inc;
cipher->decrypt(buffer + posn, msg + 1 + posn, len);
}
memcpy((void *) &data, buffer, 4);
return true;
}

@ -1,17 +1,38 @@
#ifndef KEMPT_KINKAJOU_TRANSMISSIONMODULE_H
#define KEMPT_KINKAJOU_TRANSMISSIONMODULE_H
#include <Arduino.h>
#include <Crypto.h>
#include <ChaChaPoly.h>
#include "MeasureData.h"
#include "TransmitterModule.h"
#include "ReedSolomonModule.h"
#ifndef KEMPT_KINKAJOU_TRANSMISSIONMODULE_H
#define KEMPT_KINKAJOU_TRANSMISSIONMODULE_H
#define MAX_PLAINTEXT_LEN 265
class TransmissionModule {
private:
TransmitterModule * transmitterModule;
ReedSolomonModule * reedSolomonModule;
ChaChaPoly* cipher;
uint8_t encryptionKey[16] = {0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f};
uint8_t authdata[16] = {0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3,
0xc4, 0xc5, 0xc6, 0xc7};
uint8_t iv[16] = {0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43,
0x44, 0x45, 0x46, 0x47};
uint8_t buffer[MAX_PLAINTEXT_LEN];
size_t key_size = 16;
size_t auth_size = 12;
// size_t data_size = 4;
size_t iv_size = 12;
public:
TransmissionModule(TransmitterModule &transmitterModule, ReedSolomonModule &reedSolomonModule) : transmitterModule(&transmitterModule), reedSolomonModule(&reedSolomonModule) {}
TransmissionModule(TransmitterModule &transmitterModule, ReedSolomonModule &reedSolomonModule) :
transmitterModule(&transmitterModule),
reedSolomonModule(&reedSolomonModule) {
cipher = new ChaChaPoly();
}
bool receive(uint8_t &sendor_id, MeasureData &data);
};

@ -1,19 +1,20 @@
//
// Created by o.likhogub on 10/7/2023.
//
#ifndef KEMPT_KINKAJOU_TRANSMITTERMODULE_H
#define KEMPT_KINKAJOU_TRANSMITTERMODULE_H
#include "Arduino.h"
#include <RH_ASK.h>
#include <SPI.h>
#ifndef KEMPT_KINKAJOU_TRANSMITTERMODULE_H
#define KEMPT_KINKAJOU_TRANSMITTERMODULE_H
class TransmitterModule {
private:
RH_ASK *rhAsk;
public:
TransmitterModule() {
rhAsk = new RH_ASK(2000, 4, 5, 0);
rhAsk = new RH_ASK(2000, 5, 4, 0);
}
bool init() {
return rhAsk->init();

@ -0,0 +1,180 @@
//
// FILE: UUID.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.5
// DATE: 2022-06-14
// PURPOSE: Arduino Library for generating UUID's
// URL: https://github.com/RobTillaart/UUID
// https://en.wikipedia.org/wiki/Universally_unique_identifier
#include "Uuid.h"
UUID::UUID()
{
seed(1, 2);
setVariant4Mode();
generate();
}
void UUID::seed(uint32_t s1, uint32_t s2)
{
// set Marsaglia constants, prevent 0 as value
if (s1 == 0) s1 = 1;
if (s2 == 0) s2 = 2;
_m_w = s1;
_m_z = s2;
}
// check version 0.1.1 for more readable code
void UUID::generate()
{
uint32_t ar[4];
for (uint8_t i = 0; i < 4; i++)
{
ar[i] = _random();
// store binary version globally ?
// _ar[i] = ar[i];
}
// Conforming to RFC 4122 Specification
// - byte 7: four most significant bits ==> 0100 --> always 4
// - byte 9: two most significant bits ==> 10 --> always {8, 9, A, B}.
//
// patch bits for version 1 and variant 4 here
if (_mode == UUID_MODE_VARIANT4)
{
ar[1] &= 0xFFF0FFFF; // remove 4 bits.
ar[1] |= 0x00040000; // variant 4
ar[2] &= 0xFFFFFFF3; // remove 2 bits
ar[2] |= 0x00000008; // version 1
}
// process 16 bytes build up the char array.
for (uint8_t i = 0, j = 0; i < 16; i++)
{
// multiples of 4 between 8 and 20 get a -.
// note we are processing 2 digits in one loop.
if ((i & 0x1) == 0)
{
if ((4 <= i) && (i <= 10))
{
_buffer[j++] = '-';
}
}
// process one byte at the time instead of a nibble
uint8_t nr = i / 4;
uint8_t xx = ar[nr];
uint8_t ch = xx & 0x0F;
_buffer[j++] = (ch < 10) ? '0' + ch : ('a' - 10) + ch;
ch = (xx >> 4) & 0x0F;
ar[nr] >>= 8;
_buffer[j++] = (ch < 10) ? '0' + ch : ('a' - 10) + ch;
}
// if (_upperCase)
// {
// for (int i = 0; i < 37; i++)
// {
// _buffer[i] = toUpper(_buffer[i]);
// }
// }
_buffer[36] = 0;
}
char * UUID::toCharArray()
{
// if (_upperCase)
// {
// for (int i = 0; i < 37; i++)
// {
// _buffer[i] = toLower(_buffer[i]);
// }
// }
// else
// {
// for (int i = 0; i < 37; i++)
// {
// _buffer[i] = toLower(_buffer[i]);
// }
// }
return _buffer;
}
//////////////////////////////////////////////////
//
// MODE
//
void UUID::setVariant4Mode()
{
_mode = UUID_MODE_VARIANT4;
}
void UUID::setRandomMode()
{
_mode = UUID_MODE_RANDOM;
}
uint8_t UUID::getMode()
{
return _mode;
}
//////////////////////////////////////////////////
//
// PRINTING
//
size_t UUID::printTo(Print& p) const
{
return p.print(_buffer);
}
//////////////////////////////////////////////////
//
// CASE
//
// void UUID::setLowerCase()
// {
// _upperCase = false;
// }
//
//
// void UUID::setUpperCase()
// {
// _upperCase = true;
// }
//////////////////////////////////////////////////
//
// PRIVATE
//
//////////////////////////////////////////////////
//
// RANDOM GENERATOR MARSAGLIA
//
// An example of a simple pseudo-random number generator is the
// Multiply-with-carry method invented by George Marsaglia.
// two initializers (not null)
uint32_t UUID::_random()
{
_m_z = 36969L * (_m_z & 65535L) + (_m_z >> 16);
_m_w = 18000L * (_m_w & 65535L) + (_m_w >> 16);
return (_m_z << 16) + _m_w; // 32-bit result
}
// -- END OF FILE --

@ -0,0 +1,75 @@
#pragma once
//
// FILE: UUID.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.5
// DATE: 2022-06-14
// PURPOSE: Arduino Library for generating UUID's
// URL: https://github.com/RobTillaart/UUID
// https://en.wikipedia.org/wiki/Universally_unique_identifier
//
// e.g. 20d24650-d900-e34f-de49-8964ab3eb46d
#include "Arduino.h"
#include "Printable.h"
#define UUID_LIB_VERSION (F("0.1.5"))
// TODO an enum?
const uint8_t UUID_MODE_VARIANT4 = 0;
const uint8_t UUID_MODE_RANDOM = 1;
/////////////////////////////////////////////////
//
// CLASS VERSION
//
class UUID : public Printable
{
public:
UUID();
// at least one seed value is mandatory, two is better.
void seed(uint32_t s1, uint32_t s2 = 0);
// generate a new UUID
void generate();
// make a UUID string
char * toCharArray();
// MODE
void setVariant4Mode();
void setRandomMode();
uint8_t getMode();
// Printable interface
size_t printTo(Print& p) const;
// CASE
// (experimental code, not tested yet)
// lower case is default and according to spec.
// upper case is an additional feature.
// must it be done at generation or at toCharArray() ?
// fast or flex
//
// void setLowerCase();
// void setUpperCase();
private:
// Marsaglia 'constants' + function
uint32_t _m_w = 1;
uint32_t _m_z = 2;
uint32_t _random();
// UUID in string format
char _buffer[37];
uint8_t _mode = UUID_MODE_VARIANT4;
// bool _upperCase = false;
};
// -- END OF FILE --

@ -0,0 +1,18 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
monitor_speed = 115200
lib_deps =
mikem/RadioHead@^1.120
rweather/Crypto@^0.4.0

@ -0,0 +1,110 @@
#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ReedSolomonModule.h>
#include <MeasureData.h>
#include <TransmissionModule.h>
#include <TransmitterModule.h>
#include <RH_ASK.h>
#ifdef RH_HAVE_HARDWARE_SPI
#include <SPI.h> // Not actually used but needed to compile
#endif
#include "Uuid.h"
String serverName = "http://gw.cg.k-lab.su/api/v1/measures/register";
ReedSolomonModule reedSolomonModule;
TransmitterModule transmitterModule;
TransmissionModule transmissionModule(transmitterModule, reedSolomonModule);
UUID uuid;
const char *ntpServer = "pool.ntp.org";
unsigned long epochTime;
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin("Darius wifi", "alstroemeria");
Serial.println("\nConnecting");
while (WiFi.status() != WL_CONNECTED)
{
Serial.print(".");
delay(100);
}
pinMode(LED_BUILTIN, OUTPUT);
transmitterModule.init();
configTime(0, 0, ntpServer);
}
uint8_t sensor_id;
MeasureData measureData;
unsigned long getTime()
{
time_t now;
struct tm timeinfo;
if (!getLocalTime(&timeinfo))
{
Serial.println("Failed to obtain time");
return (0);
}
time(&now);
return now;
}
String getPayload(MeasureData &data)
{
String serverPath = serverName;
serverPath += String("/") + getTime();
serverPath += String("/") + data.sensor_id;
serverPath += String("/") + WiFi.macAddress();
serverPath += String("/") + getTime();
if (data.sensor_type == 1) {
serverPath += String("/") + "temperature";
} else {
serverPath += String("/") + data.sensor_type;
}
serverPath += String("/") + data.payload;
return serverPath;
}
bool sendPayload(MeasureData &data) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String serverPath = getPayload(data);
http.begin(serverPath.c_str());
int httpResponseCode = http.GET();
if (httpResponseCode > 0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
String payload = http.getString();
Serial.println(payload);
return true;
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
http.end();
}
return false;
}
MeasureData data;
void loop() {
if (transmissionModule.receive(sensor_id, data)) {
data.sensor_id = sensor_id;
data.sensor_type = data.sensor_type;
data.payload = data.payload;
analogWrite(LED_BUILTIN, 255);
sendPayload(data);
delay(100);
analogWrite(LED_BUILTIN, 0);
}
}

@ -0,0 +1,28 @@
#include <Sensors.h>
float Sensor::temperatureSensor(){
return analogRead(TEMP_SENS);
}
float Sensor::humiditySensor(){
float h = dht->readHumidity();
if (isnan(h)) {
return -1;
}
else{
return h;
}
}
int Sensor::photoSensor(){
int value = analogRead(PHOTO_SENS);
return value;
}
int Sensor::vibroSensor(){
int value = analogRead(VIBRO_SENS);
return value;
}

@ -0,0 +1,31 @@
#pragma once
#include "Arduino.h"
#include "DHT.h"
#include "math.h"
///////////////////////////////////////////////////////
// Pins Definitions
///////////////////////////////////////////////////////
#define HUM_SENS 33
#define TEMP_SENS 32
#define PHOTO_SENS 25
#define VIBRO_SENS 26
class Sensor{
private:
//KY-015
DHT *dht;
public:
float temperatureSensor();
float humiditySensor();
int photoSensor();
int vibroSensor();
Sensor()
{
dht = new DHT(HUM_SENS, DHT11);
dht->begin();
}
};

@ -8,13 +8,50 @@
#define ECC_LENGTH 4
#define TOTAL_LENGTH (MSG_LENGTH + ECC_LENGTH)
void TransmissionModule::transmit(MeasureData &data) {
uint8_t msg[MSG_LENGTH];
msg[0] = data.sensor_id;
memcpy(msg + 1, (void *) &data, 4);
void TransmissionModule::transmit(MeasureData &data)
{
size_t posn, len, inc = 5;
size_t data_size = 4;
cipher->clear();
cipher->setKey(encryptionKey, key_size);
cipher->setIV(iv, iv_size);
memset(buffer, 0xBA, sizeof(buffer));
for (posn = 0; posn < auth_size; posn += inc) {
len = auth_size - posn;
if (len > inc)
len = inc;
cipher->addAuthData(authdata + posn, len);
}
cipher->encrypt(buffer + 1, (uint8_t*)&data, data_size);
buffer[0] = data.sensor_id;
//*************************
//Encryption Testing
//*************************
// byte buffer2[MAX_PLAINTEXT_LEN];
// memset(buffer2, 0xBA, sizeof(buffer));
// cipher->setKey(encryptionKey, 16);
// cipher->setIV(iv, iv_size);
// for (posn = 0; posn < data_size; posn += inc) {
// len = data_size - posn;
// if (len > inc)
// len = inc;
// cipher->decrypt(buffer2 + posn, buffer + posn, len);
// }
// if (memcmp(buffer2, (uint8_t*)&data + 1, data_size) != 0) {
// Serial.println("doesn't work");
// } else{
// Serial.println("works");
// }
uint8_t encoded[MSG_LENGTH + ECC_LENGTH];
reedSolomonModule->encode(msg, encoded);
reedSolomonModule->encode(buffer, encoded);
transmitterModule->send(encoded, MSG_LENGTH + ECC_LENGTH);
}

@ -1,23 +1,42 @@
#ifndef KEMPT_KINKAJOU_TRANSMISSIONMODULE_H
#define KEMPT_KINKAJOU_TRANSMISSIONMODULE_H
#include <Arduino.h>
#include <Crypto.h>
#include <ChaChaPoly.h>
#include "MeasureData.h"
#include "TransmitterModule.h"
#include "ReedSolomonModule.h"
#ifndef KEMPT_KINKAJOU_TRANSMISSIONMODULE_H
#define KEMPT_KINKAJOU_TRANSMISSIONMODULE_H
#define MAX_PLAINTEXT_LEN 265
class TransmissionModule {
private:
TransmitterModule * transmitterModule;
ReedSolomonModule * reedSolomonModule;
ChaChaPoly* cipher;
uint8_t encryptionKey[16] = {0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f};
uint8_t authdata[16] = {0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3,
0xc4, 0xc5, 0xc6, 0xc7};
uint8_t iv[16] = {0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43,
0x44, 0x45, 0x46, 0x47};
uint8_t buffer[MAX_PLAINTEXT_LEN];
size_t key_size = 16;
size_t auth_size = 12;
// size_t data_size = 4;
size_t iv_size = 12;
public:
unsigned char * encryptionKey = 0;
TransmissionModule(
TransmitterModule &transmitterModule,
ReedSolomonModule &reedSolomonModule
) :
transmitterModule(&transmitterModule),
reedSolomonModule(&reedSolomonModule) {}
reedSolomonModule(&reedSolomonModule) {
cipher = new ChaChaPoly();
}
void transmit(MeasureData &data);
};

@ -8,15 +8,15 @@
#ifndef KEMPT_KINKAJOU_TRANSMITTERMODULE_H
#define KEMPT_KINKAJOU_TRANSMITTERMODULE_H
#define RH_TRANSMIT_PIN 12
#define RH_RECEIVE_PIN 11
#define RH_TRANSMIT_PIN 4
#define RH_RECEIVE_PIN 5
class TransmitterModule {
private:
RH_ASK *rhAsk;
public:
TransmitterModule() {
rhAsk = new RH_ASK();
rhAsk = new RH_ASK(2000, RH_RECEIVE_PIN, RH_TRANSMIT_PIN);
}
bool init() {
return rhAsk->init();

@ -9,8 +9,14 @@
; https://docs.platformio.org/page/projectconf.html
[env:esp32doit-devkit-v1]
platform = atmelavr
board = megaatmega2560
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
mikem/RadioHead@^1.120
mikem/RadioHead@^1.120
rweather/Crypto@^0.4.0
paulstoffregen/OneWire@^2.3.7
milesburton/DallasTemperature@^3.11.0
adafruit/DHT sensor library@^1.4.4
adafruit/Adafruit Unified Sensor@^1.1.13

@ -2,15 +2,16 @@
#include "TransmitterModule.h"
#include "TransmissionModule.h"
#include "ReedSolomonModule.h"
#include "Sensors.h"
TransmitterModule transmitterModule;
ReedSolomonModule reedSolomonModule;
TransmissionModule transmissionModule(transmitterModule, reedSolomonModule);
Sensor sensors;
void setup() {
Serial.begin(9600);
Serial.begin(115200);
transmitterModule.init();
pinMode(LED_BUILTIN, OUTPUT);
}
uint16_t getMockSensorData() {
@ -18,14 +19,45 @@ uint16_t getMockSensorData() {
}
void loop() {
MeasureData measureData;
measureData.sensor_id = 0xA5;
measureData.sensor_type = 0x01;
measureData.payload = getMockSensorData();
transmissionModule.transmit(measureData);
analogWrite(LED_BUILTIN, 255);
delay(200);
analogWrite(LED_BUILTIN, 0);
delay(1000);
MeasureData measureData_temp;
measureData_temp.sensor_id = 0xA5;
measureData_temp.sensor_type = 0x01;
measureData_temp.payload = sensors.temperatureSensor();
transmissionModule.transmit(measureData_temp);
delay(100);
MeasureData measureData_hum;
measureData_hum.sensor_id = 0xA5;
measureData_hum.sensor_type = 0x02;
measureData_hum.payload = sensors.humiditySensor();
transmissionModule.transmit(measureData_hum);
delay(100);
MeasureData measureData_photo;
measureData_photo.sensor_id = 0xA5;
measureData_photo.sensor_type = 0x03;
measureData_photo.payload = sensors.photoSensor();
transmissionModule.transmit(measureData_photo);
delay(100);
MeasureData measureData_vibro;
measureData_vibro.sensor_id = 0xA5;
measureData_vibro.sensor_type = 0x04;
measureData_vibro.payload = sensors.photoSensor();
transmissionModule.transmit(measureData_vibro);
delay(100);
Serial.print(sensors.humiditySensor(), DEC);
Serial.print(" ");
Serial.print(sensors.temperatureSensor(), DEC);
Serial.print(" ");
Serial.print(sensors.photoSensor(), DEC);
Serial.print(" ");
Serial.println(sensors.vibroSensor(), DEC);
delay(100);
}
Loading…
Cancel
Save