@ -23,9 +23,8 @@ extern void * mem_trim(void *m, size_t s); // not well documented...
# endif
# endif
# define WIFI_CHK_INTERVAL 1000 // ms to check Wifi statis
# define WIFI_CHK_INTERVAL 1000 // ms to check Wifi statis
static os_timer_t wifi_chk_timer ;
static struct espconn syslog_espconn ;
static struct espconn * syslog_espconn = NULL ;
static uint32_t syslog_msgid = 1 ;
static uint32_t syslog_msgid = 1 ;
static uint8_t syslog_task = 0 ;
static uint8_t syslog_task = 0 ;
@ -34,144 +33,136 @@ static syslog_entry_t *syslogQueue = NULL;
static enum syslog_state syslogState = SYSLOG_NONE ;
static enum syslog_state syslogState = SYSLOG_NONE ;
static bool syslog_timer_armed = false ;
static void ICACHE_FLASH_ATTR syslog_add_entry ( syslog_entry_t * entry ) ;
static void ICACHE_FLASH_ATTR syslog_add_entry ( syslog_entry_t * entry ) ;
static void ICACHE_FLASH_ATTR syslog_chk_wifi_stat ( void ) ;
static void ICACHE_FLASH_ATTR syslog_chk_status ( void ) ;
static void ICACHE_FLASH_ATTR syslog_udp_sent_cb ( void * arg ) ;
static void ICACHE_FLASH_ATTR syslog_udp_sent_cb ( void * arg ) ;
static syslog_entry_t ICACHE_FLASH_ATTR * syslog_compose ( uint8_t facility , uint8_t severity , const char * tag , const char * fmt , . . . ) ;
# ifdef SYSLOG_UDP_RECV
# ifdef SYSLOG_UDP_RECV
static void ICACHE_FLASH_ATTR syslog_udp_recv_cb ( void * arg , char * pusrdata , unsigned short length ) ;
static void ICACHE_FLASH_ATTR syslog_udp_recv_cb ( void * arg , char * pusrdata , unsigned short length ) ;
# endif
# endif
# define syslog_send_udp() post_usr_task(syslog_task,0)
# define syslog_send_udp() post_usr_task(syslog_task,0)
# ifdef SYSLOG_DBG
static char ICACHE_FLASH_ATTR * syslog_get_status ( void ) {
switch ( syslogState )
{
case SYSLOG_NONE :
return " SYSLOG_NONE " ;
case SYSLOG_WAIT :
return " SYSLOG_WAIT " ;
case SYSLOG_INIT :
return " SYSLOG_INIT " ;
case SYSLOG_INITDONE :
return " SYSLOG_INITDONE " ;
case SYSLOG_DNSWAIT :
return " SYSLOG_DNSWAIT " ;
case SYSLOG_READY :
return " SYSLOG_READY " ;
case SYSLOG_SENDING :
return " SYSLOG_SENDING " ;
case SYSLOG_SEND :
return " SYSLOG_SEND " ;
case SYSLOG_SENT :
return " SYSLOG_SENT " ;
case SYSLOG_HALTED :
return " SYSLOG_HALTED " ;
case SYSLOG_ERROR :
return " SYSLOG_ERROR " ;
default :
break ;
}
return " UNKNOWN " ;
}
# endif
static void ICACHE_FLASH_ATTR syslog_set_status ( enum syslog_state state ) {
syslogState = state ;
DBG ( " [%dµs] %s: %s (%d) \n " , WDEV_NOW ( ) , __FUNCTION__ , syslog_get_status ( ) , state ) ;
}
static void ICACHE_FLASH_ATTR syslog_timer_arm ( int delay ) {
static os_timer_t wifi_chk_timer = { } ;
syslog_timer_armed = true ;
os_timer_disarm ( & wifi_chk_timer ) ;
os_timer_setfn ( & wifi_chk_timer , ( os_timer_func_t * ) syslog_chk_status , NULL ) ;
os_timer_arm ( & wifi_chk_timer , delay , 0 ) ;
}
/******************************************************************************
/******************************************************************************
* FunctionName : syslog_chk_wifi_stat
* FunctionName : syslog_chk_status
* Description : check whether get ip addr or not
* Description : check whether get ip addr or not
* Parameters : none
* Parameters : none
* Returns : none
* Returns : none
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void ICACHE_FLASH_ATTR syslog_chk_wifi_stat ( void )
static void ICACHE_FLASH_ATTR syslog_chk_status ( void )
{
{
struct ip_info ipconfig ;
struct ip_info ipconfig ;
DBG ( " syslog_chk_wifi_stat: state: %d " , syslogState ) ;
DBG ( " [%uµs] %s: id=%lu " , WDEV_NOW ( ) , __FUNCTION__ , syslogQueue ? syslogQueue - > msgid : 0 ) ;
//disarm timer first
//disarm timer first
os_timer_disarm ( & wifi_chk_timer ) ;
syslog_timer_armed = false ;
//try to get ip info of ESP8266 station
//try to get ip info of ESP8266 station
wifi_get_ip_info ( STATION_IF , & ipconfig ) ;
wifi_get_ip_info ( STATION_IF , & ipconfig ) ;
int wifi_status = wifi_station_get_connect_status ( ) ;
int wifi_status = wifi_station_get_connect_status ( ) ;
if ( wifi_status = = STATION_GOT_IP & & ipconfig . ip . addr ! = 0 )
if ( wifi_status = = STATION_GOT_IP & & ipconfig . ip . addr ! = 0 )
{
{
if ( syslogState = = SYSLOG_WAIT ) { // waiting for initialization
// it seems we have to add an additional delay after the Wifi is up and running.
DBG ( " connected, initializing UDP socket \n " ) ;
// so we simply add an intermediate state with 25ms delay
switch ( syslogState )
{
case SYSLOG_WAIT :
DBG ( " %s: Wifi connected \n " , syslog_get_status ( ) ) ;
syslog_set_status ( SYSLOG_INIT ) ;
syslog_timer_arm ( 100 ) ;
break ;
case SYSLOG_INIT :
DBG ( " %s: init syslog \n " , syslog_get_status ( ) ) ;
syslog_set_status ( SYSLOG_INITDONE ) ;
syslog_init ( flashConfig . syslog_host ) ;
syslog_init ( flashConfig . syslog_host ) ;
syslog_timer_arm ( 10 ) ;
break ;
case SYSLOG_DNSWAIT :
DBG ( " %s: wait for DNS resolver \n " , syslog_get_status ( ) ) ;
syslog_timer_arm ( 10 ) ;
break ;
case SYSLOG_READY :
DBG ( " %s: enforce sending \n " , syslog_get_status ( ) ) ;
syslog_send_udp ( ) ;
break ;
case SYSLOG_SENDING :
DBG ( " %s: delay \n " , syslog_get_status ( ) ) ;
syslog_set_status ( SYSLOG_SEND ) ;
syslog_timer_arm ( 2 ) ;
break ;
case SYSLOG_SEND :
DBG ( " %s: start sending \n " , syslog_get_status ( ) ) ;
syslog_send_udp ( ) ;
break ;
default :
DBG ( " %s: %d \n " , syslog_get_status ( ) , syslogState ) ;
break ;
}
}
} else {
} else {
if ( ( wifi_status = = STATION_WRONG_PASSWORD | |
if ( ( wifi_status = = STATION_WRONG_PASSWORD | |
wifi_status = = STATION_NO_AP_FOUND | |
wifi_status = = STATION_NO_AP_FOUND | |
wifi_status = = STATION_CONNECT_FAIL ) ) {
wifi_status = = STATION_CONNECT_FAIL ) ) {
syslogState = SYSLOG_ERROR ;
syslog_set_status ( SYSLOG_ERROR ) ;
os_printf ( " *** connect failure!!! \n " ) ;
os_printf ( " *** connect failure!!! \n " ) ;
} else {
} else {
DBG ( " re-arming timer... \n " ) ;
DBG ( " re-arming timer... \n " ) ;
os_timer_setfn ( & wifi_chk_timer , ( os_timer_func_t * ) syslog_chk_wifi_stat , NULL ) ;
syslog_timer_arm ( WIFI_CHK_INTERVAL ) ;
os_timer_arm ( & wifi_chk_timer , WIFI_CHK_INTERVAL , 0 ) ;
}
}
}
static void ICACHE_FLASH_ATTR syslog_udp_send_event ( os_event_t * events ) {
if ( syslogQueue = = NULL )
syslogState = SYSLOG_READY ;
else {
int res = 0 ;
syslog_espconn . proto . udp - > remote_port = syslogHost . port ; // ESP8266 udp remote port
os_memcpy ( & syslog_espconn . proto . udp - > remote_ip , & syslogHost . addr . addr , 4 ) ; // ESP8266 udp remote IP
res = espconn_send ( & syslog_espconn , ( uint8_t * ) syslogQueue - > datagram , syslogQueue - > datagram_len ) ;
if ( res ! = 0 ) {
os_printf ( " syslog_udp_send: error %d \n " , res ) ;
}
}
}
/******************************************************************************
* FunctionName : syslog_compose
* Description : compose a syslog_entry_t from va_args
* Parameters : va_args
* Returns : the malloced syslog_entry_t
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static syslog_entry_t * ICACHE_FLASH_ATTR syslog_compose ( uint8_t facility , uint8_t severity , const char * tag , const char * fmt , . . . )
{
syslog_entry_t * se = os_zalloc ( sizeof ( syslog_entry_t ) + 1024 ) ; // allow up to 1k datagram
char * p = se - > datagram ;
uint32_t tick = WDEV_NOW ( ) ; // 0 ... 4294.967295s
// The Priority value is calculated by first multiplying the Facility
// number by 8 and then adding the numerical value of the Severity.
p + = os_sprintf ( p , " <%d> " , facility * 8 + severity ) ;
// strftime doesn't work as expected - or adds 8k overhead.
// so let's do poor man conversion - format is fixed anyway
if ( flashConfig . syslog_showdate = = 0 )
p + = os_sprintf ( p , " - " ) ;
else {
time_t now = NULL ;
struct tm * tp = NULL ;
// create timestamp: FULL-DATE "T" PARTIAL-TIME "Z": 'YYYY-mm-ddTHH:MM:SSZ '
// as long as realtime_stamp is 0 we use tick div 10⁶ as date
now = ( realtime_stamp = = 0 ) ? ( tick / 1000000 ) : realtime_stamp ;
tp = gmtime ( & now ) ;
p + = os_sprintf ( p , " %4d-%02d-%02dT%02d:%02d:%02dZ " ,
tp - > tm_year + 1900 , tp - > tm_mon + 1 , tp - > tm_mday ,
tp - > tm_hour , tp - > tm_min , tp - > tm_sec ) ;
}
// add HOSTNAME APP-NAME PROCID MSGID
if ( flashConfig . syslog_showtick )
p + = os_sprintf ( p , " %s %s %lu.%06lu %lu " , flashConfig . hostname , tag , tick / 1000000 , tick % 1000000 , syslog_msgid + + ) ;
else
p + = os_sprintf ( p , " %s %s - %lu " , flashConfig . hostname , tag , syslog_msgid + + ) ;
// append syslog message
va_list arglist ;
va_start ( arglist , fmt ) ;
p + = ets_vsprintf ( p , fmt , arglist ) ;
va_end ( arglist ) ;
se - > datagram_len = p - se - > datagram ;
se = mem_trim ( se , sizeof ( syslog_entry_t ) + se - > datagram_len + 1 ) ;
return se ;
}
/******************************************************************************
* FunctionName : syslog_add_entry
* Description : add a syslog_entry_t to the syslogQueue
* Parameters : entry : the syslog_entry_t
* Returns : none
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void ICACHE_FLASH_ATTR syslog_add_entry ( syslog_entry_t * entry )
{
syslog_entry_t * pse = syslogQueue ;
// append msg to syslog_queue
if ( pse = = NULL )
syslogQueue = entry ;
else {
while ( pse - > next ! = NULL )
pse = pse - > next ;
pse - > next = entry ; // append msg to syslog queue
}
// ensure we have sufficient heap for the rest of the system
if ( system_get_free_heap_size ( ) < syslogHost . min_heap_size ) {
if ( syslogState ! = SYSLOG_HALTED ) {
os_printf ( " syslog_add_entry: Warning: queue filled up, halted \n " ) ;
entry - > next = syslog_compose ( SYSLOG_FAC_SYSLOG , SYSLOG_PRIO_CRIT , " - " , " queue filled up, halted " ) ;
if ( syslogState = = SYSLOG_READY )
syslog_send_udp ( ) ;
syslogState = SYSLOG_HALTED ;
}
}
}
}
}
}
@ -188,15 +179,39 @@ static void ICACHE_FLASH_ATTR syslog_udp_sent_cb(void *arg)
struct espconn * pespconn = arg ;
struct espconn * pespconn = arg ;
( void ) pespconn ;
( void ) pespconn ;
DBG ( " [%uµs] %s: id=%lu \n " , WDEV_NOW ( ) , __FUNCTION__ , syslogQueue ? syslogQueue - > msgid : 0 ) ;
// datagram is delivered - free and advance queue
// datagram is delivered - free and advance queue
syslog_entry_t * pse = syslogQueue ;
syslog_entry_t * pse = syslogQueue ;
syslogQueue = syslogQueue - > next ;
syslogQueue = syslogQueue - > next ;
os_free ( pse ) ;
os_free ( pse ) ;
if ( syslogQueue ! = NULL )
if ( syslogQueue = = NULL )
syslog_send_udp ( ) ;
syslog_set_status ( SYSLOG_READY ) ;
else
else {
syslogState = SYSLOG_READY ;
// UDP seems timecritical - we must ensure a minimum delay after each package...
syslog_set_status ( SYSLOG_SENDING ) ;
if ( ! syslog_timer_armed )
syslog_chk_status ( ) ;
}
}
static void ICACHE_FLASH_ATTR
syslog_udp_send_event ( os_event_t * events ) {
// os_printf("syslog_udp_send_event: %d %lu, %lu\n", syslogState, syslogQueue->msgid, syslogQueue->tick);
DBG ( " [%uµs] %s: id=%lu \n " , WDEV_NOW ( ) , __FUNCTION__ , syslogQueue ? syslogQueue - > msgid : 0 ) ;
if ( syslogQueue = = NULL )
syslog_set_status ( SYSLOG_READY ) ;
else {
int res = 0 ;
syslog_espconn - > proto . udp - > remote_port = syslogHost . port ; // ESP8266 udp remote port
os_memcpy ( syslog_espconn - > proto . udp - > remote_ip , & syslogHost . addr . addr , 4 ) ; // ESP8266 udp remote IP
res = espconn_send ( syslog_espconn , ( uint8_t * ) syslogQueue - > datagram , syslogQueue - > datagram_len ) ;
if ( res ! = 0 ) {
os_printf ( " syslog_udp_send: error %d \n " , res ) ;
}
}
}
}
/*****************************************************************************
/*****************************************************************************
@ -221,14 +236,18 @@ static void ICACHE_FLASH_ATTR syslog_gethostbyname_cb(const char *name, ip_addr_
{
{
struct espconn * pespconn = ( struct espconn * ) arg ;
struct espconn * pespconn = ( struct espconn * ) arg ;
( void ) pespconn ;
( void ) pespconn ;
DBG ( " [%uµs] %s \n " , WDEV_NOW ( ) , __FUNCTION__ ) ;
if ( ipaddr ! = NULL ) {
if ( ipaddr ! = NULL ) {
syslog ( SYSLOG_FAC_USER , SYSLOG_PRIO_NOTICE , " SYSLOG " ,
" resolved hostname: %s: " IPSTR , name , IP2STR ( ipaddr ) ) ;
syslogHost . addr . addr = ipaddr - > addr ;
syslogHost . addr . addr = ipaddr - > addr ;
syslogState = SYSLOG_SENDING ;
syslog_set_status ( SYSLOG_READY ) ;
syslog_send_udp ( ) ;
} else {
} else {
syslogState = SYSLOG_ERROR ;
syslog_set_status ( SYSLOG_ERROR ) ;
DBG ( " syslog_gethostbyname_cb: state=SYSLOG_ERROR \n " ) ;
DBG ( " syslog_gethostbyname_cb: status=%s \n " , syslog_get_status ( ) ) ;
}
}
DBG ( " [%uµs] ex syslog_gethostbyname_cb() \n " , WDEV_NOW ( ) ) ;
}
}
/******************************************************************************
/******************************************************************************
@ -240,55 +259,175 @@ static void ICACHE_FLASH_ATTR syslog_gethostbyname_cb(const char *name, ip_addr_
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void ICACHE_FLASH_ATTR syslog_init ( char * syslog_host )
void ICACHE_FLASH_ATTR syslog_init ( char * syslog_host )
{
{
DBG ( " [%uµs] %s \n " , WDEV_NOW ( ) , __FUNCTION__ ) ;
if ( ! * syslog_host ) {
if ( ! * syslog_host ) {
syslogState = SYSLOG_HALTED ;
syslog_set_status ( SYSLOG_HALTED ) ;
return ;
return ;
}
}
char host [ 32 ] , * port = & host [ 0 ] ;
syslog_task = register_usr_task ( syslog_udp_send_event ) ;
if ( syslog_host = = NULL ) {
syslogHost . min_heap_size = flashConfig . syslog_minheap ;
// disable and unregister syslog handler
syslogHost . port = 514 ;
syslog_set_status ( SYSLOG_HALTED ) ;
syslogState = SYSLOG_WAIT ;
if ( syslog_espconn ! = NULL ) {
if ( syslog_espconn - > proto . udp ) {
// there's no counterpart to espconn_create...
os_free ( syslog_espconn - > proto . udp ) ;
}
os_free ( syslog_espconn ) ;
}
syslog_espconn = NULL ;
// clean up syslog queue
syslog_entry_t * pse = syslogQueue ;
while ( pse ! = NULL ) {
syslog_entry_t * next = pse - > next ;
os_free ( pse ) ;
pse = next ;
}
syslogQueue = NULL ;
return ;
}
char host [ 32 ] , * port = & host [ 0 ] ;
os_strncpy ( host , syslog_host , 32 ) ;
os_strncpy ( host , syslog_host , 32 ) ;
while ( * port & & * port ! = ' : ' ) // find port delimiter
while ( * port & & * port ! = ' : ' ) // find port delimiter
port + + ;
port + + ;
if ( * port ) {
if ( * port ) {
* port + + = ' \0 ' ;
* port + + = ' \0 ' ;
syslogHost . port = atoi ( port ) ;
syslogHost . port = atoi ( port ) ;
}
}
wifi_set_broadcast_if ( STATIONAP_MODE ) ; // send UDP broadcast from both station and soft-AP interface
if ( syslogHost . port = = 0 )
syslog_espconn . type = ESPCONN_UDP ;
syslogHost . port = 514 ;
syslog_espconn . proto . udp = ( esp_udp * ) os_zalloc ( sizeof ( esp_udp ) ) ;
syslog_espconn . proto . udp - > local_port = espconn_port ( ) ; // set a available port
// allocate structures, init syslog_handler
if ( syslog_espconn = = NULL )
syslog_espconn = ( espconn * ) os_zalloc ( sizeof ( espconn ) ) ;
if ( syslog_espconn - > proto . udp = = NULL )
syslog_espconn - > proto . udp = ( esp_udp * ) os_zalloc ( sizeof ( esp_udp ) ) ;
syslog_espconn - > type = ESPCONN_UDP ;
syslog_espconn - > proto . udp - > local_port = espconn_port ( ) ; // set a available port
# ifdef SYSLOG_UDP_RECV
# ifdef SYSLOG_UDP_RECV
espconn_regist_recvcb ( & syslog_espconn , syslog_udp_recv_cb ) ; // register a udp packet receiving callback
espconn_regist_recvcb ( syslog_espconn , syslog_udp_recv_cb ) ; // register a udp packet receiving callback
# endif
# endif
espconn_regist_sentcb ( & syslog_espconn , syslog_udp_sent_cb ) ; // register a udp packet sent callback
espconn_regist_sentcb ( syslog_espconn , syslog_udp_sent_cb ) ; // register a udp packet sent callback
espconn_create ( & syslog_espconn ) ; // create udp
syslog_task = register_usr_task ( syslog_udp_send_event ) ;
syslogHost . min_heap_size = flashConfig . syslog_minheap ;
// the wifi_set_broadcast_if must be handled global in connection handler...
// wifi_set_broadcast_if(STATIONAP_MODE); // send UDP broadcast from both station and soft-AP interface
espconn_create ( syslog_espconn ) ; // create udp
syslog ( SYSLOG_FAC_USER , SYSLOG_PRIO_NOTICE , " SYSLOG " ,
" syslogserver: %s:%d %d " , host , syslogHost . port , syslog_espconn - > proto . udp - > local_port ) ;
if ( UTILS_StrToIP ( ( const char * ) host , ( void * ) & syslogHost . addr ) ) {
if ( UTILS_StrToIP ( ( const char * ) host , ( void * ) & syslogHost . addr ) ) {
syslogState = SYSLOG_SENDING ;
syslog_set_status ( SYSLOG_READY ) ;
syslog_send_udp ( ) ;
} else {
} else {
static struct espconn espconn_ghbn ;
syslog_set_status ( SYSLOG_DNSWAIT ) ;
espconn_gethostbyname ( & espconn_ghbn , host , & syslogHost . addr , syslog_gethostbyname_cb ) ;
syslog ( SYSLOG_FAC_USER , SYSLOG_PRIO_NOTICE , " SYSLOG " ,
// syslog_send_udp is called by syslog_gethostbyname_cb()
" must resolve hostname \" %s \" " , host ) ;
espconn_gethostbyname ( syslog_espconn , host , & syslogHost . addr , syslog_gethostbyname_cb ) ;
}
}
# ifdef SYSLOG_UDP_RECV
DBG ( " syslog_init: host: %s, port: %d, lport: %d, recvcb: %p, sentcb: %p, state: %d \n " ,
host , syslogHost . port , syslog_espconn . proto . udp - > local_port ,
syslog_udp_recv_cb , syslog_udp_sent_cb , syslogState ) ;
# else
DBG ( " syslog_init: host: %s, port: %d, lport: %d, rsentcb: %p, state: %d \n " ,
host , syslogHost . port , syslog_espconn . proto . udp - > local_port ,
syslog_udp_sent_cb , syslogState ) ;
# endif
}
}
/******************************************************************************
/******************************************************************************
* FunctionName : syslog_add_entry
* Description : add a syslog_entry_t to the syslogQueue
* Parameters : entry : the syslog_entry_t
* Returns : none
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void ICACHE_FLASH_ATTR
syslog_add_entry ( syslog_entry_t * entry )
{
syslog_entry_t * pse = syslogQueue ;
DBG ( " [%dµs] %s id=%lu \n " , WDEV_NOW ( ) , __FUNCTION__ , entry - > msgid ) ;
// append msg to syslog_queue
if ( pse = = NULL )
syslogQueue = entry ;
else {
while ( pse - > next ! = NULL )
pse = pse - > next ;
pse - > next = entry ; // append msg to syslog queue
}
// DBG("%p %lu %d\n", entry, entry->msgid, system_get_free_heap_size());
// ensure we have sufficient heap for the rest of the system
if ( system_get_free_heap_size ( ) < syslogHost . min_heap_size ) {
if ( syslogState ! = SYSLOG_HALTED ) {
os_printf ( " syslog_add_entry: Warning: queue filled up, halted \n " ) ;
entry - > next = syslog_compose ( SYSLOG_FAC_USER , SYSLOG_PRIO_CRIT , " SYSLOG " , " queue filled up, halted " ) ;
if ( syslogState = = SYSLOG_READY )
syslog_send_udp ( ) ;
syslog_set_status ( SYSLOG_HALTED ) ;
}
}
}
/******************************************************************************
* FunctionName : syslog_compose
* Description : compose a syslog_entry_t from va_args
* Parameters : va_args
* Returns : the malloced syslog_entry_t
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
LOCAL syslog_entry_t ICACHE_FLASH_ATTR *
syslog_compose ( uint8_t facility , uint8_t severity , const char * tag , const char * fmt , . . . )
{
DBG ( " [%dµs] %s id=%lu \n " , WDEV_NOW ( ) , __FUNCTION__ , syslog_msgid ) ;
syslog_entry_t * se = os_zalloc ( sizeof ( syslog_entry_t ) + 1024 ) ; // allow up to 1k datagram
char * p = se - > datagram ;
se - > tick = WDEV_NOW ( ) ; // 0 ... 4294.967295s
se - > msgid = syslog_msgid ;
// The Priority value is calculated by first multiplying the Facility
// number by 8 and then adding the numerical value of the Severity.
p + = os_sprintf ( p , " <%d> " , facility * 8 + severity ) ;
// strftime doesn't work as expected - or adds 8k overhead.
// so let's do poor man conversion - format is fixed anyway
if ( flashConfig . syslog_showdate = = 0 )
p + = os_sprintf ( p , " - " ) ;
else {
time_t now = NULL ;
struct tm * tp = NULL ;
// create timestamp: FULL-DATE "T" PARTIAL-TIME "Z": 'YYYY-mm-ddTHH:MM:SSZ '
// as long as realtime_stamp is 0 we use tick div 10⁶ as date
now = ( realtime_stamp = = 0 ) ? ( se - > tick / 1000000 ) : realtime_stamp ;
tp = gmtime ( & now ) ;
p + = os_sprintf ( p , " %4d-%02d-%02dT%02d:%02d:%02d " ,
tp - > tm_year + 1900 , tp - > tm_mon + 1 , tp - > tm_mday ,
tp - > tm_hour , tp - > tm_min , tp - > tm_sec ) ;
if ( realtime_stamp = = 0 )
p + = os_sprintf ( p , " .%06luZ " , se - > tick % 1000000 ) ;
else
p + = os_sprintf ( p , " %+03d:00 " , flashConfig . timezone_offset ) ;
}
// add HOSTNAME APP-NAME PROCID MSGID
if ( flashConfig . syslog_showtick )
p + = os_sprintf ( p , " %s %s %lu.%06lu %lu " , flashConfig . hostname , tag , se - > tick / 1000000 , se - > tick % 1000000 , syslog_msgid + + ) ;
else
p + = os_sprintf ( p , " %s %s - %lu " , flashConfig . hostname , tag , syslog_msgid + + ) ;
// append syslog message
va_list arglist ;
va_start ( arglist , fmt ) ;
p + = ets_vsprintf ( p , fmt , arglist ) ;
va_end ( arglist ) ;
se - > datagram_len = p - se - > datagram ;
se = mem_trim ( se , sizeof ( syslog_entry_t ) + se - > datagram_len + 1 ) ;
return se ;
}
/*****************************************************************************
* FunctionName : syslog
* FunctionName : syslog
* Description : compose and queue a new syslog message
* Description : compose and queue a new syslog message
* Parameters : facility
* Parameters : facility
@ -361,11 +500,15 @@ void ICACHE_FLASH_ATTR syslog_init(char *syslog_host)
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void ICACHE_FLASH_ATTR syslog ( uint8_t facility , uint8_t severity , const char * tag , const char * fmt , . . . )
void ICACHE_FLASH_ATTR syslog ( uint8_t facility , uint8_t severity , const char * tag , const char * fmt , . . . )
{
{
DBG ( " syslog: state=%d " , syslogState ) ;
DBG ( " [%dµs] %s status: %s \n " , WDEV_NOW ( ) , __FUNCTION__ , syslog_get_status ( ) ) ;
if ( syslogState = = SYSLOG_ERROR | |
if ( syslogState = = SYSLOG_ERROR | |
syslogState = = SYSLOG_HALTED )
syslogState = = SYSLOG_HALTED )
return ;
return ;
if ( severity > flashConfig . syslog_filter )
return ;
// compose the syslog message
// compose the syslog message
void * arg = __builtin_apply_args ( ) ;
void * arg = __builtin_apply_args ( ) ;
void * res = __builtin_apply ( ( void * ) syslog_compose , arg , 128 ) ;
void * res = __builtin_apply ( ( void * ) syslog_compose , arg , 128 ) ;
@ -374,13 +517,9 @@ void ICACHE_FLASH_ATTR syslog(uint8_t facility, uint8_t severity, const char *ta
// and append it to the message queue
// and append it to the message queue
syslog_add_entry ( se ) ;
syslog_add_entry ( se ) ;
if ( syslogState = = SYSLOG_READY ) {
if ( syslogState = = SYSLOG_NONE )
syslogState = SYSLOG_SENDING ;
syslog_set_status ( SYSLOG_WAIT ) ;
syslog_send_udp ( ) ;
}
if ( syslogState = = SYSLOG_NONE ) {
if ( ! syslog_timer_armed )
syslogState = SYSLOG_WAIT ;
syslog_chk_status ( ) ;
syslog_chk_wifi_stat ( ) ; // fire the timer to check the Wifi connection status
}
}
}