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

New console_httpd webserver.

Some small fixes in lex code.
parent 3bcbbbf3
......@@ -338,7 +338,7 @@ int trace_packet_type_set(struct trace_pkt *pkt, enum trace_value_type type)
return 0;
}
bool trace_fd_set(struct trace *trace, fd_set *set, int *high)
bool trace_check(struct trace *trace)
{
if (trace->fd < 0) {
if (!trace->recover)
......@@ -375,6 +375,14 @@ bool trace_fd_set(struct trace *trace, fd_set *set, int *high)
}
log_send(LOG_T_DEBUG, "Reconnected trace");
}
return true;
}
bool trace_fd_set(struct trace *trace, fd_set *set, int *high)
{
if (!trace_check(trace))
return false;
FD_SET(trace->fd, set);
......@@ -384,140 +392,144 @@ bool trace_fd_set(struct trace *trace, fd_set *set, int *high)
return true;
}
int trace_handle(struct trace *trace, fd_set *set)
int trace_handle_recv(struct trace *trace)
{
if (FD_ISSET(trace->fd, set)) {
while (trace_fd_read(trace)) {
struct trace_pkt *pkt;
pkt = trace_packet_get(trace);
if (!pkt)
while (trace_fd_read(trace)) {
struct trace_pkt *pkt;
pkt = trace_packet_get(trace);
if (!pkt)
break;
switch (pkt->data[0]) {
case TRACE_PTYPE_INTERVAL: {
struct trace_ptype_interval *pinterval;
enum trace_interval_type type;
pinterval = (void*)pkt->data + 1;
trace->interval.tv_sec = be64toh(pinterval->sec);
trace->interval.tv_nsec = be32toh(pinterval->nsec);
type = pinterval->type;
trace->interval_type = type;
if (trace->handler_interval) {
trace->handler_interval(trace, &trace->interval, type);
}
break;
}
case TRACE_PTYPE_TIMESTAMP: {
struct trace_ptype_timestamp *ptimestamp;
ptimestamp = (void*)pkt->data + 1;
trace->timestamp.tv_sec = be64toh(ptimestamp->sec);
trace->timestamp.tv_nsec = be32toh(ptimestamp->nsec);
if (trace->handler_timestamp) {
trace->handler_timestamp(trace, &trace->timestamp);
}
break;
switch (pkt->data[0]) {
case TRACE_PTYPE_INTERVAL: {
struct trace_ptype_interval *pinterval;
enum trace_interval_type type;
}
case TRACE_PTYPE_LIST: {
unsigned char *listentry;
size_t pos = 1;
while (pos < pkt->len) {
char *name;
enum trace_value_type type;
char *unit;
pinterval = (void*)pkt->data + 1;
listentry = pkt->data + pos;
trace->interval.tv_sec = be64toh(pinterval->sec);
trace->interval.tv_nsec = be32toh(pinterval->nsec);
type = pinterval->type;
trace->interval_type = type;
name = (char *)listentry;
type = listentry[strlen(name) + 1];
unit = (char *)listentry+strlen(name) + 2;
if (trace->handler_interval) {
trace->handler_interval(trace, &trace->interval, type);
if (trace->handler_list_entry) {
trace->handler_list_entry(trace,
name, type, unit);
}
break;
pos += strlen(name) + strlen(unit) + 3;
}
case TRACE_PTYPE_TIMESTAMP: {
struct trace_ptype_timestamp *ptimestamp;
ptimestamp = (void*)pkt->data + 1;
trace->timestamp.tv_sec = be64toh(ptimestamp->sec);
trace->timestamp.tv_nsec = be32toh(ptimestamp->nsec);
if (trace->handler_timestamp) {
trace->handler_timestamp(trace, &trace->timestamp);
}
break;
trace->list_received = true;
break;
}
case TRACE_PTYPE_VALUE_TYPE: {
struct trace_ptype_value_type *vt;
enum trace_value_type type;
vt = (void*)pkt->data + 1;
type = vt->type;
trace->type = type;
trace->type_set = type;
if (trace->handler_type) {
trace->handler_type(trace, type);
}
case TRACE_PTYPE_LIST: {
unsigned char *listentry;
size_t pos = 1;
while (pos < pkt->len) {
char *name;
enum trace_value_type type;
char *unit;
listentry = pkt->data + pos;
name = (char *)listentry;
type = listentry[strlen(name) + 1];
unit = (char *)listentry+strlen(name) + 2;
if (trace->handler_list_entry) {
trace->handler_list_entry(trace,
name, type, unit);
}
pos += strlen(name) + strlen(unit) + 3;
}
trace->list_received = true;
break;
break;
}
case TRACE_PTYPE_NAME: {
char *name;
name = (void*)pkt->data + 1;
trace->name_set = true;
trace->name = strdup(name);
if (trace->handler_name) {
trace->handler_name(trace, name);
}
case TRACE_PTYPE_VALUE_TYPE: {
struct trace_ptype_value_type *vt;
enum trace_value_type type;
vt = (void*)pkt->data + 1;
type = vt->type;
trace->type = type;
trace->type_set = type;
if (trace->handler_type) {
trace->handler_type(trace, type);
break;
}
case TRACE_PTYPE_DATA: {
size_t pos = 1;
struct trace_ptype_value *v;
while (pos < pkt->len) {
v = (void *)pkt->data + pos;
switch (trace->type) {
case TRACE_VALUE_TYPE_FLOAT:
case TRACE_VALUE_TYPE_UINT32:
case TRACE_VALUE_TYPE_SINT32:
trace->value.value.u32 = be32toh(v->u.u32);
pos+=4;
break;
case TRACE_VALUE_TYPE_UINT16:
case TRACE_VALUE_TYPE_SINT16:
trace->value.value.u16 = be32toh(v->u.u16);
pos+=2;
break;
case TRACE_VALUE_TYPE_BOOL:
case TRACE_VALUE_TYPE_UINT8:
case TRACE_VALUE_TYPE_SINT8:
trace->value.value.u8 = v->u.u8;
pos++;
break;
}
break;
}
case TRACE_PTYPE_NAME: {
char *name;
name = (void*)pkt->data + 1;
trace->name_set = true;
trace->name = strdup(name);
if (trace->handler_name) {
trace->handler_name(trace, name);
if (timespec_older(&trace->value.t, &trace->timestamp)) {
trace->value.t = trace->timestamp;
} else {
timespec_add(&trace->value.t, &trace->interval);
}
break;
}
case TRACE_PTYPE_DATA: {
size_t pos = 1;
struct trace_ptype_value *v;
while (pos < pkt->len) {
v = (void *)pkt->data + pos;
switch (trace->type) {
case TRACE_VALUE_TYPE_FLOAT:
case TRACE_VALUE_TYPE_UINT32:
case TRACE_VALUE_TYPE_SINT32:
trace->value.value.u32 = be32toh(v->u.u32);
pos+=4;
break;
case TRACE_VALUE_TYPE_UINT16:
case TRACE_VALUE_TYPE_SINT16:
trace->value.value.u16 = be32toh(v->u.u16);
pos+=2;
break;
case TRACE_VALUE_TYPE_BOOL:
case TRACE_VALUE_TYPE_UINT8:
case TRACE_VALUE_TYPE_SINT8:
trace->value.value.u8 = v->u.u8;
pos++;
break;
}
if (timespec_older(&trace->value.t, &trace->timestamp)) {
trace->value.t = trace->timestamp;
} else {
timespec_add(&trace->value.t, &trace->interval);
}
trace->value_set = true;
if (trace->handler_value) {
trace->handler_value(trace, &trace->value);
}
trace->value_set = true;
if (trace->handler_value) {
trace->handler_value(trace, &trace->value);
}
break;
}
break;
}
trace_packet_put(pkt);
}
return 0;
trace_packet_put(pkt);
}
return 0;
}
int trace_handle(struct trace *trace, fd_set *set)
{
if (!set || FD_ISSET(trace->fd, set)) {
trace_handle_recv(trace);
}
return 0;
}
......
......@@ -170,6 +170,7 @@ int trace_packet_name_set(struct trace_pkt *pkt, char *name);
int trace_packet_type_set(struct trace_pkt *pkt, enum trace_value_type type);
int trace_packet_value_add(struct trace_pkt *pkt, struct trace_value *value, enum trace_value_type type);
bool trace_check(struct trace *trace);
bool trace_fd_set(struct trace *trace, fd_set *set, int *high);
int trace_handle(struct trace *trace, fd_set *set);
......
/*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2013
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2013, 2014
Copyright Stichting C.A. Muller Radioastronomiestation, 2013
This program is free software: you can redistribute it and/or modify
......@@ -25,6 +25,8 @@
static char *controller_host = "localhost";
static char *console_host = "localhost";
static char *log_path = "/var/log/dt/";
static char *htdocs_path = "/var/www/htdocs/";
static unsigned short htdocs_port = 80;
static bool init_done = false;
static int load_config(void)
......@@ -55,20 +57,30 @@ static int load_config(void)
for (i = 0; i < groups_nr; i++) {
if (!strcmp(groups[i], "controller")) {
if (g_key_file_has_key(keyfile, groups[i], "host", NULL)) {
controller_host =
g_key_file_get_string(keyfile, groups[i], "host", NULL);
controller_host = strdup(
g_key_file_get_string(keyfile, groups[i], "host", NULL));
}
}
if (!strcmp(groups[i], "console")) {
if (g_key_file_has_key(keyfile, groups[i], "host", NULL)) {
console_host =
g_key_file_get_string(keyfile, groups[i], "host", NULL);
console_host = strdup(
g_key_file_get_string(keyfile, groups[i], "host", NULL));
}
}
if (!strcmp(groups[i], "log")) {
if (g_key_file_has_key(keyfile, groups[i], "path", NULL)) {
log_path =
g_key_file_get_string(keyfile, groups[i], "path", NULL);
log_path = strdup(
g_key_file_get_string(keyfile, groups[i], "path", NULL));
}
}
if (!strcmp(groups[i], "htdocs")) {
if (g_key_file_has_key(keyfile, groups[i], "path", NULL)) {
htdocs_path = strdup(
g_key_file_get_string(keyfile, groups[i], "path", NULL));
}
if (g_key_file_has_key(keyfile, groups[i], "port", NULL)) {
htdocs_port =
g_key_file_get_integer(keyfile, groups[i], "port", NULL);
}
}
}
......@@ -107,3 +119,18 @@ char *dt_host_log_path(void)
return log_path;
}
char *dt_host_htdocs_path(void)
{
if (!init_done)
load_config();
return htdocs_path;
}
unsigned short dt_host_htdocs_port(void)
{
if (!init_done)
load_config();
return htdocs_port;
}
/*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2013
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2013, 2014
Copyright Stichting C.A. Muller Radioastronomiestation, 2013
This program is free software: you can redistribute it and/or modify
......@@ -23,5 +23,7 @@
char *dt_host_console(void);
char *dt_host_controller(void);
char *dt_host_log_path(void);
char *dt_host_htdocs_path(void);
unsigned short dt_host_htdocs_port(void);
#endif /* _INCLUDE_DT_HOST_H_ */
......@@ -2,6 +2,7 @@ await_controller
command_shell
console_azel
console_dt_model
console_httpd
console_httpline
console_httptrace
console_idle
......
......@@ -25,6 +25,8 @@ CONSOLE_TARGETS += $(DIR)/console_weather
CONSOLE_TARGETS += $(DIR)/console_dt_model
CONSOLE_TARGETS += $(DIR)/await_controller
CONSOLE_TARGETS += $(DIR)/console_sattracker
CONSOLE_TARGETS += $(DIR)/console_httpd
#mod_websocket_dt/mod_websocket_dt.so
......@@ -138,6 +140,12 @@ $(DIR)/console_sattracker: libcommand.la libpredict.la libnova.la
$(DIR)/console_sattracker: $(DIR)/console_sattracker.o
CONSOLE_SRCS += $(DIR)/console_sattracker.c
$(DIR)/console_httpd.o: CFLAGS += -Wall -O0 -g
$(DIR)/console_httpd_LDFLAGS += -llog -ltrace -lcommand -lwebsockets -lmagic
$(DIR)/console_httpd: liblog.la
$(DIR)/console_httpd: $(DIR)/console_httpd.o
CONSOLE_SRCS += $(DIR)/console_httpd.c
SRCS += $(CONSOLE_SRCS)
TARGETS += $(CONSOLE_TARGETS)
......
/*
Copyright Jeroen Vreeken (jeroen@vreeken.net), 2014
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/>.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <poll.h>
#include <errno.h>
#include <time.h>
#include <magic.h>
#include <libwebsockets.h>
#include <sys/ioctl.h>
#include <dt_port_numbers.h>
#include <utils/tcp_connect.h>
#include <utils/dt_host.h>
#include <trace/trace.h>
#include <command/command.h>
magic_t magic;
#define MAX_POLL_ELEMENTS 256
struct pollfd pollfds[MAX_POLL_ELEMENTS];
int count_pollfds = 0;
static int poll_add(int fd, short events)
{
if (count_pollfds >= MAX_POLL_ELEMENTS)
return -1;
pollfds[count_pollfds].fd = fd;
pollfds[count_pollfds].events = events;
pollfds[count_pollfds].revents = 0;
count_pollfds++;
return 0;
}
static void poll_remove(int fd)
{
int n;
for (n = 0; n < count_pollfds; n++)
if (pollfds[n].fd == fd) {
while (n < count_pollfds) {
pollfds[n] = pollfds[n + 1];
n++;
}
count_pollfds--;
}
}
static void poll_set(int fd, short events)
{
int n;
for (n = 0; n < count_pollfds; n++)
if (pollfds[n].fd == fd)
pollfds[n].events = events;
}
#define LINEBUF_SIZE 8192
struct status {
char *ident;
struct libwebsocket *wsi;
int fd;
char *host;
int port;
unsigned char linebuf[LINEBUF_SIZE];
int pos;
char pre[LWS_SEND_BUFFER_PRE_PADDING];
char msg[LINEBUF_SIZE * 2];
char post[LWS_SEND_BUFFER_POST_PADDING];
struct status *next;
};
struct status *status_list;
static void start_status(struct libwebsocket *wsi, char *ident)
{
struct status *status = calloc(sizeof(struct status), 1);
char *host;
int port = -1;
int fd = -1;
printf("new status\n");
if (!status)
return;
host = dt_host_console();
if (!strcmp(ident, "sat"))
port = CONSOLE_SAT_STAT_PORT;
else if (!strcmp(ident, "sun"))
port = CONSOLE_SUN_STAT_PORT;
else if (!strcmp(ident, "moon"))
port = CONSOLE_MOON_STAT_PORT;
else if (!strcmp(ident, "auth"))
port = CONSOLE_STATUS_PORT;
else if (!strcmp(ident, "j2000"))
port = CONSOLE_J2000_POS_PORT;
else if (!strcmp(ident, "log"))
port = CONSOLE_LOG_PORT;
else if (!strcmp(ident, "weather"))
port = CONSOLE_WEATHER_PORT;
else if (!strcmp(ident, "dt_model"))
port = CONSOLE_DT_MODEL_STAT_PORT;
fd = tcp_connect(host, port);
if (fd >= 0)
poll_add(fd, POLLIN | POLLERR);
status->wsi = wsi;
status->ident = ident;
status->fd = fd;
status->port = port;
status->host = host;
status->next = status_list;
status_list = status;
}
static int status_handle(struct status *status)
{
int r;
unsigned char *linebuf = status->linebuf;
int pos = status->pos;
int fd = status->fd;
char *ident = status->ident;
r = read(fd, linebuf + pos, LINEBUF_SIZE - 1 - pos);
if (r > 0) {
int i;
for (i = 0; i <r; i++) {
if (linebuf[pos + i] == '\n') {
char *msg = status->msg;
linebuf[pos + i] = 0;
sprintf(msg,
"status %s %s\n",
ident, linebuf);
if (!lws_send_pipe_choked(status->wsi))
libwebsocket_write (status->wsi,
(unsigned char*)msg, strlen(msg),
LWS_WRITE_TEXT);
if (r - i - 1 > 0)
memmove(
linebuf,
linebuf + pos + i + 1,
r - i - 1);
pos -= pos + i +1;
}
}
pos += r;
} else if (errno != EAGAIN) {
close(fd);
fd = -1;
poll_remove(fd);
}
status->pos = pos;
status->fd = fd;
return 0;
}
static int status_reconnect(struct status *status)
{
int fd;
printf("reconnect\n");
fd = tcp_connect(status->host, status->port);
if (fd >= 0) {
poll_add(fd, POLLIN | POLLERR);
status->pos = 0;
}
status->fd = fd;
return 0;
}
static int status_remove(struct libwebsocket *wsi)
{
struct status **status;