/********************************* (C) ROTEK *********************************** * @module web_params_api * @file web_params_api.c * @version 1.0.0 * @date XX.XX.XXXX * $brief web_params_api ******************************************************************************* * @history Version Author Comment * XX.XX.XXXX 1.0.0 Telenkov D.A. First release. ******************************************************************************* */ #include "common_config.h" #include "stm32f4xx.h" #include "web_params_api.h" #if defined HTTP_SERVER_ENABLE #include "http_server.h" #elif defined SSL_SERVER_ENABLE #include "my_ssl_server.h" #endif #include "parameters.h" #include "snmp_api.h" #include "trap_api.h" #include "settings_api.h" #include "snmp.h" #include "log.h" #include "hal.h" #include "cJSON.h" #include "FreeRTOS.h" #include "task.h" #ifdef PRINTF_STDLIB #include #endif #ifdef PRINTF_CUSTOM #include "tinystdio.h" #endif #include #include "syslog.h" typedef void (*pFunction)(void); pFunction Jump_To_Application; uint32_t JumpAddress; /** * @brief Возвращяет строку с настройками на первой странице * @retval None */ char *HTTP_GetParamsPage(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut) { uint8_t len; (void)bufIn; (void)lenBufIn; (void)reqNum; cJSON *monitor_param = NULL; memset(bufOut, 0, SEND_BUF_MAX_LEN); // Headers для поддержки saffari strcpy(bufOut, "HTTP/1.1 200 OK\r\nContent-Type:text/html\r\n\r\n"); monitor_param = cJSON_CreateObject(); #define XJSON_PARAMS_TAG(tag, get_param) JSON_ADD_TAG(tag, get_param, monitor_param); WEB_PARAMS_TAGS_TABLE #undef XJSON_PARAMS_TAG if(cJSON_PrintPreallocated(monitor_param, &bufOut[strlen(bufOut)], SEND_BUF_MAX_LEN, 0)) { *lenBufOut = strlen(bufOut); } else { *lenBufOut = 0; } cJSON_Delete(monitor_param); return bufOut; } /** * @brief Возвращяет строку с настройками на второй странице * @retval None */ char *HTTP_GetSettingsPage(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut) { uint8_t len; memset(bufOut, 0, SEND_BUF_MAX_LEN); (void)bufIn; (void)lenBufIn; (void)reqNum; cJSON *settings_param = NULL; /* Headers для поддержки saffari */ strcpy(bufOut, "HTTP/1.1 200 OK\r\nContent-Type:text/html\r\n\r\n"); settings_param = cJSON_CreateObject(); #define XJSON_SETTINGS_TAG(tag, get_param, set_param) JSON_ADD_TAG(tag, get_param, settings_param); WEB_SETTINGS_TAGS_TABLE #undef XJSON_SETTINGS_TAG if(cJSON_PrintPreallocated(settings_param, &bufOut[strlen(bufOut)], SEND_BUF_MAX_LEN, 0)) { *lenBufOut = strlen(bufOut); } else { *lenBufOut = 0; } cJSON_Delete(settings_param); return bufOut; } uint8_t ConvertStringForJSON(char *inStr, char *paramValue, uint8_t inLen) { int len = 0, len2 = 0; char *strPtr = 0; uint8_t i = 0; while (i < inLen) { strPtr = strstr(inStr, "\""); if (strPtr != 0) { len = strPtr - inStr; if (len != 0) { strncat(paramValue, inStr, len); } strncat(paramValue, "\\", 1); strncat(paramValue, &inStr[len], 1); inStr = inStr + len + 1; i = i + len + 1; } else { if (paramValue != 0) { len2 = inLen - i; strncat(paramValue, inStr, len2); return 1; } else { return 0; } } } if (inLen == 0) { return 0; } return 1; } #ifdef NOTIFICATION_CONTROL_ENABLE /** * @brief Возвращяет строку с настройками уведомлений (есть/нет отправка) * @retval None */ char *HTTP_GetTrapAccess(char *params, uint16_t len_params, char *buf, uint16_t *len_out) { char str[64]; uint8_t len, i, first_item = 1; char value[20]; (void)len_params; ClearParamString(params); memset(value, 0, 20); memset(str, 0, 64); /* Headers для поддержки saffari */ strcpy(buf, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\n\r\n"); /* Формирование списка уведомлений */ strcat(buf, "{\"params\":["); for (i = 1; i < ALL_TRAPS; i++) { if (first_item) { first_item = 0; } else { strcat(buf, ","); } sprintf(str, "%d", i); len = strlen(str); strcat(buf, "{\"name\":\""); strncat(buf, str, len); GetTrapLongNameStr(str, &len, i); strcat(buf, "\",\"label\":\""); strncat(buf, str, len); GetNotificationTrapsStateStr(str, &len, i); strcat(buf, "\",\"snmp\":\""); strncat(buf, str, len); strcat(buf, "\"}"); } strcat(buf, "]"); /* Признак изменения сетевых настроек */ GetWebReinitFlag(str, &len); strcat(buf, ",\"netsettings_changed\":\""); strncat(buf, str, len); strcat(buf, "\"}"); *len_out = strlen(buf); return buf; } #endif /** * @brief Возвращяет строку с информацией об устройстве * @retval None */ // TODO Согласовать максимальную длину строк char *HTTP_GetInfo(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut) { char str[110]; char tmp_str[220]; uint8_t len; char tempStr[30]; strncpy(tempStr, bufIn, 30); (void)lenBufIn; (void)reqNum; /* В запросе нет параметров, нужно формировать JSON ответ */ if (strpbrk(tempStr, "?") == 0) { memset(bufOut, 0, SEND_BUF_MAX_LEN); /* Headers для поддержки saffari */ strcpy(bufOut, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\n\r\n"); GetWorkTimeStr(str, &len); strcat(bufOut, "{\"uptime\":\""); strncat(bufOut, str, len); GetModelStr(str, &len); strcat(bufOut, "\",\"model\":\""); strncat(bufOut, str, len); GetProductionDataStr(str, &len); strcat(bufOut, "\",\"prodate\":\""); strncat(bufOut, str, len); GetVersionStr(str, &len); strcat(bufOut, "\",\"fwversion\":\""); strncat(bufOut, str, len); GetMacStr(str, &len); strcat(bufOut, "\",\"macaddr\":\""); strncat(bufOut, str, len); GetSerialNumberStr(str, &len); strcat(bufOut, "\",\"serno\":\""); strncat(bufOut, str, len); GetNameDeviceStr(str, &len); str[len] = 0; strcat(bufOut, "\",\"sysname\":\""); memset(tmp_str, 0, sizeof(tmp_str)); if (ConvertStringForJSON(str, tmp_str, len)) { strncat(bufOut, tmp_str, strlen(tmp_str)); } else { strncat(bufOut, str, len); } GetOwnerStr(str, &len); str[len] = 0; strcat(bufOut, "\",\"owner\":\""); memset(tmp_str, 0, sizeof(tmp_str)); if (ConvertStringForJSON(str, tmp_str, len)) { strncat(bufOut, tmp_str, strlen(tmp_str)); } else { strncat(bufOut, str, len); } GetLocationStr(str, &len); str[len] = 0; strcat(bufOut, "\",\"sysLocation\":\""); memset(tmp_str, 0, sizeof(tmp_str)); if (ConvertStringForJSON(str, tmp_str, len)) { strncat(bufOut, tmp_str, strlen(tmp_str)); } else { strncat(bufOut, str, len); } GetCommentsStr(str, &len); str[len] = 0; strcat(bufOut, "\",\"comment\":\""); memset(tmp_str, 0, sizeof(tmp_str)); if (ConvertStringForJSON(str, tmp_str, len)) { strncat(bufOut, tmp_str, strlen(tmp_str)); } else { strncat(bufOut, str, len); } GetUPSModelStr(str, &len); strcat(bufOut, "\",\"ups_model\":\""); strncat(bufOut, str, len); GetUPSSerialStr(str, &len); strcat(bufOut, "\",\"ups_sn\":\""); strncat(bufOut, str, len); GetUPSVersionStr(str, &len); strcat(bufOut, "\",\"ups_fwversion\":\""); strncat(bufOut, str, len); /* Признак изменения сетевых настроек */ GetWebReinitFlag(str, &len); strcat(bufOut, "\",\"netsettings_changed\":\""); strncat(bufOut, str, len); strncat(bufOut, "\"}", 2); *lenBufOut = strlen(bufOut); return bufOut; } *lenBufOut = 0; return NULL; } void HTTP_GetHistoryPage(char *buf, uint32_t pageNumber) { char str[16]; uint16_t len; strcpy(buf, "HTTP/1.1 200 OK\r\nContent-Type:text/html\r\n\r\n"); strcat(buf, "{\"page\": ["); History_GetPage(buf, pageNumber); len = strlen(buf); buf += len - 1; *buf = 0; buf -= len - 1; /* Количество страниц */ memset(str, 0, 16); sprintf(str, "%i", History_GetPageCount()); strcat(buf, "],\"pages\":\""); strcat(buf, str); /* Часовой пояс */ GetSntpTimeZoneStr(str, (uint8_t *)&len); strcat(buf, "\",\"utc\":\""); strncat(buf, str, len); GetUnixTimeStr(str, (uint8_t *)&len); strcat(buf, "\",\"utm\":\""); strncat(buf, str, len); strcat(buf, "\"}"); //printf(buf); } void HTTP_GetUpsHistoryPage(char *buf, uint32_t pageNumber) { char str[16]; uint16_t len; strcpy(buf, "HTTP/1.1 200 OK\r\nContent-Type:text/html\r\n\r\n"); strcat(buf, "{\"page\": ["); LOG_GetPage(buf, pageNumber); len = strlen(buf); buf += len - 1; *buf = 0; buf -= len - 1; /* Количество страниц */ memset(str, 0, 16); sprintf(str, "%i", LOG_GetPageCount()); strcat(buf, "],\"pages\":\""); strcat(buf, str); /* Часовой пояс */ GetSntpTimeZoneStr(str, (uint8_t *)&len); strcat(buf, "\",\"utc\":\""); strncat(buf, str, len); GetUnixTimeStr(str, (uint8_t *)&len); strcat(buf, "\",\"utm\":\""); strncat(buf, str, len); strcat(buf, "\"}"); //printf(buf); } /** * @brief Возвращает uptime, freq, dutycicle */ void HTTP_GetProgonParams(char *buf) { char str[20]; u32_t tick; strcpy(buf, "HTTP/1.0 200 OK\r\nContent-Type:text/html\r\n\r\n"); strcat(buf, "{\"uptime\":\""); // snmp_get_sysuptime(&tick); tick = tick / 100; memset(str, 0, 20); sprintf(str, "%d", tick); strncat(buf, str, strlen(str)); strncat(buf, "\"}", 2); } /** * @brief Сброс настроек (всё кроме сетевых параметров) */ void HTTP_ResetSettings(void) { //taskENTER_CRITICAL(); SNMP_SendUserTrap(DEVICE_RESTORED); syslog_str(SYSLOG_INFORMATIONAL, "Сброс настроек (Администратор)"); log_event_data(LOG_SYSTEM_DEFCONFIG, name_login); vTaskDelay(500); SETTINGS_SetPartDefault(); SETTINGS_Save(); //taskEXIT_CRITICAL(); } /** * @brief Сохранение настроек */ void HTTP_SaveSettings(void) { // taskENTER_CRITICAL(); SETTINGS_Save(); log_event_data(LOG_SETTING_SAVE, name_login); // taskEXIT_CRITICAL(); } /** * @brief Перезагрузка контроллера */ char *HTTP_Reboot(uint32_t reqNum, char *bufIn, char *bufOut, uint16_t lenBufIn, uint16_t *lenBufOut) { (void)bufIn; (void)lenBufIn; (void)reqNum; strcpy(bufOut, "HTTP/1.1 200 OK\r\n"); *lenBufOut = strlen(bufOut); /* Запускаем задачу отложенной перезагрузки. Контроллер должен успеть * отправить ответ серверу об успешном выполнении команды */ HTTP_StartResetTask(false); return bufOut; } /** * @brief Запускает задачу ресета контроллера * @param fBootMode: * true - перед перезагрузкой будет установлен флаг входа в режим * bootloader и перезаписаны настройки * * false - обычная перезагрузка */ void HTTP_StartResetTask(bool fBootMode) { static bool temp; temp = fBootMode; xTaskCreate(vTaskReboot, "RebootTask", configMINIMAL_STACK_SIZE, (void *)&temp, tskIDLE_PRIORITY, NULL); } /** * @brief */ void vTaskReboot(void *pvParameters) { bool mode = false; // тип перезагрузки (нужно ли устанавливать флаг bootloader) for (;;) { mode = *(bool *)pvParameters; if (mode) { SNMP_SendUserTrap(FW_VERSION_UPDATE); source_act_t src_act = get_act_source(); syslog(SYSLOG_INFORMATIONAL, "Запуск обновления ПО (%s)", src_act == FTP_ACT ? "FTP" : "HTTP"); #ifdef CLI_ENABLE if (src_act == CLI_ACT) { log_event_data(LOG_UPDATE_SOFT, "Администратор"); } else #endif log_event_data(LOG_UPDATE_SOFT, name_login); SetLoadMode(); #ifdef CLI_ENABLE if (src_act == CLI_ACT) { SETTINGS_Save(); log_event_data(LOG_SETTING_SAVE, "Администратор"); } else #endif HTTP_SaveSettings(); vTaskDelay(2000); vTaskDelay(1010); Reboot(src_act); } else { vTaskDelay(1000); vTaskDelay(1010); Reboot(SNMP_ACT); } } } /********************************* (C) ROTEK **********************************/