Commit f9d740ee authored by Cedric Roux's avatar Cedric Roux

first commit of the T - review this commit, many things should

probably not be here.
parent 9185c693
......@@ -1484,6 +1484,13 @@ endif (${XFORMS})
set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}")
#add the T tracer
add_boolean_option(T_TRACER True "Activate the T tracer" )
include_directories("${OPENAIR_DIR}/common/utils/T")
add_boolean_option(T_USE_SHARED_MEMORY True "Use shared memory to communicate with the T tracer" )
set(T_SOURCE
${OPENAIR_DIR}/common/utils/T/T.c)
set (T_LIB "-lrt")
# Hack on a test of asn1c version (already dirty)
add_definitions(-DASN1_MINIMUM_VERSION=924)
......@@ -1516,6 +1523,7 @@ add_executable(lte-softmodem
${RTAI_SOURCE}
${XFORMS_SOURCE}
${XFORMS_SOURCE_SOFTMODEM}
${T_SOURCE}
)
target_link_libraries (lte-softmodem
......@@ -1529,6 +1537,8 @@ target_link_libraries (lte-softmodem pthread m ${CONFIG_LIBRARIES} rt crypt ${CR
target_link_libraries (lte-softmodem ${LIBBOOST_LIBRARIES})
target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES})
target_link_libraries (lte-softmodem ${T_LIB})
# lte-softmodem-nos1 is both eNB and UE implementation
###################################################
add_executable(lte-softmodem-nos1
......@@ -1552,6 +1562,7 @@ add_executable(lte-softmodem-nos1
${RTAI_SOURCE}
${XFORMS_SOURCE}
${XFORMS_SOURCE_SOFTMODEM}
${T_SOURCE}
)
target_link_libraries (lte-softmodem-nos1
-Wl,--start-group
......@@ -1563,6 +1574,8 @@ target_link_libraries (lte-softmodem-nos1 pthread m ${CONFIG_LIBRARIES} rt crypt
target_link_libraries (lte-softmodem-nos1 ${LIBBOOST_LIBRARIES})
target_link_libraries (lte-softmodem-nos1 ${LIB_LMS_LIBRARIES})
target_link_libraries (lte-softmodem ${T_LIB})
# rrh
################################
#Note: only one RF type (USRP) is currently supported for RRH
......@@ -1687,6 +1700,7 @@ add_executable(oaisim_nos1
${HW_SOURCE}
${TRANSPORT_SOURCE}
${XFORMS_SOURCE}
${T_SOURCE}
)
target_include_directories(oaisim_nos1 PUBLIC ${OPENAIR_TARGETS}/SIMU/USER)
target_link_libraries (oaisim_nos1
......@@ -1700,6 +1714,7 @@ target_link_libraries (oaisim_nos1 pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYP
#Force link with forms, regardless XFORMS option
target_link_libraries (oaisim_nos1 forms)
target_link_libraries (lte-softmodem ${T_LIB})
# Unitary tests for each piece of L1: example, mbmssim is MBMS L1 simulator
#####################################
......
#include "T.h"
#include <string.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
/* array used to activate/disactivate a log */
static int T_IDs[T_NUMBER_OF_IDS];
int *T_active = T_IDs;
static int T_socket;
/* T_cache
* - the T macro picks up the head of freelist and marks it busy
* - the T sender thread periodically wakes up and sends what's to be sent
*/
volatile int _T_freelist_head;
volatile int *T_freelist_head = &_T_freelist_head;
int T_busylist_head;
T_cache_t _T_cache[T_CACHE_SIZE];
T_cache_t *T_cache = _T_cache;
static void get_message(int s)
{
char t;
int l;
int id;
if (read(s, &t, 1) != 1) abort();
printf("got mess %d\n", t);
switch (t) {
case 0:
/* toggle all those IDs */
/* optimze? (too much syscalls) */
if (read(s, &l, sizeof(int)) != sizeof(int)) abort();
while (l) {
if (read(s, &id, sizeof(int)) != sizeof(int)) abort();
T_IDs[id] = 1 - T_IDs[id];
l--;
}
break;
}
}
#ifndef T_USE_SHARED_MEMORY
static void *T_send_thread(void *_)
{
while (1) {
usleep(5000);
__sync_synchronize();
while (T_cache[T_busylist_head].busy) {
char *b;
int l;
/* TODO: be sure about those memory barriers - in doubt one is
* put here too
*/
__sync_synchronize();
b = T_cache[T_busylist_head].buffer;
l = T_cache[T_busylist_head].length;
while (l) {
int done = write(T_socket, b, l);
if (done <= 0) {
printf("%s:%d:%s: error sending to socket\n",
__FILE__, __LINE__, __FUNCTION__);
abort();
}
b += done;
l -= done;
}
T_cache[T_busylist_head].busy = 0;
T_busylist_head++;
T_busylist_head &= T_CACHE_SIZE - 1;
}
}
return NULL;
}
#endif /* T_USE_SHARED_MEMORY */
static void *T_receive_thread(void *_)
{
while (1) get_message(T_socket);
return NULL;
}
static void new_thread(void *(*f)(void *), void *data)
{
pthread_t t;
pthread_attr_t att;
if (pthread_attr_init(&att))
{ fprintf(stderr, "pthread_attr_init err\n"); exit(1); }
if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED))
{ fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); }
if (pthread_create(&t, &att, f, data))
{ fprintf(stderr, "pthread_create err\n"); exit(1); }
if (pthread_attr_destroy(&att))
{ fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); }
}
void T_connect_to_tracer(char *addr, int port)
{
struct sockaddr_in a;
int s;
#ifdef T_USE_SHARED_MEMORY
int T_shm_fd;
#endif
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1) { perror("socket"); exit(1); }
a.sin_family = AF_INET;
a.sin_port = htons(port);
a.sin_addr.s_addr = inet_addr(addr);
if (connect(s, (struct sockaddr *)&a, sizeof(a)) == -1)
{ perror("connect"); exit(1); }
/* wait for first message - initial list of active T events */
get_message(s);
T_socket = s;
#ifdef T_USE_SHARED_MEMORY
/* setup shared memory */
T_shm_fd = shm_open(T_SHM_FILENAME, O_RDWR /*| O_SYNC*/, 0666);
shm_unlink(T_SHM_FILENAME);
if (T_shm_fd == -1) { perror(T_SHM_FILENAME); abort(); }
T_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t),
PROT_READ | PROT_WRITE, MAP_SHARED, T_shm_fd, 0);
if (T_cache == NULL)
{ perror(T_SHM_FILENAME); abort(); }
close(T_shm_fd);
#endif
#ifndef T_USE_SHARED_MEMORY
new_thread(T_send_thread, NULL);
#endif
new_thread(T_receive_thread, NULL);
}
This diff is collapsed.
/* generated file, do not edit by hand */
#define T_ENB_INPUT_SIGNAL T_ID(0)
#define T_ENB_UL_CHANNEL_ESTIMATE T_ID(1)
#define T_PUSCH_IQ T_ID(2)
#define T_PUCCH_1AB_IQ T_ID(3)
#define T_PUCCH_1_ENERGY T_ID(4)
#define T_LEGACY_MAC_INFO T_ID(5)
#define T_LEGACY_MAC_ERROR T_ID(6)
#define T_LEGACY_MAC_WARNING T_ID(7)
#define T_LEGACY_MAC_DEBUG T_ID(8)
#define T_LEGACY_MAC_TRACE T_ID(9)
#define T_LEGACY_PHY_INFO T_ID(10)
#define T_LEGACY_PHY_ERROR T_ID(11)
#define T_LEGACY_PHY_WARNING T_ID(12)
#define T_LEGACY_PHY_DEBUG T_ID(13)
#define T_LEGACY_PHY_TRACE T_ID(14)
#define T_LEGACY_S1AP_INFO T_ID(15)
#define T_LEGACY_S1AP_ERROR T_ID(16)
#define T_LEGACY_S1AP_WARNING T_ID(17)
#define T_LEGACY_S1AP_DEBUG T_ID(18)
#define T_LEGACY_S1AP_TRACE T_ID(19)
#define T_LEGACY_X2AP_INFO T_ID(20)
#define T_LEGACY_X2AP_ERROR T_ID(21)
#define T_LEGACY_X2AP_WARNING T_ID(22)
#define T_LEGACY_X2AP_DEBUG T_ID(23)
#define T_LEGACY_X2AP_TRACE T_ID(24)
#define T_LEGACY_RRC_INFO T_ID(25)
#define T_LEGACY_RRC_ERROR T_ID(26)
#define T_LEGACY_RRC_WARNING T_ID(27)
#define T_LEGACY_RRC_DEBUG T_ID(28)
#define T_LEGACY_RRC_TRACE T_ID(29)
#define T_LEGACY_RLC_INFO T_ID(30)
#define T_LEGACY_RLC_ERROR T_ID(31)
#define T_LEGACY_RLC_WARNING T_ID(32)
#define T_LEGACY_RLC_DEBUG T_ID(33)
#define T_LEGACY_RLC_TRACE T_ID(34)
#define T_LEGACY_PDCP_INFO T_ID(35)
#define T_LEGACY_PDCP_ERROR T_ID(36)
#define T_LEGACY_PDCP_WARNING T_ID(37)
#define T_LEGACY_PDCP_DEBUG T_ID(38)
#define T_LEGACY_PDCP_TRACE T_ID(39)
#define T_LEGACY_ENB_APP_INFO T_ID(40)
#define T_LEGACY_ENB_APP_ERROR T_ID(41)
#define T_LEGACY_ENB_APP_WARNING T_ID(42)
#define T_LEGACY_ENB_APP_DEBUG T_ID(43)
#define T_LEGACY_ENB_APP_TRACE T_ID(44)
#define T_LEGACY_SCTP_INFO T_ID(45)
#define T_LEGACY_SCTP_ERROR T_ID(46)
#define T_LEGACY_SCTP_WARNING T_ID(47)
#define T_LEGACY_SCTP_DEBUG T_ID(48)
#define T_LEGACY_SCTP_TRACE T_ID(49)
#define T_LEGACY_UDP__INFO T_ID(50)
#define T_LEGACY_UDP__ERROR T_ID(51)
#define T_LEGACY_UDP__WARNING T_ID(52)
#define T_LEGACY_UDP__DEBUG T_ID(53)
#define T_LEGACY_UDP__TRACE T_ID(54)
#define T_LEGACY_NAS_INFO T_ID(55)
#define T_LEGACY_NAS_ERROR T_ID(56)
#define T_LEGACY_NAS_WARNING T_ID(57)
#define T_LEGACY_NAS_DEBUG T_ID(58)
#define T_LEGACY_NAS_TRACE T_ID(59)
#define T_LEGACY_HW_INFO T_ID(60)
#define T_LEGACY_HW_ERROR T_ID(61)
#define T_LEGACY_HW_WARNING T_ID(62)
#define T_LEGACY_HW_DEBUG T_ID(63)
#define T_LEGACY_HW_TRACE T_ID(64)
#define T_LEGACY_EMU_INFO T_ID(65)
#define T_LEGACY_EMU_ERROR T_ID(66)
#define T_LEGACY_EMU_WARNING T_ID(67)
#define T_LEGACY_EMU_DEBUG T_ID(68)
#define T_LEGACY_EMU_TRACE T_ID(69)
#define T_LEGACY_OTG_INFO T_ID(70)
#define T_LEGACY_OTG_ERROR T_ID(71)
#define T_LEGACY_OTG_WARNING T_ID(72)
#define T_LEGACY_OTG_DEBUG T_ID(73)
#define T_LEGACY_OTG_TRACE T_ID(74)
#define T_LEGACY_OCG_INFO T_ID(75)
#define T_LEGACY_OCG_ERROR T_ID(76)
#define T_LEGACY_OCG_WARNING T_ID(77)
#define T_LEGACY_OCG_DEBUG T_ID(78)
#define T_LEGACY_OCG_TRACE T_ID(79)
#define T_LEGACY_OCM_INFO T_ID(80)
#define T_LEGACY_OCM_ERROR T_ID(81)
#define T_LEGACY_OCM_WARNING T_ID(82)
#define T_LEGACY_OCM_DEBUG T_ID(83)
#define T_LEGACY_OCM_TRACE T_ID(84)
#define T_LEGACY_OIP_INFO T_ID(85)
#define T_LEGACY_OIP_ERROR T_ID(86)
#define T_LEGACY_OIP_WARNING T_ID(87)
#define T_LEGACY_OIP_DEBUG T_ID(88)
#define T_LEGACY_OIP_TRACE T_ID(89)
#define T_LEGACY_OMG_INFO T_ID(90)
#define T_LEGACY_OMG_ERROR T_ID(91)
#define T_LEGACY_OMG_WARNING T_ID(92)
#define T_LEGACY_OMG_DEBUG T_ID(93)
#define T_LEGACY_OMG_TRACE T_ID(94)
#define T_LEGACY_OPT_INFO T_ID(95)
#define T_LEGACY_OPT_ERROR T_ID(96)
#define T_LEGACY_OPT_WARNING T_ID(97)
#define T_LEGACY_OPT_DEBUG T_ID(98)
#define T_LEGACY_OPT_TRACE T_ID(99)
#define T_LEGACY_GTPU_INFO T_ID(100)
#define T_LEGACY_GTPU_ERROR T_ID(101)
#define T_LEGACY_GTPU_WARNING T_ID(102)
#define T_LEGACY_GTPU_DEBUG T_ID(103)
#define T_LEGACY_GTPU_TRACE T_ID(104)
#define T_LEGACY_TMR_INFO T_ID(105)
#define T_LEGACY_TMR_ERROR T_ID(106)
#define T_LEGACY_TMR_WARNING T_ID(107)
#define T_LEGACY_TMR_DEBUG T_ID(108)
#define T_LEGACY_TMR_TRACE T_ID(109)
#define T_LEGACY_OSA_INFO T_ID(110)
#define T_LEGACY_OSA_ERROR T_ID(111)
#define T_LEGACY_OSA_WARNING T_ID(112)
#define T_LEGACY_OSA_DEBUG T_ID(113)
#define T_LEGACY_OSA_TRACE T_ID(114)
#define T_LEGACY_component_INFO T_ID(115)
#define T_LEGACY_component_ERROR T_ID(116)
#define T_LEGACY_component_WARNING T_ID(117)
#define T_LEGACY_component_DEBUG T_ID(118)
#define T_LEGACY_component_TRACE T_ID(119)
#define T_LEGACY_componentP_INFO T_ID(120)
#define T_LEGACY_componentP_ERROR T_ID(121)
#define T_LEGACY_componentP_WARNING T_ID(122)
#define T_LEGACY_componentP_DEBUG T_ID(123)
#define T_LEGACY_componentP_TRACE T_ID(124)
#define T_LEGACY_CLI_INFO T_ID(125)
#define T_LEGACY_CLI_ERROR T_ID(126)
#define T_LEGACY_CLI_WARNING T_ID(127)
#define T_LEGACY_CLI_DEBUG T_ID(128)
#define T_LEGACY_CLI_TRACE T_ID(129)
#define T_first T_ID(130)
#define T_buf_test T_ID(131)
#define T_NUMBER_OF_IDS 132
#ifndef _T_defs_H_
#define _T_defs_H_
/* maximum size of a message - increase if needed */
#define T_BUFFER_MAX (1024*64)
/* size of the local cache for messages (must be pow(2,something)) */
#define T_CACHE_SIZE (8192 * 2)
typedef struct {
volatile int busy;
char buffer[T_BUFFER_MAX];
int length;
} T_cache_t;
#define T_SHM_FILENAME "/T_shm_segment"
#endif /* _T_defs_H_ */
#include "defs.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
typedef struct {
char *name;
char *desc;
char **groups;
int size;
int id;
} id;
typedef struct {
char *name;
char **ids;
int size;
} group;
typedef struct {
char *name;
id *i;
int isize;
group *g;
int gsize;
} database;
typedef struct {
char *data;
int size;
int maxsize;
} buffer;
typedef struct {
buffer name;
buffer value;
} parser;
void put(buffer *b, int c)
{
if (b->size == b->maxsize) {
b->maxsize += 256;
b->data = realloc(b->data, b->maxsize);
if (b->data == NULL) { printf("memory allocation error\n"); exit(1); }
}
b->data[b->size] = c;
b->size++;
}
void smash_spaces(FILE *f)
{
int c;
while (1) {
c = fgetc(f);
if (isspace(c)) continue;
if (c == ' ') continue;
if (c == '\t') continue;
if (c == '\n') continue;
if (c == 10 || c == 13) continue;
if (c == '#') {
while (1) {
c = fgetc(f);
if (c == '\n' || c == EOF) break;
}
continue;
}
break;
}
if (c != EOF) ungetc(c, f);
}
void get_line(parser *p, FILE *f, char **name, char **value)
{
int c;
p->name.size = 0;
p->value.size = 0;
*name = NULL;
*value = NULL;
smash_spaces(f);
c = fgetc(f);
while (!(c == '=' || isspace(c) || c == EOF))
{ put(&p->name, c); c = fgetc(f); }
if (c == EOF) return;
put(&p->name, 0);
while (!(c == EOF || c == '=')) c = fgetc(f);
if (c == EOF) return;
smash_spaces(f);
c = fgetc(f);
while (!(c == 10 || c == 13 || c == EOF))
{ put(&p->value, c); c = fgetc(f); }
put(&p->value, 0);
if (p->name.size <= 1) return;
if (p->value.size <= 1) return;
*name = p->name.data;
*value = p->value.data;
}
int group_cmp(const void *_p1, const void *_p2)
{
const group *p1 = _p1;
const group *p2 = _p2;
return strcmp(p1->name, p2->name);
}
int id_cmp(const void *_p1, const void *_p2)
{
const id *p1 = _p1;
const id *p2 = _p2;
return strcmp(p1->name, p2->name);
}
int string_cmp(const void *_p1, const void *_p2)
{
char * const *p1 = _p1;
char * const *p2 = _p2;
return strcmp(*p1, *p2);
}
id *add_id(database *r, char *idname, int i)
{
if (bsearch(&(id){name:idname}, r->i, r->isize, sizeof(id), id_cmp) != NULL)
{ printf("ERROR: ID '%s' declared more than once\n", idname); exit(1); }
if ((r->isize & 1023) == 0) {
r->i = realloc(r->i, (r->isize + 1024) * sizeof(id));
if (r->i == NULL) { printf("out of memory\n"); exit(1); }
}
r->i[r->isize].name = strdup(idname);
if (r->i[r->isize].name == NULL) { printf("out of memory\n"); exit(1); }
r->i[r->isize].desc = NULL;
r->i[r->isize].groups = NULL;
r->i[r->isize].size = 0;
r->i[r->isize].id = i;
r->isize++;
qsort(r->i, r->isize, sizeof(id), id_cmp);
return (id*)bsearch(&(id){name:idname}, r->i, r->isize, sizeof(id), id_cmp);
}
group *get_group(database *r, char *group_name)
{
group *ret;
ret = bsearch(&(group){name:group_name},
r->g, r->gsize, sizeof(group), group_cmp);
if (ret != NULL) return ret;
if ((r->gsize & 1023) == 0) {
r->g = realloc(r->g, (r->gsize + 1024) * sizeof(group));
if (r->g == NULL) abort();
}
r->g[r->gsize].name = strdup(group_name);
if (r->g[r->gsize].name == NULL) abort();
r->g[r->gsize].ids = NULL;
r->g[r->gsize].size = 0;
r->gsize++;
qsort(r->g, r->gsize, sizeof(group), group_cmp);
return bsearch(&(group){name:group_name},
r->g, r->gsize, sizeof(group), group_cmp);
}
void group_add_id(group *g, char *id)
{
if ((g->size & 1023) == 0) {
g->ids = realloc(g->ids, (g->size + 1024) * sizeof(char *));
if (g->ids == NULL) abort();
}
g->ids[g->size] = id;
g->size++;
}
void id_add_group(id *i, char *group)
{
char *g = bsearch(&group, i->groups, i->size, sizeof(char *), string_cmp);
if (g != NULL) return;
if ((i->size & 1023) == 0) {
i->groups = realloc(i->groups, (i->size+1024) * sizeof(char *));
if (i->groups == NULL) abort();
}
i->groups[i->size] = group;
i->size++;
qsort(i->groups, i->size, sizeof(char *), string_cmp);
}
void add_groups(database *r, id *i, char *groups)
{
group *g;
if (i == NULL) {printf("ERROR: GROUP line before ID line\n");exit(1);}
while (1) {
char *start = groups;
char *end = start;
while (!isspace(*end) && *end != ':' && *end != 0) end++;
if (end == start) {
printf("bad group line: groups are seperated by ':'\n");
abort();
}
if (*end == 0) end = NULL; else *end = 0;
g = get_group(r, start);
group_add_id(g, i->name);
id_add_group(i, g->name);
if (end == NULL) break;
end++;
while ((isspace(*end) || *end == ':') && *end != 0) end++;
if (*end == 0) break;
groups = end;
}
}
void add_desc(id *i, char *desc)
{
if (i == NULL) {printf("ERROR: DESC line before ID line\n");exit(1);}
i->desc = strdup(desc); if (i->desc == NULL) abort();
}
void *parse_database(char *filename)
{
FILE *in;
parser p;
database *r;
char *name, *value;
id *last_id = NULL;
int i;
r = calloc(1, sizeof(*r)); if (r == NULL) abort();
memset(&p, 0, sizeof(p));
r->name = strdup(filename); if (r->name == NULL) abort();
in = fopen(filename, "r"); if (in == NULL) { perror(filename); abort(); }
i = 0;
while (1) {
get_line(&p, in, &name, &value);
if (name == NULL) break;
//printf("%s %s\n", name, value);
if (!strcmp(name, "ID")) { last_id = add_id(r, value, i); i++; }
if (!strcmp(name, "GROUP")) add_groups(r, last_id, value);
if (!strcmp(name, "DESC")) add_desc(last_id, value);
}
fclose(in);
free(p.name.data);
free(p.value.data);
return r;
}
void dump_database(void *_d)
{
database *d = _d;
int i;
printf("database %s: %d IDs, %d GROUPs\n", d->name, d->isize, d->gsize);
for (i = 0; i < d->isize; i++) {
int j;
printf("ID %s [%s] [in %d group%s]\n",
d->i[i].name, d->i[i].desc ? d->i[i].desc : "",
d->i[i].size, d->i[i].size > 1 ? "s" : "");
for (j = 0; j < d->i[i].size; j++)
printf(" in GROUP: %s\n", d->i[i].groups[j]);
}
for (i = 0; i < d->gsize; i++) {
int j;
printf("GROUP %s [size %d]\n", d->g[i].name, d->g[i].size);
for (j = 0; j < d->g[i].size; j++)
printf(" contains ID: %s\n", d->g[i].ids[j]);
}
}
void list_ids(void *_d)
{
database *d = _d;
int i;
for (i = 0; i < d->isize; i++) printf("%s\n", d->i[i].name);
}
void list_groups(void *_d)
{
database *d = _d;
int i;
for (i = 0; i < d->gsize; i++) printf("%s\n", d->g[i].name);
}
static int onoff_id(database *d, char *name, int *a, int onoff)
{
id *i;
i = bsearch(&(id){name:name}, d->i, d->isize, sizeof(id), id_cmp);
if (i == NULL) return 0;
a[i->id] = onoff;
printf("turning %s %s\n", onoff ? "ON" : "OFF", name);
return 1;
}
static int onoff_group(database *d, char *name, int *a, int onoff)
{
group *g;
int i;
g = bsearch(&(group){name:name}, d->g, d->gsize, sizeof(group), group_cmp);
if (g == NULL) return 0;
for (i = 0; i < g->size; i++) onoff_id(d, g->ids[i], a, onoff);
return 1;
}
void on_off(void *_d, char *item, int *a, int onoff)
{
int done;
database *d = _d;
int i;
if (item == NULL) {
for (i = 0; i < d->isize; i++) a[i] = onoff;
printf("turning %s all traces\n", onoff ? "ON" : "OFF");
return;
}
done = onoff_group(d, item, a, onoff);
done += onoff_id(d, item, a, onoff);
if (done == 0) {
printf("ERROR: ID/group '%s' not found in database\n", item);
exit(1);
}
}
#ifndef _TRACER_DEFS_H_
#define _TRACER_DEFS_H_
/* types of plots */
#define PLOT_VS_TIME 0
#define PLOT_IQ_POINTS 1
#define PLOT_MINMAX 2
void new_thread(void *(*f)(void *), void *data);
/* ... is { int count; int type; char *color; } for 'nplots' plots */
void *make_plot(int width, int height, char *title, int nplots, ...);
void plot_set(void *plot, float *data, int len, int pos, int pp);
void iq_plot_set(void *plot, short *data, int len, int pos, int pp);
void iq_plot_set_sized(void *_plot, short *data, int len, int pp);
void iq_plot_add_iq_point_loop(void *_plot, short i, short q, int pp);
void iq_plot_add_energy_point_loop(void *_plot, int e, int pp);
/* returns an opaque pointer - truly a 'database *', see t_data.c */
void *parse_database(char *filename);
void dump_database(void *database);
void list_ids(void *database);
void list_groups(void *database);
void on_off(void *d, char *item, int *a, int onoff);
void *forwarder(char *ip, int port);
void forward(void *forwarder, char *buf, int size);
void forward_start_client(void *forwarder, int socket);
#endif /* _TRACER_DEFS_H_ */