// // Created by xemon on 05.05.2022. // #include #include "XfcProtRespondent.h" void XfcProcRespondent_Reset(tXfcProtRespondent *env) { XfcArrayClear(&env->requestBuffer); XfcArrayClear(&env->responseBuffer); } void XfcProtRespondent_Init( tXfcProtRespondent *env, void *commonArgs, tXfcProtTable *processors, tXfcArray requestBuffer, tXfcArray responseBuffer, tXfcProtMagicNumbers magicNumbers ) { env->commonArgs = commonArgs; env->processors = processors; env->requestBuffer = requestBuffer; env->responseBuffer = responseBuffer; env->requestDecoder.magic = magicNumbers.request; env->responseEncoder.magic = magicNumbers.response; env->requestDecoder.buffer = &env->requestBuffer; env->responseEncoder.buffer = &env->responseBuffer; XfcProcRespondent_Reset(env); } void XfcTransPackServiceRespondentAddByte(tXfcProtRespondent *env, uint8_t byte) { if (XfcArrayAddByte(&env->requestBuffer, byte)) { ENV_COUNTER_INC(rx) } else { ENV_COUNTER_INC(rx_skip) } } void XfcProtRespondent_AddBytes(tXfcProtRespondent *env, uint8_t *bytes, uint16_t size) { for (uint8_t *end = bytes + size; end > bytes; ++bytes) { XfcTransPackServiceRespondentAddByte(env, *bytes); } } void XfcTransPackServiceRespondentSkipToNextMagic(tXfcProtRespondent *env, uint16_t begin) { uint16_t skip = XfcTransPackDecoderNextMagicFrom(&env->requestDecoder, begin); XfcArrayRemoveBytesFront(&env->requestBuffer, skip); // ENV_COUNTER_ADD(rx_skip, nextMagic) } bool XfcTransPackServiceRespondentHasPacket(tXfcProtRespondent *env) { while (XfcArrayGetDataSize(&env->requestBuffer)) { if (!XfcTransPackDecoderIsStartsWithMagick(&env->requestDecoder)) { XfcTransPackServiceRespondentSkipToNextMagic(env, 1); continue; } if (!XfcTransPackDecoderHasHeader(&env->requestDecoder)) { return false; } if (XfcTransPackDecoderGetRequiredFullPackLength(&env->requestDecoder) > env->requestBuffer.limit) { ////Packet size bigger than buffer XfcTransPackServiceRespondentSkipToNextMagic(env, 1); continue; } if (!XfcTransPackDecoderHasRequiredLength(&env->requestDecoder)) { return false; } if (XfcTransPackDecoderIsCrcCorrect(&env->requestDecoder)) { return true; } else { XfcTransPackServiceRespondentSkipToNextMagic(env, 1); continue; } } return false; } void XfcTransPackServiceRespondentProcessRequest(tXfcProtRespondent *env) { uint8_t packId = XfcTransPackDecoderGetId(&env->requestDecoder); tXfcArray requestData = XfcTransPackDecoderGetDataSegmentAsArray(&env->requestDecoder); tXfcArray responseData = XfcTransPackEncoderGetDataSegmentAsArray(&env->responseEncoder); XfcArrayClear(&responseData); tXfcProtProcessor *proc = XfcProtTable_GetForId(env->processors, packId); if (proc) { void *args = proc->args ? proc->args : env->commonArgs; XfcTransPackEncoderSetId(&env->responseEncoder, proc->process(&requestData, &responseData, args)); } else { XfcTransPackEncoderSetId(&env->responseEncoder, XFC_TRANSPORT_PROTOCOL_RESPONSE_RESULT_CMD_UNKNOWN); } XfcTransPackEncoderSetDataSegmentLength(&env->responseEncoder, XfcArrayGetDataSize(&responseData)); XfcTransPackEncoderFinalizeAndSignCrc(&env->responseEncoder); } void XfcProtRespondent_SkipCurrentRequest(tXfcProtRespondent *env) { XfcTransPackServiceRespondentSkipToNextMagic(env, XfcTransPackDecoderGetRequiredFullPackLength(&env->requestDecoder)); } bool XfcProtRespondent_Step(tXfcProtRespondent *env) { if (XfcTransPackServiceRespondentHasPacket(env)) { XfcTransPackServiceRespondentProcessRequest(env); return true; } return false; }