// // Created by zemon on 23.12.2021. // #include "SystemDelayInterface.h" #include #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); }