XfcTransportProtocol/Src/XfcProtRespondent.c

151 lines
4.1 KiB
C

//
// Created by CFIF on 05.05.2022.
//
#include <XfcProtResponseCodes.h>
#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);
tXfcTransportProtocolResponseCode responseCode;
tXfcProtProcessor *proc = XfcProtTable_GetForId(env->processors, packId);
if (proc) {
void *args = proc->args ? proc->args : env->commonArgs;
responseCode = proc->process(&requestData, &responseData, args);
if (responseCode != XFC_TRANSPORT_PROTOCOL_RESPONSE_RESULT_OK) {
XfcArrayClear(&responseData);
}
} else {
responseCode = XFC_TRANSPORT_PROTOCOL_RESPONSE_RESULT_CMD_UNKNOWN;
}
XfcTransPackEncoderSetId(&env->responseEncoder, responseCode);
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;
}