0

I am working on project where I have to do AES encryption of plain text received through normal UART port of ESP8266 create a cipher text and sending it to LoRa module (EByte E32 868T30D) through Software Serial port and recieve on the other end decrypt and get the plain text back. the problem I am facing is when I try to sendlarge array of bytes more than 300 or so I am getting garbled values on the other end. I am well aware of the 512 byte limit in LoRa module and so I tried using Hardware flow control by AUX pin that is available. Eventhough I am not successfull in implementing a working code. I have a grey area in how to implement such a hardware flow control in ESP8266. since its my first time I am seeking for help from experts in this field. My project requires me to send about 10kB of data over LoRa with minimum possible delay between each 512 byte transmission enter image description here

/*===========================================================================================================================================================================
   ---------------------------------------------------- ESP8266 EByte 32 Lora Encryption Test ----------------------------------------------------
   Author: Mister.B
   Date: 10 May 2020
   Objective: To test AES256 ECB Encryption on LoRa Modules
   Third-Party ibraries used:
   1) aes256 - https://github.com/qistoph/ArduinoAES256
  ===========================================================================================================================================================================*/
#include "aes256.h"
#include <SoftwareSerial.h>

//EByte E32 Pin Configuration

#define M0 D5
#define M1 D6
#define AUX D2 // AUX HIGH means BUSY LOW means READY
#define RX_Pin D3
#define TX_Pin D4

//BaudRate Selection

#define E32_BAUD 9600
#define SERIAL_BAUD 9600

//AES Parameters
#define BUFFER_SIZE 2048 //2kB buffer to store the values
#define BLOCK_SIZE 16

//Timeout selection
#define UART_SERIAL_TIMEOUT 5000
#define E32_SERIAL_TIMEOUT 5000

//Debug Selection
#define DEBUG_CONSOLE true

//Class Instances
aes256_context ctxt;
SoftwareSerial E32(RX_Pin, TX_Pin);
//#define E32 Serial
//======Global Variables Declaration======
uint8_t key[] = {
  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
};
uint8_t data_buffer[BUFFER_SIZE] = {};
int i = 0, in_count = 0, out_count = 0;
unsigned long last_packet_arrival = 0;

//MACROS
#define ARRAY_SIZE(arr) ((sizeof(arr))/(sizeof(arr[0])))
#if DEBUG_CONSOLE == true
#define DUMP(str,i,buf,sz){Serial.println(str);\
    for(i=0;i<sz;++i){if(buf[i]<0x10)Serial.print('0');Serial.print(char(buf[i]),HEX);}\
    Serial.println();}
#else
#define DUMP(str,i,buf,sz)
#endif


