// // Created by cfif on 12.12.22. // #include "httpd_post_handlers.h" #include "string.h" #include "httpd_base_func.h" #include "stdlib.h" #include "JSONSettings.h" #include "Flash_MT29F2G01ABAGDWB.h" //#include "stream.h" #include "httpd_TablesPostGet.h" #include "stdlib.h" #include "fs_base_func.h" #include "fs_interface.h" #include "ModemGonec.h" #include "http_server.h" #include "ModemGonecFunc.h" #include "DeviceStorageIni.h" #include "BootJump.h" #include "ModemSend.h" /* char bufNameDir[9]; size_t len = getNameDir(env->rtc, bufNameDir, sizeof(bufNameDir)); if (len != 8) return Post_DATATIME_ERR; */ // начало-------------------Создание входящего сообщения handlerPost_Write_Other_File----------------------------------- // начало-------------------Создание входящего сообщения handlerPost_Write_Other_File----------------------------------- // начало-------------------Создание входящего сообщения handlerPost_Write_Other_File----------------------------------- // Создание и запись в файл idPostResult_t handlerPost_Write_Other_File(tHttpPostSetting *env) { int pos = -1; int len = -1; char filename[MAX_LEN_PATH_FS]; filename[0] = '\0'; for (int i = 0; i < env->params_post_uri.paramcount; ++i) { if (strcmp(env->params_post_uri.params_names[i], "pos") == 0) pos = atoi(env->params_post_uri.params_vals[i]); if (strcmp(env->params_post_uri.params_names[i], "len") == 0) len = atoi(env->params_post_uri.params_vals[i]); if (strcmp(env->params_post_uri.params_names[i], "wrfile") == 0) extract_utf8_parameters(env->params_post_uri.params_vals[i], filename, sizeof(filename)); } if ((pos == -1) || (len == -1) || (strlen(filename) == 0) || (len > 1024 * 11)) { return Post_PARAM_ERR; } FIL file; FRESULT fr; char temp_filename[MAX_LEN_PATH_FS]; temp_filename[0] = '\0'; strcat(temp_filename, "1:/"); filename[strlen(filename) - 1] = '\0'; strcat(temp_filename, &filename[1]); fr = f_open_i(env->fs, &file, (TCHAR *) temp_filename, FA_WRITE | FA_CREATE_ALWAYS); if (fr) { return Post_FS_ERR; } fr = f_lseek_i(env->fs, &file, pos); UINT bytes_written; fr = f_write_i(env->fs, &file, env->bufAnswer, len, &bytes_written); if (fr) { f_close_i(env->fs, &file); return Post_FS_ERR; } fr = f_close_i(env->fs, &file); return Post_OK; } // конец-------------------Создание входящего сообщения handlerPost_Write_Other_File------------------------------------ // конец-------------------Создание входящего сообщения handlerPost_Write_Other_File------------------------------------ // конец-------------------Создание входящего сообщения handlerPost_Write_Other_File------------------------------------ // начало-------------------Создание входящего сообщения cmd.xip?wrfile--------------------------------------------------- // начало-------------------Создание входящего сообщения cmd.xip?wrfile--------------------------------------------------- // начало-------------------Создание входящего сообщения cmd.xip?wrfile--------------------------------------------------- // Создание и запись в файл idPostResult_t handlerPost_Message_Outbox_Wrfile(tHttpPostSetting *env) { int pos = -1; int len = -1; char filename[MAX_LEN_PATH_FS]; filename[0] = '\0'; for (int i = 0; i < env->params_post_uri.paramcount; ++i) { if (strcmp(env->params_post_uri.params_names[i], "pos") == 0) pos = atoi(env->params_post_uri.params_vals[i]); if (strcmp(env->params_post_uri.params_names[i], "len") == 0) len = atoi(env->params_post_uri.params_vals[i]); if (strcmp(env->params_post_uri.params_names[i], "wrfile") == 0) extract_utf8_parameters(env->params_post_uri.params_vals[i], filename, sizeof(filename)); } if ((pos == -1) || (len == -1) || (strlen(filename) == 0) || (len > 1024 * 11)) { return Post_PARAM_ERR; } FIL file; FRESULT fr; char temp_filename[MAX_LEN_PATH_FS]; temp_filename[0] = '\0'; strcat(temp_filename, dir_temp); filename[strlen(filename) - 1] = '\0'; strcat(temp_filename, &filename[1]); fr = f_open_i(env->fs, &file, (TCHAR *) temp_filename, FA_WRITE | FA_CREATE_ALWAYS); if (fr) { return Post_FS_ERR; } fr = f_lseek_i(env->fs, &file, pos); UINT bytes_written; fr = f_write_i(env->fs, &file, env->bufAnswer, len, &bytes_written); /* uint32_t lenInteger = len / 512; uint32_t lenTail = len % 512; uint32_t stepMiniBuf = 0; for (uint32_t i = 0; i < lenInteger; ++i) { fr = f_write_i(env->fs, &file, &env->bufAnswer[stepMiniBuf], 512, &bytes_written); stepMiniBuf += 512; } if (lenTail > 0) { fr = f_write_i(env->fs, &file, &env->bufAnswer[stepMiniBuf], lenTail, &bytes_written); } */ if (fr) { f_close_i(env->fs, &file); return Post_FS_ERR; } fr = f_close_i(env->fs, &file); return Post_OK; } // конец-------------------Создание входящего сообщения cmd.xip?wrfile--------------------------------------------------- // конец-------------------Создание входящего сообщения cmd.xip?wrfile--------------------------------------------------- // конец-------------------Создание входящего сообщения cmd.xip?wrfile--------------------------------------------------- // начало-------------------Создание динамического файла--------------------------------------------------- // начало-------------------Создание динамического файла--------------------------------------------------- // начало-------------------Создание динамического файла--------------------------------------------------- // Создание и запись в файл idPostResult_t handlerPost_Message_Outbox_DynamicWrfile(tHttpPostSetting *env, uint32_t offset, uint32_t len) { FIL file; FRESULT fr; if (env->isFirst) { fr = f_unlink_i(env->fs, env->createPostData.filename); } fr = f_open_i(env->fs, &file, (TCHAR *) env->createPostData.filename, FA_OPEN_APPEND | FA_WRITE); if (fr) { return Post_FS_ERR; } UINT bytes_written; fr = f_write_i(env->fs, &file, &env->bufAnswer[offset], len, &bytes_written); if (fr) { f_close_i(env->fs, &file); return Post_FS_ERR; } fr = f_close_i(env->fs, &file); return Post_OK; } // конец-------------------Создание динамического файла--------------------------------------------------- // конец-------------------Создание динамического файла--------------------------------------------------- // конец-------------------Создание динамического файла--------------------------------------------------- // начало-------------------Загрузка ключей----------------------------------------------------------------------------- // начало-------------------Загрузка ключей----------------------------------------------------------------------------- // начало-------------------Загрузка ключей----------------------------------------------------------------------------- // Загрузка ключей idPostResult_t handlerPost_Key_Load(tHttpPostSetting *env) { int key_num = 0; for (int i = 0; i < env->params_post_uri.paramcount; ++i) { if (strcmp(env->params_post_uri.params_names[i], "key") == 0) { key_num = atoi(env->params_post_uri.params_vals[i]); } } if ((key_num < 1) || (key_num > 12)) { return Post_PARAM_ERR; } // Загрузка ключей с проверкой idPostResult_t result = ModemLoadKey(env->modemMain, key_num, env->bufAnswer, env->content_len); return result; } // конец--------------------Загрузка ключей----------------------------------------------------------------------------- // конец--------------------Загрузка ключей----------------------------------------------------------------------------- // конец--------------------Загрузка ключей----------------------------------------------------------------------------- // начало--------------------Сохранение настроек------------------------------------------------------------------------ // начало--------------------Сохранение настроек------------------------------------------------------------------------ // начало--------------------Сохранение настроек------------------------------------------------------------------------ idPostResult_t handlerPost_Var(tHttpPostSetting *env, typeAuth auth) { idPostResult_t result = Post_OK; // Сохранение настроек во временные // NvmToRuntimeSettings(); // Сохранение настроек во временные Nvm_To_RuntimeSettings(env->storage); bool grp1, grp2, grp3, grp8, grp11, grp12, grp14, grp25, grp26; result = vJsonToStructure(env->bufAnswer, settings, env->modemMain, auth, &grp1, &grp2, &grp3, &grp8, &grp11, &grp12, &grp14, &grp25, &grp26); // Ошибка if (result) { Nvm_To_RuntimeSettings(env->storage); return result; } if ((auth == AUTH_ADMIN) || ((auth == AUTH_INTEG))) { if (env->modemMain->isModemCheck) { if ((grp1) || (grp2) || (grp3) || (grp25)) { if (osMutexAcquire(httpSettings.accessMODEM, TIME_MUTEX_MODEM_ACCESS) != osOK) { return Post_MUTEX_ERR; } result = ModemInitAt(env->modemMain, grp1, grp2, grp3, grp25); osMutexRelease(httpSettings.accessMODEM); // Ошибка if (result) { Nvm_To_RuntimeSettings(env->storage); return result; } } } // Основной режим доступа if (grp3) { if (env->storage->runtime.Settings_Basic_Access.MaxSzDataOnKB_v != env->storage->nvm.Settings_Basic_Access.MaxSzDataOnKB_v) { if (env->storage->runtime.Settings_Basic_Access.MaxSzDataOnKB_v < env->storage->nvm.Settings_Basic_Access.MaxSzDataOnKB_v) { // Удалить все пакеты из модема delRepout(env->modemMain, TYPE_FILE_MESSAGE, false, true); } env->modemMain->stateRequest.stateReqCreateExtT = StateReqExtForCreate; env->modemMain->stateRequest.stateReqCreateExtW = StateReqExtForCreate; } } // Загрузка настроек из временных Runtime_To_NvmSettings(env->storage); // Сохранение во флеш DeviceStorageSetupIni_Dump(env->storage); // Настройки 485 и Блютуз if (grp14) { // Перенастройка порта ComInt485 vSerialPort_ReInitUSART2(env->storage->nvm.Settings_RS485_Bluetooth.rs485baudrate_v); ReInitExternalProtocol(env->external); } return result; } else { return Post_NO_AUTH; } } // конец--------------------Сохранение настроек------------------------------------------------------------------------- // конец--------------------Сохранение настроек------------------------------------------------------------------------- // конец--------------------Сохранение настроек------------------------------------------------------------------------- // начало-------------------Запись WEB---------------------------------------------------------------------------------- // начало-------------------Запись WEB---------------------------------------------------------------------------------- // начало-------------------Запись WEB---------------------------------------------------------------------------------- idPostResult_t handlerPost_Update_Web_File(tHttpPostSetting *env) { char BufWrite[512]; char fileName[MAX_LEN_PATH_FS * 2]; char dirUpdateFileName[MAX_LEN_PATH_FS]; dirUpdateFileName[0] = '\0'; strcat(dirUpdateFileName, "1:/TMP/web.dat"); FIL file; FRESULT fr = f_open_i(env->fs, &file, (TCHAR *) dirUpdateFileName, FA_READ); if (fr) { return Post_FS_ERR; } UINT bytes_read; fr = f_read_i(env->fs, &file, env->bufAnswer, 12800, &bytes_read); if (fr) { f_close_i(env->fs, &file); return Post_FS_ERR; } f_close_i(env->fs, &file); uint32_t crcFileCalc = GetCrcFileFs(env->fs, dirUpdateFileName, 4); uint32_t crcFile = ((uint32_t *) (env->bufAnswer))[0]; if (crcFileCalc != crcFile) { return Post_CRC; } char dir_web_local[MAX_LEN_PATH_FS]; dir_web_local[0] = '\0'; strcat(dir_web_local, dir_web); getDelFilesDir(env->fs, dir_web_local); uint32_t fileTableDescriptorSize = ((uint32_t *) (env->bufAnswer))[1]; tFileTableDescriptor *pFileTableDescriptor = (tFileTableDescriptor *) (env->bufAnswer + 8); for (uint32_t i = 0; i < fileTableDescriptorSize; ++i) { struct { int paramcount; char *params_names[MAX_POST_GET_PARAMETERS]; char *params_vals[MAX_POST_GET_PARAMETERS]; } params_path; fileName[0] = '\0'; strcat(fileName, &pFileTableDescriptor->name[1]); params_path.paramcount = extract_path_ex_parameters(fileName, params_path.params_names, params_path.params_vals, MAX_POST_GET_PARAMETERS); char dirPathFileWeb[MAX_LEN_PATH_FS]; dirPathFileWeb[0] = '\0'; strcat(dirPathFileWeb, dir_web); for (int j = 0; j < params_path.paramcount - 1; ++j) { strcat(dirPathFileWeb, params_path.params_names[j]); strcat(dirPathFileWeb, "/"); fr = f_mkdir(dirPathFileWeb); } ++pFileTableDescriptor; } pFileTableDescriptor = (tFileTableDescriptor *) (env->bufAnswer + 8); FIL fsrc, fdst; // File objects UINT br, bw; // File read/write count fr = f_open_i(env->fs, &fsrc, (TCHAR *) dirUpdateFileName, FA_READ); if (fr) { return Post_FS_ERR; } for (uint32_t i = 0; i < fileTableDescriptorSize; ++i) { fileName[0] = '\0'; strcat(fileName, dir_web); strcat(fileName, &pFileTableDescriptor->name[1]); fr = f_open_i(env->fs, &fdst, fileName, FA_CREATE_ALWAYS | FA_WRITE); if (fr) { f_close_i(env->fs, &fsrc); return Post_FS_ERR; } uint32_t leftFileSize = pFileTableDescriptor->size; uint32_t lenTransPaket; uint32_t offset = pFileTableDescriptor->address; while (leftFileSize > 0) { fr = f_lseek_i(env->fs, &fsrc, offset); if (fr) { f_close_i(env->fs, &fsrc); f_close_i(env->fs, &fdst); return Post_FS_ERR; } lenTransPaket = TRANS_MIN(leftFileSize, sizeof(BufWrite)); f_read_i(env->fs, &fsrc, (BufWrite), lenTransPaket, &br); f_write_i(env->fs, &fdst, (BufWrite), br, &bw); offset += lenTransPaket; leftFileSize -= lenTransPaket; } ++pFileTableDescriptor; f_close_i(env->fs, &fdst); } f_close_i(env->fs, &fsrc); fileName[0] = '\0'; strcat(fileName, dir_web); strcat(fileName, "load"); fr = f_open_i(env->fs, &file, fileName, FA_CREATE_ALWAYS | FA_WRITE); if (fr) { return Post_FS_ERR; } f_close_i(env->fs, &file); return Post_OK; } // конец-------------------Запись WEB----------------------------------------------------------------------------------- // конец-------------------Запись WEB----------------------------------------------------------------------------------- // конец-------------------Запись WEB----------------------------------------------------------------------------------- // Инициализация прошивки КОНТРОЛЛЕРА idPostResult_t handlerPost_Update_File_EraseFlash(tHttpPostSetting *env, tFirmwareLoaderXFSB firmwareLoaderXFSB) { uint32_t size = 0; uint32_t crc = 0; uint8_t descriptionLen = 0; uint8_t description[MAX_LEN_PATH_FS]; uint8_t stepParam = 0; for (int i = 0; i < env->params_post_uri.paramcount; ++i) { if (strcmp(env->params_post_uri.params_names[i], "size") == 0) { size = atoi(env->params_post_uri.params_vals[i]); ++stepParam; } if (strcmp(env->params_post_uri.params_names[i], "crc") == 0) { crc = atoi(env->params_post_uri.params_vals[i]); ++stepParam; } if (strcmp(env->params_post_uri.params_names[i], "description") == 0) { extract_utf8_parameters(env->params_post_uri.params_vals[i], (char *) description, MAX_LEN_PATH_FS); descriptionLen = strlen((char *) &description[1]) - 1; ++stepParam; } } if (stepParam < 3) { return Post_PARAM_ERR; } if (firmwareLoaderXFSB == FIRMWARE_XFSB_MAIN) { if (FirmwareLoader_PrepareNewUpdate(env->firmwareMainLoader, size, crc, &description[1], descriptionLen)) { return Post_OK; } } if (firmwareLoaderXFSB == FIRMWARE_XFSB_BOOT) { if (FirmwareLoader_PrepareNewUpdate(env->firmwareBootLoader, size, crc, &description[1], descriptionLen)) { return Post_OK; } } return Post_FLASH_ERR; } // Запись прошивки КОНТРОЛЛЕРА idPostResult_t handlerPost_Update_File_WriteFlash(tHttpPostSetting *env, tFirmwareLoaderXFSB firmwareLoaderXFSB) { uint32_t offset = 0; uint8_t stepParam = 0; for (int i = 0; i < env->params_post_uri.paramcount; ++i) { if (strcmp(env->params_post_uri.params_names[i], "offset") == 0) { offset = atoi(env->params_post_uri.params_vals[i]); ++stepParam; } } if (stepParam < 1) { return Post_PARAM_ERR; } if (firmwareLoaderXFSB == FIRMWARE_XFSB_MAIN) { if (FirmwareLoader_WriteUpdatePortion(env->firmwareMainLoader, offset, (uint8_t *) env->bufAnswer, env->content_len)) { return Post_OK; } } if (firmwareLoaderXFSB == FIRMWARE_XFSB_BOOT) { if (FirmwareLoader_WriteUpdatePortion(env->firmwareBootLoader, offset, (uint8_t *) env->bufAnswer, env->content_len)) { return Post_OK; } } return Post_FLASH_ERR; } idPostResult_t handlerPost_Update_Start_Main(tHttpPostSetting *env) { //GpioPinSet(&env->gpios->Power.gonec_reset, false); //BootJumpToAddress(0x08000000); nvic_system_reset(); return Post_OK; } // Запись прошивки криптоплаты idPostResult_t handlerPost_Update_Crypto_WriteFlash(tHttpPostSetting *env) { uint32_t size = 0; uint32_t crc = 0; uint32_t offset = 0; uint8_t stepParam = 0; for (int i = 0; i < env->params_post_uri.paramcount; ++i) { if (strcmp(env->params_post_uri.params_names[i], "size") == 0) { size = atoi(env->params_post_uri.params_vals[i]); ++stepParam; } if (strcmp(env->params_post_uri.params_names[i], "crc") == 0) { crc = atoi(env->params_post_uri.params_vals[i]); ++stepParam; } if (strcmp(env->params_post_uri.params_names[i], "offset") == 0) { offset = atoi(env->params_post_uri.params_vals[i]); ++stepParam; } } if (stepParam < 3) { return Post_PARAM_ERR; } idPostResult_t result = ModemCryptoWrite(env->modemMain, (uint8_t *) env->bufAnswer, crc, offset, size); return result; } // Запись прошивки модема idPostResult_t handlerPost_Update_Modem_WriteFlash(tHttpPostSetting *env) { uint32_t size = 0; uint32_t crc = 0; uint32_t offset = 0; uint8_t stepParam = 0; for (int i = 0; i < env->params_post_uri.paramcount; ++i) { if (strcmp(env->params_post_uri.params_names[i], "size") == 0) { size = atoi(env->params_post_uri.params_vals[i]); ++stepParam; } if (strcmp(env->params_post_uri.params_names[i], "crc") == 0) { crc = atoi(env->params_post_uri.params_vals[i]); ++stepParam; } if (strcmp(env->params_post_uri.params_names[i], "offset") == 0) { offset = atoi(env->params_post_uri.params_vals[i]); ++stepParam; } } if (stepParam < 3) { return Post_PARAM_ERR; } idPostResult_t result = ModemCryptoWrite(env->modemMain, (uint8_t *) env->bufAnswer, crc, offset, size); return result; } // Инициализация записи прошивки крипто-платы idPostResult_t handlerPost_Update_Init_Crypto_WriteFlash(tHttpPostSetting *env) { uint8_t sizeModem; uint8_t sizeCrypto; char versionModem[128]; char versionCrypto[128]; memset(versionModem, 0, sizeof(versionModem)); memset(versionCrypto, 0, sizeof(versionCrypto)); strcpy(versionModem, "null,null"); strcpy(versionCrypto, "null,null"); bool result = Modem_Get_Version_Modem(env->modemMain, versionModem, &sizeModem, versionCrypto, &sizeCrypto); if (result == false) { return Post_SET_MODEM; } char *firmwareCryptoBoot = "null\0"; firmwareCryptoBoot = (char *) strchr(versionCrypto, ','); if (firmwareCryptoBoot != NULL) { *firmwareCryptoBoot = '\0'; firmwareCryptoBoot++; } if (strcmp(versionCrypto, "CRYPTO_BOOT") == 0) { return Post_OK; } return Post_NO_CRYPTO_BOOT; } // Запуск крипто-платы после прошивки idPostResult_t handlerPost_Update_Start_Crypto(tHttpPostSetting *env) { uint8_t sizeModem; uint8_t sizeCrypto; char versionModem[128]; char versionCrypto[128]; memset(versionModem, 0, sizeof(versionModem)); memset(versionCrypto, 0, sizeof(versionCrypto)); strcpy(versionModem, "null,null"); strcpy(versionCrypto, "null,null"); // Запуск прошивки bool result = RunModemOrCrypto(env->modemMain); SystemDelayMs(1000); result = Modem_Get_Version_Modem(env->modemMain, versionModem, &sizeModem, versionCrypto, &sizeCrypto); if (result == false) { return Post_SET_MODEM; } char *firmwareCryptoBoot = "null\0"; firmwareCryptoBoot = (char *) strchr(versionCrypto, ','); if (firmwareCryptoBoot != NULL) { *firmwareCryptoBoot = '\0'; firmwareCryptoBoot++; } if (strcmp(versionCrypto, "CRYPTO_MAIN") == 0) { return Post_OK; } return Post_NO_CRYPTO_MAIN; } // Инициализация записи прошивки модема idPostResult_t handlerPost_Update_Init_Modem_WriteFlash(tHttpPostSetting *env) { uint8_t sizeModem; uint8_t sizeCrypto; char versionModem[128]; char versionCrypto[128]; memset(versionModem, 0, sizeof(versionModem)); memset(versionCrypto, 0, sizeof(versionCrypto)); strcpy(versionModem, "null,null"); strcpy(versionCrypto, "null,null"); env->modemMain->isModemCheck = false; GpioPinSet(&env->gpios->Power.gonec_boot, true); GpioPinSet(&env->gpios->Power.gonec_reset, false); SystemDelayMs(1000); GpioPinSet(&env->gpios->Power.gonec_reset, true); SystemDelayMs(6000); bool result = Modem_Get_Version_Modem(env->modemMain, versionModem, &sizeModem, versionCrypto, &sizeCrypto); if (result == false) { return Post_SET_MODEM; } char *firmwareModemBoot = "null\0"; firmwareModemBoot = (char *) strchr(versionModem, ','); if (firmwareModemBoot != NULL) { *firmwareModemBoot = '\0'; firmwareModemBoot++; } if (strcmp(versionModem, "MODEM_BOOT") == 0) { return Post_OK; } return Post_NO_MODEM_BOOT; } // Запуск модема после прошивки idPostResult_t handlerPost_Update_Start_Modem(tHttpPostSetting *env) { uint8_t sizeModem; uint8_t sizeCrypto; char versionModem[128]; char versionCrypto[128]; memset(versionModem, 0, sizeof(versionModem)); memset(versionCrypto, 0, sizeof(versionCrypto)); strcpy(versionModem, "null,null"); strcpy(versionCrypto, "null,null"); GpioPinSet(&env->gpios->Power.gonec_boot, false); GpioPinSet(&env->gpios->Power.gonec_reset, false); SystemDelayMs(1000); GpioPinSet(&env->gpios->Power.gonec_reset, true); SystemDelayMs(6000); bool result = Modem_Get_Version_Modem(env->modemMain, versionModem, &sizeModem, versionCrypto, &sizeCrypto); if (result == false) { return Post_SET_MODEM; } char *firmwareModemBoot = "null\0"; firmwareModemBoot = (char *) strchr(versionModem, ','); if (firmwareModemBoot != NULL) { *firmwareModemBoot = '\0'; firmwareModemBoot++; } env->modemMain->isModemCheck = false; if (strcmp(versionModem, "MODEM_MAIN") == 0) { env->modemMain->isModemCheck = true; return Post_OK; } return Post_NO_MODEM_MAIN; }