Добавлены интерфейсы и драйверы

This commit is contained in:
cfif 2025-09-30 15:52:33 +03:00
commit bc6a125d6e
23 changed files with 1214 additions and 0 deletions

47
Inc/XfcArray.h Normal file
View File

@ -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

19
Inc/XfcCounting.h Normal file
View File

@ -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

30
Inc/XfcProtCommon.h Normal file
View File

@ -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

12
Inc/XfcProtCrc.h Normal file
View File

@ -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

36
Inc/XfcProtDecoder.h Normal file
View File

@ -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

25
Inc/XfcProtEncoder.h Normal file
View File

@ -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

58
Inc/XfcProtListener.h Normal file
View File

@ -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

19
Inc/XfcProtProcessor.h Normal file
View File

@ -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

View File

@ -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

63
Inc/XfcProtRequester.h Normal file
View File

@ -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

60
Inc/XfcProtRespondent.h Normal file
View File

@ -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

View File

@ -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

33
Inc/XfcProtTable.h Normal file
View File

@ -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

126
Src/XfcArray.c Normal file
View File

@ -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);
}
}

10
Src/XfcCommon.c Normal file
View File

@ -0,0 +1,10 @@
//
// Created by xemon on 05.05.2022.
//
#include "XfcProtCommon.h"
const tXfcProtMagicNumbers XFC_STD_MAGIC_NUMBERS = {
.request = 0x31,
.response = 0x3E,
};

17
Src/XfcProtCrc.c Normal file
View File

@ -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;
}

65
Src/XfcProtDecoder.c Normal file
View File

@ -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,
};
}

41
Src/XfcProtEncoder.c Normal file
View File

@ -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;
}

133
Src/XfcProtListener.c Normal file
View File

@ -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;
}

148
Src/XfcProtRequester.c Normal file
View File

@ -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;
}

150
Src/XfcProtRespondent.c Normal file
View File

@ -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;
}

47
Src/XfcProtTable.c Normal file
View File

@ -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;
}
}

10
modular.json Normal file
View File

@ -0,0 +1,10 @@
{
"cmake": {
"inc_dirs": [
"Inc"
],
"srcs": [
"Src/**.c"
]
}
}