Skip to content

Commit eb0da22

Browse files
committed
Implement AGW 'Y' command. More error checking.
1 parent 3a496aa commit eb0da22

File tree

3 files changed

+89
-14
lines changed

3 files changed

+89
-14
lines changed

server.c

+49-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// This file is part of Dire Wolf, an amateur radio packet TNC.
33
//
4-
// Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016 John Langner, WB2OSZ
4+
// Copyright (C) 2011, 2012, 2013, 2014, 2015, 2016, 2017 John Langner, WB2OSZ
55
//
66
// This program is free software: you can redistribute it and/or modify
77
// it under the terms of the GNU General Public License as published by
@@ -59,6 +59,8 @@
5959
*
6060
* 'y' Ask Outstanding frames waiting on a Port (new in 1.2)
6161
*
62+
* 'Y' How many frames waiting for transmit for a particular station (new in 1.5)
63+
*
6264
* 'C' Connect, Start an AX.25 Connection (new in 1.4)
6365
*
6466
* 'v' Connect VIA, Start an AX.25 circuit thru digipeaters (new in 1.4)
@@ -92,6 +94,8 @@
9294
*
9395
* 'y' Outstanding frames waiting on a Port (new in 1.2)
9496
*
97+
* 'Y' How many frames waiting for transmit for a particular station (new in 1.5)
98+
*
9599
* 'C' AX.25 Connection Received (new in 1.4)
96100
*
97101
* 'D' Connected AX.25 Data (new in 1.4)
@@ -1259,16 +1263,20 @@ static THREAD_F cmd_listen_thread (void *arg)
12591263
}
12601264

12611265
/*
1262-
* Take some precautions to guard against bad data
1263-
* which could cause problems later.
1266+
* Take some precautions to guard against bad data which could cause problems later.
12641267
*/
1268+
if (cmd.hdr.portx < 0 || cmd.hdr.portx >= MAX_CHANS) {
1269+
text_color_set(DW_COLOR_ERROR);
1270+
dw_printf ("\nInvalid port number, %d, in command '%c', from AGW client application %d.\n",
1271+
cmd.hdr.portx, cmd.hdr.datakind, client);
1272+
cmd.hdr.portx = 0; // avoid subscript out of bounds, try to keep going.
1273+
}
12651274

12661275
/*
1267-
* Call to/from must not exceeed 9 characters.
1276+
* Call to/from fields are 10 bytes but contents must not exceeed 9 characters.
12681277
* It's not guaranteed that unused bytes will contain 0 so we
12691278
* don't issue error message in this case.
12701279
*/
1271-
12721280
cmd.hdr.call_from[sizeof(cmd.hdr.call_from)-1] = '\0';
12731281
cmd.hdr.call_to[sizeof(cmd.hdr.call_to)-1] = '\0';
12741282

@@ -1455,6 +1463,7 @@ static THREAD_F cmd_listen_thread (void *arg)
14551463

14561464
// YAAC asks for this.
14571465
// Fake it to keep application happy.
1466+
// TODO: Supply real values instead of just faking it.
14581467

14591468
reply.on_air_baud_rate = 0;
14601469
reply.traffic_level = 1;
@@ -1842,6 +1851,7 @@ static THREAD_F cmd_listen_thread (void *arg)
18421851

18431852
case 'y': /* Ask Outstanding frames waiting on a Port */
18441853

