commit 6d688be71dd9b1e78ff6646201ebe9e1e558c463 Author: cfif Date: Mon May 26 14:41:45 2025 +0300 Init diff --git a/Inc/ModemAlmanah.h b/Inc/ModemAlmanah.h new file mode 100644 index 0000000..5b724c8 --- /dev/null +++ b/Inc/ModemAlmanah.h @@ -0,0 +1,31 @@ +// +// Created by cfif on 27.02.23. +// + +#ifndef GONEC_GSM_MODEMALMANAH_H +#define GONEC_GSM_MODEMALMANAH_H + +#include +#include "DeviceStorageIni.h" +#include +#include "ModemGonec.h" +#include "fs_interface.h" +#include "RtcIO.h" +#include "ModemGnss.h" +#include "httpd_types.h" +#include "file_logger.h" +#include "stdbool.h" +#include "stdlib.h" +#include "string.h" +#include "fs_base_func.h" +#include "httpd_base_func.h" + +// Инициализация записи файла альманаха +bool initWriteAlmanah(tFs *fs); + +// Запись файла альманаха +bool writeAlmanah(tModemMain *env); + + + +#endif //GONEC_GSM_MODEMALMANAH_H diff --git a/Inc/ModemBufCreateHeader.h b/Inc/ModemBufCreateHeader.h new file mode 100644 index 0000000..25bff7d --- /dev/null +++ b/Inc/ModemBufCreateHeader.h @@ -0,0 +1,13 @@ +// +// Created by cfif on 23.03.2024. +// + +#ifndef GONEC_FULL_MODEMBUFCREATEHEADER_H +#define GONEC_FULL_MODEMBUFCREATEHEADER_H + +#include "ModemSendFunc.h" + +bool cuteOffset(tFs *fs, char *path, char *bufDumpFile, uint32_t lenBufDumpFile, uint32_t cuteOffsetBegin); +bool isTo(char *to, char ch); + +#endif //GONEC_FULL_MODEMBUFCREATEHEADER_H diff --git a/Inc/ModemGnss.h b/Inc/ModemGnss.h new file mode 100644 index 0000000..278547e --- /dev/null +++ b/Inc/ModemGnss.h @@ -0,0 +1,65 @@ +// +// Created by cfif on 08.02.23. +// + +#ifndef GONEC_GSM_MODEMGNSS_H +#define GONEC_GSM_MODEMGNSS_H +#include "stdint.h" +#include "stdbool.h" + +typedef struct { + + double gnss_latitude; + double gnss_longitude; + + uint32_t speed; + uint32_t curse; + + bool valid; +} tTracertNavData; + +typedef struct { + + int32_t latitude; + int32_t longitude; + + uint16_t direction; + + bool valid; +} tNavDataMsd; + + +typedef struct { + bool isOneDateTime; + bool isOneValidGnss; + + uint32_t region; + + bool isDateTimeRecv; + bool isTimeOneStartBlock; + + double gnss_latitude; + double gnss_longitude; + + double latitude; + double longitude; + + bool valid; +} tModemNavData; + +typedef struct { + int16_t minLatitude; + int16_t maxLatitude; + int16_t minLongitude; + int16_t maxLongitude; +} tRegionData; + +typedef struct { + uint8_t min; + uint8_t max; + char ewIndicator; +} tRegionDataEwIndicator; + +extern const tRegionData regionData[60]; + +#endif //GONEC_GSM_MODEMGNSS_H diff --git a/Inc/ModemLog.h b/Inc/ModemLog.h new file mode 100644 index 0000000..d6b9a88 --- /dev/null +++ b/Inc/ModemLog.h @@ -0,0 +1,65 @@ +// +// Created by cfif on 18.02.23. +// + +#ifndef GONEC_LOG_MODEMLOG_H +#define GONEC_LOG_MODEMLOG_H + +#include +#include +#include +#include "ModemGonec.h" +#include "fs_interface.h" +#include "RtcIO.h" +#include "ModemGnss.h" +#include "httpd_types.h" +#include "file_logger.h" +#include + +typedef struct { + tSerialPortIO *io; + +// tLoggerInterface *logger; +// tAtCmd modemAt; + tFs *fs; + tRtcIO *rtcIO; + + tDeviceStorageIni *store; + + osMutexId_t access; + +// struct { +// uint8_t modemRx[2048]; +// uint8_t modemTx[2048]; +// } mem; + + struct { + osThreadId_t id; + uint32_t stack[4096]; + StaticTask_t controlBlock; + osThreadAttr_t attr; + } thread; + + char filename[64]; + char buf[24]; + uint8_t bufLog[512]; + time_t timestampWriteFileLogger; + + +} tModemMainLog; + + +void ModemMainLog_Init( + tModemMainLog *env, + tDeviceStorageIni *store, + tSerialPortIO *io, + tRtcIO *rtcIO, + tFs *fs, + osMutexId_t access_log +); + +void ModemMainLog_StartThread(tModemMainLog *env); + +uint32_t getStateWriteLog2(tModemMainLog *env); + +#endif //GONEC_LOG_MODEMLOG_H diff --git a/Inc/ModemMain.h b/Inc/ModemMain.h new file mode 100644 index 0000000..3a88a89 --- /dev/null +++ b/Inc/ModemMain.h @@ -0,0 +1,397 @@ +// +// Created by cfif on 04.10.2022. +// + +#ifndef MODEMMAIN_H +#define MODEMMAIN_H + +#include +#include +#include +#include "ModemGonec.h" +#include "fs_interface.h" +#include "RtcIO.h" +#include "ModemGnss.h" +#include "httpd_types.h" +#include "file_logger.h" +#include "stdbool.h" +#include "GonetsReedSalmon.h" +#include "md5alg.h" +#include "Gpios.h" +#include "GonetsAlmanac.h" + +//#define DEBUG_MODEM 1 +//#define DEBUG_EXT_MODEM 1 + +#define maxFilesOutBox 128 + + +typedef enum { + TYPE_FILE_MESSAGE = 0, + TYPE_FILE_TRACERT = 1, + TYPE_FILE_KVITIN = 2, + TYPE_FILE_AMS_RADAR = 3, + TYPE_FILE_LORA_WAN = 4 +} tTypeFile; + +typedef enum { + BUF_NO_RECEIVE = 0, + BUF_NO_RECEIVE_KV = 1, + BUF_RECEIVE = 2 +} tBufFreeFillState; + +typedef enum { + SLOT_FREE = 0, + SLOT_READY_READ_OR_WRITE = 1, + SLOT_READY_SENDING = 2, + SLOT_INIT = 3 +} tStatusModem; + +typedef struct { + char path_mask_fileName[MAX_LEN_PATH_FS]; +} tModemStatusFile; + +typedef struct { + uint32_t sendFrom[32]; + uint32_t sendLen[32]; + uint32_t idMessage[32]; + uint32_t urgency[32]; + uint8_t type[32]; + uint8_t sos[32]; + uint8_t id[32]; + tStatusModem status[32]; +} tModemStatus; + +typedef struct { + uint32_t receive; // Смещение доставленных пакетов + uint32_t no_receive; // Смещение не доставленных пакетов +} tStructReceiveOffset; + +typedef struct { + tTypeFile typeFile; + uint32_t from; + uint32_t mnum; + char to[MAX_LEN_PATH_FS]; + uint32_t urgency; + uint32_t chSv; + char subj[MAX_LEN_PATH_FS]; + uint32_t kvs; + char fileName[MAX_LEN_PATH_FS]; + uint32_t dateDay; + uint32_t dateMon; + uint32_t offsetMsg; + uint32_t sizeFileRep; + uint32_t isSendAll; + uint32_t bytes_sending; + uint32_t bytes_no_sending; + uint32_t sos; + + uint32_t kvt_num; + uint32_t kvt_mon; + uint32_t kvt_day; + + uint32_t crc32_MSK; + uint32_t crc32_REP; +} tFileSendInfo; + + +typedef struct { + uint32_t bytes_sending; + uint32_t bytes_no_sending; + uint32_t mnum; + uint8_t kvs; + uint8_t valid; + uint8_t isSendAll; +} tFileSendInfoForJson; + + +typedef struct { + uint32_t from; + uint32_t mnumFrom; + uint32_t to; + uint32_t chSv; + uint32_t kvs; + uint32_t mnum; + uint32_t dateDay; + uint32_t dateMon; + uint32_t fileSize; + uint32_t isEnd; + uint32_t isRecvInbox; + uint32_t crc32_MSK; + uint32_t crc32_REP; +} tFileRecvInfo; + +typedef enum { + StateReqAlmaNoSendStatus = 0, + StateReqAlmaSendStatus = 1, + StateReqAlmaReady = 3 +} tStateReqAlma; + +typedef enum { + StateReqSosStatusOff = 0, + StateReqSosStatusOn = 1 +} tStateReqSos; + +typedef enum { + StateReqRegNoSendStatus = 0, + StateReqRegSendStatus = 1, +} tStateReqReg; + +typedef enum { + StateReqAlmaWebStop = 0, + StateReqAlmaWebRun = 1, + StateReqAlmaWebRunInit = 3 +} tStateReqAlmaWebRunStop; + +typedef enum { + StateReqExtNone = 0, + StateReqExtForDel = 1, + StateReqExtForCreate = 2 +} tStateReqExt; + +typedef enum { + MODEM_WORKING_NONE, + MODEM_WORKING_REG, + MODEM_WORKING_ALMA, + MODEM_WORKING_MSG +} tModemWorkingState; + + +typedef struct { + time_t EVENT_OUTBOX; + time_t EVENT_INBOX; + time_t EVENT_SENTBOX; + time_t EVENT_ALMA; + time_t EVENT_TRACERT; +} tEventWebState; + +#define LEN_TRANS_PACKET 1300 + + +typedef struct { + uint32_t numberSender; + uint32_t numberMessage; + uint32_t dataType; + uint32_t dataCreationDay; + uint32_t dataCreationMon; + bool isEnabled; + bool isCrcUpdate; +} tPacketDataForKvitin; + +typedef struct { + tFs *fs; + tDeviceStorageIni *store; + tGnss *gnss; + + tGpios *gpios; + + tLoggerInterface *logger; + tAtCmd modemAt; + + tAtCmd modemAtGsm; + + tRtcIO *rtcIo; + + tModemWorkingState modemWorkingState; + + uint32_t stepRssi; + int32_t dataRssi[10]; + + uint32_t timestamp_start_block; + uint32_t timestamp_start_block_work; + uint32_t timestamp_start_block_work_add; + tModemNavData location; + + tFileLogger *flog; + + tPacketDataForKvitin packetDataForKvitin[16]; +// tFileSendInfoForJson fileSendInfoForJson[maxFilesOutBox]; + + osMutexId_t accessHTTP; + osMutexId_t accessMODEM; + osMutexId_t accessMODEM_GSM; + + tModemStatus modemStatus; + tStatusModem modemStatusOld[32]; + + bool isModemStart; + + bool isRequestModemRecvSlots; + + bool modemSlotSendStatusReload; + bool modemSlotReceivedStatusReload; + + uint32_t testOne; + + struct { + uint8_t modemRx[2048]; + uint8_t modemTx[2048]; + } memGonec; + + struct { + uint8_t modemRx[2048]; + uint8_t modemTx[2048]; + } memGsm; + + struct { + tStateReqExt stateReqDelExtW; + tStateReqExt stateReqCreateExtW; + + tStateReqExt stateReqDelExtT; + tStateReqExt stateReqCreateExtT; + + tStateReqAlma stateReqAlma; + tStateReqReg stateReqReg; + + tStateReqSos stateReqSos; + + tStateReqAlmaWebRunStop stateReqAlmaWebRunStop; + } stateRequest; + + struct { + osThreadId_t id; + uint32_t stack[6144]; + StaticTask_t controlBlock; + osThreadAttr_t attr; + } thread; + + +// uint32_t timeStuckGetMs; + + uint32_t mnumBufScan[128]; + uint32_t mnumBufScanCount; + + int32_t rssi; + int32_t temp; + uint32_t state; + uint32_t pwramp; + char bufLog[1024]; + + osMutexId_t accessTracert; + + uint8_t bufReceivedPacket[LEN_TRANS_PACKET]; + uint32_t bufReceivedPacketLen; + + uint8_t bufSendPacketKvitin[LEN_TRANS_PACKET * 6]; + + uint32_t timeUpdateModemRegion; + + uint8_t bufSendPacket[LEN_TRANS_PACKET]; + tStructReceiveOffset structReceiveOffset[250]; + + tEventWebState eventWebState; + + tGalois256 galois256; + tGonetsReedSalmon GonetsReedSalmonParity4; + md5a_context md5ctx_t; + md5a_context md5ctx_r; + + int32_t msgId; + char gsmIMEI[16]; + char gsmSimId[16]; + + tGonetsAlmanac alms[50]; + int countAlmanac; + + bool isModemCheck; + uint32_t isEnableTracerTimeStamp; + + +} tModemMain; + +typedef struct __attribute__ ((packed)) { + uint8_t versionProtocol; // Версия протокола + uint8_t classMessage; // Класс сообщения + uint8_t typeMessage; // Тип сообщения + uint32_t typeCodingNoise: 4; // Тип помехоустойчивого кодирования + uint32_t typeTransformation: 4; // Тип преобразования сообщения + uint32_t typeCompression: 4; // Тип сжатия сообщения + uint32_t typeCrc: 4; // Тип контрольной суммы + uint32_t reserve; // Резерв + uint8_t crc8; // crc + uint32_t rc; // Р-С +} tStructRepresentationPacket; + + +typedef struct __attribute__ ((packed)) { +//#pragma scalar_storage_order big-endian +//#pragma pack(push, 1) +//typedef struct { + uint32_t versionProtocol: 4; // Версия протокола + uint32_t dataType: 4; // Тип данных + uint32_t numberSender: 24; // Номер отправителя + uint32_t dateCreateTransportPacketDay: 5; // Дата формирования транспортного пакета + uint32_t dateCreateTransportPacketMon: 4; // Дата формирования транспортного пакета + uint32_t numberMessage: 15; // Номер сообщения + uint32_t offsetPacket: 23; // Смещение пакета в сообщении + uint32_t isEnd: 1; // Признак последнего пакета +} tStructTransportPacket; +//#pragma pack(pop) +//#pragma scalar_storage_order little-endian + + +typedef struct __attribute__ ((packed)) { +//#pragma scalar_storage_order big-endian +//#pragma pack(push, 1) +//typedef struct { + uint32_t d1: 5; // Признак последнего пакета + uint32_t d2: 3; // Признак последнего пакета + uint32_t d3: 4; // Признак последнего пакета + uint32_t d4: 4; // Признак последнего пакета + uint32_t d5: 8; // Признак последнего пакета +} tGGG; +//#pragma pack(pop) +//#pragma scalar_storage_order little-endian + +typedef struct __attribute__ ((packed)) { + uint32_t offsetKvitPacket: 24; // Смещение доставленных пакетов +} tStructTransportKvitPacketData; + + +typedef struct __attribute__ ((packed)) { + uint32_t versionProtocol: 4; // Версия протокола + uint32_t dataType: 4; // Тип данных + uint32_t numberSender: 24; // Номер отправителя + uint32_t dateCreateTransportPacketDay: 5; // Дата формирования транспортного пакета + uint32_t dateCreateTransportPacketMon: 4; // Дата формирования транспортного пакета + uint32_t numberMessage: 15; // Номер сообщения +} tStructTransportKvitPacket; + +typedef struct __attribute__ ((packed)) { + uint8_t packetType; // Тип пакета + uint16_t sizeTransportPacket; // Размер транспортного служебного пакета + uint8_t numberRecipient[3]; // Номер получателя + uint8_t idArray; // Идентификатор массива + uint16_t offsetByteArray; // Смещение первого байта сегмента в массиве + uint8_t isEndSegment; // Признак последнего сегмент в массиве + uint8_t typeArray; // Тип массива +} tStructTransportPacketService; + +void ModemMain_Init( + tModemMain *env, + tGpios *gpios, + tSerialPortIO *ioGonec, + tSerialPortIO *ioGsm, + tGnss *gnss, + tDeviceStorageIni *store, + tFileLogger *flog, + tFs *fs, + tRtcIO *rtcIo, + osMutexId_t accessMODEM_GSM, + osMutexId_t accessMODEM, + osMutexId_t accessHTTP, + osMutexId_t accessTracert +); + +void ModemMain_StartThread(tModemMain *env); +bool stuckModem(tModemMain *env); + +void getDelFilesDirScanCrc(tModemMain *env); +void controlFiles(tFs *fs, char *ext, char *path); +void sendMsd(tModemMain *env); +//void sendAmsRadar(tModemMain *env, char *buf, uint32_t buf_len); +bool almac_load_from_file(tModemMain *env); + +void sendExtProtokolPack(tModemMain *env, tTypeFile typeFile, char *buf, uint32_t buf_len); + +#endif //MODEMMAIN_H diff --git a/Inc/ModemReceive.h b/Inc/ModemReceive.h new file mode 100644 index 0000000..d9c311b --- /dev/null +++ b/Inc/ModemReceive.h @@ -0,0 +1,16 @@ +// +// Created by cfif on 21.04.23. +// + +#ifndef GONEC_GSM_MODEMRECEIVE_H +#define GONEC_GSM_MODEMRECEIVE_H +#include "ModemMain.h" + +void RequestModemRecvSlots(tModemMain *env); +bool HandlerModemInPaket(tModemMain *env, uint32_t id); +bool HandlerModemPaketKvitin(tModemMain *env); +// Создание файла квитанции входящего сообщения +bool createFileKvitinInbox(tModemMain *env); +bool HandlerModemKvitPaket(tModemMain *env); + +#endif //GONEC_GSM_MODEMRECEIVE_H diff --git a/Inc/ModemReceiveFunc.h b/Inc/ModemReceiveFunc.h new file mode 100644 index 0000000..7f019c8 --- /dev/null +++ b/Inc/ModemReceiveFunc.h @@ -0,0 +1,80 @@ +// +// Created by cfif on 21.02.23. +// + +#ifndef GONEC_GSM_MODEMRECEIVEFUNC_C_H +#define GONEC_GSM_MODEMRECEIVEFUNC_C_H + +#include +#include +#include "ModemGonec.h" +#include "fs_interface.h" +#include "RtcIO.h" +#include "ModemGnss.h" +#include "httpd_types.h" +#include "file_logger.h" +#include "stdbool.h" +#include "stdlib.h" +#include "string.h" +#include "fs_base_func.h" + +typedef enum { + RECV_OK = 0, + RECV_ERROR_CRC = 1, + RECV_ERROR= 2 +} tReceiveBuildResult; + +// Получение информации о принятых файлах +bool checkNumSentBox(tFs *fs, tRtcIO *rtc, uint32_t mnum, uint32_t from); + +// Создание имени файла +void createFileNameForId(char *path, char *basePath, uint32_t id, char *ext); +// Создание имени файла +void createFileNameForId_REP_MSK_INF(char *pathRep, char *pathMsk, char *pathInf, char *basePath, uint32_t id); + +// Создание имени файла из транспортного пакета +//void +//createFileFragInbox(char *path, uint32_t dateCreateTransportPacket, uint32_t numberSender, uint32_t numberMessage, char t, char *ext); + +bool readRecvFileInfo(tFs *fs, tFileRecvInfo *fileRecvInfo, char *path_inf_fileName); + +bool writeRecvFileInfo(tFs *fs, tFileRecvInfo *fileRecvInfo, char *path_inf_fileName); + +bool readRepresentationRecvFileRep(tFs *fs, tStructRepresentationPacket *structRepresentationPacket, + char *path_dir_frag_inbox_fileName); + +// Прием пакетов - Создание файлов +bool isReceivedCreate(tFs *fs, uint32_t mnum, uint32_t to, tStructTransportPacket *packet, uint8_t *buf, uint32_t buf_len, + char *path_dir_info_fileName, char *path_dir_mask_fileName, char *path_dir_frag_inbox_fileName, bool *isCrcUpdate); + +// Прием пакетов - Добавление файлов +bool isReceivedAppend(tFs *fs, tStructTransportPacket *packet, uint8_t *buf, uint32_t buf_len, + char *path_dir_info_fileName, char *path_dir_mask_fileName, char *path_dir_frag_inbox_fileName, bool *isCrcUpdate); + +// Сообщение принято целиком +bool isReceivedAll(tFs *fs, char *path_dir_info_fileName, char *path_dir_mask_fileName, bool *isAll); + +bool Kvitin(tFs *fs, tRtcIO *rtcIo, uint32_t numberMessage, uint32_t numberSender, + char *path_dir_info_fileName, char *path_dir_mask_fileName, uint8_t *bufKvit, uint32_t *lenPacketKvit, + bool *isAll); + +// Получение информации о принятых файлах квитанций +bool checkNumSentBoxKvitin(tFs *fs, + uint8_t *bufReceivedPacket, + uint32_t bufReceivedPacketLen, + uint32_t numberSender, + uint32_t numberMessage, + uint32_t dateCreateTransportPacketMon, + uint32_t dateCreateTransportPacketDay); + +// Перенос собранного фрагментированного файла в хранилище принятых сообщений inbox +tReceiveBuildResult renameFromFrgToInBox(tFs *fs, tGonetsReedSalmon *gonetsReedSalmon, md5a_context *md5ctx, uint32_t idFile, tRtcIO *rtc, char *path_dir_info_fileName, + char *path_dir_frag_inbox_fileName, tLoggerInterface *logger); + + +tReceiveBuildResult +renameFromFrgToInBox5555(tFs *fs, tGonetsReedSalmon *gonetsReedSalmon, md5a_context *md5ctx, uint32_t idFile, tRtcIO *rtc, + char *path_dir_info_fileName, + char *path_dir_frag_inbox_fileName, tLoggerInterface *logger); + +#endif //GONEC_GSM_MODEMRECEIVEFUNC_C_H diff --git a/Inc/ModemSend.h b/Inc/ModemSend.h new file mode 100644 index 0000000..7c34e17 --- /dev/null +++ b/Inc/ModemSend.h @@ -0,0 +1,29 @@ +// +// Created by cfif on 21.04.23. +// + +#ifndef GONEC_GSM_MODEMSEND_H +#define GONEC_GSM_MODEMSEND_H +#include "ModemMain.h" + +// Количество файлов +int getCountFiles(tModemMain *env, char *path); +// Удаление самого старого файла tracert +bool delFilesOld(tModemMain *env, char *path); + +void RequestSendMessagesModemSlots(tModemMain *env); +void RunStopTaskModem(tModemMain *env); +bool getIsSlotsRouting(tModemMain *env); +// Удаление файлов трассировки из отправки +bool delRepout(tModemMain *env, tTypeFile typeFile, bool isDelFiles, bool isAllFiles); +bool ModemMain_CreateOutFiles(tModemMain *env, tTypeFile typeFile, int32_t gr); +// Котроль файлов в отправке и приеме +void controlFiles(tFs *fs, char *ext, char *path); +bool getIsSlotsSos(tModemMain *env); + +bool ToSentFiles(tModemMain *env, tFileSendInfo *fileSendInfo, + char *path_dir_rep_fileName, + char *path_dir_mask_fileName, + char *path_dir_info_fileName); + +#endif //GONEC_GSM_MODEMSEND_H diff --git a/Inc/ModemSendFunc.h b/Inc/ModemSendFunc.h new file mode 100644 index 0000000..07b5653 --- /dev/null +++ b/Inc/ModemSendFunc.h @@ -0,0 +1,81 @@ +// +// Created by cfif on 21.02.23. +// + +#ifndef GONEC_GSM_MODEMSENDFUNC_H +#define GONEC_GSM_MODEMSENDFUNC_H + +#include +#include +#include +#include "ModemGonec.h" +#include "fs_interface.h" +#include "RtcIO.h" +#include "ModemGnss.h" +#include "httpd_types.h" +#include "file_logger.h" +#include "stdbool.h" +#include "stdlib.h" +#include "string.h" +#include "fs_base_func.h" +#include "httpd_base_func.h" +#include "ModemReceiveFunc.h" +#include "GonetsReedSalmon.h" + +// Редактирование файла маски пакета транспортного уровня +bool editMaskPacketTransportKvitinCrunch(tFs *fs, uint32_t from, uint32_t lenTransPaket, char *path_mask_fileName, + tBufFreeFillState isFill); +// Поиск неотправленных блоков в файле маски +bool isFindMaskPacketTransportIsNotProc(tFs *fs, bool *isFind, char *path_mask_fileName); + +// Получение имени файла по ид +//void createFileNameFromId(char *out_fileName, uint32_t id, uint8_t len_pref, char *ext); + +// Создание имени файла из транспортного пакета +//void createFileFragInbox(char *path, uint32_t numberSender, uint32_t dateCreateTransportPacket, uint32_t numberMessage, char t, +// char *ext); + +// Создание файлов транспортного уровня +//bool createFilesTransport(tFs *fs, tRtcIO *rtcIo, char *path_rep_fileName, tFileInfo *fileInfo, uint32_t *countPacket); + +// Поиск самого срочного сообщения +uint32_t getMaxUrgencyOutbox(tFs *fs, tGonetsReedSalmon *gonetsReedSalmon, md5a_context *md5ctx, tRtcIO *rtcIo, char *path, char *out_fileName, char *path_out_fileName, tTypeFile typeFile, tDeviceStorageIni *store, uint32_t gr); + +// Создание файла уровня представления +bool createFileRepresentation(tFs *fs, tGonetsReedSalmon *gonetsReedSalmon, md5a_context *md5ctx, tRtcIO *rtcIo, char *path_out_fileName, tFileSendInfo *fileSendInfo, uint32_t gr, uint32_t cuteOffsetBegin); + + +uint32_t getCountTypeFileInRepout(tFs *fs, tTypeFile typeFile, uint32_t *idInRepout); + +uint32_t getCountTracertInRepoutCute(tFs *fs, uint32_t max); + +uint32_t getOldOut(tFs *fs, char *path, uint32_t *idInRepout, uint32_t countIdInRepout); + +// Создание пакета транспортного уровня +bool +createPacketTransport(tFs *fs, uint32_t offset, uint8_t *bufSendPacket, bool *isFrom, uint32_t *from, uint32_t *lenTransPaket, tFileSendInfo *fileSendInfo, + tRtcIO *rtcIo, char *path_rep_fileName, char *path_mask_fileName); + +// Создание пакета квитанции +bool +createPacketKvitin(tFs *fs, uint32_t offset, uint8_t *bufSendPacket, bool *isFrom, uint32_t *from, + uint32_t *lenTransPaket, + tFileSendInfo *fileSendInfo, + tRtcIO *rtcIo, char *path_rep_fileName, char *path_mask_fileName); + +// Редактирование файла маски пакета транспортного уровня +bool editMaskPacketTransport(tFs *fs, uint32_t from, uint32_t lenTransPaket, char *path_mask_fileName, tBufFreeFillState isFill); + +// Поиск неотправленных блоков в файле маски +bool isFindMaskPacketTransport(tFs *fs, bool *isFind, char *path_mask_fileName, tFileSendInfo *fileSendInfo); + +// Перенос файла в хранилище отправленных сообщений sentbox +bool renameFromOutBoxToSentBox(tFs *fs, tRtcIO *rtc, tFileSendInfo *fileSendInfo); + +bool readSendFileInfo(tFs *fs, tFileSendInfo *fileSendInfo, char *path_inf_fileName); + +bool writeSendFileInfo(tFs *fs, tFileSendInfo *fileSendInfo, char *path_inf_fileName); + +bool createBufStateFileSend(tFs *fs); + +#endif //GONEC_GSM_MODEMSENDFUNC_H diff --git a/Inc/Modem_Timer.h b/Inc/Modem_Timer.h new file mode 100644 index 0000000..bf99507 --- /dev/null +++ b/Inc/Modem_Timer.h @@ -0,0 +1,29 @@ +// +// Created by cfif on 16.05.23. +// + +#ifndef GONEC_FULL_MODEM_TIMER_H +#define GONEC_FULL_MODEM_TIMER_H +#include "ModemMain.h" + +typedef struct { + tModemMain *modemMain; + tSerialPortIO *io; + tFileLogger *flog; + tLoggerInterface *logger; + tGpios *gpios; + + struct { + osThreadId_t id; + uint32_t stack[2048]; + StaticTask_t controlBlock; + osThreadAttr_t attr; + } thread; +} tModemTimer; + +extern volatile uint32_t timeModemStuckGetMs; + +void ModemTimer_Init(tModemTimer *env, tModemMain *modemMain, tSerialPortIO *io, tFileLogger *flog, tGpios *gpios); +void ModemTimer_StartThread(tModemTimer *env); + +#endif //GONEC_FULL_MODEM_TIMER_H diff --git a/Src/ModemAlmanah.c b/Src/ModemAlmanah.c new file mode 100644 index 0000000..b9c7194 --- /dev/null +++ b/Src/ModemAlmanah.c @@ -0,0 +1,44 @@ +// +// Created by cfif on 27.02.23. +// +#include "ModemAlmanah.h" + +// Инициализация записи файла альманаха +bool initWriteAlmanah(tFs *fs) { + FRESULT fr; + + fr = f_unlink_i(fs, file_tmp_almhs); +} + +// Запись файла альманаха +bool writeAlmanah(tModemMain *env) { + bool ret; + FRESULT fr; + + fr = f_unlink_i(env->fs, file_tmp_almhs); + + FIL file; + + fr = f_open_i(env->fs, &file, (TCHAR *) file_tmp_almhs, FA_WRITE | FA_CREATE_ALWAYS); + if (fr) { + return false; + } + + UINT bytes_written; + fr = f_write_i(env->fs, &file, env->bufReceivedPacket, env->bufReceivedPacketLen, &bytes_written); + + f_close_i(env->fs, &file); + + if (osMutexAcquire(env->accessHTTP, TIME_MUTEX_HTTP_ACCESS) == osOK) { + fr = f_unlink_i(env->fs, file_cur_almhs); + fr = f_rename_i(env->fs, file_tmp_almhs, file_cur_almhs); + osMutexRelease(env->accessHTTP); + } else { + return false; + } + + almac_load_from_file(env); + + return true; +} + diff --git a/Src/ModemBufCreateHeader.c b/Src/ModemBufCreateHeader.c new file mode 100644 index 0000000..ce11a73 --- /dev/null +++ b/Src/ModemBufCreateHeader.c @@ -0,0 +1,43 @@ +// +// Created by cfif on 23.03.2024. +// +#include "ModemBufCreateHeader.h" + +bool cuteOffset(tFs *fs, char *path, char *bufDumpFile, uint32_t lenBufDumpFile, uint32_t cuteOffsetBegin) { + FIL file; + FRESULT fr; + + UINT bytes_read; + + fr = f_open_i(fs, &file, (TCHAR *) path, FA_READ); + if (fr != FR_OK) return false; + + fr = f_read_i(fs, &file, bufDumpFile, 512, &bytes_read); + if (fr != FR_OK) { + fr = f_close_i(fs, &file); + return false; + } + + fr = f_close_i(fs, &file); + + for (uint32_t i = cuteOffsetBegin; i < lenBufDumpFile - 13; ++i) { + bufDumpFile[i] = bufDumpFile[i + 13]; + } + + return true; +} + + +bool isTo(char *to, char ch) { + + for (size_t i = 0; i < strlen(to); i++) { + if ((to[i] < '0') || (to[i] > '9')) { + return true; + } + } + + if (strlen(to) > 5) + return true; + + return false; +} diff --git a/Src/ModemGnss.c b/Src/ModemGnss.c new file mode 100644 index 0000000..0d62b06 --- /dev/null +++ b/Src/ModemGnss.c @@ -0,0 +1,925 @@ +// +// Created by cfif on 08.02.23. +// +#include "ModemGnss.h" + +const tRegionData regionData[60] = { + + {0, 30, 0, 30}, + {0, 30, 30, 60}, + {0, 30, 60, 90}, + {0, 30, 90, 120}, + {0, 30, 120, 150}, + {0, 30, 150, 180}, + {0, 30, -150, -180}, + {0, 30, -120, 150}, + {0, 30, -90, -120}, + {0, 30, -60, -90}, + {0, 30, -30, -60}, + {0, 30, 0, -30}, + + {30, 60, 0, 30}, + {30, 60, 30, 60}, + {30, 60, 60, 90}, + {30, 60, 90, 120}, + {30, 60, 120, 150}, + {30, 60, 150, 180}, + {30, 60, -150, -180}, + {30, 60, -120, -150}, + {30, 60, -90, -120}, + {30, 60, -60, -90}, + {30, 60, -30, -60}, + {30, 60, 0, -30}, + + {60, 90, 0, 60}, + {60, 90, 60, 120}, + {60, 90, 120, 180}, + {60, 90, -120, -180}, + {60, 90, -60, -120}, + {60, 90, 0, -60}, + + {0, -30, 0, 30}, + {0, -30, 30, 60}, + {0, -30, 60, 90}, + {0, -30, 90, 120}, + {0, -30, 120, 150}, + {0, -30, 150, 180}, + {0, -30, -150, -180}, + {0, -30, -120, 150}, + {0, -30, -90, -120}, + {0, -30, -60, -90}, + {0, -30, -30, -60}, + {0, -30, 0, -30}, + + {-30, -60, 0, 30}, + {-30, -60, 30, 60}, + {-30, -60, 60, 90}, + {-30, -60, 90, 120}, + {-30, -60, 120, 150}, + {-30, -60, 150, 180}, + {-30, -60, -150, -180}, + {-30, -60, -120, -150}, + {-30, -60, -90, -120}, + {-30, -60, -60, -90}, + {-30, -60, -30, -60}, + {-30, -60, 0, -30}, + + {-60, -90, 0, 60}, + {-60, -90, 60, 120}, + {-60, -90, 120, 180}, + {-60, -90, -120, -180}, + {-60, -90, -60, -120}, + {-60, -90, 0, -60} + + +}; + +/* +const uint8_t bufFillOperation[2048] = {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55}; + + +const uint8_t bufFreeOperationKV[2048] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; +*/ + +const uint8_t dumpAlma[] = {239, 93, 4, 161, 4, 0, 155, 0, 0, 1, 16, 5, 166, 248, 13, 2, 23, 144, 22, 103, 12, 115, 245, + 164, 64, 226, 86, 65, 156, 140, 10, 94, 65, 129, 207, 15, 35, 132, 71, 91, 63, 211, 164, 20, + 116, 123, 9, 247, 63, 169, 77, 156, 220, 239, 80, 217, 63, 156, 50, 55, 223, 136, 94, 19, + 64, 48, 186, 188, 57, 0, 43, 187, 64, 206, 34, 142, 99, 25, 38, 19, 63, 96, 95, 232, 15, + 206, 214, 151, 190, 38, 8, 166, 250, 12, 2, 23, 69, 128, 211, 187, 30, 168, 244, 64, 208, + 156, 245, 35, 147, 10, 94, 65, 40, 41, 176, 0, 166, 12, 92, 63, 137, 93, 219, 219, 45, 9, + 247, 63, 141, 179, 233, 8, 224, 102, 219, 63, 190, 48, 153, 42, 24, 133, 20, 64, 144, 244, + 105, 21, 9, 43, 187, 64, 34, 33, 107, 151, 26, 38, 19, 63, 149, 251, 175, 105, 2, 71, 151, + 190, 38, 21, 139, 136, 13, 2, 23, 108, 63, 25, 227, 131, 203, 131, 64, 229, 212, 206, 115, + 125, 10, 94, 65, 209, 173, 215, 244, 160, 160, 100, 63, 188, 60, 157, 43, 74, 9, 247, 63, + 114, 140, 100, 143, 80, 51, 253, 63, 79, 116, 93, 248, 193, 41, 23, 64, 10, 47, 193, 169, + 235, 42, 187, 64, 156, 33, 117, 63, 26, 38, 19, 63, 190, 175, 62, 220, 221, 28, 145, 190, + 38, 22, 139, 136, 13, 2, 23, 9, 107, 99, 236, 228, 31, 166, 64, 235, 198, 187, 222, 145, 10, + 94, 65, 209, 173, 215, 244, 160, 160, 100, 63, 149, 99, 178, 184, 255, 8, 247, 63, 67, 84, + 225, 207, 240, 38, 0, 64, 248, 51, 188, 89, 131, 119, 22, 64, 186, 188, 57, 92, 7, 43, 187, + 64, 46, 32, 87, 71, 27, 38, 19, 63, 19, 9, 6, 64, 24, 254, 145, 190, 38, 23, 139, 136, 12, + 2, 23, 148, 135, 133, 26, 172, 186, 244, 64, 133, 63, 195, 81, 129, 10, 94, 65, 144, 107, + 67, 197, 56, 127, 99, 63, 18, 46, 228, 17, 220, 8, 247, 63, 155, 115, 240, 76, 104, 82, 250, + 63, 33, 90, 43, 218, 28, 183, 23, 64, 231, 29, 167, 232, 240, 42, 187, 64, 58, 31, 67, 247, + 27, 38, 19, 63, 1, 166, 200, 203, 64, 218, 143, 190, 38, 25, 55, 130, 12, 2, 23, 245, 47, + 73, 229, 224, 112, 244, 64, 251, 206, 47, 139, 131, 10, 94, 65, 193, 225, 5, 17, 169, 105, + 87, 63, 213, 175, 116, 62, 60, 11, 247, 63, 161, 16, 1, 135, 80, 165, 228, 63, 63, 168, 139, + 20, 202, 66, 227, 63, 107, 41, 32, 237, 243, 42, 187, 64, 76, 45, 106, 212, 17, 38, 19, 63, + 89, 49, 17, 158, 82, 196, 140, 190, 38, 26, 55, 131, 12, 2, 23, 63, 171, 204, 20, 26, 5, + 245, 64, 211, 106, 72, 22, 127, 10, 94, 65, 157, 42, 223, 51, 18, 161, 65, 63, 178, 157, + 239, 167, 198, 11, 247, 63, 64, 189, 25, 53, 95, 149, 24, 64, 5, 222, 201, 167, 199, 182, + 219, 63, 194, 109, 109, 225, 237, 42, 187, 64, 41, 48, 166, 196, 15, 38, 19, 63, 169, 43, + 138, 220, 109, 133, 178, 190, 38, 27, 42, 24, 12, 2, 23, 209, 144, 241, 40, 187, 251, 244, + 64, 44, 182, 73, 51, 136, 10, 94, 65, 140, 16, 30, 109, 28, 177, 102, 63, 90, 45, 176, 199, + 68, 10, 247, 63, 75, 120, 66, 175, 63, 169, 4, 64, 43, 221, 93, 103, 67, 78, 20, 64, 115, + 247, 57, 62, 250, 42, 187, 64, 25, 39, 232, 75, 22, 38, 19, 63, 157, 104, 123, 19, 119, 180, + 150, 190, 38, 30, 38, 234, 13, 2, 23, 197, 32, 176, 114, 216, 181, 165, 64, 160, 252, 221, + 199, 132, 10, 94, 65, 176, 86, 237, 154, 144, 214, 88, 63, 61, 158, 150, 31, 184, 10, 247, + 63, 193, 114, 132, 12, 228, 201, 24, 64, 160, 136, 69, 12, 59, 44, 16, 64, 11, 208, 182, + 154, 245, 42, 187, 64, 184, 41, 31, 104, 20, 38, 19, 63, 183, 13, 119, 145, 131, 29, 163, + 190, 38, 31, 38, 234, 12, 2, 23, 163, 63, 52, 115, 35, 162, 244, 64, 44, 243, 86, 221, 122, + 10, 94, 65, 3, 36, 154, 64, 17, 139, 88, 63, 118, 140, 43, 46, 142, 10, 247, 63, 133, 94, + 127, 18, 159, 75, 24, 64, 42, 230, 32, 232, 104, 133, 17, 64, 122, 255, 31, 39, 232, 42, + 187, 64, 196, 40, 11, 24, 21, 38, 19, 63, 231, 102, 54, 85, 236, 188, 164, 190, 38, 32, 38, + 234, 13, 2, 23, 18, 133, 150, 117, 255, 248, 116, 64, 57, 236, 190, 189, 114, 10, 94, 65, + 145, 42, 138, 87, 89, 219, 84, 63, 136, 161, 213, 201, 25, 10, 247, 63, 56, 19, 211, 133, + 88, 253, 209, 63, 200, 153, 38, 108, 63, 217, 16, 64, 65, 245, 15, 34, 221, 42, 187, 64, 36, + 38, 212, 251, 22, 38, 19, 63, 151, 179, 206, 12, 141, 18, 154, 190, 38, 33, 5, 125, 12, 2, + 23, 53, 39, 47, 178, 231, 107, 244, 64, 65, 14, 74, 86, 136, 10, 94, 65, 70, 234, 61, 149, + 211, 158, 98, 63, 9, 51, 109, 255, 202, 10, 247, 63, 56, 19, 211, 133, 88, 253, 221, 63, + 221, 233, 206, 19, 207, 249, 20, 64, 189, 114, 189, 109, 250, 42, 187, 64, 245, 41, 36, 60, + 20, 38, 19, 63, 90, 47, 197, 53, 146, 168, 152, 190, 38, 34, 5, 126, 13, 2, 23, 59, 137, 8, + 255, 226, 231, 118, 64, 44, 240, 21, 78, 146, 10, 94, 65, 160, 79, 228, 73, 210, 53, 99, 63, + 141, 12, 114, 23, 97, 10, 247, 63, 115, 45, 90, 128, 182, 213, 227, 63, 88, 144, 102, 44, + 154, 14, 20, 64, 88, 56, 73, 243, 7, 43, 187, 64, 208, 39, 247, 199, 21, 38, 19, 63, 28, 56, + 241, 185, 152, 95, 150, 190, 38, 35, 5, 126, 13, 2, 23, 151, 170, 180, 197, 69, 80, 154, 64, + 165, 47, 132, 161, 138, 10, 94, 65, 244, 106, 128, 210, 80, 163, 96, 63, 158, 9, 77, 18, 75, + 10, 247, 63, 226, 91, 88, 55, 222, 157, 228, 63, 150, 207, 242, 60, 184, 171, 19, 64, 56, + 130, 84, 138, 253, 42, 187, 64, 86, 39, 237, 31, 22, 38, 19, 63, 174, 223, 168, 181, 117, + 106, 148, 190, 38}; + + + +uint32_t getAlmaSize() { + return sizeof(dumpAlma); +} + +const uint8_t dump3[] = { + 0xFB, 0xB5, 0x03, 0x70, 0x17, 0x00, 0x01, 0x70, 0x17, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0xF0, 0x00, 0x9E, + + 0xC1, 0x02, 0x18, 0x00, 0x6B, 0xD0, 0xD7, 0x00, 0x00, 0x80, + 0x01, 0x01, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xB4, + 0x0D, 0x4B, 0x22, 0xF3, 0xD0, 0x94, 0xD0, 0xBB, + 0xD1, 0x8F, 0x20, 0xE2, 0x84, 0x96, 0x36, 0x30, 0x30, 0x30, 0x2E, 0x74, 0x78, 0x74, 0x00, 0x00, + 0x33, 0x3A, 0x32, 0x31, 0x3A, 0x32, 0x32, 0x20, 0xD0, + 0x9F, 0xD1, 0x80, 0xD0, 0xBE, 0xD0, 0xB2, 0xD0, 0xB5, 0xD1, 0x80, 0xD0, 0xBA, 0xD0, 0xB0, 0x20, + 0xD0, 0xB4, 0xD0, 0xB8, 0xD1, 0x81, 0xD0, 0xBA, 0xD0, + 0xB0, 0x0D, 0x0A, 0xD0, 0x94, 0xD0, 0xB8, 0xD1, 0x80, 0xD0, 0xB5, 0xD0, 0xBA, 0xD1, 0x82, 0xD0, + 0xBE, 0xD1, 0x80, 0xD0, 0xB8, 0xD0, 0xB9, 0x20, 0x4F, + 0x92, 0x04, 0x6D, 0x87, 0x5A, 0x2A, 0x18, 0xAC, 0x0C, 0x71, 0x8B, 0xAC, 0x0E, 0xFA, 0x95, 0x31, + 0x32, 0x38, 0x0D, 0x0A, 0xD0, 0xA4, 0xD0, 0xB0, 0xD0, + 0xB9, 0xD0, 0xBB, 0xD0, 0xBE, 0xD0, 0xB2, 0x20, 0x32, 0x31, 0x30, 0x35, 0x0D, 0x0A, 0xD0, 0x9D, + 0xD1, 0x83, 0xD0, 0xBB, 0xD0, 0xB5, 0xD0, 0xB2, 0xD1, + 0x8B, 0xD1, 0x85, 0x20, 0x30, 0x0D, 0x0A, 0xD0, 0x9E, 0xD1, 0x88, 0xD0, 0xB8, 0xD0, 0xB1, 0xD0, + 0xBE, 0xD0, 0xBA, 0x20, 0x30, 0x0D, 0x0A, 0x50, 0x6F, + 0x77, 0x65, 0x72, 0x20, 0x6F, 0x6E, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x0D, 0x0A, 0x38, 0x37, + 0x41, 0x46, 0x20, 0x37, 0x37, 0x34, 0x37, 0x20, 0x33, + 0x39, 0x41, 0x46, 0x20, 0x36, 0x44, 0x41, 0x31, 0x20, 0x32, 0x43, 0x41, 0x46, 0x20, 0x41, 0x39, + 0x44, 0x36, 0x20, 0x38, 0x39, 0x30, 0x30, 0x20, 0x33, + 0x35, 0x45, 0x35, 0x20, 0x44, 0x35, 0x44, 0x45, 0x20, 0x43, 0xFC, 0x10, 0x4B, 0xEC, 0x78, 0xFA, + 0x07, 0x23, 0xCB, 0xD9, 0x0B, 0x6B, 0x06, 0x1E, 0xAF, + 0xE0, 0x31, 0x30, 0x38, 0x20, 0x41, 0x31, 0x39, 0x41, 0x20, 0x46, 0x39, 0x41, 0x33, 0x20, 0x30, + 0x36, 0x33, 0x30, 0x20, 0x33, 0x36, 0x30, 0x34, 0x20, + 0x30, 0x39, 0x32, 0x45, 0x20, 0x33, 0x46, 0x41, 0x36, 0x20, 0x0D, 0x0A, 0xD0, 0xA4, 0xD0, 0xB0, + 0xD0, 0xB9, 0xD0, 0xBB, 0x20, 0xD0, 0xBA, 0xD0, 0xBE, + 0xD0, 0xBD, 0xD1, 0x84, 0xD0, 0xB8, 0xD0, 0xB3, 0xD1, 0x83, 0xD1, 0x80, 0xD0, 0xB0, 0xD1, 0x86, + 0xD0, 0xB8, 0xD0, 0xB8, 0x20, 0xD0, 0xB7, 0xD0, 0xB0, + 0xD0, 0xB3, 0xD1, 0x80, 0xD1, 0x83, 0xD0, 0xB6, 0xD0, 0xB5, 0xD0, 0xBD, 0x2E, 0x0D, 0x0A, 0xD0, + 0x9F, 0xD0, 0xB0, 0xD0, 0xBC, 0xD1, 0x8F, 0xD1, 0x82, + 0xD1, 0x8C, 0x20, 0xD1, 0x84, 0xD0, 0xBB, 0xD1, 0x8D, 0xD1, 0x88, 0x20, 0x34, 0x30, 0x39, 0x36, + 0xD0, 0xBA, 0xD0, 0x91, 0x0D, 0xA5, 0xBC, 0x09, 0x15, + 0x9A, 0x4A, 0x74, 0x5E, 0x92, 0x31, 0x69, 0x30, 0x20, 0x93, 0xF4, 0xE0, 0x0A, 0xD0, 0x90, 0xD0, + 0xA2, 0x3A, 0x20, 0x36, 0x31, 0x34, 0x31, 0x20, 0x20, + 0x20, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x20, 0x4E, 0x6F, 0x76, 0x20, 0x33, 0x30, 0x20, 0x32, 0x30, + 0x31, 0x37, 0x20, 0x31, 0x38, 0x3A, 0x31, 0x38, 0x3A, + 0x30, 0x31, 0x0D, 0x0A, 0x76, 0x50, 0x3A, 0x20, 0x30, 0x6D, 0x56, 0x0D, 0x0A, 0x31, 0x33, 0x3A, + 0x32, 0x31, 0x3A, 0x32, 0x32, 0x20, 0x42, 0x41, 0x54, + 0x2E, 0xD0, 0x9D, 0xD0, 0xB5, 0xD1, 0x82, 0x20, 0xD1, 0x80, 0xD0, 0xB5, 0xD0, 0xB6, 0xD0, 0xB8, + 0xD0, 0xBC, 0xD0, 0xB0, 0x20, 0xD0, 0xB1, 0xD0, 0xB0, + 0xD1, 0x82, 0xD0, 0xB0, 0xD1, 0x80, 0xD0, 0xB5, 0xD0, 0xB8, 0x2E, 0x0D, 0x0A, 0xD0, 0xA2, 0xD0, + 0xB5, 0xD1, 0x81, 0xD1, 0x82, 0x20, 0xD0, 0xBF, 0xD1, + 0x80, 0xD0, 0xB8, 0xD0, 0xB5, 0xD0, 0xBC, 0xF5, 0x9A, 0xD0, 0xCC, 0x55, 0xF5, 0x3D, 0x77, 0x5D, + 0x19, 0xF0, 0x19, 0x64, 0xF7, 0x4A, 0x69, 0xD0, 0xBD, + 0xD0, 0xB8, 0xD0, 0xBA, 0xD0, 0xB0, 0x0D, 0x0A, 0xD0, 0xA1, 0xD1, 0x82, 0xD0, 0xB0, 0xD1, 0x80, + 0xD1, 0x82, 0x20, 0xD0, 0xBF, 0xD1, 0x80, 0xD0, 0xB8, + 0xD0, 0xB5, 0xD0, 0xBC, 0xD0, 0xBD, 0xD0, 0xB8, 0xD0, 0xBA, 0xD0, 0xB0, 0x0D, 0x0A, 0x31, 0x33, + 0x3A, 0x32, 0x31, 0x3A, 0x32, 0x36, 0x20, 0x52, 0x53, + 0x53, 0x49, 0x3A, 0x20, 0x2D, 0x31, 0x30, 0x31, 0x0D, 0x0A, 0xD0, 0x9E, 0xD0, 0xBF, 0xD1, 0x80, + 0xD0, 0xB5, 0xD0, 0xB4, 0xD0, 0xB5, 0xD0, 0xBB, 0xD0, + 0xB5, 0xD0, 0xBD, 0x20, 0xD0, 0xB3, 0xD0, 0xB5, 0xD0, 0xBE, 0xD1, 0x80, 0xD0, 0xB5, 0xD0, 0xB3, + 0xD0, 0xB8, 0xD0, 0xBE, 0xD0, 0xBD, 0x20, 0x31, 0x34, + 0x0D, 0x0A, 0x31, 0x34, 0x3A, 0x34, 0x37, 0x3A, 0x30, 0x39, 0x20, 0x4D, 0xD0, 0xA1, 0x31, 0xD0, + 0xBE, 0xD1, 0x3D, 0xDF, 0x32, 0x44, 0xE5, 0xAC, 0x88, + 0x79, 0x05, 0x71, 0x1B, 0xBF, 0x34, 0x0F, 0x20, 0x6F, 0x81, 0xD0, 0xBD, 0x20, 0xD0, 0x9A, 0xD0, + 0x90, 0x3D, 0x33, 0x30, 0x20, 0xD0, 0xB4, 0xD0, 0xBE, + 0x20, 0xD0, 0x9A, 0xD0, 0x90, 0x3D, 0x31, 0x37, 0x31, 0x38, 0xD0, 0xBA, 0xD0, 0xBC, 0x20, 0x74, + 0x3A, 0x31, 0x39, 0x2E, 0x36, 0x32, 0x35, 0x0D, 0x0A, + 0x31, 0x34, 0x3A, 0x34, 0x37, 0x3A, 0x30, 0x39, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x72, 0x47, 0x53, + 0x4D, 0x3A, 0x20, 0x30, 0x20, 0x72, 0x65, 0x73, 0x3A, + 0x20, 0x30, 0x0D, 0x0A, 0x31, 0x34, 0x3A, 0x34, 0x37, 0x3A, 0x30, 0x39, 0x20, 0xD0, 0x95, 0xD1, + 0x81, 0xD1, 0x82, 0xD1, 0x8C, 0x20, 0xD0, 0xBA, 0xD0, + 0xBE, 0xD0, 0xBE, 0xD1, 0x80, 0xD0, 0xB4, 0xD0, 0xB8, 0xD0, 0xBD, 0xD0, 0xB0, 0xD1, 0x82, 0xD1, + 0x8B, 0x20, 0xD0, 0xBD, 0xD0, 0xB0, 0x20, 0xD0, 0xBE, + 0xD1, 0x82, 0xD0, 0xBF, 0xC0, 0x83, 0x38, 0x42, 0x64, 0xF6, 0x23, 0x1C, 0x02, 0xEA, 0x8E, 0xE7, + 0x69, 0x55, 0x10, 0x98, 0xD1, 0x80, 0xD0, 0xB0, 0xD0, + 0xB2, 0xD0, 0xBA, 0xD1, 0x83, 0x0D, 0x0A, 0x44, 0x6F, 0x70, 0x70, 0x6C, 0x65, 0x72, 0x3A, 0x20, + 0x31, 0x36, 0x32, 0x34, 0x20, 0x48, 0x7A, 0x2E, 0x20, + 0x4E, 0x6F, 0x69, 0x73, 0x65, 0x3A, 0x20, 0x36, 0x32, 0x28, 0x31, 0x33, 0x29, 0x2C, 0x32, 0x30, + 0x33, 0x28, 0x39, 0x29, 0x2C, 0x31, 0x34, 0x33, 0x28, + 0x31, 0x31, 0x29, 0x2C, 0x31, 0x37, 0x33, 0x28, 0x39, 0x29, 0x0D, 0x0A, 0x31, 0x34, 0x3A, 0x34, + 0x37, 0x3A, 0x30, 0x39, 0x20, 0xD0, 0x97, 0xD0, 0xB0, + 0xD0, 0xBF, 0xD1, 0x80, 0xD0, 0xBE, 0xD1, 0x81, 0x20, 0xD0, 0xBD, 0xD0, 0xB0, 0x20, 0xD0, 0xB7, + 0xD0, 0xB0, 0xD0, 0xBF, 0xD0, 0xB8, 0xD1, 0x81, 0xD1, + 0x8C, 0x20, 0x46, 0xD0, 0xBF, 0xD0, 0xBA, 0x3D, 0x32, 0x31, 0x37, 0x20, 0xD0, 0xA1, 0xD0, 0x9B, + 0xA2, 0xA6, 0x96, 0x6B, 0x72, 0x48, 0x96, 0xF9, 0xED, + 0x47, 0x37, 0x16, 0x3F, 0x8B, 0xC2, 0x98, 0x3D, 0x36, 0x36, 0x20, 0xD0, 0xA0, 0xD0, 0x97, 0x3D, + 0x35, 0x35, 0x39, 0x0D, 0x0A, 0x31, 0x34, 0x3A, 0x34, + 0x37, 0x3A, 0x31, 0x32, 0x20, 0xD0, 0x92, 0xD1, 0x8B, 0xD0, 0xB4, 0xD0, 0xB0, 0xD1, 0x87, 0xD0, + 0xB0, 0x20, 0xD0, 0xBF, 0xD0, 0xBE, 0xD1, 0x81, 0xD1, + 0x8B, 0xD0, 0xBB, 0xD0, 0xBA, 0xD0, 0xB8, 0x0D, 0x0A, 0x31, 0x34, 0x3A, 0x34, 0x37, 0x3A, 0x31, + 0x32, 0x20, 0xD0, 0x9A, 0xD0, 0x91, 0xD0, 0x9E, 0xD0, + 0x9A, 0x20, 0xD1, 0x81, 0xD0, 0xB8, 0xD0, 0xBD, 0xD1, 0x85, 0xD1, 0x80, 0xD0, 0xBE, 0xD0, 0xBF, + 0xD0, 0xBE, 0xD1, 0x81, 0xD1, 0x8B, 0xD0, 0xBB, 0xD0, + 0xBA, 0xD0, 0xB0, 0x20, 0xD0, 0xA1, 0xD0, 0x98, 0x3D, 0x36, 0x39, 0x43, 0x81, 0xA2, 0xBB, 0xA8, + 0xF9, 0x12, 0xAF, 0x65, 0x1C, 0x8C, 0x88, 0x33, 0x6E, + 0x6A, 0x52, 0x86, 0xFC, 0xA3, 0x6C, 0xC2, 0x8D, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +}; + + +const uint8_t dump2[] = {0xFB, 0xDA, 0x00, 0x70, 0x17, 0x00, 0x01, 0x70, 0x17, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xE7, + 0x00, 0xB9, 0xC1, 0x02, 0x18, 0x00, 0x6E, 0xD4, 0xD7, + 0x00, 0x00, 0x80, 0x01, 0x01, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x84, 0x3D, 0x32, + 0x9D, 0xD0, 0x92, 0xD1, 0x80, 0xD0, 0xB5, 0xD0, 0xBC, + 0xD1, 0x8F, 0x20, 0x31, 0x34, 0x2D, 0x30, 0x33, 0x2D, 0x32, 0x33, 0x20, 0x31, 0x31, 0x3A, 0x33, + 0x38, 0x3A, 0x34, 0x35, 0x3C, 0x64, 0x69, 0x76, 0x3E, + 0x26, 0x6E, 0x62, 0x73, 0x70, 0x3B, 0xD0, 0x9E, 0xD1, 0x82, 0xD0, 0xBF, 0xD1, 0x80, 0xD0, 0xB0, + 0xD0, 0xB2, 0xD0, 0xBA, 0xD0, 0xB0, 0x20, 0xD0, 0xA2, + 0xD0, 0xB5, 0xD0, 0xBA, 0xD1, 0x81, 0xD1, 0x82, 0xD0, 0xBE, 0xD0, 0xB2, 0xD0, 0xBE, 0xD0, 0xB3, + 0xD0, 0xBE, 0x20, 0xD1, 0x81, 0xD0, 0xBE, 0xD0, 0xBE, + 0xD0, 0xB1, 0xD1, 0x89, 0xD0, 0xB5, 0xD0, 0xBD, 0xD0, 0xB8, 0xD1, 0x8F, 0x20, 0xD0, 0xBE, 0xD1, + 0x82, 0x20, 0xD0, 0x90, 0xD0, 0xA2, 0x20, 0xE2, 0x84, + 0x96, 0x36, 0x31, 0x34, 0x36, 0x20, 0xD0, 0xBD, 0xD0, 0xB0, 0x20, 0xD0, 0x90, 0xD0, 0xA2, 0x20, + 0xE2, 0x84, 0x96, 0x36, 0x30, 0x30, 0x30, 0x20, 0xD0, + 0xB2, 0x20, 0xD0, 0xBF, 0xD1, 0x80, 0xD1, 0x8F, 0xD0, 0xBC, 0xD0, 0xBE, 0xD0, 0xB9, 0x20, 0xD0, + 0xB0, 0xD0, 0xB4, 0xD1, 0x80, 0xD0, 0xB5, 0xD1, 0x81, + 0xD0, 0xB0, 0xD1, 0x86, 0xD0, 0xB8, 0xD0, 0xB8, 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x31, 0xC4, + 0x21, 0x49, 0x1A, 0x73, 0x81, 0x56, 0xE0, 0x2C, 0x7B, + 0xED, 0xA7, 0x21, 0x24, 0x23, 0x75, 0x1F, 0xC8, 0x46, 0xE0, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +const uint8_t dump[] = {0x1A, 0x01, 0x37, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x8C, 0xCE, 0x4E, 0x1D, + 0x0D, 0xF5, 0xE1, 0xCB, 0xEA, 0x3C, 0x82, 0xFF, 0xA1, + 0x4D, 0x8B, 0x8E, 0xF4, 0xFB, 0xB5, 0x03, 0x70, 0x17, 0x00, 0x01, 0x70, 0x17, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0xF0, 0x00, 0x9E, 0xC1, 0x02, 0x18, + 0x00, 0x6B, 0xD0, 0xD7, 0x00, 0x00, 0x80, 0x01, 0x01, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0xB4, 0x0D, 0x4B, 0x22, 0xF3, 0xD0, 0x94, 0xD0, 0xBB, + 0xD1, 0x8F, 0x20, 0xE2, 0x84, 0x96, 0x36, 0x30, 0x30, 0x30, 0x2E, 0x74, 0x78, 0x74, 0x00, 0x00, + 0x33, 0x3A, 0x32, 0x31, 0x3A, 0x32, 0x32, 0x20, 0xD0, + 0x9F, 0xD1, 0x80, 0xD0, 0xBE, 0xD0, 0xB2, 0xD0, 0xB5, 0xD1, 0x80, 0xD0, 0xBA, 0xD0, 0xB0, 0x20, + 0xD0, 0xB4, 0xD0, 0xB8, 0xD1, 0x81, 0xD0, 0xBA, 0xD0, + 0xB0, 0x0D, 0x0A, 0xD0, 0x94, 0xD0, 0xB8, 0xD1, 0x80, 0xD0, 0xB5, 0xD0, 0xBA, 0xD1, 0x82, 0xD0, + 0xBE, 0xD1, 0x80, 0xD0, 0xB8, 0xD0, 0xB9, 0x20, 0x4F, + 0x92, 0x04, 0x6D, 0x87, 0x5A, 0x2A, 0x18, 0xAC, 0x0C, 0x71, 0x8B, 0xAC, 0x0E, 0xFA, 0x95, 0x31, + 0x32, 0x38, 0x0D, 0x0A, 0xD0, 0xA4, 0xD0, 0xB0, 0xD0, + 0xB9, 0xD0, 0xBB, 0xD0, 0xBE, 0xD0, 0xB2, 0x20, 0x32, 0x31, 0x30, 0x35, 0x0D, 0x0A, 0xD0, 0x9D, + 0xD1, 0x83, 0xD0, 0xBB, 0xD0, 0xB5, 0xD0, 0xB2, 0xD1, + 0x8B, 0xD1, 0x85, 0x20, 0x30, 0x0D, 0x0A, 0xD0, 0x9E, 0xD1, 0x88, 0xD0, 0xB8, 0xD0, 0xB1, 0xD0, + 0xBE, 0xD0, 0xBA, 0x20, 0x30, 0x0D, 0x0A, 0x50, 0x6F, + 0x77, 0x65, 0x72, 0x20, 0x6F, 0x6E, 0x20, 0x72, 0x65, 0x73, 0x65, 0x74, 0x0D, 0x0A, 0x38, 0x37, + 0x41, 0x46, 0x20, 0x37, 0x37, 0x34, 0x37, 0x20, 0x33, + 0x39, 0x41, 0x46, 0x20, 0x36, 0x44, 0x41, 0x31, 0x20, 0x32, 0x43, 0x41, 0x46, 0x20, 0x41, 0x39, + 0x44, 0x36, 0x20, 0x38, 0x39, 0x30, 0x30, 0x20, 0x33, + 0x35, 0x45, 0x35, 0x20, 0x44, 0x35, 0x44, 0x45, 0x20, 0x43, 0xFC, 0x10, 0x4B, 0xEC, 0x78, 0xFA, + 0x07, 0x23, 0xCB, 0xD9, 0x0B, 0x6B, 0x06, 0x1E, 0xAF, + 0xE0, 0x31, 0x30, 0x38, 0x20, 0x41, 0x31, 0x39, 0x41, 0x20, 0x46, 0x39, 0x41, 0x33, 0x20, 0x30, + 0x36, 0x33, 0x30, 0x20, 0x33, 0x36, 0x30, 0x34, 0x20, + 0x30, 0x39, 0x32, 0x45, 0x20, 0x33, 0x46, 0x41, 0x36, 0x20, 0x0D, 0x0A, 0xD0, 0xA4, 0xD0, 0xB0, + 0xD0, 0xB9, 0xD0, 0xBB, 0x20, 0xD0, 0xBA, 0xD0, 0xBE, + 0xD0, 0xBD, 0xD1, 0x84, 0xD0, 0xB8, 0xD0, 0xB3, 0xD1, 0x83, 0xD1, 0x80, 0xD0, 0xB0, 0xD1, 0x86, + 0xD0, 0xB8, 0xD0, 0xB8, 0x20, 0xD0, 0xB7, 0xD0, 0xB0, + 0xD0, 0xB3, 0xD1, 0x80, 0xD1, 0x83, 0xD0, 0xB6, 0xD0, 0xB5, 0xD0, 0xBD, 0x2E, 0x0D, 0x0A, 0xD0, + 0x9F, 0xD0, 0xB0, 0xD0, 0xBC, 0xD1, 0x8F, 0xD1, 0x82, + 0xD1, 0x8C, 0x20, 0xD1, 0x84, 0xD0, 0xBB, 0xD1, 0x8D, 0xD1, 0x88, 0x20, 0x34, 0x30, 0x39, 0x36, + 0xD0, 0xBA, 0xD0, 0x91, 0x0D, 0xA5, 0xBC, 0x09, 0x15, + 0x9A, 0x4A, 0x74, 0x5E, 0x92, 0x31, 0x69, 0x30, 0x20, 0x93, 0xF4, 0xE0, 0x0A, 0xD0, 0x90, 0xD0, + 0xA2, 0x3A, 0x20, 0x36, 0x31, 0x34, 0x31, 0x20, 0x20, + 0x20, 0x76, 0x65, 0x72, 0x3A, 0x20, 0x20, 0x4E, 0x6F, 0x76, 0x20, 0x33, 0x30, 0x20, 0x32, 0x30, + 0x31, 0x37, 0x20, 0x31, 0x38, 0x3A, 0x31, 0x38, 0x3A, + 0x30, 0x31, 0x0D, 0x0A, 0x76, 0x50, 0x3A, 0x20, 0x30, 0x6D, 0x56, 0x0D, 0x0A, 0x31, 0x33, 0x3A, + 0x32, 0x31, 0x3A, 0x32, 0x32, 0x20, 0x42, 0x41, 0x54, + 0x2E, 0xD0, 0x9D, 0xD0, 0xB5, 0xD1, 0x82, 0x20, 0xD1, 0x80, 0xD0, 0xB5, 0xD0, 0xB6, 0xD0, 0xB8, + 0xD0, 0xBC, 0xD0, 0xB0, 0x20, 0xD0, 0xB1, 0xD0, 0xB0, + 0xD1, 0x82, 0xD0, 0xB0, 0xD1, 0x80, 0xD0, 0xB5, 0xD0, 0xB8, 0x2E, 0x0D, 0x0A, 0xD0, 0xA2, 0xD0, + 0xB5, 0xD1, 0x81, 0xD1, 0x82, 0x20, 0xD0, 0xBF, 0xD1, + 0x80, 0xD0, 0xB8, 0xD0, 0xB5, 0xD0, 0xBC, 0xF5, 0x9A, 0xD0, 0xCC, 0x55, 0xF5, 0x3D, 0x77, 0x5D, + 0x19, 0xF0, 0x19, 0x64, 0xF7, 0x4A, 0x69, 0xD0, 0xBD, + 0xD0, 0xB8, 0xD0, 0xBA, 0xD0, 0xB0, 0x0D, 0x0A, 0xD0, 0xA1, 0xD1, 0x82, 0xD0, 0xB0, 0xD1, 0x80, + 0xD1, 0x82, 0x20, 0xD0, 0xBF, 0xD1, 0x80, 0xD0, 0xB8, + 0xD0, 0xB5, 0xD0, 0xBC, 0xD0, 0xBD, 0xD0, 0xB8, 0xD0, 0xBA, 0xD0, 0xB0, 0x0D, 0x0A, 0x31, 0x33, + 0x3A, 0x32, 0x31, 0x3A, 0x32, 0x36, 0x20, 0x52, 0x53, + 0x53, 0x49, 0x3A, 0x20, 0x2D, 0x31, 0x30, 0x31, 0x0D, 0x0A, 0xD0, 0x9E, 0xD0, 0xBF, 0xD1, 0x80, + 0xD0, 0xB5, 0xD0, 0xB4, 0xD0, 0xB5, 0xD0, 0xBB, 0xD0, + 0xB5, 0xD0, 0xBD, 0x20, 0xD0, 0xB3, 0xD0, 0xB5, 0xD0, 0xBE, 0xD1, 0x80, 0xD0, 0xB5, 0xD0, 0xB3, + 0xD0, 0xB8, 0xD0, 0xBE, 0xD0, 0xBD, 0x20, 0x31, 0x34, + 0x0D, 0x0A, 0x31, 0x34, 0x3A, 0x34, 0x37, 0x3A, 0x30, 0x39, 0x20, 0x4D, 0xD0, 0xA1, 0x31, 0xD0, + 0xBE, 0xD1, 0x3D, 0xDF, 0x32, 0x44, 0xE5, 0xAC, 0x88, + 0x79, 0x05, 0x71, 0x1B, 0xBF, 0x34, 0x0F, 0x20, 0x6F, 0x81, 0xD0, 0xBD, 0x20, 0xD0, 0x9A, 0xD0, + 0x90, 0x3D, 0x33, 0x30, 0x20, 0xD0, 0xB4, 0xD0, 0xBE, + 0x20, 0xD0, 0x9A, 0xD0, 0x90, 0x3D, 0x31, 0x37, 0x31, 0x38, 0xD0, 0xBA, 0xD0, 0xBC, 0x20, 0x74, + 0x3A, 0x31, 0x39, 0x2E, 0x36, 0x32, 0x35, 0x0D, 0x0A, + 0x31, 0x34, 0x3A, 0x34, 0x37, 0x3A, 0x30, 0x39, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x72, 0x47, 0x53, + 0x4D, 0x3A, 0x20, 0x30, 0x20, 0x72, 0x65, 0x73, 0x3A, + 0x20, 0x30, 0x0D, 0x0A, 0x31, 0x34, 0x3A, 0x34, 0x37, 0x3A, 0x30, 0x39, 0x20, 0xD0, 0x95, 0xD1, + 0x81, 0xD1, 0x82, 0xD1, 0x8C, 0x20, 0xD0, 0xBA, 0xD0, + 0xBE, 0xD0, 0xBE, 0xD1, 0x80, 0xD0, 0xB4, 0xD0, 0xB8, 0xD0, 0xBD, 0xD0, 0xB0, 0xD1, 0x82, 0xD1, + 0x8B, 0x20, 0xD0, 0xBD, 0xD0, 0xB0, 0x20, 0xD0, 0xBE, + 0xD1, 0x82, 0xD0, 0xBF, 0xC0, 0x83, 0x38, 0x42, 0x64, 0xF6, 0x23, 0x1C, 0x02, 0xEA, 0x8E, 0xE7, + 0x69, 0x55, 0x10, 0x98, 0xD1, 0x80, 0xD0, 0xB0, 0xD0, + 0xB2, 0xD0, 0xBA, 0xD1, 0x83, 0x0D, 0x0A, 0x44, 0x6F, 0x70, 0x70, 0x6C, 0x65, 0x72, 0x3A, 0x20, + 0x31, 0x36, 0x32, 0x34, 0x20, 0x48, 0x7A, 0x2E, 0x20, + 0x4E, 0x6F, 0x69, 0x73, 0x65, 0x3A, 0x20, 0x36, 0x32, 0x28, 0x31, 0x33, 0x29, 0x2C, 0x32, 0x30, + 0x33, 0x28, 0x39, 0x29, 0x2C, 0x31, 0x34, 0x33, 0x28, + 0x31, 0x31, 0x29, 0x2C, 0x31, 0x37, 0x33, 0x28, 0x39, 0x29, 0x0D, 0x0A, 0x31, 0x34, 0x3A, 0x34, + 0x37, 0x3A, 0x30, 0x39, 0x20, 0xD0, 0x97, 0xD0, 0xB0, + 0xD0, 0xBF, 0xD1, 0x80, 0xD0, 0xBE, 0xD1, 0x81, 0x20, 0xD0, 0xBD, 0xD0, 0xB0, 0x20, 0xD0, 0xB7, + 0xD0, 0xB0, 0xD0, 0xBF, 0xD0, 0xB8, 0xD1, 0x81, 0xD1, + 0x8C, 0x20, 0x46, 0xD0, 0xBF, 0xD0, 0xBA, 0x3D, 0x32, 0x31, 0x37, 0x20, 0xD0, 0xA1, 0xD0, 0x9B, + 0xA2, 0xA6, 0x96, 0x6B, 0x72, 0x48, 0x96, 0xF9, 0xED, + 0x47, 0x37, 0x16, 0x3F, 0x8B, 0xC2, 0x98, 0x3D, 0x36, 0x36, 0x20, 0xD0, 0xA0, 0xD0, 0x97, 0x3D, + 0x35, 0x35, 0x39, 0x0D, 0x0A, 0x31, 0x34, 0x3A, 0x34, + 0x37, 0x3A, 0x31, 0x32, 0x20, 0xD0, 0x92, 0xD1, 0x8B, 0xD0, 0xB4, 0xD0, 0xB0, 0xD1, 0x87, 0xD0, + 0xB0, 0x20, 0xD0, 0xBF, 0xD0, 0xBE, 0xD1, 0x81, 0xD1, + 0x8B, 0xD0, 0xBB, 0xD0, 0xBA, 0xD0, 0xB8, 0x0D, 0x0A, 0x31, 0x34, 0x3A, 0x34, 0x37, 0x3A, 0x31, + 0x32, 0x20, 0xD0, 0x9A, 0xD0, 0x91, 0xD0, 0x9E, 0xD0, + 0x9A, 0x20, 0xD1, 0x81, 0xD0, 0xB8, 0xD0, 0xBD, 0xD1, 0x85, 0xD1, 0x80, 0xD0, 0xBE, 0xD0, 0xBF, + 0xD0, 0xBE, 0xD1, 0x81, 0xD1, 0x8B, 0xD0, 0xBB, 0xD0, + 0xBA, 0xD0, 0xB0, 0x20, 0xD0, 0xA1, 0xD0, 0x98, 0x3D, 0x36, 0x39, 0x43, 0x81, 0xA2, 0xBB, 0xA8, + 0xF9, 0x12, 0xAF, 0x65, 0x1C, 0x8C, 0x88, 0x33, 0x6E, + 0x6A, 0x52, 0x86, 0xFC, 0xA3, 0x6C, 0xC2, 0x8D, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; \ No newline at end of file diff --git a/Src/ModemLog.c b/Src/ModemLog.c new file mode 100644 index 0000000..fbc0092 --- /dev/null +++ b/Src/ModemLog.c @@ -0,0 +1,155 @@ +// +// Created by cfif on 18.02.23. +// + +#include +#include +#include +#include +#include "SerialPort.h" +#include "stdlib.h" +#include "string.h" +#include "httpd_types.h" +#include "httpd_base_func.h" +#include "fs_base_func.h" +#include "math.h" +#include "fs_base_func.h" +#include "file_logger.h" +#include "ModemLog.h" + +/* +void GsmWithGnss_Urc(tModemMainLog *env, tAtBuffer *buff) { + + if (buff->data[0] == '\r') + return; + + LoggerInfoRaw(LOGGER, LOG_SIGN, buff->data, buff->len); +} +*/ +void ModemMainLog_Init( + tModemMainLog *env, + tDeviceStorageIni *store, + tSerialPortIO *io, + tRtcIO *rtcIO, + tFs *fs, + osMutexId_t access_log +) { + + env->io = io; + env->fs = fs; + env->rtcIO = rtcIO; + env->access = access_log; + env->store = store; + + env->timestampWriteFileLogger = 0; + +// AtCmdInit( +// &env->modemAt, io, +// env->mem.modemTx, sizeof(env->mem.modemTx), +// env->mem.modemRx, sizeof(env->mem.modemRx), +// 1000, 1000 +// ); + +// AtCmdSetUrcProcessor(&env->modemAt, env, GsmWithGnss_Urc); + + //Инициализируем главный поток + InitThreadAtrStatic(&env->thread.attr, "ModemMainLog", env->thread.controlBlock, env->thread.stack, osPriorityNormal); + env->thread.id = 0; +} + +uint32_t getStateWriteLog2(tModemMainLog *env) { + return env->timestampWriteFileLogger; +} + +static uint16_t FileLoggerRaw_Write(tModemMainLog *env, uint32_t size) { + + FIL file; + FRESULT fr; + + if (osMutexAcquire(env->access, 8000) == osOK) { + + env->filename[0] = '\0'; + strcat(env->filename, dir_logs2); + + + time_t timestamp; + env->rtcIO->get(env->rtcIO, ×tamp); + timestamp += env->store->nvm.Settings_General.GMTcorr_v * 3600; + + struct tm timestampTM; + localtime_r(×tamp, ×tampTM); + + + strftime(env->buf, sizeof(env->buf), "%d-%m-%y.LOG", ×tampTM); + strcat(env->filename, env->buf); + + fr = f_open_i(env->fs, &file, (TCHAR *) env->filename, FA_WRITE | FA_OPEN_APPEND); + + if (fr) { + osMutexRelease(env->access); + return 0; + } + + UINT bytes_written; + fr = f_write_i(env->fs, &file, env->bufLog, size, &bytes_written); + + if (fr) { + f_close_i(env->fs, &file); + osMutexRelease(env->access); + return 0; + } + + fr = f_close_i(env->fs, &file); + if (fr) { + osMutexRelease(env->access); + return 0; + } + + osMutexRelease(env->access); + + return bytes_written; + } + return 0; +} + + + +static _Noreturn void ModemMainLog_Thread(tModemMainLog *env) { + + for (;;) { + + /* + if (AtCmdReceiveNextLine(&env->modemAt, 0xffff) == AT_OK) { + if (AtCmdRxBeginWithStatic(&env->modemAt, "#RSSI")) { + AtCmdRxClear(&env->modemAt); + } else { + AtCmdProcessUnresolvedLine(&env->modemAt); + AtCmdRxClear(&env->modemAt); + } + } +*/ + + uint16_t len = SerialPortReceive(env->io, env->bufLog, sizeof(env->bufLog), 500); + + if (len > 0) { + FileLoggerRaw_Write(env, len); + env->rtcIO->get(env->rtcIO, &env->timestampWriteFileLogger); + } + + //LoggerInfo(LOGGER, LOG_SIGN, (char *)env->bufLog, len); + + //uint8_t data[512]; + //uint16_t len = SerialPortReceive(env->io, data, sizeof(data), 2000); + //LoggerInfoRaw(LOGGER, LOG_SIGN, (char *)data, len); + } + +} + +void ModemMainLog_StartThread(tModemMainLog *env) { + if (!env->thread.id) { + env->thread.id = osThreadNew((osThreadFunc_t) (ModemMainLog_Thread), (void *) (env), &env->thread.attr); + } else { + osThreadResume(env->thread.id); + } +} + diff --git a/Src/ModemMain.c b/Src/ModemMain.c new file mode 100644 index 0000000..98d151e --- /dev/null +++ b/Src/ModemMain.c @@ -0,0 +1,1413 @@ +// +// Created by cfif on 04.10.2022. +// + +#include +#include +#include +#include +#include "SerialPort.h" +#include "stdlib.h" +#include "string.h" +#include "httpd_types.h" +#include "fs_base_func.h" +#include "math.h" +#include "fs_base_func.h" +#include "file_logger.h" +#include "ModemGonecFunc.h" +#include "Us.h" +#include "ModemReceive.h" +#include "ModemSend.h" +#include "crc32_edb88320.h" +#include "GonetsCrcs.h" +#include "ModemSendFunc.h" +#include "ModemGsmFunc.h" +#include +#include "httpd_post.h" +#include "httpd_get_handlers.h" +#include "Modem_Timer.h" +#include "i2c_smbus.h" + +#define LOGGER env->logger +#define LOG_SIGN "GONEC" + +extern const uint8_t dump[]; +extern const uint8_t dump2[]; +extern const uint8_t dump3[]; +extern const uint8_t dumpAlma[]; + +/* + +uint8_t aa[] = { + 0x3C, 0x64, 0x69, 0x76, 0x3E, 0xD0, 0x92, 0xD1, + 0x80, 0xD0, 0xB5, 0xD0, 0xBC, 0xD1, 0x8F, 0x20, 0x30, 0x33, 0x2D, 0x30, 0x35, 0x2D, + 0x32, 0x33, 0x20, + 0x31, 0x36, 0x3A, 0x33, 0x32, 0x3A, 0x32, 0x34, + 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x3C, 0x64, 0x69, 0x76, 0x3E, 0xD1, 0x82, 0xD0, 0xB5, 0xD1, 0x81, + 0xD1, 0x82, 0x20, 0xD0, 0xBF, 0xD0, 0xB0, 0xD1, + 0x83, 0xD0, 0xBA, 0xD0, 0xB0, 0x20, 0xD0, 0xB8, 0xD0, 0xB7, 0x20, 0xD0, 0xBF, 0xD0, 0xBE, 0xD0, 0xBB, + 0xD1, 0x8F, 0x3C, 0x62, 0x72, 0x3E, 0x3C, 0x2F, + 0x64, 0x69, 0x76, 0x3E +}; + +uint8_t bb[] = {0x01, 0x01, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00}; + +uint8_t buff[] = {0xC1, 0xA1, 0x04, 0x00, 0xA3, 0x10, 0x0E, 0x00, 0x00, 0x80, + 0x01, 0x01, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x84, 0x3D, 0x32, 0x9D, + + 0x3C, 0x64, 0x69, 0x76, 0x3E, 0xD0, 0x92, 0xD1, + 0x80, 0xD0, 0xB5, 0xD0, 0xBC, 0xD1, 0x8F, 0x20, 0x30, 0x33, 0x2D, 0x30, 0x35, 0x2D, + 0x32, 0x33, 0x20, + 0x31, 0x36, 0x3A, 0x33, 0x32, 0x3A, 0x32, 0x34, + 0x3C, 0x2F, 0x64, 0x69, 0x76, 0x3E, 0x3C, 0x64, 0x69, 0x76, 0x3E, 0xD1, 0x82, 0xD0, 0xB5, 0xD1, 0x81, + 0xD1, 0x82, 0x20, 0xD0, 0xBF, 0xD0, 0xB0, 0xD1, + 0x83, 0xD0, 0xBA, 0xD0, 0xB0, 0x20, 0xD0, 0xB8, 0xD0, 0xB7, 0x20, 0xD0, 0xBF, 0xD0, 0xBE, 0xD0, 0xBB, + 0xD1, 0x8F, 0x3C, 0x62, 0x72, 0x3E, 0x3C, 0x2F, + 0x64, 0x69, 0x76, 0x3E, + + + 0xD7, 0x90, 0xDE, 0x9F}; +*/ + +void ModemMain_Urc(tModemMain *env, tAtBuffer *buff) { + +// if (buff->data[0] == '\r') +// return; + +// LoggerInfoRaw(LOGGER, LOG_SIGN, buff->data, buff->len); +} + +void ModemMain_Init( + tModemMain *env, + tGpios *gpios, + tSerialPortIO *ioGonec, + tSerialPortIO *ioGsm, + tGnss *gnss, + tDeviceStorageIni *store, + tFileLogger *flog, + tFs *fs, + tRtcIO *rtcIo, + osMutexId_t accessMODEM_GSM, + osMutexId_t accessMODEM, + osMutexId_t accessHTTP, + osMutexId_t accessTracert +) { + + iGalois256Init(&env->galois256); + vGonetsReedSalmonInit(&env->GonetsReedSalmonParity4, &env->galois256, 4); + md5a_starts(&env->md5ctx_t); + md5a_starts(&env->md5ctx_r); + env->msgId = 0; + env->gpios = gpios; + + env->store->runtime.BannedSAT_ex[0] = '\0'; + + env->isModemCheck = false; + env->isEnableTracerTimeStamp = 0; + +// uint16_t sizePKT2 = ((uint16_t *) &dump3[1])[0]; +// uint32_t crcPKT2 = ((uint32_t *) &dump3[sizePKT2 - 4])[0]; +// uint32_t crc32_2 = crc32_edb88320(&dump3[18 + sizeof(tStructTransportPacket) + sizeof(tStructRepresentationPacket)], +// sizePKT2 - sizeof(tStructTransportPacket) - sizeof(tStructRepresentationPacket) - 18 - 4); + + +// uint16_t sizePKT = ((uint16_t *) &dump2[1])[0]; +// uint32_t crcPKT = ((uint32_t *) &dump2[sizePKT - 4])[0]; +// uint32_t crc32 = crc32_edb88320(&dump2[18 + sizeof(tStructTransportPacket) + sizeof(tStructRepresentationPacket)], +// sizePKT - sizeof(tStructTransportPacket) - sizeof(tStructRepresentationPacket) - 18 - 4); + + +/* + tStructTransportPacket *trans = (tStructTransportPacket *) &buff[0]; + + int day = trans->dateCreateTransportPacketDay; + int mon = trans->dateCreateTransportPacketMon; + + tStructRepresentationPacket *rep = + (tStructRepresentationPacket *) &buff[sizeof(tStructTransportPacket)]; + + + uint8_t crc8 = GonetsCrc8( bb, sizeof(bb)); + + char *data = buff[sizeof(tStructTransportPacket) + sizeof(tStructRepresentationPacket)]; + + uint32_t init = 0xFFFFFFFF; + uint32_t crc32_update; + + crc32_update = GonetsCrc32_update(aa, 3 , init); + init = crc32_update; + crc32_update = GonetsCrc32_update(&aa[3], sizeof(aa) - 3, init); + + uint32_t crc32_all = GonetsCrc32_finish(crc32_update); + + uint32_t crc32 = GonetsCrc32(aa, sizeof(aa)); +*/ + + env->store = store; + env->fs = fs; + env->gnss = gnss; + env->rtcIo = rtcIo; + env->accessMODEM_GSM = accessMODEM_GSM; + env->accessMODEM = accessMODEM; + env->accessHTTP = accessHTTP; + env->flog = flog; + env->rssi = 0; + env->temp = 0; + env->state = 0; + env->pwramp = 0; + + env->stepRssi = 0; + memset(env->dataRssi, 0, sizeof(env->dataRssi)); + + for (uint32_t i = 0; i < sizeof(env->dataRssi) / 4; ++i) + env->dataRssi[i] = -88; + + env->mnumBufScanCount = 0; + + env->timestamp_start_block = 0; + + env->modemWorkingState = MODEM_WORKING_NONE; + + env->accessTracert = accessTracert; + + env->modemSlotSendStatusReload = false; + env->modemSlotReceivedStatusReload = false; + + env->timeUpdateModemRegion = 0; + + env->isModemStart = false; + +// for (int i = 0; i < 32; ++i) { +// env->fileSendInfoForJson[i].valid = 0; +// } + + for (int i = 0; i < 32; ++i) { + env->modemStatus.status[i] = SLOT_INIT; + env->modemStatusOld[i] = SLOT_INIT; + } + + for (int i = 0; i < 16; ++i) { + env->packetDataForKvitin[i].isEnabled = false; + } + + env->location.isOneDateTime = true; + env->location.isOneValidGnss = true; + env->location.isDateTimeRecv = false; + + env->location.isTimeOneStartBlock = true; + +// env->location.isOneDateTime = false; +// env->location.isOneValidGnss = false; + + +// time_t time; +// env->rtcIo->get(env->rtcIo, &time); + env->timestamp_start_block = 0; + env->timestamp_start_block_work = 0; + + time_t timestamp; + env->rtcIo->get(&env->rtcIo->get, ×tamp); + env->timestamp_start_block_work_add = timestamp; + + env->eventWebState.EVENT_OUTBOX = 0; + env->eventWebState.EVENT_INBOX = 0; + env->eventWebState.EVENT_SENTBOX = 0; + env->eventWebState.EVENT_ALMA = 0; + + env->countAlmanac = 0; + + AtCmdInit( + &env->modemAt, ioGonec, + env->memGonec.modemTx, sizeof(env->memGonec.modemTx), + env->memGonec.modemRx, sizeof(env->memGonec.modemRx), + 6000, 6000 + ); + + AtCmdSetUrcProcessor(&env->modemAt, env, ModemMain_Urc); + + AtCmdInit( + &env->modemAtGsm, ioGsm, + env->memGsm.modemTx, sizeof(env->memGsm.modemTx), + env->memGsm.modemRx, sizeof(env->memGsm.modemRx), + 6000, 6000 + ); + + env->location.region = env->store->nvm.Settings_Frequency_Speed.RegionRegistr_v; + + env->stateRequest.stateReqReg = StateReqRegNoSendStatus; + + env->stateRequest.stateReqAlma = StateReqAlmaNoSendStatus; + env->stateRequest.stateReqDelExtW = StateReqExtNone; + env->stateRequest.stateReqCreateExtW = StateReqExtNone; + env->stateRequest.stateReqDelExtT = StateReqExtNone; + env->stateRequest.stateReqCreateExtT = StateReqExtNone; + env->stateRequest.stateReqAlmaWebRunStop = StateReqAlmaWebRunInit; + + + cConvertDecToMilliArcSecFromDegMin(env->store->nvm.Settings_General.DefLatiGrad_v, + env->store->nvm.Settings_General.DefLatiMin_v, NULL, + &env->location.latitude); + + cConvertDecToMilliArcSecFromDegMin(env->store->nvm.Settings_General.DefLongGrad_v, + env->store->nvm.Settings_General.DefLongMin_v, NULL, + &env->location.longitude); + + almac_load_from_file(env); + + + //Инициализируем главный поток + InitThreadAtrStatic(&env->thread.attr, "ModemMain", env->thread.controlBlock, env->thread.stack, osPriorityNormal); + env->thread.id = 0; +} + +void GetCoordinates(tModemMain *env, int32_t *ret_latitude, int32_t *ret_longitude) { + double latitude; + double longitude; + if (env->location.valid) { + latitude = env->location.gnss_latitude; + longitude = env->location.gnss_longitude; + } else { + cConvertDecToMilliArcSecFromDegMin(env->store->nvm.Settings_General.DefLatiGrad_v, + env->store->nvm.Settings_General.DefLatiMin_v, NULL, + &latitude); + + cConvertDecToMilliArcSecFromDegMin(env->store->nvm.Settings_General.DefLongGrad_v, + env->store->nvm.Settings_General.DefLongMin_v, NULL, + &longitude); + } + + *ret_latitude = lround(latitude); + *ret_longitude = lround(longitude); +} + +// Котроль файлов в приеме +void controlFragIn(tFs *fs, tDeviceStorageIni *store, tRtcIO *rtcIo) { + FRESULT fr; + DIR dj; + FILINFO fno; + + time_t timestampRtc; + rtcIo->get(&rtcIo, ×tampRtc); + + char path_dir_fileName[MAX_LEN_PATH_FS]; + + fr = f_findfirst_i(fs, &dj, &fno, dir_frag_inbox, "*"); + + while (fr == FR_OK && fno.fname[0]) { + + struct tm stm; + fatTimeToTimeStamp(fno.ftime | (fno.fdate << 16), &stm, 0); + time_t timestampFile = mktime(&stm); + + uint32_t dl; + if (timestampRtc > timestampFile) { + dl = (timestampRtc - timestampFile); + } else { + dl = (timestampFile - timestampRtc); + } + + if (store->nvm.Settings_Transmitter.TimeLifeFragIn == 0) + store->nvm.Settings_Transmitter.TimeLifeFragIn = 96; + + if (dl > store->nvm.Settings_Transmitter.TimeLifeFragIn * 3600) { + path_dir_fileName[0] = '\0'; + strcat(path_dir_fileName, dir_frag_inbox); + strcat(path_dir_fileName, fno.fname); + + fr = f_unlink_i(fs, path_dir_fileName); + } + + fr = f_findnext_i(fs, &dj, &fno); + } + fr = f_closedir_i(fs, &dj); + + + fr = f_findfirst_i(fs, &dj, &fno, dir_kvitin, "*"); + + while (fr == FR_OK && fno.fname[0]) { + + struct tm stm; + fatTimeToTimeStamp(fno.ftime | (fno.fdate << 16), &stm, 0); + time_t timestampFile = mktime(&stm); + + uint32_t dl; + if (timestampRtc > timestampFile) { + dl = (timestampRtc - timestampFile); + } else { + dl = (timestampFile - timestampRtc); + } + + if (store->nvm.Settings_Transmitter.TimeLifeFragIn == 0) + store->nvm.Settings_Transmitter.TimeLifeFragIn = 96; + + if (dl > store->nvm.Settings_Transmitter.TimeLifeFragIn * 3600) { + path_dir_fileName[0] = '\0'; + strcat(path_dir_fileName, dir_kvitin); + strcat(path_dir_fileName, fno.fname); + + fr = f_unlink_i(fs, path_dir_fileName); + } + + fr = f_findnext_i(fs, &dj, &fno); + } + fr = f_closedir_i(fs, &dj); + +} + +/* +bool UpdateModemRegion(tModemMain *env) { + bool isWriteMem = false; + + // Количество файлов в отправке + int countFilesOutbox = 0; + countFilesOutbox += getCountOutbox(env, 'w'); + countFilesOutbox += getCountOutbox(env, 't'); + countFilesOutbox += getCountOutbox(env, 'k'); + + if ((countFilesOutbox == 0) && (env->stateRequest.stateReqAlma != StateReqAlmaSendStatus)) + + if (osMutexAcquire(env->accessMODEM, TIME_MUTEX_MODEM_ACCESS) == osOK) { + Modem_RegRegion(&env->modemAt, &isWriteMem, env->location.region); + osMutexRelease(env->accessMODEM); + + if (isWriteMem) { + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновление георегиона регистрации на модеме"); + // Запуск регистрации + StartRegTask(env); + } + } + + return isWriteMem; +} +*/ + + + +void getDelFilesDirScanCrc(tModemMain *env) { + tFileSendInfo fileSendInfo; + tFileRecvInfo fileRecvInfo; + + FRESULT fr; + DIR dj; + FILINFO fno; + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + + fr = f_findfirst_i(env->fs, &dj, &fno, dir_rep_out, "*.INF"); + + while (fr == FR_OK && fno.fname[0]) { + + uint32_t idFile = atoi(fno.fname); + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_rep_out, idFile); + + bool resultFileInfo = readSendFileInfo(env->fs, &fileSendInfo, path_dir_info_fileName); + + if (resultFileInfo == false) { + fr = f_findnext_i(env->fs, &dj, &fno); + continue; + } + + + uint32_t crc32_MSK = CrcFileFs(env->fs, path_dir_mask_fileName); + uint32_t crc32_REP = CrcFileFs(env->fs, path_dir_rep_fileName); + + if ((fileSendInfo.crc32_MSK != crc32_MSK) || (fileSendInfo.crc32_REP != crc32_REP)) { + fr = f_unlink_i(env->fs, path_dir_rep_fileName); + fr = f_unlink_i(env->fs, path_dir_mask_fileName); + fr = f_unlink_i(env->fs, path_dir_info_fileName); + } + + + fr = f_findnext_i(env->fs, &dj, &fno); + } + fr = f_closedir_i(env->fs, &dj); + + + fr = f_findfirst_i(env->fs, &dj, &fno, dir_frag_inbox, "*.INF"); + + while (fr == FR_OK && fno.fname[0]) { + + uint32_t idFile = atoi(fno.fname); + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_frag_inbox, idFile); + + bool resultFileInfo = readRecvFileInfo(env->fs, &fileRecvInfo, path_dir_info_fileName); + + if (resultFileInfo == false) { + fr = f_findnext_i(env->fs, &dj, &fno); + continue; + } + + uint32_t crc32_MSK = CrcFileFs(env->fs, path_dir_mask_fileName); + uint32_t crc32_REP = CrcFileFs(env->fs, path_dir_rep_fileName); + + if ((fileRecvInfo.crc32_MSK != crc32_MSK) || (fileRecvInfo.crc32_REP != crc32_REP)) { + fr = f_unlink_i(env->fs, path_dir_rep_fileName); + fr = f_unlink_i(env->fs, path_dir_mask_fileName); + fr = f_unlink_i(env->fs, path_dir_info_fileName); + } + + + fr = f_findnext_i(env->fs, &dj, &fno); + } + fr = f_closedir_i(env->fs, &dj); + +} + +// Обновление георегиона +static void ModemMain_SetRegion(tModemMain *env) { + + int16_t latitude = lround(env->location.latitude); + int16_t longitude = lround(env->location.longitude); + + +#ifdef DEBUG_MODEM + char bufLog[255]; + bufLog[0] = '\0'; + strcat(bufLog, "Обновление координат на модеме. Широта: "); + + char buffer[12]; + + itoa(latitude, buffer, 10); + strcat(bufLog, buffer); + + strcat(bufLog, " Долгота: "); + + itoa(longitude, buffer, 10); + strcat(bufLog, buffer); + + strcat(bufLog, ""); + + LoggerInfo(LOGGER, LOG_SIGN, bufLog, strlen(bufLog)); +#endif + + // Установка координат + ModemSet_Coord(env, latitude, longitude); + + + for (int i = 0; i < 60; ++i) { + + if (((latitude >= regionData[i].minLatitude) && + (latitude <= regionData[i].maxLatitude)) && + ((longitude >= regionData[i].minLongitude) && + (longitude <= regionData[i].maxLongitude))) { + + env->location.region = i + 1; + + bool isWriteMem; + + if (osMutexAcquire(env->accessMODEM, TIME_MUTEX_MODEM_ACCESS) == osOK) { + + // Если георегион на модеме сменился (isWriteMem) + Modem_RegRegion(&env->modemAt, &isWriteMem, env->location.region); + osMutexRelease(env->accessMODEM); + + if (isWriteMem) { +#ifdef DEBUG_MODEM + char bufLog[255]; + bufLog[0] = '\0'; + strcat(bufLog, "Обновление георегиона регистрации на модеме: "); + char buffer[12]; + utoa(env->location.region, buffer, 10); + strcat(bufLog, buffer); + strcat(bufLog, ""); + LoggerInfo(LOGGER, LOG_SIGN, bufLog, strlen(bufLog)); +#endif + + env->stateRequest.stateReqReg = StateReqRegSendStatus; + // Запуск задач модема + RunStopTaskModem(env); + } + } + + break; + } + } + +} + +void sendExtProtokolPack(tModemMain *env, tTypeFile typeFile, char *buf, uint32_t buf_len) { + + if (osMutexAcquire(httpSettings.accessHTTP, TIME_MUTEX_HTTP_ACCESS) == osOK) { + + time_t timestamp = 0; + env->rtcIo->get(&env->rtcIo, ×tamp); + timestamp += env->store->nvm.Settings_General.GMTcorr_v * 3600; + + //char bufFileName[64]; + //struct tm stm; + //localtime_r(×tamp, &stm); + //strftime(bufFileName, sizeof(bufFileName), "%d-%m-%g %H-%M-%S", &stm); + + + char filename[MAX_LEN_PATH_FS]; + filename[0] = '\0'; + + if (typeFile == TYPE_FILE_AMS_RADAR) + strcat(filename, "1:/TMP/radar.ams"); + + if (typeFile == TYPE_FILE_LORA_WAN) + strcat(filename, "1:/TMP/lorawan.dat"); + + + char to[MAX_LEN_PATH_FS]; + memset(to, 0, sizeof(to)); + + if (typeFile == TYPE_FILE_AMS_RADAR) + utoa(env->store->nvm.Settings_AmsRadar.AmsRadarATsrv, to, 10); + + if (typeFile == TYPE_FILE_LORA_WAN) + utoa(env->store->nvm.Settings_LoRaWan.LoRaWanATsrv, to, 10); + + + idPostResult_t result = handlerGet_Message_Outbox_CreateTempOrRealFile_Sendmsg(&httpSettings, + false, + &filename[2], + buf, + buf_len, + timestamp, + to, + 0, + 1, + 1, + 0, + typeFile, + 0); + + osMutexRelease(httpSettings.accessHTTP); + + env->rtcIo->get(env->rtcIo, &env->eventWebState.EVENT_OUTBOX); + } +} + +/* +void sendAmsRadar(tModemMain *env, char *buf, uint32_t buf_len) { + + if (osMutexAcquire(httpSettings.accessHTTP, TIME_MUTEX_HTTP_ACCESS) == osOK) { + + time_t timestamp = 0; + env->rtcIo->get(&env->rtcIo, ×tamp); + timestamp += env->store->nvm.Settings_General.GMTcorr_v * 3600; + + //char bufFileName[64]; + //struct tm stm; + //localtime_r(×tamp, &stm); + //strftime(bufFileName, sizeof(bufFileName), "%d-%m-%g %H-%M-%S", &stm); + + + char filename[MAX_LEN_PATH_FS]; + filename[0] = '\0'; + strcat(filename, "1:/TMP/radar.ams"); + //strcat(filename, bufFileName); + //strcat(filename, ".txt"); + + char to[MAX_LEN_PATH_FS]; + memset(to, 0, sizeof(to)); + utoa(env->store->nvm.Settings_AmsRadar.AmsRadarATsrv, to, 10); + + + idPostResult_t result = handlerGet_Message_Outbox_CreateTempOrRealFile_Sendmsg(&httpSettings, + false, + &filename[2], + buf, + buf_len, + timestamp, + to, + 0, + 1, + 1, + 0, + TYPE_FILE_AMS_RADAR, + 0); + + osMutexRelease(httpSettings.accessHTTP); + + env->rtcIo->get(env->rtcIo, &env->eventWebState.EVENT_OUTBOX); + } +} +*/ +void sendMsd(tModemMain *env) { + tEraGlonassMsd msd; + + EraGlonassMsdInit(&msd); + + time_t timestamp; + env->rtcIo->get(&env->rtcIo, ×tamp); + + EraGlonassMsdSetTimeStamp(&msd, timestamp); + ++env->msgId; + EraGlonassMsdSetDataEmergencySituationFlags(&msd, env->msgId, AUTOMATIC_ACTIVATION, EMERGENCY_CALL); + + EraGlonassMsdSetPassengersNumber(&msd, env->store->nvm.Settings_Msd.NumHuman); +// EraGlonassMsdSetVehicleType(&msd, UVEOS_GOST_PASSENGER_VEHICLE_CLASS_M1); + + uint16_t flag = 0; + + if (env->store->nvm.Settings_Msd.TypeFuel == 0) + flag = UVEOS_GOST_GASOLINE_TANK_PRESENT; + if (env->store->nvm.Settings_Msd.TypeFuel == 1) + flag = UVEOS_GOST_DIESEL_TANK_PRESENT; + if (env->store->nvm.Settings_Msd.TypeFuel == 2) + flag = UVEOS_GOST_COMPRESSED_NATURAL_GAS; + if (env->store->nvm.Settings_Msd.TypeFuel == 3) + flag = UVEOS_GOST_LIQUID_PROPANE_GAS; + if (env->store->nvm.Settings_Msd.TypeFuel == 4) + flag = UVEOS_GOST_ELECTRIC_ENERGY_STORAGE; + if (env->store->nvm.Settings_Msd.TypeFuel == 5) + flag = UVEOS_GOST_HYDROGEN_STORAGE; + + + EraGlonassMsdSetVehicleType(&msd, 14); + +// EraGlonassMsdSetVIN(&msd, "4Y1SL65848Z411439", sizeof("4Y1SL65848Z411439") - 1); + EraGlonassMsdSetVIN(&msd, env->store->nvm.Settings_Msd.VIN, strlen(env->store->nvm.Settings_Msd.VIN)); + + EraGlonassMsdSetPropulsionStorageType(&msd, flag); + + // Координаты с ГНСС не получены + if (env->location.isOneValidGnss) { + + EraGlonassMsdNoGnssSetDefaults(&msd); + } else { + tNavDataMsd navDataMsd; + Gnss_GetNavDataMsdNmeaRmc(env->gnss, &navDataMsd); + + EraGlonassMsdSetPositionValue(&msd, navDataMsd.longitude, navDataMsd.latitude, navDataMsd.direction, + navDataMsd.valid); + + } + + uint32_t MsisdnSize = strlen(env->gsmSimId); + + uint8_t msdEncoded[256]; + uint16_t msdEncodedSize = EraGlonassMsdEncode(&msd, MSD_V_2, msdEncoded); + + uint8_t HeadEncodedAndMsd[256]; + + uint32_t step = 0; + memcpy(&HeadEncodedAndMsd[step], env->gsmIMEI, 15); + step += 15; + memcpy(&HeadEncodedAndMsd[step], &MsisdnSize, 2); + step += 2; + memcpy(&HeadEncodedAndMsd[step], env->gsmSimId, MsisdnSize); + step += MsisdnSize; + memcpy(&HeadEncodedAndMsd[step], &msdEncodedSize, 2); + step += 2; + memcpy(&HeadEncodedAndMsd[step], msdEncoded, msdEncodedSize); + step += msdEncodedSize; + + char egtsHexStr[256]; + memset(egtsHexStr, 0, sizeof(egtsHexStr)); + size_t egtsHexStrLen = 0; + vAsciiStringAddBytesAsHex(egtsHexStr, &egtsHexStrLen, HeadEncodedAndMsd, step); + +// if (osMutexAcquire(httpSettings.accessHTTP, TIME_MUTEX_HTTP_ACCESS) == osOK) { + + // Удаление всех файлов + delRepout(env, TYPE_FILE_MESSAGE, false, true); + + char filename[MAX_LEN_PATH_FS]; + filename[0] = '\0'; + strcat(filename, "1:/TMP/msd.txt"); +/* + FRESULT fr = f_unlink_i(env->fs, filename); + + FIL file; + fr = f_open_i(env->fs, &file, (TCHAR *) filename, FA_WRITE | FA_CREATE_ALWAYS); + UINT bytes_written; + fr = f_write_i(env->fs, &file, egtsHexStr, strlen(egtsHexStr), &bytes_written); + fr = f_close_i(env->fs, &file); +*/ + char to[MAX_LEN_PATH_FS]; + memset(to, 0, sizeof(to)); + utoa(env->store->nvm.Settings_Msd.SosATsrv, to, 10); + + timestamp += env->store->nvm.Settings_General.GMTcorr_v * 3600; + + idPostResult_t result = handlerGet_Message_Outbox_CreateTempOrRealFile_Sendmsg(&httpSettings, + false, + &filename[2], + egtsHexStr, + egtsHexStrLen, + timestamp, + to, + 14, + 1, + 1, + 0, + TYPE_FILE_MESSAGE, + 1); + +// osMutexRelease(httpSettings.accessHTTP); + + if (env->store->nvm.flagSos == 0) { + env->store->nvm.flagSos = 1; + DeviceStorageCounterIni_DumpSos(env->store); + } + + + env->rtcIo->get(env->rtcIo, &env->eventWebState.EVENT_OUTBOX); +// } + +} + +/* +bool setAlmac(tModemMain *env) { + + env->countAlmanac = 0; + + char dirUpdateFileName[MAX_LEN_PATH_FS]; + dirUpdateFileName[0] = '\0'; + strcat(dirUpdateFileName, dir_almhs); + strcat(dirUpdateFileName, "CURALM.DAT"); + + FIL file; + + // подгрузили альманахи + FRESULT fr = f_open_i(env->fs, &file, (TCHAR *) dirUpdateFileName, FA_READ); + + if (fr != FR_OK) + return false; + + char alm[79]; + f_lseek_i(env->fs, &file, 11); + + while (!f_eof(&file)) { + UINT bytes_read; + f_read_i(env->fs, &file, &alm, sizeof(alm), &bytes_read); + env->alms[env->countAlmanac] = decodeAlmanac(alm); + ++env->countAlmanac; + } + + f_close_i(env->fs, &file); + + return true; +} +*/ + +bool almac_load_from_file(tModemMain *env) { + env->countAlmanac = 0; + + char dirUpdateFileName[MAX_LEN_PATH_FS]; + dirUpdateFileName[0] = '\0'; + strcat(dirUpdateFileName, dir_almhs); + strcat(dirUpdateFileName, "CURALM.DAT"); + + FIL file; + + // подгружаем альманахи + FRESULT fr = f_open_i(env->fs, &file, (TCHAR *) dirUpdateFileName, FA_READ); + + if (fr != FR_OK) + return false; + + f_lseek_i(env->fs, &file, 11); + tGonetsAlmanac alm; + // сделали декодирование (достаточно просто считать их в запакованную структуру) + while (!f_eof(&file)) { + + UINT read; + f_read_i(env->fs, &file, &alm, sizeof(tGonetsAlmanac), &read); + ////важно чтобы весь альманах целиком был подгружен!!!! + if (read == sizeof(tGonetsAlmanac)) { + env->alms[env->countAlmanac] = alm; + ++env->countAlmanac; + } + } + f_close_i(env->fs, &file); + + return true; +} + +bool createFileKvitIn(tModemMain *env, + uint32_t numberSender, + uint32_t KVT_numberMessage, + uint32_t KVT_dataCreationMon, + uint32_t KVT_dataCreationDay); + +//bool HandlerModemKvitPaket(tModemMain *env); +uint8_t bufff[16] = {0x81, 0x72, 0x17, 0x00, 0xFC, 0x46, 0x5F, 0x00, 0x00, 0x00, 0x96, 0x4B, 0x00, 0xA0, 0x50, 0x00}; + +//uint8_t bufff[16] = { 0x81, 0x72, 0x17, 0x00, 0xFC, 0x46, 0x5F, 0x00, 0x00, 0x00, 0x96, 0x4B, 0x00, 0xA0, 0x50, 0x00 }; +//uint8_t bufff[19] = { 0x81, 0x72, 0x17, 0x00, 0xFC, 0x46, 0x5F, +// 0, 0, 0, +// 0x0A, 0x5, 0x00, + +// 0x14, 0xA, 0x00, +// 0x1E, 0xF, 0x00 +//}; + + + + +static _Noreturn void ModemMain_Thread(tModemMain *env) { + bool result; + + env->testOne = 0; + + +/* + + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + tFileRecvInfo fileRecvInfo; + + uint32_t idFile = 3; + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_frag_inbox, idFile); + + bool resultFileInfo = readRecvFileInfo(env->fs, &fileRecvInfo, path_dir_info_fileName); + + env->packetDataForKvitin[0].isEnabled = true; + env->packetDataForKvitin[0].numberMessage = fileRecvInfo.mnumFrom; + env->packetDataForKvitin[0].numberSender = fileRecvInfo.from; + env->packetDataForKvitin[0].dataCreationDay = fileRecvInfo.dateDay; + env->packetDataForKvitin[0].dataCreationMon = fileRecvInfo.dateMon; + + HandlerModemPaketKvitin(env); +*/ + +/* + memcpy(env->bufReceivedPacket, bufff, sizeof(bufff)); + env->bufReceivedPacketLen = sizeof(bufff); + HandlerModemKvitPaket(env); +*/ + +/* + // ТЕСТ___ + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + uint32_t idFile = 563; + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) "1:/kvitin/", idFile); + + uint32_t lenPacketKvit; + bool isAll; + + result = Kvitin(env->fs, env->rtcIo, + 1555, + env->store->nvm.Settings_General.ATnum_v, path_dir_info_fileName, + path_dir_mask_fileName, env->bufSendPacketKvitin, + &lenPacketKvit, &isAll); + + + volatile uint32_t massKvt[20]; + + tStructTransportKvitPacketData *dataKvit = (tStructTransportKvitPacketData *) &env->bufSendPacketKvitin[0]; + uint32_t stepZZ = 0; + for (int i=0; ioffsetKvitPacket; + ++stepZZ; + ++dataKvit; + } + // ТЕСТ___ +*/ + + + + +// renameFromFrgToInBox5555(env->fs, &env->GonetsReedSalmonParity4, &env->md5ctx, 123, env->rtcIo, "", "1:/1.REP", +// env->logger); + + int32_t DefLatiGrad_v = env->store->nvm.Settings_General.DefLatiGrad_v; + uint32_t DefLatiMin_v = env->store->nvm.Settings_General.DefLatiMin_v; + int32_t DefLongGrad_v = env->store->nvm.Settings_General.DefLongGrad_v; + uint32_t DefLongMin_v = env->store->nvm.Settings_General.DefLongMin_v; + + tModemWorkingState workingState; + + // Удаление файлов трассировки в исходящих + //delRepoutTracert(env); + + // Обновление координат с настроек + cConvertDecToMilliArcSecFromDegMin(env->store->nvm.Settings_General.DefLatiGrad_v, + env->store->nvm.Settings_General.DefLatiMin_v, NULL, + &env->location.latitude); + + cConvertDecToMilliArcSecFromDegMin(env->store->nvm.Settings_General.DefLongGrad_v, + env->store->nvm.Settings_General.DefLongMin_v, NULL, + &env->location.longitude); + +// bool prevStatusPin = false; + + + // Контроль файлов на передаче + controlFiles(env->fs, "*", (char *) dir_rep_out); + // Контроль файлов на приеме + controlFiles(env->fs, "*", (char *) dir_frag_inbox); + // Контроль на CRC + getDelFilesDirScanCrc(env); + + // Контроль удаления DAT файлов + getDelFileDirDatTracert(env->fs, (char *) dir_tracert); + + if (osMutexAcquire(env->accessHTTP, TIME_MUTEX_HTTP_ACCESS) == osOK) { + createBufStateFileSend(env->fs); + osMutexRelease(env->accessHTTP); + } + + bool isGonecStart = false; + if (AtCmdWaitOk(&env->modemAt, 100, 10000) == AT_OK) { + isGonecStart = true; + } + + uint8_t sizeModem; + uint8_t sizeCrypto; + char versionModem[128]; + char versionCrypto[128]; + env->isModemCheck = false; + Modem_Get_Version_Modem(env, versionModem, &sizeModem, versionCrypto, &sizeCrypto); + + char *firmwareModemBoot = "null\0"; + firmwareModemBoot = (char *) strchr(versionModem, ','); + if (firmwareModemBoot != NULL) { + *firmwareModemBoot = '\0'; + firmwareModemBoot++; + } + + if (strcmp(versionModem, "MODEM_MAIN") == 0) { + env->isModemCheck = true; + } + + + bool isGsmStart = false; + if (AtCmdWaitOk(&env->modemAtGsm, 100, 10000) == AT_OK) { + isGsmStart = true; + } + + memset(env->gsmIMEI, 0, sizeof(env->gsmIMEI)); + memset(env->gsmSimId, 0, sizeof(env->gsmSimId)); + + if (isGsmStart) { + size_t acpStringLen; + if (GsmGET_CGSN(env, env->gsmIMEI, &acpStringLen) != AT_OK) { + strcat(env->gsmIMEI, "000000000000000"); + } + + if (GsmCCID(env, env->gsmSimId, &acpStringLen) != AT_OK) { + strcat(env->gsmSimId, "0000000000"); + } + + } else { + strcat(env->gsmIMEI, "000000000000000"); + strcat(env->gsmSimId, "0000000000"); + } + + + uint32_t timeStuckGetMs = 0; + bool startStuckGetMs = false; + + // Флаг проверки включения предусилиеля + bool FlagOnUs = true; + // Флаг проверки выключения предусилиеля + bool FlagOffUs = false; + + + for (;;) { + + // Ожидание установки времени с ПК + if (env->location.isOneDateTime) { + + SystemDelayMs(100); + + uint32_t get_timestamp_gnss; + + Gnss_GetTime(env->gnss, &get_timestamp_gnss); + if (get_timestamp_gnss > 1644683158) { + + timeModemStuckGetMs = SystemGetMs(); + env->location.isOneDateTime = false; + + // Сколько прошло до этого времени + env->timestamp_start_block_work_add = SystemGetMs() / 1000; + + time_t timestamp = get_timestamp_gnss; + env->rtcIo->set(×tamp, ×tamp); + + env->timestamp_start_block = timestamp; + } + + continue; + } + + // Получение логов + uint32_t size = 0; + uint32_t wasreboot = 0; + env->state = 0; + env->pwramp = 0; + result = false; + + if (env->isModemCheck) + result = ModemGetLog(env, &env->rssi, &env->temp, &env->pwramp, &env->state, &wasreboot, &size, + (uint8_t *) env->bufLog); + + env->dataRssi[env->stepRssi] = env->rssi; + env->stepRssi = (env->stepRssi + 1) % 10; + + + if ((result) && (size)) { + + for (uint32_t i = 0; i < size; ++i) { + if ((env->bufLog[i] == '\r') || (env->bufLog[i] == '\n')) + env->bufLog[i] = ' '; + } + + LoggerInfo(LOGGER, LOG_SIGN, env->bufLog, size); + } + + + + //начало -------------------------Контроль запуска модема------------------------------------------------------- + //начало -------------------------Контроль запуска модема------------------------------------------------------- + //начало -------------------------Контроль запуска модема------------------------------------------------------- + + if ((result) && (wasreboot)) { + + for (uint32_t i = 0; i < sizeof(env->dataRssi) / 4; ++i) + env->dataRssi[i] = -88; + + // Контроль файлов в приеме на дату + controlFragIn(env->fs, env->store, env->rtcIo); + // Контроль файлов на приеме + controlFiles(env->fs, "*", (char *) dir_frag_inbox); + +#ifdef DEBUG_MODEM + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обнаружен запуск модема"); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обновление времени на модеме"); +#endif + time_t set_timestamp; + env->rtcIo->get(&env->rtcIo, &set_timestamp); + set_timestamp += env->store->nvm.Settings_General.GMTcorr_v * 3600; + ModemDateTime(env, &set_timestamp); + + bool isWriteMem; + Modem_RegRegion(&env->modemAt, &isWriteMem, env->location.region); + +#ifdef DEBUG_MODEM + char bufLog[255]; + bufLog[0] = '\0'; + strcat(bufLog, "Обновление координат на модеме. Широта: "); + char buffer[12]; + itoa(lround(env->location.latitude), buffer, 10); + strcat(bufLog, buffer); + strcat(bufLog, " Долгота: "); + itoa(lround(env->location.longitude), buffer, 10); + strcat(bufLog, buffer); + strcat(bufLog, ""); + LoggerInfo(LOGGER, LOG_SIGN, bufLog, strlen(bufLog)); +#endif + + + ModemSet_Coord(env, lround(env->location.latitude), lround(env->location.longitude)); + + // Модем освободил слот + for (int id = 0; id < 16; ++id) + env->modemStatus.idMessage[id] = 0; + + for (int i = 0; i < 16; ++i) { + env->packetDataForKvitin[i].isEnabled = false; + } + + for (int i = 0; i < 32; ++i) { + env->modemStatus.status[i] = SLOT_INIT; + env->modemStatusOld[i] = SLOT_INIT; + } + + env->modemWorkingState = MODEM_WORKING_NONE; + + // Состоянияе георегистрации + env->stateRequest.stateReqReg = StateReqRegNoSendStatus; + + // Состояние задачи получения альманаха + env->stateRequest.stateReqAlma = StateReqAlmaNoSendStatus; + + // Контроль удаления файлов Сообщений + env->stateRequest.stateReqDelExtW = StateReqExtForDel; + // Контроль удаления файлов Трассировки + env->stateRequest.stateReqDelExtT = StateReqExtForDel; + // Контроль создания файлов Сообщений + env->stateRequest.stateReqCreateExtW = StateReqExtForCreate; + // Контроль создания файлов Трассировки + env->stateRequest.stateReqCreateExtT = StateReqExtForCreate; + + env->isModemStart = true; + + } + + //конец -------------------------Контроль запуска модема------------------------------------------------------- + //конец -------------------------Контроль запуска модема------------------------------------------------------- + //конец -------------------------Контроль запуска модема------------------------------------------------------- + + + //начало -------------------------Получение данных с GNSS о местоположении-------------------------------------- + //начало -------------------------Получение данных с GNSS о местоположении-------------------------------------- + //начало -------------------------Получение данных с GNSS о местоположении-------------------------------------- + + // Контроль изменения координат с настроек + if ((DefLatiGrad_v != env->store->nvm.Settings_General.DefLatiGrad_v) || + (DefLatiMin_v != env->store->nvm.Settings_General.DefLatiMin_v) || + (DefLongGrad_v != env->store->nvm.Settings_General.DefLongGrad_v) || + (DefLongMin_v != env->store->nvm.Settings_General.DefLongMin_v)) { + + DefLatiGrad_v = env->store->nvm.Settings_General.DefLatiGrad_v; + DefLatiMin_v = env->store->nvm.Settings_General.DefLatiMin_v; + DefLongGrad_v = env->store->nvm.Settings_General.DefLongGrad_v; + DefLongMin_v = env->store->nvm.Settings_General.DefLongMin_v; + + // Обновление координат с настроек + cConvertDecToMilliArcSecFromDegMin(env->store->nvm.Settings_General.DefLatiGrad_v, + env->store->nvm.Settings_General.DefLatiMin_v, NULL, + &env->location.latitude); + + cConvertDecToMilliArcSecFromDegMin(env->store->nvm.Settings_General.DefLongGrad_v, + env->store->nvm.Settings_General.DefLongMin_v, NULL, + &env->location.longitude); + + + ModemMain_SetRegion(env); + + } + + + Gnss_GetNavDataNmeaRmc(env->gnss, &env->location); + if (env->location.valid) { + + if (env->location.isOneValidGnss) { +#ifdef DEBUG_MODEM + LoggerInfoStatic(LOGGER, LOG_SIGN, "Получены координаты с ГНСС"); +#endif + } + + env->location.isOneValidGnss = false; + + // Контроль изменения координат с ГНСС + if ((env->location.latitude <= (env->location.gnss_latitude - 0.51)) || + (env->location.latitude >= (env->location.gnss_latitude + 0.51)) || + (env->location.longitude <= (env->location.gnss_longitude - 0.51)) || + (env->location.longitude >= (env->location.gnss_longitude + 0.51))) { + + env->location.latitude = env->location.gnss_latitude; + env->location.longitude = env->location.gnss_longitude; + + ModemMain_SetRegion(env); + + } + + } + + //конец --------------------------Получение данных с GNSS о местоположении-------------------------------------- + //конец --------------------------Получение данных с GNSS о местоположении-------------------------------------- + //конец --------------------------Получение данных с GNSS о местоположении-------------------------------------- + + if (env->isModemStart) { + + // Контроль создания файлов сообщений + RequestSendMessagesModemSlots(env); + + if ((env->pwramp) && (FlagOnUs)) { + // Фиксация уже включенного предусилителя + FlagOnUs = false; + FlagOffUs = true; + + // Включение TX_PWR_En + GpioPinSet(&env->gpios->Power.tx_pwr_en, true); + + // Ожидание инициализации устройства управления питанием + SystemDelayMs(80 * 2); + // Настройка источников питания, если процесс ВДРУГ завершился с ошибкой, + // в следующем цикле настройка питания повторяется + if (sendI2c()) { + +#ifdef DEBUG_EXT_MODEM + LoggerInfoStatic(LOGGER, LOG_SIGN, "Включение предусилителя - успех"); +#endif + // Включена маршрутизация + if (((env->store->nvm.routing) || (getIsSlotsSos(env))) && + (env->store->runtime.almaError == false)) { + SetRoutingRestrictSc(env, env->store->runtime.BannedSAT_ex); + } + + } else { +//#ifdef DEBUG_MODEM + LoggerInfoStatic(LOGGER, LOG_SIGN, "Включение предусилителя - ошибка"); +//#endif + + // Отключение TX_PWR_En + GpioPinSet(&env->gpios->Power.tx_pwr_en, false); + + FlagOnUs = true; + FlagOffUs = false; + } + + // Запуск контроля включения предусилителя + timeStuckGetMs = SystemGetMs(); + startStuckGetMs = true; + + } + + if ((env->pwramp == 0) && (FlagOffUs)) { +#ifdef DEBUG_EXT_MODEM + LoggerInfoStatic(LOGGER, LOG_SIGN, "Отключение предусилителя"); +#endif + + // Отключение TX_PWR_En + GpioPinSet(&env->gpios->Power.tx_pwr_en, false); + + // Фиксация уже выключенного предусилителя + FlagOnUs = true; + FlagOffUs = false; + + if (((env->store->nvm.routing) || (getIsSlotsSos(env))) && (env->store->runtime.almaError == false)) { + SetRoutingRestrictSc(env, env->store->runtime.Settings_General.BannedSAT_v); + } + + // Останов контроля включения предусилителя + startStuckGetMs = false; + + + //начало -------------------------Регистрация--------------------------------------------------------------------- + //начало -------------------------Регистрация--------------------------------------------------------------------- + //начало -------------------------Регистрация--------------------------------------------------------------------- + // Состояние задачи регистрации + if (env->modemWorkingState == MODEM_WORKING_REG) { + // Запрос состояния регистрации + uint8_t status; + result = ModemGetRegStatus(env, &status); + + if (status == 1) { +#ifdef DEBUG_MODEM + LoggerInfoStatic(LOGGER, LOG_SIGN, "Георегистрация завершена успешно"); +#endif + // Состояние георегистрации + env->stateRequest.stateReqReg = StateReqRegNoSendStatus; + + // Запуск задач модема + RunStopTaskModem(env); + } + + } + //начало -------------------------Регистрация--------------------------------------------------------------------- + //начало -------------------------Регистрация--------------------------------------------------------------------- + //начало -------------------------Регистрация--------------------------------------------------------------------- + + + // Контроль удаления файлов Сообщений + env->stateRequest.stateReqDelExtW = StateReqExtForDel; + // Контроль удаления файлов Трассировки + env->stateRequest.stateReqDelExtT = StateReqExtForDel; + // Контроль создания файлов Сообщений + env->stateRequest.stateReqCreateExtW = StateReqExtForCreate; + // Контроль создания файлов Трассировки + env->stateRequest.stateReqCreateExtT = StateReqExtForCreate; + } + + // Проверка включенного предусилителя + if (startStuckGetMs) { + + uint32_t dlStuckGetMs = SystemGetMs() - timeStuckGetMs; + + // Если предусилитель включен больше 2 минут + if (dlStuckGetMs > 120000) { + + char bufText[128]; + bufText[0] = '\0'; + strcat(bufText, "Контроль выключения предусилителя ("); + + char buf[12]; + utoa(env->pwramp, buf, 10); + strcat(bufText, buf); + strcat(bufText, ","); + + utoa(dlStuckGetMs, buf, 10); + strcat(bufText, buf); + strcat(bufText, ","); + + utoa(timeStuckGetMs, buf, 10); + strcat(bufText, buf); + strcat(bufText, ")"); + + LoggerInfo(LOGGER, LOG_SIGN, bufText, strlen(bufText)); + startStuckGetMs = false; + // Отключение TX_PWR_En + GpioPinSet(&env->gpios->Power.tx_pwr_en, false); + } + } + + // Прием пакетов от модема + if (env->state > 0) { + + // Контроль файлов в приеме на дату + controlFragIn(env->fs, env->store, env->rtcIo); + + // Контроль файлов на приеме + controlFiles(env->fs, "*", (char *) dir_frag_inbox); + + // Запрос слотов приема + RequestModemRecvSlots(env); + + // Контроль удаления файлов Сообщений + env->stateRequest.stateReqDelExtW = StateReqExtForDel; + // Контроль удаления файлов Трассировки + env->stateRequest.stateReqDelExtT = StateReqExtForDel; + // Контроль создания файлов Сообщений + env->stateRequest.stateReqCreateExtW = StateReqExtForCreate; + // Контроль создания файлов Трассировки + env->stateRequest.stateReqCreateExtT = StateReqExtForCreate; + + } + + //начало -------------------------Альманахи--------------------------------------------------------------------- + //начало -------------------------Альманахи--------------------------------------------------------------------- + //начало -------------------------Альманахи--------------------------------------------------------------------- + if (env->stateRequest.stateReqAlmaWebRunStop == StateReqAlmaWebRun) { + env->stateRequest.stateReqAlmaWebRunStop = StateReqAlmaWebRunInit; + env->stateRequest.stateReqAlma = StateReqAlmaSendStatus; + // Запуск задач модема + RunStopTaskModem(env); + } + + if (env->stateRequest.stateReqAlmaWebRunStop == StateReqAlmaWebStop) { + env->stateRequest.stateReqAlmaWebRunStop = StateReqAlmaWebRunInit; + AlmaStop(env); + env->stateRequest.stateReqAlma = StateReqAlmaNoSendStatus; + // Запуск задач модема + RunStopTaskModem(env); + } + //конец -------------------------Альманахи---------------------------------------------------------------------- + //конец -------------------------Альманахи---------------------------------------------------------------------- + //конец -------------------------Альманахи---------------------------------------------------------------------- + } + + + SystemDelayMs(100); + } + +} + + +void ModemMain_StartThread(tModemMain *env) { + if (!env->thread.id) { + env->thread.id = osThreadNew((osThreadFunc_t) (ModemMain_Thread), (void *) (env), &env->thread.attr); + } else { + osThreadResume(env->thread.id); + } +} diff --git a/Src/ModemReceive.c b/Src/ModemReceive.c new file mode 100644 index 0000000..841b037 --- /dev/null +++ b/Src/ModemReceive.c @@ -0,0 +1,1059 @@ +// +// Created by cfif on 21.04.23. +// +#include "ModemMain.h" +#include "ModemReceiveFunc.h" +#include "ModemSendFunc.h" +#include "ModemAlmanah.h" +#include "ModemGonecFunc.h" +#include "ModemSend.h" +#include "httpd_types.h" +#include "GonetsCrcs.h" + +#define LOGGER env->logger +#define LOG_SIGN "GONEC" + +// Поиск отправляемого сообщения +uint32_t +findOutKvit(tModemMain *env, uint32_t numberSender, uint32_t numberMessage, uint32_t dateDay, uint32_t dateMon) { + FRESULT fr; + DIR dj; + FILINFO fno; + tFileSendInfo fileSendInfo; + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + + fr = f_findfirst_i(env->fs, &dj, &fno, dir_rep_out, "*.INF"); + + while (fr == FR_OK && fno.fname[0]) { + + uint32_t idFile = atoi(fno.fname); + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_rep_out, idFile); + + bool resultFileInfo = readSendFileInfo(env->fs, &fileSendInfo, path_dir_info_fileName); + if (resultFileInfo == false) continue; + + if ((numberSender == (uint32_t) atoi(fileSendInfo.to)) && (numberMessage == fileSendInfo.mnum) && + (dateDay == fileSendInfo.dateDay) && (dateMon == fileSendInfo.dateMon)) { + fr = f_closedir_i(env->fs, &dj); + + return fileSendInfo.mnum; + } + + fr = f_findnext_i(env->fs, &dj, &fno); + } + fr = f_closedir_i(env->fs, &dj); + + return 0; +} + +// Создание и запись в файл +bool createFileKvitOut(tModemMain *env, uint32_t lenPacketKvit, uint32_t numberSender, + uint32_t KVT_numberMessage, + uint32_t KVT_dataCreationMon, + uint32_t KVT_dataCreationDay) { + + FIL file; + FRESULT fr; + + char real_filename[MAX_LEN_PATH_FS]; + + char bufTemp[12]; + + char bufIdFileOutBox[12]; + char bufWithPrefixIdFileOutBox[12]; + + uint32_t leftPacketKvit = lenPacketKvit; + uint32_t posPacketKvit = 0; + + while (1) { + + // Четное количество смещений квитанций + TRANS_MIN(leftPacketKvit, LEN_TRANS_PACKET - 10); + + ++env->store->nvm.maxId_OutBox; + if (env->store->nvm.maxId_OutBox > 32767) + env->store->nvm.maxId_OutBox = 1; + + DeviceStorageCounterIni_Dump(env->store); + + utoa(env->store->nvm.maxId_OutBox, bufIdFileOutBox, 10); + toAddPrefixStr(bufWithPrefixIdFileOutBox, bufIdFileOutBox, 5); + + real_filename[0] = '\0'; + strcat(real_filename, dir_outbox); + strcat(real_filename, bufWithPrefixIdFileOutBox); + strcat(real_filename, ".OTM"); + + // Запись заголовка в файл + char BufFileWrite[512]; + BufFileWrite[0] = '\0'; + strcat(BufFileWrite, &real_filename[2]); + + time_t timestamp = 0; + env->rtcIo->get(&env->rtcIo, ×tamp); + timestamp += env->store->nvm.Settings_General.GMTcorr_v * 3600; + strcat(BufFileWrite, "&timec="); + getDataTime(×tamp, &BufFileWrite[strlen(BufFileWrite)], sizeof(BufFileWrite)); + + strcat(BufFileWrite, "&from="); + utoa(env->store->nvm.Settings_General.ATnum_v, &BufFileWrite[strlen(BufFileWrite)], 10); + + strcat(BufFileWrite, "&mnum="); + strcat(BufFileWrite, bufIdFileOutBox); + + strcat(BufFileWrite, "&to="); + utoa(numberSender, bufTemp, 10); + strcat(BufFileWrite, bufTemp); + + strcat(BufFileWrite, "&urgency=0"); + + strcat(BufFileWrite, "&kvt_num="); + utoa(KVT_numberMessage, bufTemp, 10); + strcat(BufFileWrite, bufTemp); + + strcat(BufFileWrite, "&kvt_mon="); + utoa(KVT_dataCreationMon, bufTemp, 10); + strcat(BufFileWrite, bufTemp); + + strcat(BufFileWrite, "&kvt_day="); + utoa(KVT_dataCreationDay, bufTemp, 10); + strcat(BufFileWrite, bufTemp); + + strcat(BufFileWrite, "&type=2"); + strcat(BufFileWrite, "&sos=0"); + + + strcat(BufFileWrite, "&chSv="); + utoa(1, bufTemp, 10); + strcat(BufFileWrite, bufTemp); + + strcat(BufFileWrite, "&subj=kvitout"); + + strcat(BufFileWrite, "&kvs=000"); + + + strcat(BufFileWrite, "&msg="); +// strcat(BufFileWrite, "kvitin.kvt"); + + fr = f_open_i(env->fs, &file, (TCHAR *) real_filename, FA_WRITE | FA_CREATE_ALWAYS); + if (fr) return false; + + UINT bytes_written; + fr = f_write_i(env->fs, &file, BufFileWrite, strlen(BufFileWrite), &bytes_written); + +// bufTemp[0] = '\0'; +// bufTemp[1] = '\0'; +// fr = f_write_i(env->fs, &file, bufTemp, 2, &bytes_written); + + fr = f_write_i(env->fs, &file, &env->bufSendPacketKvitin[posPacketKvit], leftPacketKvit, &bytes_written); + + fr = f_close_i(env->fs, &file); + + if (leftPacketKvit < (LEN_TRANS_PACKET - sizeof(tStructTransportKvitPacket))) + break; + + ++posPacketKvit; + } + return true; +} + + +// Создание и запись в файл +bool createFileKvitIn(tModemMain *env, + uint32_t numberSender, + uint32_t KVT_numberMessage, + uint32_t KVT_dataCreationMon, + uint32_t KVT_dataCreationDay) { + + FIL file; + FRESULT fr; + + char real_filename[MAX_LEN_PATH_FS]; + + char bufTemp[12]; + + char bufIdFileInBox[12]; + char bufWithPrefixIdFileInBox[12]; + + ++env->store->nvm.maxId_InBox; + if (env->store->nvm.maxId_InBox > 32767) + env->store->nvm.maxId_InBox = 1; + + DeviceStorageCounterIni_Dump(env->store); + + utoa(env->store->nvm.maxId_InBox, bufIdFileInBox, 10); + toAddPrefixStr(bufWithPrefixIdFileInBox, bufIdFileInBox, 5); + + real_filename[0] = '\0'; + strcat(real_filename, dir_kvitin); + strcat(real_filename, bufWithPrefixIdFileInBox); + strcat(real_filename, ".ITM"); + + // Запись заголовка в файл + char BufFileWrite[512]; + BufFileWrite[0] = '\0'; + + strcat(BufFileWrite, "&from="); + utoa(numberSender, bufTemp, 10); + strcat(BufFileWrite, bufTemp); + + strcat(BufFileWrite, "&kvt_num="); + utoa(KVT_numberMessage, bufTemp, 10); + strcat(BufFileWrite, bufTemp); + + strcat(BufFileWrite, "&kvt_mon="); + utoa(KVT_dataCreationMon, bufTemp, 10); + strcat(BufFileWrite, bufTemp); + + strcat(BufFileWrite, "&kvt_day="); + utoa(KVT_dataCreationDay, bufTemp, 10); + strcat(BufFileWrite, bufTemp); + + uint32_t crc32 = 0xFFFFFFFF; + crc32 = GonetsCrc32_noreverse_update(&env->bufReceivedPacket[sizeof(tStructTransportKvitPacket)], + env->bufReceivedPacketLen - sizeof(tStructTransportKvitPacket), crc32); + crc32 = GonetsCrc32_noreverse_finish(crc32); + + strcat(BufFileWrite, "&kvt_crc="); + utoa(crc32, bufTemp, 10); + strcat(BufFileWrite, bufTemp); + + strcat(BufFileWrite, "&chSv="); + utoa(1, bufTemp, 10); + strcat(BufFileWrite, bufTemp); + + strcat(BufFileWrite, "&subj=kvitin"); + + fr = f_open_i(env->fs, &file, (TCHAR *) real_filename, FA_WRITE | FA_CREATE_ALWAYS); + if (fr) return false; + + UINT bytes_written; + fr = f_write_i(env->fs, &file, BufFileWrite, strlen(BufFileWrite), &bytes_written); + + fr = f_close_i(env->fs, &file); + + return true; +} + + +bool HandlerModemKvitPaket(tModemMain *env) { + FRESULT fr; + FILINFO fno; + bool result; + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + tStructTransportKvitPacket *packet = (tStructTransportKvitPacket *) env->bufReceivedPacket; + + +#ifdef DEBUG_EXT_MODEM + char strMessage[128]; + strMessage[0] = '\0'; + strcat(strMessage, "Принята квитанция на сообщение номер "); + char buf[12]; + utoa(packet->numberMessage, buf, 10); + strcat(strMessage, buf); + strcat(strMessage, " от АТ-"); + utoa(packet->numberSender, buf, 10); + strcat(strMessage, buf); + LoggerInfo(LOGGER, "GONEC", strMessage, strlen(strMessage)); +#endif + + + uint32_t idFile = findOutKvit(env, packet->numberSender, packet->numberMessage, + packet->dateCreateTransportPacketDay, + packet->dateCreateTransportPacketMon); + + if (idFile == 0) { +#ifdef DEBUG_EXT_MODEM + strMessage[0] = '\0'; + strcat(strMessage, "Сборка квитанции. Сообщение не найдено. Квитанция игнорируется."); + LoggerInfo(LOGGER, "GONEC", strMessage, strlen(strMessage)); +#endif + return false; + } + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_rep_out, idFile); + + + fr = f_stat(path_dir_info_fileName, &fno); + if (fr == FR_OK) { + + tFileSendInfo fileSendInfo; + + result = readSendFileInfo(env->fs, &fileSendInfo, path_dir_info_fileName); + if (result == false) + return false; + + + uint32_t sizeDataKvit = (env->bufReceivedPacketLen - sizeof(tStructTransportKvitPacket)) / 3; + tStructTransportKvitPacketData *dataKvit = + (tStructTransportKvitPacketData *) &env->bufReceivedPacket[sizeof(tStructTransportKvitPacket)]; + + if (((env->bufReceivedPacketLen - sizeof(tStructTransportKvitPacket)) % 3) != 0) { +#ifdef DEBUG_EXT_MODEM + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Сборка квитанции. Не корректная длина квитанции. Квитанция игнорируется."); +#endif + return false; + } + + uint32_t offset1 = 0; + for (uint32_t i = 0; i < sizeDataKvit; ++i) { + uint32_t offset2 = dataKvit->offsetKvitPacket; + + if ((offset2 > offset1) || ((offset1 == 0) && (offset2 == 0))) { + offset1 = offset2; + } else { +#ifdef DEBUG_EXT_MODEM + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Сборка квитанции. Смещения идут не по возрастанию. Квитанция игнорируется."); +#endif + return false; + } + ++dataKvit; + } + + + // Получение информации о принятых файлах квитанции + if (checkNumSentBoxKvitin(env->fs, env->bufReceivedPacket, + env->bufReceivedPacketLen, + packet->numberSender, + packet->numberMessage, + packet->dateCreateTransportPacketMon, + packet->dateCreateTransportPacketDay)) { + + +#ifdef DEBUG_EXT_MODEM + char strMessage[128]; + strMessage[0] = '\0'; + strcat(strMessage, "Квитанция на сообщение номер "); + char buf[12]; + utoa(packet->numberMessage, buf, 10); + strcat(strMessage, buf); + strcat(strMessage, " от АТ-"); + utoa(packet->numberSender, buf, 10); + strcat(strMessage, buf); + strcat(strMessage, " была принята ранее"); + LoggerInfo(LOGGER, "GONEC", strMessage, strlen(strMessage)); +#endif + + return false; + } + + + createFileKvitIn(env, + packet->numberSender, + packet->numberMessage, + packet->dateCreateTransportPacketMon, + packet->dateCreateTransportPacketDay + ); + + + dataKvit = (tStructTransportKvitPacketData *) &env->bufReceivedPacket[sizeof(tStructTransportKvitPacket)]; + + memset(env->structReceiveOffset, 0, sizeof(env->structReceiveOffset)); + + uint32_t len = 0; + for (uint32_t i = 0; i < sizeDataKvit; ++i) { + if ((i % 2) == 0) { + env->structReceiveOffset[len].receive = dataKvit->offsetKvitPacket; + } else { + env->structReceiveOffset[len].no_receive = dataKvit->offsetKvitPacket; + ++len; + } + ++dataKvit; + } + + + if (sizeDataKvit == 1) { + // Квитанция - Все пакеты приняты + if (env->structReceiveOffset[0].receive == 0) { + + fileSendInfo.isSendAll = 1; + + // Создание info файла + result = writeSendFileInfo(env->fs, &fileSendInfo, path_dir_info_fileName); + if (result == false) + return false; + + ToSentFiles(env, &fileSendInfo, path_dir_rep_fileName, path_dir_mask_fileName, path_dir_info_fileName); + + } else { + // Запись в файл маски признака не отправленного пакета + result = editMaskPacketTransport(env->fs, 0, env->structReceiveOffset[0].receive, + path_dir_mask_fileName, + BUF_NO_RECEIVE_KV); + if (result == false) + return false; + + + fileSendInfo.crc32_MSK = CrcFileFs(env->fs, path_dir_mask_fileName); + // Создание info файла + result = writeSendFileInfo(env->fs, &fileSendInfo, path_dir_info_fileName); + if (result == false) + return false; + + } + } else { + + for (uint32_t i = 0; i < len; ++i) { + + uint32_t no_receive_len; + if (env->structReceiveOffset[i + 1].receive != 0) { + no_receive_len = env->structReceiveOffset[i + 1].receive - env->structReceiveOffset[i].no_receive; + } else { + no_receive_len = fileSendInfo.sizeFileRep - env->structReceiveOffset[i].no_receive; + } + + // Запись в файл маски признака не отправленного пакета + result = editMaskPacketTransport(env->fs, env->structReceiveOffset[i].no_receive, + no_receive_len, + path_dir_mask_fileName, + BUF_NO_RECEIVE_KV); + if (result == false) + return false; + + } + + fileSendInfo.crc32_MSK = CrcFileFs(env->fs, path_dir_mask_fileName); + // Создание info файла + result = writeSendFileInfo(env->fs, &fileSendInfo, path_dir_info_fileName); + if (result == false) + return false; + } + + } + return true; +} + + +// Поиск принятого сообщения +uint32_t +findIn(tModemMain *env, uint32_t numberSender, uint32_t numberMessage, uint32_t dateDay, uint32_t dateMon) { + FRESULT fr; + DIR dj; + FILINFO fno; + tFileRecvInfo fileRecvInfo; + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + + fr = f_findfirst_i(env->fs, &dj, &fno, dir_frag_inbox, "*.INF"); + + while (fr == FR_OK && fno.fname[0]) { + + uint32_t idFile = atoi(fno.fname); + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_frag_inbox, idFile); + + bool resultFileInfo = readRecvFileInfo(env->fs, &fileRecvInfo, path_dir_info_fileName); + if (resultFileInfo == false) { + fr = f_findnext_i(env->fs, &dj, &fno); + continue; + } + + if ((numberSender == fileRecvInfo.from) && (numberMessage == fileRecvInfo.mnumFrom) && + (dateDay == fileRecvInfo.dateDay) && (dateMon == fileRecvInfo.dateMon)) { + fr = f_closedir_i(env->fs, &dj); + + return fileRecvInfo.mnum; + } + + + fr = f_findnext_i(env->fs, &dj, &fno); + } + fr = f_closedir_i(env->fs, &dj); + + return 0; +} + +// Обработчик принятых пакетов сообщения - Запись пакетов полученных из модема +bool HandlerModemPaketWrite(tModemMain *env, uint32_t id) { + FRESULT fr; + FILINFO fno; + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + tStructTransportPacket *packet = (tStructTransportPacket *) env->bufReceivedPacket; + +#ifdef DEBUG_EXT_MODEM + char buf[12]; + char strMessage[128]; + + strMessage[0] = '\0'; + + strcat(strMessage, "Извлечение пакета номер "); + + utoa(packet->numberMessage, buf, 10); + strcat(strMessage, buf); + strcat(strMessage, ", смещение "); + utoa(packet->offsetPacket, buf, 10); + strcat(strMessage, buf); + + strcat(strMessage, " от АТ-"); + utoa(packet->numberSender, buf, 10); + strcat(strMessage, buf); + + + LoggerInfo(LOGGER, LOG_SIGN, strMessage, strlen(strMessage)); +#endif + + + // Получение информации о принятых файлах + if (checkNumSentBox(env->fs, env->rtcIo, packet->numberMessage, packet->numberSender)) { + +#ifdef DEBUG_EXT_MODEM + strMessage[0] = '\0'; + strcat(strMessage, "Пакет сообщения номер "); + utoa(packet->numberMessage, buf, 10); + strcat(strMessage, buf); + + strcat(strMessage, ", смещение "); + utoa(packet->offsetPacket, buf, 10); + strcat(strMessage, buf); + + + strcat(strMessage, " от АТ-"); + utoa(packet->numberSender, buf, 10); + strcat(strMessage, buf); + + strcat(strMessage, " был принят ранее"); + + LoggerInfo(LOGGER, "GONEC", strMessage, strlen(strMessage)); +#endif + + return true; + } + + +// LoggerInfoStatic(LOGGER, LOG_SIGN, "Поиск сообщения"); + + uint32_t idFile = findIn(env, packet->numberSender, packet->numberMessage, packet->dateCreateTransportPacketDay, + packet->dateCreateTransportPacketMon); + + + if (idFile == 0) { + ++env->store->nvm.maxId_InBox; + if (env->store->nvm.maxId_InBox > 32767) + env->store->nvm.maxId_InBox = 1; + DeviceStorageCounterIni_Dump(env->store); + + idFile = env->store->nvm.maxId_InBox; + } + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_frag_inbox, idFile); + + + fr = f_stat(path_dir_rep_fileName, &fno); + + bool result; + + bool isCrcUpdate; + + if (fr) { +// LoggerInfoStatic(LOGGER, LOG_SIGN, "Создание нового сообщения"); + + // Прием пакетов - Создание файлов + result = isReceivedCreate(env->fs, idFile, env->store->nvm.Settings_General.ATnum_v, packet, + env->bufReceivedPacket, env->bufReceivedPacketLen, + path_dir_info_fileName, path_dir_mask_fileName, + path_dir_rep_fileName, &isCrcUpdate); + + } else { +// LoggerInfoStatic(LOGGER, LOG_SIGN, "Редактирование старого сообщения"); + + // Прием пакетов - Добавление файлов + result = isReceivedAppend(env->fs, packet, env->bufReceivedPacket, env->bufReceivedPacketLen, + path_dir_info_fileName, path_dir_mask_fileName, + path_dir_rep_fileName, &isCrcUpdate); + } + + +// LoggerInfoStatic(LOGGER, LOG_SIGN, "Получение информации о изменении файла маски"); + + // Получение информации о изменении файла маски + if (isCrcUpdate == false) { +#ifdef DEBUG_EXT_MODEM + strMessage[0] = '\0'; + strcat(strMessage, "Пакет сообщения номер "); + utoa(packet->numberMessage, buf, 10); + strcat(strMessage, buf); + + strcat(strMessage, ", смещение "); + utoa(packet->offsetPacket, buf, 10); + strcat(strMessage, buf); + + strcat(strMessage, " от АТ-"); + utoa(packet->numberSender, buf, 10); + strcat(strMessage, buf); + + strcat(strMessage, " был принят ранее (не было изменений в сообщении)"); + + LoggerInfo(LOGGER, "GONEC", strMessage, strlen(strMessage)); +#endif + + return true; + } + + + env->packetDataForKvitin[id].isEnabled = true; + env->packetDataForKvitin[id].isCrcUpdate = isCrcUpdate; + env->packetDataForKvitin[id].numberMessage = packet->numberMessage; + env->packetDataForKvitin[id].dataType = packet->dataType; + env->packetDataForKvitin[id].numberSender = packet->numberSender; + env->packetDataForKvitin[id].dataCreationDay = packet->dateCreateTransportPacketDay; + env->packetDataForKvitin[id].dataCreationMon = packet->dateCreateTransportPacketMon; + + + return result; +} + + + +// Обработчик принятых пакетов сообщения - Создание файлов квитанций +bool HandlerModemPaketKvitin(tModemMain *env) { + FRESULT fr; + FILINFO fno; + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + if (env->bufReceivedPacketLen > 0) { + if (env->bufReceivedPacket[0] == 239) + return true; + } + +// LoggerInfoStatic(LOGGER, LOG_SIGN, "Получение информации о квитанциях"); + + // Пакет уже квитировался + tPacketDataForKvitin isWasPacketDataForKvitin[16]; + int isWasPacketDataForKvitinCount = 0; + + for (int i = 0; i < 16; ++i) { + + if (env->packetDataForKvitin[i].isEnabled) { + + uint32_t idFile = findIn(env, env->packetDataForKvitin[i].numberSender, + env->packetDataForKvitin[i].numberMessage, + env->packetDataForKvitin[i].dataCreationDay, + env->packetDataForKvitin[i].dataCreationMon); + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_frag_inbox, idFile); + + + fr = f_stat(path_dir_info_fileName, &fno); + if (fr == FR_OK) { + + uint32_t lenPacketKvit; + bool isAll; + bool result; + + result = Kvitin(env->fs, env->rtcIo, + env->packetDataForKvitin[i].numberMessage, + env->store->nvm.Settings_General.ATnum_v, path_dir_info_fileName, + path_dir_mask_fileName, env->bufSendPacketKvitin, + &lenPacketKvit, &isAll); + if (result == false) { + return false; + } + + + // Пакет квитируемого сообщения + if (env->packetDataForKvitin[i].dataType == 0) { + + bool isCreateKvit = true; + for (int j = 0; j < isWasPacketDataForKvitinCount; ++j) { + + if ((isWasPacketDataForKvitin[j].numberMessage == env->packetDataForKvitin[i].numberMessage) && + (isWasPacketDataForKvitin[j].numberSender == env->packetDataForKvitin[i].numberSender) && + (isWasPacketDataForKvitin[j].dataCreationDay == + env->packetDataForKvitin[i].dataCreationDay) && + (isWasPacketDataForKvitin[j].dataCreationMon == + env->packetDataForKvitin[i].dataCreationMon)) { + isCreateKvit = false; + break; + } + } + + if ((isCreateKvit) && (env->packetDataForKvitin[i].isCrcUpdate)) { + createFileKvitOut(env, lenPacketKvit, env->packetDataForKvitin[i].numberSender, + env->packetDataForKvitin[i].numberMessage, + env->packetDataForKvitin[i].dataCreationMon, + env->packetDataForKvitin[i].dataCreationDay + ); + // Создание файлов уровня представления + //ModemMain_CreateOutFiles(env, TYPE_FILE_KVITIN, env->store->nvm.Settings_General.GMTcorr_v); + + env->stateRequest.stateReqCreateExtW = StateReqExtForCreate; + env->rtcIo->get(env->rtcIo, &env->eventWebState.EVENT_OUTBOX); + // Удаление всех файлов квитанций + //delDirFileFs(env->fs, (char *) dir_kvitin); + + isWasPacketDataForKvitin[isWasPacketDataForKvitinCount].numberMessage = env->packetDataForKvitin[i].numberMessage; + isWasPacketDataForKvitin[isWasPacketDataForKvitinCount].numberSender = env->packetDataForKvitin[i].numberSender; + isWasPacketDataForKvitin[isWasPacketDataForKvitinCount].dataCreationDay = env->packetDataForKvitin[i].dataCreationDay; + isWasPacketDataForKvitin[isWasPacketDataForKvitinCount].dataCreationMon = env->packetDataForKvitin[i].dataCreationMon; + ++isWasPacketDataForKvitinCount; + + } + } + + + if (isAll) { +/* + // Пакет квитируемого сообщения + if (env->packetDataForKvitin[i].dataType == 0) { + createFileKvitin(env, lenPacketKvit, env->packetDataForKvitin[i].numberSender); + // Создание файлов уровня представления + //ModemMain_CreateOutFiles(env, TYPE_FILE_KVITIN, env->store->nvm.Settings_General.GMTcorr_v); + + env->stateRequest.stateReqCreateExtW = StateReqExtForCreate; + env->rtcIo->get(env->rtcIo, &env->eventWebState.EVENT_OUTBOX); + // Удаление всех файлов квитанций + //delDirFileFs(env->fs, (char *) dir_kvitin); + } +*/ + // Перенос собранного фрагментированного файла в хранилище принятых сообщений inbox + md5a_starts(&env->md5ctx_r); + tReceiveBuildResult resultBuild = renameFromFrgToInBox(env->fs, &env->GonetsReedSalmonParity4, + &env->md5ctx_r, idFile, env->rtcIo, + path_dir_info_fileName, + path_dir_rep_fileName, env->logger); + + if (resultBuild == RECV_ERROR_CRC) { +#ifdef DEBUG_MODEM + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Сборка сообщения. Обнаружена ошибка crc в заголовке сообщения"); +#endif + + // return false; + } + + if (resultBuild == RECV_ERROR) { +#ifdef DEBUG_MODEM + + LoggerInfoStatic(LOGGER, LOG_SIGN, "Сборка сообщения. Обнаружена ошибка"); +#endif + + // return false; + } + + fr = f_unlink_i(env->fs, path_dir_rep_fileName); + fr = f_unlink_i(env->fs, path_dir_mask_fileName); + fr = f_unlink_i(env->fs, path_dir_info_fileName); + + env->rtcIo->get(&env->rtcIo, &env->eventWebState.EVENT_INBOX); + + } + + env->packetDataForKvitin[i].isEnabled = false; + } + } + } + return true; +} + + +bool HandlerModemKvitPaketDiscard(tModemMain *env) { + FRESULT fr; + DIR dj; + FILINFO fno; + bool result; + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + tStructTransportKvitPacket *structTransportKvitPacket = (tStructTransportKvitPacket *) env->bufReceivedPacket; + + uint32_t idFile = findOutKvit(env, structTransportKvitPacket->numberSender, + structTransportKvitPacket->numberMessage, + structTransportKvitPacket->dateCreateTransportPacketDay, + structTransportKvitPacket->dateCreateTransportPacketMon); + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_rep_out, idFile); + + fr = f_unlink_i(env->fs, path_dir_rep_fileName); + fr = f_unlink_i(env->fs, path_dir_mask_fileName); + fr = f_unlink_i(env->fs, path_dir_info_fileName); + + env->stateRequest.stateReqCreateExtW = StateReqExtForCreate; + + return true; +} + +// Создание файла квитанции входящего сообщения +bool createFileKvitinInbox(tModemMain *env) { + + tStructTransportPacket *packet = (tStructTransportPacket *) env->bufReceivedPacket; + + uint32_t sizeDataKvit = (env->bufReceivedPacketLen - sizeof(tStructTransportKvitPacket)) / 3; + tStructTransportKvitPacketData *dataKvit = + (tStructTransportKvitPacketData *) &env->bufReceivedPacket[sizeof(tStructTransportKvitPacket)]; + + if (sizeDataKvit == 1) { + + // Квитанция - Все пакеты приняты + if (dataKvit->offsetKvitPacket == 0) { + + char str[128]; + str[0] = '\0'; + + char buf[9]; + + strcat(str, "&from="); + utoa(packet->numberSender, buf, 10); + strcat(str, buf); + + strcat(str, "&to="); + utoa(env->store->nvm.Settings_General.ATnum_v, buf, 10); + strcat(str, buf); + + strcat(str, "&chSv=1"); + + utoa(packet->numberMessage, buf, 10); + strcat(str, "&subj=KVITIN&msg=Доставлено сообщение № "); + strcat(str, buf); + + char path_in_dirDate[MAX_LEN_PATH_FS]; + path_in_dirDate[0] = '\0'; + char path_in_fileName[MAX_LEN_PATH_FS]; + path_in_fileName[0] = '\0'; + + // Путь к файлу принятых сообщений + getDateStr(env->rtcIo, path_in_dirDate, sizeof(path_in_dirDate)); + strcat(path_in_fileName, dir_inbox); + strcat(path_in_fileName, path_in_dirDate); + strcat(path_in_fileName, "/"); + + FRESULT fr; + FIL file; + fr = f_mkdir_i(env->fs, path_in_fileName); + + if (fr) { + if (fr != FR_EXIST) + return false; + } + + ++env->store->nvm.maxId_InBox; + if (env->store->nvm.maxId_InBox > 32767) + env->store->nvm.maxId_InBox = 1; + DeviceStorageCounterIni_Dump(env->store); + + uint32_t idFile = env->store->nvm.maxId_InBox; + + // Имя файла в принятых сообщениях + char bufIdFileInBox[12]; + char bufWithPrefixIdFileInBox[12]; + + utoa(idFile, bufIdFileInBox, 10); + + toAddPrefixStr(bufWithPrefixIdFileInBox, bufIdFileInBox, 5); + strcat(path_in_fileName, bufWithPrefixIdFileInBox); + strcat(path_in_fileName, ".ITM"); + + + fr = f_open_i(env->fs, &file, (TCHAR *) path_in_fileName, FA_WRITE | FA_CREATE_ALWAYS); + if (fr) { + return false; + } + + UINT bytes_written; + fr = f_write_i(env->fs, &file, str, strlen(str), &bytes_written); + + fr = f_close_i(env->fs, &file); + + + } + } +/* + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + tStructTransportKvitPacket *structTransportKvitPacket = (tStructTransportKvitPacket *) env->bufReceivedPacket; + + uint32_t idFile = findOutKvit(env, structTransportKvitPacket->numberSender, + structTransportKvitPacket->numberMessage, + structTransportKvitPacket->dateCreateTransportPacketDay, + structTransportKvitPacket->dateCreateTransportPacketMon); + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_rep_out, idFile); + + FRESULT fr; + + fr = f_unlink_i(env->fs, path_dir_rep_fileName); + fr = f_unlink_i(env->fs, path_dir_mask_fileName); + fr = f_unlink_i(env->fs, path_dir_info_fileName); + +*/ + return true; +} + + +bool HandlerModemInPaket(tModemMain *env, uint32_t id) { + bool result; + + // Пакет альманаха + if (env->bufReceivedPacket[0] == 239) { + + result = writeAlmanah(env); + + env->rtcIo->get(&env->rtcIo, &env->eventWebState.EVENT_ALMA); + + env->stateRequest.stateReqAlma = StateReqAlmaReady; + + return result; + + } else { + + tStructTransportPacket *structTransportPacket = (tStructTransportPacket *) env->bufReceivedPacket; + +// if (structTransportPacket->versionProtocol != 1) +// return false; + if (structTransportPacket->dateCreateTransportPacketDay == 0) { +#ifdef DEBUG_EXT_MODEM + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Сборка сообщения. В транспортном пакете получено некорректное значение дня. Пакет игнорируется."); +#endif + + return false; + } + + if ((structTransportPacket->dateCreateTransportPacketMon == 0) || + (structTransportPacket->dateCreateTransportPacketMon > 12)) { +#ifdef DEBUG_EXT_MODEM + LoggerInfoStatic(LOGGER, LOG_SIGN, + "Сборка сообщения. В транспортном пакете получено некорректное значение месяца. Пакет игнорируется."); +#endif + return false; + } + + // Пакет квитируемого сообщения + if ((structTransportPacket->dataType == 0) || (structTransportPacket->dataType == 12)) { + + // -------------------------- Обработчик принятых пакетов сообщения --------------------------------------- + result = HandlerModemPaketWrite(env, id); + // -------------------------------------------------------------------------------------------------------- + +#ifdef DEBUG_EXT_MODEM + if (result == false) { + char bufText[128]; + char buf[12]; + + bufText[0] = '\0'; + + strcat(bufText, "Ошибка извлечения пакета номер "); + + utoa(structTransportPacket->numberMessage, buf, 10); + strcat(bufText, buf); + strcat(bufText, ", смещение "); + utoa(structTransportPacket->offsetPacket, buf, 10); + strcat(bufText, buf); + + strcat(bufText, " от АТ-"); + utoa(structTransportPacket->numberSender, buf, 10); + strcat(bufText, buf); + + + LoggerInfo(LOGGER, LOG_SIGN, bufText, strlen(bufText)); + } +#endif + + + return result; + } + + // Пакет не квитируемого сообщения +// if (structTransportPacket->dataType == 12) { + // Обработчик принятых пакетов сообщения +// result = HandlerModemPaketWrite(env, id); +// return result; +// } + + // Квитанция на сообщение + if (structTransportPacket->dataType == 8) { + result = HandlerModemKvitPaket(env); + if (result) + result = createFileKvitinInbox(env); + return result; + } + // Квитанция - сборка прекращена + if (structTransportPacket->dataType == 4) { + result = HandlerModemKvitPaketDiscard(env); + return true; + } + } + + + return false; +} + + +//начало -------------------------Запрос приемных слотов на модем-------------------------------------------------------- +//начало -------------------------Запрос приемных слотов на модем-------------------------------------------------------- +//начало -------------------------Запрос приемных слотов на модем-------------------------------------------------------- +void RequestModemRecvSlots(tModemMain *env) { + bool result; + + // Запрос слотов приема + result = ModemGetRecvSlot(env, &env->modemStatus.id[16], (uint8_t *) &env->modemStatus.status[16], 16); + + + // Обработчик принятых пакетов из модема + for (int id = 16; id < 32; ++id) { + if (env->modemStatus.status[id] == SLOT_READY_READ_OR_WRITE) { + + // Чтение данных из пакета + result = SlotRecvRead(env, id - 16 + 1); + + if (result) { + result = HandlerModemInPaket(env, id - 16); + } + + if (result) { + // Очистка данных из пакета + char buffer[12]; + utoa(id - 16 + 1, buffer, 10); + + result = SlotRecvClear(env, buffer); + } + + } + + } + + HandlerModemPaketKvitin(env); + +} +//конец --------------------------Запрос приемных слотов на модем-------------------------------------------------------- +//конец --------------------------Запрос приемных слотов на модем-------------------------------------------------------- +//конец --------------------------Запрос приемных слотов на модем-------------------------------------------------------- \ No newline at end of file diff --git a/Src/ModemReceiveFunc.c b/Src/ModemReceiveFunc.c new file mode 100644 index 0000000..ddb5a6e --- /dev/null +++ b/Src/ModemReceiveFunc.c @@ -0,0 +1,1415 @@ +// +// Created by cfif on 21.02.23. +// +#include "ModemReceiveFunc.h" +#include "GonetsCrcs.h" +#include "httpd_base_func.h" + +extern uint8_t bufFreeOperation[1500]; +extern uint8_t bufFreeOperationKV[1500]; +extern uint8_t bufFillOperation[1500]; + +//const uint8_t bufFreeOperation[32768]; +//extern const uint8_t bufFreeOperationKV[2048]; +//extern const uint8_t bufFillOperation[2048]; + +/* +// Создание имени файла из транспортного пакета +void +createFileFragInbox(char *path, uint32_t dateCreateTransportPacket, uint32_t numberSender, uint32_t numberMessage, char t, char *ext) { + char buf[12]; + char bufWithPrefix[18]; + + utoa(dateCreateTransportPacket, buf, 10); + toAddPrefixStr(bufWithPrefix, buf, 5); + strcat(path, bufWithPrefix); + strcat(path, "_"); + + utoa(numberSender, buf, 10); + toAddPrefixStr(bufWithPrefix, buf, 5); + strcat(path, bufWithPrefix); + strcat(path, "_"); + + utoa(numberMessage, buf, 10); + toAddPrefixStr(bufWithPrefix, buf, 5); + strcat(path, bufWithPrefix); + + buf[0] = t; + buf[1] = '\0'; + strcat(path, buf); + + strcat(path, ext); + +} +*/ + +// Создание имени файла +void createFileNameForId(char *path, char *basePath, uint32_t id, char *ext) { + char buf[12]; + char bufWithPrefix[18]; + + path[0] = '\0'; + strcat(path, basePath); + utoa(id, buf, 10); + toAddPrefixStr(bufWithPrefix, buf, 5); + strcat(path, bufWithPrefix); + strcat(path, "."); + strcat(path, ext); +} + +// Создание имени файла +void createFileNameForId_REP_MSK_INF(char *pathRep, char *pathMsk, char *pathInf, char *basePath, uint32_t id) { + createFileNameForId(pathRep, basePath, id, "REP"); + createFileNameForId(pathMsk, basePath, id, "MSK"); + createFileNameForId(pathInf, basePath, id, "INF"); +} + + +bool readRepresentationRecvFileRep(tFs *fs, tStructRepresentationPacket *structRepresentationPacket, + char *path_dir_frag_inbox_fileName) { + FRESULT fr; + FIL file; + UINT br; + + fr = f_open_i(fs, &file, (TCHAR *) path_dir_frag_inbox_fileName, FA_READ); + if (fr) { + return false; + } + + fr = f_read_i(fs, &file, structRepresentationPacket, sizeof(tStructRepresentationPacket), &br); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + + fr = f_close_i(fs, &file); + + return true; +} + + +bool readRecvFileInfo(tFs *fs, tFileRecvInfo *fileRecvInfo, char *path_inf_fileName) { +/* + fileRecvInfo->from = ini_getl("MAIN", "from", 0, path_inf_fileName); + fileRecvInfo->mnumFrom = ini_getl("MAIN", "mnumFrom", 0, path_inf_fileName); + fileRecvInfo->to = ini_getl("MAIN", "to", 0, path_inf_fileName); + fileRecvInfo->chSv = ini_getl("MAIN", "chSv", 0, path_inf_fileName); + fileRecvInfo->kvs = ini_getl("MAIN", "kvs", 0, path_inf_fileName); + fileRecvInfo->mnum = ini_getl("MAIN", "mnum", 0, path_inf_fileName); + fileRecvInfo->dateDay = ini_getl("MAIN", "dateDay", 0, path_inf_fileName); + fileRecvInfo->dateMon = ini_getl("MAIN", "dateMon", 0, path_inf_fileName); + fileRecvInfo->fileSize = ini_getl("MAIN", "fileSize", 0, path_inf_fileName); + fileRecvInfo->isEnd = ini_getl("MAIN", "isEnd", 0, path_inf_fileName); + fileRecvInfo->isRecvInbox = ini_getl("MAIN", "isRecvInbox", 0, path_inf_fileName); + fileRecvInfo->crc32_MSK = ini_getl("MAIN", "crc32_MSK", 0, path_inf_fileName); + fileRecvInfo->crc32_REP = ini_getl("MAIN", "crc32_REP", 0, path_inf_fileName); +*/ + + FRESULT fr; + FIL file; + UINT br; + + fr = f_open_i(fs, &file, (TCHAR *) path_inf_fileName, FA_READ); + if (fr) { + return false; + } + + fr = f_read_i(fs, &file, fileRecvInfo, sizeof(tFileRecvInfo), &br); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + + fr = f_close_i(fs, &file); + + return true; +} + +bool writeRecvFileInfo(tFs *fs, tFileRecvInfo *fileRecvInfo, char *path_inf_fileName) { + bool result; +/* + result = ini_putl("MAIN", "from", fileRecvInfo->from, path_inf_fileName); + result = ini_putl("MAIN", "mnumFrom", fileRecvInfo->mnumFrom, path_inf_fileName); + result = ini_putl("MAIN", "chSv", fileRecvInfo->chSv, path_inf_fileName); + result = ini_putl("MAIN", "to", fileRecvInfo->to, path_inf_fileName); + result = ini_putl("MAIN", "kvs", fileRecvInfo->kvs, path_inf_fileName); + result = ini_putl("MAIN", "mnum", fileRecvInfo->mnum, path_inf_fileName); + result = ini_putl("MAIN", "dateDay", fileRecvInfo->dateDay, path_inf_fileName); + result = ini_putl("MAIN", "dateMon", fileRecvInfo->dateMon, path_inf_fileName); + result = ini_putl("MAIN", "fileSize", fileRecvInfo->fileSize, path_inf_fileName); + result = ini_putl("MAIN", "isEnd", fileRecvInfo->isEnd, path_inf_fileName); + result = ini_putl("MAIN", "isRecvInbox", fileRecvInfo->isRecvInbox, path_inf_fileName); + result = ini_putl("MAIN", "crc32_MSK", fileRecvInfo->crc32_MSK, path_inf_fileName); + result = ini_putl("MAIN", "crc32_REP", fileRecvInfo->crc32_REP, path_inf_fileName); +*/ + + FRESULT fr; + FIL file; + UINT bw; + + fr = f_open_i(fs, &file, (TCHAR *) path_inf_fileName, FA_WRITE | FA_CREATE_ALWAYS); + if (fr) { + return false; + } + + fr = f_write_i(fs, &file, fileRecvInfo, sizeof(tFileRecvInfo), &bw); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + + fr = f_close_i(fs, &file); + + return true; +} + + +// Прием пакетов - Создание файлов +bool +isReceivedCreate(tFs *fs, uint32_t mnum, uint32_t to, tStructTransportPacket *packet, uint8_t *buf, uint32_t buf_len, + char *path_dir_info_fileName, char *path_dir_mask_fileName, char *path_dir_frag_inbox_fileName, + bool *isCrcUpdate) { + FIL file; + FRESULT fr; + UINT bw; + FILINFO fno; + + *isCrcUpdate = true; + + uint32_t size = packet->offsetPacket; + + if (packet->offsetPacket > 0) { + + uint32_t lenMaskInteger = size / sizeof(bufFreeOperation); + uint32_t lenMaskTail = size % sizeof(bufFreeOperation); + + + // Расширение МАСКИ + fr = f_open_i(fs, &file, (TCHAR *) path_dir_mask_fileName, FA_WRITE | FA_CREATE_ALWAYS); + if (fr) return false; + + for (uint32_t i = 0; i < lenMaskInteger; ++i) { + fr = f_write_i(fs, &file, bufFreeOperation, sizeof(bufFreeOperation), &bw); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + } + + if (lenMaskTail > 0) { + fr = f_write_i(fs, &file, bufFreeOperation, lenMaskTail, &bw); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + } + +// fr = f_write_i(fs, &file, (bufFillOperation + sizeof(tStructTransportPacket)), buf_len - sizeof(tStructTransportPacket), &bw); + fr = f_write_i(fs, &file, bufFillOperation, buf_len - sizeof(tStructTransportPacket), &bw); + + + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + fr = f_close_i(fs, &file); + + + + // Расширение СООБЩЕНИЯ + fr = f_open_i(fs, &file, (TCHAR *) path_dir_frag_inbox_fileName, FA_WRITE | FA_CREATE_ALWAYS); + if (fr) return false; + + for (uint32_t i = 0; i < lenMaskInteger; ++i) { + fr = f_write_i(fs, &file, bufFreeOperation, sizeof(bufFreeOperation), &bw); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + } + + if (lenMaskTail > 0) { + fr = f_write_i(fs, &file, bufFreeOperation, lenMaskTail, &bw); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + } + + // Запись данных сообщения + //fr = f_write_i(fs, &file, (buf + sizeof(tStructTransportPacket)), buf_len - sizeof(tStructTransportPacket), &bw); + fr = f_write_i(fs, &file, buf + sizeof(tStructTransportPacket), buf_len - sizeof(tStructTransportPacket), &bw); + + + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + fr = f_close_i(fs, &file); + + + } else { + + fr = f_open_i(fs, &file, (TCHAR *) path_dir_mask_fileName, FA_WRITE | FA_CREATE_ALWAYS); + + if (fr) return false; + + // fr = f_write_i(fs, &file, (bufFillOperation + sizeof(tStructTransportPacket)), buf_len - sizeof(tStructTransportPacket), &bw); + fr = f_write_i(fs, &file, bufFillOperation, buf_len - sizeof(tStructTransportPacket), &bw); + + + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + fr = f_close_i(fs, &file); + + + // Создание файла сегментов и запись сегмента сообщения + fr = f_open_i(fs, &file, (TCHAR *) path_dir_frag_inbox_fileName, FA_WRITE | FA_CREATE_ALWAYS); + if (fr) return false; + + // fr = f_write_i(fs, &file, (buf + sizeof(tStructTransportPacket)), buf_len - sizeof(tStructTransportPacket), &bw); + fr = f_write_i(fs, &file, buf + sizeof(tStructTransportPacket), buf_len - sizeof(tStructTransportPacket), &bw); + + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + fr = f_close_i(fs, &file); + + } + + + + // Размер файла + fr = f_stat(path_dir_frag_inbox_fileName, &fno); + + tFileRecvInfo fileRecvInfo; + fileRecvInfo.mnum = mnum; + fileRecvInfo.from = packet->numberSender; + fileRecvInfo.mnumFrom = packet->numberMessage; + fileRecvInfo.dateDay = packet->dateCreateTransportPacketDay; + fileRecvInfo.dateMon = packet->dateCreateTransportPacketMon; + fileRecvInfo.to = to; + fileRecvInfo.chSv = 1; + fileRecvInfo.kvs = 0; + if (packet->dataType == 0) + fileRecvInfo.kvs = 1; + fileRecvInfo.isEnd = packet->isEnd; + fileRecvInfo.fileSize = fno.fsize; + fileRecvInfo.isRecvInbox = 0; + + fileRecvInfo.crc32_MSK = CrcFileFs(fs, path_dir_mask_fileName); + fileRecvInfo.crc32_REP = CrcFileFs(fs, path_dir_frag_inbox_fileName); + + // Создание файла информации + bool result = writeRecvFileInfo(fs, &fileRecvInfo, path_dir_info_fileName); + + return result; +} + +// Прием пакетов - Добавление файлов +bool isReceivedAppend(tFs *fs, tStructTransportPacket *packet, uint8_t *buf, uint32_t buf_len, + char *path_dir_info_fileName, char *path_dir_mask_fileName, char *path_dir_frag_inbox_fileName, + bool *isCrcUpdate) { + FIL file; + FRESULT fr; + UINT bw; + FILINFO fno; + + *isCrcUpdate = false; + + tFileRecvInfo fileRecvInfo; + + // Чтение файла информации + bool result = readRecvFileInfo(fs, &fileRecvInfo, path_dir_info_fileName); + + uint32_t crcMSK_Old = fileRecvInfo.crc32_MSK; + + // Размер файла + fr = f_stat(path_dir_mask_fileName, &fno); + + if (fno.fsize < packet->offsetPacket) { + + uint32_t size = packet->offsetPacket - fno.fsize; + + uint32_t lenMaskInteger = size / sizeof(bufFreeOperation); + uint32_t lenMaskTail = size % sizeof(bufFreeOperation); + + // Расширение МАСКИ + fr = f_open_i(fs, &file, (TCHAR *) path_dir_mask_fileName, FA_WRITE | FA_OPEN_APPEND); + if (fr) return false; + + for (uint32_t i = 0; i < lenMaskInteger; ++i) { + fr = f_write_i(fs, &file, bufFreeOperation, sizeof(bufFreeOperation), &bw); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + } + + if (lenMaskTail > 0) { + fr = f_write_i(fs, &file, bufFreeOperation, lenMaskTail, &bw); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + } + +// fr = f_write_i(fs, &file, (bufFillOperation + sizeof(tStructTransportPacket)),buf_len - sizeof(tStructTransportPacket),&bw); + fr = f_write_i(fs, &file, bufFillOperation, buf_len - sizeof(tStructTransportPacket), &bw); + + + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + fr = f_close_i(fs, &file); + + + // Расширение СООБЩЕНИЯ + fr = f_open_i(fs, &file, (TCHAR *) path_dir_frag_inbox_fileName, FA_WRITE | FA_OPEN_APPEND); + if (fr) return false; + + for (uint32_t i = 0; i < lenMaskInteger; ++i) { + fr = f_write_i(fs, &file, bufFreeOperation, sizeof(bufFreeOperation), &bw); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + } + + if (lenMaskTail > 0) { + fr = f_write_i(fs, &file, bufFreeOperation, lenMaskTail, &bw); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + } + + // Запись данных сообщения +// fr = f_write_i(fs, &file, (buf + sizeof(tStructTransportPacket)), buf_len - sizeof(tStructTransportPacket),&bw); + fr = f_write_i(fs, &file, buf + sizeof(tStructTransportPacket), buf_len - sizeof(tStructTransportPacket), &bw); + + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + fr = f_close_i(fs, &file); + + + } else { + // Запись маски в файл маски + fr = f_open_i(fs, &file, (TCHAR *) path_dir_mask_fileName, FA_WRITE); + if (fr) return false; + fr = f_lseek_i(fs, &file, packet->offsetPacket); + +// fr = f_write_i(fs, &file, (bufFillOperation + sizeof(tStructTransportPacket)),buf_len - sizeof(tStructTransportPacket), &bw); + fr = f_write_i(fs, &file, bufFillOperation, buf_len - sizeof(tStructTransportPacket), &bw); + + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + fr = f_close_i(fs, &file); + + + // Запись сегментов в файл сообщения + fr = f_open_i(fs, &file, (TCHAR *) path_dir_frag_inbox_fileName, FA_WRITE); + if (fr) return false; + fr = f_lseek_i(fs, &file, packet->offsetPacket); + +// fr = f_write_i(fs, &file, (buf + sizeof(tStructTransportPacket)), buf_len - sizeof(tStructTransportPacket),&bw); + fr = f_write_i(fs, &file, buf + sizeof(tStructTransportPacket), buf_len - sizeof(tStructTransportPacket), &bw); + + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + fr = f_close_i(fs, &file); + + } + + // Размер файла + fr = f_stat(path_dir_frag_inbox_fileName, &fno); + + if (packet->dataType == 0) + fileRecvInfo.kvs = 1; + + if (packet->isEnd == 1) + fileRecvInfo.isEnd = packet->isEnd; + + fileRecvInfo.fileSize = fno.fsize; + + fileRecvInfo.crc32_MSK = CrcFileFs(fs, path_dir_mask_fileName); + fileRecvInfo.crc32_REP = CrcFileFs(fs, path_dir_frag_inbox_fileName); + + // Запись файла информации + result = writeRecvFileInfo(fs, &fileRecvInfo, path_dir_info_fileName); + + if (crcMSK_Old != fileRecvInfo.crc32_MSK) { + *isCrcUpdate = true; + } + + return true; +} + + +//начало--------------------------------------Квитирование приема------------------------------------------------------- +//начало--------------------------------------Квитирование приема------------------------------------------------------- +//начало--------------------------------------Квитирование приема------------------------------------------------------- + +bool Kvitin(tFs *fs, tRtcIO *rtcIo, uint32_t numberMessage, uint32_t numberSender, + char *path_dir_info_fileName, + char *path_dir_mask_fileName, uint8_t *bufKvit, uint32_t *lenPacketKvit, bool *isAll) { +// uint32_t sizeBufKvit = 0; + + uint8_t bufRead[512]; + FIL file; + FRESULT fr; + UINT br; // File read/write count + + *isAll = false; + *lenPacketKvit = 0; + + tFileRecvInfo fileRecvInfo; + + // Чтение файла информации + bool result = readRecvFileInfo(fs, &fileRecvInfo, path_dir_info_fileName); + if (result == false) { + return false; + } + + uint32_t sizeFileFrag = fileRecvInfo.fileSize; + + // Чтение файла маски + uint32_t stepSizeFileFrag = 0; + + fr = f_open_i(fs, &file, (TCHAR *) path_dir_mask_fileName, FA_READ); + if (fr) return false; + + + fr = f_read_i(fs, &file, bufRead, sizeof(bufRead), &br); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + + uint32_t lenFieldKvit = 0; + + if (fileRecvInfo.isEnd) + *isAll = true; + + tStructTransportKvitPacketData *dataKvit = (tStructTransportKvitPacketData *) &bufKvit[0]; + + uint8_t prefByte; + + if (bufRead[0] == 0x55) { + dataKvit->offsetKvitPacket = 0; + ++dataKvit; + ++lenFieldKvit; + } else { + *isAll = false; + } + prefByte = bufRead[0]; + + for (;;) { + + for (uint32_t i = 0; i < br; ++i) { + + if (stepSizeFileFrag == sizeFileFrag) { + break; + } + + if (prefByte != bufRead[i]) { + + if (bufRead[i] == 0x55) { + dataKvit->offsetKvitPacket = stepSizeFileFrag; + } + if (bufRead[i] == 0x00) { + dataKvit->offsetKvitPacket = stepSizeFileFrag; + *isAll = false; + } + + ++dataKvit; + ++lenFieldKvit; + + prefByte = bufRead[i]; + } + + ++stepSizeFileFrag; + } + + if ((stepSizeFileFrag == sizeFileFrag) || (br == 0)) { + break; + } + + fr = f_read_i(fs, &file, bufRead, sizeof(bufRead), &br); + if (fr) { + *isAll = false; + fr = f_close_i(fs, &file); + return false; + } + + } + + fr = f_close_i(fs, &file); + + if (*isAll == true) { + dataKvit->offsetKvitPacket = 0; + lenFieldKvit = 1; + } + + // Если не было последнего пакета + if (fileRecvInfo.isEnd == 0) { + dataKvit->offsetKvitPacket = fileRecvInfo.fileSize; + ++lenFieldKvit; + } + + *lenPacketKvit = lenFieldKvit * 3; + + return true; +} +//конец--------------------------------------Квитирование приема------------------------------------------------------- +//конец--------------------------------------Квитирование приема------------------------------------------------------- +//конец--------------------------------------Квитирование приема------------------------------------------------------- + + + +// Сообщение принято целиком +bool isReceivedAll(tFs *fs, char *path_dir_info_fileName, char *path_dir_mask_fileName, bool *isAll) { + uint8_t bufRead[512]; + FIL file; + FRESULT fr; + UINT br; // File read/write count + + *isAll = false; + + tFileRecvInfo fileRecvInfo; + + // Чтение файла информации + bool result = readRecvFileInfo(fs, &fileRecvInfo, path_dir_info_fileName); + if (result == false) { + return false; + } + + /* + uint32_t sizeFileFrag = 0; + uint32_t isEnd = 0; + uint32_t isKvit = 0; + + // Чтение размера файла + fr = f_open_i(fs, &file, (TCHAR *) path_dir_info_fileName, FA_READ); + if (fr) return false; + + fr = f_read_i(fs, &file, &sizeFileFrag, 4, &br); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + + fr = f_read_i(fs, &file, &isKvit, 4, &br); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + + fr = f_read_i(fs, &file, &isEnd, 4, &br); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + + fr = f_close_i(fs, &file); +*/ + + uint32_t sizeFileFrag = 0; + + // Чтение файла маски + uint32_t stepSizeFileFrag = 0; + + fr = f_open_i(fs, &file, (TCHAR *) path_dir_mask_fileName, FA_READ); + if (fr) { + return false; + } + +//начало--------------------------------------БЕЗ Квитирование приема---------------------------------------------------- +//начало--------------------------------------БЕЗ Квитирование приема---------------------------------------------------- +//начало--------------------------------------БЕЗ Квитирование приема---------------------------------------------------- + for (;;) { + + fr = f_read_i(fs, &file, bufRead, sizeof(bufRead), &br); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + + for (uint32_t i = 0; i < br; ++i) { + + if (stepSizeFileFrag == sizeFileFrag) { + break; + } + + if (bufRead[i] == 0) { + fr = f_close_i(fs, &file); + return true; + } + + ++stepSizeFileFrag; + } + + if ((br == 0) || (stepSizeFileFrag == sizeFileFrag)) + break; + } + +//конец--------------------------------------БЕЗ Квитирование приема---------------------------------------------------- +//конец--------------------------------------БЕЗ Квитирование приема---------------------------------------------------- +//конец--------------------------------------БЕЗ Квитирование приема---------------------------------------------------- + + fr = f_close_i(fs, &file); + + if (stepSizeFileFrag == sizeFileFrag) { + if (fileRecvInfo.isEnd) { + *isAll = true; + return true; + } else { + return true; + } + } + + return true; +} + + +// Создание заголовка файла входящего сообщения трассировки +void +createFileHeadFragInboxTrace(char *str, uint32_t numberSender, uint32_t numberRecipient, uint32_t numberMessage, + uint32_t kvs, uint32_t typeMessage, char *bufIdFileInBox) { + char buf[9]; + + strcat(str, "&from="); + utoa(numberSender, buf, 10); + strcat(str, buf); + + strcat(str, "&to="); + utoa(numberRecipient, buf, 10); + strcat(str, buf); + + strcat(str, "&chSv=1"); + + if ((kvs == 0) || (kvs == 1)) { + strcat(str, "&mnum="); + utoa(numberMessage, buf, 10); + strcat(str, buf); + + strcat(str, "&kvs=0"); + + strcat(str, "&subj=file&msg="); + + strcat(str, bufIdFileInBox); + strcat(str, ".DAT"); + + } + +// if ((kvs == 8) || (kvs == 4)) { +// strcat(str, "&subj=KVITIN&msg="); +// } + +} + +// Создание заголовка файла входящего сообщения +void +createFileHeadFragInbox(char *str, uint32_t numberSender, uint32_t numberRecipient, uint32_t numberMessage, + uint32_t kvs, uint32_t typeMessage) { + char buf[9]; + + strcat(str, "&from="); + utoa(numberSender, buf, 10); + strcat(str, buf); + + strcat(str, "&to="); + utoa(numberRecipient, buf, 10); + strcat(str, buf); + + strcat(str, "&chSv=1"); + + if ((kvs == 0) || (kvs == 1)) { + strcat(str, "&mnum="); + utoa(numberMessage, buf, 10); + strcat(str, buf); + + if (kvs == 0) { + strcat(str, "&kvs=0"); + } + + if (kvs == 1) { + strcat(str, "&kvs=1"); + } + + if (typeMessage == 2) { + strcat(str, "&subj=file&msg="); + } else { + strcat(str, "&msg="); + } + } + +// if ((kvs == 8) || (kvs == 4)) { +// strcat(str, "&subj=KVITIN&msg="); +// } + +} + +// Получение информации о принятых файлах квитанций +bool checkNumSentBoxKvitin(tFs *fs, + uint8_t *bufReceivedPacket, + uint32_t bufReceivedPacketLen, + uint32_t numberSender, + uint32_t numberMessage, + uint32_t dateCreateTransportPacketMon, + uint32_t dateCreateTransportPacketDay) { + FRESULT fr; + char bufDumpFile[256]; + + char *end; + + DIR dj; + FILINFO fno; + FIL file; + + char fileName[MAX_LEN_PATH_FS]; + + struct { + int paramcount; + char *params_names[MAX_POST_GET_PARAMETERS]; + char *params_vals[MAX_POST_GET_PARAMETERS]; + } params_uri; + + uint32_t crc32 = 0xFFFFFFFF; + crc32 = GonetsCrc32_noreverse_update(&bufReceivedPacket[sizeof(tStructTransportKvitPacket)], + bufReceivedPacketLen - sizeof(tStructTransportKvitPacket), crc32); + crc32 = GonetsCrc32_noreverse_finish(crc32); + + // Путь к файлу в SENTBOX KVITIN + char path_sent_fileName[MAX_LEN_PATH_FS]; + path_sent_fileName[0] = '\0'; + strcat(path_sent_fileName, dir_kvitin); + + fr = f_findfirst_i(fs, &dj, &fno, path_sent_fileName, "*.ITM"); + + while (fr == FR_OK && fno.fname[0]) { + + fileName[0] = '\0'; + strcat(fileName, path_sent_fileName); + strcat(fileName, fno.fname); + + fr = f_open_i(fs, &file, (TCHAR *) fileName, FA_READ); + if (fr != FR_OK) { + fr = f_findnext_i(fs, &dj, &fno); + continue; + } + + UINT bytes_read; + fr = f_read_i(fs, &file, bufDumpFile, sizeof(bufDumpFile), &bytes_read); + if (fr != FR_OK) { + fr = f_close_i(fs, &file); + fr = f_findnext_i(fs, &dj, &fno); + continue; + } + + fr = f_close_i(fs, &file); + + params_uri.paramcount = extract_uri_ex_parameters(bufDumpFile, params_uri.params_names, + params_uri.params_vals, + MAX_POST_GET_PARAMETERS); + + + int stepParam = 0; + uint32_t fromFile = 0; + uint32_t kvt_numFile = 0; + uint32_t kvt_monFile = 0; + uint32_t kvt_dayFile = 0; + uint32_t kvt_crc = 0; + for (int i = 0; i < params_uri.paramcount; ++i) { + + if (strcmp(params_uri.params_names[i], "from") == 0) { + fromFile = atoi(params_uri.params_vals[i]); + ++stepParam; + } + + if (strcmp(params_uri.params_names[i], "kvt_num") == 0) { + kvt_numFile = atoi(params_uri.params_vals[i]); + ++stepParam; + } + + if (strcmp(params_uri.params_names[i], "kvt_mon") == 0) { + kvt_monFile = atoi(params_uri.params_vals[i]); + ++stepParam; + } + + if (strcmp(params_uri.params_names[i], "kvt_day") == 0) { + kvt_dayFile = atoi(params_uri.params_vals[i]); + ++stepParam; + } + + if (strcmp(params_uri.params_names[i], "kvt_crc") == 0) { + ++stepParam; + kvt_crc = strtoul(params_uri.params_vals[i], &end, 10); + } + } + + if ((numberSender == fromFile) && (numberMessage == kvt_numFile) && + (dateCreateTransportPacketMon == kvt_monFile) && (dateCreateTransportPacketDay == kvt_dayFile) && + (crc32 == kvt_crc)) { + + fr = f_closedir_i(fs, &dj); + return true; + } + + fr = f_findnext_i(fs, &dj, &fno); + } + fr = f_closedir_i(fs, &dj); + + return false; +} + +// Получение информации о принятых файлах +bool checkNumSentBox(tFs *fs, tRtcIO *rtc, uint32_t mnum, uint32_t from) { + FRESULT fr; + char bufDumpFile[256]; + + DIR dj; + FILINFO fno; + FIL file; + + char fileName[MAX_LEN_PATH_FS]; + + struct { + int paramcount; + char *params_names[MAX_POST_GET_PARAMETERS]; + char *params_vals[MAX_POST_GET_PARAMETERS]; + } params_uri; + + + // Количество дней назад + for (int j = 0; j < 4; ++j) { + + // Путь к каталогу с датой + char path_sent_dirDate[MAX_LEN_PATH_FS]; + path_sent_dirDate[0] = '\0'; + + time_t timestamp; + rtc->get(rtc, ×tamp); + timestamp -= j * 24 * 3600; + + struct tm timestampTM; + localtime_r(×tamp, ×tampTM); + + strftime(path_sent_dirDate, sizeof(path_sent_dirDate), "%Y%m%d", ×tampTM); + + // Путь к файлу в SENTBOX + char path_sent_fileName[MAX_LEN_PATH_FS]; + path_sent_fileName[0] = '\0'; + strcat(path_sent_fileName, dir_inbox); + strcat(path_sent_fileName, path_sent_dirDate); + strcat(path_sent_fileName, "/"); + + + fr = f_findfirst_i(fs, &dj, &fno, path_sent_fileName, "*.ITM"); + + while (fr == FR_OK && fno.fname[0]) { + + fileName[0] = '\0'; + strcat(fileName, path_sent_fileName); + strcat(fileName, fno.fname); + + fr = f_open_i(fs, &file, (TCHAR *) fileName, FA_READ); + if (fr != FR_OK) { + fr = f_findnext_i(fs, &dj, &fno); + continue; + } + + UINT bytes_read; + fr = f_read_i(fs, &file, bufDumpFile, sizeof(bufDumpFile), &bytes_read); + if (fr != FR_OK) { + fr = f_close_i(fs, &file); + fr = f_findnext_i(fs, &dj, &fno); + continue; + } + + fr = f_close_i(fs, &file); + + params_uri.paramcount = extract_uri_ex_parameters(bufDumpFile, params_uri.params_names, + params_uri.params_vals, + MAX_POST_GET_PARAMETERS); + + + int stepParam = 0; + uint32_t mnumFile = 0; + uint32_t fromFile = 0; + for (int i = 0; i < params_uri.paramcount; ++i) { + + if (strcmp(params_uri.params_names[i], "mnum") == 0) { + mnumFile = atoi(params_uri.params_vals[i]); + ++stepParam; + if (stepParam == 2) + break; + } + + if (strcmp(params_uri.params_names[i], "from") == 0) { + fromFile = atoi(params_uri.params_vals[i]); + ++stepParam; + if (stepParam == 2) + break; + } + + } + + if ((stepParam == 2) && (mnum == mnumFile) && (from == fromFile)) { + fr = f_closedir_i(fs, &dj); + return true; + } + + fr = f_findnext_i(fs, &dj, &fno); + } + fr = f_closedir_i(fs, &dj); + + } + return false; +} + + +// Перенос собранного фрагментированного файла в хранилище принятых сообщений inbox +tReceiveBuildResult +renameFromFrgToInBox(tFs *fs, tGonetsReedSalmon *gonetsReedSalmon, md5a_context *md5ctx, uint32_t idFile, tRtcIO *rtc, + char *path_dir_info_fileName, + char *path_dir_frag_inbox_fileName, tLoggerInterface *logger) { + tFileRecvInfo fileRecvInfo; + + // Чтение файла информации + bool result = readRecvFileInfo(fs, &fileRecvInfo, path_dir_info_fileName); + + + // Получение информации о принятых файлах + if (checkNumSentBox(fs, rtc, fileRecvInfo.mnumFrom, fileRecvInfo.from)) { + +#ifdef DEBUG_EXT_MODEM + char strMessage[128]; + strMessage[0] = '\0'; + strcat(strMessage, "Сообщение номер "); + char buf[12]; + utoa(fileRecvInfo.mnumFrom, buf, 10); + strcat(strMessage, buf); + strcat(strMessage, " от АТ-"); + utoa(fileRecvInfo.from, buf, 10); + strcat(strMessage, buf); + + strcat(strMessage, " было принято ранее"); + + LoggerInfo(logger, "GONEC", strMessage, strlen(strMessage)); +#endif + + return true; + } + +// if (fileRecvInfo.isRecvInbox) { +// return true; +// } + + tStructRepresentationPacket structRepresentationPacket; + result = readRepresentationRecvFileRep(fs, &structRepresentationPacket, path_dir_frag_inbox_fileName); + if (result == false) { + return false; + } + + vGonetsReedSalmonRecovery_1410_3430(gonetsReedSalmon, (uint8_t *) &structRepresentationPacket); + + uint8_t crc8 = GonetsCrc8((uint8_t *) &structRepresentationPacket, 9); + + if (crc8 != structRepresentationPacket.crc8) { + LoggerInfoStatic(logger, "GONEC", "Сборка сообщения. Ошибка crc8 в заголовке сообщения"); + } + + + char path_in_dirDate[MAX_LEN_PATH_FS]; + path_in_dirDate[0] = '\0'; + char path_in_fileName[MAX_LEN_PATH_FS]; + path_in_fileName[0] = '\0'; + char path_in_fileNameTrace[MAX_LEN_PATH_FS]; + path_in_fileNameTrace[0] = '\0'; + + // Путь к файлу принятых сообщений + getDateStr(rtc, path_in_dirDate, sizeof(path_in_dirDate)); + strcat(path_in_fileName, dir_inbox); + strcat(path_in_fileName, path_in_dirDate); + strcat(path_in_fileName, "/"); + + + // Путь к файлу принятых сообщений трассировки + getDateStr(rtc, path_in_dirDate, sizeof(path_in_dirDate)); + strcat(path_in_fileNameTrace, dir_inbox); + strcat(path_in_fileNameTrace, path_in_dirDate); + strcat(path_in_fileNameTrace, "/"); + + FRESULT fr; + FIL file; + fr = f_mkdir_i(fs, path_in_fileName); + + if (fr) { + if (fr != FR_EXIST) + return false; + } + + // Имя файла в принятых сообщениях + char bufIdFileInBox[12]; + char bufWithPrefixIdFileInBox[12]; + + utoa(idFile, bufIdFileInBox, 10); + + toAddPrefixStr(bufWithPrefixIdFileInBox, bufIdFileInBox, 5); + strcat(path_in_fileName, bufWithPrefixIdFileInBox); + strcat(path_in_fileName, ".ITM"); + + strcat(path_in_fileNameTrace, bufWithPrefixIdFileInBox); + strcat(path_in_fileNameTrace, ".DAT"); + + UINT br; + uint8_t headBufForTracer[10]; + memset(headBufForTracer, 0, sizeof(headBufForTracer)); + + uint8_t headerTracer[10] = {0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x74, 0x6e, 0x64, 0x00}; + + // Читаем заголовок файла + fr = f_open_i(fs, &file, path_dir_frag_inbox_fileName, FA_READ); + if (fr) return false; + + f_lseek_i(fs, &file, sizeof(tStructRepresentationPacket)); + + f_read_i(fs, &file, headBufForTracer, 10, &br); + + fr = f_close_i(fs, &file); + + bool isTracer = false; + if (memcmp(headBufForTracer, headerTracer, sizeof(headerTracer)) == 0) { + isTracer = true; + } + + // Создание заголовка файла входящего сообщения + char bufHeader[128]; + bufHeader[0] = '\0'; + + if (isTracer) { + createFileHeadFragInboxTrace(bufHeader, fileRecvInfo.from, fileRecvInfo.to, fileRecvInfo.mnumFrom, + fileRecvInfo.kvs, + structRepresentationPacket.typeMessage, bufWithPrefixIdFileInBox); + + } else { + createFileHeadFragInbox(bufHeader, fileRecvInfo.from, fileRecvInfo.to, fileRecvInfo.mnumFrom, fileRecvInfo.kvs, + structRepresentationPacket.typeMessage); + } + + fr = f_open_i(fs, &file, (TCHAR *) path_in_fileName, FA_WRITE | FA_CREATE_ALWAYS); + + UINT bytes_written; + fr = f_write_i(fs, &file, bufHeader, strlen(bufHeader), &bytes_written); + + fr = f_close_i(fs, &file); + + + uint32_t truncCrc = 0; + // CRC32 + if (structRepresentationPacket.typeCrc == 1) { + truncCrc = 4; + } + // MD5 + if (structRepresentationPacket.typeCrc == 2) { + truncCrc = 16; + } + + uint32_t crc32sum; + uint8_t md5sum[16]; + + uint32_t crc32sumFile; + uint8_t md5sumFile[16]; + + if (isTracer) { + result = CopyFileTrucSizeFs(fs, structRepresentationPacket.typeCrc, md5ctx, + &crc32sum, md5sum, + &crc32sumFile, md5sumFile, + path_in_fileNameTrace, + path_dir_frag_inbox_fileName, sizeof(tStructRepresentationPacket), + truncCrc, fileRecvInfo.fileSize); + } else { + + result = CopyFileTrucSizeFs(fs, structRepresentationPacket.typeCrc, md5ctx, + &crc32sum, md5sum, + &crc32sumFile, md5sumFile, + path_in_fileName, + path_dir_frag_inbox_fileName, sizeof(tStructRepresentationPacket), + truncCrc, fileRecvInfo.fileSize); + } + + // CRC32 + if (structRepresentationPacket.typeCrc == 1) { + if (crc32sum != crc32sumFile) { + LoggerInfoStatic(logger, "GONEC", "Сборка сообщения. Ошибка crc32 в теле сообщения"); + } + } + // MD5 + if (structRepresentationPacket.typeCrc == 2) { + bool isMd5Err = false; + + for (int i = 0; i < 16; ++i) { + if (md5sum[i] != md5sumFile[i]) { + isMd5Err = true; + break; + } + } + + if (isMd5Err) { + LoggerInfoStatic(logger, "GONEC", "Сборка сообщения. Ошибка md5 в теле сообщения"); + } + + + } + + + if (result == false) { + return false; + } +// fr = f_rename_i(fs, path_dir_frag_inbox_fileName, path_in_fileName); +// if (fr) { +// return false; +// } + +// fileRecvInfo.isRecvInbox = 1; + // Запись файла информации +// result = writeRecvFileInfo(fs, &fileRecvInfo, path_dir_info_fileName); +// if (result == false) { +// return false; +// } + + return true; +} + +/* +uint8_t file_rep[] = { + 0x01, 0x01, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x84, 0x3D, 0x32, 0x9D, + +// Данные (

