Начало
This commit is contained in:
commit
c67082cbc0
|
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// Created by xemon on 20.04.2022.
|
||||
//
|
||||
|
||||
#ifndef XfcArray_H
|
||||
#define XfcArray_H
|
||||
|
||||
#include "stdint.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t *data;
|
||||
uint16_t begin;
|
||||
uint16_t end;
|
||||
uint16_t limit;
|
||||
} tXfcArray;
|
||||
|
||||
|
||||
#define XfcArrayCreateStatic(NAME, LENGTH) \
|
||||
uint8_t NAME##_Data[LENGTH]; \
|
||||
XfcArray NAME = { .data = NAME##_Data, .begin= 0, .end = 0, .limit = sizeof(NAME##_Data)};
|
||||
|
||||
void XfcArrayInit(tXfcArray *array, uint8_t *memAlloc, uint16_t limit);
|
||||
|
||||
#define XfcArrayInitStatic(ENV, MEM) XfcArrayInit(ENV,MEM,sizeof(MEM))
|
||||
|
||||
void XfcArrayClear(tXfcArray *array);
|
||||
|
||||
bool XfcArrayNotFull(tXfcArray *array);
|
||||
|
||||
uint16_t XfcArrayGetDataSize(tXfcArray *array);
|
||||
|
||||
uint8_t *XfcGetTail(tXfcArray *array);
|
||||
|
||||
bool XfcArrayAddByte(tXfcArray *array, uint8_t value);
|
||||
|
||||
uint16_t XfcArrayAddBytes(tXfcArray *array, uint8_t *bytes, uint16_t length);
|
||||
|
||||
uint16_t XfcArrayAddLength(tXfcArray *array, uint16_t length);
|
||||
|
||||
uint16_t XfcArrayGetSpace(tXfcArray *array);
|
||||
|
||||
uint16_t XfcArrayGetBytesFront(tXfcArray *array, uint8_t *bytes, uint16_t length);
|
||||
|
||||
void XfcArrayRemoveBytesFront(tXfcArray *env, uint16_t count);
|
||||
|
||||
#endif //XfcArray_H
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// Created by xemon on 20.04.2022.
|
||||
//
|
||||
|
||||
#ifndef XFC_COUNTING_H
|
||||
#define XFC_COUNTING_H
|
||||
|
||||
|
||||
#define COUNTER_INC(COUNTER) ++COUNTER;
|
||||
#define COUNTER_ADD(COUNTER, VALUE) COUNTER += VALUE;
|
||||
#define COUNTER_ADD_IF(EXPRESION, COUNTER, VALUE) if(EXPRESION){COUNTER += VALUE;}
|
||||
|
||||
#define ENV_COUNTER_INC(COUNTER) COUNTER_INC(env->counters.COUNTER)
|
||||
#define ENV_COUNTER_ADD(COUNTER, VALUE) COUNTER_ADD(env->counters.COUNTER, VALUE)
|
||||
#define ENV_COUNTER_ADD_IF(EXPRESION, COUNTER, VALUE) COUNTER_ADD_IF(EXPRESION, env->counters.COUNTER, VALUE)
|
||||
|
||||
#define COUNTER_RESET(COUNTER) COUNTER = 0;
|
||||
|
||||
#endif //XFC_COUNTING_H
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// Created by cfif on 11.10.22.
|
||||
//
|
||||
|
||||
#ifndef UVEOS_ON_NATION_XFCTRANSPACKCOMMON_H
|
||||
#define UVEOS_ON_NATION_XFCTRANSPACKCOMMON_H
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
|
||||
#define XFC_TRANSPORT_HEADER_LEN 5
|
||||
#define XFC_TRANSPORT_COMMAND_ID_OFFSET 1
|
||||
#define XFC_TRANSPORT_DATA_LEN_OFFSET 3
|
||||
#define XFC_TRANSPORT_CRC_LEN 2
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t request;
|
||||
uint8_t response;
|
||||
} tXfcProtMagicNumbers;
|
||||
|
||||
extern const tXfcProtMagicNumbers XFC_STD_MAGIC_NUMBERS;
|
||||
|
||||
|
||||
////Mandatory request codes
|
||||
//const uint16_t XFC_PROT_CMD_CODE_NULL = 0x0;
|
||||
//const uint16_t XFC_PROT_CMD_CODE_PING = 0x1;
|
||||
//const uint16_t XFC_PROT_CMD_CMD_TABLE = 0x2;
|
||||
|
||||
#endif //UVEOS_ON_NATION_XFCTRANSPACKCOMMON_H
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
//
|
||||
// Created by xemon on 05.05.2022.
|
||||
//
|
||||
|
||||
#ifndef XFCTRANSPACKCRC_H
|
||||
#define XFCTRANSPACKCRC_H
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
uint16_t XfcProtCrc(uint8_t *data, uint16_t length);
|
||||
|
||||
#endif //XFCTRANSPACKCRC_H
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// Created by xemon on 05.05.2022.
|
||||
//
|
||||
|
||||
#ifndef XFCTRANSPORTPACKETPARSER_H
|
||||
#define XFCTRANSPORTPACKETPARSER_H
|
||||
|
||||
#include "stdint.h"
|
||||
#include "stdbool.h"
|
||||
#include "XfcArray.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t magic;
|
||||
tXfcArray *buffer;
|
||||
} tXfcProtDecoder;
|
||||
|
||||
uint16_t XfcTransPackDecoderNextMagicFrom(tXfcProtDecoder *env, uint16_t begin);
|
||||
|
||||
bool XfcTransPackDecoderIsStartsWithMagick(tXfcProtDecoder *env);
|
||||
|
||||
bool XfcTransPackDecoderHasHeader(tXfcProtDecoder *env);
|
||||
|
||||
uint16_t XfcTransPackDecoderGetId(tXfcProtDecoder *env);
|
||||
|
||||
uint16_t XfcTransPackDecoderGetDataSegmentLength(tXfcProtDecoder *env);
|
||||
|
||||
uint16_t XfcTransPackDecoderGetRequiredFullPackLength(tXfcProtDecoder *env);
|
||||
|
||||
bool XfcTransPackDecoderHasRequiredLength(tXfcProtDecoder *env);
|
||||
|
||||
bool XfcTransPackDecoderIsCrcCorrect(tXfcProtDecoder *env);
|
||||
|
||||
tXfcArray XfcTransPackDecoderGetDataSegmentAsArray(tXfcProtDecoder *env);
|
||||
|
||||
|
||||
#endif //XFCTRANSPORTPACKETPARSER_H
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
//
|
||||
// Created by xemon on 05.05.2022.
|
||||
//
|
||||
|
||||
#ifndef PDM_FIR_TEST_XFCTRANSPACKENCODER_H
|
||||
#define PDM_FIR_TEST_XFCTRANSPACKENCODER_H
|
||||
|
||||
#include "stdint.h"
|
||||
#include "stdbool.h"
|
||||
#include "XfcArray.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t magic;
|
||||
tXfcArray *buffer;
|
||||
} tXfcProtEncoder;
|
||||
|
||||
tXfcArray XfcTransPackEncoderGetDataSegmentAsArray(tXfcProtEncoder *env);
|
||||
|
||||
void XfcTransPackEncoderSetId(tXfcProtEncoder *env, uint16_t id);
|
||||
|
||||
void XfcTransPackEncoderSetDataSegmentLength(tXfcProtEncoder *env, uint16_t dataSegmentLength);
|
||||
|
||||
void XfcTransPackEncoderFinalizeAndSignCrc(tXfcProtEncoder *env);
|
||||
|
||||
#endif //PDM_FIR_TEST_XFCTRANSPACKENCODER_H
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
//
|
||||
// Created by xemon on 05.05.2022.
|
||||
//
|
||||
|
||||
#ifndef PDM_FIR_TEST_XFCTRANSPACKLISTNER_H
|
||||
#define PDM_FIR_TEST_XFCTRANSPACKLISTNER_H
|
||||
|
||||
#define XFC_COMINT_COUNTING
|
||||
|
||||
#include "XfcCounting.h"
|
||||
#include "XfcProtDecoder.h"
|
||||
#include "XfcProtProcessor.h"
|
||||
#include "XfcProtTable.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
#ifdef XFC_COMINT_COUNTING
|
||||
struct {
|
||||
uint32_t rx;
|
||||
uint32_t rx_skip;
|
||||
} counters;
|
||||
#endif
|
||||
|
||||
void *commonArgs;
|
||||
|
||||
tXfcProtDecoder requestDecoder;
|
||||
tXfcArray requestBuffer;
|
||||
|
||||
tXfcProtTable *processors;
|
||||
|
||||
} tXfcProtListener;
|
||||
|
||||
//Этот вид обработчика слушает комманды во входном потоке данных
|
||||
//находит обработчик по id, выполняет его, но ответ не посылает (в отличии от Respondent)
|
||||
void XfcProtListener_Init(
|
||||
tXfcProtListener *env,
|
||||
|
||||
void *commonArgs,
|
||||
tXfcProtTable *processors,
|
||||
|
||||
tXfcArray requestBuffer,
|
||||
uint8_t requestMagic
|
||||
);
|
||||
|
||||
bool XfcProtListener_Step(tXfcProtListener *env);
|
||||
|
||||
void XfcProtListener_SkipCurrentRequest(tXfcProtListener *env);
|
||||
|
||||
void XfcProtListener_AddBytes(tXfcProtListener *env, uint8_t *bytes, uint16_t size);
|
||||
|
||||
bool XfcProtListener_isValidHeader(tXfcProtListener *env);
|
||||
|
||||
bool XfcProtListener_HasPacket(tXfcProtListener *env);
|
||||
|
||||
void XfcProtListener_SkipToNextMagic(tXfcProtListener *env, uint16_t begin);
|
||||
|
||||
#endif //PDM_FIR_TEST_XFCTRANSPACKLISTNER_H
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// Created by xemon on 05.05.2022.
|
||||
//
|
||||
|
||||
#ifndef XFCTRANSPACKPROCESSOR_H
|
||||
#define XFCTRANSPACKPROCESSOR_H
|
||||
|
||||
#include "XfcArray.h"
|
||||
|
||||
typedef uint8_t (*tXfcProtMethod)(tXfcArray *requestData, tXfcArray *responseData, void *sub);
|
||||
|
||||
typedef struct {
|
||||
char *textId;
|
||||
uint8_t textIdLen;
|
||||
void *args;
|
||||
tXfcProtMethod process;
|
||||
} tXfcProtProcessor;
|
||||
|
||||
#endif //XFCTRANSPACKPROCESSOR_H
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// Created by xemon on 21.04.2022.
|
||||
//
|
||||
|
||||
#ifndef XFCTRANSPORTPROTOCOLPROCESSORDEFINES_H
|
||||
#define XFCTRANSPORTPROTOCOLPROCESSORDEFINES_H
|
||||
|
||||
#include <XfcProtResponseCodes.h>
|
||||
#include "XfcProtProcessor.h"
|
||||
#include <XfcProtTable.h>
|
||||
#include "stddef.h"
|
||||
|
||||
////Defines for read/write operations inside Packet Processor
|
||||
|
||||
//#define XFC_CMD_TX_SET_CODE(CODE) *response->fields.id = CODE;
|
||||
|
||||
#define XFC_CMD_TX_OVERFLOW() return XFC_TRANSPORT_PROTOCOL_RESPONSE_RESULT_CMD_OVERFLOW;
|
||||
#define XFC_CMD_RX_CUTOFF() return XFC_TRANSPORT_PROTOCOL_REQUEST_UNEXPECTEDLY_SHORT;
|
||||
|
||||
#define XFC_CMD_TX_ADD_WITH_OVERFLOW_CHECK(DATA, LEN) \
|
||||
if(XfcArrayAddBytes(response,DATA, LEN)!=LEN){ XFC_CMD_TX_OVERFLOW()};
|
||||
|
||||
|
||||
#define XFC_CMD_RX_GET_WITH_CUTOFF_CHECK(DATA, LEN) \
|
||||
if(XfcArrayGetBytesFront(request,DATA, LEN)!=LEN){ XFC_CMD_RX_CUTOFF()};
|
||||
|
||||
|
||||
#define XFC_CMD_TX_ADD_STR(str) XFC_CMD_TX_ADD_WITH_OVERFLOW_CHECK((uint8_t*)str, sizeof(str)-1)
|
||||
#define XFC_CMD_TX_ADD_STROBJ(str) XFC_CMD_TX_ADD_WITH_OVERFLOW_CHECK(str->data, str->length)
|
||||
#define XFC_CMD_TX_ADD_RAW(obj) XFC_CMD_TX_ADD_WITH_OVERFLOW_CHECK((uint8_t*)&obj, sizeof(obj))
|
||||
#define XFC_CMD_TX_ADD_ARR(arr, len) XFC_CMD_TX_ADD_WITH_OVERFLOW_CHECK((uint8_t*)arr, len)
|
||||
|
||||
#define XFC_CMD_TX_ADD_STRLINK(str) XFC_CMD_TX_ADD_RAW( *(str).length) XFC_CMD_TX_ADD_ARR((str).data, *(str).length)
|
||||
|
||||
|
||||
#define XFC_CMD_TX_ADD_PSTR(str) {uint8_t len = sizeof(str)-1; XFC_CMD_TX_ADD_RAW(len); XFC_CMD_TX_ADD_STR(str);}
|
||||
|
||||
|
||||
#define XFC_CMD_RX_GET_STR(str) XFC_CMD_RX_GET_WITH_CUTOFF_CHECK((uint8_t*)str, sizeof(str))
|
||||
#define XFC_CMD_RX_GET_RAW(obj) XFC_CMD_RX_GET_WITH_CUTOFF_CHECK((uint8_t*)&obj, sizeof(obj))
|
||||
#define XFC_CMD_RX_GET_ARR(arr, len) XFC_CMD_RX_GET_WITH_CUTOFF_CHECK((uint8_t*)arr, len)
|
||||
|
||||
|
||||
|
||||
//XFC_REQUEST_PROCESSOR_DIRECT
|
||||
#define XFC_REQPROC_DIR(CODE, METHOD) [CODE]={.id=CODE, .process=METHOD}
|
||||
|
||||
|
||||
#endif //XFCTRANSPORTPROTOCOLPROCESSORDEFINES_H
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
//
|
||||
// Created by xemon on 07.11.23.
|
||||
//
|
||||
|
||||
#ifndef MOTOTERMINAL_MAIN_ONAT435_XFCPROTREQUESTER_H
|
||||
#define MOTOTERMINAL_MAIN_ONAT435_XFCPROTREQUESTER_H
|
||||
|
||||
#include "XfcProtDecoder.h"
|
||||
#include "XfcProtEncoder.h"
|
||||
#include "XfcProtResponseCodes.h"
|
||||
#include "SerialPortIO.h"
|
||||
#include "XfcProtCommon.h"
|
||||
|
||||
typedef enum {
|
||||
eXfcProtRequesterStatus_OK = 0,
|
||||
eXfcProtRequesterStatus_UNKNOWN_ERROR,
|
||||
eXfcProtRequesterStatus_REQUEST_BUILD_OVERFLOW,
|
||||
eXfcProtRequesterStatus_TRANSMIT_ERROR,
|
||||
eXfcProtRequesterStatus_RECIVE_BUFFER_OVERFLOW,
|
||||
eXfcProtRequesterStatus_PREFIX_MISMATCH,
|
||||
eXfcProtRequesterStatus_CRC_ERROR,
|
||||
eXfcProtRequesterStatus_RECIVE_TIMEOUT,
|
||||
eXfcProtRequesterStatus_RESPONSE_SHORT,
|
||||
eXfcProtRequesterStatus_BUILD_EXECUTION_ERROR,
|
||||
eXfcProtRequesterStatus_PARSING_EXECUTION_ERROR,
|
||||
} eXfcProtRequesterStatus;
|
||||
|
||||
typedef tXfcTransportProtocolResponseCode (*tXfcRequesterMethod)(void *env, tXfcArray *request);
|
||||
|
||||
typedef struct {
|
||||
|
||||
tSerialPortIO *io;
|
||||
|
||||
tXfcProtDecoder decoder;
|
||||
tXfcProtEncoder encoder;
|
||||
|
||||
tXfcArray requestBuffer;
|
||||
tXfcArray responseBuffer;
|
||||
|
||||
int32_t transmitTimeout;
|
||||
|
||||
} tXfcProtRequester;
|
||||
|
||||
|
||||
void XfcProtRequester_init(
|
||||
tXfcProtRequester *env,
|
||||
|
||||
tSerialPortIO *io,
|
||||
|
||||
tXfcArray requestBuffer,
|
||||
tXfcArray responseBuffer,
|
||||
|
||||
tXfcProtMagicNumbers magicNumbers
|
||||
);
|
||||
|
||||
eXfcProtRequesterStatus XfcProtRequester_makeRequest(
|
||||
tXfcProtRequester *env, uint16_t id,
|
||||
void *builder, tXfcRequesterMethod buildMethod,
|
||||
void *parser, tXfcRequesterMethod parseMethod,
|
||||
int32_t timeout
|
||||
);
|
||||
|
||||
#endif //MOTOTERMINAL_MAIN_ONAT435_XFCPROTREQUESTER_H
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
// Created by xemon on 05.05.2022.
|
||||
//
|
||||
|
||||
#ifndef PDM_FIR_TEST_XFCTRANSPACKRESPONSER_H
|
||||
#define PDM_FIR_TEST_XFCTRANSPACKRESPONSER_H
|
||||
|
||||
#define XFC_COMINT_COUNTING
|
||||
|
||||
#include "XfcCounting.h"
|
||||
#include "XfcProtDecoder.h"
|
||||
#include "XfcProtProcessor.h"
|
||||
#include "XfcProtEncoder.h"
|
||||
#include "XfcProtTable.h"
|
||||
#include "XfcProtCommon.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
#ifdef XFC_COMINT_COUNTING
|
||||
struct {
|
||||
uint32_t rx;
|
||||
uint32_t tx;
|
||||
uint32_t rx_skip;
|
||||
uint32_t tx_skip;
|
||||
} counters;
|
||||
#endif
|
||||
|
||||
void *commonArgs;
|
||||
|
||||
tXfcProtDecoder requestDecoder;
|
||||
tXfcProtEncoder responseEncoder;
|
||||
|
||||
tXfcArray requestBuffer;
|
||||
tXfcArray responseBuffer;
|
||||
|
||||
tXfcProtTable *processors;
|
||||
} tXfcProtRespondent;
|
||||
|
||||
//Этот вид обработчика слушает комманды во входном потоке данных
|
||||
//находит обработчик по id, и возвращает ответ (в отличии от Listener)
|
||||
void XfcProtRespondent_Init(
|
||||
tXfcProtRespondent *env,
|
||||
|
||||
void *commonArgs,
|
||||
tXfcProtTable *processors,
|
||||
|
||||
tXfcArray requestBuffer,
|
||||
tXfcArray responseBuffer,
|
||||
|
||||
tXfcProtMagicNumbers magicNumbers
|
||||
);
|
||||
|
||||
bool XfcProtRespondent_Step(tXfcProtRespondent *env);
|
||||
|
||||
void XfcProtRespondent_SkipCurrentRequest(tXfcProtRespondent *env);
|
||||
|
||||
void XfcProtRespondent_AddBytes(tXfcProtRespondent *env, uint8_t *bytes, uint16_t size);
|
||||
|
||||
#endif //PDM_FIR_TEST_XFCTRANSPACKRESPONSER_H
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
//
|
||||
// Created by xemon on 21.04.2022.
|
||||
//
|
||||
|
||||
#ifndef XFCTRANSPORTPROTOCOLRESPONSECODES_H
|
||||
#define XFCTRANSPORTPROTOCOLRESPONSECODES_H
|
||||
|
||||
typedef enum {
|
||||
XFC_TRANSPORT_PROTOCOL_RESPONSE_RESULT_OK = 0x01,
|
||||
XFC_TRANSPORT_PROTOCOL_RESPONSE_RESULT_EXECUTION_ERROR = 0x02,
|
||||
XFC_TRANSPORT_PROTOCOL_RESPONSE_RESULT_CMD_UNKNOWN = 0x03,
|
||||
XFC_TRANSPORT_PROTOCOL_RESPONSE_RESULT_CMD_OVERFLOW = 0x04,
|
||||
XFC_TRANSPORT_PROTOCOL_REQUEST_UNEXPECTEDLY_SHORT = 0x05,
|
||||
} tXfcTransportProtocolResponseCode;
|
||||
|
||||
#endif //XFCTRANSPORTPROTOCOLRESPONSECODES_H
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
//
|
||||
// Created by xemon on 01.11.22.
|
||||
//
|
||||
|
||||
#ifndef XFC_TRANSPORT_PROTOCOL_XFCPROTTABLE_H
|
||||
#define XFC_TRANSPORT_PROTOCOL_XFCPROTTABLE_H
|
||||
|
||||
#include "XfcProtProcessor.h"
|
||||
|
||||
typedef struct {
|
||||
tXfcProtProcessor *items;
|
||||
uint16_t count;
|
||||
uint16_t limit;
|
||||
} tXfcProtTable;
|
||||
|
||||
void XfcProtTable_Init(tXfcProtTable *env, tXfcProtProcessor *allocatedMem, uint16_t memLimit);
|
||||
|
||||
#define XfcProtTable_InitStatic(ENV, MEM) XfcProtTable_Init(ENV,MEM, sizeof(MEM) / sizeof(tXfcProtProcessor))
|
||||
|
||||
bool XfcProtTable_Add(
|
||||
tXfcProtTable *env,
|
||||
char *staticStringTextId,
|
||||
uint8_t textIdLen,
|
||||
tXfcProtMethod method,
|
||||
void *args
|
||||
);
|
||||
|
||||
#define XfcProtTable_AddStatic(ENV, TEXT_ID, METHOD, ARGS) XfcProtTable_Add(ENV, TEXT_ID,sizeof(TEXT_ID)-1,(tXfcProtMethod)METHOD, ARGS)
|
||||
|
||||
tXfcProtProcessor *XfcProtTable_GetForId(tXfcProtTable *env, uint16_t id);
|
||||
|
||||
|
||||
#endif //XFC_TRANSPORT_PROTOCOL_XFCPROTTABLE_H
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
//
|
||||
// Created by xemon on 20.04.2022.
|
||||
//
|
||||
#include <string.h>
|
||||
#include "XfcArray.h"
|
||||
|
||||
void XfcArrayInit(tXfcArray *array, uint8_t *memAlloc, uint16_t limit) {
|
||||
array->limit = limit;
|
||||
array->data = memAlloc;
|
||||
array->end = 0;
|
||||
array->begin = 0;
|
||||
}
|
||||
|
||||
void XfcArrayClear(tXfcArray *array) {
|
||||
array->end = 0;
|
||||
array->begin = 0;
|
||||
}
|
||||
|
||||
bool XfcArrayNotFull(tXfcArray *array) {
|
||||
return array->end < array->limit;
|
||||
}
|
||||
|
||||
|
||||
uint16_t XfcArrayGetDataSize(tXfcArray *array) {
|
||||
if (array->begin >= array->end) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return array->end - array->begin;
|
||||
}
|
||||
|
||||
uint8_t *XfcGetTail(tXfcArray *array) {
|
||||
return array->data + array->end;
|
||||
}
|
||||
|
||||
uint16_t XfcArrayGetSpace(tXfcArray *array) {
|
||||
if (array->limit <= array->end) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return array->limit - array->end;
|
||||
}
|
||||
|
||||
uint16_t XfcArrayGetAvailable(tXfcArray *array) {
|
||||
if (array->limit <= array->end) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return array->limit - array->end;
|
||||
}
|
||||
|
||||
|
||||
bool XfcArrayAddByte(tXfcArray *array, uint8_t value) {
|
||||
if (XfcArrayNotFull(array)) {
|
||||
array->data[array->end] = value;
|
||||
++array->end;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t XfcArrayAddLength(tXfcArray *array, uint16_t length) {
|
||||
|
||||
uint16_t space = XfcArrayGetSpace(array);
|
||||
|
||||
uint16_t toAdd = space > length ? length : space;
|
||||
|
||||
array->end += toAdd;
|
||||
|
||||
return toAdd;
|
||||
}
|
||||
|
||||
uint16_t XfcArrayAddBytes(tXfcArray *array, uint8_t *bytes, uint16_t length) {
|
||||
|
||||
uint16_t space = XfcArrayGetSpace(array);
|
||||
|
||||
uint16_t toAdd = space > length ? length : space;
|
||||
|
||||
memcpy(array->data + array->end, bytes, toAdd);
|
||||
|
||||
array->end += toAdd;
|
||||
|
||||
return toAdd;
|
||||
}
|
||||
|
||||
void XfcArraySpaceInv(tXfcArray *array) {
|
||||
if (array->begin == array->end) {
|
||||
array->begin = array->end = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//void XfcArraySpaceInvForce(XfcArray *array) {
|
||||
// if (array->begin == array->end) {
|
||||
// array->begin = array->end = 0;
|
||||
// }
|
||||
//}
|
||||
|
||||
uint16_t XfcArrayGetBytesFront(tXfcArray *array, uint8_t *bytes, uint16_t length) {
|
||||
|
||||
uint16_t available = XfcArrayGetDataSize(array);
|
||||
|
||||
uint16_t toGet = available > length ? length : available;
|
||||
|
||||
memcpy(bytes, array->data + array->begin, toGet);
|
||||
|
||||
array->begin += toGet;
|
||||
|
||||
XfcArraySpaceInv(array);
|
||||
|
||||
return toGet;
|
||||
}
|
||||
|
||||
|
||||
void XfcArrayRemoveBytesFront(tXfcArray *env, uint16_t count) {
|
||||
uint16_t left = XfcArrayGetDataSize(env) - count;
|
||||
|
||||
if (left) {
|
||||
memmove(env->data, env->data + env->begin + count, left);
|
||||
env->begin = 0;
|
||||
env->end = left;
|
||||
} else {
|
||||
XfcArrayClear(env);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
//
|
||||
// Created by xemon on 05.05.2022.
|
||||
//
|
||||
|
||||
#include "XfcProtCommon.h"
|
||||
|
||||
const tXfcProtMagicNumbers XFC_STD_MAGIC_NUMBERS = {
|
||||
.request = 0x31,
|
||||
.response = 0x3E,
|
||||
};
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
//
|
||||
// Created by xemon on 05.05.2022.
|
||||
//
|
||||
|
||||
|
||||
#include "XfcProtCrc.h"
|
||||
|
||||
uint16_t XfcProtCrc(uint8_t *data, uint16_t length) {
|
||||
uint16_t src = 0;
|
||||
|
||||
uint8_t *end = data + length;
|
||||
|
||||
for (; data < end; ++data) {
|
||||
src += *data;
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
//
|
||||
// Created by xemon on 05.05.2022.
|
||||
//
|
||||
|
||||
#include "XfcProtDecoder.h"
|
||||
#include "XfcProtCrc.h"
|
||||
#include "XfcProtCommon.h"
|
||||
|
||||
|
||||
uint16_t XfcTransPackDecoderNextMagicFrom(tXfcProtDecoder *env, uint16_t begin) {
|
||||
|
||||
for (uint8_t *end = env->buffer->data + env->buffer->end, *byte = env->buffer->data + begin; end > byte; ++byte) {
|
||||
if (*byte == env->magic) {
|
||||
return byte - env->buffer->data;
|
||||
}
|
||||
}
|
||||
|
||||
return env->buffer->end;
|
||||
}
|
||||
|
||||
bool XfcTransPackDecoderIsStartsWithMagick(tXfcProtDecoder *env) {
|
||||
return env->buffer->data[0] == env->magic;
|
||||
}
|
||||
|
||||
bool XfcTransPackDecoderHasHeader(tXfcProtDecoder *env) {
|
||||
return XfcArrayGetDataSize(env->buffer) >= XFC_TRANSPORT_HEADER_LEN;
|
||||
}
|
||||
|
||||
uint16_t XfcTransPackDecoderGetId(tXfcProtDecoder *env) {
|
||||
return *((env->buffer->data + XFC_TRANSPORT_COMMAND_ID_OFFSET ));
|
||||
}
|
||||
|
||||
uint16_t XfcTransPackDecoderGetDataSegmentLength(tXfcProtDecoder *env) {
|
||||
return *((uint16_t *) (env->buffer->data + XFC_TRANSPORT_DATA_LEN_OFFSET));
|
||||
}
|
||||
|
||||
|
||||
uint16_t XfcTransPackDecoderGetCrc(tXfcProtDecoder *env) {
|
||||
return *((uint16_t *) (env->buffer->data + XFC_TRANSPORT_HEADER_LEN + XfcTransPackDecoderGetDataSegmentLength(env)));
|
||||
}
|
||||
|
||||
|
||||
uint16_t XfcTransPackDecoderGetRequiredFullPackLength(tXfcProtDecoder *env) {
|
||||
return XfcTransPackDecoderGetDataSegmentLength(env) + XFC_TRANSPORT_HEADER_LEN + XFC_TRANSPORT_CRC_LEN;
|
||||
}
|
||||
|
||||
bool XfcTransPackDecoderHasRequiredLength(tXfcProtDecoder *env) {
|
||||
return XfcTransPackDecoderGetRequiredFullPackLength(env) <= XfcArrayGetDataSize(env->buffer);
|
||||
}
|
||||
|
||||
bool XfcTransPackDecoderIsCrcCorrect(tXfcProtDecoder *env) {
|
||||
|
||||
return XfcProtCrc(env->buffer->data, XfcTransPackDecoderGetDataSegmentLength(env) + XFC_TRANSPORT_HEADER_LEN) ==
|
||||
XfcTransPackDecoderGetCrc(env);
|
||||
}
|
||||
|
||||
tXfcArray XfcTransPackDecoderGetDataSegmentAsArray(tXfcProtDecoder *env) {
|
||||
uint16_t dataLen = XfcTransPackDecoderGetDataSegmentLength(env);
|
||||
return (tXfcArray) {
|
||||
.data = env->buffer->data + XFC_TRANSPORT_HEADER_LEN,
|
||||
.begin = 0,
|
||||
.end = dataLen,
|
||||
.limit = dataLen,
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// Created by xemon on 05.05.2022.
|
||||
//
|
||||
|
||||
#include "XfcProtEncoder.h"
|
||||
#include "XfcProtCrc.h"
|
||||
#include "XfcProtCommon.h"
|
||||
|
||||
|
||||
////private
|
||||
uint16_t XfcTransPackEncoderGetDataSegmentLength(tXfcProtEncoder *env) {
|
||||
return *((uint16_t *) (env->buffer->data + XFC_TRANSPORT_DATA_LEN_OFFSET));
|
||||
}
|
||||
|
||||
////public
|
||||
tXfcArray XfcTransPackEncoderGetDataSegmentAsArray(tXfcProtEncoder *env) {
|
||||
return (tXfcArray) {
|
||||
.data = env->buffer->data + XFC_TRANSPORT_HEADER_LEN,
|
||||
.begin = 0,
|
||||
.end = 0,
|
||||
.limit = env->buffer->limit - XFC_TRANSPORT_HEADER_LEN + XFC_TRANSPORT_CRC_LEN,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void XfcTransPackEncoderSetId(tXfcProtEncoder *env, uint16_t id) {
|
||||
*((env->buffer->data + XFC_TRANSPORT_COMMAND_ID_OFFSET)) = id;
|
||||
}
|
||||
|
||||
void XfcTransPackEncoderSetDataSegmentLength(tXfcProtEncoder *env, uint16_t dataSegmentLength) {
|
||||
*((uint16_t *) (env->buffer->data + XFC_TRANSPORT_DATA_LEN_OFFSET)) = dataSegmentLength;
|
||||
}
|
||||
|
||||
|
||||
void XfcTransPackEncoderFinalizeAndSignCrc(tXfcProtEncoder *env) {
|
||||
env->buffer->data[0] = env->magic;
|
||||
uint16_t dataLen = XfcTransPackEncoderGetDataSegmentLength(env);
|
||||
uint16_t crc = XfcProtCrc(env->buffer->data, dataLen + XFC_TRANSPORT_HEADER_LEN);
|
||||
*((uint16_t *) (env->buffer->data + XFC_TRANSPORT_HEADER_LEN + dataLen)) = crc;
|
||||
env->buffer->end = env->buffer->begin + dataLen + XFC_TRANSPORT_HEADER_LEN + XFC_TRANSPORT_CRC_LEN;
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
//
|
||||
// Created by xemon on 05.05.2022.
|
||||
//
|
||||
|
||||
#include <XfcProtResponseCodes.h>
|
||||
#include <stddef.h>
|
||||
#include "XfcProtListener.h"
|
||||
|
||||
|
||||
void XfcProtListener_Reset(tXfcProtListener *env) {
|
||||
XfcArrayClear(&env->requestBuffer);
|
||||
}
|
||||
|
||||
void XfcProtListener_Init(
|
||||
tXfcProtListener *env,
|
||||
|
||||
void *commonArgs,
|
||||
tXfcProtTable *processors,
|
||||
|
||||
tXfcArray requestBuffer,
|
||||
uint8_t requestMagic
|
||||
) {
|
||||
env->commonArgs = commonArgs;
|
||||
env->processors = processors;
|
||||
|
||||
env->requestBuffer = requestBuffer;
|
||||
env->requestDecoder.magic = requestMagic;
|
||||
env->requestDecoder.buffer = &env->requestBuffer;
|
||||
|
||||
XfcProtListener_Reset(env);
|
||||
}
|
||||
|
||||
|
||||
void XfcTransPackServiceListenerAddByte(tXfcProtListener *env, uint8_t byte) {
|
||||
if (XfcArrayAddByte(&env->requestBuffer, byte)) {
|
||||
ENV_COUNTER_INC(rx)
|
||||
} else {
|
||||
ENV_COUNTER_INC(rx_skip)
|
||||
}
|
||||
}
|
||||
|
||||
void XfcProtListener_AddBytes(tXfcProtListener *env, uint8_t *bytes, uint16_t size) {
|
||||
for (uint8_t *end = bytes + size; end > bytes; ++bytes) {
|
||||
XfcTransPackServiceListenerAddByte(env, *bytes);
|
||||
}
|
||||
}
|
||||
|
||||
void XfcProtListener_SkipToNextMagic(tXfcProtListener *env, uint16_t begin) {
|
||||
|
||||
uint16_t skip = XfcTransPackDecoderNextMagicFrom(&env->requestDecoder, begin);
|
||||
|
||||
XfcArrayRemoveBytesFront(&env->requestBuffer, skip);
|
||||
|
||||
// ENV_COUNTER_ADD(rx_skip, nextMagic)
|
||||
}
|
||||
|
||||
bool XfcProtListener_isValidHeader(tXfcProtListener *env) {
|
||||
return XfcArrayGetDataSize(&env->requestBuffer) &&
|
||||
XfcTransPackDecoderIsStartsWithMagick(&env->requestDecoder) &&
|
||||
XfcTransPackDecoderHasHeader(&env->requestDecoder);
|
||||
}
|
||||
|
||||
bool XfcProtListener_HasPacket(tXfcProtListener *env) {
|
||||
|
||||
|
||||
while (XfcArrayGetDataSize(&env->requestBuffer)) {
|
||||
|
||||
if (!XfcTransPackDecoderIsStartsWithMagick(&env->requestDecoder)) {
|
||||
XfcProtListener_SkipToNextMagic(env, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (!XfcTransPackDecoderHasHeader(&env->requestDecoder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (XfcTransPackDecoderGetRequiredFullPackLength(&env->requestDecoder) >
|
||||
env->requestBuffer.limit) {
|
||||
|
||||
////Packet size bigger than buffer
|
||||
XfcProtListener_SkipToNextMagic(env, 1);
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
if (!XfcTransPackDecoderHasRequiredLength(&env->requestDecoder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (XfcTransPackDecoderIsCrcCorrect(&env->requestDecoder)) {
|
||||
return true;
|
||||
} else {
|
||||
XfcProtListener_SkipToNextMagic(env, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void XfcTransPackServiceListenerProcessRequest(tXfcProtListener *env) {
|
||||
|
||||
uint8_t packId = XfcTransPackDecoderGetId(&env->requestDecoder);
|
||||
|
||||
tXfcArray requestData = XfcTransPackDecoderGetDataSegmentAsArray(&env->requestDecoder);
|
||||
|
||||
tXfcProtProcessor *proc = XfcProtTable_GetForId(env->processors, packId);
|
||||
if (proc) {
|
||||
|
||||
void *args = proc->args ? proc->args : env->commonArgs;
|
||||
proc->process(&requestData, NULL, args);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void XfcProtListener_SkipCurrentRequest(tXfcProtListener *env) {
|
||||
XfcProtListener_SkipToNextMagic(env, XfcTransPackDecoderGetRequiredFullPackLength(&env->requestDecoder));
|
||||
}
|
||||
|
||||
bool XfcProtListener_Step(tXfcProtListener *env) {
|
||||
|
||||
|
||||
if (XfcProtListener_HasPacket(env)) {
|
||||
XfcTransPackServiceListenerProcessRequest(env);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
//
|
||||
// Created by xemon on 07.11.23.
|
||||
//
|
||||
|
||||
#include <SystemDelayInterface.h>
|
||||
#include "XfcProtRequester.h"
|
||||
#include "SerialPort.h"
|
||||
|
||||
#define XFC_PROT_REQUESTER_DEFAULT_TIMEOUT (1000);
|
||||
|
||||
void XfcProtRequester_reset(tXfcProtRequester *env) {
|
||||
XfcArrayClear(&env->requestBuffer);
|
||||
XfcArrayClear(&env->responseBuffer);
|
||||
}
|
||||
|
||||
void XfcProtRequester_init(
|
||||
tXfcProtRequester *env,
|
||||
|
||||
tSerialPortIO *io,
|
||||
|
||||
tXfcArray requestBuffer,
|
||||
tXfcArray responseBuffer,
|
||||
|
||||
tXfcProtMagicNumbers magicNumbers
|
||||
) {
|
||||
|
||||
env->io = io;
|
||||
|
||||
env->transmitTimeout = XFC_PROT_REQUESTER_DEFAULT_TIMEOUT;
|
||||
|
||||
env->requestBuffer = requestBuffer;
|
||||
env->responseBuffer = responseBuffer;
|
||||
|
||||
env->encoder.magic = magicNumbers.request;
|
||||
env->decoder.magic = magicNumbers.response;
|
||||
|
||||
env->encoder.buffer = &env->requestBuffer;
|
||||
env->decoder.buffer = &env->responseBuffer;
|
||||
|
||||
XfcProtRequester_reset(env);
|
||||
}
|
||||
|
||||
eXfcProtRequesterStatus XfcProtRequester_makeRequest(
|
||||
tXfcProtRequester *env, uint16_t id,
|
||||
void *builder, tXfcRequesterMethod buildMethod,
|
||||
void *parser, tXfcRequesterMethod parseMethod,
|
||||
int32_t timeout
|
||||
) {
|
||||
|
||||
SerialPortClearRxBuffer(env->io);
|
||||
XfcArrayClear(env->decoder.buffer);
|
||||
XfcArrayClear(env->encoder.buffer);
|
||||
|
||||
|
||||
tXfcArray request = XfcTransPackEncoderGetDataSegmentAsArray(&env->encoder);
|
||||
XfcArrayClear(&request);
|
||||
|
||||
if (buildMethod) {
|
||||
switch (buildMethod(builder, &request)) {
|
||||
|
||||
case XFC_TRANSPORT_PROTOCOL_RESPONSE_RESULT_OK:
|
||||
break;
|
||||
case XFC_TRANSPORT_PROTOCOL_RESPONSE_RESULT_CMD_OVERFLOW:
|
||||
return eXfcProtRequesterStatus_REQUEST_BUILD_OVERFLOW;
|
||||
|
||||
case XFC_TRANSPORT_PROTOCOL_RESPONSE_RESULT_EXECUTION_ERROR:
|
||||
return eXfcProtRequesterStatus_BUILD_EXECUTION_ERROR;
|
||||
|
||||
default:
|
||||
return eXfcProtRequesterStatus_UNKNOWN_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
XfcTransPackEncoderSetId(&env->encoder, id);
|
||||
XfcTransPackEncoderSetDataSegmentLength(&env->encoder, XfcArrayGetDataSize(&request));
|
||||
XfcTransPackEncoderFinalizeAndSignCrc(&env->encoder);
|
||||
|
||||
uint16_t transmitted = SerialPortTransmit(
|
||||
env->io,
|
||||
env->encoder.buffer->data,
|
||||
XfcArrayGetDataSize(env->encoder.buffer),
|
||||
env->transmitTimeout
|
||||
);
|
||||
|
||||
if (transmitted != XfcArrayGetDataSize(env->encoder.buffer)) {
|
||||
return eXfcProtRequesterStatus_TRANSMIT_ERROR;
|
||||
}
|
||||
|
||||
uint8_t byte;
|
||||
|
||||
int32_t timeEnd = SystemGetMs() + timeout;
|
||||
|
||||
while (timeEnd >= SystemGetMs()) {
|
||||
|
||||
if (!SerialPortReceive(env->io, &byte, 1, timeout)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!XfcArrayAddByte(env->decoder.buffer, byte)) {
|
||||
return eXfcProtRequesterStatus_RECIVE_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
if (!XfcTransPackDecoderIsStartsWithMagick(&env->decoder)) {
|
||||
return eXfcProtRequesterStatus_PREFIX_MISMATCH;
|
||||
}
|
||||
|
||||
if (!XfcTransPackDecoderHasHeader(&env->decoder)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (XfcTransPackDecoderGetRequiredFullPackLength(&env->decoder) > env->decoder.buffer->limit) {
|
||||
return eXfcProtRequesterStatus_RECIVE_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
if (!XfcTransPackDecoderHasRequiredLength(&env->decoder)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!XfcTransPackDecoderIsCrcCorrect(&env->decoder)) {
|
||||
return eXfcProtRequesterStatus_CRC_ERROR;
|
||||
}
|
||||
|
||||
tXfcArray response = XfcTransPackDecoderGetDataSegmentAsArray(&env->decoder);
|
||||
|
||||
if (parseMethod) {
|
||||
|
||||
switch (parseMethod(parser, &response)) {
|
||||
case XFC_TRANSPORT_PROTOCOL_RESPONSE_RESULT_OK:
|
||||
break;
|
||||
|
||||
case XFC_TRANSPORT_PROTOCOL_REQUEST_UNEXPECTEDLY_SHORT:
|
||||
return eXfcProtRequesterStatus_RESPONSE_SHORT;
|
||||
|
||||
case XFC_TRANSPORT_PROTOCOL_RESPONSE_RESULT_EXECUTION_ERROR:
|
||||
return eXfcProtRequesterStatus_PARSING_EXECUTION_ERROR;
|
||||
|
||||
default:
|
||||
return eXfcProtRequesterStatus_UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return eXfcProtRequesterStatus_OK;
|
||||
}
|
||||
|
||||
return eXfcProtRequesterStatus_RECIVE_TIMEOUT;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
//
|
||||
// Created by xemon 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;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// Created by xemon on 01.11.22.
|
||||
//
|
||||
|
||||
#include <stddef.h>
|
||||
#include <memory.h>
|
||||
#include "XfcProtTable.h"
|
||||
|
||||
void XfcProtTable_Init(tXfcProtTable *env, tXfcProtProcessor *allocatedMem, uint16_t memLimit) {
|
||||
env->limit = memLimit;
|
||||
env->items = allocatedMem;
|
||||
env->count = 0;
|
||||
memset(env->items, 0, env->limit * sizeof(tXfcProtProcessor));
|
||||
}
|
||||
|
||||
bool XfcProtTable_Add(
|
||||
tXfcProtTable *env,
|
||||
char *staticStringTextId,
|
||||
uint8_t textIdLen,
|
||||
tXfcProtMethod method,
|
||||
void *args
|
||||
) {
|
||||
if (env->limit <= env->count) {
|
||||
return false;
|
||||
}
|
||||
tXfcProtProcessor *proc = env->items + env->count;
|
||||
|
||||
proc->textId = staticStringTextId;
|
||||
proc->textIdLen = textIdLen;
|
||||
proc->args = args;
|
||||
proc->process = method;
|
||||
|
||||
++env->count;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
tXfcProtProcessor *XfcProtTable_GetForId(tXfcProtTable *env, uint16_t id) {
|
||||
if ((id < env->count) && env->items[id].process) {
|
||||
return &env->items[id];
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"cmake": {
|
||||
"inc_dirs": [
|
||||
"Inc"
|
||||
],
|
||||
"srcs": [
|
||||
"Src/**.c"
|
||||
]
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue