Implement AGW 'Y' command. More error checking.

This commit is contained in:
wb2osz 2017-08-27 21:16:24 -04:00
parent 3a496aa566
commit eb0da22067
3 changed files with 89 additions and 14 deletions

View File

@ -1,7 +1,7 @@
//
// This file is part of Dire Wolf, an amateur radio packet TNC.
//
// Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016 John Langner, WB2OSZ
// Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016, 2017 John Langner, WB2OSZ
//
// 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
@ -59,6 +59,8 @@
*
* 'y' Ask Outstanding frames waiting on a Port (new in 1.2)
*
* 'Y' How many frames waiting for transmit for a particular station (new in 1.5)
*
* 'C' Connect, Start an AX.25 Connection (new in 1.4)
*
* 'v' Connect VIA, Start an AX.25 circuit thru digipeaters (new in 1.4)
@ -92,6 +94,8 @@
*
* 'y' Outstanding frames waiting on a Port (new in 1.2)
*
* 'Y' How many frames waiting for transmit for a particular station (new in 1.5)
*
* 'C' AX.25 Connection Received (new in 1.4)
*
* 'D' Connected AX.25 Data (new in 1.4)
@ -1259,16 +1263,20 @@ static THREAD_F cmd_listen_thread (void *arg)
}
/*
* Take some precautions to guard against bad data
* which could cause problems later.
* Take some precautions to guard against bad data which could cause problems later.
*/
if (cmd.hdr.portx < 0 || cmd.hdr.portx >= MAX_CHANS) {
text_color_set(DW_COLOR_ERROR);
dw_printf ("\nInvalid port number, %d, in command '%c', from AGW client application %d.\n",
cmd.hdr.portx, cmd.hdr.datakind, client);
cmd.hdr.portx = 0; // avoid subscript out of bounds, try to keep going.
}
/*
* Call to/from must not exceeed 9 characters.
* Call to/from fields are 10 bytes but contents must not exceeed 9 characters.
* It's not guaranteed that unused bytes will contain 0 so we
* don't issue error message in this case.
*/
cmd.hdr.call_from[sizeof(cmd.hdr.call_from)-1] = '\0';
cmd.hdr.call_to[sizeof(cmd.hdr.call_to)-1] = '\0';
@ -1455,6 +1463,7 @@ static THREAD_F cmd_listen_thread (void *arg)
// YAAC asks for this.
// Fake it to keep application happy.
// TODO: Supply real values instead of just faking it.
reply.on_air_baud_rate = 0;
reply.traffic_level = 1;
@ -1842,6 +1851,7 @@ static THREAD_F cmd_listen_thread (void *arg)
case 'y': /* Ask Outstanding frames waiting on a Port */
/* Number of frames sitting in transmit queue for specified channel. */
{
struct {
struct agwpe_s hdr;
@ -1856,7 +1866,40 @@ static THREAD_F cmd_listen_thread (void *arg)
int n = 0;
if (cmd.hdr.portx >= 0 && cmd.hdr.portx < MAX_CHANS) {
n = tq_count (cmd.hdr.portx, TQ_PRIO_0_HI) + tq_count (cmd.hdr.portx, TQ_PRIO_1_LO);
n = tq_count (cmd.hdr.portx, -1, "", "");
}
reply.data_NETLE = host2netle(n);
send_to_client (client, &reply);
}
break;
case 'Y': /* How Many Outstanding frames wait for tx for a particular station */
/* Number of frames sitting in transmit queue for given channel, */
/* source (optional) and destination addresses. */
{
char source[AX25_MAX_ADDR_LEN];
char dest[AX25_MAX_ADDR_LEN];
struct {
struct agwpe_s hdr;
int data_NETLE; // Little endian order.
} reply;
strlcpy (source, cmd.hdr.call_from, sizeof(source));
strlcpy (dest, cmd.hdr.call_to, sizeof(dest));
memset (&reply, 0, sizeof(reply));
reply.hdr.portx = cmd.hdr.portx; /* Reply with same port number, addresses. */
reply.hdr.datakind = 'Y';
strlcpy (reply.hdr.call_from, source, sizeof(reply.hdr.call_from));
strlcpy (reply.hdr.call_to, dest, sizeof(reply.hdr.call_to));
reply.hdr.data_len_NETLE = host2netle(4);
int n = 0;
if (cmd.hdr.portx >= 0 && cmd.hdr.portx < MAX_CHANS) {
n = tq_count (cmd.hdr.portx, -1, source, dest);
}
reply.data_NETLE = host2netle(n);

46
tq.c
View File

@ -281,7 +281,7 @@ void tq_append (int chan, int prio, packet_t pp)
* Implementing the 6PACK protocol is probably the proper solution.
*/
if (ax25_is_aprs(pp) && tq_count(chan,prio) > 100) {
if (ax25_is_aprs(pp) && tq_count(chan,prio,"","") > 100) {
text_color_set(DW_COLOR_ERROR);
dw_printf ("Transmit packet queue for channel %d is too long. Discarding packet.\n", chan);
dw_printf ("Perhaps the channel is so busy there is no opportunity to send.\n");
@ -458,7 +458,7 @@ void lm_data_request (int chan, int prio, packet_t pp)
* Is transmit queue out of control?
*/
if (tq_count(chan,prio) > 250) {
if (tq_count(chan,prio,"","") > 250) {
text_color_set(DW_COLOR_ERROR);
dw_printf ("Warning: Transmit packet queue for channel %d is extremely long.\n", chan);
dw_printf ("Perhaps the channel is so busy there is no opportunity to send.\n");
@ -913,35 +913,67 @@ static int tq_is_empty (int chan)
* Name: tq_count
*
* Purpose: Return count of the number of packets in the specified transmit queue.
* This is used only for queries from KISS or AWG client applications.
*
* Inputs: chan - Channel, 0 is first.
*
* prio - Priority, use TQ_PRIO_0_HI or TQ_PRIO_1_LO.
* Specify -1 for total of both.
*
* source - If specified, count only those with this source address.
*
* dest - If specified, count only those with this destination address.
*
* Returns: Number of items in specified queue.
*
*--------------------------------------------------------------------*/
int tq_count (int chan, int prio)
int tq_count (int chan, int prio, char *source, char *dest)
{
packet_t p;
int n;
if (prio == -1) {
return (tq_count(chan, TQ_PRIO_0_HI, source, dest)
+ tq_count(chan, TQ_PRIO_1_LO, source, dest));
}
/* Don't bother with critical section. */
/* Only used for debugging a problem. */
// Array bounds check. FIXME: TODO: should have internal error instead of dying.
assert (chan >= 0 && chan < MAX_CHANS);
assert (prio >= 0 && prio < TQ_NUM_PRIO);
// Don't want lists being rearranged while we are traversing them.
dw_mutex_lock (&tq_mutex);
n = 0;
p = queue_head[chan][prio];
while (p != NULL) {
n++;
int count_it = 1;
if (source != NULL && *source != '\0') {
char frame_source[AX25_MAX_ADDR_LEN];
ax25_get_addr_with_ssid (p, AX25_SOURCE, frame_source);
if (strcmp(source,frame_source) != 0) count_it = 0;
}
if (count_it && dest != NULL && *dest != '\0') {
char frame_dest[AX25_MAX_ADDR_LEN];
ax25_get_addr_with_ssid (p, AX25_DESTINATION, frame_dest);
if (strcmp(dest,frame_dest) != 0) count_it = 0;
}
if (count_it) n++;
p = ax25_get_nextp(p);
}
dw_mutex_unlock (&tq_mutex);
#if DEBUG
text_color_set(DW_COLOR_DEBUG);
dw_printf ("tq_count(%d,%d) returns %d\n", chan, prio, n);
dw_printf ("tq_count(%d, %d, \"%s\", \"%s\") returns %d\n", chan, prio, source, dest, n);
#endif
return (n);

2
tq.h
View File

@ -34,7 +34,7 @@ packet_t tq_remove (int chan, int prio);
packet_t tq_peek (int chan, int prio);
int tq_count (int chan, int prio);
int tq_count (int chan, int prio, char *source, char *dest);
#endif