add webserver components, some webserver fices and improvements in templating, add real time history chart

This commit is contained in:
2020-01-07 00:21:27 +01:00
parent ed53611e0f
commit ef7866a29f
50 changed files with 3594 additions and 2 deletions
@@ -0,0 +1,75 @@
/*
* Copyright (C) 2010 Michael Brown <mbrown@fensystems.co.uk>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef BASE16_H_
#define BASE16_H_
#include <stdint.h>
#include <string.h>
/**
* Calculate length of base16-encoded data
* @param raw_len Raw data length
* @return Encoded string length (excluding NUL)
*/
static inline size_t base16_encoded_len(size_t raw_len) {
return (2 * raw_len);
}
/**
* Calculate maximum length of base16-decoded string
* @param encoded Encoded string
* @return Maximum length of raw data
*/
static inline size_t base16_decoded_max_len(const char *encoded) {
return ((strlen(encoded) + 1) / 2);
}
/**
* Base16-encode data
*
* The buffer must be the correct length for the encoded string. Use
* something like
*
* char buf[ base16_encoded_len ( len ) + 1 ];
*
* (the +1 is for the terminating NUL) to provide a buffer of the
* correct size.
*
* @param raw Raw data
* @param len Length of raw data
* @param encoded Buffer for encoded string
*/
extern void base16_encode(uint8_t *raw, size_t len, char *encoded);
/**
* Base16-decode data
*
* The buffer must be large enough to contain the decoded data. Use
* something like
*
* char buf[ base16_decoded_max_len ( encoded ) ];
*
* to provide a buffer of the correct size.
* @param encoded Encoded string
* @param raw Raw data
* @return Length of raw data, or negative error
*/
extern int base16_decode(const char *encoded, uint8_t *raw);
#endif /* BASE16_H_ */
@@ -0,0 +1,131 @@
/**
* TODO file description
*
* Created on 2019/09/13.
*/
#ifndef CSPEMU_DATETIME_H
#define CSPEMU_DATETIME_H
#include <stdbool.h>
#include <stdint.h>
enum weekday {
MONDAY = 1,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
};
_Static_assert(MONDAY==1, "enum weekday numbering Mon");
_Static_assert(SUNDAY==7, "enum weekday numbering Sun");
enum month {
JANUARY = 1,
FEBRUARY,
MARCH,
APRIL,
MAY,
JUNE,
JULY,
AUGUST,
SEPTEMBER,
OCTOBER,
NOVEMBER,
DECEMBER
};
_Static_assert(JANUARY==1, "enum month numbering Jan");
_Static_assert(DECEMBER==12, "enum month numbering Dec");
/** Abbreviated weekday names */
extern const char *DT_WKDAY_NAMES[];
/** Full-length weekday names */
extern const char *DT_WKDAY_NAMES_FULL[];
/** Abbreviated month names */
extern const char *DT_MONTH_NAMES[];
/** Full-length month names */
extern const char *DT_MONTH_NAMES_FULL[];
typedef struct datetime {
uint16_t year;
enum month month;
uint8_t day;
uint8_t hour;
uint8_t min;
uint8_t sec;
enum weekday wkday; // 1=monday
} datetime_t;
// Templates for printf
#define DT_FORMAT_DATE "%d/%d/%d"
#define DT_SUBS_DATE(dt) (dt).year, (dt).month, (dt).day
#define DT_FORMAT_TIME "%d:%02d:%02d"
#define DT_SUBS_TIME(dt) (dt).hour, (dt).min, (dt).sec
#define DT_FORMAT_DATE_WK DT_FORMAT_WK " " DT_FORMAT_DATE
#define DT_SUBS_DATE_WK(dt) DT_SUBS_WK(dt), DT_SUBS_DATE(dt)
#define DT_FORMAT_WK "%s"
#define DT_SUBS_WK(dt) DT_WKDAY_NAMES[(dt).wkday]
#define DT_FORMAT_DATE_TIME DT_FORMAT_DATE " " DT_FORMAT_TIME
#define DT_SUBS_DATE_TIME(dt) DT_SUBS_DATE(dt), DT_SUBS_TIME(dt)
#define DT_FORMAT DT_FORMAT_DATE_WK " " DT_FORMAT_TIME
#define DT_SUBS(dt) DT_SUBS_DATE_WK(dt), DT_SUBS_TIME(dt)
// base century for two-digit year conversions
#define DT_CENTURY 2000
// start year for weekday computation
#define DT_START_YEAR 2019
// January 1st weekday of DT_START_YEAR
#define DT_START_WKDAY TUESDAY
// max date supported by 2-digit year RTC counters (it can't check Y%400==0 with only two digits)
#define DT_END_YEAR 2399
typedef union __attribute__((packed)) {
struct __attribute__((packed)) {
uint8_t ones : 4;
uint8_t tens : 4;
};
uint8_t byte;
} bcd_t;
_Static_assert(sizeof(bcd_t) == 1, "Bad bcd_t len");
/** Check if a year is leap */
static inline bool is_leap_year(int year)
{
return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
}
/**
* Check if a datetime could be valid (ignores leap years)
*
* @param[in] dt
* @return basic validations passed
*/
bool datetime_is_valid(const datetime_t *dt);
/**
* Set weekday based on a date in a given datetime
*
* @param[in,out] dt
* @return success
*/
bool datetime_set_weekday(datetime_t *dt);
/**
* Get weekday for given a date
*
* @param year - year number
* @param month - 1-based month number
* @param day - 1-based day number
* @return weekday
*/
enum weekday date_weekday(uint16_t year, enum month month, uint8_t day);
#endif //CSPEMU_DATETIME_H
@@ -0,0 +1,19 @@
/**
* @file
* @brief A simple way of dumping memory to a hex output
*
* \addtogroup Hexdump
*
* @{
*/
#include <stdio.h>
#define HEX_DUMP_LINE_BUFF_SIZ 16
extern void hex_dump(FILE * fp,void *src, int len);
extern void hex_dump_buff_line(FILE *fp, int addr_size, unsigned pos, char *line, unsigned len);
/**
* }@
*/
@@ -0,0 +1,101 @@
/**
* General purpose, platform agnostic, reusable utils
*/
#ifndef COMMON_UTILS_UTILS_H
#define COMMON_UTILS_UTILS_H
#include <stdbool.h>
#include <stdint.h>
#include "base16.h"
#include "datetime.h"
#include "hexdump.h"
/** Convert a value to BCD struct */
static inline bcd_t num2bcd(uint8_t value)
{
return (bcd_t) {.ones=value % 10, .tens=value / 10};
}
/** Convert unpacked BCD to value */
static inline uint8_t bcd2num(uint8_t tens, uint8_t ones)
{
return tens * 10 + ones;
}
/**
* Append to a buffer.
*
* In case the buffer capacity is reached, it is reverted to the previous length (by replacing the NUL byte)
* and NULL is returned.
*
* @param buf - buffer position to append at; if NULL is given, the function immediately returns NULL.
* @param appended - string to append
* @param pcap - pointer to a capacity variable
* @return the new end of the string (null byte); use as 'buf' for following appends
*/
char *append(char *buf, const char *appended, size_t *pcap);
/**
* Append, re-allocating as needed.
*
* @param head - pointer to heap buffer head, may be updated on realloc.
* @param size - string size pointer, may be updated on realloc.
* @param appended - string to append
* @return false on alloc error
*/
bool append_realloc(char **head, size_t *cap, const char *appended);
/**
* Test if a file descriptor is valid (e.g. when cleaning up after a failed select)
*
* @param fd - file descriptor number
* @return is valid
*/
bool fd_is_valid(int fd);
/**
* parse user-provided string as boolean
*
* @param str
* @return is true
*/
bool parse_boolean_arg(const char *str);
/**
* complementary function to parse_boolean_arg() that matches strings
* meaning 'false'. Can be used together with the positive version
* in case there can be other values as well.
*
* @param str
* @return is false
*/
bool parse_boolean_arg_false(const char *str);
/** Check equality of two strings; returns bool */
#define streq(a, b) (strcmp((const char*)(a), (const char*)(b)) == 0)
/** Check prefix equality of two strings; returns bool */
#define strneq(a, b, n) (strncmp((const char*)(a), (const char*)(b), (n)) == 0)
/** Check if a string starts with a substring; returns bool */
#define strstarts(a, b) strneq((a), (b), (int)strlen((b)))
#ifndef MIN
/** Get min of two numbers */
#define MIN(a, b) ((a) > (b) ? (b) : (a))
#endif
#ifndef MAX
/** Get max of two values */
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
#ifndef STR
#define STR_HELPER(x) #x
/** Stringify a token */
#define STR(x) STR_HELPER(x)
#endif
#endif //COMMON_UTILS_UTILS_H