//
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiUdp.h>
// 
#define WIFI_SSID "FritzBoxSA7"
#define WIFI_PASS "01234567890123456789"
const unsigned int UDP_PORT = 1234;
const unsigned int SIZE_BUFFER = 255;
const unsigned SIZE_RESPONSECOUNT = 3;
const int PIN_LEDSYSTEM = 2;
//
WiFiUDP UDP;
char RxBuffer[SIZE_BUFFER];
char TxBuffer[SIZE_BUFFER];
bool IsRemoteIP = false;
long unsigned TicksPreset;
unsigned ResponseLedCount = SIZE_RESPONSECOUNT;
//
const char* GetStateLed(void)
{
  if (digitalRead(PIN_LEDSYSTEM))
  {
    return "ON";
  }
  return "OFF";
}

//
void setup() 
{
  Serial.begin(115200);
  Serial.println("\r\n");
  Serial.println("**********************");
  Serial.println("* Esp32UdpServer     *");
  Serial.println("* Version: 01V04     *");
  Serial.println("* Date...: 221104    *");
  Serial.println("* Time...: 1136      *");
  Serial.println("* Author.: OMdevelop *");
  Serial.println("**********************");
  //
  pinMode(PIN_LEDSYSTEM, OUTPUT);
  for (int I = 0; I < 3; I++)
  {
    digitalWrite(PIN_LEDSYSTEM, HIGH);
    delay(200); 
    digitalWrite(PIN_LEDSYSTEM, LOW);
    delay(200); 
  }
  //
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  Serial.print("Connecting to ");
  Serial.print(WIFI_SSID);
  Serial.print(" : ");
  while (WiFi.status() != WL_CONNECTED)
  {
    digitalWrite(PIN_LEDSYSTEM, HIGH);
    delay(200); 
    Serial.print(".");
    digitalWrite(PIN_LEDSYSTEM, LOW);
    delay(200); 
  }
  Serial.println("");
  Serial.print("Connected to IPAddress: ");
  Serial.println(WiFi.localIP());
  //
  UDP.begin(UDP_PORT);
  Serial.print("Listening on UDP-Port: ");
  Serial.println(UDP_PORT);
  //
  TicksPreset = millis();
}

void loop() 
{
  int SP = UDP.parsePacket();
  if (0 < SP) 
  {
    Serial.print("RxData: Size[B]: ");
    Serial.println(SP); 
    int LR = UDP.read(RxBuffer, SIZE_BUFFER);
    if (0 < LR)
    {
      RxBuffer[LR] = '\0';
    }
    Serial.print("Packet received: ");
    Serial.println(RxBuffer);
    IsRemoteIP = true;
    if (0 == strncmp("LSO", RxBuffer, 3))
    {
      digitalWrite(PIN_LEDSYSTEM, HIGH);
      sprintf(TxBuffer, "Command-Handshake[%s]", RxBuffer);
      UDP.beginPacket(UDP.remoteIP(), UDP.remotePort());
      UDP.print(TxBuffer);
      UDP.endPacket();    
      ResponseLedCount = 0;
    }
  }
  if (IsRemoteIP)
  {
    if (1000 < (millis() - TicksPreset))
    {
      TicksPreset = millis();
      if (ResponseLedCount < SIZE_RESPONSECOUNT)
      {
        ResponseLedCount++;
        sprintf(TxBuffer, "Response[%d/%d]<%s>", 
                ResponseLedCount, SIZE_RESPONSECOUNT, GetStateLed());
        Serial.println(TxBuffer);
        UDP.beginPacket(UDP.remoteIP(), UDP.remotePort());
        UDP.print(TxBuffer);
        UDP.endPacket();
      }
      else
      { // wait for next Client-Request
        digitalWrite(PIN_LEDSYSTEM, LOW);
      }
    }
  }

}
