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

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