From d71e47036c6f4c53c55f0578ac06be2008cfdec6 Mon Sep 17 00:00:00 2001 From: Qukich Date: Mon, 8 May 2023 14:47:51 +0300 Subject: [PATCH 01/14] add header hdlc file --- .idea/.gitignore | 8 ++++++ .idea/Display_Avr_3.iml | 8 ++++++ .idea/modules.xml | 8 ++++++ .idea/vcs.xml | 6 +++++ hdlc/hdlc.c | 60 +++++++++++++++++++++++++++++++++++++++++ hdlc/hdlc.h | 43 +++++++++++++++++++++++++++++ 6 files changed, 133 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/Display_Avr_3.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 hdlc/hdlc.c create mode 100644 hdlc/hdlc.h diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/Display_Avr_3.iml b/.idea/Display_Avr_3.iml new file mode 100644 index 0000000..bc2cd87 --- /dev/null +++ b/.idea/Display_Avr_3.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..639da93 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/hdlc/hdlc.c b/hdlc/hdlc.c new file mode 100644 index 0000000..7ffb65f --- /dev/null +++ b/hdlc/hdlc.c @@ -0,0 +1,60 @@ +#include "hdlc.h" +#include + +#include "setup.h" + +__weak void uart_putchar(char ch) +{ + // implement function to send character via UART +} + +static hdlc_t hdlc; + +// Static buffer allocations +static uint8_t _hdlc_rx_frame[HDLC_MRU]; // rx frame buffer allocation +static uint8_t _hdlc_tx_frame[HDLC_MRU]; // tx frame buffer allocation +static uint8_t _hdlc_payload[HDLC_MRU]; // payload buffer allocation + + + +/** Приватная функция для отправки байтов по uart */ +static void hdlc_tx_byte(uint8_t byte) +{ + uart_putchar((char)byte); +} + +/* инициализация конечного автомата HDLC, указателей буфера и переменных состояния */ +void hdlc_init(void) +{ + hdlc.rx_frame_index = 0; + hdlc.rx_frame_fcs = HDLC_CRC_INIT_VAL; + hdlc.p_rx_frame = _hdlc_rx_frame; + memset(hdlc.p_rx_frame, 0, HDLC_MRU); + hdlc.p_tx_frame = _hdlc_tx_frame; + memset(hdlc.p_tx_frame, 0, HDLC_MRU); + hdlc.p_payload = _hdlc_payload; + memset(hdlc.p_payload, 0, HDLC_MRU); + hdlc.state = HDLC_SOF_WAIT; + hdlc.own_addr = SETUP_OWNADDRESS; +} + +//Эта функция должна вызываться при получении нового символа через UART +static void hdlc_esc_tx_byte(uint8_t byte) +{ + if((byte == HDLC_CONTROL_ESCAPE) || (byte == HDLC_FLAG_SOF)) + { + hdlc_tx_byte(HDLC_CONTROL_ESCAPE); + byte ^= HDLC_ESCAPE_BIT; + hdlc_tx_byte(byte); + } + else + hdlc_tx_byte(byte); +} + +void hdlc_process_rx_frame(uint8_t *buf, uint16_t len){ + return; +} + +void hdlc_tx_frame(const uint8_t *txbuffer, uint8_t len){ + return; +} \ No newline at end of file diff --git a/hdlc/hdlc.h b/hdlc/hdlc.h new file mode 100644 index 0000000..9d4d956 --- /dev/null +++ b/hdlc/hdlc.h @@ -0,0 +1,43 @@ +#ifndef DISPLAY_AVR_3_HDLC_H +#define DISPLAY_AVR_3_HDLC_H + +#define HDLC_MRU 256 +// HDLC constants --- RFC 1662 +#define HDLC_FLAG_SOF 0x7e // Flag +#define HDLC_CONTROL_ESCAPE 0x7d // Control Escape octet +#define HDLC_ESCAPE_BIT 0x20 // Transparency modifier octet (XOR bit) +#define HDLC_CRC_INIT_VAL 0xffff +#define HDLC_CRC_MAGIC_VAL 0xf0b8 +#define HDLC_CRC_POLYNOMIAL 0x8408 +#define HDLC_UI_CMD 0x03 // Unnumbered Information with payload +#define HDLC_FINAL_FLAG 0x10 // F flag +#define HDLC_POLL_FLAG 0x10 // P flag + +typedef enum +{ + HDLC_SOF_WAIT, + HDLC_DATARX, + HDLC_PROC_ESC, +} hdlc_state_t; + +typedef struct +{ + uint8_t own_addr; + uint8_t src_addr; + uint8_t dest_addr; + uint8_t ctrl; + uint8_t *p_tx_frame; // tx frame buffer + uint8_t *p_rx_frame; // rx frame buffer + uint8_t *p_payload; // payload pointer + uint16_t rx_frame_index; + uint16_t rx_frame_fcs; + hdlc_state_t state; +} hdlc_t; + + +void hdlc_init(void); + +void hdlc_process_rx_frame(uint8_t *buf, uint16_t len); +void hdlc_tx_frame(const uint8_t *txbuffer, uint8_t len); + +#endif //DISPLAY_AVR_3_HDLC_H From c82c3b11cba273a638505593d1d15e7d236de7f8 Mon Sep 17 00:00:00 2001 From: Qukich Date: Wed, 24 May 2023 18:09:43 +0300 Subject: [PATCH 02/14] add hdlc protocol, need test --- .idea/Display_Avr_3.iml | 8 -- hdlc/fcs.c | 35 +++++ hdlc/fcs.h | 25 ++++ hdlc/hdlc.c | 295 +++++++++++++++++++++++++++++++++------- hdlc/hdlc.h | 155 ++++++++++++++++----- 5 files changed, 426 insertions(+), 92 deletions(-) delete mode 100644 .idea/Display_Avr_3.iml create mode 100644 hdlc/fcs.c create mode 100644 hdlc/fcs.h diff --git a/.idea/Display_Avr_3.iml b/.idea/Display_Avr_3.iml deleted file mode 100644 index bc2cd87..0000000 --- a/.idea/Display_Avr_3.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/hdlc/fcs.c b/hdlc/fcs.c new file mode 100644 index 0000000..caea596 --- /dev/null +++ b/hdlc/fcs.c @@ -0,0 +1,35 @@ +#include "fcs.h" + +static const unsigned short fcstab[256] = { 0x0000, 0x1189, 0x2312, 0x329b, + 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, + 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, + 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, + 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, + 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, + 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, + 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, + 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, + 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, + 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, + 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, + 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581, + 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, + 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, + 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, + 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, + 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, + 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, + 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, + 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, + 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, + 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, + 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, + 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, + 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; + +FCS_SIZE calc_fcs(FCS_SIZE fcs, unsigned char value) { + return (fcs >> 8) ^ fcstab[(fcs ^ value) & 0xff]; +} \ No newline at end of file diff --git a/hdlc/fcs.h b/hdlc/fcs.h new file mode 100644 index 0000000..390d163 --- /dev/null +++ b/hdlc/fcs.h @@ -0,0 +1,25 @@ +#ifndef FCS_H +#define FCS_H + +#ifdef CRC32 +#define FCS_INIT_VALUE 0xFFFFFFFF /* FCS initialization value. */ + #define FCS_GOOD_VALUE 0xDEBB20E3 /* FCS value for valid frames. */ + #define FCS_INVERT_MASK 0xFFFFFFFF /* Invert the FCS value accordingly to the specification */ + #define FCS_SIZE unsigned int +#else +#define FCS_INIT_VALUE 0xFFFF /* FCS initialization value. */ +#define FCS_GOOD_VALUE 0xF0B8 /* FCS value for valid frames. */ +#define FCS_INVERT_MASK 0xFFFF /* Invert the FCS value accordingly to the specification */ +#define FCS_SIZE unsigned short +#endif + +/** + * Вычисляет новый Frame Check Sequence на основе текущего значения и ценности данных. + * + * @param fcs Current FCS value + * @param value The value to be added + * @returns Calculated FCS value + */ +FCS_SIZE calc_fcs(FCS_SIZE fcs, unsigned char value); + +#endif //FCS_H diff --git a/hdlc/hdlc.c b/hdlc/hdlc.c index 7ffb65f..e829df2 100644 --- a/hdlc/hdlc.c +++ b/hdlc/hdlc.c @@ -1,60 +1,257 @@ #include "hdlc.h" -#include -#include "setup.h" +#define HDLC_CONTROL_S_OR_U_FRAME_BIT 0 +#define HDLC_CONTROL_SEND_SEQ_NO_BIT 1 +#define HDLC_CONTROL_S_FRAME_TYPE_BIT 2 +#define HDLC_CONTROL_POLL_BIT 4 +#define HDLC_CONTROL_RECV_SEQ_NO_BIT 5 -__weak void uart_putchar(char ch) -{ - // implement function to send character via UART -} +// HDLC Control type definitions +#define HDLC_CONTROL_TYPE_RECEIVE_READY 0 +#define HDLC_CONTROL_TYPE_RECEIVE_NOT_READY 1 +#define HDLC_CONTROL_TYPE_REJECT 2 +#define HDLC_CONTROL_TYPE_SELECTIVE_REJECT 3 -static hdlc_t hdlc; +static hdlc_state_t hdlc_state = { + .control_escape = 0, + .fcs = FCS_INIT_VALUE, + .start_index = -1, + .end_index = -1, + .src_index = 0, + .dest_index = 0, +}; -// Static buffer allocations -static uint8_t _hdlc_rx_frame[HDLC_MRU]; // rx frame buffer allocation -static uint8_t _hdlc_tx_frame[HDLC_MRU]; // tx frame buffer allocation -static uint8_t _hdlc_payload[HDLC_MRU]; // payload buffer allocation - - - -/** Приватная функция для отправки байтов по uart */ -static void hdlc_tx_byte(uint8_t byte) -{ - uart_putchar((char)byte); -} - -/* инициализация конечного автомата HDLC, указателей буфера и переменных состояния */ -void hdlc_init(void) -{ - hdlc.rx_frame_index = 0; - hdlc.rx_frame_fcs = HDLC_CRC_INIT_VAL; - hdlc.p_rx_frame = _hdlc_rx_frame; - memset(hdlc.p_rx_frame, 0, HDLC_MRU); - hdlc.p_tx_frame = _hdlc_tx_frame; - memset(hdlc.p_tx_frame, 0, HDLC_MRU); - hdlc.p_payload = _hdlc_payload; - memset(hdlc.p_payload, 0, HDLC_MRU); - hdlc.state = HDLC_SOF_WAIT; - hdlc.own_addr = SETUP_OWNADDRESS; -} - -//Эта функция должна вызываться при получении нового символа через UART -static void hdlc_esc_tx_byte(uint8_t byte) -{ - if((byte == HDLC_CONTROL_ESCAPE) || (byte == HDLC_FLAG_SOF)) - { - hdlc_tx_byte(HDLC_CONTROL_ESCAPE); - byte ^= HDLC_ESCAPE_BIT; - hdlc_tx_byte(byte); +int hdlc_set_state(hdlc_state_t *state) { + if (!state) { + return -EINVAL; } - else - hdlc_tx_byte(byte); + + hdlc_state = *state; + return 0; } -void hdlc_process_rx_frame(uint8_t *buf, uint16_t len){ - return; +int hdlc_get_state(hdlc_state_t *state) { + if (!state) { + return -EINVAL; + } + + *state = hdlc_state; + return 0; } -void hdlc_tx_frame(const uint8_t *txbuffer, uint8_t len){ - return; +void hdlc_escape_value(char value, char *dest, int *dest_index) { + // Проверяет и экранируйте значение, если это необходимо + if ((value == HDLC_FLAG_SEQUENCE) || (value == HDLC_CONTROL_ESCAPE)) { + dest[(*dest_index)++] = HDLC_CONTROL_ESCAPE; + value ^= 0x20; + } + + // Добавляет значение в буфер назначения и увеличьте индекс назначения + dest[(*dest_index)++] = value; +} + +hdlc_control_t hdlc_get_control_type(unsigned char control) { + hdlc_control_t value; + + // Проверяет, является ли S-фреймом (или U-фреймом) + if (control & (1 << HDLC_CONTROL_S_OR_U_FRAME_BIT)) { + // Проверяет, есть ли S-фрейм тип в Receive Ready (ACK) + if (((control >> HDLC_CONTROL_S_FRAME_TYPE_BIT) & 0x3) + == HDLC_CONTROL_TYPE_RECEIVE_READY) { + value.frame = HDLC_FRAME_ACK; + } else { + // Предположим, что это отрицательное подтверждение (NACK), так как функции "Receive Not Ready", "Selective Reject" и U-фреймы не поддерживаются. + value.frame = HDLC_FRAME_NACK; + } + + // Добавляет номер последовательности приема из S-фрейма (или U-фрейма). + value.seq_no = (control >> HDLC_CONTROL_RECV_SEQ_NO_BIT); + } else { + // Должен быть I-фрейм, поэтому добавляет номер последовательности отправки (номер последовательности приема не используется). + value.frame = HDLC_FRAME_DATA; + value.seq_no = (control >> HDLC_CONTROL_SEND_SEQ_NO_BIT); + } + + return value; +} + +unsigned char hdlc_frame_control_type(hdlc_control_t *control) { + unsigned char value = 0; + + switch (control->frame) { + case HDLC_FRAME_DATA: + // Создает байт управления HDLC I-фрейма с установленным битом опроса. + value |= (control->seq_no << HDLC_CONTROL_SEND_SEQ_NO_BIT); + value |= (1 << HDLC_CONTROL_POLL_BIT); + break; + case HDLC_FRAME_ACK: + // Создает байт управления HDLC S-фрейма "Receive Ready" с сброшенным битом опроса. + value |= (control->seq_no << HDLC_CONTROL_RECV_SEQ_NO_BIT); + value |= (1 << HDLC_CONTROL_S_OR_U_FRAME_BIT); + break; + case HDLC_FRAME_NACK: + // Создает байт управления HDLC S-фрейма "Receive Ready" с сброшенным битом опроса. + value |= (control->seq_no << HDLC_CONTROL_RECV_SEQ_NO_BIT); + value |= (HDLC_CONTROL_TYPE_REJECT << HDLC_CONTROL_S_FRAME_TYPE_BIT); + value |= (1 << HDLC_CONTROL_S_OR_U_FRAME_BIT); + break; + } + + return value; +} + +void hdlc_get_data_reset() { + hdlc_get_data_reset_with_state(&hdlc_state); +} + +void hdlc_get_data_reset_with_state(hdlc_state_t *state) { + state->fcs = FCS_INIT_VALUE; + state->start_index = state->end_index = -1; + state->src_index = state->dest_index = 0; + state->control_escape = 0; +} + +int hdlc_get_data(hdlc_control_t *control, const char *src, + unsigned int src_len, char *dest, unsigned int *dest_len) { + return hdlc_get_data_with_state(&hdlc_state, control, src, src_len, dest, dest_len); +} + +int hdlc_get_data_with_state(hdlc_state_t *state, hdlc_control_t *control, const char *src, + unsigned int src_len, char *dest, unsigned int *dest_len) { + int ret; + char value; + unsigned int i; + + // Проверка, что все параметры валидны + if (!state || !control || !src || !dest || !dest_len) { + return -EINVAL; + } + + // Проход по байтам данных + for (i = 0; i < src_len; i++) { + // В первую очередь находит последовательность начальных флагов + if (state->start_index < 0) { + if (src[i] == HDLC_FLAG_SEQUENCE) { + // Проверяет, присутствует ли дополнительный байт последовательности флагов + if ((i < (src_len - 1)) && (src[i + 1] == HDLC_FLAG_SEQUENCE)) { + // Согласно протоколу HDLC, просто выполните цикл снова, чтобы молча отбросить его. + continue; + } + + state->start_index = state->src_index; + } + } else { + // Проверка последовательность флага окончания + if (src[i] == HDLC_FLAG_SEQUENCE) { + // Проверка, присутствует ли дополнительный байт последовательности флага или был ли он получен ранее. + if (((i < (src_len - 1)) && (src[i + 1] == HDLC_FLAG_SEQUENCE)) + || ((state->start_index + 1) == state->src_index)) { + // Согласно протоколу HDLC, просто выполните цикл снова, чтобы молча отбросить его. + continue; + } + + state->end_index = state->src_index; + break; + } else if (src[i] == HDLC_CONTROL_ESCAPE) { + state->control_escape = 1; + } else { + // Обновите значение на основе полученного символа управления экранирования (control escape) + if (state->control_escape) { + state->control_escape = 0; + value = src[i] ^ 0x20; + } else { + value = src[i]; + } + + // Теперь обновите значение FCS (контрольной суммы фрейма). + state->fcs = calc_fcs(state->fcs, value); + + if (state->src_index == state->start_index + 2) { + // Поле управления (control field) находится вторым байтом после последовательности стартового флага. + *control = hdlc_get_control_type(value); + } else if (state->src_index > (state->start_index + 2)) { + // Начинает добавлять значения данных после поля управления (control field) в буфер. + dest[state->dest_index++] = value; + } + } + } + state->src_index++; + } + + // Проверьте наличие неверного фрейма (отсутствие последовательности стартового или окончательного флага). + if ((state->start_index < 0) || (state->end_index < 0)) { + // Return no message and make sure destination length is 0 + *dest_len = 0; + ret = -ENOMSG; + } else { + // Фрейм имеет размер не менее 4 байтов и содержит допустимое значение FCS (контрольной суммы). + if ((state->end_index < (state->start_index + 4)) + || (state->fcs != FCS_GOOD_VALUE)) { + // Возвращает ошибку FCS (контрольной суммы) и указывает, что данные до последовательности флага окончания в буфере должны быть отброшены. + *dest_len = i; + ret = -EIO; + } else { + // Возвращает успешный результат и указывает, что данные до последовательности флага окончания в буфере должны быть отброшены. + *dest_len = state->dest_index - sizeof(state->fcs); + ret = i; + } + + // Сбрасывает значения для следующего фрейма + hdlc_get_data_reset_with_state(state); + } + + return ret; +} + +int hdlc_frame_data(hdlc_control_t *control, const char *src, + unsigned int src_len, char *dest, unsigned int *dest_len) { + unsigned int i; + int dest_index = 0; + unsigned char value = 0; + FCS_SIZE fcs = FCS_INIT_VALUE; + + // Проверка, что все параметры валидны + if (!control || (!src && (src_len > 0)) || !dest || !dest_len) { + return -EINVAL; + } + + // Добавления последовательности стартового флага. + dest[dest_index++] = HDLC_FLAG_SEQUENCE; + + // Добавление адреса "все станции" из протокола HDLC (широковещательный адрес). + fcs = calc_fcs(fcs, HDLC_ALL_STATION_ADDR); + hdlc_escape_value(HDLC_ALL_STATION_ADDR, dest, &dest_index); + + // Добавление значения поля управления фрейма. + value = hdlc_frame_control_type(control); + fcs = calc_fcs(fcs, value); + hdlc_escape_value(value, dest, &dest_index); + + // Только фреймы типа DATA должны содержать данные. + if (control->frame == HDLC_FRAME_DATA) { + // Вычислите контрольную сумму FCS и экранируйте данные. + for (i = 0; i < src_len; i++) { + fcs = calc_fcs(fcs, src[i]); + hdlc_escape_value(src[i], dest, &dest_index); + } + } + + // Инвертирует значения FCS в соответствии со спецификацией. + fcs ^= FCS_INVERT_MASK; + + // Проходит по байтам FCS и выполните экранирование значений. + for (i = 0; i < sizeof(fcs); i++) { + value = ((fcs >> (8 * i)) & 0xFF); + hdlc_escape_value(value, dest, &dest_index); + } + + // Добавляет последовательность флага окончания и обновляет длину фрейма. + dest[dest_index++] = HDLC_FLAG_SEQUENCE; + *dest_len = dest_index; + + return 0; +} + +int hello(){ + return 1; } \ No newline at end of file diff --git a/hdlc/hdlc.h b/hdlc/hdlc.h index 9d4d956..6a64638 100644 --- a/hdlc/hdlc.h +++ b/hdlc/hdlc.h @@ -1,43 +1,128 @@ -#ifndef DISPLAY_AVR_3_HDLC_H -#define DISPLAY_AVR_3_HDLC_H +/** + * @file hdlc.h + */ -#define HDLC_MRU 256 -// HDLC constants --- RFC 1662 -#define HDLC_FLAG_SOF 0x7e // Flag -#define HDLC_CONTROL_ESCAPE 0x7d // Control Escape octet -#define HDLC_ESCAPE_BIT 0x20 // Transparency modifier octet (XOR bit) -#define HDLC_CRC_INIT_VAL 0xffff -#define HDLC_CRC_MAGIC_VAL 0xf0b8 -#define HDLC_CRC_POLYNOMIAL 0x8408 -#define HDLC_UI_CMD 0x03 // Unnumbered Information with payload -#define HDLC_FINAL_FLAG 0x10 // F flag -#define HDLC_POLL_FLAG 0x10 // P flag +#ifndef HDLC_H +#define HDLC_H -typedef enum -{ - HDLC_SOF_WAIT, - HDLC_DATARX, - HDLC_PROC_ESC, +#include "fcs.h" +#include + +/** HDLC флаг начала и конца */ +#define HDLC_FLAG_SEQUENCE 0x7E + +/** HDLC управляющее выходное значение */ +#define HDLC_CONTROL_ESCAPE 0x7D + +/** HDLC все адресса станций */ +#define HDLC_ALL_STATION_ADDR 0xFF + +/** Поддерживаемые HDLC фрейм типы */ +typedef enum { + HDLC_FRAME_DATA, + HDLC_FRAME_ACK, + HDLC_FRAME_NACK, +} hdlc_frame_t; + +/** Информация о поле управления */ +typedef struct { + hdlc_frame_t frame; + unsigned char seq_no :3; +} hdlc_control_t; + +/** Перменные для hdlc_get_data и hdlc_get_data_with_state + * для отслеживания полученных буферов + */ +typedef struct { + char control_escape; + FCS_SIZE fcs; + int start_index; + int end_index; + int src_index; + int dest_index; } hdlc_state_t; -typedef struct -{ - uint8_t own_addr; - uint8_t src_addr; - uint8_t dest_addr; - uint8_t ctrl; - uint8_t *p_tx_frame; // tx frame buffer - uint8_t *p_rx_frame; // rx frame buffer - uint8_t *p_payload; // payload pointer - uint16_t rx_frame_index; - uint16_t rx_frame_fcs; - hdlc_state_t state; -} hdlc_t; +/** + * Установить состояние hdlc + * + * @param[in] state состояние hdlc, которое будет использоваться + * @retval 0 Успешно + * @retval -EINVAL Невалидный параметр + */ +int hdlc_set_state(hdlc_state_t *state); + +/** + * Получить текущее состояние hdlc + * + * @param[out] state Текущее состояние hdlc + * @retval 0 Success + * @retval -EINVAL Невалидный параметр + */ +int hdlc_get_state(hdlc_state_t *state); + +/** + * Извлекает данные из указанного буфера, содержащего HDLC-фрейм. + * Фреймы могут быть разобраны из нескольких буферов при получении через uart + * + * @param[out] control Структура поля управления с типом фрейма и номером последовательности. + * @param[in] src Основной буффер для фрейма + * @param[in] src_len Длинна основного буффера + * @param[out] dest Целевой буффер (должен быть способен содержать максимальный размер кадра) + * @param[out] dest_len Длинна целевого буффера + * @retval >=0 Успешно (размер возвращаемого значения должен быть удален из исходного буфера) + * @retval -EINVAL Невалидный параметр + * @retval -INMSG Невалидное сообщение + * @retval -EIO Невалидный FCS (размер dest_len должен быть удален из исходного буфера) + * + * @see hdlc_get_data_with_state + */ +int hdlc_get_data(hdlc_control_t *control, const char *src, + unsigned int src_len, char *dest, unsigned int *dest_len); + +/** + * Извлекает данные из указанного буфера, содержащего HDLC-фрейм. + * Фреймы могут быть разобраны из нескольких буферов при получении через uart + * + * Эта функция вариация @ref hdlc_get_data + * Разница только в первом аргументе: hdlc_state_t *state + * Данные под этим указателем используются для отслеживания внутренних буферов. + * + * @see hdlc_get_data + */ +int hdlc_get_data_with_state(hdlc_state_t *state, hdlc_control_t *control, const char *src, + unsigned int src_len, char *dest, unsigned int *dest_len); -void hdlc_init(void); +/** + * Сбрасывает значения, используемые в функции hdlc_get_data для отслеживания полученных буферов + */ +void hdlc_get_data_reset(); -void hdlc_process_rx_frame(uint8_t *buf, uint16_t len); -void hdlc_tx_frame(const uint8_t *txbuffer, uint8_t len); +/** + * Эта функция вариация @ref hdlc_get_data_reset + * Сбрасывает значения состояния, которые находятся под указателем, указанным в качестве аргумента + * + * Эта функция должна быть вызвана перед первым вызовом hdlc_get_data_with_state + * когда используется пользовательское хранилище состояний. + * + * @see hdlc_get_data_reset + */ +void hdlc_get_data_reset_with_state(hdlc_state_t *state); -#endif //DISPLAY_AVR_3_HDLC_H +/** + * Создает кадр HDLC с указанным буфером данных. + * + * @param[in] control Структура поля управления с типом кадра и порядковым номером + * @param[in] src Исходный буфер с данными + * @param[in] src_len Длинна исходного буффера + * @param[out] dest Целевой буфер (должно быть больше, чем исходный буфер) + * @param[out] dest_len Длинна целевого буффера + * @retval 0 Success + * @retval -EINVAL Невалидный параметр + */ +int hdlc_frame_data(hdlc_control_t *control, const char *src, + unsigned int src_len, char *dest, unsigned int *dest_len); + +int hello(); + +#endif \ No newline at end of file From a2546d2931b363fe93acee2e8ebe394c74b948bf Mon Sep 17 00:00:00 2001 From: Kirill Kurshakow Date: Mon, 5 Jun 2023 18:34:34 +0300 Subject: [PATCH 03/14] uart module added --- uart.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 uart.c diff --git a/uart.c b/uart.c new file mode 100644 index 0000000..2b77e0c --- /dev/null +++ b/uart.c @@ -0,0 +1,101 @@ +#include +#include +#include + +#define F_CPU 16000000 +#define SIZE_BUF 8 + +//кольцевой (циклический) буфер +volatile unsigned char usartTxBuf[SIZE_BUF]; +unsigned char txBufTail = 0; //"указатель" хвоста буфера +unsigned char txBufHead = 0; //"указатель" головы буфера +volatile unsigned char txCount = 0; //счетчик символов + +uint8_t receive = 0; +uint8_t rx_data = 0; +volatile uint8_t rx_flag = 0; + +void UARTInit(void) { +UCSR1B=0; UCSR1C=0; // Обнулим, на всякий случай регистры статуса и контроля. +UBRR0H = 0; // Старшие биты регистра скорости. +UBRR0L = 103; //скорость передачи данных 9600 +UCSR0B = (1«RXEN0)|(1«TXEN0)|(1«RXCIE0)|(1«TXCIE0)|(0«UDRIE0);//Включаем (подключаем ножки контроллера) приём и передачу по UART. +UCSR0C = (1«UCSZ01)|(1«UCSZ00); //8 bit + +} + +void UARTSend(uint8_t data) { +while (!(UCSR0A & (1«UDRE0))); // Ждём опустошения буфера передачи (читаем флаг). +UDR0 = data; // Записываем в регистр значение переменной "data" для передачи. +} + +//"очищает" буфер +void USART_FlushTxBuf(void) +{ +txBufTail = 0; +txCount = 0; +txBufHead = 0; + +//положить символ в буфер +void USART_PutChar(unsigned char sym) +{ +if(((UCSRA0 & (1«UDRE0)) != 0) && (txCount == 0)) UDR0 = sym; //Если модуль USART не занят и передающий буфер пустой, +else { //символ записывается в регистр UDR +if (txCount < SIZE_BUF){ //если в буфере еще есть место +usartTxBuf[txBufTail] = sym; //помещаем в него символ +txCount++; //инкрементируем счетчик символов +txBufTail++; //и индекс хвоста буфера +if (txBufTail == SIZE_BUF) txBufTail = 0; +} +} +} +//взять символ из буфера +unsigned char GetChar(void) +{ +unsigned char sym = 0; +if (count > 0){ //если буфер не пустой +sym = cycleBuf[head]; //считываем символ из буфера +count--; //уменьшаем счетчик символов +head++; //инкрементируем индекс головы буфера +if (head == SIZE_BUF) head = 0; +} +return sym; +} + +//функция загрузки строк +void USART_SendStr(unsigned char * data) +{ +unsigned char sym; +while(*data){ // пока не будет считан символ конца строки +sym = *data++; +USART_PutChar(sym); +} +} +// unsigned char UARTGet() { +// while(!rx_flag); //пока значение флага не станет равно "1" +// rx_flag = 0; +// return rx_data; //возвращет состояние переменной rx_data +// } + +int main(void) { +sei(); +UARTInit(); +DDRL = 0b11111111; // Определим порт "L" на выход +while(1) { +receive = UARTGet(); +receive++; +UARTSend(receive); +} +} + + +ISR(USART_RXC_vect) { +if (txCount > 0){ //если буфер не пустой +UDR = usartTxBuf[txBufHead]; //записываем в UDR символ из буфера +txCount--; //уменьшаем счетчик символов +txBufHead++; //инкрементируем индекс головы буфера +if (txBufHead == SIZE_BUF) txBufHead = 0; +} +// rx_data = UDR0; //В нем данные из приемного буфера UDR переносятся в глобальную переменную rx_data +// rx_flag = 1; //выставляется флаг rx_flag, говорящий о том, что прием завершен +} \ No newline at end of file From c0bb094a3974689eb41234f480abb82bb0d4386a Mon Sep 17 00:00:00 2001 From: Qukich Date: Tue, 6 Jun 2023 19:59:18 +0300 Subject: [PATCH 04/14] rework hdlc protocol --- hdlc/fcs.c | 35 ----- hdlc/fcs.h | 25 ---- hdlc/hdlc.c | 363 +++++++++++++++++++--------------------------------- hdlc/hdlc.h | 136 +++----------------- 4 files changed, 150 insertions(+), 409 deletions(-) delete mode 100644 hdlc/fcs.c delete mode 100644 hdlc/fcs.h diff --git a/hdlc/fcs.c b/hdlc/fcs.c deleted file mode 100644 index caea596..0000000 --- a/hdlc/fcs.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "fcs.h" - -static const unsigned short fcstab[256] = { 0x0000, 0x1189, 0x2312, 0x329b, - 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, - 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, - 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, - 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, - 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, - 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, - 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, - 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, - 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, - 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, - 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, - 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581, - 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, - 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, - 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, - 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, - 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, - 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, - 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, - 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, - 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, - 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, - 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, - 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, - 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 }; - -FCS_SIZE calc_fcs(FCS_SIZE fcs, unsigned char value) { - return (fcs >> 8) ^ fcstab[(fcs ^ value) & 0xff]; -} \ No newline at end of file diff --git a/hdlc/fcs.h b/hdlc/fcs.h deleted file mode 100644 index 390d163..0000000 --- a/hdlc/fcs.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef FCS_H -#define FCS_H - -#ifdef CRC32 -#define FCS_INIT_VALUE 0xFFFFFFFF /* FCS initialization value. */ - #define FCS_GOOD_VALUE 0xDEBB20E3 /* FCS value for valid frames. */ - #define FCS_INVERT_MASK 0xFFFFFFFF /* Invert the FCS value accordingly to the specification */ - #define FCS_SIZE unsigned int -#else -#define FCS_INIT_VALUE 0xFFFF /* FCS initialization value. */ -#define FCS_GOOD_VALUE 0xF0B8 /* FCS value for valid frames. */ -#define FCS_INVERT_MASK 0xFFFF /* Invert the FCS value accordingly to the specification */ -#define FCS_SIZE unsigned short -#endif - -/** - * Вычисляет новый Frame Check Sequence на основе текущего значения и ценности данных. - * - * @param fcs Current FCS value - * @param value The value to be added - * @returns Calculated FCS value - */ -FCS_SIZE calc_fcs(FCS_SIZE fcs, unsigned char value); - -#endif //FCS_H diff --git a/hdlc/hdlc.c b/hdlc/hdlc.c index e829df2..96a7672 100644 --- a/hdlc/hdlc.c +++ b/hdlc/hdlc.c @@ -1,257 +1,164 @@ #include "hdlc.h" -#define HDLC_CONTROL_S_OR_U_FRAME_BIT 0 -#define HDLC_CONTROL_SEND_SEQ_NO_BIT 1 -#define HDLC_CONTROL_S_FRAME_TYPE_BIT 2 -#define HDLC_CONTROL_POLL_BIT 4 -#define HDLC_CONTROL_RECV_SEQ_NO_BIT 5 +#define FRAME_BOUNDARY_OCTET 0x7E -// HDLC Control type definitions -#define HDLC_CONTROL_TYPE_RECEIVE_READY 0 -#define HDLC_CONTROL_TYPE_RECEIVE_NOT_READY 1 -#define HDLC_CONTROL_TYPE_REJECT 2 -#define HDLC_CONTROL_TYPE_SELECTIVE_REJECT 3 +/* "Управляющий экранирующий октет", имеет битовую последовательность '01111101', (7D шестнадцатеричный) */ +#define CONTROL_ESCAPE_OCTET 0x7D -static hdlc_state_t hdlc_state = { - .control_escape = 0, - .fcs = FCS_INIT_VALUE, - .start_index = -1, - .end_index = -1, - .src_index = 0, - .dest_index = 0, -}; +/* Если любой из этих двух октетов появляется в передаваемых данных, отправляется экранирующий октет, */ +/* за которым следует исходный октет данных с инвертированным битом 5 */ +#define INVERT_OCTET 0x20 -int hdlc_set_state(hdlc_state_t *state) { - if (!state) { - return -EINVAL; - } +/* Последовательность проверки кадров (FCS) представляет собой 16-битный CRC-CCITT */ +/* Функция AVR Libc CRC - это _crc_ccitt_update() */ +#define CRC16_CCITT_INIT_VAL 0xFFFF - hdlc_state = *state; - return 0; +/* 16-битный копировальный аппарат с младшими и старшими байтами */ +#define low(x) ((x) & 0xFF) +#define high(x) (((x)>>8) & 0xFF) + +#define lo8(x) ((x)&0xff) +#define hi8(x) ((x)>>8) + +struct { + sendchar_type sendchar_function; + frame_handler_type frame_handler; + bool escape_character; + uint16_t frame_position; + uint16_t frame_checksum; + uint8_t receive_frame_buffer[MINIHDLC_MAX_FRAME_LENGTH + 1]; +} mhst; + +static uint16_t _crc_ccitt_update(uint16_t crc, uint8_t data) { + data ^= lo8(crc); + data ^= data << 4; + + return ((((uint16_t) data << 8) | hi8(crc)) ^ (uint8_t) (data >> 4) + ^ ((uint16_t) data << 3)); } -int hdlc_get_state(hdlc_state_t *state) { - if (!state) { - return -EINVAL; - } - - *state = hdlc_state; - return 0; +void hdlc_init(sendchar_type sendchar_function, + frame_handler_type frame_hander_function) { + mhst.sendchar_function = sendchar_function; + mhst.frame_handler = frame_hander_function; + mhst.frame_position = 0; + mhst.frame_checksum = CRC16_CCITT_INIT_VAL; + mhst.escape_character = false; } -void hdlc_escape_value(char value, char *dest, int *dest_index) { - // Проверяет и экранируйте значение, если это необходимо - if ((value == HDLC_FLAG_SEQUENCE) || (value == HDLC_CONTROL_ESCAPE)) { - dest[(*dest_index)++] = HDLC_CONTROL_ESCAPE; - value ^= 0x20; +/* Функция для отправки байта через UART*/ +static inline void hdlc_sendchar(uint8_t data) { + if (mhst.sendchar_function) { + (*mhst.sendchar_function)(data); } - - // Добавляет значение в буфер назначения и увеличьте индекс назначения - dest[(*dest_index)++] = value; } -hdlc_control_t hdlc_get_control_type(unsigned char control) { - hdlc_control_t value; - - // Проверяет, является ли S-фреймом (или U-фреймом) - if (control & (1 << HDLC_CONTROL_S_OR_U_FRAME_BIT)) { - // Проверяет, есть ли S-фрейм тип в Receive Ready (ACK) - if (((control >> HDLC_CONTROL_S_FRAME_TYPE_BIT) & 0x3) - == HDLC_CONTROL_TYPE_RECEIVE_READY) { - value.frame = HDLC_FRAME_ACK; - } else { - // Предположим, что это отрицательное подтверждение (NACK), так как функции "Receive Not Ready", "Selective Reject" и U-фреймы не поддерживаются. - value.frame = HDLC_FRAME_NACK; +/* Функция для поиска допустимого кадра HDLC по входящим данным */ +void hdlc_char_receiver(uint8_t data) { + /* FRAME FLAG */ + if (data == FRAME_BOUNDARY_OCTET) { + if (mhst.escape_character == true) { + mhst.escape_character = false; } - - // Добавляет номер последовательности приема из S-фрейма (или U-фрейма). - value.seq_no = (control >> HDLC_CONTROL_RECV_SEQ_NO_BIT); - } else { - // Должен быть I-фрейм, поэтому добавляет номер последовательности отправки (номер последовательности приема не используется). - value.frame = HDLC_FRAME_DATA; - value.seq_no = (control >> HDLC_CONTROL_SEND_SEQ_NO_BIT); - } - - return value; -} - -unsigned char hdlc_frame_control_type(hdlc_control_t *control) { - unsigned char value = 0; - - switch (control->frame) { - case HDLC_FRAME_DATA: - // Создает байт управления HDLC I-фрейма с установленным битом опроса. - value |= (control->seq_no << HDLC_CONTROL_SEND_SEQ_NO_BIT); - value |= (1 << HDLC_CONTROL_POLL_BIT); - break; - case HDLC_FRAME_ACK: - // Создает байт управления HDLC S-фрейма "Receive Ready" с сброшенным битом опроса. - value |= (control->seq_no << HDLC_CONTROL_RECV_SEQ_NO_BIT); - value |= (1 << HDLC_CONTROL_S_OR_U_FRAME_BIT); - break; - case HDLC_FRAME_NACK: - // Создает байт управления HDLC S-фрейма "Receive Ready" с сброшенным битом опроса. - value |= (control->seq_no << HDLC_CONTROL_RECV_SEQ_NO_BIT); - value |= (HDLC_CONTROL_TYPE_REJECT << HDLC_CONTROL_S_FRAME_TYPE_BIT); - value |= (1 << HDLC_CONTROL_S_OR_U_FRAME_BIT); - break; - } - - return value; -} - -void hdlc_get_data_reset() { - hdlc_get_data_reset_with_state(&hdlc_state); -} - -void hdlc_get_data_reset_with_state(hdlc_state_t *state) { - state->fcs = FCS_INIT_VALUE; - state->start_index = state->end_index = -1; - state->src_index = state->dest_index = 0; - state->control_escape = 0; -} - -int hdlc_get_data(hdlc_control_t *control, const char *src, - unsigned int src_len, char *dest, unsigned int *dest_len) { - return hdlc_get_data_with_state(&hdlc_state, control, src, src_len, dest, dest_len); -} - -int hdlc_get_data_with_state(hdlc_state_t *state, hdlc_control_t *control, const char *src, - unsigned int src_len, char *dest, unsigned int *dest_len) { - int ret; - char value; - unsigned int i; - - // Проверка, что все параметры валидны - if (!state || !control || !src || !dest || !dest_len) { - return -EINVAL; - } - - // Проход по байтам данных - for (i = 0; i < src_len; i++) { - // В первую очередь находит последовательность начальных флагов - if (state->start_index < 0) { - if (src[i] == HDLC_FLAG_SEQUENCE) { - // Проверяет, присутствует ли дополнительный байт последовательности флагов - if ((i < (src_len - 1)) && (src[i + 1] == HDLC_FLAG_SEQUENCE)) { - // Согласно протоколу HDLC, просто выполните цикл снова, чтобы молча отбросить его. - continue; - } - - state->start_index = state->src_index; - } - } else { - // Проверка последовательность флага окончания - if (src[i] == HDLC_FLAG_SEQUENCE) { - // Проверка, присутствует ли дополнительный байт последовательности флага или был ли он получен ранее. - if (((i < (src_len - 1)) && (src[i + 1] == HDLC_FLAG_SEQUENCE)) - || ((state->start_index + 1) == state->src_index)) { - // Согласно протоколу HDLC, просто выполните цикл снова, чтобы молча отбросить его. - continue; - } - - state->end_index = state->src_index; - break; - } else if (src[i] == HDLC_CONTROL_ESCAPE) { - state->control_escape = 1; - } else { - // Обновите значение на основе полученного символа управления экранирования (control escape) - if (state->control_escape) { - state->control_escape = 0; - value = src[i] ^ 0x20; - } else { - value = src[i]; - } - - // Теперь обновите значение FCS (контрольной суммы фрейма). - state->fcs = calc_fcs(state->fcs, value); - - if (state->src_index == state->start_index + 2) { - // Поле управления (control field) находится вторым байтом после последовательности стартового флага. - *control = hdlc_get_control_type(value); - } else if (state->src_index > (state->start_index + 2)) { - // Начинает добавлять значения данных после поля управления (control field) в буфер. - dest[state->dest_index++] = value; - } - } + /* Если обнаружен допустимый кадр */ + else if ((mhst.frame_position >= 2) + && (mhst.frame_checksum + == ((mhst.receive_frame_buffer[mhst.frame_position - 1] + << 8) + | (mhst.receive_frame_buffer[mhst.frame_position + - 2] & 0xff)))) + { + /* Вызовите пользовательскую функцию и передайте ей фрейм */ + (*mhst.frame_handler)(mhst.receive_frame_buffer, + mhst.frame_position - 2); } - state->src_index++; + mhst.frame_position = 0; + mhst.frame_checksum = CRC16_CCITT_INIT_VAL; + return; } - // Проверьте наличие неверного фрейма (отсутствие последовательности стартового или окончательного флага). - if ((state->start_index < 0) || (state->end_index < 0)) { - // Return no message and make sure destination length is 0 - *dest_len = 0; - ret = -ENOMSG; - } else { - // Фрейм имеет размер не менее 4 байтов и содержит допустимое значение FCS (контрольной суммы). - if ((state->end_index < (state->start_index + 4)) - || (state->fcs != FCS_GOOD_VALUE)) { - // Возвращает ошибку FCS (контрольной суммы) и указывает, что данные до последовательности флага окончания в буфере должны быть отброшены. - *dest_len = i; - ret = -EIO; - } else { - // Возвращает успешный результат и указывает, что данные до последовательности флага окончания в буфере должны быть отброшены. - *dest_len = state->dest_index - sizeof(state->fcs); - ret = i; - } - - // Сбрасывает значения для следующего фрейма - hdlc_get_data_reset_with_state(state); + if (mhst.escape_character) { + mhst.escape_character = false; + data ^= INVERT_OCTET; + } else if (data == CONTROL_ESCAPE_OCTET) { + mhst.escape_character = true; + return; } - return ret; + mhst.receive_frame_buffer[mhst.frame_position] = data; + + if (mhst.frame_position - 2 >= 0) { + mhst.frame_checksum = _crc_ccitt_update(mhst.frame_checksum, + mhst.receive_frame_buffer[mhst.frame_position - 2]); + } + + mhst.frame_position++; + + if (mhst.frame_position == MINIHDLC_MAX_FRAME_LENGTH) { + mhst.frame_position = 0; + mhst.frame_checksum = CRC16_CCITT_INIT_VAL; + } } -int hdlc_frame_data(hdlc_control_t *control, const char *src, - unsigned int src_len, char *dest, unsigned int *dest_len) { - unsigned int i; - int dest_index = 0; - unsigned char value = 0; - FCS_SIZE fcs = FCS_INIT_VALUE; +/* Оберните заданные данные во фрейм HDLC и отправляйте их по байту за раз */ +void hdlc_send_frame(const uint8_t *frame_buffer, uint8_t frame_length) { + uint8_t data; + uint16_t fcs = CRC16_CCITT_INIT_VAL; - // Проверка, что все параметры валидны - if (!control || (!src && (src_len > 0)) || !dest || !dest_len) { - return -EINVAL; - } + hdlc_sendchar((uint8_t) FRAME_BOUNDARY_OCTET); - // Добавления последовательности стартового флага. - dest[dest_index++] = HDLC_FLAG_SEQUENCE; - - // Добавление адреса "все станции" из протокола HDLC (широковещательный адрес). - fcs = calc_fcs(fcs, HDLC_ALL_STATION_ADDR); - hdlc_escape_value(HDLC_ALL_STATION_ADDR, dest, &dest_index); - - // Добавление значения поля управления фрейма. - value = hdlc_frame_control_type(control); - fcs = calc_fcs(fcs, value); - hdlc_escape_value(value, dest, &dest_index); - - // Только фреймы типа DATA должны содержать данные. - if (control->frame == HDLC_FRAME_DATA) { - // Вычислите контрольную сумму FCS и экранируйте данные. - for (i = 0; i < src_len; i++) { - fcs = calc_fcs(fcs, src[i]); - hdlc_escape_value(src[i], dest, &dest_index); + while (frame_length) { + data = *frame_buffer++; + fcs = _crc_ccitt_update(fcs, data); + if ((data == CONTROL_ESCAPE_OCTET) || (data == FRAME_BOUNDARY_OCTET)) { + hdlc_sendchar((uint8_t) CONTROL_ESCAPE_OCTET); + data ^= INVERT_OCTET; } + hdlc_sendchar((uint8_t) data); + frame_length--; } - - // Инвертирует значения FCS в соответствии со спецификацией. - fcs ^= FCS_INVERT_MASK; - - // Проходит по байтам FCS и выполните экранирование значений. - for (i = 0; i < sizeof(fcs); i++) { - value = ((fcs >> (8 * i)) & 0xFF); - hdlc_escape_value(value, dest, &dest_index); + data = low(fcs); + if ((data == CONTROL_ESCAPE_OCTET) || (data == FRAME_BOUNDARY_OCTET)) { + hdlc_sendchar((uint8_t) CONTROL_ESCAPE_OCTET); + data ^= (uint8_t) INVERT_OCTET; } - - // Добавляет последовательность флага окончания и обновляет длину фрейма. - dest[dest_index++] = HDLC_FLAG_SEQUENCE; - *dest_len = dest_index; - - return 0; + hdlc_sendchar((uint8_t) data); + data = high(fcs); + if ((data == CONTROL_ESCAPE_OCTET) || (data == FRAME_BOUNDARY_OCTET)) { + hdlc_sendchar(CONTROL_ESCAPE_OCTET); + data ^= INVERT_OCTET; + } + hdlc_sendchar(data); + hdlc_sendchar(FRAME_BOUNDARY_OCTET); } -int hello(){ - return 1; +/* Оберните заданные данные во фрейм HDLC и отправьте их в статический буфер */ + +static uint8_t frame_buffer[MINIHDLC_MAX_FRAME_LENGTH + 1]; +static uint32_t frame_buffer_size = 0; + +static void buffer_init() { + frame_buffer_size = 0; +} + +static void buffer_push(uint8_t data) { + if (frame_buffer_size >= MINIHDLC_MAX_FRAME_LENGTH) { + return; + } + frame_buffer[frame_buffer_size] = data; + frame_buffer_size++; +} + +void hdlc_send_frame_to_buffer(const uint8_t *frame_buffer, uint8_t frame_length) { + mhst.sendchar_function = buffer_push; + buffer_init(); + hdlc_send_frame(frame_buffer, frame_length); +} + +uint8_t *hdlc_get_buffer() { + return frame_buffer; +} + +uint32_t hdlc_get_buffer_size() { + return frame_buffer_size; } \ No newline at end of file diff --git a/hdlc/hdlc.h b/hdlc/hdlc.h index 6a64638..035fc0a 100644 --- a/hdlc/hdlc.h +++ b/hdlc/hdlc.h @@ -1,128 +1,22 @@ -/** - * @file hdlc.h - */ +#ifndef hdlc_h +#define hdlc_h -#ifndef HDLC_H -#define HDLC_H +#include +#include -#include "fcs.h" -#include +typedef void (*sendchar_type)(uint8_t data); +typedef void (*frame_handler_type)(const uint8_t *frame_buffer, + uint16_t frame_length); -/** HDLC флаг начала и конца */ -#define HDLC_FLAG_SEQUENCE 0x7E +#define MINIHDLC_MAX_FRAME_LENGTH 64 -/** HDLC управляющее выходное значение */ -#define HDLC_CONTROL_ESCAPE 0x7D +void hdlc_init(sendchar_type sendchar_function, + frame_handler_type frame_hander_function); +void hdlc_char_receiver(uint8_t data); +void hdlc_send_frame(const uint8_t *frame_buffer, uint8_t frame_length); -/** HDLC все адресса станций */ -#define HDLC_ALL_STATION_ADDR 0xFF - -/** Поддерживаемые HDLC фрейм типы */ -typedef enum { - HDLC_FRAME_DATA, - HDLC_FRAME_ACK, - HDLC_FRAME_NACK, -} hdlc_frame_t; - -/** Информация о поле управления */ -typedef struct { - hdlc_frame_t frame; - unsigned char seq_no :3; -} hdlc_control_t; - -/** Перменные для hdlc_get_data и hdlc_get_data_with_state - * для отслеживания полученных буферов - */ -typedef struct { - char control_escape; - FCS_SIZE fcs; - int start_index; - int end_index; - int src_index; - int dest_index; -} hdlc_state_t; - -/** - * Установить состояние hdlc - * - * @param[in] state состояние hdlc, которое будет использоваться - * @retval 0 Успешно - * @retval -EINVAL Невалидный параметр - */ -int hdlc_set_state(hdlc_state_t *state); - -/** - * Получить текущее состояние hdlc - * - * @param[out] state Текущее состояние hdlc - * @retval 0 Success - * @retval -EINVAL Невалидный параметр - */ -int hdlc_get_state(hdlc_state_t *state); - -/** - * Извлекает данные из указанного буфера, содержащего HDLC-фрейм. - * Фреймы могут быть разобраны из нескольких буферов при получении через uart - * - * @param[out] control Структура поля управления с типом фрейма и номером последовательности. - * @param[in] src Основной буффер для фрейма - * @param[in] src_len Длинна основного буффера - * @param[out] dest Целевой буффер (должен быть способен содержать максимальный размер кадра) - * @param[out] dest_len Длинна целевого буффера - * @retval >=0 Успешно (размер возвращаемого значения должен быть удален из исходного буфера) - * @retval -EINVAL Невалидный параметр - * @retval -INMSG Невалидное сообщение - * @retval -EIO Невалидный FCS (размер dest_len должен быть удален из исходного буфера) - * - * @see hdlc_get_data_with_state - */ -int hdlc_get_data(hdlc_control_t *control, const char *src, - unsigned int src_len, char *dest, unsigned int *dest_len); - -/** - * Извлекает данные из указанного буфера, содержащего HDLC-фрейм. - * Фреймы могут быть разобраны из нескольких буферов при получении через uart - * - * Эта функция вариация @ref hdlc_get_data - * Разница только в первом аргументе: hdlc_state_t *state - * Данные под этим указателем используются для отслеживания внутренних буферов. - * - * @see hdlc_get_data - */ -int hdlc_get_data_with_state(hdlc_state_t *state, hdlc_control_t *control, const char *src, - unsigned int src_len, char *dest, unsigned int *dest_len); - - -/** - * Сбрасывает значения, используемые в функции hdlc_get_data для отслеживания полученных буферов - */ -void hdlc_get_data_reset(); - -/** - * Эта функция вариация @ref hdlc_get_data_reset - * Сбрасывает значения состояния, которые находятся под указателем, указанным в качестве аргумента - * - * Эта функция должна быть вызвана перед первым вызовом hdlc_get_data_with_state - * когда используется пользовательское хранилище состояний. - * - * @see hdlc_get_data_reset - */ -void hdlc_get_data_reset_with_state(hdlc_state_t *state); - -/** - * Создает кадр HDLC с указанным буфером данных. - * - * @param[in] control Структура поля управления с типом кадра и порядковым номером - * @param[in] src Исходный буфер с данными - * @param[in] src_len Длинна исходного буффера - * @param[out] dest Целевой буфер (должно быть больше, чем исходный буфер) - * @param[out] dest_len Длинна целевого буффера - * @retval 0 Success - * @retval -EINVAL Невалидный параметр - */ -int hdlc_frame_data(hdlc_control_t *control, const char *src, - unsigned int src_len, char *dest, unsigned int *dest_len); - -int hello(); +void hdlc_send_frame_to_buffer(const uint8_t *frame_buffer, uint8_t frame_length); +uint8_t *hdlc_get_buffer(); +uint32_t hdlc_get_buffer_size(); #endif \ No newline at end of file From 4e3047071d7352730273e86d7c6d53c0a5238701 Mon Sep 17 00:00:00 2001 From: Kirill Kurshakow Date: Wed, 7 Jun 2023 12:34:54 +0300 Subject: [PATCH 05/14] fix --- main.c | 25 +++++++++++++ uart.c | 101 -------------------------------------------------- uart_module.c | 82 ++++++++++++++++++++++++++++++++++++++++ uart_module.h | 20 ++++++++++ 4 files changed, 127 insertions(+), 101 deletions(-) create mode 100644 main.c delete mode 100644 uart.c create mode 100644 uart_module.c create mode 100644 uart_module.h diff --git a/main.c b/main.c new file mode 100644 index 0000000..a421409 --- /dev/null +++ b/main.c @@ -0,0 +1,25 @@ +#include +#include "config.h" +#include +#include +#include +#include "uart_hal.h" + + +int main(void) +{ + + uint8_t data = 'A'; + + uart_init(9600,0); + uart_send_byte(data); + sei(); + while (1) + { + if(uart_read_count() > 0){ + data = uart_read(); + uart_send_byte(data); + } + + } +} \ No newline at end of file diff --git a/uart.c b/uart.c deleted file mode 100644 index 2b77e0c..0000000 --- a/uart.c +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include -#include - -#define F_CPU 16000000 -#define SIZE_BUF 8 - -//кольцевой (циклический) буфер -volatile unsigned char usartTxBuf[SIZE_BUF]; -unsigned char txBufTail = 0; //"указатель" хвоста буфера -unsigned char txBufHead = 0; //"указатель" головы буфера -volatile unsigned char txCount = 0; //счетчик символов - -uint8_t receive = 0; -uint8_t rx_data = 0; -volatile uint8_t rx_flag = 0; - -void UARTInit(void) { -UCSR1B=0; UCSR1C=0; // Обнулим, на всякий случай регистры статуса и контроля. -UBRR0H = 0; // Старшие биты регистра скорости. -UBRR0L = 103; //скорость передачи данных 9600 -UCSR0B = (1«RXEN0)|(1«TXEN0)|(1«RXCIE0)|(1«TXCIE0)|(0«UDRIE0);//Включаем (подключаем ножки контроллера) приём и передачу по UART. -UCSR0C = (1«UCSZ01)|(1«UCSZ00); //8 bit - -} - -void UARTSend(uint8_t data) { -while (!(UCSR0A & (1«UDRE0))); // Ждём опустошения буфера передачи (читаем флаг). -UDR0 = data; // Записываем в регистр значение переменной "data" для передачи. -} - -//"очищает" буфер -void USART_FlushTxBuf(void) -{ -txBufTail = 0; -txCount = 0; -txBufHead = 0; - -//положить символ в буфер -void USART_PutChar(unsigned char sym) -{ -if(((UCSRA0 & (1«UDRE0)) != 0) && (txCount == 0)) UDR0 = sym; //Если модуль USART не занят и передающий буфер пустой, -else { //символ записывается в регистр UDR -if (txCount < SIZE_BUF){ //если в буфере еще есть место -usartTxBuf[txBufTail] = sym; //помещаем в него символ -txCount++; //инкрементируем счетчик символов -txBufTail++; //и индекс хвоста буфера -if (txBufTail == SIZE_BUF) txBufTail = 0; -} -} -} -//взять символ из буфера -unsigned char GetChar(void) -{ -unsigned char sym = 0; -if (count > 0){ //если буфер не пустой -sym = cycleBuf[head]; //считываем символ из буфера -count--; //уменьшаем счетчик символов -head++; //инкрементируем индекс головы буфера -if (head == SIZE_BUF) head = 0; -} -return sym; -} - -//функция загрузки строк -void USART_SendStr(unsigned char * data) -{ -unsigned char sym; -while(*data){ // пока не будет считан символ конца строки -sym = *data++; -USART_PutChar(sym); -} -} -// unsigned char UARTGet() { -// while(!rx_flag); //пока значение флага не станет равно "1" -// rx_flag = 0; -// return rx_data; //возвращет состояние переменной rx_data -// } - -int main(void) { -sei(); -UARTInit(); -DDRL = 0b11111111; // Определим порт "L" на выход -while(1) { -receive = UARTGet(); -receive++; -UARTSend(receive); -} -} - - -ISR(USART_RXC_vect) { -if (txCount > 0){ //если буфер не пустой -UDR = usartTxBuf[txBufHead]; //записываем в UDR символ из буфера -txCount--; //уменьшаем счетчик символов -txBufHead++; //инкрементируем индекс головы буфера -if (txBufHead == SIZE_BUF) txBufHead = 0; -} -// rx_data = UDR0; //В нем данные из приемного буфера UDR переносятся в глобальную переменную rx_data -// rx_flag = 1; //выставляется флаг rx_flag, говорящий о том, что прием завершен -} \ No newline at end of file diff --git a/uart_module.c b/uart_module.c new file mode 100644 index 0000000..6fa0926 --- /dev/null +++ b/uart_module.c @@ -0,0 +1,82 @@ +#include "uart_hal.h" + +volatile static uint8_t rx_buffer[RX_BUFFER_SIZE] = {0}; +volatile static uint16_t rx_count = 0; +volatile static uint8_t uart_tx_busy = 1; + +ISR(USART_RX_vect){ + + volatile static uint16_t rx_write_pos = 0; + + rx_buffer[rx_write_pos] = UDR0; + rx_count++; + rx_write_pos++; + if(rx_write_pos >= RX_BUFFER_SIZE){ + rx_write_pos = 0; + } + +} + + +ISR(USART_TX_vect){ + uart_tx_busy = 1; +} + + +void uart_init(uint32_t baud,uint8_t high_speed){ + + uint8_t speed = 16; + + if(high_speed != 0){ + speed = 8; + UCSR0A |= 1 << U2X0; + } + + baud = (F_CPU/(speed*baud)) - 1; + + UBRR0H = (baud & 0x0F00) >> 8; + UBRR0L = (baud & 0x00FF); + + UCSR0B |= (1 << TXEN0) | (1 << RXEN0) | (1 << TXCIE0) | (1 << RXCIE0); + +} + + +void uart_send_byte(uint8_t c){ + while(uart_tx_busy == 0); + uart_tx_busy = 0; + UDR0 = c; +} + +void uart_send_array(uint8_t *c,uint16_t len){ + for(uint16_t i = 0; i < len;i++){ + uart_send_byte(c[i]); + } +} + +void uart_send_string(uint8_t *c){ + uint16_t i = 0; + do{ + uart_send_byte(c[i]); + i++; + + }while(c[i] != '\0'); + uart_send_byte(c[i]); +} + +uint16_t uart_read_count(void){ + return rx_count; +} + +uint8_t uart_read(void){ + static uint16_t rx_read_pos = 0; + uint8_t data = 0; + + data = rx_buffer[rx_read_pos]; + rx_read_pos++; + rx_count--; + if(rx_read_pos >= RX_BUFFER_SIZE){ + rx_read_pos = 0; + } + return data; +} \ No newline at end of file diff --git a/uart_module.h b/uart_module.h new file mode 100644 index 0000000..284a941 --- /dev/null +++ b/uart_module.h @@ -0,0 +1,20 @@ +#ifndef UART_HAL_H_ +#define UART_HAL_H_ + + +#include +#include "config.h" +#include +#include +#include + +#define RX_BUFFER_SIZE 128 + +void uart_init(uint32_t baud,uint8_t high_speed); +void uart_send_byte(uint8_t c); +void uart_send_array(uint8_t *c,uint16_t len); +void uart_send_string(uint8_t *c); +uint16_t uart_read_count(void); +uint8_t uart_read(void); + +#endif /* UART_HAL_H_ */ \ No newline at end of file From bfd1776bba773023f6afd9062b29f78b4d78cf80 Mon Sep 17 00:00:00 2001 From: Kirill Kurshakow Date: Wed, 7 Jun 2023 12:41:42 +0300 Subject: [PATCH 06/14] fix --- main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.c b/main.c index a421409..93e2b83 100644 --- a/main.c +++ b/main.c @@ -8,7 +8,7 @@ int main(void) { - + //example uint8_t data = 'A'; uart_init(9600,0); From d3b39dbc9f3feb8cf1b50e57a7bbf0b442907dff Mon Sep 17 00:00:00 2001 From: Kirill Kurshakow Date: Wed, 7 Jun 2023 13:02:45 +0300 Subject: [PATCH 07/14] fix --- uart_module.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uart_module.c b/uart_module.c index 6fa0926..c4cbc2a 100644 --- a/uart_module.c +++ b/uart_module.c @@ -3,7 +3,7 @@ volatile static uint8_t rx_buffer[RX_BUFFER_SIZE] = {0}; volatile static uint16_t rx_count = 0; volatile static uint8_t uart_tx_busy = 1; - +// кольцевой буффер ISR(USART_RX_vect){ volatile static uint16_t rx_write_pos = 0; From a154d9290357e15c1e722dc50bf433b1bb8e5e9c Mon Sep 17 00:00:00 2001 From: Qukich Date: Wed, 14 Jun 2023 15:36:47 +0300 Subject: [PATCH 08/14] rework hdlc protocol, example in main.c --- hdlc/crc.c | 66 ++++++++++++++++++++ hdlc/crc.h | 25 ++++++++ hdlc/hdlc.c | 164 ------------------------------------------------ hdlc/hdlc.h | 175 +++++++++++++++++++++++++++++++++++++++++++++++----- hdlc/main.c | 33 ++++++++++ 5 files changed, 284 insertions(+), 179 deletions(-) create mode 100644 hdlc/crc.c create mode 100644 hdlc/crc.h delete mode 100644 hdlc/hdlc.c create mode 100644 hdlc/main.c diff --git a/hdlc/crc.c b/hdlc/crc.c new file mode 100644 index 0000000..121c210 --- /dev/null +++ b/hdlc/crc.c @@ -0,0 +1,66 @@ +#include "crc.h" + +const int8_t size = 2; +const CRC_t CRC_INIT = 0xFFFFU; +const CRC_t CRC_FINALXOR = 0xFFFFU; +const CRC_t CRC_GOOD = 0xF0B8U; + +static const uint16_t CRC_TAB[256U] = { + 0x0000UL, 0x1189UL, 0x2312UL, 0x329BUL, 0x4624UL, 0x57ADUL, 0x6536UL, 0x74BFUL, + 0x8C48UL, 0x9DC1UL, 0xAF5AUL, 0xBED3UL, 0xCA6CUL, 0xDBE5UL, 0xE97EUL, 0xF8F7UL, + 0x1081UL, 0x0108UL, 0x3393UL, 0x221AUL, 0x56A5UL, 0x472CUL, 0x75B7UL, 0x643EUL, + 0x9CC9UL, 0x8D40UL, 0xBFDBUL, 0xAE52UL, 0xDAEDUL, 0xCB64UL, 0xF9FFUL, 0xE876UL, + 0x2102UL, 0x308BUL, 0x0210UL, 0x1399UL, 0x6726UL, 0x76AFUL, 0x4434UL, 0x55BDUL, + 0xAD4AUL, 0xBCC3UL, 0x8E58UL, 0x9FD1UL, 0xEB6EUL, 0xFAE7UL, 0xC87CUL, 0xD9F5UL, + 0x3183UL, 0x200AUL, 0x1291UL, 0x0318UL, 0x77A7UL, 0x662EUL, 0x54B5UL, 0x453CUL, + 0xBDCBUL, 0xAC42UL, 0x9ED9UL, 0x8F50UL, 0xFBEFUL, 0xEA66UL, 0xD8FDUL, 0xC974UL, + 0x4204UL, 0x538DUL, 0x6116UL, 0x709FUL, 0x0420UL, 0x15A9UL, 0x2732UL, 0x36BBUL, + 0xCE4CUL, 0xDFC5UL, 0xED5EUL, 0xFCD7UL, 0x8868UL, 0x99E1UL, 0xAB7AUL, 0xBAF3UL, + 0x5285UL, 0x430CUL, 0x7197UL, 0x601EUL, 0x14A1UL, 0x0528UL, 0x37B3UL, 0x263AUL, + 0xDECDUL, 0xCF44UL, 0xFDDFUL, 0xEC56UL, 0x98E9UL, 0x8960UL, 0xBBFBUL, 0xAA72UL, + 0x6306UL, 0x728FUL, 0x4014UL, 0x519DUL, 0x2522UL, 0x34ABUL, 0x0630UL, 0x17B9UL, + 0xEF4EUL, 0xFEC7UL, 0xCC5CUL, 0xDDD5UL, 0xA96AUL, 0xB8E3UL, 0x8A78UL, 0x9BF1UL, + 0x7387UL, 0x620EUL, 0x5095UL, 0x411CUL, 0x35A3UL, 0x242AUL, 0x16B1UL, 0x0738UL, + 0xFFCFUL, 0xEE46UL, 0xDCDDUL, 0xCD54UL, 0xB9EBUL, 0xA862UL, 0x9AF9UL, 0x8B70UL, + 0x8408UL, 0x9581UL, 0xA71AUL, 0xB693UL, 0xC22CUL, 0xD3A5UL, 0xE13EUL, 0xF0B7UL, + 0x0840UL, 0x19C9UL, 0x2B52UL, 0x3ADBUL, 0x4E64UL, 0x5FEDUL, 0x6D76UL, 0x7CFFUL, + 0x9489UL, 0x8500UL, 0xB79BUL, 0xA612UL, 0xD2ADUL, 0xC324UL, 0xF1BFUL, 0xE036UL, + 0x18C1UL, 0x0948UL, 0x3BD3UL, 0x2A5AUL, 0x5EE5UL, 0x4F6CUL, 0x7DF7UL, 0x6C7EUL, + 0xA50AUL, 0xB483UL, 0x8618UL, 0x9791UL, 0xE32EUL, 0xF2A7UL, 0xC03CUL, 0xD1B5UL, + 0x2942UL, 0x38CBUL, 0x0A50UL, 0x1BD9UL, 0x6F66UL, 0x7EEFUL, 0x4C74UL, 0x5DFDUL, + 0xB58BUL, 0xA402UL, 0x9699UL, 0x8710UL, 0xF3AFUL, 0xE226UL, 0xD0BDUL, 0xC134UL, + 0x39C3UL, 0x284AUL, 0x1AD1UL, 0x0B58UL, 0x7FE7UL, 0x6E6EUL, 0x5CF5UL, 0x4D7CUL, + 0xC60CUL, 0xD785UL, 0xE51EUL, 0xF497UL, 0x8028UL, 0x91A1UL, 0xA33AUL, 0xB2B3UL, + 0x4A44UL, 0x5BCDUL, 0x6956UL, 0x78DFUL, 0x0C60UL, 0x1DE9UL, 0x2F72UL, 0x3EFBUL, + 0xD68DUL, 0xC704UL, 0xF59FUL, 0xE416UL, 0x90A9UL, 0x8120UL, 0xB3BBUL, 0xA232UL, + 0x5AC5UL, 0x4B4CUL, 0x79D7UL, 0x685EUL, 0x1CE1UL, 0x0D68UL, 0x3FF3UL, 0x2E7AUL, + 0xE70EUL, 0xF687UL, 0xC41CUL, 0xD595UL, 0xA12AUL, 0xB0A3UL, 0x8238UL, 0x93B1UL, + 0x6B46UL, 0x7ACFUL, 0x4854UL, 0x59DDUL, 0x2D62UL, 0x3CEBUL, 0x0E70UL, 0x1FF9UL, + 0xF78FUL, 0xE606UL, 0xD49DUL, 0xC514UL, 0xB1ABUL, 0xA022UL, 0x92B9UL, 0x8330UL, + 0x7BC7UL, 0x6A4EUL, 0x58D5UL, 0x495CUL, 0x3DE3UL, 0x2C6AUL, 0x1EF1UL, 0x0F78UL +}; + +void crc_init(CRC16_CCITT* crc_obj) { + crc_obj->crc = CRC_INIT; + crc_obj->size = 2; +} + +void crc_update(CRC16_CCITT* crc_obj, uint8_t data) { + crc_obj->crc = (crc_obj->crc >> 8U) ^ CRC_TAB[(crc_obj->crc ^ data) & CRC_FINALXOR]; +} + +bool crc_good(const CRC16_CCITT* crc_obj) { + return crc_obj->crc == 0xF0B8U; +} + +void crc_final(CRC16_CCITT* crc_obj) { + crc_obj->crc ^= CRC_FINALXOR; +} + +uint8_t crc_get(const CRC16_CCITT* crc_obj, int8_t pos) { + if (pos == 0){ + return crc_obj->crc; + } else{ + return crc_obj->crc >> 8U; + } +} \ No newline at end of file diff --git a/hdlc/crc.h b/hdlc/crc.h new file mode 100644 index 0000000..4b88f0d --- /dev/null +++ b/hdlc/crc.h @@ -0,0 +1,25 @@ +// +// Created by 79513 on 13.06.2023. +// + +#ifndef CRC16_CCITT_H_ +#define CRC16_CCITT_H_ + +#include +#include + +typedef uint16_t CRC_t; + +typedef struct { + const CRC_t* CRC_TAB; + CRC_t crc; + int size; +} CRC16_CCITT; + +void crc_init(CRC16_CCITT* crc_obj); +void crc_update(CRC16_CCITT* crc_obj, uint8_t data); +bool crc_good(const CRC16_CCITT* crc_obj); +void crc_final(CRC16_CCITT* crc_obj); +uint8_t crc_get(const CRC16_CCITT* crc_obj, int8_t pos); + +#endif diff --git a/hdlc/hdlc.c b/hdlc/hdlc.c deleted file mode 100644 index 96a7672..0000000 --- a/hdlc/hdlc.c +++ /dev/null @@ -1,164 +0,0 @@ -#include "hdlc.h" - -#define FRAME_BOUNDARY_OCTET 0x7E - -/* "Управляющий экранирующий октет", имеет битовую последовательность '01111101', (7D шестнадцатеричный) */ -#define CONTROL_ESCAPE_OCTET 0x7D - -/* Если любой из этих двух октетов появляется в передаваемых данных, отправляется экранирующий октет, */ -/* за которым следует исходный октет данных с инвертированным битом 5 */ -#define INVERT_OCTET 0x20 - -/* Последовательность проверки кадров (FCS) представляет собой 16-битный CRC-CCITT */ -/* Функция AVR Libc CRC - это _crc_ccitt_update() */ -#define CRC16_CCITT_INIT_VAL 0xFFFF - -/* 16-битный копировальный аппарат с младшими и старшими байтами */ -#define low(x) ((x) & 0xFF) -#define high(x) (((x)>>8) & 0xFF) - -#define lo8(x) ((x)&0xff) -#define hi8(x) ((x)>>8) - -struct { - sendchar_type sendchar_function; - frame_handler_type frame_handler; - bool escape_character; - uint16_t frame_position; - uint16_t frame_checksum; - uint8_t receive_frame_buffer[MINIHDLC_MAX_FRAME_LENGTH + 1]; -} mhst; - -static uint16_t _crc_ccitt_update(uint16_t crc, uint8_t data) { - data ^= lo8(crc); - data ^= data << 4; - - return ((((uint16_t) data << 8) | hi8(crc)) ^ (uint8_t) (data >> 4) - ^ ((uint16_t) data << 3)); -} - -void hdlc_init(sendchar_type sendchar_function, - frame_handler_type frame_hander_function) { - mhst.sendchar_function = sendchar_function; - mhst.frame_handler = frame_hander_function; - mhst.frame_position = 0; - mhst.frame_checksum = CRC16_CCITT_INIT_VAL; - mhst.escape_character = false; -} - -/* Функция для отправки байта через UART*/ -static inline void hdlc_sendchar(uint8_t data) { - if (mhst.sendchar_function) { - (*mhst.sendchar_function)(data); - } -} - -/* Функция для поиска допустимого кадра HDLC по входящим данным */ -void hdlc_char_receiver(uint8_t data) { - /* FRAME FLAG */ - if (data == FRAME_BOUNDARY_OCTET) { - if (mhst.escape_character == true) { - mhst.escape_character = false; - } - /* Если обнаружен допустимый кадр */ - else if ((mhst.frame_position >= 2) - && (mhst.frame_checksum - == ((mhst.receive_frame_buffer[mhst.frame_position - 1] - << 8) - | (mhst.receive_frame_buffer[mhst.frame_position - - 2] & 0xff)))) - { - /* Вызовите пользовательскую функцию и передайте ей фрейм */ - (*mhst.frame_handler)(mhst.receive_frame_buffer, - mhst.frame_position - 2); - } - mhst.frame_position = 0; - mhst.frame_checksum = CRC16_CCITT_INIT_VAL; - return; - } - - if (mhst.escape_character) { - mhst.escape_character = false; - data ^= INVERT_OCTET; - } else if (data == CONTROL_ESCAPE_OCTET) { - mhst.escape_character = true; - return; - } - - mhst.receive_frame_buffer[mhst.frame_position] = data; - - if (mhst.frame_position - 2 >= 0) { - mhst.frame_checksum = _crc_ccitt_update(mhst.frame_checksum, - mhst.receive_frame_buffer[mhst.frame_position - 2]); - } - - mhst.frame_position++; - - if (mhst.frame_position == MINIHDLC_MAX_FRAME_LENGTH) { - mhst.frame_position = 0; - mhst.frame_checksum = CRC16_CCITT_INIT_VAL; - } -} - -/* Оберните заданные данные во фрейм HDLC и отправляйте их по байту за раз */ -void hdlc_send_frame(const uint8_t *frame_buffer, uint8_t frame_length) { - uint8_t data; - uint16_t fcs = CRC16_CCITT_INIT_VAL; - - hdlc_sendchar((uint8_t) FRAME_BOUNDARY_OCTET); - - while (frame_length) { - data = *frame_buffer++; - fcs = _crc_ccitt_update(fcs, data); - if ((data == CONTROL_ESCAPE_OCTET) || (data == FRAME_BOUNDARY_OCTET)) { - hdlc_sendchar((uint8_t) CONTROL_ESCAPE_OCTET); - data ^= INVERT_OCTET; - } - hdlc_sendchar((uint8_t) data); - frame_length--; - } - data = low(fcs); - if ((data == CONTROL_ESCAPE_OCTET) || (data == FRAME_BOUNDARY_OCTET)) { - hdlc_sendchar((uint8_t) CONTROL_ESCAPE_OCTET); - data ^= (uint8_t) INVERT_OCTET; - } - hdlc_sendchar((uint8_t) data); - data = high(fcs); - if ((data == CONTROL_ESCAPE_OCTET) || (data == FRAME_BOUNDARY_OCTET)) { - hdlc_sendchar(CONTROL_ESCAPE_OCTET); - data ^= INVERT_OCTET; - } - hdlc_sendchar(data); - hdlc_sendchar(FRAME_BOUNDARY_OCTET); -} - -/* Оберните заданные данные во фрейм HDLC и отправьте их в статический буфер */ - -static uint8_t frame_buffer[MINIHDLC_MAX_FRAME_LENGTH + 1]; -static uint32_t frame_buffer_size = 0; - -static void buffer_init() { - frame_buffer_size = 0; -} - -static void buffer_push(uint8_t data) { - if (frame_buffer_size >= MINIHDLC_MAX_FRAME_LENGTH) { - return; - } - frame_buffer[frame_buffer_size] = data; - frame_buffer_size++; -} - -void hdlc_send_frame_to_buffer(const uint8_t *frame_buffer, uint8_t frame_length) { - mhst.sendchar_function = buffer_push; - buffer_init(); - hdlc_send_frame(frame_buffer, frame_length); -} - -uint8_t *hdlc_get_buffer() { - return frame_buffer; -} - -uint32_t hdlc_get_buffer_size() { - return frame_buffer_size; -} \ No newline at end of file diff --git a/hdlc/hdlc.h b/hdlc/hdlc.h index 035fc0a..b160558 100644 --- a/hdlc/hdlc.h +++ b/hdlc/hdlc.h @@ -1,22 +1,167 @@ -#ifndef hdlc_h -#define hdlc_h +#ifndef HDLC_H_ +#define HDLC_H_ #include -#include +#include +#include "crc.h" -typedef void (*sendchar_type)(uint8_t data); -typedef void (*frame_handler_type)(const uint8_t *frame_buffer, - uint16_t frame_length); +#define HDLC_TEMPLATE \ + int16_t (*readByte)(void), \ + void (*writeByte)(uint8_t data), \ + uint16_t rxBuffLen, \ + struct CRC -#define MINIHDLC_MAX_FRAME_LENGTH 64 +#define HDLC_TEMPLATETYPE \ + readByte, \ + writeByte, \ + rxBuffLen, \ + CRC -void hdlc_init(sendchar_type sendchar_function, - frame_handler_type frame_hander_function); -void hdlc_char_receiver(uint8_t data); -void hdlc_send_frame(const uint8_t *frame_buffer, uint8_t frame_length); +struct HDLC { + const uint8_t DATAINVBIT; + const uint8_t DATASTART; + const uint8_t DATAESCAPE; + const uint8_t* DATAESCAPELIST; -void hdlc_send_frame_to_buffer(const uint8_t *frame_buffer, uint8_t frame_length); -uint8_t *hdlc_get_buffer(); -uint32_t hdlc_get_buffer_size(); + int16_t (*readByte)(void); + void (*writeByte)(uint8_t data); + uint16_t rxBuffLen; + CRC16_CCITT rxcrc; -#endif \ No newline at end of file + const uint16_t RXBFLEN; + + int8_t status; + uint16_t len; + CRC16_CCITT txcrc; + uint8_t data[]; +}; + +void escapeAndWriteByte(struct HDLC* hdlc, uint8_t data) { + const uint8_t* escapeList = hdlc->DATAESCAPELIST; + while (*escapeList != 0) { + if (data == *escapeList) { + hdlc->writeByte(hdlc->DATAESCAPE); + data ^= hdlc->DATAINVBIT; + break; + } + escapeList++; + } + hdlc->writeByte(data); +} + +#define ESCAPED (-1) +#define RECEIVING 0 +#define OK 1 +#define CRCERR 2 + +void HDLC_init(struct HDLC* hdlc){ + hdlc->len = 0U; + hdlc->status = RECEIVING; + crc_init(&hdlc->rxcrc); +};; + +void HDLC_transmitStart(struct HDLC *hdlc); +void HDLC_transmitStart(struct HDLC *hdlc) { + hdlc->writeByte(hdlc->DATASTART); + crc_init(&hdlc->txcrc); +} + +void HDLC_transmitByte(struct HDLC* hdlc, uint8_t data); +void HDLC_transmitByte(struct HDLC* hdlc, uint8_t data){ + escapeAndWriteByte(hdlc, data); + crc_update(&hdlc->txcrc, data); +} + +void HDLC_transmitBytes(struct HDLC* hdlc, const void *vdata, uint16_t len); +void HDLC_transmitBytes(struct HDLC* hdlc, const void *vdata, uint16_t len){ + const uint8_t* data = (const uint8_t*)vdata; + while(len) + { + HDLC_transmitByte(hdlc, *data); + ++data; + --len; + } +} + +void HDLC_transmitEnd(struct HDLC *hdlc); +void HDLC_transmitEnd(struct HDLC *hdlc){ + crc_final(&hdlc->txcrc); + for(int i = 0; i < hdlc->txcrc.size; ++i) + escapeAndWriteByte(hdlc, hdlc->txcrc.crc); + + hdlc->writeByte(hdlc->DATASTART); +} + +void HDLC_transmitBlock(struct HDLC* hdlc, const void* vdata, uint16_t len){ + HDLC_transmitStart(hdlc); + HDLC_transmitBytes(hdlc, vdata, len); + HDLC_transmitEnd(hdlc); +} + +uint16_t HDLC_receive(struct HDLC* hdlc); +uint16_t HDLC_receive(struct HDLC* hdlc){ + int16_t c = hdlc->readByte(); + if(c == -1) + return 0U; + + if(hdlc->status >= OK) + HDLC_init(hdlc); + + uint16_t retv = 0U; + + if(c == hdlc->DATASTART) + { + if(hdlc->status == RECEIVING && hdlc->len != 0U) + { + if(crc_good(&hdlc->rxcrc)) + { + hdlc->status = OK; + hdlc->len -= hdlc->rxcrc.size; + retv = hdlc->len; + } + else + { + hdlc->status = CRCERR; + } + } + else + { + HDLC_init(hdlc); + } + } + else + { + if(hdlc->status == ESCAPED) + { + hdlc->status = RECEIVING; + + c ^= hdlc->DATAINVBIT; + crc_update(&hdlc->rxcrc, c); + if (hdlc->len < hdlc->RXBFLEN) + hdlc->data[hdlc->len] = c; + ++hdlc->len; + } + else if(c != hdlc->DATAESCAPE) + { + crc_update(&hdlc->rxcrc, c); + if(hdlc->len < hdlc->RXBFLEN) + hdlc->data[hdlc->len] = c; + ++hdlc->len; + } + else + { + hdlc->status = ESCAPED; + } + } + + return retv; +} +uint16_t HDLC_copyReceivedMessage(const struct HDLC* hdlc, uint8_t buff[]); +uint16_t HDLC_copyReceivedMessage(const struct HDLC* hdlc, uint8_t buff[]){ + const uint16_t datalen = (hdlc->len > hdlc->RXBFLEN) ? hdlc->RXBFLEN : hdlc->len; + memcpy(buff, hdlc->data, datalen); + return datalen; +} +uint16_t HDLC_copyReceivedMessage2(const struct HDLC* hdlc, uint8_t* buff, uint16_t pos, uint16_t num); + +#endif /* HDLC_H_ */ diff --git a/hdlc/main.c b/hdlc/main.c new file mode 100644 index 0000000..9325619 --- /dev/null +++ b/hdlc/main.c @@ -0,0 +1,33 @@ +#include "hdlc.h" +#include + +struct HDLC hdlc; + +void hdlc_sendMsg() { + uint8_t msg[] = "Hello world!"; + HDLC_transmitBlock(&hdlc, msg, sizeof(msg)); +} + +void hdlc_receiveMsg() { + int16_t resp = HDLC_receive(&hdlc); + if(resp != 0U) + { + uint8_t buff[hdlc.RXBFLEN]; + uint16_t size = HDLC_copyReceivedMessage(&hdlc, buff); + + printf("Msg[%u]=%s\n", size, buff); + } +} + +//нужно указать 2 функции на чтение и запись байтов, чтобы работало +int main(void) +{ + HDLC_init(&hdlc); + + hdlc_sendMsg(); + + for(;;) + { + hdlc_receiveMsg(); + } +} From a19da2cbd3a9d9cdf0c2662916f827f8d862f978 Mon Sep 17 00:00:00 2001 From: Qukich Date: Thu, 15 Jun 2023 16:22:51 +0300 Subject: [PATCH 09/14] add hdlc frame --- hdlc/crc.c | 66 ---------------- hdlc/crc.h | 25 ------ hdlc/hdlc.h | 167 ----------------------------------------- hdlc/hdlc_frame.c | 78 +++++++++++++++++++ hdlc/hdlc_frame.h | 21 ++++++ hdlc/main.c | 33 -------- hdlc/test_hdlc_frame.c | 47 ++++++++++++ 7 files changed, 146 insertions(+), 291 deletions(-) delete mode 100644 hdlc/crc.c delete mode 100644 hdlc/crc.h delete mode 100644 hdlc/hdlc.h create mode 100644 hdlc/hdlc_frame.c create mode 100644 hdlc/hdlc_frame.h delete mode 100644 hdlc/main.c create mode 100644 hdlc/test_hdlc_frame.c diff --git a/hdlc/crc.c b/hdlc/crc.c deleted file mode 100644 index 121c210..0000000 --- a/hdlc/crc.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "crc.h" - -const int8_t size = 2; -const CRC_t CRC_INIT = 0xFFFFU; -const CRC_t CRC_FINALXOR = 0xFFFFU; -const CRC_t CRC_GOOD = 0xF0B8U; - -static const uint16_t CRC_TAB[256U] = { - 0x0000UL, 0x1189UL, 0x2312UL, 0x329BUL, 0x4624UL, 0x57ADUL, 0x6536UL, 0x74BFUL, - 0x8C48UL, 0x9DC1UL, 0xAF5AUL, 0xBED3UL, 0xCA6CUL, 0xDBE5UL, 0xE97EUL, 0xF8F7UL, - 0x1081UL, 0x0108UL, 0x3393UL, 0x221AUL, 0x56A5UL, 0x472CUL, 0x75B7UL, 0x643EUL, - 0x9CC9UL, 0x8D40UL, 0xBFDBUL, 0xAE52UL, 0xDAEDUL, 0xCB64UL, 0xF9FFUL, 0xE876UL, - 0x2102UL, 0x308BUL, 0x0210UL, 0x1399UL, 0x6726UL, 0x76AFUL, 0x4434UL, 0x55BDUL, - 0xAD4AUL, 0xBCC3UL, 0x8E58UL, 0x9FD1UL, 0xEB6EUL, 0xFAE7UL, 0xC87CUL, 0xD9F5UL, - 0x3183UL, 0x200AUL, 0x1291UL, 0x0318UL, 0x77A7UL, 0x662EUL, 0x54B5UL, 0x453CUL, - 0xBDCBUL, 0xAC42UL, 0x9ED9UL, 0x8F50UL, 0xFBEFUL, 0xEA66UL, 0xD8FDUL, 0xC974UL, - 0x4204UL, 0x538DUL, 0x6116UL, 0x709FUL, 0x0420UL, 0x15A9UL, 0x2732UL, 0x36BBUL, - 0xCE4CUL, 0xDFC5UL, 0xED5EUL, 0xFCD7UL, 0x8868UL, 0x99E1UL, 0xAB7AUL, 0xBAF3UL, - 0x5285UL, 0x430CUL, 0x7197UL, 0x601EUL, 0x14A1UL, 0x0528UL, 0x37B3UL, 0x263AUL, - 0xDECDUL, 0xCF44UL, 0xFDDFUL, 0xEC56UL, 0x98E9UL, 0x8960UL, 0xBBFBUL, 0xAA72UL, - 0x6306UL, 0x728FUL, 0x4014UL, 0x519DUL, 0x2522UL, 0x34ABUL, 0x0630UL, 0x17B9UL, - 0xEF4EUL, 0xFEC7UL, 0xCC5CUL, 0xDDD5UL, 0xA96AUL, 0xB8E3UL, 0x8A78UL, 0x9BF1UL, - 0x7387UL, 0x620EUL, 0x5095UL, 0x411CUL, 0x35A3UL, 0x242AUL, 0x16B1UL, 0x0738UL, - 0xFFCFUL, 0xEE46UL, 0xDCDDUL, 0xCD54UL, 0xB9EBUL, 0xA862UL, 0x9AF9UL, 0x8B70UL, - 0x8408UL, 0x9581UL, 0xA71AUL, 0xB693UL, 0xC22CUL, 0xD3A5UL, 0xE13EUL, 0xF0B7UL, - 0x0840UL, 0x19C9UL, 0x2B52UL, 0x3ADBUL, 0x4E64UL, 0x5FEDUL, 0x6D76UL, 0x7CFFUL, - 0x9489UL, 0x8500UL, 0xB79BUL, 0xA612UL, 0xD2ADUL, 0xC324UL, 0xF1BFUL, 0xE036UL, - 0x18C1UL, 0x0948UL, 0x3BD3UL, 0x2A5AUL, 0x5EE5UL, 0x4F6CUL, 0x7DF7UL, 0x6C7EUL, - 0xA50AUL, 0xB483UL, 0x8618UL, 0x9791UL, 0xE32EUL, 0xF2A7UL, 0xC03CUL, 0xD1B5UL, - 0x2942UL, 0x38CBUL, 0x0A50UL, 0x1BD9UL, 0x6F66UL, 0x7EEFUL, 0x4C74UL, 0x5DFDUL, - 0xB58BUL, 0xA402UL, 0x9699UL, 0x8710UL, 0xF3AFUL, 0xE226UL, 0xD0BDUL, 0xC134UL, - 0x39C3UL, 0x284AUL, 0x1AD1UL, 0x0B58UL, 0x7FE7UL, 0x6E6EUL, 0x5CF5UL, 0x4D7CUL, - 0xC60CUL, 0xD785UL, 0xE51EUL, 0xF497UL, 0x8028UL, 0x91A1UL, 0xA33AUL, 0xB2B3UL, - 0x4A44UL, 0x5BCDUL, 0x6956UL, 0x78DFUL, 0x0C60UL, 0x1DE9UL, 0x2F72UL, 0x3EFBUL, - 0xD68DUL, 0xC704UL, 0xF59FUL, 0xE416UL, 0x90A9UL, 0x8120UL, 0xB3BBUL, 0xA232UL, - 0x5AC5UL, 0x4B4CUL, 0x79D7UL, 0x685EUL, 0x1CE1UL, 0x0D68UL, 0x3FF3UL, 0x2E7AUL, - 0xE70EUL, 0xF687UL, 0xC41CUL, 0xD595UL, 0xA12AUL, 0xB0A3UL, 0x8238UL, 0x93B1UL, - 0x6B46UL, 0x7ACFUL, 0x4854UL, 0x59DDUL, 0x2D62UL, 0x3CEBUL, 0x0E70UL, 0x1FF9UL, - 0xF78FUL, 0xE606UL, 0xD49DUL, 0xC514UL, 0xB1ABUL, 0xA022UL, 0x92B9UL, 0x8330UL, - 0x7BC7UL, 0x6A4EUL, 0x58D5UL, 0x495CUL, 0x3DE3UL, 0x2C6AUL, 0x1EF1UL, 0x0F78UL -}; - -void crc_init(CRC16_CCITT* crc_obj) { - crc_obj->crc = CRC_INIT; - crc_obj->size = 2; -} - -void crc_update(CRC16_CCITT* crc_obj, uint8_t data) { - crc_obj->crc = (crc_obj->crc >> 8U) ^ CRC_TAB[(crc_obj->crc ^ data) & CRC_FINALXOR]; -} - -bool crc_good(const CRC16_CCITT* crc_obj) { - return crc_obj->crc == 0xF0B8U; -} - -void crc_final(CRC16_CCITT* crc_obj) { - crc_obj->crc ^= CRC_FINALXOR; -} - -uint8_t crc_get(const CRC16_CCITT* crc_obj, int8_t pos) { - if (pos == 0){ - return crc_obj->crc; - } else{ - return crc_obj->crc >> 8U; - } -} \ No newline at end of file diff --git a/hdlc/crc.h b/hdlc/crc.h deleted file mode 100644 index 4b88f0d..0000000 --- a/hdlc/crc.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// Created by 79513 on 13.06.2023. -// - -#ifndef CRC16_CCITT_H_ -#define CRC16_CCITT_H_ - -#include -#include - -typedef uint16_t CRC_t; - -typedef struct { - const CRC_t* CRC_TAB; - CRC_t crc; - int size; -} CRC16_CCITT; - -void crc_init(CRC16_CCITT* crc_obj); -void crc_update(CRC16_CCITT* crc_obj, uint8_t data); -bool crc_good(const CRC16_CCITT* crc_obj); -void crc_final(CRC16_CCITT* crc_obj); -uint8_t crc_get(const CRC16_CCITT* crc_obj, int8_t pos); - -#endif diff --git a/hdlc/hdlc.h b/hdlc/hdlc.h deleted file mode 100644 index b160558..0000000 --- a/hdlc/hdlc.h +++ /dev/null @@ -1,167 +0,0 @@ -#ifndef HDLC_H_ -#define HDLC_H_ - -#include -#include -#include "crc.h" - -#define HDLC_TEMPLATE \ - int16_t (*readByte)(void), \ - void (*writeByte)(uint8_t data), \ - uint16_t rxBuffLen, \ - struct CRC - -#define HDLC_TEMPLATETYPE \ - readByte, \ - writeByte, \ - rxBuffLen, \ - CRC - -struct HDLC { - const uint8_t DATAINVBIT; - const uint8_t DATASTART; - const uint8_t DATAESCAPE; - const uint8_t* DATAESCAPELIST; - - int16_t (*readByte)(void); - void (*writeByte)(uint8_t data); - uint16_t rxBuffLen; - CRC16_CCITT rxcrc; - - const uint16_t RXBFLEN; - - int8_t status; - uint16_t len; - CRC16_CCITT txcrc; - uint8_t data[]; -}; - -void escapeAndWriteByte(struct HDLC* hdlc, uint8_t data) { - const uint8_t* escapeList = hdlc->DATAESCAPELIST; - while (*escapeList != 0) { - if (data == *escapeList) { - hdlc->writeByte(hdlc->DATAESCAPE); - data ^= hdlc->DATAINVBIT; - break; - } - escapeList++; - } - hdlc->writeByte(data); -} - -#define ESCAPED (-1) -#define RECEIVING 0 -#define OK 1 -#define CRCERR 2 - -void HDLC_init(struct HDLC* hdlc){ - hdlc->len = 0U; - hdlc->status = RECEIVING; - crc_init(&hdlc->rxcrc); -};; - -void HDLC_transmitStart(struct HDLC *hdlc); -void HDLC_transmitStart(struct HDLC *hdlc) { - hdlc->writeByte(hdlc->DATASTART); - crc_init(&hdlc->txcrc); -} - -void HDLC_transmitByte(struct HDLC* hdlc, uint8_t data); -void HDLC_transmitByte(struct HDLC* hdlc, uint8_t data){ - escapeAndWriteByte(hdlc, data); - crc_update(&hdlc->txcrc, data); -} - -void HDLC_transmitBytes(struct HDLC* hdlc, const void *vdata, uint16_t len); -void HDLC_transmitBytes(struct HDLC* hdlc, const void *vdata, uint16_t len){ - const uint8_t* data = (const uint8_t*)vdata; - while(len) - { - HDLC_transmitByte(hdlc, *data); - ++data; - --len; - } -} - -void HDLC_transmitEnd(struct HDLC *hdlc); -void HDLC_transmitEnd(struct HDLC *hdlc){ - crc_final(&hdlc->txcrc); - for(int i = 0; i < hdlc->txcrc.size; ++i) - escapeAndWriteByte(hdlc, hdlc->txcrc.crc); - - hdlc->writeByte(hdlc->DATASTART); -} - -void HDLC_transmitBlock(struct HDLC* hdlc, const void* vdata, uint16_t len){ - HDLC_transmitStart(hdlc); - HDLC_transmitBytes(hdlc, vdata, len); - HDLC_transmitEnd(hdlc); -} - -uint16_t HDLC_receive(struct HDLC* hdlc); -uint16_t HDLC_receive(struct HDLC* hdlc){ - int16_t c = hdlc->readByte(); - if(c == -1) - return 0U; - - if(hdlc->status >= OK) - HDLC_init(hdlc); - - uint16_t retv = 0U; - - if(c == hdlc->DATASTART) - { - if(hdlc->status == RECEIVING && hdlc->len != 0U) - { - if(crc_good(&hdlc->rxcrc)) - { - hdlc->status = OK; - hdlc->len -= hdlc->rxcrc.size; - retv = hdlc->len; - } - else - { - hdlc->status = CRCERR; - } - } - else - { - HDLC_init(hdlc); - } - } - else - { - if(hdlc->status == ESCAPED) - { - hdlc->status = RECEIVING; - - c ^= hdlc->DATAINVBIT; - crc_update(&hdlc->rxcrc, c); - if (hdlc->len < hdlc->RXBFLEN) - hdlc->data[hdlc->len] = c; - ++hdlc->len; - } - else if(c != hdlc->DATAESCAPE) - { - crc_update(&hdlc->rxcrc, c); - if(hdlc->len < hdlc->RXBFLEN) - hdlc->data[hdlc->len] = c; - ++hdlc->len; - } - else - { - hdlc->status = ESCAPED; - } - } - - return retv; -} -uint16_t HDLC_copyReceivedMessage(const struct HDLC* hdlc, uint8_t buff[]); -uint16_t HDLC_copyReceivedMessage(const struct HDLC* hdlc, uint8_t buff[]){ - const uint16_t datalen = (hdlc->len > hdlc->RXBFLEN) ? hdlc->RXBFLEN : hdlc->len; - memcpy(buff, hdlc->data, datalen); - return datalen; -} -uint16_t HDLC_copyReceivedMessage2(const struct HDLC* hdlc, uint8_t* buff, uint16_t pos, uint16_t num); - -#endif /* HDLC_H_ */ diff --git a/hdlc/hdlc_frame.c b/hdlc/hdlc_frame.c new file mode 100644 index 0000000..40efe30 --- /dev/null +++ b/hdlc/hdlc_frame.c @@ -0,0 +1,78 @@ +#include "hdlc_frame.h" +#include + +#define START_FLAG 0x7E +#define END_FLAG 0x7E +#define ESCAPE_FLAG 0x7D +#define ESCAPE_XOR 0x20 + +void initialize_frame(HDLCFrame* frame, uint8_t address, uint8_t control, uint8_t* data, size_t data_length) { + frame->address = address; + frame->control = control; + frame->data = data; + frame->data_length = data_length; +} + +uint16_t calculate_fcs(HDLCFrame* frame) { + uint16_t fcs = 0xFFFF; + uint8_t* data_bytes = malloc(frame->data_length + 2); + data_bytes[0] = frame->address; + data_bytes[1] = frame->control; + + for (size_t i = 0; i < frame->data_length; i++) { + data_bytes[i + 2] = frame->data[i]; + } + + for (size_t i = 0; i < frame->data_length + 2; i++) { + uint8_t byte = data_bytes[i]; + fcs = (fcs >> 8) ^ (fcs << 8) ^ byte; + fcs &= 0xFFFF; + } + + free(data_bytes); + return fcs; +} + +void create_frame(HDLCFrame* frame, uint8_t** frame_data, size_t* frame_length) { + *frame_length = 4 + frame->data_length; + *frame_data = malloc(*frame_length); + (*frame_data)[0] = START_FLAG; + (*frame_data)[1] = frame->address; + (*frame_data)[2] = frame->control; + + size_t index = 3; + for (size_t i = 0; i < frame->data_length; i++) { + uint8_t byte = frame->data[i]; + if (byte == START_FLAG || byte == END_FLAG || byte == ESCAPE_FLAG) { + (*frame_data)[index++] = ESCAPE_FLAG; + (*frame_data)[index++] = byte ^ ESCAPE_XOR; + } else { + (*frame_data)[index++] = byte; + } + } + + uint16_t fcs = calculate_fcs(frame); + (*frame_data)[index++] = fcs & 0xFF; + (*frame_data)[index] = END_FLAG; +} + +HDLCFrame* create_u_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length) { + HDLCFrame* frame = malloc(sizeof(HDLCFrame)); + initialize_frame(frame, address, control, data, data_length); + return frame; +} + +HDLCFrame* create_s_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length, uint8_t receive_sequence_number, uint8_t send_sequence_number) { + HDLCFrame* frame = malloc(sizeof(HDLCFrame)); + initialize_frame(frame, address, control, data, data_length); + frame->control |= (receive_sequence_number << 2) & 0xFC; + frame->control |= (send_sequence_number << 1) & 0xFE; + return frame; +} + +HDLCFrame* create_i_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length, uint8_t sequence_number) { + HDLCFrame* frame = malloc(sizeof(HDLCFrame)); + initialize_frame(frame, address, control, data, data_length); + frame->control |= (sequence_number << 1) & 0xFE; + return frame; +} \ No newline at end of file diff --git a/hdlc/hdlc_frame.h b/hdlc/hdlc_frame.h new file mode 100644 index 0000000..ceae96e --- /dev/null +++ b/hdlc/hdlc_frame.h @@ -0,0 +1,21 @@ +#ifndef HDLC_FRAME_H +#define HDLC_FRAME_H + +#include + +typedef struct { + uint8_t address; + uint8_t control; + uint8_t* data; + size_t data_length; +} HDLCFrame; + +void initialize_frame(HDLCFrame* frame, uint8_t address, uint8_t control, uint8_t* data, size_t data_length); +uint16_t calculate_fcs(HDLCFrame* frame); +void create_frame(HDLCFrame* frame, uint8_t** frame_data, size_t* frame_length); + +HDLCFrame* create_u_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length); +HDLCFrame* create_s_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length, uint8_t receive_sequence_number, uint8_t send_sequence_number); +HDLCFrame* create_i_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length, uint8_t sequence_number); + +#endif \ No newline at end of file diff --git a/hdlc/main.c b/hdlc/main.c deleted file mode 100644 index 9325619..0000000 --- a/hdlc/main.c +++ /dev/null @@ -1,33 +0,0 @@ -#include "hdlc.h" -#include - -struct HDLC hdlc; - -void hdlc_sendMsg() { - uint8_t msg[] = "Hello world!"; - HDLC_transmitBlock(&hdlc, msg, sizeof(msg)); -} - -void hdlc_receiveMsg() { - int16_t resp = HDLC_receive(&hdlc); - if(resp != 0U) - { - uint8_t buff[hdlc.RXBFLEN]; - uint16_t size = HDLC_copyReceivedMessage(&hdlc, buff); - - printf("Msg[%u]=%s\n", size, buff); - } -} - -//нужно указать 2 функции на чтение и запись байтов, чтобы работало -int main(void) -{ - HDLC_init(&hdlc); - - hdlc_sendMsg(); - - for(;;) - { - hdlc_receiveMsg(); - } -} diff --git a/hdlc/test_hdlc_frame.c b/hdlc/test_hdlc_frame.c new file mode 100644 index 0000000..34ab052 --- /dev/null +++ b/hdlc/test_hdlc_frame.c @@ -0,0 +1,47 @@ +#include +#include +#include "hdlc_frame.h" + +void print_frame(uint8_t* frame_data, size_t frame_length) { + printf("Сформированный кадр:\n"); + for (size_t i = 0; i < frame_length; i++) { + printf("%02X ", frame_data[i]); + } + printf("\n"); +} + +int main() { + uint8_t address = 0x01; + uint8_t control = 0x02; + uint8_t data[] = {0x10, 0x20, 0x30}; + size_t data_length = sizeof(data) / sizeof(data[0]); + + HDLCFrame* u_frame = create_u_frame(address, control, data, data_length); + uint8_t* u_frame_data; + size_t u_frame_length; + create_frame(u_frame, &u_frame_data, &u_frame_length); + print_frame(u_frame_data, u_frame_length); + free(u_frame_data); + free(u_frame); + + uint8_t receive_sequence_number = 0x01; + uint8_t send_sequence_number = 0x02; + HDLCFrame* s_frame = create_s_frame(address, control, data, data_length, receive_sequence_number, send_sequence_number); + uint8_t* s_frame_data; + size_t s_frame_length; + create_frame(s_frame, &s_frame_data, &s_frame_length); + print_frame(s_frame_data, s_frame_length); + free(s_frame_data); + free(s_frame); + + uint8_t sequence_number = 0x03; + HDLCFrame* i_frame = create_i_frame(address, control, data, data_length, sequence_number); + uint8_t* i_frame_data; + size_t i_frame_length; + create_frame(i_frame, &i_frame_data, &i_frame_length); + print_frame(i_frame_data, i_frame_length); + free(i_frame_data); + free(i_frame); + + return 0; +} \ No newline at end of file From 4b4a162f7251bbf631ebbae0f78fc91ea93558d1 Mon Sep 17 00:00:00 2001 From: Qukich Date: Thu, 15 Jun 2023 19:48:27 +0300 Subject: [PATCH 10/14] delete malloc --- hdlc/hdlc_frame.c | 35 +++++++++++++++++------------------ hdlc/hdlc_frame.h | 4 +++- hdlc/test_hdlc_frame.c | 27 +++++++++++---------------- 3 files changed, 31 insertions(+), 35 deletions(-) diff --git a/hdlc/hdlc_frame.c b/hdlc/hdlc_frame.c index 40efe30..f73e0db 100644 --- a/hdlc/hdlc_frame.c +++ b/hdlc/hdlc_frame.c @@ -1,5 +1,4 @@ #include "hdlc_frame.h" -#include #define START_FLAG 0x7E #define END_FLAG 0x7E @@ -15,7 +14,7 @@ void initialize_frame(HDLCFrame* frame, uint8_t address, uint8_t control, uint8_ uint16_t calculate_fcs(HDLCFrame* frame) { uint16_t fcs = 0xFFFF; - uint8_t* data_bytes = malloc(frame->data_length + 2); + uint8_t data_bytes[MAX_FRAME_LENGTH]; data_bytes[0] = frame->address; data_bytes[1] = frame->control; @@ -29,41 +28,41 @@ uint16_t calculate_fcs(HDLCFrame* frame) { fcs &= 0xFFFF; } - free(data_bytes); return fcs; } -void create_frame(HDLCFrame* frame, uint8_t** frame_data, size_t* frame_length) { - *frame_length = 4 + frame->data_length; - *frame_data = malloc(*frame_length); - (*frame_data)[0] = START_FLAG; - (*frame_data)[1] = frame->address; - (*frame_data)[2] = frame->control; +void create_frame(HDLCFrame* frame, uint8_t* frame_data, size_t* frame_length) { + size_t index = 0; + frame_data[index++] = START_FLAG; + frame_data[index++] = frame->address; + frame_data[index++] = frame->control; - size_t index = 3; for (size_t i = 0; i < frame->data_length; i++) { uint8_t byte = frame->data[i]; if (byte == START_FLAG || byte == END_FLAG || byte == ESCAPE_FLAG) { - (*frame_data)[index++] = ESCAPE_FLAG; - (*frame_data)[index++] = byte ^ ESCAPE_XOR; + frame_data[index++] = ESCAPE_FLAG; + frame_data[index++] = byte ^ ESCAPE_XOR; } else { - (*frame_data)[index++] = byte; + frame_data[index++] = byte; } } uint16_t fcs = calculate_fcs(frame); - (*frame_data)[index++] = fcs & 0xFF; - (*frame_data)[index] = END_FLAG; + frame_data[index++] = fcs & 0xFF; + frame_data[index++] = (fcs >> 8) & 0xFF; + frame_data[index] = END_FLAG; + + *frame_length = index + 1; } HDLCFrame* create_u_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length) { - HDLCFrame* frame = malloc(sizeof(HDLCFrame)); + HDLCFrame* frame = (HDLCFrame*)malloc(sizeof(HDLCFrame)); initialize_frame(frame, address, control, data, data_length); return frame; } HDLCFrame* create_s_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length, uint8_t receive_sequence_number, uint8_t send_sequence_number) { - HDLCFrame* frame = malloc(sizeof(HDLCFrame)); + HDLCFrame* frame = (HDLCFrame*)malloc(sizeof(HDLCFrame)); initialize_frame(frame, address, control, data, data_length); frame->control |= (receive_sequence_number << 2) & 0xFC; frame->control |= (send_sequence_number << 1) & 0xFE; @@ -71,7 +70,7 @@ HDLCFrame* create_s_frame(uint8_t address, uint8_t control, uint8_t* data, size_ } HDLCFrame* create_i_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length, uint8_t sequence_number) { - HDLCFrame* frame = malloc(sizeof(HDLCFrame)); + HDLCFrame* frame = (HDLCFrame*)malloc(sizeof(HDLCFrame)); initialize_frame(frame, address, control, data, data_length); frame->control |= (sequence_number << 1) & 0xFE; return frame; diff --git a/hdlc/hdlc_frame.h b/hdlc/hdlc_frame.h index ceae96e..09792a6 100644 --- a/hdlc/hdlc_frame.h +++ b/hdlc/hdlc_frame.h @@ -2,6 +2,7 @@ #define HDLC_FRAME_H #include +#define MAX_FRAME_LENGTH 256 typedef struct { uint8_t address; @@ -12,10 +13,11 @@ typedef struct { void initialize_frame(HDLCFrame* frame, uint8_t address, uint8_t control, uint8_t* data, size_t data_length); uint16_t calculate_fcs(HDLCFrame* frame); -void create_frame(HDLCFrame* frame, uint8_t** frame_data, size_t* frame_length); +void create_frame(HDLCFrame* frame, uint8_t* frame_data, size_t* frame_length); HDLCFrame* create_u_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length); HDLCFrame* create_s_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length, uint8_t receive_sequence_number, uint8_t send_sequence_number); HDLCFrame* create_i_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length, uint8_t sequence_number); + #endif \ No newline at end of file diff --git a/hdlc/test_hdlc_frame.c b/hdlc/test_hdlc_frame.c index 34ab052..2c8a748 100644 --- a/hdlc/test_hdlc_frame.c +++ b/hdlc/test_hdlc_frame.c @@ -17,30 +17,25 @@ int main() { size_t data_length = sizeof(data) / sizeof(data[0]); HDLCFrame* u_frame = create_u_frame(address, control, data, data_length); - uint8_t* u_frame_data; + uint8_t u_frame_data[MAX_FRAME_LENGTH]; size_t u_frame_length; - create_frame(u_frame, &u_frame_data, &u_frame_length); + create_frame(u_frame, u_frame_data, &u_frame_length); print_frame(u_frame_data, u_frame_length); - free(u_frame_data); - free(u_frame); - uint8_t receive_sequence_number = 0x01; - uint8_t send_sequence_number = 0x02; - HDLCFrame* s_frame = create_s_frame(address, control, data, data_length, receive_sequence_number, send_sequence_number); - uint8_t* s_frame_data; + HDLCFrame* s_frame = create_s_frame(address, control, data, data_length, 0x01, 0x02); + uint8_t s_frame_data[MAX_FRAME_LENGTH]; size_t s_frame_length; - create_frame(s_frame, &s_frame_data, &s_frame_length); + create_frame(s_frame, s_frame_data, &s_frame_length); print_frame(s_frame_data, s_frame_length); - free(s_frame_data); - free(s_frame); - uint8_t sequence_number = 0x03; - HDLCFrame* i_frame = create_i_frame(address, control, data, data_length, sequence_number); - uint8_t* i_frame_data; + HDLCFrame* i_frame = create_i_frame(address, control, data, data_length, 0x03); + uint8_t i_frame_data[MAX_FRAME_LENGTH]; size_t i_frame_length; - create_frame(i_frame, &i_frame_data, &i_frame_length); + create_frame(i_frame, i_frame_data, &i_frame_length); print_frame(i_frame_data, i_frame_length); - free(i_frame_data); + + free(u_frame); + free(s_frame); free(i_frame); return 0; From eceecf15d4f1a1ff49866f2be01f28f64dd1a41a Mon Sep 17 00:00:00 2001 From: Qukich Date: Mon, 19 Jun 2023 19:38:35 +0300 Subject: [PATCH 11/14] add client --- hdlc/client.c | 113 +++++++++++++++++++++++++++++++++++++++++ hdlc/client.h | 29 +++++++++++ hdlc/hdlc_frame.c | 111 +++++++++++++++++++++++++--------------- hdlc/hdlc_frame.h | 38 +++++++++++--- hdlc/test_hdlc_frame.c | 42 --------------- 5 files changed, 243 insertions(+), 90 deletions(-) create mode 100644 hdlc/client.c create mode 100644 hdlc/client.h delete mode 100644 hdlc/test_hdlc_frame.c diff --git a/hdlc/client.c b/hdlc/client.c new file mode 100644 index 0000000..62a53b9 --- /dev/null +++ b/hdlc/client.c @@ -0,0 +1,113 @@ +#include "client.h" + +#include +#include +#include + +void init_Client(Client* client, bool test_is_valid, uint8_t address, void* serial_port) { + client->TEST_IS_VALID = test_is_valid; + client->address = address; + client->_send_sequence_number = 0; + client->poll_final = 1; + client->_receive_sequence_number = 0; + client->serial_port = serial_port; +} + + +void connect(Client* client) { + UFrame u_frame; + init_UFrame(&u_frame, client->address, client->poll_final, "BP", NULL, 0); + + uint8_t result[256]; + create_frame(&u_frame.base, result); + + void* serial_port = client->serial_port; + // Write result to serial port to establish connection + // ... + + // Wait for acknowledgment frame + // Read bytes from serial port + // ... + + uint8_t received[256]; // Example buffer size, adjust as needed + size_t received_length = 0; + + // Process received bytes + // ... + + // Validate acknowledgment frame + HDLCFrame frame; + init_HDLCFrame(&frame, 0, 0, received + 3, received_length - 6); + if (validate(client, &frame, received, received_length)) { + // Connection established + } else { + // Connection failed + } +} + +void send(Client* client, uint8_t* data, size_t data_length) { + connect(client); + + IFrame i_frame; + init_IFrame(&i_frame, client->address, client->_receive_sequence_number, client->poll_final, client->_send_sequence_number, data, data_length); + + uint8_t result[256]; + create_frame(&i_frame.base, result); + + void* serial_port = client->serial_port; + sendSerialData(client->serial_port, &i_frame.base.data, i_frame.base.data_length); + + client->_send_sequence_number++; +} + +void receive_data(Client* client) { + void* serial_port = client->serial_port; + // Read data from serial port + // ... + + // Process received data + // ... +} + +bool validate(Client* client, HDLCFrame* frame, uint8_t* received_data, size_t received_length) { + uint8_t control = received_data[2]; + if ((control & 0x01) == 0) { + // I-frame + printf("i frame\n"); + uint8_t send_sequence_number = (control >> 1) & 0x07; + uint16_t crc = (received_data[received_length - 2] << 8) | received_data[received_length - 3]; + uint16_t calculated_crc = calculate_fcs(received_data + 1, received_length - 4); + if (crc == calculated_crc && send_sequence_number == client->_receive_sequence_number && client->TEST_IS_VALID) { + client->_receive_sequence_number++; + return true; + } + } else if ((control & 0x03) == 1) { + // S-frame + printf("s frame\n"); + // Handle S-frame + } else { + // U-frame + printf("u frame\n"); + // Handle U-frame + } + return false; +} + +int sendSerialData(const char* port, const char* data, size_t length) { + int serial_port = open(port, O_RDWR); // Replace "port" with your serial port device + + if (serial_port < 0) { + perror("Error opening the serial port"); + return -1; + } + + ssize_t bytes_written = write(serial_port, data, length); + + if (bytes_written < 0) { + perror("Error writing to the serial port"); + return -1; + } + + close(serial_port); + return bytes_written; +} \ No newline at end of file diff --git a/hdlc/client.h b/hdlc/client.h new file mode 100644 index 0000000..6b48c0a --- /dev/null +++ b/hdlc/client.h @@ -0,0 +1,29 @@ +// +// Created by 79513 on 19.06.2023. +// + +#ifndef CLIENT_H +#define CLIENT_H + +#include "hdlc_frame.h" +#include +#include // Для использования size_t +#include + +typedef struct { + bool TEST_IS_VALID; + uint8_t address; + uint8_t _send_sequence_number; + uint8_t poll_final; + uint8_t _receive_sequence_number; + void* serial_port; // Указатель на объект последовательного порта +} Client; + +void init_Client(Client* client, bool test_is_valid, uint8_t address, void* serial_port); +void connect(Client* client); +void send(Client* client, uint8_t* data, size_t data_length); +void receive_data(Client* client); +bool validate(Client* client, HDLCFrame* frame, uint8_t* received_data, size_t received_length); +int sendSerialData(const char* port, const char* data, size_t length); + +#endif diff --git a/hdlc/hdlc_frame.c b/hdlc/hdlc_frame.c index f73e0db..e7965c6 100644 --- a/hdlc/hdlc_frame.c +++ b/hdlc/hdlc_frame.c @@ -1,26 +1,26 @@ #include "hdlc_frame.h" +#include + #define START_FLAG 0x7E #define END_FLAG 0x7E #define ESCAPE_FLAG 0x7D #define ESCAPE_XOR 0x20 -void initialize_frame(HDLCFrame* frame, uint8_t address, uint8_t control, uint8_t* data, size_t data_length) { +void init_HDLCFrame(HDLCFrame* frame, uint8_t address, uint8_t control, uint8_t* data, size_t data_length) { frame->address = address; frame->control = control; frame->data = data; frame->data_length = data_length; } -uint16_t calculate_fcs(HDLCFrame* frame) { +uint16_t calculate_fcs(const HDLCFrame *frame, size_t i) { uint16_t fcs = 0xFFFF; - uint8_t data_bytes[MAX_FRAME_LENGTH]; + + uint8_t data_bytes[2 + frame->data_length]; data_bytes[0] = frame->address; data_bytes[1] = frame->control; - - for (size_t i = 0; i < frame->data_length; i++) { - data_bytes[i + 2] = frame->data[i]; - } + memcpy(data_bytes + 2, frame->data, frame->data_length); for (size_t i = 0; i < frame->data_length + 2; i++) { uint8_t byte = data_bytes[i]; @@ -31,47 +31,78 @@ uint16_t calculate_fcs(HDLCFrame* frame) { return fcs; } -void create_frame(HDLCFrame* frame, uint8_t* frame_data, size_t* frame_length) { +void create_frame(const HDLCFrame* frame, uint8_t* result) { size_t index = 0; - frame_data[index++] = START_FLAG; - frame_data[index++] = frame->address; - frame_data[index++] = frame->control; - for (size_t i = 0; i < frame->data_length; i++) { - uint8_t byte = frame->data[i]; - if (byte == START_FLAG || byte == END_FLAG || byte == ESCAPE_FLAG) { - frame_data[index++] = ESCAPE_FLAG; - frame_data[index++] = byte ^ ESCAPE_XOR; - } else { - frame_data[index++] = byte; + result[index++] = START_FLAG; + result[index++] = frame->address; + result[index++] = frame->control; + + if (frame->data != NULL) { + for (size_t i = 0; i < frame->data_length; i++) { + uint8_t byte = frame->data[i]; + if (byte == START_FLAG || byte == END_FLAG || byte == ESCAPE_FLAG) { + result[index++] = ESCAPE_FLAG; + result[index++] = byte ^ ESCAPE_XOR; + } else { + result[index++] = byte; + } } } - uint16_t fcs = calculate_fcs(frame); - frame_data[index++] = fcs & 0xFF; - frame_data[index++] = (fcs >> 8) & 0xFF; - frame_data[index] = END_FLAG; - - *frame_length = index + 1; + uint16_t fcs = calculate_fcs(frame, 0); + result[index++] = fcs & 0xFF; + result[index++] = (fcs >> 8) & 0xFF; + result[index++] = END_FLAG; } -HDLCFrame* create_u_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length) { - HDLCFrame* frame = (HDLCFrame*)malloc(sizeof(HDLCFrame)); - initialize_frame(frame, address, control, data, data_length); - return frame; +void init_IFrame(IFrame* frame, uint8_t address, uint8_t receive_sequence_number, uint8_t poll_final, + uint8_t send_sequence_number, uint8_t* data, size_t data_length) { + init_HDLCFrame(&frame->base, address, + ((receive_sequence_number & 0b111) << 6) | ((poll_final & 0b1) << 4) | + ((send_sequence_number & 0b111) << 1) | 0, + data, data_length); + frame->receive_sequence_number = receive_sequence_number; + frame->poll_final = poll_final; + frame->send_sequence_number = send_sequence_number; } -HDLCFrame* create_s_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length, uint8_t receive_sequence_number, uint8_t send_sequence_number) { - HDLCFrame* frame = (HDLCFrame*)malloc(sizeof(HDLCFrame)); - initialize_frame(frame, address, control, data, data_length); - frame->control |= (receive_sequence_number << 2) & 0xFC; - frame->control |= (send_sequence_number << 1) & 0xFE; - return frame; +void init_SFrame(SFrame* frame, uint8_t address, uint8_t receive_sequence_number, uint8_t poll_final, + const char* frame_type) { + uint8_t frame_type_value; + if (strcmp(frame_type, "RR") == 0) { + frame_type_value = 0; + } else if (strcmp(frame_type, "RNR") == 0) { + frame_type_value = 1; + } else if (strcmp(frame_type, "REJ") == 0) { + frame_type_value = 2; + } else if (strcmp(frame_type, "SREJ") == 0) { + frame_type_value = 3; + } else { + // Handle error + return; + } + + init_HDLCFrame(&frame->base, address, + ((receive_sequence_number & 0b111) << 6) | ((poll_final & 0b1) << 5) | + ((frame_type_value & 0b111) << 2) | 1, + NULL, 0); + frame->receive_sequence_number = receive_sequence_number; + frame->poll_final = poll_final; + frame->frame_type = frame_type; } -HDLCFrame* create_i_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length, uint8_t sequence_number) { - HDLCFrame* frame = (HDLCFrame*)malloc(sizeof(HDLCFrame)); - initialize_frame(frame, address, control, data, data_length); - frame->control |= (sequence_number << 1) & 0xFE; - return frame; -} \ No newline at end of file +void init_UFrame(UFrame* frame, uint8_t address, uint8_t poll_final, const char* frame_type, + uint8_t* data, size_t data_length) { + uint8_t frame_type_value; + if (strcmp(frame_type, "BP") == 0) { + frame_type_value = 63; + } else { + // Handle error + return; + } + + init_HDLCFrame(&frame->base, address, (frame_type_value << 2) | 3, data, data_length); + frame->poll_final = poll_final; + frame->frame_type = frame_type; +} diff --git a/hdlc/hdlc_frame.h b/hdlc/hdlc_frame.h index 09792a6..c12eaf5 100644 --- a/hdlc/hdlc_frame.h +++ b/hdlc/hdlc_frame.h @@ -2,7 +2,6 @@ #define HDLC_FRAME_H #include -#define MAX_FRAME_LENGTH 256 typedef struct { uint8_t address; @@ -11,13 +10,36 @@ typedef struct { size_t data_length; } HDLCFrame; -void initialize_frame(HDLCFrame* frame, uint8_t address, uint8_t control, uint8_t* data, size_t data_length); -uint16_t calculate_fcs(HDLCFrame* frame); -void create_frame(HDLCFrame* frame, uint8_t* frame_data, size_t* frame_length); +void init_HDLCFrame(HDLCFrame* frame, uint8_t address, uint8_t control, uint8_t* data, size_t data_length); +uint16_t calculate_fcs(const HDLCFrame *frame, size_t i); +void create_frame(const HDLCFrame* frame, uint8_t* result); -HDLCFrame* create_u_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length); -HDLCFrame* create_s_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length, uint8_t receive_sequence_number, uint8_t send_sequence_number); -HDLCFrame* create_i_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length, uint8_t sequence_number); +typedef struct { + HDLCFrame base; + uint8_t receive_sequence_number; + uint8_t poll_final; + uint8_t send_sequence_number; +} IFrame; +void init_IFrame(IFrame* frame, uint8_t address, uint8_t receive_sequence_number, uint8_t poll_final, + uint8_t send_sequence_number, uint8_t* data, size_t data_length); -#endif \ No newline at end of file +typedef struct { + HDLCFrame base; + uint8_t receive_sequence_number; + uint8_t poll_final; + const char* frame_type; +} SFrame; + +void init_SFrame(SFrame* frame, uint8_t address, uint8_t receive_sequence_number, uint8_t poll_final, + const char* frame_type); + +typedef struct { + HDLCFrame base; + uint8_t poll_final; + const char* frame_type; +} UFrame; + +void init_UFrame(UFrame* frame, uint8_t address, uint8_t poll_final, const char* frame_type, uint8_t* data, size_t data_length); + +#endif diff --git a/hdlc/test_hdlc_frame.c b/hdlc/test_hdlc_frame.c deleted file mode 100644 index 2c8a748..0000000 --- a/hdlc/test_hdlc_frame.c +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include -#include "hdlc_frame.h" - -void print_frame(uint8_t* frame_data, size_t frame_length) { - printf("Сформированный кадр:\n"); - for (size_t i = 0; i < frame_length; i++) { - printf("%02X ", frame_data[i]); - } - printf("\n"); -} - -int main() { - uint8_t address = 0x01; - uint8_t control = 0x02; - uint8_t data[] = {0x10, 0x20, 0x30}; - size_t data_length = sizeof(data) / sizeof(data[0]); - - HDLCFrame* u_frame = create_u_frame(address, control, data, data_length); - uint8_t u_frame_data[MAX_FRAME_LENGTH]; - size_t u_frame_length; - create_frame(u_frame, u_frame_data, &u_frame_length); - print_frame(u_frame_data, u_frame_length); - - HDLCFrame* s_frame = create_s_frame(address, control, data, data_length, 0x01, 0x02); - uint8_t s_frame_data[MAX_FRAME_LENGTH]; - size_t s_frame_length; - create_frame(s_frame, s_frame_data, &s_frame_length); - print_frame(s_frame_data, s_frame_length); - - HDLCFrame* i_frame = create_i_frame(address, control, data, data_length, 0x03); - uint8_t i_frame_data[MAX_FRAME_LENGTH]; - size_t i_frame_length; - create_frame(i_frame, i_frame_data, &i_frame_length); - print_frame(i_frame_data, i_frame_length); - - free(u_frame); - free(s_frame); - free(i_frame); - - return 0; -} \ No newline at end of file From 8e4329c9d3e8172d4526390cbb948de6bee3566c Mon Sep 17 00:00:00 2001 From: Qukich Date: Thu, 22 Jun 2023 13:11:57 +0300 Subject: [PATCH 12/14] It remains to complete the validation of frames --- hdlc/client.c | 66 ++++++++++++++++++++++++++++++++------------------- hdlc/client.h | 5 ++-- 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/hdlc/client.c b/hdlc/client.c index 62a53b9..a4307af 100644 --- a/hdlc/client.c +++ b/hdlc/client.c @@ -2,7 +2,6 @@ #include #include -#include void init_Client(Client* client, bool test_is_valid, uint8_t address, void* serial_port) { client->TEST_IS_VALID = test_is_valid; @@ -22,24 +21,21 @@ void connect(Client* client) { create_frame(&u_frame.base, result); void* serial_port = client->serial_port; - // Write result to serial port to establish connection - // ... - + sendSerialData(serial_port, u_frame.base.data, u_frame.base.data_length); // Wait for acknowledgment frame - // Read bytes from serial port - // ... + bool flag = true; + uint8_t data[u_frame.base.data_length]; + while(flag){ + int bytes_received = receiveSerialData(serial_port, data, 256); + if (bytes_received > 0){ + flag = false; + } + } - uint8_t received[256]; // Example buffer size, adjust as needed - size_t received_length = 0; - - // Process received bytes - // ... - - // Validate acknowledgment frame HDLCFrame frame; - init_HDLCFrame(&frame, 0, 0, received + 3, received_length - 6); - if (validate(client, &frame, received, received_length)) { - // Connection established + init_HDLCFrame(&frame, 0, 0, data + 3, 256 - 6); + if (validate(client, &frame, data, 256)) { + return; } else { // Connection failed } @@ -54,19 +50,20 @@ void send(Client* client, uint8_t* data, size_t data_length) { uint8_t result[256]; create_frame(&i_frame.base, result); - void* serial_port = client->serial_port; - sendSerialData(client->serial_port, &i_frame.base.data, i_frame.base.data_length); + sendSerialData(client->serial_port, i_frame.base.data, i_frame.base.data_length); client->_send_sequence_number++; } -void receive_data(Client* client) { +void receive_data(Client* client, uint8_t* recivedData, int lenRecived) { void* serial_port = client->serial_port; - // Read data from serial port - // ... - - // Process received data - // ... + bool flag = true; + while(flag){ + int bytes_received = receiveSerialData(serial_port, recivedData, lenRecived); + if (bytes_received > 0){ + flag = false; + } + } } bool validate(Client* client, HDLCFrame* frame, uint8_t* received_data, size_t received_length) { @@ -93,7 +90,7 @@ bool validate(Client* client, HDLCFrame* frame, uint8_t* received_data, size_t r return false; } -int sendSerialData(const char* port, const char* data, size_t length) { +int sendSerialData(const char* port, uint8_t* data, size_t length) { int serial_port = open(port, O_RDWR); // Replace "port" with your serial port device if (serial_port < 0) { @@ -110,4 +107,23 @@ int sendSerialData(const char* port, const char* data, size_t length) { close(serial_port); return bytes_written; +} + +int receiveSerialData(const char* port, uint8_t* data, int length) { + int serial_port = open(port, O_RDWR); // Replace "port" with your serial port device + + if (serial_port < 0) { + perror("Error opening the serial port"); + return -1; + } + + ssize_t bytes_read = read(serial_port, data, length); + + if (bytes_read < 0) { + perror("Error reading from the serial port"); + return -1; + } + + close(serial_port); + return bytes_read; } \ No newline at end of file diff --git a/hdlc/client.h b/hdlc/client.h index 6b48c0a..ca306cb 100644 --- a/hdlc/client.h +++ b/hdlc/client.h @@ -22,8 +22,9 @@ typedef struct { void init_Client(Client* client, bool test_is_valid, uint8_t address, void* serial_port); void connect(Client* client); void send(Client* client, uint8_t* data, size_t data_length); -void receive_data(Client* client); +void receive_data(Client* client, uint8_t* recivedData, int lenRecived); bool validate(Client* client, HDLCFrame* frame, uint8_t* received_data, size_t received_length); -int sendSerialData(const char* port, const char* data, size_t length); +int sendSerialData(const char* port, uint8_t* data, size_t length); +int receiveSerialData(const char* port, uint8_t* data, int length); #endif From 321722d9b1c5551bd5db6bb97a91fdde942e6099 Mon Sep 17 00:00:00 2001 From: Qukich Date: Sun, 25 Jun 2023 16:04:52 +0300 Subject: [PATCH 13/14] rework validate --- hdlc/client.c | 45 ++++++++++++++++++++++----------------------- hdlc/client.h | 6 ++---- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/hdlc/client.c b/hdlc/client.c index a4307af..51b4b0a 100644 --- a/hdlc/client.c +++ b/hdlc/client.c @@ -3,6 +3,9 @@ #include #include +#define START_FLAG 0x7E +#define END_FLAG 0x7E + void init_Client(Client* client, bool test_is_valid, uint8_t address, void* serial_port) { client->TEST_IS_VALID = test_is_valid; client->address = address; @@ -34,7 +37,7 @@ void connect(Client* client) { HDLCFrame frame; init_HDLCFrame(&frame, 0, 0, data + 3, 256 - 6); - if (validate(client, &frame, data, 256)) { + if (validate(data, 256)) { return; } else { // Connection failed @@ -66,32 +69,28 @@ void receive_data(Client* client, uint8_t* recivedData, int lenRecived) { } } -bool validate(Client* client, HDLCFrame* frame, uint8_t* received_data, size_t received_length) { - uint8_t control = received_data[2]; - if ((control & 0x01) == 0) { - // I-frame - printf("i frame\n"); - uint8_t send_sequence_number = (control >> 1) & 0x07; - uint16_t crc = (received_data[received_length - 2] << 8) | received_data[received_length - 3]; - uint16_t calculated_crc = calculate_fcs(received_data + 1, received_length - 4); - if (crc == calculated_crc && send_sequence_number == client->_receive_sequence_number && client->TEST_IS_VALID) { - client->_receive_sequence_number++; - return true; - } - } else if ((control & 0x03) == 1) { - // S-frame - printf("s frame\n"); - // Handle S-frame - } else { - // U-frame - printf("u frame\n"); - // Handle U-frame +#include + +bool validate(const uint8_t* frame, size_t length) { + if (length < 4 || frame[0] != START_FLAG || frame[length - 1] != END_FLAG) { + // Invalid frame length or missing start/end flag + return false; } - return false; + + uint16_t received_fcs = (frame[length - 3] << 8) | frame[length - 2]; + uint16_t calculated_fcs = 0xFFFF; + + for (size_t i = 1; i < length - 3; i++) { + uint8_t byte = frame[i]; + calculated_fcs = (calculated_fcs >> 8) ^ (calculated_fcs << 8) ^ byte; + calculated_fcs &= 0xFFFF; + } + + return received_fcs == calculated_fcs; } int sendSerialData(const char* port, uint8_t* data, size_t length) { - int serial_port = open(port, O_RDWR); // Replace "port" with your serial port device + int serial_port = open(port, O_RDWR); if (serial_port < 0) { perror("Error opening the serial port"); diff --git a/hdlc/client.h b/hdlc/client.h index ca306cb..fb18c71 100644 --- a/hdlc/client.h +++ b/hdlc/client.h @@ -1,6 +1,4 @@ -// -// Created by 79513 on 19.06.2023. -// + #ifndef CLIENT_H #define CLIENT_H @@ -23,7 +21,7 @@ void init_Client(Client* client, bool test_is_valid, uint8_t address, void* seri void connect(Client* client); void send(Client* client, uint8_t* data, size_t data_length); void receive_data(Client* client, uint8_t* recivedData, int lenRecived); -bool validate(Client* client, HDLCFrame* frame, uint8_t* received_data, size_t received_length); +bool validate(const uint8_t* frame, size_t length); int sendSerialData(const char* port, uint8_t* data, size_t length); int receiveSerialData(const char* port, uint8_t* data, int length); From ecdac7b3d38e66ad96bc7e260930f6f15f0c4769 Mon Sep 17 00:00:00 2001 From: Qukich Date: Sun, 25 Jun 2023 16:36:30 +0300 Subject: [PATCH 14/14] delete serial ports --- hdlc/client.c => client.c | 25 +++++++++++-------------- hdlc/client.h => client.h | 10 +++------- hdlc/hdlc_frame.c => hdlc_frame.c | 0 hdlc/hdlc_frame.h => hdlc_frame.h | 0 4 files changed, 14 insertions(+), 21 deletions(-) rename hdlc/client.c => client.c (78%) rename hdlc/client.h => client.h (61%) rename hdlc/hdlc_frame.c => hdlc_frame.c (100%) rename hdlc/hdlc_frame.h => hdlc_frame.h (100%) diff --git a/hdlc/client.c b/client.c similarity index 78% rename from hdlc/client.c rename to client.c index 51b4b0a..a456c45 100644 --- a/hdlc/client.c +++ b/client.c @@ -6,13 +6,12 @@ #define START_FLAG 0x7E #define END_FLAG 0x7E -void init_Client(Client* client, bool test_is_valid, uint8_t address, void* serial_port) { +void init_Client(Client* client, bool test_is_valid, uint8_t address) { client->TEST_IS_VALID = test_is_valid; client->address = address; client->_send_sequence_number = 0; client->poll_final = 1; client->_receive_sequence_number = 0; - client->serial_port = serial_port; } @@ -23,21 +22,20 @@ void connect(Client* client) { uint8_t result[256]; create_frame(&u_frame.base, result); - void* serial_port = client->serial_port; - sendSerialData(serial_port, u_frame.base.data, u_frame.base.data_length); + // Wait for acknowledgment frame bool flag = true; - uint8_t data[u_frame.base.data_length]; + uint8_t data; while(flag){ - int bytes_received = receiveSerialData(serial_port, data, 256); - if (bytes_received > 0){ + data = uart_read(); + if (data > 0){ flag = false; } } HDLCFrame frame; - init_HDLCFrame(&frame, 0, 0, data + 3, 256 - 6); - if (validate(data, 256)) { + init_HDLCFrame(&frame, 0, 0, &data + 3, 256 - 6); + if (validate(&data, 256)) { return; } else { // Connection failed @@ -53,17 +51,16 @@ void send(Client* client, uint8_t* data, size_t data_length) { uint8_t result[256]; create_frame(&i_frame.base, result); - sendSerialData(client->serial_port, i_frame.base.data, i_frame.base.data_length); + uart_send_byte(*i_frame.base.data); client->_send_sequence_number++; } -void receive_data(Client* client, uint8_t* recivedData, int lenRecived) { - void* serial_port = client->serial_port; +void receive_data(uint8_t* recivedData) { bool flag = true; while(flag){ - int bytes_received = receiveSerialData(serial_port, recivedData, lenRecived); - if (bytes_received > 0){ + *recivedData = uart_read(); + if (recivedData > 0){ flag = false; } } diff --git a/hdlc/client.h b/client.h similarity index 61% rename from hdlc/client.h rename to client.h index fb18c71..0a19d58 100644 --- a/hdlc/client.h +++ b/client.h @@ -1,9 +1,8 @@ - - #ifndef CLIENT_H #define CLIENT_H #include "hdlc_frame.h" +#include "uart_module.h" #include #include // Для использования size_t #include @@ -14,15 +13,12 @@ typedef struct { uint8_t _send_sequence_number; uint8_t poll_final; uint8_t _receive_sequence_number; - void* serial_port; // Указатель на объект последовательного порта } Client; -void init_Client(Client* client, bool test_is_valid, uint8_t address, void* serial_port); +void init_Client(Client* client, bool test_is_valid, uint8_t address); void connect(Client* client); void send(Client* client, uint8_t* data, size_t data_length); -void receive_data(Client* client, uint8_t* recivedData, int lenRecived); +void receive_data(uint8_t* recivedData); bool validate(const uint8_t* frame, size_t length); -int sendSerialData(const char* port, uint8_t* data, size_t length); -int receiveSerialData(const char* port, uint8_t* data, int length); #endif diff --git a/hdlc/hdlc_frame.c b/hdlc_frame.c similarity index 100% rename from hdlc/hdlc_frame.c rename to hdlc_frame.c diff --git a/hdlc/hdlc_frame.h b/hdlc_frame.h similarity index 100% rename from hdlc/hdlc_frame.h rename to hdlc_frame.h