ported header files to c++ classes

This commit is contained in:
Steffen Vogel 2012-02-05 18:14:01 +01:00
parent f7651ca9dd
commit 8ff2e43d53
14 changed files with 221 additions and 350 deletions

View file

@ -28,12 +28,18 @@
#include <pthread.h>
#include "meter.h"
#include "vzlogger.h"
#include "reading.h"
#include "buffer.h"
typedef struct channel {
char id[5]; /* only for internal usage & debugging */
class Channel {
public:
Channel(const char *pUuid, const char *pMiddleware, reading_id_t pIdentifier);
virtual ~Channel();
protected:
static int instances;
int id; /* only for internal usage & debugging */
reading_id_t identifier; /* channel identifier (OBIS, string) */
reading_t last; /* most recent reading */
@ -44,10 +50,6 @@ typedef struct channel {
char *middleware; /* url to middleware */
char *uuid; /* unique identifier for middleware */
} channel_t;
/* prototypes */
void channel_init(channel_t *ch, const char *uuid, const char *middleware, reading_id_t identifier);
void channel_free(channel_t *ch);
};
#endif /* _CHANNEL_H_ */

View file

@ -3,6 +3,8 @@
#include <stdarg.h>
#include "../config.h" /* GNU buildsystem config */
/* enumerations */
typedef enum {
log_error = -1,
@ -16,14 +18,6 @@ typedef enum {
typedef unsigned char bool;
/* constants */
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif
#define SUCCESS 0
#define ERR -1
#define ERR_NOT_FOUND -2

View file

@ -26,61 +26,30 @@
#ifndef _METER_H_
#define _METER_H_
/**
* We have 2 diffrent protocol types:
* - sensors: a readout is triggered in equidistant intervals by calling
* the read function with an POSIX timer.
* The interval is set in the configuration.
* - meters: the meter itselfs triggers a readout.
* The pointer to the read function shoul be NULL.
* The 'interval' column in the configuration as no meaning.
*/
#include <map>
#include "../config.h" /* GNU buildsystem config */
#include "common.h"
#include "list.h"
#include "reading.h"
/* meter protocols */
#include "protocols/file.h"
#include "protocols/exec.h"
#include "protocols/random.h"
#include "protocols/s0.h"
#include "protocols/d0.h"
#include "protocols/fluksov2.h"
#ifdef SML_SUPPORT
#include "protocols/sml.h"
#endif /* SML_SUPPORT */
using namespace std;
typedef enum meter_procotol {
meter_protocol_file = 1,
meter_protocol_exec,
meter_protocol_random,
meter_protocol_s0,
meter_protocol_d0,
meter_protocol_sml,
meter_protocol_fluksov2
} meter_protocol_t;
class Meter {
public:
virtual ~Meter();
virtual int open() = 0;
virtual int close() = 0;
virtual size_t read(reading_t *rds, size_t n);
protected:
Meter(map<string, Option> options);
static int instances
int id;
typedef struct meter {
char id[5];
int interval;
meter_protocol_t protocol;
union {
meter_handle_file_t file;
meter_handle_exec_t exec;
meter_handle_random_t random;
meter_handle_s0_t s0;
meter_handle_d0_t d0;
meter_handle_fluksov2_t fluksov2;
#ifdef SML_SUPPORT
meter_handle_sml_t sml;
#endif /* SML_SUPPORT */
} handle;
} meter_t;
};
typedef struct {
meter_protocol_t id;
@ -88,13 +57,6 @@ typedef struct {
char *desc; /* more detailed description */
size_t max_readings; /* how many readings can be read with 1 call */
int periodic:1; /* does this meter has be triggered periodically? */
/* function pointers */
int (*init_func)(meter_t *mtr, list_t options);
void (*free_func)(meter_t *mtr);
int (*open_func)(meter_t *mtr);
int (*close_func)(meter_t *mtr);
size_t (*read_func)(meter_t *mtr, reading_t *rds, size_t n);
} meter_details_t;
/* prototypes */
@ -105,52 +67,4 @@ typedef struct {
const meter_details_t * meter_get_protocols();
const meter_details_t * meter_get_details(meter_protocol_t protocol);
/**
* Initialize meter
*
* @param mtr the meter structure to initialze
* @param list of key, value pairs of options
* @return 0 on success, -1 on error
*/
int meter_init(meter_t *mtr, list_t options);
/**
* Freeing all memory which has been allocated during the initialization
*
* @param mtr the meter structure
*/
void meter_free(meter_t *mtr);
/**
* Dispatcher for blocking read from meters of diffrent types
*
* rds has to point to an array with space for at least n readings!
*
* @param mtr the meter structure
* @param rds the array to store the readings to
* @param n the size of the array
* @return number of readings
*/
size_t meter_read(meter_t *mtr, reading_t rds[], size_t n);
/**
* Dispatcher for opening meters of diffrent types,
*
* Establish connection, initialize meter etc.
*
* @param mtr the meter structure
* @return 0 on success, -1 on error
*/
int meter_open(meter_t *mtr);
/**
* Dispatcher for closing meters of diffrent types
*
* Reset ports, shutdown meter etc.
*
* @param mtr the meter structure
* @return 0 on success, -1 on error
*/
int meter_close(meter_t *mtr);
#endif /* _METER_H_ */

View file

@ -33,32 +33,36 @@
#include <termios.h>
typedef struct {
#include "meter.h"
using namespace std;
class MeterD0 : public Meter {
public:
MeterD0(map<string, Option> options);
virtual ~MeterD0();
int open();
int close();
int read(reading_t *rds, size_t n);
protected:
char *host;
char *device;
int baudrate;
int fd; /* file descriptor of port */
struct termios oldtio; /* required to reset port */
} meter_handle_d0_t;
/* forward declarations */
struct meter;
struct reading;
int meter_init_d0(struct meter *mtr, list_t options);
void meter_free_d0(struct meter *mtr);
int meter_open_d0(struct meter *mtr);
int meter_close_d0(struct meter *mtr);
size_t meter_read_d0(struct meter *mtr, struct reading *rds, size_t n);
/**
* Open socket
*
* @param node the hostname or ASCII encoded IP address
* @param the ASCII encoded portnum or service as in /etc/services
* @return file descriptor, <0 on error
*/
int meter_d0_open_socket(const char *node, const char *service);
/**
* Open socket
*
* @param node the hostname or ASCII encoded IP address
* @param the ASCII encoded portnum or service as in /etc/services
* @return file descriptor, <0 on error
*/
int openSocket(const char *node, const char *service)
};
#endif /* _D0_H_ */

View file

@ -26,21 +26,23 @@
#ifndef _EXEC_H_
#define _EXEC_H_
#include <stdio.h>
#include "meter.h"
typedef struct {
using namespace std;
class MeterExec : public Meter {
public:
MeterExec(map<string, Option> options);
virtual MeterExec();
int open();
int close();
int read(reading_t *rds, size_t n);
protected:
char *command;
char *format;
} meter_handle_exec_t;
/* forward declarations */
struct meter;
struct reading;
int meter_init_exec(struct meter *mtr, list_t options);
void meter_free_exec(struct meter *mtr);
int meter_open_exec(struct meter *mtr);
int meter_close_exec(struct meter *mtr);
size_t meter_read_exec(struct meter *mtr, struct reading *rds, size_t n);
};
#endif /* _EXEC_H_ */

View file

@ -26,24 +26,26 @@
#ifndef _FILE_H_
#define _FILE_H_
#include <stdio.h>
#include "meter.h"
typedef struct {
using namespace std;
class MeterFile : public Meter {
public:
MeterFile(map<string, Option> options);
virtual ~MeterFile();
int open();
int close();
int read(reading_t *rds, size_t n);
protected:
char *path;
char *format;
int rewind;
FILE *fd;
} meter_handle_file_t;
/* forward declarations */
struct meter;
struct reading;
int meter_init_file(struct meter *mtr, list_t options);
void meter_free_file(struct meter *mtr);
int meter_open_file(struct meter *mtr);
int meter_close_file(struct meter *mtr);
size_t meter_read_file(struct meter *mtr, struct reading *rds, size_t n);
};
#endif /* _FILE_H_ */

View file

@ -22,26 +22,29 @@
* You should have received a copy of the GNU General Public License
* along with volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _FLUKSOV2_H_
#define _FLUKSOV2_H_
#define FLUKSOV2_DEFAULT_FIFO "/var/run/spid/delta/out"
#include "meter.h"
typedef struct {
using namespace std;
class MeterFluksoV2 : public Meter {
public:
MeterFluksoV2(map<string, Option> options);
virtual ~MeterFluksoV2();
int open();
int close();
int read(reading_t *rds, size_t n);
protected:
char *fifo;
int fd; /* file descriptor of fifo */
} meter_handle_fluksov2_t;
/* forward declarations */
struct meter;
struct reading;
int meter_init_fluksov2(struct meter *mtr, list_t options);
void meter_free_fluksov2(struct meter *mtr);
int meter_open_fluksov2(struct meter *mtr);
int meter_close_fluksov2(struct meter *mtr);
size_t meter_read_fluksov2(struct meter *mtr, struct reading *rds, size_t n);
const char *DEFAULT_FIFO = "/var/run/spid/delta/out";
};
#endif /* _FLUKSOV2_H_ */

View file

@ -26,21 +26,25 @@
#ifndef _RANDOM_H_
#define _RANDOM_H_
typedef struct {
#include "meter.h"
using namespace std;
double ltqnorm(double p); /* forward declaration */
class MeterRandom : public Meter {
public:
Random(map<string, Option> options);
virtual ~Random();
int open();
int close();
int read(reading_t *rds, size_t n);
protected:
double min, max;
double last;
} meter_handle_random_t;
/* forward declarations */
struct meter;
struct reading;
double ltqnorm(double p);
int meter_init_random(struct meter *mtr, list_t options);
void meter_free_random(struct meter *mtr);
int meter_open_random(struct meter *mtr);
int meter_close_random(struct meter *mtr);
size_t meter_read_random(struct meter *mtr, struct reading *rds, size_t n);
};
#endif /* _RANDOM_H_ */

View file

@ -28,22 +28,26 @@
#include <termios.h>
typedef struct {
#include "meter.h"
using namespace std;
class MeterS0 : public Meter {
public:
MeterS0(map<string, Option> options);
virtual ~MeterS0();
int open();
int close();
int read(reading_t *rds, size_t n);
protected:
char *device;
int resolution;
int fd; /* file descriptor of port */
struct termios old_tio; /* required to reset port */
} meter_handle_s0_t;
/* forward declarations */
struct meter;
struct reading;
int meter_init_s0(struct meter *mtr, list_t options);
void meter_free_s0(struct meter *mtr);
int meter_open_s0(struct meter *mtr);
int meter_close_s0(struct meter *mtr);
size_t meter_read_s0(struct meter *mtr, struct reading *rds, size_t n);
};
#endif /* _S0_H_ */

View file

@ -30,97 +30,63 @@
#ifndef _SML_H_
#define _SML_H_
#define SML_BUFFER_LEN 8096
#include <sml/sml_file.h>
#include <sml/sml_value.h>
#include <termios.h>
#include "meter.h"
#include "obis.h"
typedef struct {
using namespace std;
class MeterSML : public Meter {
public:
MeterSML(map<string, Option> options);
virtual ~MeterSML();
int open();
int close();
int read(reading_t *rds, size_t n);
protected:
char *host;
char *device;
speed_t baudrate;
int fd; /* file descriptor of port */
struct termios old_tio; /* required to reset port */
} meter_handle_sml_t;
/* forward declarations */
struct meter;
struct reading;
const int BUFFER_LEN = 8192;
/**
* Initialize meter structure with a list of options
*
* @param mtr the meter structure
* @param options a list of options
* @return 0 on success, <0 on error
*/
int meter_init_sml(struct meter *mtr, list_t options);
/**
* Parses SML list entry and stores it in reading pointed by rd
*
* @param list the list entry
* @param rd the reading to store to
*/
void parse(sml_list *list, struct reading *rd);
/**
* Freeing allocated resources during initialization
*
* @param mtr the meter structure
*/
void meter_free_sml(struct meter *mtr);
/**
* Open serial port by device
*
* @param device the device path, usually /dev/ttyS*
* @param old_config pointer to termios structure, will be filled with old port configuration
* @param baudrate the baudrate
* @return file descriptor, <0 on error
*/
int openDevice(const char *device, struct termios *old_config, speed_t baudrate);
/**
* Open connection via serial port or socket to meter
*
* @param mtr the meter structure
* @return 0 on success, <0 on error
*/
int meter_open_sml(struct meter *mtr);
/**
* Open socket
*
* @param node the hostname or ASCII encoded IP address
* @param the ASCII encoded portnum or service as in /etc/services
* @return file descriptor, <0 on error
*/
int openSocket(const char *node, const char *service);
};
/**
* Reset port/socket and freeing handle
*
* @param mtr the meter structure
*/
int meter_close_sml(struct meter *mtr);
/**
* Blocking read on meter
*
* Most EDL conform meters periodically send data every
* 3-4 seconds.
*
* @param mtr the meter structure
* @param rds pointer to array of readings with size n
* @param n size of the rds array
* @return number of readings stored to rds
*/
size_t meter_read_sml(struct meter *mtr, struct reading *rds, size_t n);
/**
* Parses SML list entry and stores it in reading pointed by rd
*
* @param list the list entry
* @param rd the reading to store to
*/
void meter_sml_parse(sml_list *list, struct reading *rd);
/**
* Open serial port by device
*
* @param device the device path, usually /dev/ttyS*
* @param old_config pointer to termios structure, will be filled with old port configuration
* @param baudrate the baudrate
* @return file descriptor, <0 on error
*/
int meter_sml_open_device(const char *device, struct termios *old_config, speed_t baudrate);
/**
* Open socket
*
* @param node the hostname or ASCII encoded IP address
* @param the ASCII encoded portnum or service as in /etc/services
* @return file descriptor, <0 on error
*/
int meter_sml_open_socket(const char *node, const char *service);
#endif /* _SML_H_ */

View file

@ -27,23 +27,27 @@
#define _VZLOGGER_H_
#include <pthread.h>
#include "../config.h" /* GNU buildsystem config */
#include <vector>
#include "config.h"
#include "meter.h"
#include "common.h"
#include "list.h"
#include "channel.h"
using namespace std;
/**
* Type for mapping channels to meters
* Class for mapping channels to meters
*/
typedef struct map {
meter_t meter;
list_t channels;
class Mapping {
public:
protected:
Meter meter;
vector<Channel> channels;
pthread_t thread;
} map_t;
};
/* prototypes */
void quit(int sig);

View file

@ -30,27 +30,28 @@
#include "channel.h"
void channel_init(channel_t *ch, const char *uuid, const char *middleware, reading_id_t identifier) {
static int instances; /* static to generate channel ids */
snprintf(ch->id, 5, "ch%i", instances++);
Channel::instances = 0;
ch->identifier = identifier;
Channel::Channel(const char *pUuid, const char *pMiddleware, reading_id_t pIdentifier) {
id = instances++;
ch->uuid = strdup(uuid);
ch->middleware = strdup(middleware);
identifier = pIdentifier;
buffer_init(&ch->buffer); /* initialize buffer */
pthread_cond_init(&ch->condition, NULL); /* initialize thread syncronization helpers */
uuid = strdup(pUuid);
middleware = strdup(pMiddleware);
buffer_init(&buffer); /* initialize buffer */
pthread_cond_init(&condition, NULL); /* initialize thread syncronization helpers */
}
/**
* Free all allocated memory recursivly
*/
void channel_free(channel_t *ch) {
buffer_free(&ch->buffer);
pthread_cond_destroy(&ch->condition);
Channel::~Channel() {
buffer_free(&buffer);
pthread_cond_destroy(&condition);
free(ch->uuid);
free(ch->middleware);
free(uuid);
free(middleware);
}

View file

@ -29,12 +29,12 @@
#include "meter.h"
#include "options.h"
#define METER_DETAIL(NAME, DESC, MAX_RDS, PERIODIC) { meter_protocol_##NAME, #NAME, DESC, MAX_RDS, PERIODIC, meter_init_##NAME, meter_free_##NAME, meter_open_##NAME, meter_close_##NAME, meter_read_##NAME }
#define METER_DETAIL(NAME, DESC, MAX_RDS, PERIODIC) { meter_protocol_##NAME, #NAME, DESC, MAX_RDS, PERIODIC, meter_init_##NAME }
static const meter_details_t protocols[] = {
/* alias description max_rds periodic
===============================================================================================*/
METER_DETAIL(file, "Read from file or fifo", 32, TRUE),
METER_DETAIL( file, "Read from file or fifo", 32, TRUE),
//METER_DETAIL(exec, "Parse program output", 32, TRUE),
METER_DETAIL(random, "Generate random values with a random walk", 1, TRUE),
METER_DETAIL(fluksov2, "Read from Flukso's onboard SPI fifo", 16, FALSE),
@ -46,9 +46,8 @@ METER_DETAIL(sml, "Smart Message Language as used by EDL-21, eHz and SyM²", 32,
{} /* stop condition for iterator */
};
int meter_init(meter_t *mtr, list_t options) {
static int instances; /* static to generate unique channel ids */
snprintf(mtr->id, 5, "mtr%i", instances++); /* set/increment id */
Meter::Meter(list_t pOptions) {
id = instances++;
/* protocol */
char *protocol_str;
@ -57,44 +56,26 @@ int meter_init(meter_t *mtr, list_t options) {
return ERR;
}
if (meter_lookup_protocol(protocol_str, &mtr->protocol) != SUCCESS) {
if (meter_lookup_protocol(protocol_str, &protocol) != SUCCESS) {
print(log_error, "Invalid protocol: %s", mtr, protocol_str);
return ERR; /* skipping this meter */
}
/* interval */
mtr->interval = -1; /* indicates unknown interval */
if (options_lookup_int(options, "interval", &mtr->interval) == ERR_INVALID_TYPE) {
if (options_lookup_int(options, "interval", &interval) == ERR_INVALID_TYPE) {
print(log_error, "Invalid type for interval", mtr);
return ERR;
}
const meter_details_t *details = meter_get_details(mtr->protocol);
const meter_details_t *details = meter_get_details(protocol);
if (details->periodic == TRUE && mtr->interval < 0) {
print(log_error, "Interval has to be positive!", mtr);
}
return details->init_func(mtr, options);
}
void meter_free(meter_t *mtr) {
const meter_details_t *details = meter_get_details(mtr->protocol);
return details->free_func(mtr);
}
Meter::~Meter() {
int meter_open(meter_t *mtr) {
const meter_details_t *details = meter_get_details(mtr->protocol);
return details->open_func(mtr);
}
int meter_close(meter_t *mtr) {
const meter_details_t *details = meter_get_details(mtr->protocol);
return details->close_func(mtr);
}
size_t meter_read(meter_t *mtr, reading_t rds[], size_t n) {
const meter_details_t *details = meter_get_details(mtr->protocol);
return details->read_func(mtr, rds, n);
}
int meter_lookup_protocol(const char* name, meter_protocol_t *protocol) {

View file

@ -41,14 +41,12 @@
#include <netdb.h>
#include <sys/socket.h>
#include "meter.h"
#include "protocols/d0.h"
#include "obis.h"
#include "options.h"
int meter_init_d0(meter_t *mtr, list_t options) {
meter_handle_d0_t *handle = &mtr->handle.d0;
int MeterD0::MeterD0(map<string, Option> options) {
/* connection */
char *host, *device;
if (options_lookup_string(options, "host", &host) == SUCCESS) {
@ -94,25 +92,19 @@ int meter_init_d0(meter_t *mtr, list_t options) {
print(log_error, "Failed to parse the baudrate", mtr);
return ERR;
}
return SUCCESS;
}
void meter_free_d0(meter_t *mtr) {
meter_handle_d0_t *handle = &mtr->handle.d0;
if (handle->device != NULL) {
free(handle->device);
MeterD0::~MeterD0() {
if (device != NULL) {
free(device);
}
if (handle->host != NULL) {
free(handle->host);
if (host != NULL) {
free(host);
}
}
int meter_open_d0(meter_t *mtr) {
meter_handle_d0_t *handle = &mtr->handle.d0;
int MeterD0::open() {
if (handle->device != NULL) {
print(log_error, "TODO: implement serial interface", mtr);
return ERR;
@ -128,13 +120,11 @@ int meter_open_d0(meter_t *mtr) {
return (handle->fd < 0) ? ERR : SUCCESS;
}
int meter_close_d0(meter_t *mtr) {
meter_handle_d0_t *handle = &mtr->handle.d0;
int MeterD0::close() {
return close(handle->fd);
}
size_t meter_read_d0(meter_t *mtr, reading_t rds[], size_t max_readings) {
size_t MeterD0::read(reading_t rds[], size_t max_readings) {
meter_handle_d0_t *handle = &mtr->handle.d0;
enum { START, VENDOR, BAUDRATE, IDENTIFICATION, START_LINE, OBIS_CODE, VALUE, UNIT, END_LINE, END } context;
@ -280,7 +270,7 @@ error:
return 0;
}
int meter_d0_open_socket(const char *node, const char *service) {
int MeterD0::openSocket(const char *node, const char *service) {
struct sockaddr_in sin;
struct addrinfo *ais;
int fd; /* file descriptor */