cogito/protocol.cpp

425 lines
9.4 KiB
C++

#include "protocol.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
unsigned long startTime, stopTime, usedTime;
char trattamento[10] = { 0,0,0,0,0,0,0,0,0,0 };
#define UARTBUFFSIZE 128
struct _UartBuffer {
uint8_t buffer[UARTBUFFSIZE];
uint16_t length;
};
typedef struct _UartBuffer UartBuffer;
UartBuffer rxBuffer, txBuffer;
extern int getRemainingTime(void);
extern int sendConsumedTime(uint32_t timeConsumed, const char* treatment);
extern int checkNodeRedConnection(void);
extern int getWifiConn(void);
extern void setWiFi();
extern HardwareSerial comSerial;
void UartBufferInit();
extern uint8_t RXData;
extern bool isEnabled;
extern int timeRem;
void PCmd_TIME(UartBuffer* _response);
void PCmd_STOP(UartBuffer* _response);
void PCmd_STOPNGO(UartBuffer* _response);
void PCmd_WMNGR(UartBuffer* _response);
void PCmd_START(UartBuffer* response, char* _command);
void PCmd_CONS(UartBuffer* response, char* _command);
void PCmd_CONN(UartBuffer* _response);
void PCmd_sendACKCNN();
void PCmd_sendACK();
void PCmdClear(UartBuffer* command) {
memset(command, 0, sizeof(UartBuffer));
}
uint8_t PCmdCheckSumOk(UartBuffer command) {
uint8_t csum = 0;
uint16_t i = 1;
for (i = 1; i < command.length - 2; i++) {
csum = (csum + command.buffer[i]) % 256;// prima era 0xFF;
}
if ((csum == 0) || (csum == 2) || (csum == 3))
csum += 10;
return (command.buffer[command.length - 2] == csum);
}
uint8_t PCmdIsValid(UartBuffer command) {
if ((command.length > 0) && (command.buffer[0] == 2) && (command.buffer[command.length - 1] == 3)) {
return PCmdCheckSumOk(command);
}
return 0;
}
void PCmdFillEnd(UartBuffer* command) {
uint8_t len = 1;
uint8_t csum = 0;
uint8_t* p = &command->buffer[1];
while (*p) {
csum = (csum + *p) % 256;//prima era 0xFF;
len++;
p++;
}
if ((csum == 0) || (csum == 2) || (csum == 3))
csum += 10;
*p = csum;
p++;
*p = 0x03;
command->length = len + 2;
}
void PCmdFillNack(UartBuffer* command) {
PCmdClear(command);
command->buffer[0] = 0x02;
command->buffer[1] = 0x15;
command->buffer[2] = 0x15;
command->buffer[3] = 0x03;
command->length = 4;
}
void PCmdFillAck(UartBuffer* command) {
PCmdClear(command);
command->buffer[0] = 0x02;
command->buffer[1] = 0x06;
command->buffer[2] = 0x06;
command->buffer[3] = 0x03;
command->length = 4;
}
uint8_t PCmdReqResp(UartBuffer request, UartBuffer* response) {
if (PCmdIsValid(request)) {
// char* s_cmd = ext_string(&request.buffer[1], request.length-3);
char* s_cmd = (char*)malloc(request.length - 3 + 1);
memset(s_cmd, 0, request.length - 3 + 1);
memcpy(s_cmd, &request.buffer[2], request.length - 4); //in origine era [1] e [-4]
if (strncmp(s_cmd, "AL", 2) == 0) { // ## alive
//PCmdFillAck(response);
PCmd_sendACK();
}
else
if (strncmp(s_cmd, "TIME", 4) == 0) { //
PCmd_TIME(response);
}
else
if (strncmp(s_cmd, "STOP", 4) == 0) { //
PCmd_STOP(response);
}
else
if (strncmp(s_cmd, "START", 5) == 0) { //
PCmd_START(response, s_cmd);
}
else
if (strncmp(s_cmd, "CONS", 4) == 0) { //
PCmd_CONS(response, s_cmd);
}
else
if (strncmp(s_cmd, "STONGO", 6) == 0) { // STOP'N'GO
PCmd_STOPNGO(response);
}
else
if (strncmp(s_cmd, "WMNGR", 5) == 0) { //
PCmd_WMNGR(response);
}
else
if (strncmp(s_cmd, "CONN", 4) == 0) { //
PCmd_CONN(response);
}
else {
PCmdFillNack(response);
}
free(s_cmd);
}
else {
PCmdFillNack(response);
}
return 0;
}
void UartTransmit(UartBuffer command) {
comSerial.write(command.buffer, command.length);
/* for (int j =0;j<command.length; j++){
Serial.println(command.buffer[j],HEX);
}
*/
}
uint8_t UartRxBufferEmpty() {
return (rxBuffer.length == 0);
}
void UartRxBufferClear() {
memset(&rxBuffer, 0, sizeof(UartBuffer));
}
void UartTxBufferClear() {
memset(&txBuffer, 0, sizeof(UartBuffer));
}
void UartBufferInit() {
UartRxBufferClear();
UartTxBufferClear();
}
void UartRxBufferDecode() {
UartTxBufferClear();
if (!UartRxBufferEmpty()) {
PCmdReqResp(rxBuffer, &txBuffer);
UartTransmit(txBuffer);
}
UartRxBufferClear();
}
uint8_t IsSTX(uint8_t data) {
return (data == 0x02);
}
uint8_t IsETX(uint8_t data) {
return (data == 0x03);
}
uint8_t LastByteIsETXinRxBuffer() {
return (IsETX(rxBuffer.buffer[rxBuffer.length - 1]));
}
void checkComData() {
if (IsSTX(RXData)) {
rxBuffer.length = 0;
}
rxBuffer.buffer[rxBuffer.length++] = RXData;
if (LastByteIsETXinRxBuffer()) {
UartRxBufferDecode();
}
}
void PCmd_STOP(UartBuffer* _response) {
stopTime = millis();
Serial.println("STOP: ");
usedTime = (stopTime - startTime) / 1000;
Serial.println(usedTime);
if (sendConsumedTime(usedTime, trattamento) == 0) {
PCmd_sendACKCNN();
}
//PCmdClear(command);
// PCmdFillAck(_response);
}
void PCmd_STOPNGO(UartBuffer* _response) {
stopTime = millis();
Serial.println("STOP'N'GO: ");
usedTime = (stopTime - startTime) / 1000;
Serial.println(usedTime);
startTime = millis();
if (sendConsumedTime(usedTime, trattamento) == 0) {
PCmd_sendACKCNN();
}
//PCmdClear(command);
// PCmdFillAck(_response);
}
void PCmd_TIME(UartBuffer* _response) {
_response = &txBuffer;
int j;
// int time=0;
if (getRemainingTime() != 0) {
timeRem = 0;
}
// Serial.print("time: ");
// Serial.println(timeRem);
UartTxBufferClear();
PCmdClear(_response);
_response->buffer[0] = 0x02;
j = sprintf((char*)&(_response->buffer[2]), "TME:%lu:%d/", timeRem, isEnabled);
_response->buffer[1] = j; //dimensione del solo payload
PCmdFillEnd(_response);
//UartTransmit(txBuffer);
}
void PCmd_START(UartBuffer* response, char* _command) {
startTime = millis();
Serial.println("START");
// uint8_t result = 1;
char* token;
char delimiters[3] = "/:";
// get the first token
token = strtok(_command, delimiters);
// walk through other tokens
while (token != NULL) {
if (strcmp(token, "START") == 0) {
token = strtok(NULL, delimiters);
strcpy((char*)trattamento, token);
//trattamento=atoi(token);
}
token = strtok(NULL, delimiters);
}
Serial.print("trattamento: ");
Serial.println(trattamento);
/*
if (result){
PCmdFillAck(response);
}
else
PCmdFillNack(response);
*/
}
void PCmd_CONS(UartBuffer* response, char* _command) {
// startTime=millis();
// uint8_t result = 1;
char* token;
char delimiters[3] = "/:";
// get the first token
token = strtok(_command, delimiters);
// walk through other tokens
while (token != NULL) {
if (strcmp(token, "CONS") == 0) {
token = strtok(NULL, delimiters);
usedTime = atol(token);
token = strtok(NULL, delimiters);
strcpy((char*)trattamento, token);
}
token = strtok(NULL, delimiters);
}
Serial.print("CONS-> ");
Serial.print(" Tempo consumato: ");
Serial.print(usedTime);
Serial.print(" Trattamento: ");
Serial.println(trattamento);
if (sendConsumedTime(usedTime, trattamento) == 0) {
PCmd_sendACKCNN();
}
}
void PCmd_CONN(UartBuffer* _response) {
/* extern const char* username;
extern const char* devicePassword;
extern const char* serverURL_getRemaining;
*/
_response = &txBuffer;
int connection = 0;
int j;
UartTxBufferClear();
PCmdClear(_response);
_response->buffer[0] = 0x02;
if (getWifiConn() == 0) {
connection = 1;
if (checkNodeRedConnection()) {
connection = 2;
}
}
j = sprintf((char*)&(_response->buffer[2]), "CNN:%d/", connection);
_response->buffer[1] = j; //dimensione del solo payload
PCmdFillEnd(_response);
//UartTransmit(txBuffer);
}
void PCmd_WMNGR(UartBuffer* _response) {
Serial.println("WiFi MANAGER");
setWiFi();
}
void PCmd_refreshCONN(int connection) {
/* extern const char* username;
extern const char* devicePassword;
extern const char* serverURL_getRemaining;
*/
UartBuffer* _response = &txBuffer;
int j;
UartTxBufferClear();
PCmdClear(_response);
_response->buffer[0] = 0x02;
j = sprintf((char*)&(_response->buffer[2]), "CNN:%d/", connection);
_response->buffer[1] = j; //dimensione del solo payload
PCmdFillEnd(_response);
UartTransmit(txBuffer);
}
void PCmd_sendACKCNN() {
/* extern const char* username;
extern const char* devicePassword;
extern const char* serverURL_getRemaining;
*/
UartBuffer* _response = &txBuffer;
int j;
UartTxBufferClear();
PCmdClear(_response);
_response->buffer[0] = 0x02;
j = sprintf((char*)&(_response->buffer[2]), "ACKCNN/");
_response->buffer[1] = j; //dimensione del solo payload
PCmdFillEnd(_response);
UartTransmit(txBuffer);
}
void PCmd_sendACK() {
/* extern const char* username;
extern const char* devicePassword;
extern const char* serverURL_getRemaining;
*/
UartBuffer* _response = &txBuffer;
int j;
UartTxBufferClear();
PCmdClear(_response);
_response->buffer[0] = 0x02;
j = sprintf((char*)&(_response->buffer[2]), "ACK/");
_response->buffer[1] = j; //dimensione del solo payload
PCmdFillEnd(_response);
UartTransmit(txBuffer);
}