Commit 35017641 authored by Jeroen Vreeken's avatar Jeroen Vreeken
Browse files

First modifications to trace server

Ported trace_list to new protocol and interface
Started port of trace_dump
parent 78bb85d7
......@@ -21,8 +21,10 @@
#include "trace.h"
#include "../utils/tcp_connect.h"
#include <trace_def.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <inttypes.h>
......@@ -116,45 +118,230 @@ int trace_init(char *host, int port, char *trace_name, struct traceval *trc)
return 0;
}
int trace_handle(struct traceval *trc)
int trace_handler_add(struct traceval *trc, void (*func)(struct traceval *trc))
{
int ret;
uint32_t nin;
float fin;
float32_t f;
int fd = trc->fd;
trc->handler_func = func;
ret = read(fd, &nin, sizeof(uint32_t));
if (ret != sizeof(uint32_t)) {
close(fd);
trc->fd = -1;
return -1;
return 0;
}
void trace_initialize(struct trace *trace, size_t buffer)
{
memset(trace, 0, sizeof(struct trace));
trace->rx_buffer = malloc(buffer);
trace->rx_buf_size = buffer;
trace->fd = -1;
}
void trace_packet_initialize(struct trace_pkt *pkt)
{
memset(pkt, 0, sizeof(struct trace_pkt));
}
void trace_packet_put(struct trace_pkt *pkt)
{
free(pkt->data);
free(pkt);
}
struct trace_pkt *trace_packet_new(void)
{
struct trace_pkt *pkt;
pkt = calloc(1, sizeof(struct trace_pkt));
return pkt;
}
int trace_packet_list_add(struct trace_pkt *pkt,
char *name, enum trace_value_type type, char *unit)
{
size_t entry_size = strlen(name)+1 + 1 + strlen(unit)+1;
char *entry;
if (!pkt->len) {
pkt->len = 1;
pkt->data = realloc(pkt->data, 1);
pkt->data[0] = TRACE_PTYPE_LIST;
}
nin = ntohl(nin);
f.u = nin;
fin = f.f;
if (trc->wasnan) {
trc->seconds = nin;
trc->sample = -1;
trc->wasnan = 0;
trc->new = 0;
} else if (isnan(fin)) {
trc->wasnan = 1;
trc->new = 0;
} else {
trc->value = fin;
trc->sample++;
trc->new = 1;
if (trc->handler_func)
trc->handler_func(trc);
pkt->data = realloc(pkt->data, pkt->len + entry_size);
entry = pkt->data + pkt->len;
strcpy(entry, name);
entry += strlen(name) + 1;
*entry = type;
entry++;
strcpy(entry, unit);
pkt->len += entry_size;
return 0;
}
int trace_packet_interval_set(struct trace_pkt *pkt,
struct timespec *interval, enum trace_interval_type type)
{
struct trace_ptype_interval *pinterval;
if (pkt->len < sizeof(struct trace_ptype_interval) + sizeof(struct trace_header)) {
pkt->len = sizeof(struct trace_ptype_interval) + sizeof(struct trace_header);
pkt->data = realloc(pkt->data, pkt->len);
pkt->data[0] = TRACE_PTYPE_INTERVAL;
}
pinterval = (struct trace_ptype_interval *)&pkt->data[1];
pinterval->sec = htobe64(interval->tv_sec);
pinterval->nsec = htobe32(interval->tv_nsec);
pinterval->type = type;
return 0;
}
int trace_handler_add(struct traceval *trc, void (*func)(struct traceval *trc))
int trace_packet_name_set(struct trace_pkt *pkt, char *name)
{
trc->handler_func = func;
if (pkt->len < sizeof(struct trace_header) + strlen(name) + 1) {
pkt->len = strlen(name) + 1 + sizeof(struct trace_header);
pkt->data = realloc(pkt->data, pkt->len);
pkt->data[0] = TRACE_PTYPE_NAME;
}
strcpy(pkt->data + 1, name);
return 0;
}
void trace_fd_set(struct trace *trace, fd_set *set, int *high)
{
FD_SET(trace->fd, set);
if (trace->fd > *high)
*high = trace->fd;
}
int trace_handle(struct trace *trace, fd_set *set)
{
if (FD_ISSET(trace->fd, set)) {
while (trace_fd_read(trace)) {
struct trace_pkt *pkt;
pkt = trace_packet_get(trace);
switch (pkt->data[0]) {
case TRACE_PTYPE_INTERVAL: {
struct timespec interval;
struct trace_ptype_interval *pinterval;
enum trace_interval_type type;
pinterval = (void*)pkt->data + 1;
interval.tv_sec = be64toh(pinterval->sec);
interval.tv_nsec = be32toh(pinterval->nsec);
type = pinterval->type;
if (trace->handler_interval) {
trace->handler_interval(trace, &interval, type);
}
break;
}
case TRACE_PTYPE_LIST: {
char *listentry;
size_t pos = 1;
while (pos < pkt->len) {
char *name;
enum trace_value_type type;
char *unit;
listentry = pkt->data + pos;
name = listentry;
type = listentry[strlen(name) + 1];
unit = listentry+strlen(name) + 2;
if (trace->handler_list_entry) {
trace->handler_list_entry(trace,
name, type, unit);
}
pos += strlen(name) + strlen(unit) + 3;
}
}
}
trace_packet_put(pkt);
}
}
return 0;
}
enum trace_state trace_state_get(struct trace *trace)
{
if (trace->fd < 0)
return TRACE_STATE_DISCONNECTED;
return TRACE_STATE_CONNECTED;
}
char *enum_trace_value_type2str(enum trace_value_type type)
{
switch(type) {
case TRACE_VALUE_TYPE_FLOAT:
return "FLOAT";
case TRACE_VALUE_TYPE_BOOL:
return "BOOL";
case TRACE_VALUE_TYPE_UINT8:
return "UINT8";
case TRACE_VALUE_TYPE_UINT16:
return "UINT16";
case TRACE_VALUE_TYPE_UINT32:
return "UINT32";
case TRACE_VALUE_TYPE_SINT8:
return "SINT8";
case TRACE_VALUE_TYPE_SINT16:
return "SINT16";
case TRACE_VALUE_TYPE_SINT32:
return "SINT32";
default:
return "unknown";
}
}
char *enum_trace_interval_type2str(enum trace_interval_type type)
{
switch(type) {
case TRACE_INTERVAL_TYPE_INTERVAL:
return "INTERVAL";
case TRACE_INTERVAL_TYPE_CHANGED:
return "CHANGED";
case TRACE_INTERVAL_TYPE_CHANGED_INTERVAL:
return "CHANGED_INTERVAL";
default:
return "unknown";
}
}
char *enum_trace_state2str(enum trace_state state)
{
switch(state) {
case TRACE_STATE_DISCONNECTED:
return "DISCONECTED";
case TRACE_STATE_CONNECTED:
return "CONNECTED";
case TRACE_STATE_READY:
return "READY";
case TRACE_STATE_RECEIVING:
return "RECEIVING";
default:
return "unknown";
}
}
......@@ -24,13 +24,13 @@
#include <time.h>
#include <stdbool.h>
#include <sys/select.h>
struct traceval;
struct traceval *trace_create(void);
int trace_init(char *host, int port, char *trace_name, struct traceval *trc);
int trace_handle(struct traceval *trc);
int trace_handler_add(struct traceval *trc, void (*func)(struct traceval *trc));
......@@ -62,6 +62,7 @@ enum trace_ptype {
TRACE_PTYPE_LIST = 1,
TRACE_PTYPE_NAME = 2,
TRACE_PTYPE_INTERVAL = 3,
TRACE_PTYPE_DATA = 4,
};
enum trace_value_type {
......@@ -75,19 +76,42 @@ enum trace_value_type {
TRACE_VALUE_TYPE_SINT32,
};
char *enum_trace_value_type2str(enum trace_value_type type);
enum trace_interval_type {
TRACE_INTERVAL_TYPE_INTERVAL,
TRACE_INTERVAL_TYPE_CHANGED,
TRACE_INTERVAL_TYPE_CHANGED_INTERVAL,
};
char *enum_trace_interval_type2str(enum trace_interval_type type);
enum trace_state {
TRACE_STATE_DISCONNECTED,
TRACE_STATE_CONNECTED,
TRACE_STATE_READY,
TRACE_STATE_RECEIVING,
};
char *enum_trace_state2str(enum trace_state state);
struct trace {
int fd;
char *host;
int port;
char *rx_buffer;
unsigned char *rx_buffer;
size_t rx_len;
size_t rx_buf_size;
size_t packet_size;
struct timespec timestamp;
void (*handler_interval)(struct trace *,
struct timespec *interval, enum trace_interval_type type);
void (*handler_list_entry)(struct trace *,
char *name, enum trace_value_type type, char *unit);
};
struct trace_pkt {
......@@ -98,14 +122,33 @@ struct trace_pkt {
struct trace *trace_open(char *host, int port);
void trace_initialize(struct trace *trace, int fd);
void trace_initialize(struct trace *trace, size_t buffer);
void trace_initialize_fd(struct trace *trace, int fd);
void trace_close(struct trace *trace);
void trace_free(struct trace *trace);
int trace_fd_get(struct trace *trace);
bool trace_fd_read(struct trace *trace);
struct trace_pkt *trace_packet_get(struct trace *trace);
void trace_packet_put(struct trace_pkt *pkt);
void trace_packet_initialize(struct trace_pkt *pkt);
int trace_packet_write(struct trace *trace, struct trace_pkt *pkt);
struct trace_pkt *trace_packet_new(void);
int trace_packet_list_add(struct trace_pkt *list_pkt,
char *name, enum trace_value_type type, char *unit);
int trace_packet_interval_set(struct trace_pkt *pkt,
struct timespec *interval, enum trace_interval_type type);
int trace_packet_name_set(struct trace_pkt *pkt, char *name);
void trace_fd_set(struct trace *trace, fd_set *set, int *high);
int trace_handle(struct trace *trace, fd_set *set);
enum trace_state trace_state_get(struct trace *trace);
#endif /* _INCLUDE_TRACE_H_ */
/*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2007, 2008, 2011
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2007, 2008, 2011, 2013
Copyright Stichting C.A. Muller Radioastronomiestation, 2007, 2008, 2011
This program is free software: you can redistribute it and/or modify
......@@ -26,51 +26,91 @@
#include <string.h>
#include <math.h>
#include "trace.h"
#include <trace/trace.h>
int interval = 1;
struct timespec t_int;
char *tracename;
enum trace_value_type tracetype;
void handle_val(struct traceval *trc)
static void handler_interval(struct trace *trace,
struct timespec *interval, enum trace_interval_type type)
{
int sample = trace_sample(trc);
if (sample % interval)
return;
printf("%f %e\n",
(double)trace_seconds(trc) + (double)sample * trace_period(trc),
trace_val(trc));
fflush(NULL);
memcpy(&t_int, interval, sizeof(struct timespec));
}
static void handler_list_entry(struct trace *trace,
char *name, enum trace_value_type type, char *unit)
{
if (!strcmp(name, tracename)) {
tracetype = type;
}
}
int main(int argc, char **argv)
{
struct traceval *trc;
trc = trace_create();
if (!trc)
return 1;
trace_handler_add(trc, handle_val);
struct trace *trace;
struct trace_pkt *pkt;
int interval = 1;
if (argc < 2) {
printf("Usage:\n\n");
printf("%s [trace] <interval>\n", argv[0]);
}
tracename = argv[1];
trace = trace_open("localhost", 10000);
if (argc >= 3) {
interval = atoi(argv[2]);
}
trace->handler_interval = handler_interval;
trace->handler_list_entry = handler_list_entry;
if (trace_init("localhost", 10000, argv[1], trc)) {
return 1;
while (trace_state_get(trace) == TRACE_STATE_CONNECTED) {
fd_set fdrx;
int high = 0;
trace_fd_set(trace, &fdrx, &high);
select(high + 1, &fdrx, NULL, NULL, NULL);
trace_handle(trace, &fdrx);
}
if (interval != 1) {
t_int.tv_sec *= interval;
t_int.tv_nsec *= interval;
if (t_int.tv_nsec > 1000000000) {
t_int.tv_sec++;
t_int.tv_nsec -= 1000000000;
}
while (1) {
if (trace_handle(trc))
return 1;
pkt = trace_packet_new();
trace_packet_interval_set(pkt,
&t_int, TRACE_INTERVAL_TYPE_INTERVAL);
trace_packet_write(trace, pkt);
trace_packet_put(pkt);
}
pkt = trace_packet_new();
trace_packet_name_set(pkt, tracename);
trace_packet_write(trace, pkt);
trace_packet_put(pkt);
while (trace_state_get(trace) == TRACE_STATE_RECEIVING ||
trace_state_get(trace) == TRACE_STATE_READY) {
fd_set fdrx;
int high = 0;
trace_fd_set(trace, &fdrx, &high);
select(high + 1, &fdrx, NULL, NULL, NULL);
trace_handle(trace, &fdrx);
}
return 0;
}
/*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2007
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2007, 2013
Copyright Stichting C.A. Muller Radioastronomiestation, 2007
This program is free software: you can redistribute it and/or modify
......@@ -24,63 +24,52 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include "tcp_connect.h"
#include <trace/trace.h>
typedef union {
float f;
uint32_t u;
} f32_t;
static char *host = "localhost";
static int port = 10000;
static void handler_interval(struct trace *trace,
struct timespec *interval, enum trace_interval_type type)
{
printf("Server interval: %ld.%09ld, type: %s\n",
interval->tv_sec, interval->tv_nsec,
enum_trace_interval_type2str(type));
}
static void handler_list_entry(struct trace *trace,
char *name, enum trace_value_type type, char *unit)
{
printf("Trace name='%s', type=%s, unit='%s'\n",
name, enum_trace_value_type2str(type), unit);
}
int main(int argc, char **argv)
{
union {
char name[100];
uint32_t val32[25];
} buffer;
int len = 0;
int unit = 0;
int ret;
int fd;
float period;
f32_t f;
fd = tcp_connect("localhost", 10000);
if (fd < 0)
return -1;
struct trace *trace;
do {
ret = read(fd, buffer.name + len, 1);
if (ret == 1) {
if ((buffer.name[len] == 0 && unit != 2) ||
(len == 4 && unit == 2)) {
if (len == 0)
break;
switch (unit) {
case 0:
printf("%s", buffer.name);
unit++;
break;
case 1:
printf("\t%s", buffer.name);
unit++;
break;
case 2:
f.u = ntohl(*buffer.val32);
period = f.f;
printf("\t%esec\t%eHz\n",
period, 1/period);
unit = 0;
break;
}
len = -1;
}
len++;
if (len >= 100) {
len = 0;
}
}
} while (ret == 1);
if (argc > 1) {
host = argv[1];
}
if (argc > 2) {
port = atoi(argv[2]);
}
printf("Trace list from %s:%d\n", host, port);
trace = trace_open(host, port);
trace->handler_interval = handler_interval;
trace->handler_list_entry = handler_list_entry;
while (trace_state_get(trace) == TRACE_STATE_CONNECTED) {
fd_set fdrx;
int high = 0;
trace_fd_set(trace, &fdrx, &high);
select(high + 1, &fdrx, NULL, NULL, NULL);
trace_handle(trace, &fdrx);
}
return 0;
}
......@@ -28,6 +28,7 @@
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <stdio.h>
#define TRACE_BUF_BLOCK 4096
......@@ -50,10 +51,16 @@ struct trace *trace_open(char *host, int port)
return trace;
}
void trace_initialize(struct trace *trace, int fd)
void trace_initialize_fd(struct trace *trace, int fd)
{
unsigned char *buffer = trace->rx_buffer;
size_t buflen = trace->rx_buf_size;