297 lines
9.3 KiB
C
297 lines
9.3 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_МАХ_SPEED_THRESHOLD) {
|
||
|
||
int32_t *arr = env->srCommand->data.arr;
|
||
|
||
memcpy(arr, env->subRecData + inRecOffset, 5 * 4);
|
||
|
||
inRecOffset += (5 * 4);
|
||
} else if (env->srCommand->cmd == EGTS_UPDATE_SOFTWARE) {
|
||
tString32 *ServerInfo = &env->srCommand->data.updateServerInfo;
|
||
|
||
ServerInfo->length = env->subRecLength - inRecOffset;
|
||
memcpy(ServerInfo->data, env->subRecData + inRecOffset, ServerInfo->length);
|
||
|
||
inRecOffset += ServerInfo->length;
|
||
}
|
||
}
|
||
|
||
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);
|
||
}
|