/*

Teszt Parancsok
*ASKI:##: Ellenőrizd, hogy helyesen jelenik meg a DeviceState metaadatai.
*ASKA:##: Ellenőrizd a mérési értékek helyességét.
*SETG:1F##: A gain legyen 0x1F.
*SETG:30##: Hibaüzenet (wrong value).

*/

#include <Arduino.h>

#define MAX_MSG_LEN 256
#define ERR_MSG_LEN 127

// Állapotok tárolása
struct DeviceState {
  char deviceType[16] = "BRTK12";
  char serialNumber[16] = "34";
  char manufacturingDate[16] = "2022-11-23";
  char firmwareVersion[16] = "v2.4";
  double temperature = 32.4;
  double supplyVoltage = 11.7;
  unsigned int alarms = 0x17;
  unsigned int gain = 0x05;
};

DeviceState device;

// ReceiveBuffer és hossza
char ReceiveBuffer[MAX_MSG_LEN] = {0};
volatile int ReceiveBufferLen = 0;

// Hexadecimális érték validálása
bool isValidHex(const char *value) {
  while (*value) {
    if (!isxdigit(*value)) return false;
    value++;
  }
  return true;
}
// Levágni a \n karaktert
void trimToNewline(char *buffer) {
    char *newlinePos = strchr(buffer, '\n');
    if (newlinePos) {
        *newlinePos = '\0'; // A '\n' helyére lezáró karakter kerül
    }
}
// Parancs feldolgozása
void processCommand(const char *command) {
  char response[MAX_MSG_LEN] = {0};
  char cmdCode[5] = {0};
  char params[MAX_MSG_LEN] = {0};

  Serial.print("Received Command: ");
  Serial.println(command); // A beolvasott parancs kiírása

  // Parancs dekódolása
  if (sscanf(command, "*%4[^:]:%[^#]##", cmdCode, params) < 1) {
    snprintf(response, sizeof(response), "!ERRR:Invalid command format##");
    Serial.println(response);
  }

  // Parancsok kezelése
  if (strcmp(cmdCode, "ASKI") == 0) {
    snprintf(response, sizeof(response), "!ASKI:%s,%s,%s,%s##",
             device.deviceType, device.serialNumber, device.manufacturingDate, device.firmwareVersion);
           //  Serial.println("ASKI");
  } else if (strcmp(cmdCode, "ASKA") == 0) {
    snprintf(response, sizeof(response), "!ASKA:%.1f,%.1f,%X,%02X##", device.temperature, device.supplyVoltage, device.alarms, device.gain);
          //   Serial.println("ASKA");
  } else if (strcmp(cmdCode, "SETG") == 0) {
    if (!isValidHex(params) || strlen(params) > 2) 
    {
      snprintf(response, sizeof(response), "!ERRR:Invalid hex format##");
     // Serial.println("SETG");
      
    } else 
    {
      unsigned int gainValue = strtoul(params, NULL, 16);
      if (gainValue > 0x20) {
        snprintf(response, sizeof(response), "!ERRR:Wrong value##");
      } else {
        device.gain = gainValue;  // Érték tárolása
        snprintf(response, sizeof(response), "!SETG:%02X##", device.gain);  // Válasz küldése
        // Serial.println("SETG V");
      }
    }
  } else 
  {
    snprintf(response, sizeof(response), "!ERRR:Unknown command##");
  }

  // Válasz küldése
  Serial.println(response);
 // Buffer törlése
// Serial.println("Torles");
    memset(ReceiveBuffer, 0, MAX_MSG_LEN);
//    trimToNewline(ReceiveBuffer);
}

// Interrupt Service Routine - adat fogadása
/*
void __interrupt UART2_ISR(void)
	{
		if(USART_GetITStatus(UART2, UART_IT_RXNE) != RESET)
		{
			ReceiveBuffer[ReceiveBufferLen] = UART_ReceiveData(UART2);
			ReceiveBufferLen++;
		}
	}
*/

void serialEvent() {
  while (Serial.available()) {
    char received = Serial.read();
    if (ReceiveBufferLen < MAX_MSG_LEN - 1|| received=='\n') {
      ReceiveBuffer[ReceiveBufferLen++] = received;
      if (received == '#' && ReceiveBufferLen >= 2 &&
          ReceiveBuffer[ReceiveBufferLen - 2] == '#') {
        ReceiveBuffer[ReceiveBufferLen] = '\0'; // String lezárása
        //trimToNewline(ReceiveBuffer);
        processCommand(ReceiveBuffer);
        ReceiveBufferLen = 0;  // Buffer lenullázása
      }
    } else {
      // Hiba: túl hosszú parancs
      Serial.println("!ERRR:Command too long##");
      ReceiveBufferLen = 0;  // Buffer lenullázása
    }
  }
}

void setup() {
  Serial.begin(9600);
  while (!Serial) {
    ; // Várjuk meg a soros port elindulását
  }
  Serial.println("Device Ready.");
}

void loop() {
  // A parancsok feldolgozása a serialEvent függvényen keresztül történik
}