// // 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; }