Legacy_EgtsEncoderDecoder/Src/egtsWorker.c

290 lines
9.0 KiB
C

//
// Created by zemon on 23.12.2021.
//
#include "SystemDelayInterface.h"
#include <egts.h>
#include "egtsWorker.h"
#include "string.h"
//bool EgtsWorkerLoadPreBuffer(EgtsWorkerEnvironment *env, uint8_t *data, uint16_t dataLength) {
//
// uint8_t *data_end = data + dataLength;
// uint32_t END = HAL_GetTick() + 10000;
//
// while (data != data_end) {
// xQueueSend(env->xQueueRxData, data, 1);
// ++data;
//
// if(END < HAL_GetTick()){
// return false;
// }
// }
//
// return true;
//
//}
//
//bool EgtsWorkerReadPreBuffer(EgtsWorkerEnvironment *env, uint8_t *data) {
// return xQueueReceive(env->xQueueRxData, data, 0) != pdTRUE ? false : true;
//}
#define EGTS_STATIC_HEADER_LENGTH 10
uint8_t EgtsGetTransportHeaderLength(EgtsWorkerEnvironment *env) {
return env->workingBuffer[3];
}
void EgtsResetBuffer(EgtsWorkerEnvironment *env) {
memset(env->workingBuffer, 0, env->workingBufferLength);
memset(&env->subRecMemAlloc, 0, sizeof(EgtsSubRecMemAlloc));
memset(&env->header, 0, sizeof(EgtsHeader));
memset(&env->ptResponse, 0, sizeof(EgtsPtResponse));
env->srNotificationData = NULL;
env->srCommand = NULL;
env->workingBufferLength = 0;
}
uint16_t EgtsGetTransportFrameDataLength(EgtsWorkerEnvironment *env) {
return *((uint16_t *) (env->workingBuffer + 5));
}
uint16_t EgtsGetTransportFullLength(EgtsWorkerEnvironment *env) {
env->headerLength = EgtsGetTransportHeaderLength(env);
env->frameDataLength = EgtsGetTransportFrameDataLength(env);
env->frameDataSrcLength = (env->frameDataLength > 0) ? 2 : 0;
return env->headerLength + env->frameDataLength + env->frameDataSrcLength;
}
bool EgtsCompleteTransport(EgtsWorkerEnvironment *env) {
size_t read = env->readData(
env->readDataEnv,
env->workingBuffer + env->workingBufferLength,
EGTS_STATIC_HEADER_LENGTH - env->workingBufferLength
);
env->workingBufferLength += read;
if (env->workingBufferLength < EGTS_STATIC_HEADER_LENGTH) {
return false;
}
uint16_t fullLength = EgtsGetTransportFullLength(env);
read = env->readData(
env->readDataEnv,
env->workingBuffer + env->workingBufferLength,
fullLength - env->workingBufferLength
);
env->workingBufferLength += read;
if (env->workingBufferLength < fullLength) {
return false;
}
return true;
}
bool EgtsIsTransportComplete(EgtsWorkerEnvironment *env) {
if (env->workingBufferLength < EGTS_STATIC_HEADER_LENGTH) {
return false;
}
uint16_t fullLength = EgtsGetTransportFullLength(env);
if (env->workingBufferLength < fullLength) {
return false;
}
return true;
}
void EgtsParseHeader(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);
}
void EgtsParseFrameData(EgtsWorkerEnvironment *env) {
env->frameData = env->workingBuffer + env->headerLength;
if (env->header.type == EGTS_PT_RESPONSE) {
env->ptResponse.responsePacketId = *(uint16_t *) (env->frameData);
env->ptResponse.status = *(env->frameData + 2);
env->record = (env->frameData + 3);
} else {
env->record = env->frameData;
}
}
void EgtsParseSrvSubRecordSrCommand(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;
if (env->srCommand->cmd == EGTS_SEND_ACCIDENT_DATA) {
env->srCommand->data.next.profile = *((bool *) (env->subRecData + inRecOffset));
inRecOffset += 1;
} else if (env->srCommand->cmd == EGTS_START_SEND_READY) {
env->srCommand->data.next.enabled = *((uint32_t *) (env->subRecData + inRecOffset));
inRecOffset += 4;
} else if (env->srCommand->cmd == EGTS_ECALL_MSD_REQ) {
env->srCommand->data.msdReq.mid = *((int32_t *) (env->subRecData + inRecOffset));
inRecOffset += 4;
env->srCommand->data.msdReq.transport = *((uint8_t *) (env->subRecData + inRecOffset));
} else if (env->srCommand->cmd == EGTS_ECALL_REQ) {
env->srCommand->data.ecallReq.reqType = *((uint8_t *) (env->subRecData + inRecOffset));
inRecOffset += 1;
} else if ((env->srCommand->cmd == EGTS_ECALL_TEST_NUMBER) ||
(env->srCommand->cmd == EGTS_ECALL_SMS_FALLBACK_NUMBER)) {
tString32 *number = &env->srCommand->data.newFallbackNumber;
number->length = env->subRecLength - inRecOffset;
memcpy(number->data, env->subRecData + inRecOffset, number->length);
inRecOffset += number->length;
} else if (env->srCommand->cmd == EGTS_FLEET_MAX_SPEED_THRESHOLD) {
int32_t *arr = env->srCommand->data.arr;
memcpy(arr, env->subRecData + inRecOffset, 5 * 4);
inRecOffset += (5 * 4);
}
}
void EgtsParseSrvNotificationData(uint8_t *rec, EgtsSrNotificationData *notificationData) {
notificationData->flags = rec[0];
notificationData->count = rec[1];
if (notificationData->count) {
memcpy((uint8_t *) notificationData->notifications, rec + 2, (notificationData->count * 2));
}
uint8_t afterArray = (notificationData->count * 2) + 2;
notificationData->storeHours = rec[afterArray + 0];
notificationData->repeatCount = rec[afterArray + 1];
notificationData->repeatIntervalMin = rec[afterArray + 2];
}
void EgtsParseSrvSubRecord(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;
EgtsParseSrvSubRecordSrCommand(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: ")
}
}
void EgtsParseSrvRecord(EgtsWorkerEnvironment *env) {
env->recordLength = *((uint16_t *) env->record);
env->recordNumber = *((uint16_t *) (env->record + 2));
env->recordFlags = env->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 = env->record[5 + variableOffset];
env->recRecipientService = env->record[6 + variableOffset];
env->recordData = env->record + 7 + variableOffset;
EgtsParseSrvSubRecord(env, env->recordData);
}