mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-04-07 11:08:36 +00:00
Improve html debug statistics
- shift radio rssi onto interace structure - track packets sent received - create html output for interface stats - create html output for link state routing stats
This commit is contained in:
parent
ae25091fab
commit
08b44e96ed
17
mavlink.c
17
mavlink.c
@ -204,11 +204,6 @@ int mavlink_heartbeat(unsigned char *frame,int *outlen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern unsigned long long last_rssi_time;
|
||||
extern int last_radio_rssi;
|
||||
extern int last_radio_temperature;
|
||||
extern int last_radio_rxpackets;
|
||||
|
||||
static int parse_heartbeat(struct overlay_interface *interface, const unsigned char *payload)
|
||||
{
|
||||
if (payload[0]==0xFE
|
||||
@ -218,9 +213,8 @@ static int parse_heartbeat(struct overlay_interface *interface, const unsigned c
|
||||
&& payload[5]==MAVLINK_MSG_ID_RADIO){
|
||||
|
||||
// we can assume that radio status packets arrive without corruption
|
||||
last_radio_rssi=(1.0*payload[10]-payload[13])/1.9;
|
||||
last_radio_temperature=-999; // doesn't get reported
|
||||
last_radio_rxpackets=-999; // doesn't get reported
|
||||
interface->radio_rssi=(1.0*payload[10]-payload[13])/1.9;
|
||||
interface->remote_rssi=(1.0*payload[11] - payload[14])/1.9;
|
||||
int free_space = payload[12];
|
||||
int free_bytes = (free_space * 1280) / 100 - 30;
|
||||
interface->remaining_space = free_bytes;
|
||||
@ -228,12 +222,11 @@ static int parse_heartbeat(struct overlay_interface *interface, const unsigned c
|
||||
interface->next_tx_allowed = gettime_ms();
|
||||
if (free_bytes>720)
|
||||
interface->next_heartbeat=gettime_ms()+1000;
|
||||
if (config.debug.mavlink||gettime_ms()-last_rssi_time>30000) {
|
||||
if (config.debug.packetradio) {
|
||||
INFOF("Link budget = %+ddB, remote link budget = %+ddB, buffer space = %d%% (approx %d)",
|
||||
last_radio_rssi,
|
||||
(int)((1.0*payload[11] - payload[14])/1.9),
|
||||
interface->radio_rssi,
|
||||
interface->remote_rssi,
|
||||
free_space, free_bytes);
|
||||
last_rssi_time=gettime_ms();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -63,6 +63,54 @@ overlay_interface_close(overlay_interface *interface){
|
||||
interface->state=INTERFACE_STATE_DOWN;
|
||||
}
|
||||
|
||||
void interface_state_html(struct strbuf *b, struct overlay_interface *interface)
|
||||
{
|
||||
switch(interface->state){
|
||||
case INTERFACE_STATE_UP:
|
||||
strbuf_sprintf(b, "Interface %s is Up<br>", interface->name);
|
||||
break;
|
||||
default:
|
||||
strbuf_puts(b, "Interface Down");
|
||||
return;
|
||||
}
|
||||
switch(interface->type){
|
||||
case OVERLAY_INTERFACE_PACKETRADIO:
|
||||
strbuf_puts(b, "Type: Packet Radio<br>");
|
||||
strbuf_sprintf(b, "RSSI: %ddB<br>",interface->radio_rssi);
|
||||
strbuf_sprintf(b, "Remote RSSI: %ddB<br>",interface->remote_rssi);
|
||||
break;
|
||||
case OVERLAY_INTERFACE_ETHERNET:
|
||||
strbuf_puts(b, "Type: Ethernet<br>");
|
||||
break;
|
||||
case OVERLAY_INTERFACE_WIFI:
|
||||
strbuf_puts(b, "Type: Wifi<br>");
|
||||
break;
|
||||
default:
|
||||
case OVERLAY_INTERFACE_UNKNOWN:
|
||||
strbuf_puts(b, "Type: Unknown<br>");
|
||||
}
|
||||
switch(interface->socket_type){
|
||||
case SOCK_STREAM:
|
||||
strbuf_puts(b, "Socket: Stream<br>");
|
||||
break;
|
||||
case SOCK_DGRAM:
|
||||
{
|
||||
char addrtxt[INET_ADDRSTRLEN];
|
||||
strbuf_puts(b, "Socket: DGram<br>");
|
||||
if (inet_ntop(AF_INET, (const void *)&interface->address.sin_addr, addrtxt, INET_ADDRSTRLEN))
|
||||
strbuf_sprintf(b, "Address: %s:%d<br>", addrtxt, ntohs(interface->address.sin_port));
|
||||
if (inet_ntop(AF_INET, (const void *)&interface->destination->address.sin_addr, addrtxt, INET_ADDRSTRLEN))
|
||||
strbuf_sprintf(b, "Broadcast Address: %s:%d<br>", addrtxt, ntohs(interface->destination->address.sin_port));
|
||||
}
|
||||
break;
|
||||
case SOCK_FILE:
|
||||
strbuf_puts(b, "Socket: File<br>");
|
||||
break;
|
||||
}
|
||||
strbuf_sprintf(b, "TX: %d<br>", interface->tx_count);
|
||||
strbuf_sprintf(b, "RX: %d<br>", interface->recv_count);
|
||||
}
|
||||
|
||||
// create a socket with options common to all our UDP sockets
|
||||
static int
|
||||
overlay_bind_socket(const struct sockaddr *addr, size_t addr_size, char *interface_name){
|
||||
@ -230,7 +278,6 @@ overlay_interface_read_any(struct sched_ent *alarm){
|
||||
DEBUGF("Could not find matching interface for packet received from %s", inet_ntoa(src));
|
||||
return;
|
||||
}
|
||||
|
||||
packetOkOverlay(interface, packet, plen, recvttl, &src_addr, addrlen);
|
||||
}
|
||||
if (alarm->poll.revents & (POLLHUP | POLLERR)) {
|
||||
@ -374,6 +421,8 @@ overlay_interface_init(const char *name, struct in_addr src_addr, struct in_addr
|
||||
interface->state=INTERFACE_STATE_DOWN;
|
||||
interface->alarm.poll.fd=0;
|
||||
interface->debug = ifconfig->debug;
|
||||
interface->tx_count=0;
|
||||
interface->recv_count=0;
|
||||
|
||||
// How often do we announce ourselves on this interface?
|
||||
int tick_ms=-1;
|
||||
@ -655,8 +704,6 @@ static void interface_read_stream(struct overlay_interface *interface){
|
||||
OUT();
|
||||
return;
|
||||
}
|
||||
if (config.debug.packetradio)
|
||||
dump("read bytes", buffer, nread);
|
||||
struct slip_decode_state *state=&interface->slip_decode_state;
|
||||
|
||||
int i;
|
||||
@ -681,14 +728,12 @@ static void write_stream_buffer(overlay_interface *interface){
|
||||
// Queue a hearbeat now
|
||||
mavlink_heartbeat(interface->txbuffer,&interface->tx_bytes_pending);
|
||||
if (config.debug.packetradio)
|
||||
DEBUGF("Built %d byte heartbeat", interface->tx_bytes_pending);
|
||||
DEBUGF("Sending heartbeat");
|
||||
interface->next_heartbeat = now+1000;
|
||||
}else if(interface->tx_packet && interface->remaining_space >= 256 + 8+9){
|
||||
// prepare a new link layer packet in txbuffer
|
||||
if (mavlink_encode_packet(interface))
|
||||
break;
|
||||
if (config.debug.packetradio)
|
||||
DEBUGF("Built %d byte payload from packet (%d)", interface->tx_bytes_pending, interface->remaining_space);
|
||||
if (interface->remaining_space - interface->tx_bytes_pending < 256 + 8+9)
|
||||
interface->next_heartbeat = now;
|
||||
}
|
||||
@ -703,8 +748,6 @@ static void write_stream_buffer(overlay_interface *interface){
|
||||
if (bytes<=0)
|
||||
break;
|
||||
|
||||
if (config.debug.packetradio)
|
||||
DEBUGF("Trying to write %d bytes of %d%s", bytes, interface->tx_bytes_pending, interface->tx_packet?", pending packet":"");
|
||||
int written=write(interface->alarm.poll.fd, interface->txbuffer, bytes);
|
||||
if (written<=0){
|
||||
DEBUGF("Blocking for POLLOUT");
|
||||
@ -720,8 +763,6 @@ static void write_stream_buffer(overlay_interface *interface){
|
||||
interface->tx_bytes_pending);
|
||||
DEBUGF("Partial write, %d left", interface->tx_bytes_pending);
|
||||
}
|
||||
if (config.debug.packetradio)
|
||||
DEBUGF("Wrote %d bytes (%d left pending, %d remains)", written, interface->tx_bytes_pending, interface->remaining_space);
|
||||
}
|
||||
|
||||
if (total_written>0){
|
||||
@ -867,6 +908,8 @@ int overlay_broadcast_ensemble(struct network_destination *destination, struct o
|
||||
if (interface->debug)
|
||||
DEBUGF("Sending on %s, len %d: %s", interface->name, len, alloca_tohex(bytes, len>64?64:len));
|
||||
|
||||
interface->tx_count++;
|
||||
|
||||
switch(interface->socket_type){
|
||||
case SOCK_STREAM:
|
||||
{
|
||||
|
@ -413,6 +413,7 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
|
||||
RETURN(ret);
|
||||
}
|
||||
f.sender_interface = context.sender_interface;
|
||||
interface->recv_count++;
|
||||
|
||||
while(ob_remaining(b)>0){
|
||||
context.invalid_addresses=0;
|
||||
|
113
rhizome_http.c
113
rhizome_http.c
@ -543,58 +543,71 @@ int rhizome_server_parse_http_request(rhizome_http_request *r)
|
||||
if (strcmp(path, "/")==0) {
|
||||
r->request_type = RHIZOME_HTTP_REQUEST_FROMBUFFER;
|
||||
char temp[8192];
|
||||
snprintf(temp,8192,
|
||||
"<html><body>"
|
||||
strbuf b=strbuf_local(temp, sizeof(temp));
|
||||
strbuf_sprintf(b, "<html><head><meta http-equiv=\"refresh\" content=\"5\" ></head><body>"
|
||||
"<h1>Hello, I'm %s*</h1><br>"
|
||||
"<a href=\"/rssi\">rssi</a><br>"
|
||||
"<a href=\"/rhizome/status\">rhizome status</a><br>"
|
||||
"<a href=\"/rhizome/files\">rhizome files</a><br>"
|
||||
"<a href=\"/rhizome/bars\">rhizome bars</a><br>"
|
||||
"</body></html>",
|
||||
"Interfaces;<br>",
|
||||
alloca_tohex(my_subscriber->sid, 8));
|
||||
rhizome_server_simple_http_response(r, 200, temp);
|
||||
int i;
|
||||
for (i=0;i<OVERLAY_MAX_INTERFACES;i++){
|
||||
if (overlay_interfaces[i].state==INTERFACE_STATE_UP)
|
||||
strbuf_sprintf(b, "<a href=\"/interface/%d\">%d: %s, TX: %d, RX: %d</a><br>",
|
||||
i, i, overlay_interfaces[i].name, overlay_interfaces[i].tx_count, overlay_interfaces[i].recv_count);
|
||||
}
|
||||
|
||||
strbuf_puts(b, "Neighbours;<br>");
|
||||
link_neighbour_short_status_html(b, "/neighbour");
|
||||
|
||||
if (is_rhizome_http_enabled()){
|
||||
strbuf_puts(b, "<a href=\"/rhizome/status\">Rhizome Status</a><br>");
|
||||
}
|
||||
strbuf_puts(b, "</body></html>");
|
||||
if (strbuf_overrun(b)){
|
||||
rhizome_server_simple_http_response(r, 500, "<html><h1>Buffer overflow</h1></html>\r\n");
|
||||
}else{
|
||||
rhizome_server_simple_http_response(r, 200, temp);
|
||||
}
|
||||
} else if (str_startswith(path, "/neighbour/", (const char **)&id)) {
|
||||
char buf[8*1024];
|
||||
strbuf b=strbuf_local(buf, sizeof buf);
|
||||
|
||||
sid_t neighbour_sid;
|
||||
if (str_to_sid_t(&neighbour_sid, id) == -1)
|
||||
rhizome_server_simple_http_response(r, 500, "<html><h1>Invalid subscriber id</h1></html>\r\n");
|
||||
else{
|
||||
struct subscriber *neighbour = find_subscriber(neighbour_sid.binary, sizeof(neighbour_sid.binary), 0);
|
||||
if (neighbour){
|
||||
strbuf_puts(b, "<html><head><meta http-equiv=\"refresh\" content=\"5\" ></head><body>");
|
||||
link_neighbour_status_html(b, neighbour);
|
||||
strbuf_puts(b, "</body></html>");
|
||||
if (strbuf_overrun(b)){
|
||||
rhizome_server_simple_http_response(r, 500, "<html><h1>Buffer overflow</h1></html>\r\n");
|
||||
}else{
|
||||
rhizome_server_simple_http_response(r, 200, buf);
|
||||
}
|
||||
}else{
|
||||
rhizome_server_simple_http_response(r, 404, "<html><h1>Subscriber not known</h1></html>\r\n");
|
||||
}
|
||||
}
|
||||
} else if (str_startswith(path, "/interface/", (const char **)&id)) {
|
||||
char buf[8*1024];
|
||||
strbuf b=strbuf_local(buf, sizeof buf);
|
||||
int index=atoi(id);
|
||||
if (index>=0 && index<OVERLAY_MAX_INTERFACES){
|
||||
strbuf_puts(b, "<html><head><meta http-equiv=\"refresh\" content=\"5\" ></head><body>");
|
||||
interface_state_html(b, &overlay_interfaces[index]);
|
||||
strbuf_puts(b, "</body></html>");
|
||||
if (strbuf_overrun(b)){
|
||||
rhizome_server_simple_http_response(r, 500, "<html><h1>Buffer overflow</h1></html>\r\n");
|
||||
}else{
|
||||
rhizome_server_simple_http_response(r, 200, buf);
|
||||
}
|
||||
}else{
|
||||
rhizome_server_simple_http_response(r, 400, "<html><h1>Invalid interface id</h1></html>\r\n");
|
||||
}
|
||||
} else if (strcmp(path, "/favicon.ico") == 0) {
|
||||
r->request_type = RHIZOME_HTTP_REQUEST_FAVICON;
|
||||
rhizome_server_http_response_header(r, 200, "image/vnd.microsoft.icon", favicon_len);
|
||||
} else if (strcmp(path, "/rssi.csv") == 0) {
|
||||
r->request_type = RHIZOME_HTTP_REQUEST_FROMBUFFER;
|
||||
char temp[8192];
|
||||
snprintf(temp,8192,
|
||||
";%lld;%d;%d;%d;%d;%d;%s;%d;%d;%d;%d;%d\n",
|
||||
gettime_ms(),
|
||||
last_radio_rssi,last_radio_temperature,last_radio_rxpackets,
|
||||
(int)bundles_available,
|
||||
rhizome_active_fetch_count(),
|
||||
alloca_tohex(my_subscriber->sid, 8),
|
||||
rhizome_active_fetch_bytes_received(0),
|
||||
rhizome_active_fetch_bytes_received(1),
|
||||
rhizome_active_fetch_bytes_received(2),
|
||||
rhizome_active_fetch_bytes_received(3),
|
||||
rhizome_active_fetch_bytes_received(4)
|
||||
);
|
||||
rhizome_server_simple_http_response(r, 200, temp);
|
||||
} else if (strcmp(path, "/rssi") == 0) {
|
||||
r->request_type = RHIZOME_HTTP_REQUEST_FROMBUFFER;
|
||||
char temp[8192];
|
||||
snprintf(temp,8192,
|
||||
"<html><head><meta http-equiv=\"refresh\" content=\"5\" >"
|
||||
"</head><body><h1>Radio link margin = %+ddB (%d packets received)<br>"
|
||||
"Radio temperature = %d°C<br>"
|
||||
"SID: %s*<br>"
|
||||
"%d rhizome bundles in database<br>"
|
||||
"%d rhizome transfers in progress<br>(%d,%d,%d,%d,%d bytes)<br>"
|
||||
"</h1></body></html>\n",
|
||||
last_radio_rssi,last_radio_rxpackets,last_radio_temperature,
|
||||
alloca_tohex(my_subscriber->sid, 8),
|
||||
(int)bundles_available,
|
||||
rhizome_active_fetch_count(),
|
||||
rhizome_active_fetch_bytes_received(0),
|
||||
rhizome_active_fetch_bytes_received(1),
|
||||
rhizome_active_fetch_bytes_received(2),
|
||||
rhizome_active_fetch_bytes_received(3),
|
||||
rhizome_active_fetch_bytes_received(4)
|
||||
);
|
||||
rhizome_server_simple_http_response(r, 200, temp);
|
||||
} else if (is_rhizome_http_enabled()){
|
||||
if (strcmp(path, "/rhizome/groups") == 0) {
|
||||
/* Return the list of known groups */
|
||||
@ -606,7 +619,11 @@ int rhizome_server_parse_http_request(rhizome_http_request *r)
|
||||
strbuf_puts(&b, "<html><head><meta http-equiv=\"refresh\" content=\"5\" ></head><body>");
|
||||
rhizome_fetch_status_html(&b);
|
||||
strbuf_puts(&b, "</body></html>");
|
||||
rhizome_server_simple_http_response(r, 200, buf);
|
||||
if (strbuf_overrun(&b)){
|
||||
rhizome_server_simple_http_response(r, 500, "<html><h1>Buffer overflow</h1></html>\r\n");
|
||||
}else{
|
||||
rhizome_server_simple_http_response(r, 200, buf);
|
||||
}
|
||||
} else if (strcmp(path, "/rhizome/files") == 0) {
|
||||
/* Return the list of known files */
|
||||
rhizome_server_sql_query_http_response(r, "id", "files", "from files", 32, 1);
|
||||
|
69
route_link.c
69
route_link.c
@ -624,6 +624,75 @@ static void clean_neighbours(time_ms_t now)
|
||||
}
|
||||
}
|
||||
|
||||
static void link_status_html(struct strbuf *b, struct subscriber *n, struct link *link)
|
||||
{
|
||||
if (!link)
|
||||
return;
|
||||
link_status_html(b, n, link->_left);
|
||||
int best=0;
|
||||
if (link->receiver->next_hop==n)
|
||||
best=1;
|
||||
else if(link->receiver==n && n->reachable&REACHABLE_DIRECT)
|
||||
best=1;
|
||||
strbuf_sprintf(b, "%s* -%s H: %d, C: %d, via %s*<br>",
|
||||
alloca_tohex(link->receiver->sid,8),
|
||||
best?" *best*":"",
|
||||
link->hop_count, link->path_drop_rate,
|
||||
link->transmitter?alloca_tohex(link->transmitter->sid,8):"unreachable");
|
||||
link_status_html(b, n, link->_right);
|
||||
}
|
||||
|
||||
void link_neighbour_short_status_html(struct strbuf *b, const char *link_prefix)
|
||||
{
|
||||
struct neighbour *n = neighbours;
|
||||
if (!n)
|
||||
strbuf_puts(b, "No peers<br>");
|
||||
while(n){
|
||||
strbuf_sprintf(b, "<a href=\"%s/%s\">%s*</a>, seq=%d, mask=%08"PRIx64";<br>",
|
||||
link_prefix,
|
||||
alloca_tohex_sid(n->subscriber->sid),
|
||||
alloca_tohex(n->subscriber->sid,8),
|
||||
n->mdp_ack_sequence, n->mdp_ack_mask);
|
||||
n=n->_next;
|
||||
}
|
||||
}
|
||||
|
||||
void link_neighbour_status_html(struct strbuf *b, struct subscriber *neighbour)
|
||||
{
|
||||
time_ms_t now = gettime_ms();
|
||||
struct neighbour *n = neighbours;
|
||||
while(n){
|
||||
if (n->subscriber == neighbour){
|
||||
strbuf_sprintf(b, "Neighbour %s*;<br>", alloca_tohex(n->subscriber->sid,8));
|
||||
strbuf_sprintf(b, "Seq=%d, mask=%08"PRIx64"<br>", n->mdp_ack_sequence, n->mdp_ack_mask);
|
||||
struct link_in *link_in = n->links;
|
||||
while(link_in){
|
||||
strbuf_sprintf(b, "In: %s%s, seq=%d, mask=%08"PRIx64"<br>",
|
||||
link_in->interface->name,
|
||||
link_in == n->best_link?" *best":"",
|
||||
link_in->ack_sequence,
|
||||
link_in->ack_mask);
|
||||
link_in = link_in->_next;
|
||||
}
|
||||
struct link_out *link_out = n->out_links;
|
||||
while(link_out){
|
||||
if (link_out->timeout >= now){
|
||||
strbuf_sprintf(b, "Out: %s %s<br>",
|
||||
link_out->destination->interface->name,
|
||||
link_out->destination->unicast?"unicast":"broadcast");
|
||||
}
|
||||
link_out = link_out->_next;
|
||||
}
|
||||
strbuf_puts(b, "Links;<br>");
|
||||
link_status_html(b, n->subscriber, n->root);
|
||||
return;
|
||||
}
|
||||
n = n->_next;
|
||||
}
|
||||
strbuf_puts(b, "Not found<br>");
|
||||
}
|
||||
|
||||
|
||||
static int send_legacy_self_announce_ack(struct neighbour *neighbour, struct link_in *link, time_ms_t now){
|
||||
struct overlay_frame *frame=emalloc_zero(sizeof(struct overlay_frame));
|
||||
frame->type = OF_TYPE_SELFANNOUNCE_ACK;
|
||||
|
12
serval.h
12
serval.h
@ -472,6 +472,9 @@ typedef struct overlay_interface {
|
||||
|
||||
int recv_offset; /* file offset */
|
||||
|
||||
int recv_count;
|
||||
int tx_count;
|
||||
|
||||
// stream socket tx state;
|
||||
struct overlay_buffer *tx_packet;
|
||||
unsigned char txbuffer[OVERLAY_INTERFACE_RX_BUFFER_SIZE];
|
||||
@ -483,7 +486,8 @@ typedef struct overlay_interface {
|
||||
int32_t remaining_space;
|
||||
time_ms_t next_heartbeat;
|
||||
int mavlink_seq;
|
||||
|
||||
int radio_rssi;
|
||||
int remote_rssi;
|
||||
|
||||
struct slip_decode_state slip_decode_state;
|
||||
|
||||
@ -723,6 +727,7 @@ overlay_interface * overlay_interface_find(struct in_addr addr, int return_defau
|
||||
overlay_interface * overlay_interface_find_name(const char *name);
|
||||
int overlay_interface_compare(overlay_interface *one, overlay_interface *two);
|
||||
int overlay_broadcast_ensemble(struct network_destination *destination, struct overlay_buffer *buffer);
|
||||
void interface_state_html(struct strbuf *b, struct overlay_interface *interface);
|
||||
|
||||
int directory_registration();
|
||||
int directory_service_init();
|
||||
@ -877,9 +882,6 @@ int slip_decode(struct slip_decode_state *state);
|
||||
int upper7_decode(struct slip_decode_state *state,unsigned char byte);
|
||||
uint32_t Crc32_ComputeBuf( uint32_t inCrc32, const void *buf,
|
||||
size_t bufLen );
|
||||
extern int last_radio_rssi;
|
||||
extern int last_radio_temperature;
|
||||
extern int last_radio_rxpackets;
|
||||
int rhizome_active_fetch_count();
|
||||
int rhizome_active_fetch_bytes_received(int q);
|
||||
extern int64_t bundles_available;
|
||||
@ -897,6 +899,8 @@ int link_state_ack_soon(struct subscriber *sender);
|
||||
int link_state_should_forward_broadcast(struct subscriber *transmitter);
|
||||
int link_unicast_ack(struct subscriber *subscriber, struct overlay_interface *interface, struct sockaddr_in addr);
|
||||
int link_add_destinations(struct overlay_frame *frame);
|
||||
void link_neighbour_short_status_html(struct strbuf *b, const char *link_prefix);
|
||||
void link_neighbour_status_html(struct strbuf *b, struct subscriber *neighbour);
|
||||
|
||||
int generate_nonce(unsigned char *nonce,int bytes);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user