290 lines
9.0 KiB
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);
|
|
}
|