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