You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
4.9 KiB
154 lines
4.9 KiB
#include "VK_Log.h"
|
|
#include <ulog.h>
|
|
#include <string.h>
|
|
|
|
typedef struct
|
|
{
|
|
rt_uint16_t year;
|
|
rt_uint8_t month;
|
|
rt_uint8_t day;
|
|
rt_uint8_t hour;
|
|
rt_uint8_t minute;
|
|
rt_uint8_t second;
|
|
rt_tick_t base_tick;
|
|
rt_bool_t valid;
|
|
} log_clock_t;
|
|
|
|
static log_clock_t log_clock;
|
|
|
|
static rt_bool_t is_leap_year(rt_uint16_t year)
|
|
{
|
|
return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
|
|
}
|
|
|
|
static rt_uint8_t days_in_month(rt_uint16_t year, rt_uint8_t month)
|
|
{
|
|
static const rt_uint8_t days[] = {31, 28, 31, 30, 31, 30,
|
|
31, 31, 30, 31, 30, 31};
|
|
return (month == 2 && is_leap_year(year)) ? 29 : days[month - 1];
|
|
}
|
|
|
|
static void log_clock_add_seconds(rt_uint32_t seconds,
|
|
rt_uint16_t *year, rt_uint8_t *month,
|
|
rt_uint8_t *day, rt_uint8_t *hour,
|
|
rt_uint8_t *minute, rt_uint8_t *second)
|
|
{
|
|
rt_uint32_t days;
|
|
|
|
*second += seconds % 60;
|
|
if (*second >= 60) { *second -= 60; seconds = seconds / 60 + 1; }
|
|
else { seconds /= 60; }
|
|
*minute += seconds % 60;
|
|
if (*minute >= 60) { *minute -= 60; seconds = seconds / 60 + 1; }
|
|
else { seconds /= 60; }
|
|
*hour += seconds % 24;
|
|
days = seconds / 24;
|
|
if (*hour >= 24) { *hour -= 24; days++; }
|
|
|
|
while (days > 0) {
|
|
rt_uint8_t month_days = days_in_month(*year, *month);
|
|
if (*day < month_days) { (*day)++; days--; }
|
|
else {
|
|
*day = 1;
|
|
if (*month < 12) (*month)++;
|
|
else { *month = 1; (*year)++; }
|
|
days--;
|
|
}
|
|
}
|
|
}
|
|
|
|
int dev_log_time_set_from_at(const char *response)
|
|
{
|
|
const char *p;
|
|
rt_uint16_t year = 0;
|
|
rt_uint8_t fields[5];
|
|
int year_digits = 0;
|
|
int i;
|
|
|
|
if (response == RT_NULL) return -1;
|
|
p = rt_strstr(response, "+QLTS:");
|
|
if (p != RT_NULL) year_digits = 4;
|
|
else {
|
|
p = rt_strstr(response, "+CCLK:");
|
|
if (p == RT_NULL) return -1;
|
|
year_digits = 2;
|
|
}
|
|
p = strchr(p, '"');
|
|
if (p == RT_NULL || p[1] == '"') return -1;
|
|
p++;
|
|
for (i = 0; i < year_digits; i++) {
|
|
if (p[i] < '0' || p[i] > '9') return -1;
|
|
year = (rt_uint16_t)(year * 10 + p[i] - '0');
|
|
}
|
|
p += year_digits;
|
|
if (*p++ != '/') return -1;
|
|
for (i = 0; i < 5; i++) {
|
|
if (p[0] < '0' || p[0] > '9' || p[1] < '0' || p[1] > '9') return -1;
|
|
fields[i] = (rt_uint8_t)((p[0] - '0') * 10 + p[1] - '0');
|
|
p += 2;
|
|
if (i == 0 && *p++ != '/') return -1;
|
|
if (i == 1 && *p++ != ',') return -1;
|
|
if (i >= 2 && i < 4 && *p++ != ':') return -1;
|
|
}
|
|
if ((year_digits == 4 && (year < 2000 || year > 2099)) ||
|
|
(year_digits == 2 && year == 70 && fields[0] == 1 && fields[1] == 1) ||
|
|
fields[0] < 1 || fields[0] > 12 || fields[1] < 1 ||
|
|
fields[1] > days_in_month(year_digits == 2 ? (rt_uint16_t)(2000 + year) : year,
|
|
fields[0]) || fields[2] > 23 ||
|
|
fields[3] > 59 || fields[4] > 59) return -1;
|
|
|
|
log_clock.year = year_digits == 2 ? (rt_uint16_t)(2000 + year) : year;
|
|
log_clock.month = fields[0]; log_clock.day = fields[1];
|
|
log_clock.hour = fields[2]; log_clock.minute = fields[3];
|
|
log_clock.second = fields[4];
|
|
log_clock.base_tick = rt_tick_get();
|
|
log_clock.valid = RT_TRUE;
|
|
return 0;
|
|
}
|
|
|
|
static struct ulog_backend vcom_backend;
|
|
static rt_device_t log_dev = RT_NULL;
|
|
|
|
static void vcom_log_output(struct ulog_backend *backend,
|
|
rt_uint32_t level,
|
|
const char *tag,
|
|
rt_bool_t is_raw,
|
|
const char *log,
|
|
size_t len)
|
|
{
|
|
(void)backend;
|
|
(void)level;
|
|
(void)tag;
|
|
(void)is_raw;
|
|
|
|
if (log_dev != RT_NULL && len > 0) {
|
|
char prefix[32];
|
|
rt_uint16_t year = log_clock.year;
|
|
rt_uint8_t month = log_clock.month, day = log_clock.day;
|
|
rt_uint8_t hour = log_clock.hour, minute = log_clock.minute;
|
|
rt_uint8_t second = log_clock.second;
|
|
if (log_clock.valid) {
|
|
log_clock_add_seconds((rt_uint32_t)((rt_tick_get() - log_clock.base_tick) /
|
|
RT_TICK_PER_SECOND),
|
|
&year, &month, &day, &hour, &minute, &second);
|
|
rt_snprintf(prefix, sizeof(prefix), "[%04u-%02u-%02u %02u:%02u:%02u] ",
|
|
year, month, day, hour, minute, second);
|
|
(void)rt_device_write(log_dev, 0, prefix, rt_strlen(prefix));
|
|
}
|
|
(void)rt_device_write(log_dev, 0, log, len);
|
|
}
|
|
}
|
|
|
|
int dev_log_backend_init(rt_device_t dev)
|
|
{
|
|
if (dev == RT_NULL)
|
|
{
|
|
return -RT_EINVAL;
|
|
}
|
|
|
|
log_dev = dev;
|
|
rt_memset(&vcom_backend, 0, sizeof(vcom_backend));
|
|
vcom_backend.output = vcom_log_output;
|
|
|
|
return ulog_backend_register(&vcom_backend, "vcom", RT_FALSE);
|
|
}
|
|
|