void setup()
{
  Serial.begin(SERIAL_BAUD);
  E32.begin(E32_BAUD);
  pinMode(M0, OUTPUT);
  pinMode(M1, OUTPUT);
  pinMode(AUX, INPUT);
  /*
     Setting Ebyte 32 in Normal Mode (M0=LOW and M1=LOW)
  */
  digitalWrite(M0, LOW);
  digitalWrite(M1, LOW);
  delay(1000);
  DUMP("\nKey:", i, key, sizeof(key));
  aes256_init(&ctxt, key); // Send key for key scheduling
}
void loop()
{
  int frame_count = 0;
  out_count = 0;
  in_count = 0;
  last_packet_arrival = millis();
  /*
     RECEIVE DATA FROM EBYTE E32 LoRa
  */
  if (E32.available()) {
    out_count = 0;
    last_packet_arrival = millis();
    frame_count = (int)E32.read();
    while ((millis() - last_packet_arrival < E32_SERIAL_TIMEOUT) or (frame_count > out_count)) {
      out_count += E32.readBytes(data_buffer+out_count,58);
      if (out_count >= BUFFER_SIZE)Serial.printf("\n Input Buffer[%d] full :(", BUFFER_SIZE); break; //Prevent buffer overflow
    }
    Serial.printf("\nFc:%d", frame_count);
    frame_count = 0;
    Serial.printf("\nReceiveCount:%d\n", out_count);
    DUMP("\nRecived Data:", i, data_buffer, out_count);
    for (int n = 0; n <= (out_count / BLOCK_SIZE); n += BLOCK_SIZE)aes256_decrypt_ecb(&ctxt, data_buffer + n);
    DUMP("\nDecrypted Data:", i, data_buffer, out_count);
    for (int i = 0; i < out_count; i++)Serial.print((char)data_buffer[i]); yield();
    memset(data_buffer, 0x00, BUFFER_SIZE);
    out_count = 0;
  }
  /*
     RECEIVE DATA FROM UART Port
  */
  if (Serial.available()) {
    in_count=0;
    last_packet_arrival = millis();
    while ((millis() - last_packet_arrival) < UART_SERIAL_TIMEOUT) {
      in_count += Serial.readBytes(data_buffer + in_count, 58);
      if (in_count >= BUFFER_SIZE)Serial.printf("\n Output Buffer[%d] full :(", BUFFER_SIZE); break; // Prevent buffer overflow
    }
    /*
       Padding with zeros
    */
    if (in_count < 58) { // if Serial data entered is smaller than 58
      for (int i = in_count; i < 58; i++)data_buffer[i] = 0x00;
    }
    if (in_count > 58 && (in_count % 58 != 0)) { // if the Serial data is not multiple of 58 do padding with 0x00
      for (int i = in_count; i < in_count + (in_count % 58); i++)data_buffer[i] = 0x00;
    }
    Serial.printf("\nSendCount:%d", in_count);
    DUMP("\nData Entered:", i, data_buffer, in_count);
    //for (int n = 0; n <= (in_count / BLOCK_SIZE); n += BLOCK_SIZE)aes256_encrypt_ecb(&ctxt, data_buffer + n); // Encrypting whole data by 16 byte blocks
    //DUMP("\nEncrypted Data:", i, data_buffer, in_count);
    /*
       Add the length number of 512 byte in data frame
    */
    //uint8_t data_frame[BUFFER_SIZE + (BUFFER_SIZE % 58)] = {};
    //for (int i = 0; i <= BUFFER_SIZE; i++) data_frame[i + 1] = data_buffer[i];
    //data_frame[0] = (in_count / 58) + 1;
    //DUMP("\nSent Data:", i, data_frame, in_count + 1);
    /*
       Prevent buffer overflow in LoRa module using Hardware Flow control
    */
    uint8_t buff[58] = {};
//    for (int i = 0; i < (in_count / 464)+1 ; i++) //divide the data buffer into 464 byte frames
//    {
//      for (int j = 464 * i; j < (464 * i) + 464; j += 58) { //divide the 464 byte frames into 58 byte frames
        byte* f_count=(in_count<58) ? in_count : (in_count / 58) + 1;
        E32.write(f_count,1);
        for (int j = 0 ; j < in_count ; j+=58){
        memcpy(buff, data_buffer + j, 58);
        aes256_encrypt_ecb(&ctxt,buff);
        DUMP("\nEncrypted Data:", i, buff, 58);
        while (digitalRead(AUX) == HIGH) yield(); // wait for the pin to get LOW
        if (digitalRead(AUX) == LOW) { //if the module is READY send
          E32.write(buff, 58);
//          E32.flush();
        }
      }
//    }
    in_count = 0;
    memset(data_buffer, 0x00, BUFFER_SIZE);
    //memset(data_frame, 0x00, ARRAY_SIZE(data_frame));
  }
}
  • The ESPSoftwareSerial bundled with the esp8266 Arduino boards package supports transmit flow control with setTransmitEnablePin – Juraj May 24 at 17:00
  • @Juraj can we use this pin as an input in ESP8266 and hold say 10kB data in buffer until the pin is asserted to given logic and send data as chunks of 512 byte? – Mr.B May 24 at 19:20
  • yes the transmit enable pin is an input. you can test availableForWrite to check if you can write more data to SoftwareSerial instance – Juraj May 24 at 19:55
  • @Juraj will test this tommorow and will revert back – Mr.B May 24 at 21:04
  • sorry, I was wrong. the transmit enable has other purpose (as for RS485) and availableForWrite doesn't work as it should on ESPSoftwareSerial – Juraj May 25 at 4:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.