Commit 576e88b3 authored by Jeroen Vreeken's avatar Jeroen Vreeken
Browse files

Command server step 2: move all trackers to the new command server lib.

parent 3659d183
......@@ -40,6 +40,7 @@ struct command_server {
struct command_client *clients;
int (*handle_func)(char *name, char *value);
int (*handle_raw_func)(char *command);
};
......@@ -77,7 +78,17 @@ err_alloc:
void command_server_destroy(struct command_server *srv)
{
struct command_client *client;
if (srv) {
while (srv->clients) {
client = srv->clients;
srv->clients = client->next;
close(client->fd);
free(client);
}
close(srv->fd);
free(srv);
}
......@@ -87,13 +98,27 @@ void command_server_destroy(struct command_server *srv)
int command_server_handler_set(struct command_server *srv,
int (*func)(char *name, char *value))
{
/* Remember who to call when a command is received */
srv->handle_func = func;
return 0;
}
int command_server_handler_raw_set(struct command_server *srv,
int (*func)(char *command))
{
/* Remember who to call when a command is received */
srv->handle_raw_func = func;
return 0;
}
int command_server_fdset_add(struct command_server *srv, fd_set *set, int *high)
{
/* Add all our sockets to the set
*/
struct command_client *client;
for (client = srv->clients; client; client = client->next) {
......@@ -111,16 +136,29 @@ int command_server_fdset_add(struct command_server *srv, fd_set *set, int *high)
void command_server_handle(struct command_server *srv, struct command_client *client)
{
/* A command has been received.
Split it in a key, value pair and pass it to application handler
Some applications have a command format which is not (completly) in
a key=value format. They can get the 'raw' string and still enjoy
the other benefits of this lib.
*/
char *namevalue;
char *name;
char *value;
char *ptr;
namevalue = client->buffer;
name = strtok_r(namevalue, ",=", &ptr);
value = strtok_r(NULL, ",=", &ptr);
srv->handle_func(name, value);
if (srv->handle_raw_func) {
srv->handle_raw_func(client->buffer);
} else {
do {
namevalue = client->buffer;
name = strtok_r(namevalue, ",=", &ptr);
value = strtok_r(NULL, ",=", &ptr);
if (name && value)
srv->handle_func(name, value);
} while (name && value);
}
}
int command_server_fdset_handle(struct command_server *srv, fd_set *set)
......@@ -138,12 +176,17 @@ int command_server_fdset_handle(struct command_server *srv, fd_set *set)
do {
ret = read((*clientp)->fd, (*clientp)->buffer+(*clientp)->buflen, 1);
if ((ret < 0 && errno != EAGAIN) || ret == 0) {
/* Fatal error on socket to client.
Clean up client
*/
client = *clientp;
close(client->fd);
*clientp = (*clientp)->next;
free(client);
nextp = clientp;
} else if (ret == 1) {
/* Data from client received.
*/
(*clientp)->buflen += 1;
if ((*clientp)->buffer[(*clientp)->buflen-1] == '\n' ||
(*clientp)->buffer[(*clientp)->buflen-1] == '\r') {
......
......@@ -31,6 +31,8 @@ void command_server_destroy(struct command_server *srv);
int command_server_handler_set(struct command_server *srv,
int (*func)(char *name, char *value));
int command_server_handler_raw_set(struct command_server *srv,
int (*func)(char *command));
int command_server_fdset_add(struct command_server *srv, fd_set *set, int *high);
int command_server_fdset_handle(struct command_server *srv, fd_set *set);
......
/*
Command generator for az/el positions
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2008
Copyright Stichting C.A. Muller Radioastronomiestation, 2008
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2008, 2013
Copyright Stichting C.A. Muller Radioastronomiestation, 2008, 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
......@@ -38,8 +38,7 @@
#include "setpoint.h"
#include "tcp_connect.h"
#include "tcp_listen.h"
#include "command_server.h"
char *command_host = "localhost";
int command_port = 11000;
......@@ -57,58 +56,16 @@ typedef union {
} float32_t;
struct cmd_client {
struct cmd_client *next;
int fd;
char buffer[100];
int buflen;
};
struct cmd_client *cmd_clients = NULL;
void new_cmd_client(int fd_cmd)
{
struct cmd_client *new_cmd;
int fd;
fd = tcp_accept(fd_cmd);
if (fd < 0)
return;
ioctl(fd, FIONBIO, &(int){ 1 });
new_cmd = malloc(sizeof(struct cmd_client));
if (!new_cmd) {
close(fd);
return;
}
new_cmd->fd = fd;
new_cmd->buflen = 0;
new_cmd->next = cmd_clients;
cmd_clients = new_cmd;
}
void fdset_cmd_clients(fd_set *fdset_rx, int *high)
{
struct cmd_client *cmd;
for (cmd = cmd_clients; cmd; cmd = cmd->next) {
FD_SET(cmd->fd, fdset_rx);
if (cmd->fd >= *high)
*high = cmd->fd + 1;
}
}
void handle_cmd(struct cmd_client *cmd)
int handle_cmd(char *command)
{
char *aaz, *ael, *ptr;
printf("cmd: '%s'\n", cmd->buffer);
aaz = strtok_r(cmd->buffer, " \t", &ptr);
printf("cmd: '%s'\n", command);
aaz = strtok_r(command, " \t", &ptr);
ael = strtok_r(NULL, " \t", &ptr);
if (!aaz || !ael)
return;
return -1;
printf("aaz: '%s' ael: '%s'\n", aaz, ael);
......@@ -127,55 +84,17 @@ void handle_cmd(struct cmd_client *cmd)
printf("%g %g\n", sp_az, sp_el);
go = 1;
}
void check_cmd_clients(fd_set *fdset_rx)
{
struct cmd_client **cmdp, **nextp = NULL;
for (cmdp = &cmd_clients; *cmdp; cmdp = nextp) {
int ret;
nextp = &(*cmdp)->next;
if (!FD_ISSET((*cmdp)->fd, fdset_rx))
continue;
do {
ret = read((*cmdp)->fd, (*cmdp)->buffer+(*cmdp)->buflen, 1);
if ((ret < 0 && errno != EAGAIN) || ret == 0) {
struct cmd_client *tmp;
tmp = *cmdp;
close((*cmdp)->fd);
*cmdp = (*cmdp)->next;
free(tmp);
nextp = cmdp;
} else if (ret < 0 && errno == EAGAIN) {
/* nothing */
} else {
(*cmdp)->buflen += 1;
if ((*cmdp)->buffer[(*cmdp)->buflen-1] == '\n' ||
(*cmdp)->buffer[(*cmdp)->buflen-1] == '\r') {
if ((*cmdp)->buflen > 1) {
(*cmdp)->buffer[(*cmdp)->buflen] = 0;
handle_cmd(*cmdp);
}
(*cmdp)->buflen = 0;
}
if ((*cmdp)->buflen >= 100)
(*cmdp)->buflen = 0;
}
} while (ret > 0);
}
return 0;
}
int main(int argc, char **argv)
{
struct setpoint_command *sp_command_az = NULL;
struct setpoint_command *sp_command_el = NULL;
struct command_server *cmd_srv;
time_t lastt = 0;
int fd_cmd;
signal(SIGPIPE, SIG_IGN);
......@@ -201,11 +120,12 @@ int main(int argc, char **argv)
} while (!sp_command_el);
fd_cmd = tcp_listen(cmd_port, 0, 100);
if (fd_cmd < 0) {
printf("Could not open liste port for commands\n");
cmd_srv = command_server_create(cmd_port, 0, 100);
if (!cmd_srv) {
printf("Could not open listen port for commands\n");
} else {
ioctl(fd_cmd, FIONBIO, &(int){ 1 });
command_server_handler_raw_set(cmd_srv, handle_cmd);
}
while (1)
......@@ -234,24 +154,14 @@ int main(int argc, char **argv)
FD_ZERO(&fdset_rx);
if (fd_cmd >= 0) {
FD_SET(fd_cmd, &fdset_rx);
if (fd_cmd >= high)
high = fd_cmd + 1;
}
command_server_fdset_add(cmd_srv, &fdset_rx, &high);
fdset_cmd_clients(&fdset_rx, &high);
tv.tv_sec = 1;
tv.tv_usec = 0;
select(high, &fdset_rx, NULL, NULL, &tv);
if (FD_ISSET(fd_cmd, &fdset_rx)) {
new_cmd_client(fd_cmd);
}
check_cmd_clients(&fdset_rx);
command_server_fdset_handle(cmd_srv, &fdset_rx);
}
}
......@@ -44,6 +44,8 @@
#include "dt_port_numbers.h"
#include "command_server.h"
int stat_port = CONSOLE_DT_MODEL_STAT_PORT;
int cmd_port = CONSOLE_DT_MODEL_CMD_PORT;
......@@ -149,14 +151,6 @@ struct stat_client {
struct stat_client *stat_clients = NULL;
struct cmd_client {
struct cmd_client *next;
int fd;
char buffer[200];
int buflen;
};
struct cmd_client *cmd_clients = NULL;
......@@ -181,95 +175,16 @@ void new_stat_client(int fd_stat)
stat_clients = new_stat;
}
void new_cmd_client(int fd_cmd)
{
struct cmd_client *new_cmd;
int fd;
fd = tcp_accept(fd_cmd);
if (fd < 0)
return;
ioctl(fd, FIONBIO, &(int){ 1 });
new_cmd = malloc(sizeof(struct cmd_client));
if (!new_cmd) {
close(fd);
return;
}
new_cmd->fd = fd;
new_cmd->buflen = 0;
new_cmd->next = cmd_clients;
cmd_clients = new_cmd;
}
void fdset_cmd_clients(fd_set *fdset_rx, int *high)
{
struct cmd_client *cmd;
for (cmd = cmd_clients; cmd; cmd = cmd->next) {
FD_SET(cmd->fd, fdset_rx);
if (cmd->fd >= *high)
*high = cmd->fd + 1;
}
}
void handle_cmd(struct cmd_client *cmd)
static int handle_cmd(char *name, char *val)
{
char *switches, *ptr;
switches = cmd->buffer;
printf("command: %s\n", switches);
if (switches) {
char *name, *val;
printf("name %s value %s\n", name, val);
if (!strcmp(name, "reload"))
load_ini();
name = strtok_r(switches, ",=", &ptr);
val = strtok_r(NULL, ",=", &ptr);
printf("name %s value %s\n", name, val);
if (!strcmp(name, "reload"))
load_ini();
}
return 0;
}
void check_cmd_clients(fd_set *fdset_rx)
{
struct cmd_client **cmdp, **nextp = NULL;
for (cmdp = &cmd_clients; *cmdp; cmdp = nextp) {
int ret;
nextp = &(*cmdp)->next;
if (!FD_ISSET((*cmdp)->fd, fdset_rx))
continue;
do {
ret = read((*cmdp)->fd, (*cmdp)->buffer+(*cmdp)->buflen, 1);
if ((ret < 0 && errno != EAGAIN) || ret == 0) {
struct cmd_client *tmp;
tmp = *cmdp;
close((*cmdp)->fd);
*cmdp = (*cmdp)->next;
free(tmp);
nextp = cmdp;
} else if (ret == 1) {
(*cmdp)->buflen += 1;
if ((*cmdp)->buffer[(*cmdp)->buflen-1] == '\n' ||
(*cmdp)->buffer[(*cmdp)->buflen-1] == '\r') {
if ((*cmdp)->buflen > 1) {
(*cmdp)->buffer[(*cmdp)->buflen] = 0;
handle_cmd(*cmdp);
(*cmdp)->buffer[0] = '9';
}
(*cmdp)->buflen = 0;
}
if ((*cmdp)->buflen >= 200)
(*cmdp)->buflen = 0;
}
} while (ret > 0);
}
}
void output(void)
{
......@@ -316,7 +231,8 @@ void output(void)
int main(int argc, char **argv)
{
int fd_stat, fd_cmd;
int fd_stat;
struct command_server *cmd_srv;
dt_model_init_server();
......@@ -324,12 +240,13 @@ int main(int argc, char **argv)
signal(SIGPIPE, SIG_IGN);
fd_cmd = tcp_listen(cmd_port, 0, 100);
if (fd_cmd < 0) {
cmd_srv = command_server_create(cmd_port, 0, 100);
if (!cmd_srv) {
printf("Could not open listen port for commands\n");
} else {
ioctl(fd_cmd, FIONBIO, &(int){ 1 });
command_server_handler_set(cmd_srv, handle_cmd);
}
fd_stat = tcp_listen(stat_port, 0, 100);
if (fd_stat < 0) {
printf("Could not open listen port for status\n");
......@@ -351,12 +268,7 @@ int main(int argc, char **argv)
if (fd_stat >= high)
high = fd_stat + 1;
}
if (fd_cmd >= 0) {
FD_SET(fd_cmd, &fdset_rx);
if (fd_cmd >= high)
high = fd_cmd + 1;
}
fdset_cmd_clients(&fdset_rx, &high);
command_server_fdset_add(cmd_srv, &fdset_rx, &high);
tv.tv_sec = OUTPUT_RATE;
tv.tv_usec = 0;
......@@ -366,10 +278,8 @@ int main(int argc, char **argv)
if (FD_ISSET(fd_stat, &fdset_rx)) {
new_stat_client(fd_stat);
}
if (FD_ISSET(fd_cmd, &fdset_rx)) {
new_cmd_client(fd_cmd);
}
check_cmd_clients(&fdset_rx);
command_server_fdset_handle(cmd_srv, &fdset_rx);
output();
}
......
......@@ -50,8 +50,8 @@
#include "weather.h"
#include "dt_model.h"
#include "trace.h"
#include "dt_port_numbers.h"
#include "command_server.h"
#define TIME_OFFSET 2
......@@ -113,15 +113,6 @@ struct stat_client {
struct stat_client *stat_clients = NULL;
struct cmd_client {
struct cmd_client *next;
int fd;
char buffer[100];
int buflen;
};
struct cmd_client *cmd_clients = NULL;
void a2coord(char *ara, char *adec, struct ln_hms *ra, struct ln_dms *dec)
......@@ -203,50 +194,17 @@ void new_stat_client(int fd_stat)
stat_clients = new_stat;
}
void new_cmd_client(int fd_cmd)
{
struct cmd_client *new_cmd;
int fd;
fd = tcp_accept(fd_cmd);
if (fd < 0)
return;
ioctl(fd, FIONBIO, &(int){ 1 });
new_cmd = malloc(sizeof(struct cmd_client));
if (!new_cmd) {
close(fd);
return;
}
new_cmd->fd = fd;
new_cmd->buflen = 0;
new_cmd->next = cmd_clients;
cmd_clients = new_cmd;
}
void fdset_cmd_clients(fd_set *fdset_rx, int *high)
{
struct cmd_client *cmd;
for (cmd = cmd_clients; cmd; cmd = cmd->next) {
FD_SET(cmd->fd, fdset_rx);
if (cmd->fd >= *high)
*high = cmd->fd + 1;
}
}
void handle_cmd(struct cmd_client *cmd)
int handle_cmd(char *command)
{
char *ara, *adec, *switches, *ptr;
double oldra, olddec;
ara = strtok_r(cmd->buffer, " \t", &ptr);
ara = strtok_r(command, " \t", &ptr);
adec = strtok_r(NULL, " \t", &ptr);
switches = strtok_r(NULL, " \t", &ptr);
if (!ara || !adec)
return;
return -1;
while (adec[strlen(adec)-1] == '\n' ||
adec[strlen(adec)-1] == '\r')
......@@ -276,45 +234,7 @@ void handle_cmd(struct cmd_client *cmd)
}
}
}
}
void check_cmd_clients(fd_set *fdset_rx)
{
struct cmd_client **cmdp, **nextp = NULL;
for (cmdp = &cmd_clients; *cmdp; cmdp = nextp) {
int ret;
nextp = &(*cmdp)->next;
if (!FD_ISSET((*cmdp)->fd, fdset_rx))
continue;
do {
ret = read((*cmdp)->fd, (*cmdp)->buffer+(*cmdp)->buflen, 1);
if ((ret < 0 && errno != EAGAIN) || ret == 0) {
struct cmd_client *tmp;
tmp = *cmdp;
close((*cmdp)->fd);
*cmdp = (*cmdp)->next;
free(tmp);
nextp = cmdp;
} else if (ret == 1) {
(*cmdp)->buflen += 1;
if ((*cmdp)->buffer[(*cmdp)->buflen-1] == '\n' ||
(*cmdp)->buffer[(*cmdp)->buflen-1] == '\r') {
if ((*cmdp)->buflen > 1) {
(*cmdp)->buffer[(*cmdp)->buflen] = 0;
handle_cmd(*cmdp);
(*cmdp)->buffer[0] = '9';
}
(*cmdp)->buflen = 0;
}
if ((*cmdp)->buflen >= 100)
(*cmdp)->buflen = 0;
}
} while (ret > 0);
}
return 0;
}
void output(void)
......@@ -455,9 +375,10 @@ int main(int argc, char **argv)
{
struct setpoint_command *sp_command_az = NULL;
struct setpoint_command *sp_command_el = NULL;
struct command_server *cmd_srv;
time_t lastt = 0;
int fd_stat, fd_cmd;
int fd_stat;
dt_model_init();
......@@ -519,11 +440,11 @@ int main(int argc, char **argv)
trace_init(trace_host, trace_port, az_trace_name, traceval_az);
trace_init(trace_host, trace_port, el_trace_name, traceval_el);