Files
small_tel/Daemons/weatherdaemon_multimeteo/weathlib.c

120 lines
3.8 KiB
C

/*
* This file is part of the weatherdaemon project.
* Copyright 2026 Edward V. Emelianov <edward.emelianoff@gmail.com>.
*
* 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 3 of the License, or
* (at your option) 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, see <http://www.gnu.org/licenses/>.
*/
// Some common functions and handlers for sensors
#include <pthread.h>
#include "weathlib.h"
// private functions (for plugins usage only)
//static int common_onrefresh(sensordata_t*, void (*handler)(sensordata_t*));
//static void common_kill(sensordata_t *);
//static int common_getval(sensordata_t*, val_t*, int);
//static int common_init(sensordata_t*, int, time_t, int);
/**
* @brief sensor_new - call this function before calling `sensor_init`
* @param N - plugin number in array
* @return pointer to allocated sensor's structure
*/
sensordata_t *sensor_new(int N, const char *descr){
sensordata_t *s = MALLOC(sensordata_t, 1);
s->fdes = -1; // not inited
s->onrefresh = common_onrefresh; // `init` function can redefine basic stubs
s->get_value = common_getval;
s->kill = common_kill;
s->PluginNo = N; // `init` shouldn't change this value
snprintf(s->path, PATH_MAX, "%s", descr); // `init` shouldn't change this value
pthread_mutex_init(&s->valmutex, NULL);
return s;
}
/**
* @brief sensor_alive - test if sensor's thread isn't dead
* @param s - sensor
* @return FALSE if thread is dead
*/
int sensor_alive(sensordata_t *s){
if(!s || s->fdes < 0) return FALSE;
if(pthread_kill(s->thread, 0)) return FALSE;
return TRUE;
}
/**
* @brief common_onrefresh - common `change onrefresh handler`
* @param s - sensor
* @return FALSE if failed
*/
int common_onrefresh(sensordata_t *s, void (*handler)(sensordata_t *)){
FNAME();
if(!s || !handler) return FALSE;
s->freshdatahandler = handler;
return TRUE;
}
/**
* @brief common_kill - common `die` function (close, but don't destroy sensor)
* @param s - sensor
*/
void common_kill(sensordata_t *s){
FNAME();
if(!s) return;
if(s->fdes > -1){ // inited and maybe have opened file/socket
close(s->fdes);
s->fdes = -1;
DBG("FD closed");
usleep(5000);
if(pthread_equal(pthread_self(), s->thread)){
DBG("Don't cancel myself");
}else{
DBG("Cancel sensor's thread");
if(0 == pthread_cancel(s->thread)){
DBG("%s main thread canceled, join", s->name);
pthread_join(s->thread, NULL);
DBG("Done");
}
}
}
DBG("Delete RB");
if(s->ringbuffer) sl_RB_delete(&s->ringbuffer);
FREE(s->values);
if(s->privdatafree) s->privdatafree(s->privdata);
else FREE(s->privdata);
DBG("Sensor '%s' killed", s->name);
if(s->path[0]) LOGERR("Sensor '%s' @ '%s' killed", s->name, s->path);
else LOGERR("Sensor '%s' killed", s->name);
}
/**
* @brief common_getval - common value getter
* @param s (i) - station
* @param o (o) - value or NULL (if you just wants test N)
* @param N - number of sensor
* @return FALSE if failed
*/
int common_getval(struct sensordata_t *s, val_t *o, int N){
if(!s || N < 0 || N >= s->Nvalues) return FALSE;
if(o){
pthread_mutex_lock(&s->valmutex);
*o = s->values[N];
pthread_mutex_unlock(&s->valmutex);
}
return TRUE;
}