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