Сообщение 23:23 22-05-2023

) + 0x3C, 0x70, 0x3E, 0xD0, 0xA1, 0xD0, 0xBE, 0xD0, 0xBE, 0xD0, 0xB1, 0xD1, 0x89, + 0xD0, 0xB5, 0xD0, 0xBD, 0xD0, 0xB8, 0xD0, 0xB5, 0x20, 0x32, 0x33, 0x3A, 0x32, + 0x33, 0x20, 0x32, 0x32, 0x2D, 0x30, 0x35, 0x2D, 0x32, 0x30, 0x32, 0x33, 0x3C, + 0x62, 0x72, 0x3E, 0x3C, 0x2F, 0x70, 0x3E, + +// CRC32 данных + 0x43, 0x5B, 0x38, 0xFC +}; + + +// Перенос собранного фрагментированного файла в хранилище принятых сообщений inbox +tReceiveBuildResult +renameFromFrgToInBox5555(tFs *fs, tGonetsReedSalmon *gonetsReedSalmon, md5a_context *md5ctx, uint32_t idFile, + tRtcIO *rtc, + char *path_dir_info_fileName, + char *path_dir_frag_inbox_fileName, tLoggerInterface *logger) { + tFileRecvInfo fileRecvInfo; + + fileRecvInfo.fileSize = sizeof(file_rep); + + + FIL file; + FRESULT fr; + + fr = f_unlink_i(fs, path_dir_frag_inbox_fileName); + + fr = f_open_i(fs, &file, (TCHAR *) path_dir_frag_inbox_fileName, FA_WRITE | FA_CREATE_ALWAYS); + UINT bytes_written; + fr = f_write_i(fs, &file, file_rep, sizeof(file_rep), &bytes_written); + fr = f_close_i(fs, &file); + + + bool result; + // Чтение файла информации + //bool result = readRecvFileInfo(fs, &fileRecvInfo, path_dir_info_fileName); + + //if (fileRecvInfo.isRecvInbox) { + // return true; + //} + + + + tStructRepresentationPacket structRepresentationPacket; + result = readRepresentationRecvFileRep(fs, &structRepresentationPacket, path_dir_frag_inbox_fileName); + if (result == false) { + return false; + } + + vGonetsReedSalmonRecovery_1410_3430(gonetsReedSalmon, (uint8_t *) &structRepresentationPacket); + + uint8_t crc8 = GonetsCrc8((uint8_t *) &structRepresentationPacket, 9); + + if (crc8 != structRepresentationPacket.crc8) { + LoggerInfoStatic(logger, "GONEC", "Сборка сообщения. Ошибка crc8 в заголовке сообщения"); + } + + + char path_in_dirDate[MAX_LEN_PATH_FS]; + path_in_dirDate[0] = '\0'; + char path_in_fileName[MAX_LEN_PATH_FS]; + path_in_fileName[0] = '\0'; + char path_in_fileNameTrace[MAX_LEN_PATH_FS]; + path_in_fileNameTrace[0] = '\0'; + + // Путь к файлу принятых сообщений + getDateStr(rtc, path_in_dirDate, sizeof(path_in_dirDate)); + strcat(path_in_fileName, dir_inbox); + strcat(path_in_fileName, path_in_dirDate); + strcat(path_in_fileName, "/"); + + + // Путь к файлу принятых сообщений трассировки + getDateStr(rtc, path_in_dirDate, sizeof(path_in_dirDate)); + strcat(path_in_fileNameTrace, dir_inbox); + strcat(path_in_fileNameTrace, path_in_dirDate); + strcat(path_in_fileNameTrace, "/"); + + + fr = f_mkdir_i(fs, path_in_fileName); + + if (fr) { + if (fr != FR_EXIST) + return false; + } + + // Имя файла в принятых сообщениях + char bufIdFileInBox[12]; + char bufWithPrefixIdFileInBox[12]; + + utoa(idFile, bufIdFileInBox, 10); + + toAddPrefixStr(bufWithPrefixIdFileInBox, bufIdFileInBox, 5); + strcat(path_in_fileName, bufWithPrefixIdFileInBox); + strcat(path_in_fileName, ".ITM"); + + strcat(path_in_fileNameTrace, bufWithPrefixIdFileInBox); + strcat(path_in_fileNameTrace, ".DAT"); + + UINT br; + uint8_t headBufForTracer[10]; + memset(headBufForTracer, 0, sizeof(headBufForTracer)); + + uint8_t headerTracer[10] = {0x74, 0x72, 0x61, 0x63, 0x65, 0x2e, 0x74, 0x6e, 0x64, 0x00}; + + // Читаем заголовок файла + fr = f_open_i(fs, &file, path_dir_frag_inbox_fileName, FA_READ); + if (fr) return false; + + f_lseek_i(fs, &file, sizeof(tStructRepresentationPacket)); + + f_read_i(fs, &file, headBufForTracer, 10, &br); + + fr = f_close_i(fs, &file); + + bool isTracer = false; + if (memcmp(headBufForTracer, headerTracer, sizeof(headerTracer)) == 0) { + isTracer = true; + } + + // Создание заголовка файла входящего сообщения + char bufHeader[128]; + bufHeader[0] = '\0'; + + if (isTracer) { + createFileHeadFragInboxTrace(bufHeader, fileRecvInfo.from, fileRecvInfo.to, fileRecvInfo.mnumFrom, + fileRecvInfo.kvs, + structRepresentationPacket.typeMessage, bufWithPrefixIdFileInBox); + + } else { + createFileHeadFragInbox(bufHeader, fileRecvInfo.from, fileRecvInfo.to, fileRecvInfo.mnumFrom, fileRecvInfo.kvs, + structRepresentationPacket.typeMessage); + } + + fr = f_open_i(fs, &file, (TCHAR *) path_in_fileName, FA_WRITE | FA_CREATE_ALWAYS); + + fr = f_write_i(fs, &file, bufHeader, strlen(bufHeader), &bytes_written); + + fr = f_close_i(fs, &file); + + + uint32_t truncCrc = 0; + // CRC32 + if (structRepresentationPacket.typeCrc == 1) { + truncCrc = 4; + } + // MD5 + if (structRepresentationPacket.typeCrc == 2) { + truncCrc = 16; + } + + uint32_t crc32sum; + uint8_t md5sum[16]; + + uint32_t crc32sumFile; + uint8_t md5sumFile[16]; + + if (isTracer) { + result = CopyFileTrucSizeFs(fs, structRepresentationPacket.typeCrc, md5ctx, + &crc32sum, md5sum, + &crc32sumFile, md5sumFile, + path_in_fileNameTrace, + path_dir_frag_inbox_fileName, sizeof(tStructRepresentationPacket), + truncCrc, fileRecvInfo.fileSize); + } else { + + result = CopyFileTrucSizeFs(fs, structRepresentationPacket.typeCrc, md5ctx, + &crc32sum, md5sum, + &crc32sumFile, md5sumFile, + path_in_fileName, + path_dir_frag_inbox_fileName, sizeof(tStructRepresentationPacket), + truncCrc, fileRecvInfo.fileSize); + } + + // CRC32 + if (structRepresentationPacket.typeCrc == 1) { + if (crc32sum != crc32sumFile) { + LoggerInfoStatic(logger, "GONEC", "Сборка сообщения. Ошибка crc32 в теле сообщения"); + } + } + // MD5 + if (structRepresentationPacket.typeCrc == 2) { + bool isMd5Err = false; + + for (int i = 0; i < 16; ++i) { + if (md5sum[i] != md5sumFile[i]) { + isMd5Err = true; + break; + } + } + + if (isMd5Err) { + LoggerInfoStatic(logger, "GONEC", "Сборка сообщения. Ошибка md5 в теле сообщения"); + } + + + } + + + if (result == false) { + return false; + } +// fr = f_rename_i(fs, path_dir_frag_inbox_fileName, path_in_fileName); +// if (fr) { +// return false; +// } + + fileRecvInfo.isRecvInbox = 1; + // Запись файла информации + result = writeRecvFileInfo(fs, &fileRecvInfo, path_dir_info_fileName); +// if (result == false) { +// return false; +// } + + return true; +} +*/ diff --git a/Src/ModemSend.c b/Src/ModemSend.c new file mode 100644 index 0000000..d72adee --- /dev/null +++ b/Src/ModemSend.c @@ -0,0 +1,1503 @@ +// +// Created by cfif on 21.04.23. +// +#include "ModemMain.h" +#include "ModemReceiveFunc.h" +#include "ModemSendFunc.h" +#include "ModemGonecFunc.h" +#include "ModemBufCreateHeader.h" + +#define LOGGER env->logger +#define LOG_SIGN "GONEC" + + +//начало -------------------------Запрос передающих слотов на модем-------------------------------------------------------- +//начало -------------------------Запрос передающих слотов на модем-------------------------------------------------------- +//начало -------------------------Запрос передающих слотов на модем-------------------------------------------------------- +void RequestModemSendSlots(tModemMain *env) { + bool result; + + // Запрос слотов передачи + result = ModemGetSlot(env, env->modemStatus.id, (uint8_t *) env->modemStatus.status, 16); + + if (result) { + + for (int id = 0; id < 16; ++id) { + if (env->modemStatus.status[id] != env->modemStatusOld[id]) { + //env->modemSlotSendStatusReload = true; + } + env->modemStatusOld[id] = env->modemStatus.status[id]; + } + } + +} +//конец --------------------------Запрос передающих слотов на модем-------------------------------------------------------- +//конец --------------------------Запрос передающих слотов на модем-------------------------------------------------------- +//конец --------------------------Запрос передающих слотов на модем-------------------------------------------------------- + + +bool getIsSlotsFree(tModemMain *env) { + bool isSlotFree = false; + for (int i = 0; i < 16; ++i) { + if (env->modemStatus.status[i] == SLOT_FREE) { + isSlotFree = true; + break; + } + } + return isSlotFree; +} + +bool getIsSlotsSos(tModemMain *env) { + bool isSlotSos = false; + for (int i = 0; i < 16; ++i) { + if (env->modemStatus.sos[i] == 1) { + isSlotSos = true; + break; + } + } + return isSlotSos; +} + +uint32_t getSlotsMemSize(tModemMain *env) { + uint32_t size = 0; + for (int i = 0; i < 16; ++i) { + if (env->modemStatus.status[i] != SLOT_FREE) { + size += env->modemStatus.sendLen[i]; + } + } + return size; +} + + +// Поиск самого срочного сообщения +uint32_t getMaxUrgencyRepout(tModemMain *env) { + tFileSendInfo fileSendInfo; + bool result = true; + FRESULT fr; + DIR dj; + FILINFO fno; + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + uint32_t maxUrgency = 0; + uint32_t maxMnum = 0xFFFFFFFF; + + fr = f_findfirst_i(env->fs, &dj, &fno, dir_rep_out, "*.INF"); + while (fr == FR_OK && fno.fname[0]) { + + uint32_t idFile = atoi(fno.fname); + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_rep_out, idFile); + + bool resultFileInfo = readSendFileInfo(env->fs, &fileSendInfo, path_dir_info_fileName); + + if (resultFileInfo == false) { + fr = f_findnext_i(env->fs, &dj, &fno); + continue; + } + + + char strId[MAX_LEN_PATH_FS]; + strId[0] = '\0'; + + bool isDelModem = false; + + + // Запись в файл маски признака отправленного пакета + for (int i = 0; i < 16; ++i) { + + // Пакет отправлен + if ((env->modemStatus.status[i] == SLOT_READY_SENDING) && + (env->modemStatus.idMessage[i] == fileSendInfo.mnum)) { + + uint32_t sizeHead = sizeof(tStructTransportPacket); + if (fileSendInfo.typeFile == TYPE_FILE_KVITIN) { + sizeHead = sizeof(tStructTransportKvitPacket); + } + + result = editMaskPacketTransport(env->fs, env->modemStatus.sendFrom[i], + env->modemStatus.sendLen[i] - sizeHead, + path_dir_mask_fileName, + BUF_RECEIVE); + + if (result == false) { + break; + } + + isDelModem = true; + + char buffer[12]; + utoa(i + 1, buffer, 10); + strcat(strId, buffer); + strcat(strId, ","); + + env->modemStatus.status[i] = SLOT_INIT; + } + } + + // Отправка на модем команды удаления пакетов + if (isDelModem) { + + // Контроль состояния процентов индикации отправки + bool isFind; + result = isFindMaskPacketTransport(env->fs, &isFind, path_dir_mask_fileName, &fileSendInfo); + + if (result == false) { + fr = f_findnext_i(env->fs, &dj, &fno); + continue; + } + + fileSendInfo.crc32_MSK = CrcFileFs(env->fs, path_dir_mask_fileName); + writeSendFileInfo(env->fs, &fileSendInfo, path_dir_info_fileName); + + if (osMutexAcquire(env->accessHTTP, TIME_MUTEX_HTTP_ACCESS) == osOK) { + createBufStateFileSend(env->fs); + osMutexRelease(env->accessHTTP); + } + + strId[strlen(strId) - 1] = '\0'; + result = SlotClearNoStartTask(env, strId); + + // Запрос слотов передачи + RequestModemSendSlots(env); + + + + } + + + + + + // Пропуск просканированых файлов + bool isContinue = false; + + for (uint32_t i = 0; i < env->mnumBufScanCount; ++i) { + if (env->mnumBufScan[i] == idFile) { + isContinue = true; + break; + } + } + + if (isContinue) { + fr = f_findnext_i(env->fs, &dj, &fno); + continue; + } + + if ((fileSendInfo.mnum < maxMnum) && (fileSendInfo.urgency >= maxUrgency)) { + + // Пришел пакет SOS + if ((env->store->nvm.flagSos == 1) && (fileSendInfo.sos == 0)) { + fr = f_findnext_i(env->fs, &dj, &fno); + continue; + } + + // Трассировка выключена + if ((env->store->nvm.Settings_Tracert.PeSvCoor_v == 0) || + (env->store->nvm.Settings_Tracert.mTracer_v == 0)) { + if (fileSendInfo.typeFile == TYPE_FILE_TRACERT) { + + fr = f_findnext_i(env->fs, &dj, &fno); + continue; + } + } + + maxUrgency = fileSendInfo.urgency; + maxMnum = fileSendInfo.mnum; + + } + + fr = f_findnext_i(env->fs, &dj, &fno); + } + fr = f_closedir_i(env->fs, &dj); + + + if (maxMnum != 0xFFFFFFFF) { + + bool isSlotFree = getIsSlotsFree(env); + + // Если есть высокоприоритетные сообщения + if (isSlotFree == false) { + for (int i = 0; i < 16; ++i) { + if ((env->modemStatus.urgency[i] < maxUrgency) && (env->modemStatus.idMessage[i] != 0)) { + return maxMnum; + } + } + } + + // Все слоты заняты + if (isSlotFree == false) { + return 0; + } + + } +/* + if (maxMnum != 0) { + + bool isSlotFree = getIsSlotsFree(env); + + // Если есть высокоприоритетные сообщения + if (isSlotFree == false) { + for (int i = 0; i < 16; ++i) { + if ((env->modemStatus.urgency[i] < maxUrgency) && (env->modemStatus.idMessage[i] != 0)) { + return maxMnum; + } + } + } + + // Все слоты заняты. Нельзя вовращать 0 + if (isSlotFree == false) { + return 0; + } + + } +*/ + bool isSlotFree = getIsSlotsFree(env); + // Все слоты заняты + if (isSlotFree == false) { + return 0; + } + + if (maxMnum == 0xFFFFFFFF) + return 0; + + return maxMnum; +} + + +bool ToSentFiles(tModemMain *env, tFileSendInfo *fileSendInfo, + char *path_dir_rep_fileName, + char *path_dir_mask_fileName, + char *path_dir_info_fileName) { + + + // Квитируемое сообщение - еще не отквитировано полностью + if ((fileSendInfo->kvs == 1) && (fileSendInfo->isSendAll == 0)) { + return true; + } + + // Поиск пакетов в модеме на случай, если они загружены в модем на передачу + char strId[MAX_LEN_PATH_FS]; + strId[0] = '\0'; + + bool isDelModem = false; + + for (int i = 0; i < 16; ++i) { + if (env->modemStatus.idMessage[i] == fileSendInfo->mnum) { + + isDelModem = true; + + char buffer[12]; + utoa(i + 1, buffer, 10); + strcat(strId, buffer); + strcat(strId, ","); + + env->modemStatus.status[i] = SLOT_INIT; + } + } + + // Отправка на модем команды удаления пакетов + if (isDelModem) { + strId[strlen(strId) - 1] = '\0'; + bool result = SlotClearNoStartTask(env, strId); + } + + + if (env->store->nvm.Settings_General.SaveToSentBox_v) { + bool result = renameFromOutBoxToSentBox(env->fs, env->rtcIo, fileSendInfo); + if (result == false) { + env->modemSlotSendStatusReload = true; + return false; + } + + } else { + // Путь к файлу в OUTBOX + char path_out_fileName[MAX_LEN_PATH_FS]; + path_out_fileName[0] = '\0'; + + if (fileSendInfo->typeFile == TYPE_FILE_TRACERT) { + createFileNameForId(path_out_fileName, (char *) dir_tracert, fileSendInfo->mnum, "OTM"); + } else { + createFileNameForId(path_out_fileName, (char *) dir_outbox, fileSendInfo->mnum, "OTM"); + } + + f_unlink_i(env->fs, path_out_fileName); + + } + + FRESULT fr; + fr = f_unlink_i(env->fs, path_dir_rep_fileName); + fr = f_unlink_i(env->fs, path_dir_mask_fileName); + fr = f_unlink_i(env->fs, path_dir_info_fileName); + + env->rtcIo->get(&env->rtcIo, &env->eventWebState.EVENT_OUTBOX); + env->rtcIo->get(&env->rtcIo, &env->eventWebState.EVENT_TRACERT); + env->rtcIo->get(&env->rtcIo, &env->eventWebState.EVENT_SENTBOX); + + env->stateRequest.stateReqCreateExtW = StateReqExtForCreate; + env->stateRequest.stateReqCreateExtT = StateReqExtForCreate; + + return true; +} + +// Обработчик создания исходящих пакетов в модем +bool HandlerModemOutPaket(tModemMain *env) { + tFileSendInfo fileSendInfo; + + FRESULT fr; + DIR dj; + FILINFO fno; + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + bool resultKvit; + + // Модем освободил слот + for (int id = 0; id < 16; ++id) { + if (env->modemStatus.status[id] == SLOT_FREE) { + env->modemStatus.idMessage[id] = 0; + } + } + + bool result = true; + bool isStopSend = false; + +// fr = f_findfirst_i(env->fs, &dj, &fno, dir_rep_out, "*.INF"); +// while (fr == FR_OK && fno.fname[0]) { + env->mnumBufScanCount = 0; + + uint32_t mnum = getMaxUrgencyRepout(env); + while (mnum) { + +// bool isSlotFree = getIsSlotsFree(env); +// if (isSlotFree == false) { +// break; +// } + + // Запись уже просканированных файлов + env->mnumBufScan[env->mnumBufScanCount] = mnum; + ++env->mnumBufScanCount; + if (env->mnumBufScanCount > sizeof(env->mnumBufScan)) + return true; + + uint32_t idFile = mnum; + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_rep_out, idFile); + + bool resultFileInfo = readSendFileInfo(env->fs, &fileSendInfo, path_dir_info_fileName); + if (resultFileInfo == false) { + fr = f_findnext_i(env->fs, &dj, &fno); + continue; + } + + // Поиск не отправленных блоков в файле маски + bool isFind; + //result = isFindMaskPacketTransport(env->fs, &isFind, path_dir_mask_fileName, &fileSendInfo); + result = isFindMaskPacketTransportIsNotProc(env->fs, &isFind, path_dir_mask_fileName); + if (result == false) { + break; + } + + // Контроль состояния процентов индикации отправки +// if (fileSendInfo.typeFile == TYPE_FILE_MESSAGE) { +// result = createBufStateFileSend(env->fs, env->fileSendInfoForJson, 32); +// if (result == false) { +// break; +// } +// } + +// resultFileInfo = writeSendFileInfo(env->fs, &fileSendInfo, path_dir_info_fileName); +// if (resultFileInfo == false) { +// env->modemSlotSendStatusReload = true; +// return false; +// } + + // Если найдены не отправленные блоки + if (isFind) { +//начало------------------------------------Отправка пакетов на модем--------------------------------------------------- +//начало------------------------------------Отправка пакетов на модем--------------------------------------------------- +//начало------------------------------------Отправка пакетов на модем--------------------------------------------------- + bool isFrom = true; + bool isSlotFree = true; + uint32_t from = 0; + uint32_t lenTransPaket = 0; + + while ((isFrom) && (isSlotFree)) { + + // Если модем в передаче не передавать данные в модем + if (env->pwramp) { + isSlotFree = false; + break; + } + + // Проверка ограничения канала + uint32_t memSize = getSlotsMemSize(env); + if (memSize / 1300 > env->store->nvm.Settings_Basic_Access.MaxSzDataOnKB_v) { + isSlotFree = false; + break; + } + + + tStructTransportPacket *trans; + tStructRepresentationPacket *rep; + + if (fileSendInfo.typeFile == TYPE_FILE_KVITIN) { + + if (lenTransPaket > 0) + lenTransPaket -= sizeof(tStructTransportKvitPacket); + + result = createPacketKvitin(env->fs, + from + lenTransPaket, + env->bufSendPacket, + &isFrom, + &from, + &lenTransPaket, + &fileSendInfo, + env->rtcIo, + path_dir_rep_fileName, + path_dir_mask_fileName); + + } else { + + if (lenTransPaket > 0) + lenTransPaket -= sizeof(tStructTransportPacket); + + result = createPacketTransport(env->fs, + from + lenTransPaket, + env->bufSendPacket, + &isFrom, + &from, + &lenTransPaket, + &fileSendInfo, + env->rtcIo, + path_dir_rep_fileName, + path_dir_mask_fileName); + + trans = (tStructTransportPacket *) &env->bufSendPacket[0]; + rep = (tStructRepresentationPacket *) &env->bufSendPacket[sizeof(tStructTransportPacket)]; + + } + + if (result == false) { + env->modemSlotSendStatusReload = true; + return false; + } + + // Проверка на уже переданный модему блок + bool isNoSend = true; + for (int i = 0; i < 16; ++i) { + if ((env->modemStatus.id[i] != 0) && + (env->modemStatus.sendFrom[i] == from) && + (env->modemStatus.sendLen[i] == lenTransPaket) && + (env->modemStatus.idMessage[i] == fileSendInfo.mnum)) { + isNoSend = false; + break; + } + } + + // Если блок уже загружен в модем, то перейти к проверке следующего блока + if (isNoSend == false) { + continue; + //break; + } + + + // Найден не отправленный блок + if ((isFrom) && (isNoSend)) { + + // Поиск более приоритетных сообщений !!!!!!!!!!!!!! + if (getIsSlotsFree(env) == false) { + for (int i = 0; i < 16; ++i) { + if ((env->modemStatus.urgency[i] < fileSendInfo.urgency) && + (env->modemStatus.idMessage[i] != 0)) { + + char buffer[12]; + utoa(i + 1, buffer, 10); + //result = SlotClear(env, buffer); + + isStopSend = true; + result = ModemStopSend(env); + result = SlotClearNoStopTask(env, buffer); + + // Запрос слотов передачи + result = ModemGetSlot(env, env->modemStatus.id, + (uint8_t *) env->modemStatus.status, 16); + break; + } + } + } + + bool isNotSlotFree = true; + + for (int i = 0; i < 16; ++i) { + if (env->modemStatus.status[i] == SLOT_FREE) { + isNotSlotFree = false; + + if (isStopSend == false) { + isStopSend = true; + if (env->modemWorkingState != MODEM_WORKING_MSG) { + // Останов регистрации + StopRegTask(env); + // Останов альманаха + AlmaStop(env); + } + result = ModemStopSend(env); + } + + // ModemStopSend(env); + + uint32_t urgency = fileSendInfo.urgency; + if (fileSendInfo.urgency > 3) { + urgency = 3; + } + +#ifdef DEBUG_EXT_MODEM + char bufText[128]; + bufText[0] = '\0'; + + // Квитанция + if (fileSendInfo.typeFile == TYPE_FILE_KVITIN) { + + tStructTransportKvitPacket *transKvit = (tStructTransportKvitPacket *) &env->bufSendPacket[0]; + + strcat(bufText, "Загрузка пакета квитанции на сообщение номер "); + + char buf[12]; + utoa(transKvit->numberMessage, buf, 10); + strcat(bufText, buf); + + strcat(bufText, ", получатель АТ-"); + utoa(atoi(fileSendInfo.to), buf, 10); + strcat(bufText, buf); + + LoggerInfo(LOGGER, LOG_SIGN, bufText, strlen(bufText)); + } else { + strcat(bufText, "Загрузка пакета номер "); + + char buf[12]; + utoa(trans->numberMessage, buf, 10); + strcat(bufText, buf); + strcat(bufText, ", смещение "); + utoa(trans->offsetPacket, buf, 10); + strcat(bufText, buf); + strcat(bufText, ", получатель АТ-"); + utoa(atoi(fileSendInfo.to), buf, 10); + strcat(bufText, buf); + + + LoggerInfo(LOGGER, LOG_SIGN, bufText, strlen(bufText)); + } +#endif + + uint32_t adrAT; + if (isTo(fileSendInfo.to, '@')) { + adrAT = 7; + } else { + adrAT = atoi(fileSendInfo.to); + } + + // Запись данных в пакет + result = SlotWrite(env, i, env->store->nvm.Settings_Basic_Access.NumRegStation_v, + adrAT, + urgency, + fileSendInfo.kvs, lenTransPaket); + + //bool resultStartSend = ModemStartSend(env); + //if (resultStartSend) + // env->modemWorkingState = MODEM_WORKING_MSG; + //SystemDelayMs(1000); + + + //result = true; + if (result) { + env->modemStatus.idMessage[i] = fileSendInfo.mnum; + env->modemStatus.sendFrom[i] = from; + env->modemStatus.sendLen[i] = lenTransPaket; + env->modemStatus.urgency[i] = fileSendInfo.urgency; + env->modemStatus.sos[i] = fileSendInfo.sos; + env->modemStatus.type[i] = fileSendInfo.typeFile; + env->modemStatus.status[i] = SLOT_INIT; + break; + } else { + env->modemSlotSendStatusReload = true; + return false; + } + } + } + + // Если все слоты заняты + if (isNotSlotFree) + isSlotFree = false; + + } + + } + +//конец-------------------------------------Отправка пакетов на модем--------------------------------------------------- +//конец-------------------------------------Отправка пакетов на модем--------------------------------------------------- +//конец-------------------------------------Отправка пакетов на модем--------------------------------------------------- + } else { +// Перенос файлов в отправленные + ToSentFiles(env, &fileSendInfo, path_dir_rep_fileName, path_dir_mask_fileName, path_dir_info_fileName); + } + + +// fr = f_findnext_i(env->fs, &dj, &fno); + + mnum = getMaxUrgencyRepout(env); + } +// fr = f_closedir_i(env->fs, &dj); + + if (isStopSend) { + bool resultStartSend = ModemStartSend(env); + if (resultStartSend) + env->modemWorkingState = MODEM_WORKING_MSG; + } + + + bool isSos = false; + + fr = f_findfirst_i(env->fs, &dj, &fno, dir_rep_out, "*.INF"); + while (fr == FR_OK && fno.fname[0]) { + + uint32_t idFile = atoi(fno.fname); + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_rep_out, idFile); + + bool resultFileInfo = readSendFileInfo(env->fs, &fileSendInfo, path_dir_info_fileName); + + if (resultFileInfo == false) { + fr = f_findnext_i(env->fs, &dj, &fno); + continue; + } + + // Есть файл SOS + if (fileSendInfo.sos == 1) { + isSos = true; + } + + // Поиск неотправленных блоков в файле маски + bool isFind; + if (isFindMaskPacketTransportIsNotProc(env->fs, &isFind, path_dir_mask_fileName) == false) { + fr = f_findnext_i(env->fs, &dj, &fno); + continue; + } + + if (isFind == false) { +// Перенос файлов в отправленные + ToSentFiles(env, &fileSendInfo, path_dir_rep_fileName, path_dir_mask_fileName, path_dir_info_fileName); + + } + + fr = f_findnext_i(env->fs, &dj, &fno); + } + fr = f_closedir_i(env->fs, &dj); + + // Файлов SOS нет + if (isSos == false) { + if (env->store->nvm.flagSos == 1) { + env->store->nvm.flagSos = 0; + DeviceStorageCounterIni_DumpSos(env->store); + env->stateRequest.stateReqCreateExtW = StateReqExtForCreate; + env->stateRequest.stateReqCreateExtT = StateReqExtForCreate; + } + } + + return result; +} + + +int isFilesRepOutInModem(tModemMain *env) { + // Запрос слотов передачи + RequestModemSendSlots(env); + + for (int id = 0; id < 16; ++id) { + if (env->modemStatus.status[id] == SLOT_READY_READ_OR_WRITE) { + return 1; + } + } + + return 0; +} + +// Запуск задачи модема +void RunStopTaskModem(tModemMain *env) { + + bool result1, result2, result3; + + if (isFilesRepOutInModem(env) > 0) { + + if (env->modemWorkingState != MODEM_WORKING_MSG) { + // Останов регистрации + result1 = StopRegTask(env); + // Останов альманаха + result2 = AlmaStop(env); + // Запуск передачи сообщений + result3 = ModemStartSend(env); + + if ((result1) && (result2) && (result3)) + env->modemWorkingState = MODEM_WORKING_MSG; + + } + + + } else { + if (env->stateRequest.stateReqAlma == StateReqAlmaSendStatus) { + + if (env->modemWorkingState != MODEM_WORKING_ALMA) { + // Останов задачи передачи сообщений + result1 = ModemStopSend(env); + // Останов регистрации + result2 = StopRegTask(env); + // Запуск альманаха + result3 = AlmaRun(env); + + if ((result1) && (result2) && (result3)) + env->modemWorkingState = MODEM_WORKING_ALMA; + + } + + + } else { + if (env->stateRequest.stateReqReg == StateReqRegSendStatus) { + + if (env->modemWorkingState != MODEM_WORKING_REG) { + // Останов передачи сообщений + result1 = ModemStopSend(env); + // Останов альманаха + result2 = AlmaStop(env); + // Запуск регистрации + result3 = StartRegTask(env); + + if ((result1) && (result2) && (result3)) + env->modemWorkingState = MODEM_WORKING_REG; + + } + } else { + + if (env->modemWorkingState != MODEM_WORKING_NONE) { + // Останов передачи сообщений + result1 = ModemStopSend(env); + // Останов альманаха + result2 = AlmaStop(env); + // Останов регистрации + result3 = StopRegTask(env); + + if ((result1) && (result2) && (result3)) + env->modemWorkingState = MODEM_WORKING_NONE; + + } + + + } + } + } + +} + +// Количество файлов +int getCountFiles(tModemMain *env, char *path) { + FRESULT fr; + DIR dj; + FILINFO fno; + + int count = 0; + + fr = f_findfirst_i(env->fs, &dj, &fno, path, "*.OTM"); + + while (fr == FR_OK && fno.fname[0]) { + + ++count; + fr = f_findnext_i(env->fs, &dj, &fno); + } + + fr = f_closedir_i(env->fs, &dj); + + return count; +} + + +// Количество файлов в отправке +int getCountOutbox(tModemMain *env) { + FRESULT fr; + DIR dj; + FILINFO fno; + FILINFO fnoInf; + FRESULT frInf; + tFileSendInfo fileSendInfo; + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + int count = 0; + + fr = f_findfirst_i(env->fs, &dj, &fno, dir_rep_out, "*.INF"); + + while (fr == FR_OK && fno.fname[0]) { + + uint32_t idFile = atoi(fno.fname); + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_rep_out, idFile); + + bool resultFileInfo = readSendFileInfo(env->fs, &fileSendInfo, path_dir_info_fileName); + if (resultFileInfo == false) { + fr = f_findnext_i(env->fs, &dj, &fno); + continue; + } + + fr = f_findnext_i(env->fs, &dj, &fno); + } + + fr = f_closedir_i(env->fs, &dj); + + return count; +} + + +// Котроль файлов в отправке и приеме +void controlFiles(tFs *fs, char *ext, char *path) { + FRESULT fr; + DIR dj; + FILINFO fno; + + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + fr = f_findfirst_i(fs, &dj, &fno, path, ext); + + while (fr == FR_OK && fno.fname[0]) { + + // Получение указателя на расширение файла + char *pExt = getVoidExt((char *) fno.fname); + + if ((strcmp(pExt, ".REP") != 0) && (strcmp(pExt, ".INF") != 0) && (strcmp(pExt, ".MSK") != 0)) { + char path_fileName[MAX_LEN_PATH_FS]; + path_fileName[0] = '\0'; + + strcat(path_fileName, path); + strcat(path_fileName, fno.fname); + + fr = f_unlink_i(fs, path_fileName); + } else { + + uint32_t idFile = atoi(fno.fname); + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) path, idFile); + + FILINFO fnoInf; + FRESULT frInf = f_stat(path_dir_info_fileName, &fnoInf); + + FILINFO fnoRep; + FRESULT frRep = f_stat(path_dir_rep_fileName, &fnoRep); + + FILINFO fnoMsk; + FRESULT frMsk = f_stat(path_dir_mask_fileName, &fnoMsk); + + if ((frRep) || (frMsk) || (frInf)) { + fr = f_unlink_i(fs, path_dir_rep_fileName); + fr = f_unlink_i(fs, path_dir_mask_fileName); + fr = f_unlink_i(fs, path_dir_info_fileName); + } + + } + fr = f_findnext_i(fs, &dj, &fno); + } + + fr = f_closedir_i(fs, &dj); + +} + + +// Поиск и создание файла представления +bool CreateModemOutPaket(tFs *fs, tGonetsReedSalmon *gonetsReedSalmon, md5a_context *md5ctx, tRtcIO *rtcIo, + tTypeFile typeFile, tDeviceStorageIni *store, int32_t gr) { + // Имя файла исходящего сообщения + char out_fileName[MAX_LEN_PATH_FS]; + // Полный путь с именем файла до файла исходящего сообщения + char path_out_fileName[MAX_LEN_PATH_FS]; + // Структура содержащая информацию по исходящему сообщению +// tFileSendInfo fileSendInfo; + + uint32_t id = 0; + + // Контроль файлов в отправке + controlFiles(fs, "*", (char *) dir_rep_out); + + // Поиск самого сообщения + if (typeFile == TYPE_FILE_TRACERT) { + id = getMaxUrgencyOutbox(fs, gonetsReedSalmon, md5ctx, rtcIo, (char *) dir_tracert, out_fileName, + path_out_fileName, typeFile, store, gr); +// } else if (typeFile == TYPE_FILE_KVITIN) { +// id = getMaxUrgencyOutbox(fs, gonetsReedSalmon, md5ctx, rtcIo, (char *) dir_kvitin, out_fileName, +// path_out_fileName, typeFile, store, gr); + } else { + id = getMaxUrgencyOutbox(fs, gonetsReedSalmon, md5ctx, rtcIo, (char *) dir_outbox, out_fileName, + path_out_fileName, typeFile, store, gr); + + } + + return true; +} + + +// Удаление файлов сообщения из отправки (контроль сравнения в отправке) +bool delRepoutMessage(tModemMain *env) { + FRESULT fr; + DIR dj; + FILINFO fno; + FILINFO fnoInf; + FRESULT frInf; + tFileSendInfo fileSendInfo; + char fileNameInOutbox[MAX_LEN_PATH_FS]; + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + char strId[MAX_LEN_PATH_FS]; + strId[0] = '\0'; + + bool isDelModem = false; + + fr = f_findfirst_i(env->fs, &dj, &fno, dir_rep_out, "*.INF"); + + while (fr == FR_OK && fno.fname[0]) { + + uint32_t idFile = atoi(fno.fname); + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_rep_out, idFile); + + bool resultFileInfo = readSendFileInfo(env->fs, &fileSendInfo, path_dir_info_fileName); + if (resultFileInfo == false) { + fr = f_findnext_i(env->fs, &dj, &fno); + continue; + } + + // Тип файла - сообщение + if (fileSendInfo.typeFile != TYPE_FILE_TRACERT) { + + createFileNameForId(fileNameInOutbox, (char *) dir_outbox, fileSendInfo.mnum, "OTM"); + + // Если файл в исходящих не найден, то удаляем его + frInf = f_stat(fileNameInOutbox, &fnoInf); + if (frInf) { + + for (int i = 0; i < 16; ++i) { + if (env->modemStatus.idMessage[i] == fileSendInfo.mnum) { + env->modemStatus.idMessage[i] = 0; + isDelModem = true; + char buffer[12]; + utoa(i + 1, buffer, 10); + strcat(strId, buffer); + strcat(strId, ","); + } + } + + fr = f_unlink_i(env->fs, path_dir_rep_fileName); + fr = f_unlink_i(env->fs, path_dir_mask_fileName); + fr = f_unlink_i(env->fs, path_dir_info_fileName); + + } + + + } + + + // Тип файла - трассировка + if (fileSendInfo.typeFile == TYPE_FILE_TRACERT) { + + createFileNameForId(fileNameInOutbox, (char *) dir_tracert, fileSendInfo.mnum, "OTM"); + + // Если файл в исходящих не найден, то удаляем его + frInf = f_stat(fileNameInOutbox, &fnoInf); + if (frInf) { + + for (int i = 0; i < 16; ++i) { + if (env->modemStatus.idMessage[i] == fileSendInfo.mnum) { + env->modemStatus.idMessage[i] = 0; + isDelModem = true; + char buffer[12]; + utoa(i + 1, buffer, 10); + strcat(strId, buffer); + strcat(strId, ","); + } + } + + fr = f_unlink_i(env->fs, path_dir_rep_fileName); + fr = f_unlink_i(env->fs, path_dir_mask_fileName); + fr = f_unlink_i(env->fs, path_dir_info_fileName); + + } + + + } + + + fr = f_findnext_i(env->fs, &dj, &fno); + } + fr = f_closedir_i(env->fs, &dj); + + bool result = true; + + // Отправка на модем команды удаления пакетов + if (isDelModem) { + strId[strlen(strId) - 1] = '\0'; + + //result = SlotClear(env, strId); + result = SlotClearNoStartTask(env, strId); + } + + + return result; +} + + +// Удаление файлов трассировки из отправки +bool delRepout(tModemMain *env, tTypeFile typeFile, bool isDelFiles, bool isAllFiles) { + FRESULT fr; + DIR dj; + FILINFO fno; + tFileSendInfo fileSendInfo; + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + char strId[MAX_LEN_PATH_FS]; + strId[0] = '\0'; + + bool isDelModem = false; + + fr = f_findfirst_i(env->fs, &dj, &fno, dir_rep_out, "*.INF"); + + while (fr == FR_OK && fno.fname[0]) { + + uint32_t idFile = atoi(fno.fname); + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_rep_out, idFile); + + bool resultFileInfo = readSendFileInfo(env->fs, &fileSendInfo, path_dir_info_fileName); + if (resultFileInfo == false) { + fr = f_findnext_i(env->fs, &dj, &fno); + continue; + } + + // Тип файла - трассировка + if ((fileSendInfo.typeFile == typeFile) || (isAllFiles)) { + + for (int i = 0; i < 16; ++i) { + if (env->modemStatus.idMessage[i] == fileSendInfo.mnum) { + env->modemStatus.idMessage[i] = 0; + isDelModem = true; + char buffer[12]; + utoa(i + 1, buffer, 10); + strcat(strId, buffer); + strcat(strId, ","); + } + } + + if (isDelFiles) { + fr = f_unlink_i(env->fs, path_dir_rep_fileName); + fr = f_unlink_i(env->fs, path_dir_mask_fileName); + fr = f_unlink_i(env->fs, path_dir_info_fileName); + } + } + + fr = f_findnext_i(env->fs, &dj, &fno); + } + fr = f_closedir_i(env->fs, &dj); + + bool result = true; + + // Отправка на модем команды удаления пакетов + if (isDelModem) { + strId[strlen(strId) - 1] = '\0'; + + result = SlotClearNoStartTask(env, strId); + } + + return result; +} + +// Удаление самого старого файла +bool delRepoutOld(tModemMain *env) { + FRESULT fr; + DIR dj; + FILINFO fno; + FILINFO fnoInf; + FRESULT frInf; + tFileSendInfo fileSendInfo; + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + char strId[MAX_LEN_PATH_FS]; + strId[0] = '\0'; + + uint32_t minNum = 0xFFFFFFFF; + + bool isDelModem = false; + + fr = f_findfirst_i(env->fs, &dj, &fno, dir_rep_out, "*.INF"); + + char path_Old_fileName[MAX_LEN_PATH_FS]; + path_Old_fileName[0] = '\0'; + + while (fr == FR_OK && fno.fname[0]) { + + uint32_t idFile = atoi(fno.fname); + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_rep_out, idFile); + + bool resultFileInfo = readSendFileInfo(env->fs, &fileSendInfo, path_dir_info_fileName); + if (resultFileInfo == false) { + fr = f_findnext_i(env->fs, &dj, &fno); + continue; + } + + // Самый старый файл + frInf = f_stat(path_dir_rep_fileName, &fnoInf); + if (frInf == FR_OK) { + if (fileSendInfo.mnum < minNum) { + minNum = fileSendInfo.mnum; + } + } + + fr = f_findnext_i(env->fs, &dj, &fno); + } + fr = f_closedir_i(env->fs, &dj); + + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_rep_out, minNum); + + + for (int i = 0; i < 16; ++i) { + if (env->modemStatus.idMessage[i] == minNum) { + env->modemStatus.idMessage[i] = 0; + isDelModem = true; + char buffer[12]; + utoa(i + 1, buffer, 10); + strcat(strId, buffer); + strcat(strId, ","); + } + } + + fr = f_unlink_i(env->fs, path_dir_rep_fileName); + fr = f_unlink_i(env->fs, path_dir_mask_fileName); + fr = f_unlink_i(env->fs, path_dir_info_fileName); + + bool result = true; + + // Отправка на модем команды удаления пакетов + if (isDelModem) { + strId[strlen(strId) - 1] = '\0'; + + result = SlotClearNoStartTask(env, strId); + } + + return result; +} + +// Удаление самого старого файла +bool delFilesOld(tModemMain *env, char *path) { + FRESULT fr; + DIR dj; + FILINFO fno; + FILINFO fnoInf; + FRESULT frInf; + + uint32_t minNum = 0; + uint32_t minData = 0xFFFFFFFF; + uint32_t curDara = 0; + +// char path_dir_rep_fileName[MAX_LEN_PATH_FS]; +// char path_dir_mask_fileName[MAX_LEN_PATH_FS]; +// char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + + char strId[MAX_LEN_PATH_FS]; + strId[0] = '\0'; + + char path_fileName[MAX_LEN_PATH_FS]; + path_fileName[0] = '\0'; + + bool isDelModem = false; + + fr = f_findfirst_i(env->fs, &dj, &fno, path, "*.OTM"); + + while (fr == FR_OK && fno.fname[0]) { + + uint32_t idFile = atoi(fno.fname); + createFileNameForId(path_fileName, (char *) path, idFile, "OTM"); + + // Самый старый файл + frInf = f_stat(path_fileName, &fnoInf); + if (frInf == FR_OK) { + curDara = fno.ftime | (fno.fdate << 16); + + if (curDara < minData) { + minData = curDara; + minNum = idFile; + } + } + + fr = f_findnext_i(env->fs, &dj, &fno); + } + fr = f_closedir_i(env->fs, &dj); + + createFileNameForId(path_fileName, (char *) path, minNum, "OTM"); + fr = f_unlink_i(env->fs, path_fileName); + createFileNameForId(path_fileName, (char *) path, minNum, "DAT"); + fr = f_unlink_i(env->fs, path_fileName); +/* + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_rep_out, minNum); + + fr = f_unlink_i(env->fs, path_dir_rep_fileName); + fr = f_unlink_i(env->fs, path_dir_mask_fileName); + fr = f_unlink_i(env->fs, path_dir_info_fileName); + + + bool result = true; + + for (int i = 0; i < 16; ++i) { + if (env->modemStatus.idMessage[i] == minNum) { + env->modemStatus.idMessage[i] = 0; + isDelModem = true; + char buffer[12]; + utoa(i + 1, buffer, 10); + strcat(strId, buffer); + strcat(strId, ","); + } + } + + // Отправка на модем команды удаления пакетов + if (isDelModem) { + strId[strlen(strId) - 1] = '\0'; + + result = SlotClearNoStartTask(env, strId); + } + + + return result; + */ + return true; +} + + +bool ModemMain_CreateOutFiles(tModemMain *env, tTypeFile typeFile, int32_t gr) { + bool result = true; + +// Обработчик создания файлов представления + if (osMutexAcquire(env->accessMODEM, TIME_MUTEX_MODEM_ACCESS) == osOK) { + md5a_starts(&env->md5ctx_t); + result = CreateModemOutPaket(env->fs, &env->GonetsReedSalmonParity4, &env->md5ctx_t, env->rtcIo, typeFile, + env->store, gr); + osMutexRelease(env->accessMODEM); + } else { + return false; + } + return result; +} + + +//начало -------------------------Контроль создания файлов сообщений---------------------------------------------------- +//начало -------------------------Контроль создания файлов сообщений---------------------------------------------------- +//начало -------------------------Контроль создания файлов сообщений---------------------------------------------------- +void RequestSendMessagesModemSlots(tModemMain *env) { + + // Если модем в передаче не передавать данные в модем + if (env->pwramp) + return; + + bool isEdit = false; + + // Контроль удаления файлов Сообщений + if (env->stateRequest.stateReqDelExtW == StateReqExtForDel) { + env->stateRequest.stateReqDelExtW = StateReqExtNone; + delRepoutMessage(env); + isEdit = true; + } + + // Контроль удаления файлов Трассировки + if (env->stateRequest.stateReqDelExtT == StateReqExtForDel) { + env->stateRequest.stateReqDelExtT = StateReqExtNone; + delRepoutMessage(env); + + if ((env->store->nvm.Settings_Tracert.PeSvCoor_v == 0) || + (env->store->nvm.Settings_Tracert.mTracer_v == 0)) { + delRepout(env, TYPE_FILE_TRACERT, true, false); + } else { + env->stateRequest.stateReqCreateExtT = StateReqExtForCreate; + } + + isEdit = true; + } + + + // Контроль создания файлов Сообщений + if (env->stateRequest.stateReqCreateExtW == StateReqExtForCreate) { + env->stateRequest.stateReqCreateExtW = StateReqExtNone; + + ModemMain_CreateOutFiles(env, TYPE_FILE_MESSAGE, env->store->nvm.Settings_General.GMTcorr_v); + + // Количество файлов в tracert + uint32_t count = getCountFiles(env, (char *) dir_outbox); + + bool isDelFiles = false; + + while (count > (maxFilesOutBox - 1)) { + + // Удаление самого старого файла outbox + delFilesOld(env, (char *) dir_outbox); + isDelFiles = true; + + // Количество файлов в outbox + count = getCountFiles(env, (char *) dir_outbox); + + } + + if (isDelFiles) + delRepoutMessage(env); + + if (osMutexAcquire(env->accessHTTP, TIME_MUTEX_HTTP_ACCESS) == osOK) { + createBufStateFileSend(env->fs); + osMutexRelease(env->accessHTTP); + } + + isEdit = true; + } + + // Контроль создания файлов Трассировки + if (env->stateRequest.stateReqCreateExtT == StateReqExtForCreate) { + env->stateRequest.stateReqCreateExtT = StateReqExtNone; + + /* + int step = 0; + // Количество файлов в отправке + uint32_t count = getCountOutbox(env, TYPE_FILE_TRACERT); + while (count > env->store->nvm.Settings_Tracert.cntPackExtCoord_v) { + // Удаление самого старого файла + delRepoutOld(env, TYPE_FILE_TRACERT); + // Количество файлов в отправке + count = getCountOutbox(env, TYPE_FILE_TRACERT); + + ++step; + if (step == 15) + break; + } +*/ + +/* + // Количество файлов в tracert + uint32_t count = getCountTracert(env); + + while (count > 15) { + + // Удаление самого старого файла tracert + delTracertOld(env); + + // Количество файлов в tracert + count = getCountTracert(env); + + } +*/ + + if ((env->store->nvm.Settings_Tracert.PeSvCoor_v != 0) && + (env->store->nvm.Settings_Tracert.mTracer_v != 0)) { + + if (osMutexAcquire(env->accessTracert, 2000) == osOK) { + + // Создание файлов уровня представления + ModemMain_CreateOutFiles(env, TYPE_FILE_TRACERT, env->store->nvm.Settings_General.GMTcorr_v); + + osMutexRelease(env->accessTracert); + } + } + + isEdit = true; + } + + if (isEdit) { + // Запрос слотов передачи + RequestModemSendSlots(env); +/* + // начало Тест + if (env->testOne) { + --env->testOne; + // начало Тест + for (int i = 0; i < 2; ++i) { + env->modemStatus.status[i] = SLOT_READY_SENDING; + } + // конец Тест + //env->state = 1; + } + // конец Тест +*/ + + // Обработчик создания исходящих пакетов в модем + bool result = HandlerModemOutPaket(env); + + int step = 0; + + // Если произошла ошибка: Обработчик создания исходящих пакетов в модем + while (env->modemSlotSendStatusReload) { + // Если модем в передаче не передавать данные в модем + if (env->pwramp) + break; + +#ifdef DEBUG_MODEM + LoggerInfoStatic(LOGGER, LOG_SIGN, "Обнаружена ошибка в процедуре формирования исходящих сообщений\n") + LoggerInfoStatic(LOGGER, LOG_SIGN, "Повтор процедуры формирования исходящих сообщений\n") +#endif + SystemDelayMs(1000); + + env->modemSlotSendStatusReload = false; + // Запрос слотов передачи + RequestModemSendSlots(env); + // Обработчик создания исходящих пакетов в модем + result = HandlerModemOutPaket(env); + + ++step; + if (step >= 3) + break; + } + + // Запуск задач модема + RunStopTaskModem(env); + + } + + +} +//конец --------------------------Контроль создания файлов сообщений---------------------------------------------------- +//конец --------------------------Контроль создания файлов сообщений---------------------------------------------------- +//конец --------------------------Контроль создания файлов сообщений---------------------------------------------------- diff --git a/Src/ModemSendFunc.c b/Src/ModemSendFunc.c new file mode 100644 index 0000000..aef1e27 --- /dev/null +++ b/Src/ModemSendFunc.c @@ -0,0 +1,1433 @@ +// +// Created by cfif on 21.02.23. +// +#include "ModemSendFunc.h" +#include "GonetsCrcs.h" +#include "ModemBufCreateHeader.h" + +extern uint8_t bufFreeOperation[1500]; +extern uint8_t bufFreeOperationKV[1500]; +extern uint8_t bufFillOperation[1500]; + +// Получение информации о исходящем файле +bool getInfoFromFileNameOutBox(tFs *fs, char *path, tFileSendInfo *fileSendInfo, uint32_t *cuteOffsetBegin) { + FRESULT fr; + char bufDumpFile[512]; + int stepParam = 0; + + struct { + int paramcount; + char *params_names[MAX_POST_GET_PARAMETERS]; + char *params_vals[MAX_POST_GET_PARAMETERS]; + } params_uri; + + *cuteOffsetBegin = 0; + + FIL file; + fr = f_open_i(fs, &file, (TCHAR *) path, FA_READ); + if (fr != FR_OK) return false; + + UINT bytes_read; + fr = f_read_i(fs, &file, bufDumpFile, 512, &bytes_read); + if (fr != FR_OK) { + fr = f_close_i(fs, &file); + return false; + } + + fr = f_close_i(fs, &file); + + params_uri.paramcount = extract_uri_ex_parameters(bufDumpFile, params_uri.params_names, + params_uri.params_vals, + MAX_POST_GET_PARAMETERS); + + for (int i = 0; i < params_uri.paramcount; ++i) { + + if (strcmp(params_uri.params_names[i], "mnum") == 0) { + fileSendInfo->mnum = atoi(params_uri.params_vals[i]); + ++stepParam; + } + + if (strcmp(params_uri.params_names[i], "urgency") == 0) { + fileSendInfo->urgency = atoi(params_uri.params_vals[i]); + ++stepParam; + } + + + if (strcmp(params_uri.params_names[i], "kvt_num") == 0) { + fileSendInfo->kvt_num = atoi(params_uri.params_vals[i]); + ++stepParam; + } + + if (strcmp(params_uri.params_names[i], "kvt_mon") == 0) { + fileSendInfo->kvt_mon = atoi(params_uri.params_vals[i]); + ++stepParam; + } + + if (strcmp(params_uri.params_names[i], "kvt_day") == 0) { + fileSendInfo->kvt_day = atoi(params_uri.params_vals[i]); + ++stepParam; + } + + + if (strcmp(params_uri.params_names[i], "type") == 0) { + fileSendInfo->typeFile = atoi(params_uri.params_vals[i]); + ++stepParam; + *cuteOffsetBegin = params_uri.params_vals[i] - bufDumpFile - 5; + } + + if (strcmp(params_uri.params_names[i], "sos") == 0) { + + fileSendInfo->sos = atoi(params_uri.params_vals[i]); + ++stepParam; + } + + if (strcmp(params_uri.params_names[i], "chSv") == 0) { + fileSendInfo->chSv = atoi(params_uri.params_vals[i]); + ++stepParam; + } + + if (strcmp(params_uri.params_names[i], "kvs") == 0) { + fileSendInfo->kvs = atoi(params_uri.params_vals[i]); + ++stepParam; + } + + if (strcmp(params_uri.params_names[i], "from") == 0) { + fileSendInfo->from = atoi(params_uri.params_vals[i]); + ++stepParam; + } + + if (strcmp(params_uri.params_names[i], "to") == 0) { + extract_utf8_parameters(params_uri.params_vals[i], fileSendInfo->to, + sizeof(fileSendInfo->to)); + ++stepParam; + } + + if (strcmp(params_uri.params_names[i], "subj") == 0) { + extract_utf8_parameters(params_uri.params_vals[i], fileSendInfo->subj, + sizeof(fileSendInfo->subj)); + ++stepParam; + } + + if (strcmp(params_uri.params_names[i], "msg") == 0) { + ++stepParam; + + //fileSendInfo->typeFile = TYPE_FILE_MESSAGE; + + fileSendInfo->offsetMsg = params_uri.params_vals[i] - bufDumpFile; + fileSendInfo->fileName[0] = '\0'; + + if (strcmp(fileSendInfo->subj, "kvitin") == 0) { + fileSendInfo->typeFile = TYPE_FILE_KVITIN; + } + + +// if (strcmp(fileSendInfo->subj, "trace") == 0) { +// strcat(fileSendInfo->fileName, params_uri.params_vals[i]); +// fileSendInfo->typeFile = TYPE_FILE_TRACERT; +// } + + if (strcmp(fileSendInfo->subj, "file") == 0) { + strcat(fileSendInfo->fileName, params_uri.params_vals[i]); + + + char dirFileNameOut[MAX_LEN_PATH_FS]; + getPath(path, dirFileNameOut, 2); + + if (strcmp(dirFileNameOut, dir_tracert) == 0) { + + fileSendInfo->offsetMsg = 0; + + fileSendInfo->typeFile = TYPE_FILE_TRACERT; + + DIR dj; + FILINFO fnoInf; + char real_filename[MAX_LEN_PATH_FS]; + createFileNameForId(real_filename, (char *) dir_tracert, fileSendInfo->mnum, "DAT"); + + fr = f_stat(real_filename, &fnoInf); + + // Если не найден DAT + if (fr) { + f_unlink_i(fs, path); + return false; + } + + } + +/* + for (int j = params_uri.params_vals[i] - bufDumpFile; j < (int) sizeof(bufDumpFile); ++j) { + if (bufDumpFile[j] == '\0') { + ++fileSendInfo->offsetMsg; + ++fileSendInfo->offsetMsg; + break; + } + ++fileSendInfo->offsetMsg; + } + */ + } + + } + + } + + fileSendInfo->isSendAll = 0; + + if (stepParam < 10) + return false; + + return true; +} + +bool readSendFileInfo(tFs *fs, tFileSendInfo *fileSendInfo, char *path_inf_fileName) { + int result; +/* + fileSendInfo->typeFile = ini_getl("MAIN", "typeFile", 0, path_inf_fileName); + fileSendInfo->from = ini_getl("MAIN", "from", 0, path_inf_fileName); + fileSendInfo->mnum = ini_getl("MAIN", "mnum", 0, path_inf_fileName); + result = ini_gets("MAIN", "to", "0", fileSendInfo->to, MAX_LEN_PATH_FS, path_inf_fileName); + fileSendInfo->urgency = ini_getl("MAIN", "urgency", 0, path_inf_fileName); + fileSendInfo->chSv = ini_getl("MAIN", "chSv", 0, path_inf_fileName); + result = ini_gets("MAIN", "subj", "", fileSendInfo->subj, MAX_LEN_PATH_FS, path_inf_fileName); + fileSendInfo->kvs = ini_getl("MAIN", "kvs", 0, path_inf_fileName); + result = ini_gets("MAIN", "fileName", "", fileSendInfo->fileName, MAX_LEN_PATH_FS, path_inf_fileName); + fileSendInfo->dateDay = ini_getl("MAIN", "dateDay", 0, path_inf_fileName); + fileSendInfo->dateMon = ini_getl("MAIN", "dateMon", 0, path_inf_fileName); + fileSendInfo->sizeFileRep = ini_getl("MAIN", "sizeFileRep", 0, path_inf_fileName); + fileSendInfo->isSendAll = ini_getl("MAIN", "isSendAll", 0, path_inf_fileName); + fileSendInfo->bytes_sending = ini_getl("MAIN", "bytes_sending", 0, path_inf_fileName); + fileSendInfo->bytes_no_sending = ini_getl("MAIN", "bytes_no_sending", 0, path_inf_fileName); + + fileSendInfo->routing = ini_getl("MAIN", "routing", 0, path_inf_fileName); + fileSendInfo->sos = ini_getl("MAIN", "sos", 0, path_inf_fileName); + + fileSendInfo->crc32_MSK = ini_getl("MAIN", "crc32_MSK", 0, path_inf_fileName); + fileSendInfo->crc32_REP = ini_getl("MAIN", "crc32_REP", 0, path_inf_fileName); +*/ + + FRESULT fr; + FIL file; + UINT br; + + fr = f_open_i(fs, &file, (TCHAR *) path_inf_fileName, FA_READ); + if (fr) { + return false; + } + + fr = f_read_i(fs, &file, fileSendInfo, sizeof(tFileSendInfo), &br); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + + fr = f_close_i(fs, &file); + + return true; +} + +bool writeSendFileInfo(tFs *fs, tFileSendInfo *fileSendInfo, char *path_inf_fileName) { + int result; +/* + result = ini_putl("MAIN", "typeFile", fileSendInfo->typeFile, path_inf_fileName); + result = ini_putl("MAIN", "from", fileSendInfo->from, path_inf_fileName); + result = ini_putl("MAIN", "mnum", fileSendInfo->mnum, path_inf_fileName); + result = ini_puts("MAIN", "to", fileSendInfo->to, path_inf_fileName); + result = ini_putl("MAIN", "urgency", fileSendInfo->urgency, path_inf_fileName); + result = ini_putl("MAIN", "chSv", fileSendInfo->chSv, path_inf_fileName); + result = ini_puts("MAIN", "subj", fileSendInfo->subj, path_inf_fileName); + result = ini_putl("MAIN", "kvs", fileSendInfo->kvs, path_inf_fileName); + result = ini_puts("MAIN", "fileName", fileSendInfo->fileName, path_inf_fileName); + result = ini_putl("MAIN", "dateDay", fileSendInfo->dateDay, path_inf_fileName); + result = ini_putl("MAIN", "dateMon", fileSendInfo->dateMon, path_inf_fileName); + result = ini_putl("MAIN", "sizeFileRep", fileSendInfo->sizeFileRep, path_inf_fileName); + result = ini_putl("MAIN", "isSendAll", fileSendInfo->isSendAll, path_inf_fileName); + result = ini_putl("MAIN", "bytes_sending", fileSendInfo->bytes_sending, path_inf_fileName); + result = ini_putl("MAIN", "bytes_no_sending", fileSendInfo->bytes_no_sending, path_inf_fileName); + result = ini_putl("MAIN", "routing", fileSendInfo->routing, path_inf_fileName); + result = ini_putl("MAIN", "sos", fileSendInfo->sos, path_inf_fileName); + result = ini_putl("MAIN", "crc32_MSK", fileSendInfo->crc32_MSK, path_inf_fileName); + result = ini_putl("MAIN", "crc32_REP", fileSendInfo->crc32_REP, path_inf_fileName); +*/ + + + FRESULT fr; + FIL file; + UINT bw; + + fr = f_open_i(fs, &file, (TCHAR *) path_inf_fileName, FA_WRITE | FA_CREATE_ALWAYS); + if (fr) { + return false; + } + + fr = f_write_i(fs, &file, fileSendInfo, sizeof(tFileSendInfo), &bw); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + + fr = f_close_i(fs, &file); + + return true; +} + +uint32_t getCountTracertInRepoutCute(tFs *fs, uint32_t max) { + FRESULT fr; + DIR dj; + FILINFO fno; + tFileSendInfo fileSendInfo; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + uint32_t count = 0; + + fr = f_findfirst_i(fs, &dj, &fno, dir_rep_out, "*.INF"); + + while (fr == FR_OK && fno.fname[0]) { + + uint32_t idFile = atoi(&fno.fname[0]); + createFileNameForId(path_dir_info_fileName, (char *) dir_rep_out, idFile, "INF"); + + bool resultFileInfo = readSendFileInfo(fs, &fileSendInfo, path_dir_info_fileName); + if (resultFileInfo == false) { + fr = f_findnext_i(fs, &dj, &fno); + continue; + } + + if (fileSendInfo.typeFile == TYPE_FILE_TRACERT) { + ++count; + if (count > max + 1) + break; + } + + fr = f_findnext_i(fs, &dj, &fno); + } + fr = f_closedir_i(fs, &dj); + + return count; +} + +uint32_t getCountTypeFileInRepout(tFs *fs, tTypeFile typeFile, uint32_t *idInRepout) { + FRESULT fr; + DIR dj; + FILINFO fno; + tFileSendInfo fileSendInfo; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + uint32_t count = 0; + + fr = f_findfirst_i(fs, &dj, &fno, dir_rep_out, "*.INF"); + + while (fr == FR_OK && fno.fname[0]) { + + uint32_t idFile = atoi(&fno.fname[0]); + createFileNameForId(path_dir_info_fileName, (char *) dir_rep_out, idFile, "INF"); + + bool resultFileInfo = readSendFileInfo(fs, &fileSendInfo, path_dir_info_fileName); + if (resultFileInfo == false) { + fr = f_findnext_i(fs, &dj, &fno); + continue; + } + + if (fileSendInfo.typeFile == typeFile) { + idInRepout[count] = idFile; + ++count; + + if (count >= 16) + return count; + + } + + fr = f_findnext_i(fs, &dj, &fno); + } + fr = f_closedir_i(fs, &dj); + + return count; +} + +uint32_t getOldOut(tFs *fs, char *path, uint32_t *idInRepout, uint32_t countIdInRepout) { + FRESULT fr; + DIR dj; + FILINFO fno; + + uint32_t minNum = 0xFFFFFFFF; + + fr = f_findfirst_i(fs, &dj, &fno, path, "*.OTM"); + + while (fr == FR_OK && fno.fname[0]) { + + uint32_t Num = atoi(&fno.fname[0]); + + if (Num < minNum) { + bool isFind = false; + for (uint32_t i = 0; i < countIdInRepout; ++i) { + if (idInRepout[i] == Num) { + isFind = true; + break; + } + } + + if (isFind == false) + minNum = Num; + } + + fr = f_findnext_i(fs, &dj, &fno); + } + fr = f_closedir_i(fs, &dj); + + if (minNum == 0xFFFFFFFF) + minNum = 0; + + return minNum; +} + + +/* +// Создание пакета транспортного уровня +bool +createPacketKvitin(tFs *fs, uint32_t offset, uint8_t *bufSendPacket, bool *isFrom, uint32_t *from, + uint32_t *lenTransPaket, + tFileSendInfo *fileSendInfo, + tRtcIO *rtcIo, char *path_rep_fileName, char *path_mask_fileName) { + uint8_t bufRead[512]; + FIL fileRep; + FIL fileMask; + FRESULT fr; + UINT brRep, brMask; // File read/write count + + // Создание заголовка транспортного пакета + tStructTransportKvitPacket *structTransportKvitPacket = (tStructTransportKvitPacket *) bufSendPacket; + + structTransportKvitPacket->versionProtocol = 1; + + structTransportKvitPacket->dataType = 8; // Квитанция на сообщение + + structTransportKvitPacket->numberSender = fileSendInfo->from; + + structTransportKvitPacket->dateCreateTransportPacketDay = fileSendInfo->dateDay; + structTransportKvitPacket->dateCreateTransportPacketMon = fileSendInfo->dateMon; + + structTransportKvitPacket->numberMessage = fileSendInfo->mnum; + + *isFrom = false; + bool isTo = false; + uint32_t stepFromOrTo = 0; + uint32_t stepFromOrTo_MaxLen = 0; + *from = 0; + uint32_t to = 0; + + // Открытие файла маски + fr = f_open_i(fs, &fileMask, (TCHAR *) path_mask_fileName, FA_READ); + if (fr) { + return false; + } + + fr = f_lseek_i(fs, &fileMask, offset); + if (fr) { + return false; + } + + for (;;) { + + fr = f_read_i(fs, &fileMask, bufRead, sizeof(bufRead), &brMask); + if (fr) { + fr = f_close_i(fs, &fileMask); + return false; + } + + for (uint32_t i = 0; i < brMask; ++i) { + + // Поиск неотправленного начала + if (*isFrom == false) { + if ((bufRead[i] == 0) || (bufRead[i] == 1)) { + *from = stepFromOrTo + offset; + + *isFrom = true; + } + } else { + // Поиск неотправленного конца + if (bufRead[i] == 0x55) { + to = stepFromOrTo + offset; + isTo = true; + break; + } + } + + ++stepFromOrTo; + + if (*isFrom) { + ++stepFromOrTo_MaxLen; + } + } + + + // Нашли начало и конец + if ((*isFrom) && (isTo)) + break; + + // Нашли данные для полного пакета + if (stepFromOrTo_MaxLen > LEN_TRANS_PACKET) { + to = stepFromOrTo + offset; + isTo = true; + break; + } + + // Нашли конец файла + if (brMask == 0) { + to = stepFromOrTo + offset; + isTo = true; + break; + } + } + fr = f_close_i(fs, &fileMask); + + + uint32_t dl = fileSendInfo->sizeFileRep - stepFromOrTo + *from; + + *lenTransPaket = 0; + if (*isFrom) { + + uint32_t leftFileSize = to - *from; + *lenTransPaket = TRANS_MIN(leftFileSize, LEN_TRANS_PACKET - sizeof(tStructTransportKvitPacket)); +// *lenTransPaket = TRANS_MIN(leftFileSize, 13); + + uint8_t *dataSendPacket = &bufSendPacket[sizeof(tStructTransportKvitPacket)]; + + // Открытие файла представления + fr = f_open_i(fs, &fileRep, (TCHAR *) path_rep_fileName, FA_READ); + if (fr) { + return false; + } + + fr = f_lseek_i(fs, &fileRep, *from); + if (fr) { + return false; + } + + fr = f_read_i(fs, &fileRep, dataSendPacket, *lenTransPaket, &brRep); + if (fr) { + fr = f_close_i(fs, &fileRep); + return false; + } + + fr = f_close_i(fs, &fileRep); + + *lenTransPaket += sizeof(tStructTransportKvitPacket); + + } + + return true; +} +*/ + +// Создание пакета квитанции +bool +createPacketKvitin(tFs *fs, uint32_t offset, uint8_t *bufSendPacket, bool *isFrom, uint32_t *from, + uint32_t *lenTransPaket, + tFileSendInfo *fileSendInfo, + tRtcIO *rtcIo, char *path_rep_fileName, char *path_mask_fileName) { + uint8_t bufRead[512]; + FIL fileRep; + FIL fileMask; + FRESULT fr; + UINT brRep, brMask; // File read/write count + + // Создание заголовка транспортного пакета + tStructTransportKvitPacket *structTransportKvitPacket = (tStructTransportKvitPacket *) bufSendPacket; + + structTransportKvitPacket->versionProtocol = 1; + + structTransportKvitPacket->dataType = 8; // Квитанция на сообщение + + structTransportKvitPacket->numberSender = fileSendInfo->from; + + structTransportKvitPacket->dateCreateTransportPacketDay = fileSendInfo->kvt_day; + structTransportKvitPacket->dateCreateTransportPacketMon = fileSendInfo->kvt_mon; + + structTransportKvitPacket->numberMessage = fileSendInfo->kvt_num; + + *isFrom = false; + bool isTo = false; + uint32_t stepFromOrTo = 0; + *from = 0; + uint32_t to = 0; + + // Открытие файла маски + fr = f_open_i(fs, &fileMask, (TCHAR *) path_mask_fileName, FA_READ); + if (fr) { + return false; + } + + fr = f_lseek_i(fs, &fileMask, offset); + if (fr) { + return false; + } + + for (;;) { + + fr = f_read_i(fs, &fileMask, bufRead, sizeof(bufRead), &brMask); + if (fr) { + fr = f_close_i(fs, &fileMask); + return false; + } + + for (uint32_t i = 0; i < brMask; ++i) { + + if (*isFrom == false) { + if ((bufRead[i] == 0) || (bufRead[i] == 0x56)) { + *from = stepFromOrTo + offset; + *isFrom = true; + } + } else { + if (bufRead[i] == 0x55) { + to = stepFromOrTo + offset; + isTo = true; + break; + } + } + + ++stepFromOrTo; + } + + if ((*isFrom) && (isTo)) + break; + + if (brMask == 0) { + to = stepFromOrTo + offset; + isTo = true; + break; + } + } + fr = f_close_i(fs, &fileMask); + + + *lenTransPaket = 0; + if (*isFrom) { + + uint32_t leftFileSize = to - *from; + *lenTransPaket = TRANS_MIN(leftFileSize, LEN_TRANS_PACKET - sizeof(tStructTransportKvitPacket)); +// *lenTransPaket = TRANS_MIN(leftFileSize, 13); + + uint8_t *dataSendPacket = &bufSendPacket[sizeof(tStructTransportKvitPacket)]; + + // Открытие файла представления + fr = f_open_i(fs, &fileRep, (TCHAR *) path_rep_fileName, FA_READ); + if (fr) { + return false; + } + + fr = f_lseek_i(fs, &fileRep, offset); + if (fr) { + return false; + } + + fr = f_read_i(fs, &fileRep, dataSendPacket, *lenTransPaket, &brRep); + if (fr) { + fr = f_close_i(fs, &fileRep); + return false; + } + + fr = f_close_i(fs, &fileRep); + + *lenTransPaket += sizeof(tStructTransportKvitPacket); + + } + + return true; +} + + +// Создание пакета транспортного уровня +bool +createPacketTransport(tFs *fs, uint32_t offset, uint8_t *bufSendPacket, bool *isFrom, uint32_t *from, + uint32_t *lenTransPaket, + tFileSendInfo *fileSendInfo, + tRtcIO *rtcIo, char *path_rep_fileName, char *path_mask_fileName) { + uint8_t bufRead[512]; + FIL fileRep; + FIL fileMask; + FRESULT fr; + UINT brRep, brMask; // File read/write count + + // Создание заголовка транспортного пакета + tStructTransportPacket *structTransportPacket = (tStructTransportPacket *) bufSendPacket; + + structTransportPacket->versionProtocol = 1; + + structTransportPacket->dataType = 12; // Пакет не квитируемого сообщения + if (fileSendInfo->kvs) + structTransportPacket->dataType = 0; // Пакет квитируемого сообщения + + structTransportPacket->numberSender = fileSendInfo->from; // НС отправителя; + structTransportPacket->dateCreateTransportPacketDay = fileSendInfo->dateDay; + structTransportPacket->dateCreateTransportPacketMon = fileSendInfo->dateMon; + structTransportPacket->numberMessage = fileSendInfo->mnum; + + //structTransportPacket->offsetPacket = offsetPacket; + //structTransportPacket->isEnd = isEnd; + + *isFrom = false; + bool isTo = false; + uint32_t stepFromOrTo = 0; + uint32_t stepFromOrTo_MaxLen = 0; + *from = 0; + uint32_t to = 0; + + // Открытие файла маски + fr = f_open_i(fs, &fileMask, (TCHAR *) path_mask_fileName, FA_READ); + if (fr) { + return false; + } + + fr = f_lseek_i(fs, &fileMask, offset); + if (fr) { + return false; + } + + for (;;) { + + fr = f_read_i(fs, &fileMask, bufRead, sizeof(bufRead), &brMask); + if (fr) { + fr = f_close_i(fs, &fileMask); + return false; + } + + for (uint32_t i = 0; i < brMask; ++i) { + + // Поиск неотправленного начала + if (*isFrom == false) { + if ((bufRead[i] == 0) || (bufRead[i] == 0x56)) { + *from = stepFromOrTo + offset; + + *isFrom = true; + } + } else { + // Поиск неотправленного конца + if (bufRead[i] == 0x55) { + to = stepFromOrTo + offset; + isTo = true; + break; + } + } + + ++stepFromOrTo; + + if (*isFrom) { + ++stepFromOrTo_MaxLen; + } + } + + + // Нашли начало и конец + if ((*isFrom) && (isTo)) + break; + + // Нашли данные для полного пакета + if (stepFromOrTo_MaxLen > LEN_TRANS_PACKET) { + to = stepFromOrTo + offset; + isTo = true; + break; + } + + // Нашли конец файла + if (brMask == 0) { + to = stepFromOrTo + offset; + isTo = true; + break; + } + } + fr = f_close_i(fs, &fileMask); + + + uint32_t dl = fileSendInfo->sizeFileRep - stepFromOrTo + *from; + + *lenTransPaket = 0; + if (*isFrom) { + + uint32_t leftFileSize = to - *from; + *lenTransPaket = TRANS_MIN(leftFileSize, LEN_TRANS_PACKET - sizeof(tStructTransportPacket)); +// *lenTransPaket = TRANS_MIN(leftFileSize, 13); + + structTransportPacket->offsetPacket = *from; + structTransportPacket->isEnd = 0; + + if ((*from + *lenTransPaket) == fileSendInfo->sizeFileRep) { + structTransportPacket->isEnd = 1; + } + + uint8_t *dataSendPacket = &bufSendPacket[sizeof(tStructTransportPacket)]; + + // Открытие файла представления + fr = f_open_i(fs, &fileRep, (TCHAR *) path_rep_fileName, FA_READ); + if (fr) { + return false; + } + + fr = f_lseek_i(fs, &fileRep, *from); + if (fr) { + return false; + } + + fr = f_read_i(fs, &fileRep, dataSendPacket, *lenTransPaket, &brRep); + if (fr) { + fr = f_close_i(fs, &fileRep); + return false; + } + + fr = f_close_i(fs, &fileRep); + + *lenTransPaket += sizeof(tStructTransportPacket); + + } + + return true; +} + +// Редактирование файла маски пакета транспортного уровня +bool editMaskPacketTransport(tFs *fs, uint32_t from, uint32_t lenTransPaket, char *path_mask_fileName, + tBufFreeFillState isFill) { + FIL fileMask; + FRESULT fr; + UINT bwMask; // File read/write count + + // Открытие файла маски + fr = f_open_i(fs, &fileMask, (TCHAR *) path_mask_fileName, FA_WRITE); + + if (fr) { + return false; + } + + fr = f_lseek_i(fs, &fileMask, from); + + const uint8_t *pBuf = bufFillOperation; + + if (isFill == BUF_NO_RECEIVE) + pBuf = bufFreeOperation; + + if (isFill == BUF_NO_RECEIVE_KV) + pBuf = bufFreeOperationKV; + + + uint32_t lenMaskInteger = lenTransPaket / sizeof(bufFreeOperation); + uint32_t lenMaskTail = lenTransPaket % sizeof(bufFreeOperation); + + for (uint32_t i = 0; i < lenMaskInteger; ++i) { + fr = f_write_i(fs, &fileMask, pBuf, sizeof(bufFreeOperation), &bwMask); + if (fr) { + fr = f_close_i(fs, &fileMask); + return false; + } + } + + if (lenMaskTail > 0) { + fr = f_write_i(fs, &fileMask, pBuf, lenMaskTail, &bwMask); + if (fr) { + fr = f_close_i(fs, &fileMask); + return false; + } + } + + fr = f_close_i(fs, &fileMask); + + return true; +} + +// Поиск неотправленных блоков в файле маски +bool isFindMaskPacketTransport(tFs *fs, bool *isFind, char *path_mask_fileName, tFileSendInfo *fileSendInfo) { + uint8_t bufRead[512]; + + FIL fileMask; + FRESULT fr; + UINT brMask; // File read/write count + + *isFind = false; + uint32_t step_len_mask_file = 0; + + fileSendInfo->bytes_sending = 0; + fileSendInfo->bytes_no_sending = 0; + + // Открытие файла маски + fr = f_open_i(fs, &fileMask, (TCHAR *) path_mask_fileName, FA_READ); + if (fr) { + return false; + } + + for (;;) { + + fr = f_read_i(fs, &fileMask, bufRead, sizeof(bufRead), &brMask); + if (fr) { + fr = f_close_i(fs, &fileMask); + return false; + } + + for (uint32_t i = 0; i < brMask; ++i) { + if ((bufRead[i] == 0x00) || (bufRead[i] == 0x56)) { + *isFind = true; + ++fileSendInfo->bytes_no_sending; + // return true; + } else { + ++fileSendInfo->bytes_sending; + } + ++step_len_mask_file; + } + + if ((step_len_mask_file == fileSendInfo->sizeFileRep) || (brMask == 0)) + break; + + } + fr = f_close_i(fs, &fileMask); + + return true; +} + + +// Поиск неотправленных блоков в файле маски +bool isFindMaskPacketTransportIsNotProc(tFs *fs, bool *isFind, char *path_mask_fileName) { + uint8_t bufRead[512]; + + FIL fileMask; + FRESULT fr; + UINT brMask; // File read/write count + + *isFind = false; + + // Открытие файла маски + fr = f_open_i(fs, &fileMask, (TCHAR *) path_mask_fileName, FA_READ); + if (fr) { + return false; + } + + for (;;) { + + fr = f_read_i(fs, &fileMask, bufRead, sizeof(bufRead), &brMask); + if (fr) { + fr = f_close_i(fs, &fileMask); + return false; + } + + for (uint32_t i = 0; i < brMask; ++i) { + if ((bufRead[i] == 0x00) || (bufRead[i] == 0x56)) { + *isFind = true; + fr = f_close_i(fs, &fileMask); + return true; + } + } + + if (brMask == 0) + break; + + } + fr = f_close_i(fs, &fileMask); + + return true; +} + +bool isAlreadyAdded(tFs *fs, uint32_t mnum) { +// uint32_t mnum = atoi(fname); + + // Получение имени файла по ид + char fileNameRep[24]; + // Создание имени файла + createFileNameForId(fileNameRep, "", mnum, "REP"); + + FRESULT fr; + FILINFO fno; + DIR dj; + + bool result = false; + fr = f_findfirst_i(fs, &dj, &fno, dir_rep_out, fileNameRep); + + if (fr == FR_OK && fno.fname[0]) + result = true; + + fr = f_closedir_i(fs, &dj); + + return result; +} + + +uint32_t +getMaxUrgencyOutbox(tFs *fs, tGonetsReedSalmon *gonetsReedSalmon, md5a_context *md5ctx, tRtcIO *rtcIo, char *path, + char *out_fileName, char *path_out_fileName, tTypeFile typeFile, tDeviceStorageIni *store, + uint32_t gr) { + FRESULT fr; + DIR dj; + FILINFO fno; + char bufDumpFile[512]; + char dirFileName[MAX_LEN_PATH_FS]; + // Структура содержащая информацию по исходящему сообщению + tFileSendInfo fileSendInfo; + uint32_t idFilesArray[16]; + + uint32_t cuteOffsetBegin = 0; + + if (typeFile == TYPE_FILE_TRACERT) { + uint32_t count = getCountTypeFileInRepout(fs, TYPE_FILE_TRACERT, idFilesArray); + uint32_t countStep = count; + + while (countStep < store->nvm.Settings_Tracert.MaxBuf_v) { + + uint32_t idFileOld = getOldOut(fs, (char *) dir_tracert, idFilesArray, countStep); + + if (idFileOld == 0) + break; + + // Создание файла с полным путем + createFileNameForId(path_out_fileName, path, idFileOld, "OTM"); + + // Получение информации о файле + bool resultInfo = getInfoFromFileNameOutBox(fs, path_out_fileName, &fileSendInfo, &cuteOffsetBegin); + + // Создание файла уровня представления + bool resultCreateRep = createFileRepresentation(fs, gonetsReedSalmon, md5ctx, rtcIo, path_out_fileName, + &fileSendInfo, gr, cuteOffsetBegin); + + idFilesArray[countStep] = idFileOld; + ++countStep; + } + + + return 1; + } + + + fr = f_findfirst_i(fs, &dj, &fno, path, "*.OTM"); + while (fr == FR_OK && fno.fname[0]) { + + uint32_t idFile = atoi(fno.fname); + + // Если файл представления уже создан + bool isAlready = isAlreadyAdded(fs, idFile); + if (isAlready) { + fr = f_findnext_i(fs, &dj, &fno); + continue; + } + + // Создание файла с полным путем + createFileNameForId(path_out_fileName, path, idFile, "OTM"); + + // Получение информации о файле + bool resultInfo = getInfoFromFileNameOutBox(fs, path_out_fileName, &fileSendInfo, &cuteOffsetBegin); + + if ((fileSendInfo.typeFile == TYPE_FILE_AMS_RADAR) || (fileSendInfo.typeFile == TYPE_FILE_LORA_WAN)) { + + uint32_t count = getCountTypeFileInRepout(fs, fileSendInfo.typeFile, idFilesArray); + uint32_t countStep = count; + + uint32_t countMax; + + if (fileSendInfo.typeFile == TYPE_FILE_AMS_RADAR) + countMax = store->nvm.Settings_AmsRadar.AmsRadarMaxBuf; + + if (fileSendInfo.typeFile == TYPE_FILE_LORA_WAN) + countMax = store->nvm.Settings_LoRaWan.LoRaWanMaxBuf; + + while (countStep < countMax) { + + uint32_t idFileOld = getOldOut(fs, (char *) dir_outbox, idFilesArray, countStep); + + if (idFileOld == 0) + break; + + // Создание файла с полным путем + createFileNameForId(path_out_fileName, path, idFileOld, "OTM"); + + // Создание файла уровня представления + bool resultCreateRep = createFileRepresentation(fs, gonetsReedSalmon, md5ctx, rtcIo, path_out_fileName, + &fileSendInfo, gr, cuteOffsetBegin); + + idFilesArray[countStep] = idFileOld; + ++countStep; + } + + + } else { + + // Создание файла уровня представления + bool resultCreateRep = createFileRepresentation(fs, gonetsReedSalmon, md5ctx, rtcIo, path_out_fileName, + &fileSendInfo, gr, cuteOffsetBegin); + + } + fr = f_findnext_i(fs, &dj, &fno); + } + fr = f_closedir_i(fs, &dj); + + + return 1; +} + + +// Создание файла уровня представления +bool createFileRepresentation(tFs *fs, tGonetsReedSalmon *gonetsReedSalmon, md5a_context *md5ctx, tRtcIO *rtcIo, + char *path_out_fileName, tFileSendInfo *fileSendInfo, uint32_t gr, + uint32_t cuteOffsetBegin) { + + char path_dir_rep_fileName[MAX_LEN_PATH_FS]; + char path_dir_mask_fileName[MAX_LEN_PATH_FS]; + char path_dir_info_fileName[MAX_LEN_PATH_FS]; + + + createFileNameForId_REP_MSK_INF(path_dir_rep_fileName, + path_dir_mask_fileName, + path_dir_info_fileName, + (char *) dir_rep_out, fileSendInfo->mnum); + + FRESULT fr; + FIL file; + + fr = f_open_i(fs, &file, (TCHAR *) path_dir_rep_fileName, FA_WRITE | FA_CREATE_ALWAYS); + if (fr) { + return false; + } + + tStructRepresentationPacket structRepresentationPacket; + memset(&structRepresentationPacket, 0, sizeof(structRepresentationPacket)); + structRepresentationPacket.versionProtocol = 1; + + uint32_t to = atoi(fileSendInfo->to); + + if (to < 100) { + structRepresentationPacket.classMessage = 3; // Сообщения в шлюз + structRepresentationPacket.typeMessage = 1; // Электронная почта в сети Интернет + } else { + structRepresentationPacket.classMessage = 1; // Целевые сообщения + + if (fileSendInfo->typeFile == TYPE_FILE_TRACERT) { + structRepresentationPacket.typeMessage = 4; // сообщение о местоположении + } else { + + if (strcmp(fileSendInfo->subj, "file") == 0) { + structRepresentationPacket.typeMessage = 2; // файл с простой структурой + } else { + structRepresentationPacket.typeMessage = 1; // Текстовые сообщения + } + + } + } + + + if (fileSendInfo->typeFile != TYPE_FILE_KVITIN) { + FILINFO fnoOutInf; + FRESULT frOutInf; + + if (fileSendInfo->typeFile != TYPE_FILE_TRACERT) { + + frOutInf = f_stat(path_out_fileName, &fnoOutInf); + if (frOutInf) { + return false; + } + } + + if (fileSendInfo->typeFile == TYPE_FILE_TRACERT) { + + char path_dir_tracert_dat[MAX_LEN_PATH_FS]; + createFileNameForId(path_dir_tracert_dat, (char *) dir_tracert, fileSendInfo->mnum, "DAT"); + + frOutInf = f_stat(path_dir_tracert_dat, &fnoOutInf); + if (frOutInf) { + return false; + } + } + + structRepresentationPacket.typeCrc = 1; + + if (fnoOutInf.fsize > 100 * 1024) { + structRepresentationPacket.typeCrc = 2; + } + } + + uint8_t *head = (uint8_t *) &structRepresentationPacket; + uint8_t crc8 = GonetsCrc8(head, 9); + + structRepresentationPacket.crc8 = crc8; + structRepresentationPacket.rc = 0; + vGonetsReedSalmonEncode_1410_3430(gonetsReedSalmon, (uint8_t *) &structRepresentationPacket); + + uint32_t initCrc32 = 0xFFFFFFFF; + + // Запись заголовка + if (fileSendInfo->typeFile != TYPE_FILE_KVITIN) { + UINT bytes_written; + fr = f_write_i(fs, &file, &structRepresentationPacket, sizeof(tStructRepresentationPacket), &bytes_written); + + if (fr) { + f_close_i(fs, &file); + return false; + } + + if (fileSendInfo->typeFile != TYPE_FILE_TRACERT) { + // Запись заголовка для сервера ГОНЦА + if (isTo(fileSendInfo->to, '@')) { + char bufDumpFileHead[512]; + cuteOffset(fs, path_out_fileName, bufDumpFileHead, sizeof(bufDumpFileHead), cuteOffsetBegin); + + // crc32 + if (structRepresentationPacket.typeCrc == 1) { + initCrc32 = GonetsCrc32_update((uint8_t *) bufDumpFileHead, fileSendInfo->offsetMsg - 13, + initCrc32); + } + + // md5 + if (structRepresentationPacket.typeCrc == 2) { + md5a_update(md5ctx, (uint8_t *) bufDumpFileHead, (int) fileSendInfo->offsetMsg - 13); + } + + fr = f_write_i(fs, &file, &bufDumpFileHead, fileSendInfo->offsetMsg - 13, &bytes_written); + + if (fr) { + f_close_i(fs, &file); + return false; + } + + } + } + + } + + fr = f_close_i(fs, &file); + + if (fileSendInfo->typeFile != TYPE_FILE_TRACERT) { + + bool res = CopyFileFs_crc_md5(fs, structRepresentationPacket.typeCrc, md5ctx, path_dir_rep_fileName, + path_out_fileName, fileSendInfo->offsetMsg, initCrc32); + if (res == false) { + return false; + } + + } + + if (fileSendInfo->typeFile == TYPE_FILE_TRACERT) { + + char path_dir_tracert_dat[MAX_LEN_PATH_FS]; + createFileNameForId(path_dir_tracert_dat, (char *) dir_tracert, fileSendInfo->mnum, "DAT"); + + bool res = CopyFileFs_crc_md5(fs, structRepresentationPacket.typeCrc, md5ctx, path_dir_rep_fileName, + path_dir_tracert_dat, fileSendInfo->offsetMsg, 0xFFFFFFFF); + if (res == false) { + return false; + } + + } + + + // Добавление размера REP файла в info структуру + FILINFO fnoInf; + FRESULT frInf; + + frInf = f_stat(path_dir_rep_fileName, &fnoInf); + if (frInf) { + return false; + } else { + fileSendInfo->sizeFileRep = fnoInf.fsize; + } + + time_t timestamp; + rtcIo->get(rtcIo, ×tamp); + timestamp += gr * 3600; + + struct tm timestampTM; + localtime_r(×tamp, ×tampTM); + + + fileSendInfo->bytes_sending = 0; + fileSendInfo->bytes_no_sending = fileSendInfo->sizeFileRep; + + fileSendInfo->dateDay = timestampTM.tm_mday; + fileSendInfo->dateMon = timestampTM.tm_mon + 1; + + // Создание файла маски + UINT bw; + + uint32_t lenMaskInteger = fileSendInfo->sizeFileRep / sizeof(bufFreeOperation); + uint32_t lenMaskTail = fileSendInfo->sizeFileRep % sizeof(bufFreeOperation); + + fr = f_open_i(fs, &file, (TCHAR *) path_dir_mask_fileName, FA_WRITE | FA_CREATE_ALWAYS); + if (fr) return false; + + for (uint32_t i = 0; i < lenMaskInteger; ++i) { + fr = f_write_i(fs, &file, bufFreeOperation, sizeof(bufFreeOperation), &bw); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + } + + if (lenMaskTail > 0) { + fr = f_write_i(fs, &file, bufFreeOperation, lenMaskTail, &bw); + if (fr) { + fr = f_close_i(fs, &file); + return false; + } + } + + + fr = f_close_i(fs, &file); + + fileSendInfo->crc32_MSK = CrcFileFs(fs, path_dir_mask_fileName); + fileSendInfo->crc32_REP = CrcFileFs(fs, path_dir_rep_fileName); + + // Создание info файла + bool result = writeSendFileInfo(fs, fileSendInfo, path_dir_info_fileName); + + return true; +} + + +// Перенос файла в хранилище отправленных сообщений sentbox +bool renameFromOutBoxToSentBox(tFs *fs, tRtcIO *rtc, tFileSendInfo *fileSendInfo) { + + // Путь к каталогу с датой + char path_sent_dirDate[MAX_LEN_PATH_FS]; + path_sent_dirDate[0] = '\0'; + getDateStr(rtc, path_sent_dirDate, sizeof(path_sent_dirDate)); + + // Путь к файлу в SENTBOX + char path_sent_fileName[MAX_LEN_PATH_FS]; + path_sent_fileName[0] = '\0'; + strcat(path_sent_fileName, dir_sentbox); + strcat(path_sent_fileName, path_sent_dirDate); + strcat(path_sent_fileName, "/"); + + FRESULT fr; + fr = f_mkdir_i(fs, path_sent_fileName); + + if (fr) { + if (fr != FR_EXIST) + return false; + } + + + // Путь к файлу в OUTBOX + char path_out_fileName[MAX_LEN_PATH_FS]; + path_out_fileName[0] = '\0'; + + // Создание имени файла по id + char sent_fileName[MAX_LEN_PATH_FS]; + sent_fileName[0] = '\0'; + + + if (fileSendInfo->typeFile == TYPE_FILE_TRACERT) { + createFileNameForId(path_out_fileName, (char *) dir_tracert, fileSendInfo->mnum, "OTM"); + } else { + createFileNameForId(path_out_fileName, (char *) dir_outbox, fileSendInfo->mnum, "OTM"); + } + + createFileNameForId(sent_fileName, "", fileSendInfo->mnum, "STM"); + strcat(path_sent_fileName, sent_fileName); + + //fr = f_rename_i(fs, path_out_fileName, path_sent_fileName); + CopyFileFs(fs, path_sent_fileName, path_out_fileName, 0); + f_unlink_i(fs, path_out_fileName); + + + if (fileSendInfo->typeFile == TYPE_FILE_TRACERT) { + path_out_fileName[0] = '\0'; + sent_fileName[0] = '\0'; + + createFileNameForId(path_out_fileName, (char *) dir_tracert, fileSendInfo->mnum, "DAT"); + + createFileNameForId(sent_fileName, "", fileSendInfo->mnum, "DAT"); + + + path_sent_fileName[0] = '\0'; + strcat(path_sent_fileName, dir_sentbox); + strcat(path_sent_fileName, path_sent_dirDate); + strcat(path_sent_fileName, "/"); + + strcat(path_sent_fileName, sent_fileName); + + //fr = f_rename_i(fs, path_out_fileName, path_sent_fileName); + CopyFileFs(fs, path_sent_fileName, path_out_fileName, 0); + f_unlink_i(fs, path_out_fileName); + + } + + + return true; +} + +bool createBufStateFileSend(tFs *fs) { + FIL file; + char temp_filename[MAX_LEN_PATH_FS]; + UINT bytes_written; + + FRESULT fr; + DIR dj; + FILINFO fno; + tFileSendInfo fileSendInfo; + + char buf_proc[120]; + + + char dirScan[MAX_LEN_PATH_FS]; + dirScan[0] = '\0'; + strcat(dirScan, dir_rep_out); + + char dirFileScan[MAX_LEN_PATH_FS]; + +// uint8_t bufMnum[maxFilesOutBox]; +// memset(bufMnum, 0, sizeof(bufMnum)); +// int countFileInfo = 0; + + temp_filename[0] = '\0'; + strcat(temp_filename, file_dir_proc); + fr = f_open_i(fs, &file, (TCHAR *) temp_filename, FA_CREATE_ALWAYS | FA_WRITE); + + buf_proc[0] = '\0'; + strcat(buf_proc, "{\"InfoSend\":["); + fr = f_write_i(fs, &file, buf_proc, strlen(buf_proc), &bytes_written); + + buf_proc[0] = ' '; + + fr = f_findfirst_i(fs, &dj, &fno, dirScan, "*.INF"); + while (fr == FR_OK && fno.fname[0]) { + + dirFileScan[0] = '\0'; + strcat(dirFileScan, dirScan); + strcat(dirFileScan, fno.fname); + + readSendFileInfo(fs, &fileSendInfo, dirFileScan); + + struct to_json jsonResponse_State[] = { + {.name = "mnum", .value = &fileSendInfo.mnum, .vtype = t_to_uint32_t, .stype = t_to_object}, + {.name = "kvs", .value = &fileSendInfo.kvs, .vtype = t_to_uint8_t}, + {.name = "isSendAll", .value = &fileSendInfo.isSendAll, .vtype = t_to_uint8_t}, + {.name = "bytes_sending", .value = &fileSendInfo.bytes_sending, .vtype = t_to_uint32_t}, + {.name = "bytes_no_sending", .value = &fileSendInfo.bytes_no_sending, .vtype = t_to_uint32_t}, + {NULL} + }; + + size_t len_json = json_generate(&buf_proc[1], jsonResponse_State, sizeof(buf_proc)); + + fr = f_write_i(fs, &file, buf_proc, len_json + 1, &bytes_written); + + buf_proc[0] = ','; + + +// bufMnum[countFileInfo] = 1; + +// bufStateFileSend[countFileInfo].valid = 1; +// bufStateFileSend[countFileInfo].kvs = fileSendInfo.kvs; +// bufStateFileSend[countFileInfo].isSendAll = fileSendInfo.isSendAll; +// bufStateFileSend[countFileInfo].mnum = fileSendInfo.mnum; +// bufStateFileSend[countFileInfo].bytes_sending = fileSendInfo.bytes_sending; +// bufStateFileSend[countFileInfo].bytes_no_sending = fileSendInfo.bytes_no_sending; + +// ++countFileInfo; + + fr = f_findnext_i(fs, &dj, &fno); + } + + fr = f_closedir_i(fs, &dj); + + buf_proc[0] = '\0'; + strcat(buf_proc, "]}"); + fr = f_write_i(fs, &file, buf_proc, strlen(buf_proc), &bytes_written); + fr = f_close_i(fs, &file); + + +// for (int i = 0; i < maxFilesOutBox; ++i) { +// if (bufMnum[i] == 0) { +// bufStateFileSend[i].valid = 0; +// } +// } + + return true; +} \ No newline at end of file diff --git a/Src/Modem_Timer.c b/Src/Modem_Timer.c new file mode 100644 index 0000000..701f229 --- /dev/null +++ b/Src/Modem_Timer.c @@ -0,0 +1,61 @@ +// +// Created by cfif on 16.05.23. +// +#include "Modem_Timer.h" +#include "CmsisRtosThreadUtils.h" + +#define LOGGER env->logger +#define LOG_SIGN "GONEC" + +void ModemTimer_Init(tModemTimer *env, tModemMain *modemMain, tSerialPortIO *io, tFileLogger *flog, tGpios *gpios) { + + env->modemMain = modemMain; + env->io = io; + env->flog = flog; + env->gpios = gpios; + + InitThreadAtrStatic(&env->thread.attr, "ModemTimer", env->thread.controlBlock, env->thread.stack, osPriorityHigh); + env->thread.id = 0; +} + +extern volatile uint32_t timeModemStuckGetMs; + +static _Noreturn void ModemTimer_Thread(tModemTimer *env) { + uint8_t data[] = {'A', 'T', '\r', '\n'}; + + + + for (;;) { + + if (env->modemMain->location.isOneDateTime == false) { + + uint32_t dlStuckGetMs = SystemGetMs() - timeModemStuckGetMs; + + + // Если завис больше 30 секунд + if (dlStuckGetMs > 30000) { + GpioPinSet(&env->gpios->Power.gonec_reset, false); + SystemDelayMs(1000); + GpioPinSet(&env->gpios->Power.gonec_reset, true); + SystemDelayMs(6000); + + timeModemStuckGetMs = SystemGetMs(); + LoggerInfoStatic(LOGGER, LOG_SIGN, "Контроль задачи модема"); + + SerialPortTransmit(env->io, data, 4, 1000); + } + + } + + SystemDelayMs(1000); + + } +} + +void ModemTimer_StartThread(tModemTimer *env) { + if (!env->thread.id) { + env->thread.id = osThreadNew((osThreadFunc_t) (ModemTimer_Thread), (void *) (env), &env->thread.attr); + } else { + osThreadResume(env->thread.id); + } +} \ No newline at end of file diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..8066703 --- /dev/null +++ b/modular.json @@ -0,0 +1,18 @@ +{ + "dep": [ + { + "type": "git", + "provider": "GONEC_NEW", + "repo": "GONEC_ARTERY_Modem_GONEC" + } + ], + + "cmake": { + "inc_dirs": [ + "Inc" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file