1854+
/* Number of frames sitting in transmit queue for specified channel. */
18451855
{
18461856
struct {
18471857
struct agwpe_s hdr;
@@ -1856,7 +1866,40 @@ static THREAD_F cmd_listen_thread (void *arg)
18561866

18571867
int n = 0;
18581868
if (cmd.hdr.portx >= 0 && cmd.hdr.portx < MAX_CHANS) {
1859-
n = tq_count (cmd.hdr.portx, TQ_PRIO_0_HI) + tq_count (cmd.hdr.portx, TQ_PRIO_1_LO);
1869+
n = tq_count (cmd.hdr.portx, -1, "", "");
1870+
}
1871+
reply.data_NETLE = host2netle(n);
1872+
1873+
send_to_client (client, &reply);
1874+
}
1875+
break;
1876+
1877+
case 'Y': /* How Many Outstanding frames wait for tx for a particular station */
1878+
1879+
/* Number of frames sitting in transmit queue for given channel, */
1880+
/* source (optional) and destination addresses. */
1881+
{
1882+
char source[AX25_MAX_ADDR_LEN];
1883+
char dest[AX25_MAX_ADDR_LEN];
1884+
1885+
struct {
1886+
struct agwpe_s hdr;
1887+
int data_NETLE; // Little endian order.
1888+
} reply;
1889+
1890+
strlcpy (source, cmd.hdr.call_from, sizeof(source));
1891+
strlcpy (dest, cmd.hdr.call_to, sizeof(dest));
1892+
1893+
memset (&reply, 0, sizeof(reply));
1894+
reply.hdr.portx = cmd.hdr.portx; /* Reply with same port number, addresses. */
1895+
reply.hdr.datakind = 'Y';
1896+
strlcpy (reply.hdr.call_from, source, sizeof(reply.hdr.call_from));
1897+
strlcpy (reply.hdr.call_to, dest, sizeof(reply.hdr.call_to));
1898+
reply.hdr.data_len_NETLE = host2netle(4);
1899+
1900+
int n = 0;
1901+
if (cmd.hdr.portx >= 0 && cmd.hdr.portx < MAX_CHANS) {
1902+
n = tq_count (cmd.hdr.portx, -1, source, dest);
18601903
}
18611904
reply.data_NETLE = host2netle(n);
18621905

tq.c

+39-7
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ void tq_append (int chan, int prio, packet_t pp)
281281
* Implementing the 6PACK protocol is probably the proper solution.
282282
*/
283283

284-
if (ax25_is_aprs(pp) && tq_count(chan,prio) > 100) {
284+
if (ax25_is_aprs(pp) && tq_count(chan,prio,"","") > 100) {
285285
text_color_set(DW_COLOR_ERROR);
286286
dw_printf ("Transmit packet queue for channel %d is too long. Discarding packet.\n", chan);
287287
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)
458458
* Is transmit queue out of control?
459459
*/
460460

461-
if (tq_count(chan,prio) > 250) {
461+
if (tq_count(chan,prio,"","") > 250) {
462462
text_color_set(DW_COLOR_ERROR);
463463
dw_printf ("Warning: Transmit packet queue for channel %d is extremely long.\n", chan);
464464
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)
913913
* Name: tq_count
914914
*
915915
* Purpose: Return count of the number of packets in the specified transmit queue.
916+
* This is used only for queries from KISS or AWG client applications.
916917
*
917918
* Inputs: chan - Channel, 0 is first.
918919
*
919920
* prio - Priority, use TQ_PRIO_0_HI or TQ_PRIO_1_LO.
921+
* Specify -1 for total of both.
922+
*
923+
* source - If specified, count only those with this source address.
924+
*
925+
* dest - If specified, count only those with this destination address.
920926
*
921927
* Returns: Number of items in specified queue.
922928
*
923929
*--------------------------------------------------------------------*/
924930

925-
int tq_count (int chan, int prio)
931+
int tq_count (int chan, int prio, char *source, char *dest)
926932
{
927933

928934
packet_t p;
929935
int n;
930936

937+
if (prio == -1) {
938+
return (tq_count(chan, TQ_PRIO_0_HI, source, dest)
939+
+ tq_count(chan, TQ_PRIO_1_LO, source, dest));
940+
}
941+
942+
943+
// Array bounds check. FIXME: TODO: should have internal error instead of dying.
944+
945+
assert (chan >= 0 && chan < MAX_CHANS);
946+
assert (prio >= 0 && prio < TQ_NUM_PRIO);
947+
948+
// Don't want lists being rearranged while we are traversing them.
931949

932-
/* Don't bother with critical section. */
933-
/* Only used for debugging a problem. */
950+
dw_mutex_lock (&tq_mutex);
934951

935952
n = 0;
936953
p = queue_head[chan][prio];
937954
while (p != NULL) {
938-
n++;
955+
int count_it = 1;
956+
957+
if (source != NULL && *source != '\0') {
958+
char frame_source[AX25_MAX_ADDR_LEN];
959+
ax25_get_addr_with_ssid (p, AX25_SOURCE, frame_source);
960+
if (strcmp(source,frame_source) != 0) count_it = 0;
961+
}
962+
if (count_it && dest != NULL && *dest != '\0') {
963+
char frame_dest[AX25_MAX_ADDR_LEN];
964+
ax25_get_addr_with_ssid (p, AX25_DESTINATION, frame_dest);
965+
if (strcmp(dest,frame_dest) != 0) count_it = 0;
966+
}
967+
968+
if (count_it) n++;
939969
p = ax25_get_nextp(p);
940970
}
941971

972+
dw_mutex_unlock (&tq_mutex);
973+
942974
#if DEBUG
943975
text_color_set(DW_COLOR_DEBUG);
944-
dw_printf ("tq_count(%d,%d) returns %d\n", chan, prio, n);
976+
dw_printf ("tq_count(%d, %d, \"%s\", \"%s\") returns %d\n", chan, prio, source, dest, n);
945977
#endif
946978

947979
return (n);

tq.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ packet_t tq_remove (int chan, int prio);
3434

3535
packet_t tq_peek (int chan, int prio);
3636

37-
int tq_count (int chan, int prio);
37+
int tq_count (int chan, int prio, char *source, char *dest);
3838

3939
#endif
4040

0 commit comments

Comments
 (0)