Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ec42fbb8c | ||
|
|
ab3a8bc820 | ||
|
|
7b6eaa563b | ||
|
|
c719f259ed | ||
|
|
b32be8eaa4 | ||
|
|
bfe0df9256 | ||
|
|
14e71a3ccc | ||
|
|
8a38d78c25 |
17
.gitignore
vendored
17
.gitignore
vendored
@ -1,14 +1,3 @@
|
|||||||
# ---> CMake
|
.cache/
|
||||||
CMakeLists.txt.user
|
build/
|
||||||
CMakeCache.txt
|
*.zip
|
||||||
CMakeFiles
|
|
||||||
CMakeScripts
|
|
||||||
Testing
|
|
||||||
Makefile
|
|
||||||
cmake_install.cmake
|
|
||||||
install_manifest.txt
|
|
||||||
compile_commands.json
|
|
||||||
CTestTestfile.cmake
|
|
||||||
_deps
|
|
||||||
CMakeUserPresets.json
|
|
||||||
|
|
||||||
|
|||||||
18
.vscode/c_cpp_properties.json
vendored
Normal file
18
.vscode/c_cpp_properties.json
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Linux",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**"
|
||||||
|
],
|
||||||
|
// "defines": ["DO_UNIT_TESTS=1"],
|
||||||
|
"compilerPath": "/usr/bin/clang",
|
||||||
|
"cStandard": "c17",
|
||||||
|
"cppStandard": "c++17",
|
||||||
|
"intelliSenseMode": "linux-clang-x64",
|
||||||
|
"configurationProvider": "ms-vscode.cmake-tools",
|
||||||
|
"compileCommands": "${workspaceFolder}/build/compile_commands.json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
30
.vscode/launch.json
vendored
Normal file
30
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "(gdb) Launch",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/build/bin/test-kod-bez",
|
||||||
|
"args": [],
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"cwd": "${fileDirname}",
|
||||||
|
"environment": [],
|
||||||
|
"externalConsole": false,
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"setupCommands": [
|
||||||
|
{
|
||||||
|
"description": "Enable pretty-printing for gdb",
|
||||||
|
"text": "-enable-pretty-printing",
|
||||||
|
"ignoreFailures": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Set Disassembly Flavor to Intel",
|
||||||
|
"text": "-gdb-set disassembly-flavor intel",
|
||||||
|
"ignoreFailures": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"preLaunchTask": "CMake: build"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
32
.vscode/settings.json
vendored
Normal file
32
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"worker_type.h": "c",
|
||||||
|
"main.h": "c",
|
||||||
|
"stdio.h": "c",
|
||||||
|
"stdint.h": "c",
|
||||||
|
"stdbool.h": "c",
|
||||||
|
"unistd.h": "c",
|
||||||
|
"stdlib.h": "c",
|
||||||
|
"time.h": "c",
|
||||||
|
"hdlc_type.h": "c",
|
||||||
|
"hdlc.h": "c",
|
||||||
|
"fifo_type.h": "c",
|
||||||
|
"chrono": "c",
|
||||||
|
"span": "c",
|
||||||
|
"worker.h": "c",
|
||||||
|
"fifo.h": "c",
|
||||||
|
"string.h": "c",
|
||||||
|
"*.ipp": "c",
|
||||||
|
"cstring": "c",
|
||||||
|
"stddef.h": "c",
|
||||||
|
"coroutine": "c",
|
||||||
|
"filo.h": "c",
|
||||||
|
"filo_type.h": "c",
|
||||||
|
"array": "c",
|
||||||
|
"string": "c",
|
||||||
|
"string_view": "c",
|
||||||
|
"ranges": "c",
|
||||||
|
"compare": "c",
|
||||||
|
"cstdint": "c"
|
||||||
|
}
|
||||||
|
}
|
||||||
40
CMakeLists.txt
Normal file
40
CMakeLists.txt
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
cmake_minimum_required(VERSION 4.1 FATAL_ERROR)
|
||||||
|
|
||||||
|
set(PROJECT_NAME test-kod-bez)
|
||||||
|
set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||||
|
|
||||||
|
project(${PROJECT_NAME} LANGUAGES C)
|
||||||
|
set(CMAKE_C_STANDARD 11)
|
||||||
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_C_EXTENSIONS OFF)
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
# set(CMAKE_BUILD_TYPE Release)
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} ${SOURCE_DIR}/main.c)
|
||||||
|
|
||||||
|
set(HEADERS
|
||||||
|
${SOURCE_DIR}
|
||||||
|
${SOURCE_DIR}/hdlc
|
||||||
|
${SOURCE_DIR}/worker
|
||||||
|
${SOURCE_DIR}/fifo
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
${SOURCE_DIR}/main.c
|
||||||
|
${SOURCE_DIR}/tools.c
|
||||||
|
${SOURCE_DIR}/hdlc/hdlc.c
|
||||||
|
${SOURCE_DIR}/worker/worker.c
|
||||||
|
${SOURCE_DIR}/worker/worker_tools.c
|
||||||
|
${SOURCE_DIR}/worker/worker_master.c
|
||||||
|
${SOURCE_DIR}/worker/worker_slave.c
|
||||||
|
${SOURCE_DIR}/fifo/fifo.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(${PROJECT_NAME} PRIVATE ${HEADERS})
|
||||||
|
# target_compile_definitions(${PROJECT_NAME} PUBLIC )
|
||||||
|
|
||||||
|
target_sources(${PROJECT_NAME} PRIVATE ${SOURCES})
|
||||||
|
|
||||||
|
target_compile_options(${PROJECT_NAME} PRIVATE -O0 -Wall -Wextra)
|
||||||
|
set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "bin")
|
||||||
90
readme.md
Normal file
90
readme.md
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
# Тестовое задание
|
||||||
|
|
||||||
|
## Описание
|
||||||
|
Программа демонстрирует взаимодействие клиента с сервером посредством протокола HDLC
|
||||||
|
|
||||||
|
## Структура проекта
|
||||||
|
- **fifo** - исходные коды для работы с fifo
|
||||||
|
- fifo_type.h - структуры и типы для работы с fifo
|
||||||
|
- fifo.h
|
||||||
|
- fifo.c
|
||||||
|
- **hdlc** - исходные коды для работы с hdlc
|
||||||
|
- hdlc_type.h - структуры и типы для работы с hdlc
|
||||||
|
- hdlc.h
|
||||||
|
- hdlc.c
|
||||||
|
- main.h
|
||||||
|
- main.c
|
||||||
|
- tools.c - вспомагательные функции
|
||||||
|
- worker - исходные коды обработчиков (хостов)
|
||||||
|
- worker.h
|
||||||
|
- worker.c
|
||||||
|
- worker_master.c - файл с ведущим хостом
|
||||||
|
- worker_slave.c - файл с ведомым хостом
|
||||||
|
|
||||||
|
|
||||||
|
## Задача
|
||||||
|
Необходимо разработать программу на языке C без использования сторонних
|
||||||
|
библиотек и наработок (ChatGPT, исходники с github и т.п.) для реализации
|
||||||
|
её основных функций. Для реализации вспомогательных функций типа ввода-вывода,
|
||||||
|
расчёта CRC и т.п. можно использовать библиотечные функции или исходные
|
||||||
|
тексты библиотек с github или аналогичного ресурса.
|
||||||
|
|
||||||
|
Программа должна реализовывать модель системы, состоящей из двух узлов
|
||||||
|
(ведущего и ведомого), взаимодействующих друг с другом по протоколу
|
||||||
|
HDLC (https://ru.wikipedia.org/wiki/HDLC) через два байтовых FIFO размером 8 байт.
|
||||||
|
Один блок FIFO должен обеспечивать передачу байт данных от ведущего к ведомому,
|
||||||
|
а другой в обратном направлении. Программная реализация FIFO должна обеспечивать
|
||||||
|
возможность записи и чтения одного байта в FIFO, а также проверку его состояния:
|
||||||
|
FIFO пуст или FIFO полон. Вся логика работы программы должна быть реализована
|
||||||
|
в виде общего цикла в функции main (big loop OS) и демонстрировать отправку
|
||||||
|
ведущим узлом команды в направлении ведомого, ожидание получения ответа от ведомого,
|
||||||
|
получение и обработку ответа. При этом на экран в текстовом виде должны
|
||||||
|
выводиться сообщения, позволяющие понять что сейчас происходит и в каком из
|
||||||
|
узлов моделируемой системы.
|
||||||
|
|
||||||
|
Адреса на виртуальной шине HDLC можно выбрать константными.
|
||||||
|
Управляющее поле пакета должно обеспечивать выбор команды, которая будет
|
||||||
|
выполняться на стороне ведомого устройства. Размер информационного поля пакета должен
|
||||||
|
быть не менее 16 байт. При реализации обработки команды на стороне
|
||||||
|
ведомого не требуется реализовывать какую-то сложную обработку, достаточно например
|
||||||
|
поменять порядок байт в исходной полученной команде или что-то вроде этого.
|
||||||
|
|
||||||
|
Сразу уточню, что по условиям задачи посылка от ведущего к ведомому целиком
|
||||||
|
не влезет в FIFO между ними. Поэтому по сути необходимо будет реализовать работу в
|
||||||
|
асинхронном режиме записи в FIFO с опросом его состояния и возвратом управления
|
||||||
|
в главный цикл при невозможности чтения или записи из/в FIFO.
|
||||||
|
|
||||||
|
При оценке будет учитываться как логика работы, так и стиль написания
|
||||||
|
(имена функций и переменных должны быть осмысленными, комментарии должны
|
||||||
|
пояснять ключевые решения в коде и т.п.).
|
||||||
|
|
||||||
|
Программа должна компилироваться типовым компилятором и не должна требовать
|
||||||
|
наличия нестандартных библиотек (для реализации достаточно stdio, stdlib и т.п.
|
||||||
|
стандартных библиотек С).
|
||||||
|
|
||||||
|
Апдейт
|
||||||
|
Протокол нужно реализовать как транспорт для своих тестовых команд. Поэтому в нём должны быть реализованы только самые базовые вещи: фрейминг, проверка контрольных сумм, байт-стаффинг и т.п. Минимальная реализация.
|
||||||
|
Никаких множественных буферов пакетов не требуется, достаточно одного буфера на приём и одного буфера на передачу на каждом из участников обмена. Ведущий всегда отправляет один пакет данных с командой и параметрами, а далее ждёт получения ответа на свою команду от ведомого. Аналогично и у ведомого - он ждёт получения команды от ведущего, а дальше отправляет ответ ведущему и пока не отправил новые запросы от ведущего не обрабатывает. Никаких очередей команд. FIFO, указанный в задании, используется для эмуляции канала между ведущим и ведомым устройствами, т.к. как RX и TX FIFO UART. В канале предполагается наличие контроля потока и блокировка передачи при заполнении FIFO, т.е. если FIFO оказалось забито, то отправитель данных будет ждать пока оно освободится.
|
||||||
|
|
||||||
|
|
||||||
|
## Функции и их параметры
|
||||||
|
### worker
|
||||||
|
- *int WORK_execute(int (*callback)(workerHost_s*), workerHost_s *worker);*
|
||||||
|
- int WORK_preparePackage(workerHost_s *worker);
|
||||||
|
- int WORK_sendPackage(workerHost_s *worker);
|
||||||
|
- int WORK_waitPackage(workerHost_s *worker);
|
||||||
|
- int WORK_receivePackage(workerHost_s *worker);
|
||||||
|
- int WORK_checkPackage(workerHost_s *worker);
|
||||||
|
- int WORK_parsePackage(workerHost_s *worker);
|
||||||
|
- int WORK_fillBuffer8b(uint8_t *buffer, size_t size);
|
||||||
|
|
||||||
|
// tools
|
||||||
|
int WORK_printBlocks(workerHost_s *worker, uint8_t mode);
|
||||||
|
int WORK_testFill(uint8_t* buffer, size_t bufferSize);
|
||||||
|
### tools
|
||||||
|
- TOOL_workerPrintBlocks
|
||||||
|
- hdlcHost_s *worker - указатель на машину
|
||||||
|
- uint8_t mode - режим
|
||||||
|
- 0 - не выводить ничего
|
||||||
|
- 1 - вывести содержимое пакета
|
||||||
|
- 3 - вывести содержимое буфера
|
||||||
93
src/fifo/fifo.c
Normal file
93
src/fifo/fifo.c
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include "fifo.h"
|
||||||
|
#include "stdio.h"
|
||||||
|
|
||||||
|
// if (FIFO_get(fifo, byte) == 0) {
|
||||||
|
// OK
|
||||||
|
// } else {
|
||||||
|
// FIFO ERROR
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Инициализация fifo
|
||||||
|
int FIFO_init(fifo_s* fifo) {
|
||||||
|
if (fifo != NULL) {
|
||||||
|
for (size_t i = 0; i < FIFO_DATA_SIZE; ++i) {
|
||||||
|
fifo->data[i] = 0;
|
||||||
|
}
|
||||||
|
fifo->head = 0;
|
||||||
|
fifo->tail = 0;
|
||||||
|
fifo->count = 0;
|
||||||
|
fifo->state = FIFOS_empty;
|
||||||
|
fifo->isInitialized = 1;
|
||||||
|
if (FIFO_isUsable(fifo) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Заполнение fifo
|
||||||
|
int FIFO_put(fifo_s* fifo, uint8_t data) {
|
||||||
|
if (FIFO_isUsable(fifo) == 0) { // Не заполнено
|
||||||
|
if ((fifo->state == FIFOS_empty) || (fifo->state == FIFOS_ready)) {
|
||||||
|
fifo->data[fifo->tail] = data;
|
||||||
|
fifo->tail = (fifo->tail + 1) % FIFO_DATA_SIZE;
|
||||||
|
if (fifo->count < FIFO_DATA_SIZE - 1) {
|
||||||
|
fifo->count++;
|
||||||
|
fifo->state = FIFOS_ready;
|
||||||
|
} else {
|
||||||
|
fifo->count = FIFO_DATA_SIZE - 1;
|
||||||
|
fifo->state = FIFOS_full;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Получение из fifo
|
||||||
|
int FIFO_get(fifo_s* fifo, uint8_t *data) {
|
||||||
|
if (FIFO_isUsable(fifo) == 0) {
|
||||||
|
if ((fifo->state == FIFOS_full) || (fifo->state == FIFOS_ready)) {
|
||||||
|
*data = fifo->data[fifo->head];
|
||||||
|
fifo->data[fifo->head] = 0;
|
||||||
|
fifo->head = (fifo->head + 1) % FIFO_DATA_SIZE;
|
||||||
|
if (fifo->count > 1) {
|
||||||
|
fifo->count--;
|
||||||
|
fifo->state = FIFOS_ready;
|
||||||
|
} else {
|
||||||
|
fifo->count = 0;
|
||||||
|
fifo->state = FIFOS_empty;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int FIFO_print(fifo_s* fifo) {
|
||||||
|
if (FIFO_isUsable(fifo) == 0) {
|
||||||
|
printf("FIFO: ");
|
||||||
|
for (size_t i = 0; i < FIFO_DATA_SIZE; i++) {
|
||||||
|
printf("%d", fifo->data[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Проверка доступности fifo
|
||||||
|
int FIFO_isUsable(fifo_s* fifo) {
|
||||||
|
if (fifo != NULL) {
|
||||||
|
if (fifo->isInitialized == 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
29
src/fifo/fifo.h
Normal file
29
src/fifo/fifo.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef FIFO_H
|
||||||
|
#define FIFO_H
|
||||||
|
|
||||||
|
#include "fifo_type.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
// Размер FIFO
|
||||||
|
#define FIFO_DATA_SIZE 8
|
||||||
|
|
||||||
|
// Структура FIFO
|
||||||
|
typedef struct {
|
||||||
|
uint8_t data[FIFO_DATA_SIZE];
|
||||||
|
uint8_t head;
|
||||||
|
uint8_t tail;
|
||||||
|
uint8_t count;
|
||||||
|
fifoState_e state;
|
||||||
|
uint8_t isInitialized;
|
||||||
|
} fifo_s;
|
||||||
|
|
||||||
|
|
||||||
|
// Функции FIFO
|
||||||
|
int FIFO_init(fifo_s* fifo);
|
||||||
|
int FIFO_put(fifo_s* fifo, uint8_t data);
|
||||||
|
int FIFO_get(fifo_s* fifo, uint8_t *data);
|
||||||
|
int FIFO_print(fifo_s* fifo);
|
||||||
|
int FIFO_isUsable(fifo_s* fifo);
|
||||||
|
|
||||||
|
#endif // FIFO_H
|
||||||
16
src/fifo/fifo_type.h
Normal file
16
src/fifo/fifo_type.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef FIFO_TYPE_H
|
||||||
|
#define FIFO_TYPE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Структура состояний FIFO
|
||||||
|
typedef enum {
|
||||||
|
FIFOS_empty = 0,
|
||||||
|
FIFOS_ready,
|
||||||
|
FIFOS_full,
|
||||||
|
FIFOS_error
|
||||||
|
} fifoState_e;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // FIFO_TYPE_H
|
||||||
90
src/filo/filo.c
Normal file
90
src/filo/filo.c
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#include "filo.h"
|
||||||
|
#include "stdio.h"
|
||||||
|
|
||||||
|
// if (FILO_get(filo, byte) == 0) {
|
||||||
|
// OK
|
||||||
|
// } else {
|
||||||
|
// FILO ERROR
|
||||||
|
// }
|
||||||
|
|
||||||
|
int FILO_isUsable(filo_s* filo);
|
||||||
|
|
||||||
|
// Инициализация filo
|
||||||
|
int FILO_init(filo_s* filo) {
|
||||||
|
if (filo != NULL) {
|
||||||
|
for (size_t i = 0; i < FILO_DATA_SIZE; ++i) {
|
||||||
|
filo->data[i] = 0;
|
||||||
|
}
|
||||||
|
filo->head = 0;
|
||||||
|
filo->state = FILOS_empty;
|
||||||
|
filo->isInitialized = 1;
|
||||||
|
if (FILO_isUsable(filo) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Заполнение filo
|
||||||
|
int FILO_put(filo_s* filo, uint8_t data) {
|
||||||
|
if (FILO_isUsable(filo) == 0) { // Не заполнено
|
||||||
|
if ((filo->state == FILOS_empty) || (filo->state == FILOS_ready)) {
|
||||||
|
filo->data[filo->head] = data;
|
||||||
|
|
||||||
|
if (filo->head < FILO_DATA_SIZE-1) {
|
||||||
|
filo->head++;
|
||||||
|
filo->state = FILOS_ready;
|
||||||
|
} else {
|
||||||
|
filo->head = FILO_DATA_SIZE-1;
|
||||||
|
filo->state = FILOS_full;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Получение из filo
|
||||||
|
int FILO_get(filo_s* filo, uint8_t *data) {
|
||||||
|
if (FILO_isUsable(filo) == 0) {
|
||||||
|
if ((filo->state == FILOS_full) || (filo->state == FILOS_ready)) {
|
||||||
|
*data = filo->data[filo->head-1];
|
||||||
|
filo->data[filo->head-1] = 0;
|
||||||
|
if (filo->head > 1) {
|
||||||
|
filo->head--;
|
||||||
|
filo->state = FILOS_ready;
|
||||||
|
} else {
|
||||||
|
filo->head = 0;
|
||||||
|
filo->state = FILOS_empty;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int FILO_print(filo_s* filo) {
|
||||||
|
if (FILO_isUsable(filo) == 0) {
|
||||||
|
printf("FILO: ");
|
||||||
|
for (size_t i = 0; i < FILO_DATA_SIZE; i++) {
|
||||||
|
printf("%d", filo->data[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Проверка доступности filo
|
||||||
|
int FILO_isUsable(filo_s* filo) {
|
||||||
|
if (filo != NULL) {
|
||||||
|
if (filo->isInitialized == 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
27
src/filo/filo.h
Normal file
27
src/filo/filo.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef FILO_H
|
||||||
|
#define FILO_H
|
||||||
|
|
||||||
|
#include "filo_type.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
// Размер FILO
|
||||||
|
#define FILO_DATA_SIZE 8
|
||||||
|
|
||||||
|
// Структура FILO
|
||||||
|
typedef struct {
|
||||||
|
uint8_t data[FILO_DATA_SIZE];
|
||||||
|
uint8_t head;
|
||||||
|
filoState_e state;
|
||||||
|
uint8_t isInitialized;
|
||||||
|
} filo_s;
|
||||||
|
|
||||||
|
|
||||||
|
// Функции FILO
|
||||||
|
int FILO_init(filo_s* filo);
|
||||||
|
int FILO_put(filo_s* filo, uint8_t data);
|
||||||
|
int FILO_get(filo_s* filo, uint8_t *data);
|
||||||
|
int FILO_print(filo_s* filo);
|
||||||
|
int FILO_isUsable(filo_s* filo);
|
||||||
|
|
||||||
|
#endif // FILO_H
|
||||||
16
src/filo/filo_type.h
Normal file
16
src/filo/filo_type.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef FILO_TYPE_H
|
||||||
|
#define FILO_TYPE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Структура состояний FILO
|
||||||
|
typedef enum {
|
||||||
|
FILOS_empty = 0,
|
||||||
|
FILOS_ready,
|
||||||
|
FILOS_full,
|
||||||
|
FILOS_error
|
||||||
|
} filoState_e;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // FILO_TYPE_H
|
||||||
39
src/hdlc/hdlc.c
Normal file
39
src/hdlc/hdlc.c
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#include "main.h"
|
||||||
|
#include "hdlc.h"
|
||||||
|
#include "hdlc_type.h"
|
||||||
|
|
||||||
|
|
||||||
|
int HDLC_printControlField (hdlcControlField16b_u field);
|
||||||
|
|
||||||
|
|
||||||
|
int HDLC_printControlField (hdlcControlField16b_u field) {
|
||||||
|
printf ("HDLC: Printing fields:\n");
|
||||||
|
printf ("HDLC: .. Type:\n");
|
||||||
|
printf ("HDLC: .. Send sequence: %d\n", field.bits.sendSequence);
|
||||||
|
printf ("HDLC: .. Poll/Final: %d\n", field.bits.pollFinal);
|
||||||
|
printf ("HDLC: .. Receive sequence: %d\n", field.bits.receiveSequence);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
hdlcControlField16b_u HDLC_parseControlField (uint16_t value) {
|
||||||
|
hdlcControlField16b_u fieldUnion;
|
||||||
|
// fieldUnion.value = TOOL_reverseBits16(value);
|
||||||
|
fieldUnion.value = value;
|
||||||
|
|
||||||
|
HDLC_printControlField(fieldUnion);
|
||||||
|
|
||||||
|
return fieldUnion;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int HDLC_isControlFieldValid (uint16_t value) {
|
||||||
|
if ((value == 0xffff) || (value == 0)) {
|
||||||
|
printf ("HDLC: Wrong control field:\n");
|
||||||
|
// Так как обрабатывается только вариант с информационным пакетом
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
23
src/hdlc/hdlc.h
Normal file
23
src/hdlc/hdlc.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef HDLC_H
|
||||||
|
#define HDLC_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "hdlc_type.h"
|
||||||
|
|
||||||
|
// Cтруктура поля управления
|
||||||
|
typedef union {
|
||||||
|
struct __attribute__((packed)) {
|
||||||
|
uint8_t receiveSequence : 7;
|
||||||
|
uint8_t pollFinal : 1;
|
||||||
|
uint8_t sendSequence : 7;
|
||||||
|
uint8_t type : 1;
|
||||||
|
} bits;
|
||||||
|
uint16_t value;
|
||||||
|
} hdlcControlField16b_u;
|
||||||
|
|
||||||
|
int HDLC_isControlFieldValid (uint16_t value);
|
||||||
|
hdlcControlField16b_u HDLC_parseControlField (uint16_t value);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // HDLC_H
|
||||||
33
src/hdlc/hdlc_type.h
Normal file
33
src/hdlc/hdlc_type.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef HDLC_TYPE_H
|
||||||
|
#define HDLC_TYPE_H
|
||||||
|
|
||||||
|
#include "fifo_type.h"
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------------
|
||||||
|
// Фрейм HDLC
|
||||||
|
// Флаг FD | Адрес | Управляющее поле | Информационное поле | FCS | Флаг FD
|
||||||
|
// 8 бит | кратно 8 | 8 или 16 бит | 0 или более байт | 16 бит | 8 бит
|
||||||
|
// ----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define HDLC_INFO_LENGTH 16
|
||||||
|
#define HDLC_PACKET_LENGTH 1+2+2+HDLC_INFO_LENGTH+2+1
|
||||||
|
|
||||||
|
#define HDLC_PACKET_FLAG 0x7e
|
||||||
|
#define HDLC_PACKET_ESCAPE 0xab
|
||||||
|
|
||||||
|
// Структура пакета (фрейма) HDLC
|
||||||
|
typedef struct {
|
||||||
|
// const uint8_t flag;
|
||||||
|
uint16_t address;
|
||||||
|
uint16_t control;
|
||||||
|
uint8_t info[HDLC_INFO_LENGTH];
|
||||||
|
uint16_t fcs;
|
||||||
|
// const uint8_t closeFlag;
|
||||||
|
} hdlcPacket_s;
|
||||||
|
|
||||||
|
|
||||||
|
static const uint8_t hdlcFlag = 0b01111110;
|
||||||
|
|
||||||
|
#endif // HDLC_TYPE_H
|
||||||
67
src/main.c
Normal file
67
src/main.c
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
// Перечисление статусов машины состояния
|
||||||
|
enum bigLoopOsState_e {
|
||||||
|
OS_first = 0,
|
||||||
|
OS_masterWorker,
|
||||||
|
OS_slaveWorker,
|
||||||
|
OS_wait,
|
||||||
|
OS_last
|
||||||
|
} bigLoopOsState;
|
||||||
|
|
||||||
|
// Текстовые надписи соответствующие статусам машины состояния
|
||||||
|
const char* bigLoopOsStateNames[OS_last] = {
|
||||||
|
"starting",
|
||||||
|
"master worker",
|
||||||
|
"slave worker",
|
||||||
|
"idle"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// BIG LOOP OS
|
||||||
|
int main(void) {
|
||||||
|
// while(true){WORK_master();TOOL_msleep(1000);}
|
||||||
|
|
||||||
|
bigLoopOsState = OS_first;
|
||||||
|
while(true) {
|
||||||
|
if (bigLoopOsState >= OS_last) {
|
||||||
|
bigLoopOsState = OS_masterWorker;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("OS: Current state is: %s\n", bigLoopOsStateNames[bigLoopOsState]);
|
||||||
|
switch (bigLoopOsState) {
|
||||||
|
case OS_first:
|
||||||
|
printf("\n\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OS_masterWorker:
|
||||||
|
WORK_master();
|
||||||
|
printf("\n\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OS_slaveWorker:
|
||||||
|
WORK_slave();
|
||||||
|
printf("\n\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OS_wait:
|
||||||
|
TOOL_msleep(5);
|
||||||
|
printf("\n\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("OS: Wrong state, going to first state");
|
||||||
|
bigLoopOsState = OS_first;
|
||||||
|
TOOL_msleep(3000);
|
||||||
|
printf("\033[2J\033[H");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bigLoopOsState++;
|
||||||
|
|
||||||
|
// Для контроля
|
||||||
|
TOOL_msleep(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
26
src/main.h
Normal file
26
src/main.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef MAIN_H
|
||||||
|
#define MAIN_H
|
||||||
|
|
||||||
|
#define DO_UNIT_TESTS 1
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
// Конфигурация
|
||||||
|
static const uint16_t hdlcMasterAddress = 0b10000000;
|
||||||
|
static const uint16_t hdlcSlaveAddress = 0b11000000;
|
||||||
|
static const uint16_t xorByte = 0xaf;
|
||||||
|
|
||||||
|
// Вспомогательные функции
|
||||||
|
uint16_t CRC16_compute(uint8_t *data, size_t length);
|
||||||
|
uint16_t TOOL_reverseBits16(uint16_t value);
|
||||||
|
void TOOL_msleep(long milliseconds);
|
||||||
|
|
||||||
|
// Потоки ОС
|
||||||
|
int WORK_master(void);
|
||||||
|
int WORK_slave(void);
|
||||||
|
|
||||||
|
#endif //MAIN_H
|
||||||
77
src/tools.c
Normal file
77
src/tools.c
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
// Файл с общими функциями и конфигурацией
|
||||||
|
|
||||||
|
#define _POSIX_C_SOURCE 199309L
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
#pragma message ("plus")
|
||||||
|
#else
|
||||||
|
#pragma message ("pure")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Вычисление контрольной суммы CRC16
|
||||||
|
uint16_t CRC16_compute(uint8_t *data, size_t length) {
|
||||||
|
const uint16_t CRC16_poly = 0x8005;
|
||||||
|
const uint16_t CRC16_initVal = 0xffff;
|
||||||
|
|
||||||
|
uint16_t crc = CRC16_initVal;
|
||||||
|
size_t i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
crc ^= (uint16_t)data[i];
|
||||||
|
for (j = 0; j < 8; j++) {
|
||||||
|
if ((crc & 0x0001) != 0) {
|
||||||
|
crc = (crc >> 1) ^ CRC16_poly;
|
||||||
|
} else {
|
||||||
|
crc >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t TOOL_reverseBits16(uint16_t value) {
|
||||||
|
uint16_t reversed = 0;
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
if ((value >> i) & 1) {
|
||||||
|
reversed |= (1 << (15 - i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return reversed;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t TOOL_reverseBitsN(uint16_t value, uint8_t n) {
|
||||||
|
if ((n > 15) || (n < 2)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t reversed = 0;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
if ((value >> i) & 1) {
|
||||||
|
reversed |= (1 << (n - 1 - i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return reversed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void TOOL_msleep(long milliseconds) {
|
||||||
|
struct timespec time;
|
||||||
|
time.tv_sec = milliseconds / 1000;
|
||||||
|
time.tv_nsec = (milliseconds % 1000) * 1000000;
|
||||||
|
|
||||||
|
// nanosleep can be interrupted by signals, so we loop if interrupted
|
||||||
|
while (nanosleep(&time, &time) == -1) {
|
||||||
|
// If interrupted, remaining time is in ts, so we continue sleeping
|
||||||
|
// unless an actual error occurred (other than EINTR)
|
||||||
|
// For simplicity, this example assumes EINTR is the only -1 cause.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
301
src/worker/worker.c
Normal file
301
src/worker/worker.c
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include "main.h"
|
||||||
|
#include "worker.h"
|
||||||
|
|
||||||
|
#include "hdlc.h"
|
||||||
|
#include "fifo.h"
|
||||||
|
|
||||||
|
extern void WORK_formattedPrintArray(char* str, uint8_t* array, size_t size);
|
||||||
|
|
||||||
|
workerHost_s* WORK_workerInit (workerHost_s* worker,
|
||||||
|
hdlcPacket_s* packet, fifo_s* fifo, uint8_t* buffer) {
|
||||||
|
if (!worker->isInitialized) {
|
||||||
|
printf("WORKX: Starting master worker initialization\n");
|
||||||
|
worker->packet = packet;
|
||||||
|
worker->fifoWrite = fifo;
|
||||||
|
worker->fifoRead = NULL;
|
||||||
|
worker->isInitialized = true;
|
||||||
|
worker->byteBuffer = buffer;
|
||||||
|
|
||||||
|
FIFO_init(worker->fifoWrite);
|
||||||
|
|
||||||
|
printf("WORKX: Master initialization done\n");
|
||||||
|
WORK_printBlocks(worker, 3);
|
||||||
|
|
||||||
|
return worker;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ошибка в пакете, повторная инициализация
|
||||||
|
worker->isInitialized = false;
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int WORK_waitClient (fifo_s *clientFifo) {
|
||||||
|
printf("WORKX: .. Waiting for a client\n");
|
||||||
|
if (FIFO_isUsable(clientFifo) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Подготовка пакета для отправки
|
||||||
|
int WORK_preparePackage(workerHost_s *worker) {
|
||||||
|
printf("WORKX: .. Preparing package\n");
|
||||||
|
|
||||||
|
// Перемещение структуры в массив на передачу
|
||||||
|
// Вычитаем байты начала и конца сообщения
|
||||||
|
size_t structSize = HDLC_PACKET_LENGTH-2;
|
||||||
|
// size_t structSize = sizeof(hdlcPacket_s);
|
||||||
|
|
||||||
|
uint8_t tmpPtr = 0;
|
||||||
|
uint8_t *packPtr = (uint8_t*)worker->packet;
|
||||||
|
|
||||||
|
worker->byteBuffer[tmpPtr++] = HDLC_PACKET_FLAG;
|
||||||
|
for (size_t s = 0; s < structSize; s++, tmpPtr++) {
|
||||||
|
// Нашли флаг в теле сообщения
|
||||||
|
if (packPtr[s] == HDLC_PACKET_FLAG) {
|
||||||
|
worker->byteBuffer[tmpPtr] = HDLC_PACKET_ESCAPE;
|
||||||
|
tmpPtr++;
|
||||||
|
}
|
||||||
|
worker->byteBuffer[tmpPtr] = packPtr[s];
|
||||||
|
}
|
||||||
|
|
||||||
|
worker->byteBuffer[tmpPtr] = HDLC_PACKET_FLAG;
|
||||||
|
worker->byteBufferLength = tmpPtr+1;
|
||||||
|
WORK_formattedPrintArray("prepared bytes:",
|
||||||
|
worker->byteBuffer, worker->byteBufferLength);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Отправка пакета
|
||||||
|
int WORK_sendPackage(workerHost_s *worker) {
|
||||||
|
printf("WORKX: .. Sending package\n");
|
||||||
|
|
||||||
|
if (worker->byteBufferHead > worker->byteBufferLength) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FIFO_isUsable(worker->fifoWrite) == 0) {
|
||||||
|
if (worker->fifoWrite->count < FIFO_DATA_SIZE) {
|
||||||
|
FIFO_put(worker->fifoWrite, worker->byteBuffer[worker->byteBufferHead]);
|
||||||
|
if (worker->byteBufferHead < worker->byteBufferLength) {
|
||||||
|
worker->byteBufferHead++;
|
||||||
|
return 1;
|
||||||
|
} else if (worker->byteBufferHead == worker->byteBufferLength) {
|
||||||
|
// Передан весь буфер через фифо
|
||||||
|
WORK_formattedPrintArray("sent bytes:",
|
||||||
|
worker->byteBuffer, worker->byteBufferLength);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
worker->byteBufferHead = 0;
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Ожидание пакета
|
||||||
|
int WORK_waitPackage(workerHost_s *worker) {
|
||||||
|
printf("WORKX: .. Waiting for a package\n");
|
||||||
|
if (FIFO_isUsable(worker->fifoRead) == 0) {
|
||||||
|
if (worker->fifoRead->count > 0) {
|
||||||
|
// Появились данные в fifo
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WORK_receivePackage(workerHost_s *worker) {
|
||||||
|
printf("WORKX: .. Receiving package\n");
|
||||||
|
if (FIFO_isUsable(worker->fifoRead) == 0) {
|
||||||
|
if (worker->fifoRead->count > 0) {
|
||||||
|
FIFO_get(worker->fifoRead, &worker->byteBuffer[worker->byteBufferHead]);
|
||||||
|
if (worker->byteBufferHead < WORK_BYTE_BUFFER_SIZE) {
|
||||||
|
worker->byteBufferHead++;
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
worker->byteBufferHead = 0;
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (worker->byteBufferHead > 0) {
|
||||||
|
// Приняли данные. Сейчас fifo пуст, можно обрабатывать пакет
|
||||||
|
// fifo пуст, можно обрабатывать пакет
|
||||||
|
WORK_formattedPrintArray("receives bytes:",
|
||||||
|
worker->byteBuffer, worker->byteBufferLength);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int WORK_doGroupPackageBytes(hdlcPacket_s *packet, uint8_t *first, uint8_t *last, size_t bufLen) {
|
||||||
|
if (last > first) {
|
||||||
|
bufLen = last - first;
|
||||||
|
// Так как может быть меньше в теории
|
||||||
|
if (bufLen <= HDLC_PACKET_LENGTH - 2) {
|
||||||
|
// Считываем адрес
|
||||||
|
if (bufLen > 2) {
|
||||||
|
packet->address = ((uint16_t)*(first+1) << 8) | *(first);
|
||||||
|
first += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Считываем управляющее поле
|
||||||
|
if (bufLen > 4) {
|
||||||
|
packet->control = ((uint16_t)*(first+1) << 8) | *(first);
|
||||||
|
first += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Считываем контрольную сумму
|
||||||
|
if (bufLen > 6) {
|
||||||
|
printf("CRCRCR:%d,%d\n", *last, *(last-1));
|
||||||
|
packet->fcs = ((uint16_t)*(last) << 8) | *(last-1);
|
||||||
|
last -= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Считываем информационный пакет
|
||||||
|
if ((bufLen > 8) && (last > first)) {
|
||||||
|
int j = 0;
|
||||||
|
// От переполнения
|
||||||
|
size_t infoLen = last - first + 1;
|
||||||
|
if (infoLen > HDLC_INFO_LENGTH) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// Заполнение данными
|
||||||
|
for (uint8_t* i = first; i <= last; i++) {
|
||||||
|
packet->info[j] = *i;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
// Чистка хвоста
|
||||||
|
for (; j < HDLC_INFO_LENGTH; j++) {
|
||||||
|
packet->info[j] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
} // bufLen <= HDLC_PACKET_LENGTH - 2
|
||||||
|
} // (last > first)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int WORK_parsePackage(workerHost_s *worker) {
|
||||||
|
printf("WORKX: .. Parsing package\n");
|
||||||
|
|
||||||
|
// Поиск пакета в массиве
|
||||||
|
uint8_t *first = NULL, *last = NULL;
|
||||||
|
uint8_t tmpArr[WORK_BYTE_BUFFER_SIZE] = {0};
|
||||||
|
size_t bufPtrI = 0, tmpArrI = 0, bufLen = 0;
|
||||||
|
// Выносим из принятого массива только нагрузку в буфер
|
||||||
|
for (bufPtrI = 0; bufPtrI < WORK_BYTE_BUFFER_SIZE; bufPtrI++) {
|
||||||
|
// Заполняем временный буфер если нашли начало
|
||||||
|
if (first) {
|
||||||
|
tmpArr[tmpArrI] = worker->byteBuffer[bufPtrI];
|
||||||
|
tmpArrI++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Найден escape-флаг и следующие значение - флаг
|
||||||
|
if (worker->byteBuffer[bufPtrI] == HDLC_PACKET_ESCAPE) {
|
||||||
|
if (worker->byteBuffer[bufPtrI+1] == HDLC_PACKET_FLAG) {
|
||||||
|
tmpArr[tmpArrI-1] = HDLC_PACKET_FLAG;
|
||||||
|
bufPtrI++;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
// Найден флаг
|
||||||
|
if (worker->byteBuffer[bufPtrI] == HDLC_PACKET_FLAG) {
|
||||||
|
if (!first) {
|
||||||
|
first = &tmpArr[0];
|
||||||
|
} else if (!last) {
|
||||||
|
tmpArrI--;
|
||||||
|
last = &tmpArr[tmpArrI-1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
WORK_formattedPrintArray("received bytes:", first, tmpArrI);
|
||||||
|
|
||||||
|
// Разбор пакета в структуру, если найдены флаги
|
||||||
|
if (first && last) {
|
||||||
|
bufLen = last - first + 1;
|
||||||
|
int ret = WORK_doGroupPackageBytes(worker->packet, first, last, bufLen);
|
||||||
|
if (ret == 0) {
|
||||||
|
// memset(worker->byteBuffer, 0, WORK_BYTE_BUFFER_SIZE);
|
||||||
|
// memcpy(worker->byteBuffer, tmpArr, tmpArrI);
|
||||||
|
|
||||||
|
// WORK_formattedPrintArray("parsed bytes:", worker->byteBuffer, bufLen);
|
||||||
|
WORK_formattedPrintArray("parsed bytes:", tmpArr, bufLen);
|
||||||
|
WORK_printBlocks(worker, 3);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
// неправильный пакет
|
||||||
|
printf("WORKX: .. WRONG PACKET\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int WORK_checkPackage(workerHost_s *worker) {
|
||||||
|
printf("WORKX: .. Checking package\n");
|
||||||
|
int res = 0;
|
||||||
|
res = HDLC_isControlFieldValid(worker->packet->control);
|
||||||
|
// Проверка поля управления
|
||||||
|
if (res != 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
printf("WORKX: .. Package is info ...\n");
|
||||||
|
|
||||||
|
// Проверка контрольной суммы разобранного пакета
|
||||||
|
uint16_t crc = worker->packet->fcs;
|
||||||
|
worker->packet->fcs = 0;
|
||||||
|
uint16_t crcc = CRC16_compute((uint8_t*) worker->packet, sizeof(hdlcPacket_s));
|
||||||
|
if (crcc == crc) {
|
||||||
|
printf("WORKX: .. CRC OK\n");
|
||||||
|
printf("WORKX: .. Package checked\n");
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
printf("WORKX: .. WRONG CRC\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Вызов функций обработчика хоста
|
||||||
|
int WORK_execute(int (*callback)(workerHost_s*), workerHost_s *worker) {
|
||||||
|
if (callback == NULL) {
|
||||||
|
printf("WORKX: .. Wrong object\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int res = callback(worker);
|
||||||
|
|
||||||
|
if (res > 0) {
|
||||||
|
printf("WORKX: .. Progerss (%d)\n", res);
|
||||||
|
} else if (res < 0) {
|
||||||
|
printf("WORKX: .. Error (%d)\n", res);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
51
src/worker/worker.h
Normal file
51
src/worker/worker.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef WORKER_H
|
||||||
|
#define WORKER_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "hdlc_type.h"
|
||||||
|
|
||||||
|
#include "fifo.h"
|
||||||
|
|
||||||
|
// Структура устройства
|
||||||
|
typedef struct __attribute__((packed)){
|
||||||
|
hdlcPacket_s *packet;
|
||||||
|
fifo_s *fifoRead;
|
||||||
|
fifo_s *fifoWrite;
|
||||||
|
uint8_t *byteBuffer;
|
||||||
|
uint8_t byteBufferHead;
|
||||||
|
size_t byteBufferLength;
|
||||||
|
bool isInitialized;
|
||||||
|
} workerHost_s;
|
||||||
|
|
||||||
|
#define WORK_BYTE_BUFFER_SIZE 128
|
||||||
|
|
||||||
|
workerHost_s* WORK_workerInit (workerHost_s* worker,
|
||||||
|
hdlcPacket_s* packet, fifo_s* fifo, uint8_t* buffer);
|
||||||
|
|
||||||
|
int WORK_execute(int (*callback)(workerHost_s*), workerHost_s *worker);
|
||||||
|
|
||||||
|
int WORK_waitClient (fifo_s *clientFifo);
|
||||||
|
int WORK_preparePackage(workerHost_s *worker);
|
||||||
|
int WORK_sendPackage(workerHost_s *worker);
|
||||||
|
int WORK_waitPackage(workerHost_s *worker);
|
||||||
|
int WORK_receivePackage(workerHost_s *worker);
|
||||||
|
int WORK_checkPackage(workerHost_s *worker);
|
||||||
|
int WORK_parsePackage(workerHost_s *worker);
|
||||||
|
|
||||||
|
int WORK_fillBuffer8b(uint8_t *buffer, size_t size);
|
||||||
|
|
||||||
|
// tools and tests
|
||||||
|
int WORK_printBlocks(workerHost_s *worker, uint8_t mode);
|
||||||
|
int WORK_testFill(uint8_t* buffer, size_t bufferSize);
|
||||||
|
int WORK_testFifo(fifo_s *fifo);
|
||||||
|
|
||||||
|
|
||||||
|
#endif //WORKER_H
|
||||||
|
|
||||||
|
|
||||||
117
src/worker/worker_master.c
Normal file
117
src/worker/worker_master.c
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
#include "main.h"
|
||||||
|
#include "worker.h"
|
||||||
|
#include "worker_type.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static hdlcPacket_s hdlcMasterPacket = {0};
|
||||||
|
fifo_s hdlcMasterFifo;
|
||||||
|
extern fifo_s hdlcSlaveFifo;
|
||||||
|
static workerHost_s hdlcMaster = {0};
|
||||||
|
static uint8_t masterBuffer[WORK_BYTE_BUFFER_SIZE];
|
||||||
|
|
||||||
|
|
||||||
|
int WORK_master (void) {
|
||||||
|
static workerMasterHostState_e masterState = WSMASTER_first;
|
||||||
|
if (masterState >= WSMASTER_last) {
|
||||||
|
masterState = WSMASTER_first;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("WMAST: In master worker\n");
|
||||||
|
|
||||||
|
int res = 0;
|
||||||
|
switch (masterState) {
|
||||||
|
case WSMASTER_first:
|
||||||
|
printf("WSLAV: Starting master worker\n");
|
||||||
|
masterState = WSMASTER_initializing;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Инициализация хоста
|
||||||
|
case WSMASTER_initializing:
|
||||||
|
if (WORK_workerInit(&hdlcMaster,
|
||||||
|
&hdlcMasterPacket, &hdlcMasterFifo, masterBuffer) != NULL) {
|
||||||
|
masterState = WSMASTER_waitClient;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Ожидание инициализации клиента
|
||||||
|
case WSMASTER_waitClient:
|
||||||
|
res = WORK_waitClient(&hdlcSlaveFifo);
|
||||||
|
if (res == 0) {
|
||||||
|
// Дождались клиента на линии, сохраняем указатель на его фифо
|
||||||
|
hdlcMaster.fifoRead = &hdlcSlaveFifo;
|
||||||
|
masterState = WSMASTER_preparingPackage;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Подготовка пакета
|
||||||
|
case WSMASTER_preparingPackage:
|
||||||
|
hdlcMaster.packet->address = hdlcMasterAddress;
|
||||||
|
hdlcMaster.packet->control = 0b0100110011110000;
|
||||||
|
WORK_fillBuffer8b(hdlcMaster.packet->info, HDLC_INFO_LENGTH);
|
||||||
|
hdlcMaster.packet->fcs = 0;
|
||||||
|
uint16_t crc = CRC16_compute((uint8_t*) hdlcMaster.packet, sizeof(hdlcPacket_s));
|
||||||
|
hdlcMaster.packet->fcs = crc;
|
||||||
|
hdlcMaster.byteBufferHead = 0;
|
||||||
|
|
||||||
|
res = WORK_execute(WORK_preparePackage, &hdlcMaster);
|
||||||
|
if (res == 0) {
|
||||||
|
masterState = WSMASTER_sendingPackage;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Отправка пакета
|
||||||
|
case WSMASTER_sendingPackage:
|
||||||
|
res = WORK_execute(WORK_sendPackage, &hdlcMaster);
|
||||||
|
if (res == 0) {
|
||||||
|
hdlcMaster.byteBufferHead = 0;
|
||||||
|
masterState = WSMASTER_waitingPackage;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Ожидание ответа
|
||||||
|
case WSMASTER_waitingPackage:
|
||||||
|
res = WORK_execute(WORK_waitPackage, &hdlcMaster);
|
||||||
|
if (res == 0) {
|
||||||
|
masterState = WSMASTER_receivingPackage;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Получение пакета
|
||||||
|
case WSMASTER_receivingPackage:
|
||||||
|
res = WORK_execute(WORK_receivePackage, &hdlcMaster);
|
||||||
|
if (res == 0) {
|
||||||
|
masterState = WSMASTER_parsingPackage;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Парсинг пакета
|
||||||
|
case WSMASTER_parsingPackage:
|
||||||
|
res = WORK_execute(WORK_parsePackage, &hdlcMaster);
|
||||||
|
if (res == 0) {
|
||||||
|
masterState = WSMASTER_checkingPackage;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Проверка пакета
|
||||||
|
case WSMASTER_checkingPackage:
|
||||||
|
res = WORK_execute(WORK_checkPackage, &hdlcMaster);
|
||||||
|
if (res == 0) {
|
||||||
|
masterState = WSMASTER_last;
|
||||||
|
__attribute__((fallthrough));
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Цикл завершён, повторяем
|
||||||
|
case WSMASTER_last:
|
||||||
|
printf("WMAST: Job done. Starting from the beginning\n");
|
||||||
|
masterState = WSMASTER_preparingPackage;
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
92
src/worker/worker_slave.c
Normal file
92
src/worker/worker_slave.c
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#include "main.h"
|
||||||
|
#include "worker.h"
|
||||||
|
#include "worker_type.h"
|
||||||
|
|
||||||
|
static hdlcPacket_s hdlcSlavePacket = {0};
|
||||||
|
fifo_s hdlcSlaveFifo;
|
||||||
|
static workerHost_s hdlcSlave = {0};
|
||||||
|
static uint8_t slaveBuffer[WORK_BYTE_BUFFER_SIZE];
|
||||||
|
extern fifo_s hdlcMasterFifo;
|
||||||
|
|
||||||
|
|
||||||
|
int WORK_slave(void) {
|
||||||
|
static workerSlaveHostState_e slaveState = WSSLAVE_first;
|
||||||
|
if (slaveState >= WSSLAVE_last) {
|
||||||
|
slaveState = WSSLAVE_first;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("WSLAV: In slave worker\n");
|
||||||
|
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
switch (slaveState) {
|
||||||
|
case WSSLAVE_first:
|
||||||
|
printf("WSLAV: Starting slave worker\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WSSLAVE_initializing:
|
||||||
|
if (WORK_workerInit(&hdlcSlave,
|
||||||
|
&hdlcSlavePacket, &hdlcSlaveFifo, slaveBuffer) != NULL) {
|
||||||
|
res = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WSSLAVE_waitClient:
|
||||||
|
res = WORK_waitClient(&hdlcMasterFifo);
|
||||||
|
if (res == 0) {
|
||||||
|
hdlcSlave.fifoRead = &hdlcMasterFifo;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WSSLAVE_waitingPackage:
|
||||||
|
res = WORK_execute(WORK_waitPackage, &hdlcSlave);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WSSLAVE_receivingPackage:
|
||||||
|
res = WORK_execute(WORK_receivePackage, &hdlcSlave);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WSSLAVE_parsingPackage:
|
||||||
|
res = WORK_execute(WORK_parsePackage, &hdlcSlave);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WSSLAVE_checkingPackage:
|
||||||
|
res = WORK_execute(WORK_checkPackage, &hdlcSlave);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WSSLAVE_preparingPackage:
|
||||||
|
hdlcSlave.packet->address = hdlcSlaveAddress;
|
||||||
|
uint8_t tmp = hdlcSlave.packet->info[0];
|
||||||
|
hdlcSlave.packet->info[0] = hdlcSlave.packet->info[1];
|
||||||
|
hdlcSlave.packet->info[1] = tmp;
|
||||||
|
hdlcSlave.packet->fcs = 0;
|
||||||
|
uint16_t crc = CRC16_compute((uint8_t*) hdlcSlave.packet, sizeof(hdlcPacket_s));
|
||||||
|
hdlcSlave.packet->fcs = crc;
|
||||||
|
hdlcSlave.byteBufferHead = 0;
|
||||||
|
|
||||||
|
res = WORK_execute(WORK_preparePackage, &hdlcSlave);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WSSLAVE_sendingPackage:
|
||||||
|
res = WORK_execute(WORK_sendPackage, &hdlcSlave);
|
||||||
|
if (res == 0) {
|
||||||
|
hdlcSlave.byteBufferHead = 0;
|
||||||
|
slaveState = WSSLAVE_last;
|
||||||
|
__attribute__((fallthrough));
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case WSSLAVE_last:
|
||||||
|
printf("WSLAV: Job done. Starting from the beginning\n");
|
||||||
|
slaveState = WSSLAVE_waitClient;
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
} // switch (slaveState)
|
||||||
|
|
||||||
|
if (res == 0) {
|
||||||
|
slaveState++;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
118
src/worker/worker_tools.c
Normal file
118
src/worker/worker_tools.c
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
#include "worker.h"
|
||||||
|
|
||||||
|
#define ARRAY_SIZE(array) sizeof(array)/sizeof(array[0])
|
||||||
|
|
||||||
|
static inline void WORK_printArray (uint8_t* array, size_t size) {
|
||||||
|
for (size_t s = 0; s < size; s++) {
|
||||||
|
printf("%d, ", array[s]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WORK_formattedPrintArray(const char* str, uint8_t* array, size_t size) {
|
||||||
|
printf("WORKX: %s (%d bytes):", str, (int)size);
|
||||||
|
for (size_t s = 0; s < size; s++) {
|
||||||
|
printf("%d, ", array[s]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf("FILL:");for (int i = 0; i < 50; i++) {printf("%d:", worker->byteBuffer[i]);} printf("\n");
|
||||||
|
|
||||||
|
|
||||||
|
// Параметрический вывод пакета worker
|
||||||
|
int WORK_printBlocks(workerHost_s *worker, uint8_t mode) {
|
||||||
|
if (worker == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode > 0) {
|
||||||
|
printf("TOOL: Packet consists of several units:\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вывод содержимого пакета
|
||||||
|
if (mode & 1) {
|
||||||
|
printf("TOOL: .. Packet:\n");
|
||||||
|
printf("TOOL: .... Address: %d \n", worker->packet->address);
|
||||||
|
// printf("TOOL: .... Flag: %d \n", worker->packet->flag);
|
||||||
|
printf("TOOL: .... Conrol Field: %d \n", worker->packet->control);
|
||||||
|
printf("TOOL: .... Info Field: ");
|
||||||
|
WORK_printArray(worker->packet->info, ARRAY_SIZE(worker->packet->info));
|
||||||
|
printf("\n");
|
||||||
|
printf("TOOL: .... FCS: %d \n", worker->packet->fcs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вывод содержимого буфера fifo
|
||||||
|
if (mode & 3) {
|
||||||
|
size_t size = sizeof(worker->fifoWrite->data) / sizeof(worker->fifoWrite->data[0]);
|
||||||
|
|
||||||
|
printf("TOOL: .. FIFO:\n");
|
||||||
|
printf("TOOL: .... Data (%d items): ", (int)size);
|
||||||
|
for (size_t i = 0; i < size; i++) {
|
||||||
|
printf("%02X ", worker->fifoWrite->data[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
printf("TOOL: .. Pointer: %d ", worker->fifoWrite->head);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Тестовое заполнение буфера
|
||||||
|
int WORK_testFill(uint8_t* buffer, size_t bufferSize) {
|
||||||
|
bufferSize++;
|
||||||
|
static uint8_t testbuffer[50] = {
|
||||||
|
0xaa,0xbb,
|
||||||
|
HDLC_PACKET_FLAG,
|
||||||
|
0xa1, 0xa2,
|
||||||
|
0xc1, 0xc2,
|
||||||
|
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
|
||||||
|
HDLC_PACKET_ESCAPE, HDLC_PACKET_FLAG,
|
||||||
|
0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xde,
|
||||||
|
0xcc, 0xcd,
|
||||||
|
HDLC_PACKET_FLAG
|
||||||
|
};
|
||||||
|
for (int i = 0; i < 50; i++) {
|
||||||
|
buffer[i] = testbuffer[i];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Тестирование фифо
|
||||||
|
int WORK_testFifo(fifo_s *fifo) {
|
||||||
|
printf("TEST: FIFO START:\n");
|
||||||
|
|
||||||
|
FIFO_put(fifo, 4);
|
||||||
|
FIFO_put(fifo, 3);
|
||||||
|
FIFO_put(fifo, 8);
|
||||||
|
FIFO_print(fifo);
|
||||||
|
|
||||||
|
uint8_t arr[10] = {0};
|
||||||
|
for (int a = 0; a < 10; a++) {
|
||||||
|
FIFO_get(fifo, &arr[a]);
|
||||||
|
printf("%d:", arr[a]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
printf("TEST: FIFO END:\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Заполнение массива
|
||||||
|
int WORK_fillBuffer8b(uint8_t *buffer, size_t size) {
|
||||||
|
memset(buffer, 0, size);
|
||||||
|
for (size_t i = 0; i < size; i++) {
|
||||||
|
buffer[i] = i;
|
||||||
|
}
|
||||||
|
buffer[size/2] = HDLC_PACKET_FLAG;
|
||||||
|
buffer[size/3] = HDLC_PACKET_FLAG;
|
||||||
|
buffer[size/4] = HDLC_PACKET_FLAG;
|
||||||
|
buffer[size/5] = HDLC_PACKET_FLAG;
|
||||||
|
buffer[10] = HDLC_PACKET_FLAG;
|
||||||
|
buffer[12] = HDLC_PACKET_FLAG;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
42
src/worker/worker_type.h
Normal file
42
src/worker/worker_type.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef WORKER_TYPE_H
|
||||||
|
#define WORKER_TYPE_H
|
||||||
|
|
||||||
|
// Перечисление статусов машины состояния общего обработчика
|
||||||
|
// typedef enum {
|
||||||
|
// WORKE_first = 0,
|
||||||
|
// WORKE_masterWorker,
|
||||||
|
// WORKE_slaveWorker,
|
||||||
|
// WORKE_wait,
|
||||||
|
// WORKE_last
|
||||||
|
// } workerState_e;
|
||||||
|
|
||||||
|
// Перечисление статусов конкретного хоста
|
||||||
|
typedef enum {
|
||||||
|
WSMASTER_first = 0,
|
||||||
|
WSMASTER_initializing,
|
||||||
|
WSMASTER_waitClient,
|
||||||
|
WSMASTER_preparingPackage,
|
||||||
|
WSMASTER_sendingPackage,
|
||||||
|
WSMASTER_waitingPackage,
|
||||||
|
WSMASTER_receivingPackage,
|
||||||
|
WSMASTER_checkingPackage,
|
||||||
|
WSMASTER_parsingPackage,
|
||||||
|
WSMASTER_last
|
||||||
|
} workerMasterHostState_e;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WSSLAVE_first = 0,
|
||||||
|
WSSLAVE_initializing,
|
||||||
|
WSSLAVE_waitClient,
|
||||||
|
WSSLAVE_waitingPackage,
|
||||||
|
WSSLAVE_receivingPackage,
|
||||||
|
WSSLAVE_parsingPackage,
|
||||||
|
WSSLAVE_checkingPackage,
|
||||||
|
WSSLAVE_preparingPackage,
|
||||||
|
WSSLAVE_sendingPackage,
|
||||||
|
WSSLAVE_last
|
||||||
|
} workerSlaveHostState_e;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // WORKER_TYPE_H
|
||||||
Loading…
x
Reference in New Issue
Block a user