282 lines
9.2 KiB
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;
|
|
} |