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

introduce status server library and use it in trackers

parent 576e88b3
......@@ -5,7 +5,7 @@ LDFLAGS= -lpthread
CFLAGS+=`pkg-config --cflags glib-2.0`
LDFLAGS+=`pkg-config --libs glib-2.0`
UTILSRCS= tcp_connect.c tcp_listen.c command_server.c \
UTILSRCS= tcp_connect.c tcp_listen.c command_server.c status_server.c \
config.c weather.c dt_model.c location.c dt_host.c
LIBUTILOBJS= $(UTILSRCS:.c=.lo)
......
/*
status server
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2013
Copyright Stichting C.A. Muller Radioastronomiestation, 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 <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/ioctl.h>
#include "tcp_listen.h"
struct status_client {
struct status_client *next;
int fd;
};
struct status_server {
int fd;
struct status_client *clients;
};
struct status_server *status_server_create(int port, int local, int backlog)
{
struct status_server *srv;
srv = calloc(1, sizeof(struct status_server));
if (!srv)
goto err_alloc;
srv->fd = tcp_listen(port, local, backlog);
if (srv->fd < 0)
goto err_listen;
ioctl(srv->fd, FIONBIO, &(int){ 1 });
return srv;
err_listen:
close(srv->fd);
err_alloc:
return NULL;
}
void status_server_destroy(struct status_server *srv)
{
struct status_client *client;
if (srv) {
while (srv->clients) {
client = srv->clients;
srv->clients = client->next;
close(client->fd);
free(client);
}
close(srv->fd);
free(srv);
}
}
int status_server_fdset_add(struct status_server *srv, fd_set *set, int *high)
{
FD_SET(srv->fd, set);
if (srv->fd >= *high)
*high = srv->fd + 1;
return 0;
}
int status_server_fdset_handle(struct status_server *srv, fd_set *set)
{
struct status_client *client;
if (FD_ISSET(srv->fd, set)) {
/* New client */
int client_fd;
client_fd = tcp_accept(srv->fd);
if (client_fd < 0)
return -1;
ioctl(client_fd, FIONBIO, &(int){ 1 });
client = calloc(1, sizeof(struct status_client));
if (!client) {
close(client_fd);
} else {
client->fd = client_fd;
client->next = srv->clients;
srv->clients = client;
}
}
return 0;
}
int status_server_send(struct status_server *srv, char *status)
{
struct status_client **clientp, **nextp;
for (clientp = &srv->clients; *clientp; clientp = nextp){
int ret;
ret = write((*clientp)->fd, status, strlen(status));
if (ret <= 0) {
struct status_client *tmp;
tmp = *clientp;
close(tmp->fd);
*clientp = (*clientp)->next;
free(tmp);
nextp = clientp;
} else {
nextp = &(*clientp)->next;
}
}
return 0;
}
/*
Command server
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2013
Copyright Stichting C.A. Muller Radioastronomiestation, 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/>.
*/
#ifndef _INCLUDE_STATUS_SERVER_
#define _INCLUDE_STATUS_SERVER_
#include <sys/select.h>
struct status_server;
struct status_server *status_server_create(int port, int local, int backlog);
void status_server_destroy(struct status_server *srv);
int status_server_fdset_add(struct status_server *srv, fd_set *set, int *high);
int status_server_fdset_handle(struct status_server *srv, fd_set *set);
int status_server_send(struct status_server *srv, char *status);
#endif /* _INCLUDE_COMMAND_SERVER_ */
......@@ -38,13 +38,13 @@
#include <stdbool.h>
#include <glib.h>
#include "tcp_connect.h"
#include "tcp_listen.h"
#include "dt_model.h"
#include "dt_port_numbers.h"
#include "command_server.h"
#include "status_server.h"
int stat_port = CONSOLE_DT_MODEL_STAT_PORT;
int cmd_port = CONSOLE_DT_MODEL_CMD_PORT;
......@@ -144,37 +144,6 @@ static int load_ini(void)
/************************************/
struct stat_client {
struct stat_client *next;
int fd;
};
struct stat_client *stat_clients = NULL;
void new_stat_client(int fd_stat)
{
struct stat_client *new_stat;
int fd;
fd = tcp_accept(fd_stat);
if (fd < 0)
return;
ioctl(fd, FIONBIO, &(int){ 1 });
new_stat = malloc(sizeof(struct stat_client));
if (!new_stat) {
close(fd);
return;
}
new_stat->fd = fd;
new_stat->next = stat_clients;
stat_clients = new_stat;
}
static int handle_cmd(char *name, char *val)
{
......@@ -186,11 +155,10 @@ static int handle_cmd(char *name, char *val)
}
void output(void)
void output(struct status_server *stat_srv)
{
static time_t last = 0;
time_t now;
struct stat_client **stat_clientp, **nextp;
char statline[800];
char *statlinepos;
struct dt_model_params params;
......@@ -210,29 +178,14 @@ void output(void)
params.name, params.a0, params.c1, params.c2, params.e0,
params.b, params.za, params.aa);
for (stat_clientp = &stat_clients; *stat_clientp; stat_clientp = nextp){
int ret;
ret = write((*stat_clientp)->fd, statline, strlen(statline));
if (ret <= 0) {
struct stat_client *tmp;
tmp = *stat_clientp;
close((*stat_clientp)->fd);
*stat_clientp = (*stat_clientp)->next;
free(tmp);
nextp = stat_clientp;
} else {
nextp = &(*stat_clientp)->next;
}
}
status_server_send(stat_srv, statline);
}
int main(int argc, char **argv)
{
int fd_stat;
struct command_server *cmd_srv;
struct status_server *stat_srv;
dt_model_init_server();
......@@ -247,11 +200,9 @@ int main(int argc, char **argv)
command_server_handler_set(cmd_srv, handle_cmd);
}
fd_stat = tcp_listen(stat_port, 0, 100);
if (fd_stat < 0) {
stat_srv = status_server_create(stat_port, 0, 100);
if (!cmd_srv) {
printf("Could not open listen port for status\n");
} else {
ioctl(fd_stat, FIONBIO, &(int){ 1 });
}
while (1)
......@@ -263,24 +214,17 @@ int main(int argc, char **argv)
FD_ZERO(&fdset_rx);
if (fd_stat >= 0) {
FD_SET(fd_stat, &fdset_rx);
if (fd_stat >= high)
high = fd_stat + 1;
}
command_server_fdset_add(cmd_srv, &fdset_rx, &high);
status_server_fdset_add(stat_srv, &fdset_rx, &high);
tv.tv_sec = OUTPUT_RATE;
tv.tv_usec = 0;
select(high, &fdset_rx, NULL, NULL, &tv);
if (FD_ISSET(fd_stat, &fdset_rx)) {
new_stat_client(fd_stat);
}
command_server_fdset_handle(cmd_srv, &fdset_rx);
status_server_fdset_handle(stat_srv, &fdset_rx);
output();
output(stat_srv);
}
}
......@@ -45,13 +45,13 @@
#include <libnova/refraction.h>
#include "setpoint.h"
#include "tcp_connect.h"
#include "tcp_listen.h"
#include "weather.h"
#include "dt_model.h"
#include "trace.h"
#include "dt_port_numbers.h"
#include "command_server.h"
#include "status_server.h"
#define TIME_OFFSET 2
......@@ -106,12 +106,6 @@ struct ln_equ_posn object_aber;
struct ln_hms track_hms;
struct ln_dms track_dms;
struct stat_client {
struct stat_client *next;
int fd;
};
struct stat_client *stat_clients = NULL;
......@@ -173,27 +167,6 @@ void a2coord(char *ara, char *adec, struct ln_hms *ra, struct ln_dms *dec)
}
}
void new_stat_client(int fd_stat)
{
struct stat_client *new_stat;
int fd;
fd = tcp_accept(fd_stat);
if (fd < 0)
return;
ioctl(fd, FIONBIO, &(int){ 1 });
new_stat = malloc(sizeof(struct stat_client));
if (!new_stat) {
close(fd);
return;
}
new_stat->fd = fd;
new_stat->next = stat_clients;
stat_clients = new_stat;
}
int handle_cmd(char *command)
{
char *ara, *adec, *switches, *ptr;
......@@ -237,7 +210,7 @@ int handle_cmd(char *command)
return 0;
}
void output(void)
void output(struct status_server *stat_srv)
{
static time_t last = 0;
time_t now;
......@@ -247,7 +220,6 @@ void output(void)
struct ln_equ_posn equ_pos, equ_pos_prec, equ_pos_aber;
struct ln_hms hms;
struct ln_dms dms;
struct stat_client **stat_clientp, **nextp;
char statline[200];
int ret, i;
char *statlinepos;
......@@ -353,22 +325,7 @@ void output(void)
}
sprintf(statlinepos, "\n");
for (stat_clientp = &stat_clients; *stat_clientp; stat_clientp = nextp){
int ret;
ret = write((*stat_clientp)->fd, statline, strlen(statline));
if (ret <= 0) {
struct stat_client *tmp;
tmp = *stat_clientp;
close((*stat_clientp)->fd);
*stat_clientp = (*stat_clientp)->next;
free(tmp);
nextp = stat_clientp;
} else {
nextp = &(*stat_clientp)->next;
}
}
status_server_send(stat_srv, statline);
}
int main(int argc, char **argv)
......@@ -376,9 +333,8 @@ 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;
struct status_server *stat_srv;
time_t lastt = 0;
int fd_stat;
dt_model_init();
......@@ -446,11 +402,9 @@ int main(int argc, char **argv)
} else {
command_server_handler_raw_set(cmd_srv, handle_cmd);
}
fd_stat = tcp_listen(stat_port, 0, 100);
if (fd_stat < 0) {
stat_srv = status_server_create(stat_port, 0, 100);
if (!cmd_srv) {
printf("Could not open listen port for status\n");
} else {
ioctl(fd_stat, FIONBIO, &(int){ 1 });
}
weather = weather_create("Dwingeloo");
......@@ -580,11 +534,7 @@ int main(int argc, char **argv)
FD_ZERO(&fdset_rx);
if (fd_stat >= 0) {
FD_SET(fd_stat, &fdset_rx);
if (fd_stat >= high)
high = fd_stat + 1;
}
status_server_fdset_add(stat_srv, &fdset_rx, &high);
command_server_fdset_add(cmd_srv, &fdset_rx, &high);
if (trace_fd(traceval_el) < 0) {
......@@ -615,9 +565,6 @@ int main(int argc, char **argv)
select(high, &fdset_rx, NULL, NULL, &tv);
if (FD_ISSET(fd_stat, &fdset_rx)) {
new_stat_client(fd_stat);
}
if (trace_fd(traceval_az) > 0 &&
FD_ISSET(trace_fd(traceval_az), &fdset_rx)) {
trace_handle(traceval_az);
......@@ -626,9 +573,11 @@ int main(int argc, char **argv)
FD_ISSET(trace_fd(traceval_el), &fdset_rx)) {
trace_handle(traceval_el);
}
command_server_fdset_handle(cmd_srv, &fdset_rx);
status_server_fdset_handle(stat_srv, &fdset_rx);
output();
output(stat_srv);
}
}
......@@ -42,8 +42,6 @@
#include "setpoint.h"
#include "tcp_connect.h"
#include "tcp_listen.h"
#include "aalib.h"
#include "weather.h"
......@@ -52,6 +50,7 @@
#include "dt_port_numbers.h"
#include "command_server.h"
#include "status_server.h"
char *command_host = "localhost";
int command_port = CONSOLE_COMMAND_PORT;
......@@ -84,36 +83,6 @@ struct ln_equ_posn object_aber;
struct ln_hms track_hms;
struct ln_dms track_dms;
struct stat_client {
struct stat_client *next;
int fd;
};
struct stat_client *stat_clients = NULL;
void new_stat_client(int fd_stat)
{
struct stat_client *new_stat;
int fd;
fd = tcp_accept(fd_stat);
if (fd < 0)
return;
ioctl(fd, FIONBIO, &(int){ 1 });
new_stat = malloc(sizeof(struct stat_client));
if (!new_stat) {
close(fd);
return;
}
new_stat->fd = fd;
new_stat->next = stat_clients;
stat_clients = new_stat;
}
static int handle_cmd(char *name, char *val)
{
......@@ -134,11 +103,10 @@ static int handle_cmd(char *name, char *val)
}
void output(void)
void output(struct status_server *stat_srv)
{
static time_t last = 0;
time_t now;
struct stat_client **stat_clientp, **nextp;
char statline[800];
int ret, i;
char *statlinepos;
......@@ -163,22 +131,7 @@ void output(void)
}
sprintf(statlinepos, "\n");
for (stat_clientp = &stat_clients; *stat_clientp; stat_clientp = nextp){
int ret;
ret = write((*stat_clientp)->fd, statline, strlen(statline));
if (ret <= 0) {
struct stat_client *tmp;
tmp = *stat_clientp;
close((*stat_clientp)->fd);
*stat_clientp = (*stat_clientp)->next;
free(tmp);
nextp = stat_clientp;
} else {
nextp = &(*stat_clientp)->next;
}
}
status_server_send(stat_srv, statline);
}
......@@ -189,8 +142,8 @@ 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;
struct status_server *stat_srv;
struct weather *weather;
int fd_stat;
time_t lastt = 0;
......@@ -224,11 +177,9 @@ int main(int argc, char **argv)
} else {
command_server_handler_set(cmd_srv, handle_cmd);
}
fd_stat = tcp_listen(stat_port, 0, 100);
if (fd_stat < 0) {
stat_srv = status_server_create(stat_port, 0, 100);
if (!cmd_srv) {
printf("Could not open listen port for status\n");
} else {
ioctl(fd_stat, FIONBIO, &(int){ 1 });
}
weather = weather_create("Dwingeloo");
......@@ -288,26 +239,18 @@ int main(int argc, char **argv)
FD_ZERO(&fdset_rx);
if (fd_stat >= 0) {
FD_SET(fd_stat, &fdset_rx);
if (fd_stat >= high)
high = fd_stat + 1;
}
command_server_fdset_add(cmd_srv, &fdset_rx, &high);
status_server_fdset_add(stat_srv, &fdset_rx, &high);
tv.tv_sec = 1;
tv.tv_usec = 0;
select(high, &fdset_rx, NULL, NULL, &tv);
if (FD_ISSET(fd_stat, &fdset_rx)) {
new_stat_client(fd_stat);
}
command_server_fdset_handle(cmd_srv, &fdset_rx);
status_server_fdset_handle(stat_srv, &fdset_rx);
output();
output(stat_srv);
}
}