diff --git a/.vscode/settings.json b/.vscode/settings.json index 0938b59..654244f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -21,6 +21,12 @@ "stddef.h": "c", "coroutine": "c", "filo.h": "c", - "filo_type.h": "c" + "filo_type.h": "c", + "array": "c", + "string": "c", + "string_view": "c", + "ranges": "c", + "compare": "c", + "cstdint": "c" } } \ No newline at end of file diff --git a/src/main.c b/src/main.c index f163673..e66d1c6 100644 --- a/src/main.c +++ b/src/main.c @@ -45,7 +45,7 @@ int main(void) { break; case OS_wait: - TOOL_msleep(50); + TOOL_msleep(5); printf("\n\n"); break; @@ -60,7 +60,7 @@ int main(void) { bigLoopOsState++; // Для контроля - TOOL_msleep(100); + TOOL_msleep(10); } return 0; diff --git a/src/tools.c b/src/tools.c index e3d8d17..6b83f82 100644 --- a/src/tools.c +++ b/src/tools.c @@ -32,7 +32,7 @@ uint16_t CRC16_compute(uint8_t *data, size_t length) { } } } - + return crc; } diff --git a/src/worker/worker.c b/src/worker/worker.c index 051948b..69ceab3 100644 --- a/src/worker/worker.c +++ b/src/worker/worker.c @@ -85,6 +85,7 @@ int WORK_sendPackage(workerHost_s *worker) { 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:", @@ -92,12 +93,12 @@ int WORK_sendPackage(workerHost_s *worker) { return 0; } else { worker->byteBufferHead = 0; - return -2; + return -3; } } else { - return 1; + return -2; } - return -1; + return 2; } return -1; } @@ -122,6 +123,7 @@ int WORK_receivePackage(workerHost_s *worker) { 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; @@ -134,104 +136,119 @@ int WORK_receivePackage(workerHost_s *worker) { worker->byteBuffer, worker->byteBufferLength); return 0; } - return 1; + 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; - size_t bufPtrI = 0, bufLen = 0; 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 = &worker->byteBuffer[bufPtrI]; - first++; // Скипаем байт флага + first = &tmpArr[0]; } else if (!last) { - last = &worker->byteBuffer[bufPtrI]; - last--; + tmpArrI--; + last = &tmpArr[tmpArrI-1]; break; } } - // Найден escape-флаг - if (worker->byteBuffer[bufPtrI] == HDLC_PACKET_ESCAPE) { - if (worker->byteBuffer[bufPtrI+1] == HDLC_PACKET_FLAG) { - bufPtrI++; - } - } } - WORK_formattedPrintArray("received bytes:", first, bufPtrI); + WORK_formattedPrintArray("received bytes:", first, tmpArrI); - // Разбор пакета в структуру + // Разбор пакета в структуру, если найдены флаги if (first && last) { - if (last > first) { - bufLen = last - first; - // Так как может быть меньше в теории - if (bufLen <= HDLC_PACKET_LENGTH-2) { - if (bufLen > 2) { // Считываем адрес - uint16_t a = ((uint16_t)*first << 8) | *(first+1); - worker->packet->address = ((uint16_t)*(first+1) << 8) | *(first); - first += 2; - } - if (bufLen > 4) { // Считываем управляющее поле - worker->packet->control = ((uint16_t)*(first+1) << 8) | *(first); - first += 2; - } - if (bufLen > 6) { // Считываем контрольную сумму - worker->packet->fcs = ((uint16_t)*(last) << 8) | *(last-1); - last -= 2; - } - if ((bufLen > 8) && (last > first)) { // Считываем информационный пакет - int j = 0; - // От переполнения - size_t infoLen = last - first; - if (infoLen > HDLC_INFO_LENGTH) { - return -1; - } - - // Заполнение данными - for (uint8_t* i = first; i < last; i++) { - worker->packet->info[j] = *i; - j++; - } - - // Чистка хвоста - for (; j < HDLC_INFO_LENGTH; j++) { - worker->packet->info[j] = 0; - } - } - } - } // (last > first) - } // (first && last) - else { - // неправильный пакет - return -1; - } - - WORK_formattedPrintArray("parsed bytes:", worker->byteBuffer, bufPtrI); - - - // Проверка контрольной суммы разобранного пакета - uint16_t crc = worker->packet->fcs; - worker->packet->fcs = 0; - if (CRC16_compute((uint8_t*) &worker->packet, sizeof(workerHost_s)) == crc) { - printf("WORKX: .. CRC OK"); - return 0; + 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 CRC"); + // неправильный пакет + printf("WORKX: .. WRONG PACKET\n"); return -1; } - return -1; } @@ -239,7 +256,6 @@ int WORK_parsePackage(workerHost_s *worker) { int WORK_checkPackage(workerHost_s *worker) { printf("WORKX: .. Checking package\n"); int res = 0; - return 0; res = HDLC_isControlFieldValid(worker->packet->control); // Проверка поля управления if (res != 0) { @@ -247,10 +263,20 @@ int WORK_checkPackage(workerHost_s *worker) { } 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; + } - printf("WORKX: .. Package checked\n"); - return 0; + return -1; } @@ -264,8 +290,10 @@ int WORK_execute(int (*callback)(workerHost_s*), workerHost_s *worker) { int res = callback(worker); - if (res != 0) { - printf("WORKX: .. Error\n"); + if (res > 0) { + printf("WORKX: .. Progerss (%d)\n", res); + } else if (res < 0) { + printf("WORKX: .. Error (%d)\n", res); } return res; diff --git a/src/worker/worker.h b/src/worker/worker.h index f9d40ba..12725a7 100644 --- a/src/worker/worker.h +++ b/src/worker/worker.h @@ -13,7 +13,7 @@ #include "fifo.h" // Структура устройства -typedef struct { +typedef struct __attribute__((packed)){ hdlcPacket_s *packet; fifo_s *fifoRead; fifo_s *fifoWrite; diff --git a/src/worker/worker_master.c b/src/worker/worker_master.c index 6975158..48923a1 100644 --- a/src/worker/worker_master.c +++ b/src/worker/worker_master.c @@ -50,7 +50,7 @@ int WORK_master (void) { 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(workerHost_s)); + uint16_t crc = CRC16_compute((uint8_t*) hdlcMaster.packet, sizeof(hdlcPacket_s)); hdlcMaster.packet->fcs = crc; hdlcMaster.byteBufferHead = 0; @@ -64,6 +64,7 @@ int WORK_master (void) { case WSMASTER_sendingPackage: res = WORK_execute(WORK_sendPackage, &hdlcMaster); if (res == 0) { + hdlcMaster.byteBufferHead = 0; masterState = WSMASTER_waitingPackage; } break; @@ -107,9 +108,10 @@ int WORK_master (void) { case WSMASTER_last: printf("WMAST: Job done. Starting from the beginning\n"); masterState = WSMASTER_preparingPackage; + return 0; break; } - return 0; + return res; } diff --git a/src/worker/worker_slave.c b/src/worker/worker_slave.c index 0c3aef6..1cb7092 100644 --- a/src/worker/worker_slave.c +++ b/src/worker/worker_slave.c @@ -46,25 +46,31 @@ int WORK_slave(void) { res = WORK_execute(WORK_receivePackage, &hdlcSlave); break; - case WSSLAVE_checkingPackage: - res = WORK_execute(WORK_checkPackage, &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 { @@ -74,6 +80,7 @@ int WORK_slave(void) { case WSSLAVE_last: printf("WSLAV: Job done. Starting from the beginning\n"); slaveState = WSSLAVE_waitClient; + return 0; break; } // switch (slaveState) @@ -81,6 +88,5 @@ int WORK_slave(void) { if (res == 0) { slaveState++; } - - return 0; + return res; } \ No newline at end of file diff --git a/src/worker/worker_tools.c b/src/worker/worker_tools.c index bebd24d..07198b9 100644 --- a/src/worker/worker_tools.c +++ b/src/worker/worker_tools.c @@ -109,5 +109,10 @@ int WORK_fillBuffer8b(uint8_t *buffer, size_t size) { 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; } \ No newline at end of file diff --git a/src/worker/worker_type.h b/src/worker/worker_type.h index cf2f964..40c6ef3 100644 --- a/src/worker/worker_type.h +++ b/src/worker/worker_type.h @@ -31,8 +31,8 @@ typedef enum { WSSLAVE_waitClient, WSSLAVE_waitingPackage, WSSLAVE_receivingPackage, - WSSLAVE_checkingPackage, WSSLAVE_parsingPackage, + WSSLAVE_checkingPackage, WSSLAVE_preparingPackage, WSSLAVE_sendingPackage, WSSLAVE_last