Legacy_EgtsEncoderDecoder/Src/egtsWorkerExt.c

282 lines
9.2 KiB
C

//
// Created by cfif on 18.05.2024.
//
#include "egtsWorkerExt.h"
#include "egts_crc.h"
#include "string.h"
#define EGTS_STATIC_HEADER_EXT_LENGTH 11
bool EgtsParseHeaderExt(EgtsWorkerEnvironment *env) {
// uint8_t protocol;
// uint8_t SecKeyID;
// uint8_t flags;
// uint16_t length;
// uint8_t encoding;
// uint16_t id;
// uint8_t type;
// uint8_t crc;
env->header.protocol = *env->workingBuffer;
env->header.SecKeyID = *(env->workingBuffer + 1);
env->header.flags = *(env->workingBuffer + 2);
env->header.headerLength = *(uint8_t *) (env->workingBuffer + 3);
env->header.encoding = *(env->workingBuffer + 4);
env->header.frameDataLength = *(uint16_t *) (env->workingBuffer + 5);
env->header.packetId = *(uint16_t *) (env->workingBuffer + 7);
env->header.type = *(uint8_t *) (env->workingBuffer + 9);
env->header.crc = *(env->workingBuffer + 10);
if (env->header.protocol != 1)
return false;
uint8_t crc = CRC8EGTS((uint8_t *) &env->header, 10);//Header CRC
if (crc != env->header.crc)
return false;
return true;
}
void EgtsParseSrvSubRecordSrCommandExt(EgtsWorkerEnvironment *env) {
uint16_t inRecOffset = 0;
env->srCommand->cmdType = *((uint8_t *) env->subRecData + inRecOffset) >> 0x4;
env->srCommand->cmdConfirmationType = *((uint8_t *) env->subRecData + inRecOffset) & 0b1111;
inRecOffset += 1;
env->srCommand->cmdId = *((uint32_t *) (env->subRecData + inRecOffset));
inRecOffset += 4;
env->srCommand->srcId = *((uint32_t *) (env->subRecData + inRecOffset));
inRecOffset += 4;
uint8_t flags = *((uint8_t *) (env->subRecData + inRecOffset));
inRecOffset += 1;
env->srCommand->hasCharset = flags & 0b1;
env->srCommand->hasAuth = (flags >> 0x1) & 0b1;
if (env->srCommand->hasCharset) {
env->srCommand->charset = *((uint8_t *) (env->subRecData + inRecOffset));
inRecOffset += 1;
}
if (env->srCommand->hasAuth) {
env->srCommand->authLen = *((uint8_t *) (env->subRecData + inRecOffset));
inRecOffset += 1;
memcpy(env->srCommand->auth, (env->subRecData + inRecOffset), env->srCommand->authLen);
inRecOffset += env->srCommand->authLen;
}
env->srCommand->address = *((uint16_t *) (env->subRecData + inRecOffset));
inRecOffset += 2;
uint8_t actFlags = *((uint8_t *) (env->subRecData + inRecOffset));
inRecOffset += 1;
env->srCommand->act = actFlags & 0xF;
env->srCommand->size = (actFlags >> 0x4) & 0xF;
env->srCommand->cmd = *((uint16_t *) (env->subRecData + inRecOffset));
inRecOffset += 2;
env->srCommand->dataPointer = (env->subRecData + inRecOffset);
}
void EgtsParseSrvSubRecordFirmwareExt(EgtsWorkerEnvironment *env) {
uint16_t inRecOffset = 0;
env->firmware->Identity = *((uint16_t *) (env->subRecData + inRecOffset));
inRecOffset += 2;
env->firmware->PartNumber = *((uint16_t *) (env->subRecData + inRecOffset));
inRecOffset += 2;
env->firmware->ExpectedPartsQuantity = *((uint16_t *) (env->subRecData + inRecOffset));
inRecOffset += 2;
if (env->firmware->PartNumber == 1) {
uint8_t OA = *((uint8_t *) (env->subRecData + inRecOffset));
((uint8_t *) ((uint8_t *) &env->firmware->ObjectAttribute))[0] = OA;
inRecOffset += 1;
env->firmware->ComponentOrModuleIdentifier = *((uint8_t *) (env->subRecData + inRecOffset));
inRecOffset += 1;
env->firmware->Version = *((uint16_t *) (env->subRecData + inRecOffset));
inRecOffset += 2;
env->firmware->WholeObjectSignature = *((uint16_t *) (env->subRecData + inRecOffset));
inRecOffset += 2;
for (size_t i = 0; i < 64 + 1; ++i) {
env->firmware->FileName[i] = *((uint8_t *) (env->subRecData + inRecOffset));
inRecOffset += 1;
if (env->firmware->FileName[i] == 0)
break;
}
}
env->firmware->dataPointer = env->subRecData + inRecOffset;
env->firmware->dataLength = env->subRecLength - inRecOffset;
}
void EgtsParseSrvSubRecordExt(EgtsWorkerEnvironment *env, uint8_t *subRecRaw) {
env->subRecType = subRecRaw[0];
env->subRecLength = *((uint16_t *) (subRecRaw + 1));
env->subRecData = subRecRaw + 3;
env->srNotificationData = NULL;
env->srCommand = NULL;
if (env->recSourceService == EGTS_COMMANDS_SERVICE) {
env->srCommand = &env->subRecMemAlloc.cmd;
EgtsParseSrvSubRecordSrCommandExt(env);
} else if (env->recSourceService == EGTS_FIRMWARE_SERVICE) {
env->firmware = &env->subRecMemAlloc.firmware;
EgtsParseSrvSubRecordFirmwareExt(env);
} else if (env->recSourceService == EGTS_NOTIFICATION_SERVICE) {
switch (env->subRecType) {
case EGTS_SR_NOTIFICATION_DATA:
env->srNotificationData = &env->subRecMemAlloc.notificationData;
EgtsParseSrvNotificationData(env->subRecData, env->srNotificationData);
break;
case EGTS_SR_NOTIFICATION_FULL_DATA:
// LOG("EGTS_SR_NOTIFICATION_FULL_DATA")
break;
}
} else {
// LOG("UNKNOWN EGTS SERVICE, CODE: ")
}
}
uint16_t EgtsParseSrvRecordExt(EgtsWorkerEnvironment *env, uint8_t *record) {
env->recordLength = *((uint16_t *) record);
env->recordNumber = *((uint16_t *) (record + 2));
env->recordFlags = record[4];
env->recHasTime = env->recordFlags & 0b00000100 ? true : false;
env->recHasEvent = env->recordFlags & 0b00000010 ? true : false;
env->recHasObj = env->recordFlags & 0b00000001 ? true : false;
uint8_t variableOffset = (env->recHasTime ? 4 : 0) + (env->recHasEvent ? 4 : 0) + (env->recHasObj ? 4 : 0);
env->recSourceService = record[5 + variableOffset];
env->recRecipientService = record[6 + variableOffset];
env->recordData = record + 7 + variableOffset;
EgtsParseSrvSubRecordExt(env, env->recordData);
// 3 - env->subRecType + env->subRecLength
return 7 + variableOffset + 3 + env->subRecLength;
}
EgtsCompleteResult egtsCompleteResult;
EgtsCompleteResult *EgtsCompleteTransportExt(EgtsWorkerEnvironment *env) {
uint16_t read;
if (env->workingBufferLength < EGTS_STATIC_HEADER_EXT_LENGTH) {
read = env->readData(
env->readDataEnv,
env->workingBuffer + env->workingBufferLength,
EGTS_STATIC_HEADER_EXT_LENGTH - env->workingBufferLength
);
env->workingBufferLength += read;
if (env->workingBufferLength < EGTS_STATIC_HEADER_EXT_LENGTH) {
egtsCompleteResult.completeResult = EGTS_COMPLETE_WAIT;
return &egtsCompleteResult;
}
if (env->workingBuffer[0] != 1) {
env->workingBufferLength = 0;
egtsCompleteResult.completeResult = EGTS_COMPLETE_ERR_VER;
return &egtsCompleteResult;
}
uint8_t crc = CRC8EGTS(env->workingBuffer, EGTS_STATIC_HEADER_EXT_LENGTH - 1); //Header CRC
if (crc != env->workingBuffer[EGTS_STATIC_HEADER_EXT_LENGTH - 1]) {
env->workingBufferLength = 0;
egtsCompleteResult.calcHeaderCrc = crc;
egtsCompleteResult.receivedHeaderCrc = env->workingBuffer[EGTS_STATIC_HEADER_EXT_LENGTH - 1];
egtsCompleteResult.completeResult = EGTS_COMPLETE_HEADER_ERR_CRC;
return &egtsCompleteResult;
}
}
uint16_t fullLength = EgtsGetTransportFullLength(env);
// Переполнение приемного буфера
if ((env->workingBufferLength + fullLength) >= env->workingBufferLimit) {
egtsCompleteResult.completeResult = EGTS_COMPLETE_ERR_OVERFLOW;
env->workingBufferLength = 0;
return &egtsCompleteResult;
}
if (env->workingBufferLength < fullLength) {
read = env->readData(
env->readDataEnv,
env->workingBuffer + env->workingBufferLength,
fullLength - env->workingBufferLength
);
env->workingBufferLength += read;
if (env->workingBufferLength < fullLength) {
egtsCompleteResult.completeResult = EGTS_COMPLETE_WAIT;
return &egtsCompleteResult;
}
uint16_t crc = CRC16EGTS(env->workingBuffer + EGTS_STATIC_HEADER_EXT_LENGTH,
fullLength - EGTS_STATIC_HEADER_EXT_LENGTH - 2);
uint16_t crcBody = *(uint16_t *) &env->workingBuffer[fullLength - 2];
if (crc != crcBody) {
env->workingBufferLength = 0;
egtsCompleteResult.fullLength = fullLength;
egtsCompleteResult.calcBodyCrc = crc;
egtsCompleteResult.receivedBodyCrc = crcBody;
egtsCompleteResult.completeResult = EGTS_COMPLETE_BODY_ERR_CRC;
return &egtsCompleteResult;
}
}
egtsCompleteResult.completeResult = EGTS_COMPLETE_OK;
return &egtsCompleteResult;
}
eEgts_CompleteResult EgtsIsTransportCompleteExt(EgtsWorkerEnvironment *env) {
if (env->workingBufferLength < EGTS_STATIC_HEADER_EXT_LENGTH) {
return EGTS_COMPLETE_WAIT;
}
uint16_t fullLength = EgtsGetTransportFullLength(env);
if (env->workingBufferLength < fullLength) {
return EGTS_COMPLETE_WAIT;
}
return EGTS_COMPLETE_OK;
}