#ifdef CONFIG_FTP_CLIENT_ENABLE #include #include "app_serv.h" #include "ftp_client.h" #include #include "time.h" #include "term_tsk.h" #include "journal.h" #include "data.h" #include "datadesc.h" #include "ftp_app.h" /* 92.53.96.10 xmiker_morozov Qwerty11 */ // испольузем общий с терминалом буфер данных extern char term_buffer[TERM_BUFFER_SIZE]; extern void PrintEventJournalRecord(TEventRecord *record, char *str_event, char *str_data); CPU_INT08U time_to_ftp = 0; /// void FtpCheckTimeToSend(CPU_INT32U systime) { CPU_INT32U enabled; GetData(&FtpEnableDesc, &enabled, 0, DATA_FLAG_SYSTEM_INDEX); if (enabled) { static const CPU_INT32U intervals_sec[8] = {1, 2, 3, 4, 6, 8, 12, 24}; CPU_INT32U hh_mm; CPU_INT32U interval; CPU_INT32U last_time; TRTC_Data rtc_last, rtc_hhmm, rtc_curr; GetData(&FtpSendIntervalDesc, &interval, 0, DATA_FLAG_SYSTEM_INDEX); if (interval > 7) return; interval = intervals_sec[interval]; GetData(&FtpSendHourMinDesc, &hh_mm, 0, DATA_FLAG_SYSTEM_INDEX); hh_mm *= 60; GetData(&FtpLastSendTimeDesc, &last_time, 0, DATA_FLAG_SYSTEM_INDEX); Sec2Date(&rtc_last, last_time); Sec2Date(&rtc_hhmm, hh_mm); Sec2Date(&rtc_curr, systime); if (systime - last_time > interval * 3600) { // отправляли больше чем заданный интервал назад -> отправляем всё time_to_ftp = FTP_FLAG_SEND_COUNTERS | FTP_FLAG_SEND_LOGS; } else if ((rtc_curr.hour == rtc_hhmm.hour) && (rtc_curr.min == rtc_hhmm.min) && (systime - last_time >= 60)) { // совпал заданный час и минута в сутках + отправляли раньше, чем минуту назад -> отправляем всё time_to_ftp = FTP_FLAG_SEND_COUNTERS | FTP_FLAG_SEND_LOGS; } else if (((rtc_curr.hour % interval) == (rtc_hhmm.hour % interval)) && (rtc_curr.min == rtc_hhmm.min) && (systime - last_time >= 60)) { // если совпал интервал с периодом в течение суток -> отправляем счетчики time_to_ftp |= FTP_FLAG_SEND_COUNTERS; } } } // чтение очередной строки для создания файла csv счетчиков int ReadFtpCountersString(int index, char *buf) { CPU_INT32U i; static const char header1[] = ";Солярий 1 Коллатэн;Солярий 1 Ультрафиолет;Солярий 1 Максимальный;Солярий 2 Коллатэн;Солярий 2 Ультрафиолет;Солярий 2 Максимальный;Солярий 3 Коллатэн;Солярий 3 Ультрафиолет;Солярий 3 Максимальный\r\n"; static const char line1[] = "Деньги, руб."; static const char line2[] = "Запусков"; static const char line3[] = "Наработка, мин."; static const char header2[] = ";Коллатэн;Ультрафиолет;Максимальный\r\n"; static const char header3[] = ";Солярий 1;Солярий 2;Солярий 3\r\n"; static const char line4[] = "Коллатэн, ч:мм"; static const char line5[] = "Ультрафиолет, ч:мм"; static const char header4[] = "Наличные, руб.;Банк, руб.;Всего, руб.\r\n"; static const char line6[] = "Тестовых запусков"; static const char line7[] = "Время теста, мин."; static const char line10[] = "Количество уборок"; static const char line11[] = "Время уборок, мин."; static const char line12[] = "Среднее время уборки, м:сс"; static const char line13[] = "Среднее время теста, м:сс"; switch (index) { case 0: strcpy(buf, header1); break; case 1: strcpy(buf, line1); for (i = 0; i < CHANNELS_NUM * SOLAR_MODES_COUNT; i++) { strcat(buf, ";"); GetDataStr(&CounterSolarMoneyDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 2: strcpy(buf, line2); for (i = 0; i < CHANNELS_NUM * SOLAR_MODES_COUNT; i++) { strcat(buf, ";"); GetDataStr(&CounterSolarRunsDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 3: strcpy(buf, line3); for (i = 0; i < CHANNELS_NUM * SOLAR_MODES_COUNT; i++) { strcat(buf, ";"); GetDataStr(&CounterSolarWorkTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 4: strcpy(buf, line6); for (i = 0; i < CHANNELS_NUM * SOLAR_MODES_COUNT; i++) { strcat(buf, ";"); GetDataStr(&CounterSolarTestRunsDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 5: strcpy(buf, line6); for (i = 0; i < CHANNELS_NUM * SOLAR_MODES_COUNT; i++) { strcat(buf, ";"); GetDataStr(&CounterSolarTestWorkTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 6: strcpy(buf, "\r\n"); break; case 7: strcpy(buf, header2); break; case 8: strcpy(buf, line1); for (i = 0; i < SOLAR_MODES_COUNT; i++) { strcat(buf, ";"); GetDataStr(&CounterModeMoneyDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 9: strcpy(buf, line2); for (i = 0; i < SOLAR_MODES_COUNT; i++) { strcat(buf, ";"); GetDataStr(&CounterModeRunsDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 10: strcpy(buf, line3); for (i = 0; i < SOLAR_MODES_COUNT; i++) { strcat(buf, ";"); GetDataStr(&CounterModeWorkTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 11: strcpy(buf, line6); for (i = 0; i < SOLAR_MODES_COUNT; i++) { strcat(buf, ";"); GetDataStr(&CounterModeTestRunsDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 12: strcpy(buf, line7); for (i = 0; i < SOLAR_MODES_COUNT; i++) { strcat(buf, ";"); GetDataStr(&CounterModeWorkTestTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 13: strcpy(buf, "\r\n"); break; case 14: strcpy(buf, header3); break; case 15: strcpy(buf, line4); for (i = 0; i < CHANNELS_NUM; i++) { strcat(buf, ";"); GetDataStr(&CounterCollatenTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 16: strcpy(buf, line5); for (i = 0; i < CHANNELS_NUM; i++) { strcat(buf, ";"); GetDataStr(&CounterUFTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 17: strcpy(buf, line6); for (i = 0; i < CHANNELS_NUM; i++) { strcat(buf, ";"); GetDataStr(&CounterAllTestCountDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 18: strcpy(buf, line7); for (i = 0; i < CHANNELS_NUM; i++) { strcat(buf, ";"); GetDataStr(&CounterAllTestTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 19: strcpy(buf, line13); for (i = 0; i < CHANNELS_NUM; i++) { strcat(buf, ";"); GetDataStr(&CounterTestMeanTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 20: strcpy(buf, line10); for (i = 0; i < CHANNELS_NUM; i++) { strcat(buf, ";"); GetDataStr(&CounterCleaningCountDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 21: strcpy(buf, line11); for (i = 0; i < CHANNELS_NUM; i++) { strcat(buf, ";"); GetDataStr(&CounterCleaningTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 22: strcpy(buf, line12); for (i = 0; i < CHANNELS_NUM; i++) { strcat(buf, ";"); GetDataStr(&CounterCleaningMeanTimeDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); } strcat(buf, "\r\n"); break; case 23: strcpy(buf, "\r\n"); break; case 24: strcpy(buf, header4); break; case 25: GetDataStr(&CounterCashMoneyDesc, (CPU_INT08U*)buf, i, DATA_FLAG_DIRECT_INDEX); strcat(buf, ";"); GetDataStr(&CounterCardMoneyDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); strcat(buf, ";"); GetDataStr(&CounterCommonMoneyDesc, (CPU_INT08U*)&buf[strlen(buf)], i, DATA_FLAG_DIRECT_INDEX); strcat(buf, "\r\n"); break; default: return 0; } return 1; } // чтение очередной строки для создания файла csv журналов TEventRecord record; int ReadFtpLogString(int index, char *buf) { static const char header[] = "Номер записи;Время;Событие;Данные\r\n"; if (index == 0) { strcpy(buf, header); return 1; } else if ((index >= 1) && (index <= EVENT_RECORDS_COUNT)) { index -= 1; GetEventRecord(&record, index); sprintf(buf, "%d;", index); PrintTimeString(&buf[strlen(buf)], record.time); strcat(buf, ";"); PrintEventJournalRecord(&record, &buf[strlen(buf)], &buf[128]); strcat(buf, ";"); strcpy(&buf[strlen(buf)], &buf[128]); strcat(buf, "\r\n"); return 1; } return 0; } /// отправка на ftp-сервер отчета счетчиков в формате csv int FtpUploadCsvReport(NET_IP_ADDR ip, CPU_INT32U id, char* login, char* pass, CPU_INT32U time, CPU_INT08U flags) { uint16_t port = FTP_CONTROL_PORT; FtpClientContext *ftp_context = (FtpClientContext *)term_buffer; char *bufstr = &term_buffer[sizeof(FtpClientContext)]; int str_index; int res_ftp; char str[48]; memset(ftp_context, 0, sizeof(FtpClientContext)); if (ftpConnect(ftp_context, &ip, port, FTP_PASSIVE_MODE) != 0) { return -1; } if (ftpLogin(ftp_context, login, pass, NULL) != 0) { ftpClose(ftp_context); return -2; } // создадим путь к каталогу выгрузки /solarium/00000001/ res_ftp = ftpChangeWorkingDir(ftp_context, "solarium"); if (res_ftp != 0) { res_ftp = ftpMakeDir(ftp_context, "solarium"); if (res_ftp != 0) { ftpClose(ftp_context); return -3; } res_ftp = ftpChangeWorkingDir(ftp_context, "solarium"); if (res_ftp != 0) { ftpClose(ftp_context); return -3; } } sprintf(str, "%08d", id); res_ftp = ftpChangeWorkingDir(ftp_context, str); if (res_ftp != 0) { res_ftp = ftpMakeDir(ftp_context, str); if (res_ftp != 0) { ftpClose(ftp_context); return -3; } res_ftp = ftpChangeWorkingDir(ftp_context, str); if (res_ftp != 0) { ftpClose(ftp_context); return -3; } } if (flags & FTP_FLAG_SEND_COUNTERS) { // СЧЕТЧИКИ res_ftp = ftpChangeWorkingDir(ftp_context, "counters"); if (res_ftp != 0) { res_ftp = ftpMakeDir(ftp_context, "counters"); if (res_ftp != 0) { ftpClose(ftp_context); return -3; } res_ftp = ftpChangeWorkingDir(ftp_context, "counters"); if (res_ftp != 0) { ftpClose(ftp_context); return -3; } } // имя файла counters/counters_20191201_121005.csv strcpy(str, "counters_"); PrintSecDateTimeStringRaw(&str[strlen(str)], time); strcpy(&str[strlen(str)], ".csv"); res_ftp = ftpOpenFile(ftp_context, str, FTP_FOR_WRITING | FTP_BINARY_TYPE); if (res_ftp != 0) { ftpClose(ftp_context); return -4; } str_index = 0; while (ReadFtpCountersString(str_index, bufstr)) { res_ftp = ftpWriteFile(ftp_context, bufstr, strlen(bufstr), 0); if (res_ftp != 0) { ftpDeleteFile(ftp_context, str); ftpClose(ftp_context); return -5; } str_index++; } res_ftp = ftpCloseFile(ftp_context); if (res_ftp != 0) { ftpDeleteFile(ftp_context, str); ftpClose(ftp_context); return -6; } ftpChangeToParentDir(ftp_context); // имя файла counters.csv strcpy(str, "counters.csv"); res_ftp = ftpOpenFile(ftp_context, str, FTP_FOR_WRITING | FTP_BINARY_TYPE); if (res_ftp != 0) { ftpClose(ftp_context); return -4; } str_index = 0; while (ReadFtpCountersString(str_index, bufstr)) { res_ftp = ftpWriteFile(ftp_context, bufstr, strlen(bufstr), 0); if (res_ftp != 0) { ftpDeleteFile(ftp_context, str); ftpClose(ftp_context); return -5; } str_index++; } res_ftp = ftpCloseFile(ftp_context); if (res_ftp != 0) { ftpDeleteFile(ftp_context, str); ftpClose(ftp_context); return -6; } } // ЖУРНАЛ // имя файла log_20191201_121005.csv if (flags & FTP_FLAG_SEND_LOGS) { res_ftp = ftpChangeWorkingDir(ftp_context, "logs"); if (res_ftp != 0) { res_ftp = ftpMakeDir(ftp_context, "logs"); if (res_ftp != 0) { ftpClose(ftp_context); return -3; } res_ftp = ftpChangeWorkingDir(ftp_context, "logs"); if (res_ftp != 0) { ftpClose(ftp_context); return -3; } } strcpy(str, "log_"); PrintSecDateTimeStringRaw(&str[strlen(str)], time); strcpy(&str[strlen(str)], ".csv"); res_ftp = ftpOpenFile(ftp_context, str, FTP_FOR_WRITING | FTP_BINARY_TYPE); if (res_ftp != 0) { ftpClose(ftp_context); return -4; } str_index = 0; while (ReadFtpLogString(str_index, bufstr)) { res_ftp = ftpWriteFile(ftp_context, bufstr, strlen(bufstr), 0); if (res_ftp != 0) { ftpDeleteFile(ftp_context, str); ftpClose(ftp_context); return -5; } str_index++; } res_ftp = ftpCloseFile(ftp_context); if (res_ftp != 0) { ftpDeleteFile(ftp_context, str); ftpClose(ftp_context); return -6; } } ftpClose(ftp_context); return 0; } #endif //#ifdef CONFIG_FTP_CLIENT_ENABLE