// // 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); } }