Commit 78bb85d7 authored by Jeroen Vreeken's avatar Jeroen Vreeken
Browse files

New trace definitions and first stream handling code

parent e6ab4541
CFLAGS+= -Wall -O3 -I../utils/
CFLAGS+= -Wall -O3 -I../utils/ -I.. -I../include
LDFLAGS+= -L../lib
LOBJS= trace.lo
SRCS= trace_dump.c trace_dumpdiff.c trace_fft.c
SRCS= trace_dump.c trace_dumpdiff.c trace_fft.c trace_tcp.c
all: libs bins
......@@ -16,8 +16,8 @@ bins: trace_dump trace_dumpdiff trace_fft trace_view trace_list
${CURDIR}/../lib:
@mkdir ${CURDIR}/../lib
libtrace.la_LDFLAGS= -lutils -lm -rpath ${CURDIR}/../lib
libtrace.la: trace.lo
libtrace.la_LDFLAGS= -lutils -llog -lm -rpath ${CURDIR}/../lib
libtrace.la: trace.lo trace_tcp.lo
libtrace.la_install: libtrace.la ${CURDIR}/../lib
@echo "CP $^ to libdir"
......
......@@ -158,10 +158,3 @@ int trace_handler_add(struct traceval *trc, void (*func)(struct traceval *trc))
return 0;
}
int trace_close(struct traceval *trc)
{
close(trc->fd);
trc->fd = -1;
return 0;
}
......@@ -23,6 +23,8 @@
#define _INCLUDE_TRACE_H_
#include <time.h>
#include <stdbool.h>
struct traceval;
......@@ -48,12 +50,62 @@ struct traceval {
};
int trace_close(struct traceval *trc);
#define trace_val(trace) ((trace)->value)
#define trace_fd(trace) ((trace)->fd)
#define trace_seconds(trace) ((trace)->seconds)
#define trace_sample(trace) ((trace)->sample)
#define trace_period(trace) ((trace)->period)
enum trace_ptype {
TRACE_PTYPE_TIMESTAMP = 0,
TRACE_PTYPE_LIST = 1,
TRACE_PTYPE_NAME = 2,
TRACE_PTYPE_INTERVAL = 3,
};
enum trace_value_type {
TRACE_VALUE_TYPE_FLOAT, /* 4 bytes */
TRACE_VALUE_TYPE_BOOL, /* 1 byte */
TRACE_VALUE_TYPE_UINT8,
TRACE_VALUE_TYPE_UINT16,
TRACE_VALUE_TYPE_UINT32,
TRACE_VALUE_TYPE_SINT8,
TRACE_VALUE_TYPE_SINT16,
TRACE_VALUE_TYPE_SINT32,
};
struct trace {
int fd;
char *host;
int port;
char *rx_buffer;
size_t rx_len;
size_t rx_buf_size;
size_t packet_size;
struct timespec timestamp;
};
struct trace_pkt {
enum trace_ptype type;
char *data;
size_t len;
};
struct trace *trace_open(char *host, int port);
void trace_initialize(struct trace *trace, int fd);
void trace_close(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);
int trace_packet_write(struct trace *trace, struct trace_pkt *pkt);
#endif /* _INCLUDE_TRACE_H_ */
/*
trace tcp connection handling
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2013
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/>.
*/
#include <trace_def.h>
#include <trace/trace.h>
#include <log/log.h>
#include <tcp_connect.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#define TRACE_BUF_BLOCK 4096
struct trace *trace_open(char *host, int port)
{
struct trace *trace;
trace = calloc(sizeof(struct trace), 1);
if (!trace)
return NULL;
trace->host = strdup(host);
trace->port = port;
trace->fd = tcp_connect(host, port);
if (trace->fd >= 0) {
ioctl(trace->fd, FIONBIO, &(int){1});
}
return trace;
}
void trace_initialize(struct trace *trace, int fd)
{
memset(trace, 0, sizeof(struct trace));
trace->fd = fd;
if (trace->fd >= 0) {
ioctl(trace->fd, FIONBIO, &(int){1});
}
}
void trace_close(struct trace *trace)
{
if (trace->fd >= 0)
close(trace->fd);
free(trace->rx_buffer);
free(trace->host);
free(trace);
}
int trace_fd_get(struct trace *trace)
{
return trace->fd;
}
bool trace_fd_read(struct trace *trace)
{
ssize_t ret;
int i;
bool rx_ready = false;
if (trace->rx_buf_size - trace->rx_buf_size < TRACE_BUF_BLOCK) {
char *newbuf;
newbuf = realloc(trace->rx_buffer, trace->rx_buf_size + TRACE_BUF_BLOCK);
if (newbuf) {
trace->rx_buffer = newbuf;
} else {
log_send(LOG_T_WARNING,
"Could not enlarge buffer for receiving traces");
return false;
}
}
ret = read(trace->fd, trace->rx_buffer + trace->rx_len, TRACE_BUF_BLOCK);
if (ret > 0) {
trace->rx_len += ret;
} else {
if (ret <= 0 && errno != EAGAIN) {
log_send(LOG_T_ERROR, "Trace connection lost");
close(trace->fd);
trace->fd = -1;
}
}
for (i = 0; i < trace->rx_len; i++) {
if (trace->rx_buffer[i] == TRACE_END)
rx_ready = true;
}
return rx_ready;
}
struct trace_pkt *trace_packet_get(struct trace *trace)
{
int i;
size_t len = 0;
struct trace_pkt *pkt;
while(trace->rx_len && trace->rx_buffer[0] == TRACE_END) {
memmove(trace->rx_buffer, trace->rx_buffer+1, trace->rx_len-1);
trace->rx_len--;
}
for (i = 0; i < trace->rx_len; i++) {
if (trace->rx_buffer[i] == TRACE_END) {
len = i;
break;
}
}
if (!len) {
return NULL;
}
pkt = malloc(sizeof(struct trace_pkt));
if (!pkt)
goto err_pkt;
pkt->data = malloc(len);
if (!pkt->data)
goto err_pkt_data;
memcpy(pkt->data, trace->rx_buffer, len);
pkt->type = pkt->data[0];
for (i = 0; i < len - 1; i++) {
if (pkt->data[i] == TRACE_ESC) {
if (pkt->data[i+1] == TRACE_ESC_END)
pkt->data[i] = TRACE_END;
memmove(pkt->data + 1, pkt->data + 2, len - i - 2);
len--;
}
}
pkt->len = len;
trace->rx_len -= len + 1;
memmove(trace->rx_buffer, trace->rx_buffer + len + 1, trace->rx_len);
return pkt;
err_pkt_data:
free(pkt);
err_pkt:
return NULL;
}
void trace_packet_put(struct trace_pkt *pkt)
{
free(pkt->data);
free(pkt);
}
static char esc_esc[2] = { TRACE_ESC, TRACE_ESC_ESC };
static char esc_end[2] = { TRACE_ESC, TRACE_ESC_END };
int trace_packet_write(struct trace *trace, struct trace_pkt *pkt)
{
int i;
int start = 0;
while (start < pkt->len) for (i = start; i < pkt->len; i++) {
if (pkt->data[i] == TRACE_ESC || pkt->data[i] == TRACE_END) {
char *seq;
write(trace->fd, pkt->data + start, i - start);
start = i + 1;
if (pkt->data[i] == TRACE_ESC)
seq = esc_esc;
else
seq = esc_end;
write(trace->fd, seq, 2);
}
if (i == pkt->len -1)
write(trace->fd, pkt->data + start, i - start);
}
return 0;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment