add client
This commit is contained in:
parent
4b4a162f72
commit
eceecf15d4
113
hdlc/client.c
Normal file
113
hdlc/client.c
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
#include "client.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
29
hdlc/client.h
Normal file
29
hdlc/client.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// Created by 79513 on 19.06.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef CLIENT_H
|
||||||
|
#define CLIENT_H
|
||||||
|
|
||||||
|
#include "hdlc_frame.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h> // Для использования size_t
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
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
|
@ -1,26 +1,26 @@
|
|||||||
#include "hdlc_frame.h"
|
#include "hdlc_frame.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define START_FLAG 0x7E
|
#define START_FLAG 0x7E
|
||||||
#define END_FLAG 0x7E
|
#define END_FLAG 0x7E
|
||||||
#define ESCAPE_FLAG 0x7D
|
#define ESCAPE_FLAG 0x7D
|
||||||
#define ESCAPE_XOR 0x20
|
#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->address = address;
|
||||||
frame->control = control;
|
frame->control = control;
|
||||||
frame->data = data;
|
frame->data = data;
|
||||||
frame->data_length = data_length;
|
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;
|
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[0] = frame->address;
|
||||||
data_bytes[1] = frame->control;
|
data_bytes[1] = frame->control;
|
||||||
|
memcpy(data_bytes + 2, frame->data, frame->data_length);
|
||||||
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++) {
|
for (size_t i = 0; i < frame->data_length + 2; i++) {
|
||||||
uint8_t byte = data_bytes[i];
|
uint8_t byte = data_bytes[i];
|
||||||
@ -31,47 +31,78 @@ uint16_t calculate_fcs(HDLCFrame* frame) {
|
|||||||
return fcs;
|
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;
|
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++) {
|
result[index++] = START_FLAG;
|
||||||
uint8_t byte = frame->data[i];
|
result[index++] = frame->address;
|
||||||
if (byte == START_FLAG || byte == END_FLAG || byte == ESCAPE_FLAG) {
|
result[index++] = frame->control;
|
||||||
frame_data[index++] = ESCAPE_FLAG;
|
|
||||||
frame_data[index++] = byte ^ ESCAPE_XOR;
|
if (frame->data != NULL) {
|
||||||
} else {
|
for (size_t i = 0; i < frame->data_length; i++) {
|
||||||
frame_data[index++] = byte;
|
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);
|
uint16_t fcs = calculate_fcs(frame, 0);
|
||||||
frame_data[index++] = fcs & 0xFF;
|
result[index++] = fcs & 0xFF;
|
||||||
frame_data[index++] = (fcs >> 8) & 0xFF;
|
result[index++] = (fcs >> 8) & 0xFF;
|
||||||
frame_data[index] = END_FLAG;
|
result[index++] = END_FLAG;
|
||||||
|
|
||||||
*frame_length = index + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HDLCFrame* create_u_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length) {
|
void init_IFrame(IFrame* frame, uint8_t address, uint8_t receive_sequence_number, uint8_t poll_final,
|
||||||
HDLCFrame* frame = (HDLCFrame*)malloc(sizeof(HDLCFrame));
|
uint8_t send_sequence_number, uint8_t* data, size_t data_length) {
|
||||||
initialize_frame(frame, address, control, data, data_length);
|
init_HDLCFrame(&frame->base, address,
|
||||||
return frame;
|
((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) {
|
void init_SFrame(SFrame* frame, uint8_t address, uint8_t receive_sequence_number, uint8_t poll_final,
|
||||||
HDLCFrame* frame = (HDLCFrame*)malloc(sizeof(HDLCFrame));
|
const char* frame_type) {
|
||||||
initialize_frame(frame, address, control, data, data_length);
|
uint8_t frame_type_value;
|
||||||
frame->control |= (receive_sequence_number << 2) & 0xFC;
|
if (strcmp(frame_type, "RR") == 0) {
|
||||||
frame->control |= (send_sequence_number << 1) & 0xFE;
|
frame_type_value = 0;
|
||||||
return frame;
|
} 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) {
|
void init_UFrame(UFrame* frame, uint8_t address, uint8_t poll_final, const char* frame_type,
|
||||||
HDLCFrame* frame = (HDLCFrame*)malloc(sizeof(HDLCFrame));
|
uint8_t* data, size_t data_length) {
|
||||||
initialize_frame(frame, address, control, data, data_length);
|
uint8_t frame_type_value;
|
||||||
frame->control |= (sequence_number << 1) & 0xFE;
|
if (strcmp(frame_type, "BP") == 0) {
|
||||||
return frame;
|
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;
|
||||||
}
|
}
|
@ -2,7 +2,6 @@
|
|||||||
#define HDLC_FRAME_H
|
#define HDLC_FRAME_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#define MAX_FRAME_LENGTH 256
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t address;
|
uint8_t address;
|
||||||
@ -11,13 +10,36 @@ typedef struct {
|
|||||||
size_t data_length;
|
size_t data_length;
|
||||||
} HDLCFrame;
|
} HDLCFrame;
|
||||||
|
|
||||||
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);
|
||||||
uint16_t calculate_fcs(HDLCFrame* frame);
|
uint16_t calculate_fcs(const HDLCFrame *frame, size_t i);
|
||||||
void create_frame(HDLCFrame* frame, uint8_t* frame_data, size_t* frame_length);
|
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);
|
typedef struct {
|
||||||
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 base;
|
||||||
HDLCFrame* create_i_frame(uint8_t address, uint8_t control, uint8_t* data, size_t data_length, uint8_t sequence_number);
|
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);
|
||||||
|
|
||||||
|
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
|
#endif
|
@ -1,42 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#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;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user