mirror of https://github.com/wb2osz/direwolf.git
KISS Set Hardware commands TNC, TXBUF.
This commit is contained in:
parent
cc84a610dd
commit
c23ab04338
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
# Revision History #
|
# Revision History #
|
||||||
|
|
||||||
## Version 1.5 -- Development snapshot C -- September 2017 ##
|
## Version 1.5 -- Development snapshot C -- October 2017 ##
|
||||||
|
|
||||||
This is a snapshot of ongoing development towards version of 1.5. Some features might be incomplete or broken or not documented properly.
|
This is a snapshot of ongoing development towards version of 1.5. Some features might be incomplete or broken or not documented properly.
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@ This is a snapshot of ongoing development towards version of 1.5. Some features
|
||||||
|
|
||||||
- "kissutil" for troubleshooting a KISS TNC or interfacing to an application via files.
|
- "kissutil" for troubleshooting a KISS TNC or interfacing to an application via files.
|
||||||
|
|
||||||
|
- KISS "Set Hardware" command to report transmit queue length.
|
||||||
|
|
||||||
|
|
||||||
### Bugs Fixed: ###
|
### Bugs Fixed: ###
|
||||||
|
|
||||||
|
|
29
ax25_pad.c
29
ax25_pad.c
|
@ -2000,7 +2000,7 @@ int ax25_pack (packet_t this_p, unsigned char result[AX25_MAX_PACKET_LEN])
|
||||||
assert (this_p->magic1 == MAGIC);
|
assert (this_p->magic1 == MAGIC);
|
||||||
assert (this_p->magic2 == MAGIC);
|
assert (this_p->magic2 == MAGIC);
|
||||||
|
|
||||||
assert (this_p->frame_len > 0 && this_p->frame_len <= AX25_MAX_PACKET_LEN);
|
assert (this_p->frame_len >= 0 && this_p->frame_len <= AX25_MAX_PACKET_LEN);
|
||||||
|
|
||||||
memcpy (result, this_p->frame_data, this_p->frame_len);
|
memcpy (result, this_p->frame_data, this_p->frame_len);
|
||||||
|
|
||||||
|
@ -2503,6 +2503,33 @@ int ax25_get_pid (packet_t this_p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Function: ax25_get_frame_len
|
||||||
|
*
|
||||||
|
* Purpose: Get length of frame.
|
||||||
|
*
|
||||||
|
* Inputs: this_p - pointer to packet object.
|
||||||
|
*
|
||||||
|
* Returns: Number of octets in the frame buffer.
|
||||||
|
* Does NOT include the extra 2 for FCS.
|
||||||
|
*
|
||||||
|
*------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
int ax25_get_frame_len (packet_t this_p)
|
||||||
|
{
|
||||||
|
assert (this_p->magic1 == MAGIC);
|
||||||
|
assert (this_p->magic2 == MAGIC);
|
||||||
|
|
||||||
|
assert (this_p->frame_len >= 0 && this_p->frame_len <= AX25_MAX_PACKET_LEN);
|
||||||
|
|
||||||
|
return (this_p->frame_len);
|
||||||
|
|
||||||
|
} /* end ax25_get_frame_len */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Name: ax25_dedupe_crc
|
* Name: ax25_dedupe_crc
|
||||||
|
|
|
@ -427,6 +427,8 @@ extern int ax25_get_c2 (packet_t this_p);
|
||||||
|
|
||||||
extern int ax25_get_pid (packet_t this_p);
|
extern int ax25_get_pid (packet_t this_p);
|
||||||
|
|
||||||
|
extern int ax25_get_frame_len (packet_t this_p);
|
||||||
|
|
||||||
extern unsigned short ax25_dedupe_crc (packet_t pp);
|
extern unsigned short ax25_dedupe_crc (packet_t pp);
|
||||||
|
|
||||||
extern unsigned short ax25_m_m_crc (packet_t pp);
|
extern unsigned short ax25_m_m_crc (packet_t pp);
|
||||||
|
|
84
kiss_frame.c
84
kiss_frame.c
|
@ -25,7 +25,7 @@
|
||||||
*
|
*
|
||||||
* Purpose: Common code used by Serial port and network versions of KISS protocol.
|
* Purpose: Common code used by Serial port and network versions of KISS protocol.
|
||||||
*
|
*
|
||||||
* Description: The KISS TNS protocol is described in http://www.ka9q.net/papers/kiss.html
|
* Description: The KISS TNC protocol is described in http://www.ka9q.net/papers/kiss.html
|
||||||
*
|
*
|
||||||
* ( An extended form, to handle multiple TNCs on a single serial port.
|
* ( An extended form, to handle multiple TNCs on a single serial port.
|
||||||
* Not applicable for our situation. http://he.fi/pub/oh7lzb/bpq/multi-kiss.pdf )
|
* Not applicable for our situation. http://he.fi/pub/oh7lzb/bpq/multi-kiss.pdf )
|
||||||
|
@ -40,11 +40,11 @@
|
||||||
*
|
*
|
||||||
* The first byte of the frame contains:
|
* The first byte of the frame contains:
|
||||||
*
|
*
|
||||||
* * port number in upper nybble.
|
* * port number (radio channel) in upper nybble.
|
||||||
* * command in lower nybble.
|
* * command in lower nybble.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Commands from application recognized:
|
* Commands from application tp TNC:
|
||||||
*
|
*
|
||||||
* _0 Data Frame AX.25 frame in raw format.
|
* _0 Data Frame AX.25 frame in raw format.
|
||||||
*
|
*
|
||||||
|
@ -72,6 +72,9 @@
|
||||||
*
|
*
|
||||||
* _0 Data Frame Received AX.25 frame in raw format.
|
* _0 Data Frame Received AX.25 frame in raw format.
|
||||||
*
|
*
|
||||||
|
* _6 SetHardware TNC specific.
|
||||||
|
* Usually a response to a query.
|
||||||
|
*
|
||||||
*---------------------------------------------------------------*/
|
*---------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "direwolf.h"
|
#include "direwolf.h"
|
||||||
|
@ -88,6 +91,8 @@
|
||||||
#include "kiss_frame.h"
|
#include "kiss_frame.h"
|
||||||
#include "tq.h"
|
#include "tq.h"
|
||||||
#include "xmit.h"
|
#include "xmit.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
|
|
||||||
/* In server.c. Should probably move to some misc. function file. */
|
/* In server.c. Should probably move to some misc. function file. */
|
||||||
void hex_dump (unsigned char *p, int len);
|
void hex_dump (unsigned char *p, int len);
|
||||||
|
@ -138,10 +143,10 @@ static void kiss_set_hardware (int chan, char *command, int debug, int client, v
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if KISSUTIL
|
//#if KISSUTIL
|
||||||
#define text_color_set(x) ;
|
//#define text_color_set(x) ;
|
||||||
#define dw_printf printf
|
//#define dw_printf printf
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------
|
/*-------------------------------------------------------------------
|
||||||
|
@ -171,6 +176,7 @@ void kiss_frame_init (struct audio_s *pa)
|
||||||
* Inputs: in - Address of input block.
|
* Inputs: in - Address of input block.
|
||||||
* First byte is the "type indicator" with type and
|
* First byte is the "type indicator" with type and
|
||||||
* channel but we don't care about that here.
|
* channel but we don't care about that here.
|
||||||
|
* If it happens to be FEND or FESC, it is escaped, like any other byte.
|
||||||
*
|
*
|
||||||
* This seems cumbersome and confusing to have this
|
* This seems cumbersome and confusing to have this
|
||||||
* one byte offset when encapsulating an AX.25 frame.
|
* one byte offset when encapsulating an AX.25 frame.
|
||||||
|
@ -190,7 +196,7 @@ void kiss_frame_init (struct audio_s *pa)
|
||||||
* FEND - Magic frame separator.
|
* FEND - Magic frame separator.
|
||||||
*
|
*
|
||||||
* Returns: Number of bytes in the output.
|
* Returns: Number of bytes in the output.
|
||||||
* Absolute max length will be twice input plus 2.
|
* Absolute max length (extremely unlikely) will be twice input plus 2.
|
||||||
*
|
*
|
||||||
*-----------------------------------------------------------------*/
|
*-----------------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -242,6 +248,8 @@ int kiss_encapsulate (unsigned char *in, int ilen, unsigned char *out)
|
||||||
* the escapes or FEND.
|
* the escapes or FEND.
|
||||||
* First byte is the "type indicator" with type and
|
* First byte is the "type indicator" with type and
|
||||||
* channel but we don't care about that here.
|
* channel but we don't care about that here.
|
||||||
|
* We treat it like any other byte with special handling
|
||||||
|
* if it happens to be FESC.
|
||||||
* Note that this is "binary" data and can contain
|
* Note that this is "binary" data and can contain
|
||||||
* nul (0x00) values. Don't treat it like a text string!
|
* nul (0x00) values. Don't treat it like a text string!
|
||||||
*
|
*
|
||||||
|
@ -509,6 +517,8 @@ void kiss_rec_byte (kiss_frame_t *kf, unsigned char ch, int debug, int client, v
|
||||||
// Some functions are only for the TNC end.
|
// Some functions are only for the TNC end.
|
||||||
// Other functions are suitble for both TNC and client app.
|
// Other functions are suitble for both TNC and client app.
|
||||||
|
|
||||||
|
// This is used only by the TNC sided.
|
||||||
|
|
||||||
void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug, int client, void (*sendfun)(int,int,unsigned char*,int,int))
|
void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug, int client, void (*sendfun)(int,int,unsigned char*,int,int))
|
||||||
{
|
{
|
||||||
int port;
|
int port;
|
||||||
|
@ -690,6 +700,7 @@ void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug, int cli
|
||||||
* debug - debug level.
|
* debug - debug level.
|
||||||
*
|
*
|
||||||
* client - Client app number for TCP KISS.
|
* client - Client app number for TCP KISS.
|
||||||
|
* Needed so we can send any response to the right client app.
|
||||||
* Ignored for pseudo terminal and serial port.
|
* Ignored for pseudo terminal and serial port.
|
||||||
*
|
*
|
||||||
* sendfun - Function to send something to the client application.
|
* sendfun - Function to send something to the client application.
|
||||||
|
@ -713,13 +724,17 @@ void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug, int cli
|
||||||
* be used for throttling of large transmissions and performing some action
|
* be used for throttling of large transmissions and performing some action
|
||||||
* after the last frame has been sent.
|
* after the last frame has been sent.
|
||||||
*
|
*
|
||||||
* The original KISS protocol spec offers no guidance on what this might look
|
* The original KISS protocol spec offers no guidance on what "Set Hardware" might look
|
||||||
* like. I'm aware of only two, drastically different, implementations:
|
* like. I'm aware of only two, drastically different, implementations:
|
||||||
*
|
*
|
||||||
* fldigi - http://www.w1hkj.com/FldigiHelp-3.22/kiss_command_page.html
|
* fldigi - http://www.w1hkj.com/FldigiHelp-3.22/kiss_command_page.html
|
||||||
*
|
*
|
||||||
* Everything is in human readable text in the form of:
|
* Everything is in human readable in both directions:
|
||||||
* COMMAND : [ parameter [ , parameter ... ] ]
|
*
|
||||||
|
* COMMAND: [ parameter [ , parameter ... ] ]
|
||||||
|
*
|
||||||
|
* Lack of a parameter, in the client to TNC direction, is a query
|
||||||
|
* which should generate a response in the same format.
|
||||||
*
|
*
|
||||||
* Used by applications, http://www.w1hkj.com/FldigiHelp/kiss_host_prgs_page.html
|
* Used by applications, http://www.w1hkj.com/FldigiHelp/kiss_host_prgs_page.html
|
||||||
* - BPQ32
|
* - BPQ32
|
||||||
|
@ -740,6 +755,19 @@ void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug, int cli
|
||||||
*
|
*
|
||||||
* Let's start with the easy to understand human readable format.
|
* Let's start with the easy to understand human readable format.
|
||||||
*
|
*
|
||||||
|
* Commands: (Client to TNC, with parameter(s) to set something.)
|
||||||
|
*
|
||||||
|
* none yet
|
||||||
|
*
|
||||||
|
* Queries: (Client to TNC, no parameters, generate a response.)
|
||||||
|
*
|
||||||
|
* Query Response Comment
|
||||||
|
* ----- -------- -------
|
||||||
|
*
|
||||||
|
* TNC: TNC:DIREWOLF 9.9 9.9 represents current version.
|
||||||
|
*
|
||||||
|
* TXBUF: TXBUF:999 Number of bytes (not frames) in transmit queue.
|
||||||
|
*
|
||||||
*--------------------------------------------------------------------*/
|
*--------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef KISSUTIL
|
#ifndef KISSUTIL
|
||||||
|
@ -754,39 +782,37 @@ static void kiss_set_hardware (int chan, char *command, int debug, int client, v
|
||||||
*param = '\0';
|
*param = '\0';
|
||||||
param++;
|
param++;
|
||||||
|
|
||||||
if (strcmp(command, "TXBUF") == 0) { /* Number of frames in transmit queue. */
|
if (strcmp(command, "TNC") == 0) { /* TNC - Identify software version. */
|
||||||
|
|
||||||
if (strlen(param) > 0) {
|
if (strlen(param) > 0) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("KISS Set Hardware TXBUF: did not expect a parameter.\n");
|
dw_printf ("KISS Set Hardware TNC: Did not expect a parameter.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// See what we have in the transmit queue for specified channel.
|
snprintf (response, sizeof(response), "DIREWOLF %d.%d", MAJOR_VERSION, MINOR_VERSION);
|
||||||
// fldigi uses bytes but frames seems to make more sense in this situation.
|
|
||||||
// Do we add one if PTT is on? That information doesn't seem to be easily available.
|
|
||||||
|
|
||||||
// TODO: FIXME: not implemented yet.
|
|
||||||
|
|
||||||
// n = tq_count (chan, TQ_PRIO_0_HI) + tq_count (chan, TQ_PRIO_1_LO);
|
|
||||||
|
|
||||||
snprintf (response, sizeof(response), "TXBUF:whatever");
|
|
||||||
|
|
||||||
(*sendfun) (chan, KISS_CMD_SET_HARDWARE, (unsigned char *)response, strlen(response), client);
|
(*sendfun) (chan, KISS_CMD_SET_HARDWARE, (unsigned char *)response, strlen(response), client);
|
||||||
}
|
}
|
||||||
else if (strcmp(command, "TNC") == 0) { /* Identify software version. */
|
|
||||||
; // TODO...
|
else if (strcmp(command, "TXBUF") == 0) { /* TXBUF - Number of bytes in transmit queue. */
|
||||||
|
|
||||||
|
if (strlen(param) > 0) {
|
||||||
|
text_color_set(DW_COLOR_ERROR);
|
||||||
|
dw_printf ("KISS Set Hardware TXBUF: Did not expect a parameter.\n");
|
||||||
}
|
}
|
||||||
else if (strcmp(command, "TRXS") == 0) {
|
|
||||||
; // TODO... BUSY
|
int n = tq_count (chan, -1, "", "", 1);
|
||||||
|
snprintf (response, sizeof(response), "TXBUF:%d", n);
|
||||||
|
(*sendfun) (chan, KISS_CMD_SET_HARDWARE, (unsigned char *)response, strlen(response), client);
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("KISS Set Hardware invalid command.\n");
|
dw_printf ("KISS Set Hardware unrecognized command: %s.\n", command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("KISS Set Hardware expected the form COMMAND:[parameter[,parameter...]]\n");
|
dw_printf ("KISS Set Hardware \"%s\" expected the form COMMAND:[parameter[,parameter...]]\n", command);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
16
server.c
16
server.c
|
@ -1705,7 +1705,17 @@ static THREAD_F cmd_listen_thread (void *arg)
|
||||||
struct via_info {
|
struct via_info {
|
||||||
unsigned char num_digi; /* Expect to be in range 1 to 7. Why not up to 8? */
|
unsigned char num_digi; /* Expect to be in range 1 to 7. Why not up to 8? */
|
||||||
char dcall[7][10];
|
char dcall[7][10];
|
||||||
} *v = (struct via_info *)cmd.data;
|
}
|
||||||
|
#if 1
|
||||||
|
// October 2017. gcc ??? complained:
|
||||||
|
// warning: dereferencing pointer 'v' does break strict-aliasing rules
|
||||||
|
// Try adding this attribute to get rid of the warning.
|
||||||
|
// If this upsets your compiler, take it out.
|
||||||
|
// Let me know. Maybe we could put in a compiler version check here.
|
||||||
|
|
||||||
|
__attribute__((__may_alias__))
|
||||||
|
#endif
|
||||||
|
*v = (struct via_info *)cmd.data;
|
||||||
|
|
||||||
char callsigns[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN];
|
char callsigns[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN];
|
||||||
int num_calls = 2; /* 2 plus any digipeaters. */
|
int num_calls = 2; /* 2 plus any digipeaters. */
|
||||||
|
@ -1866,7 +1876,7 @@ static THREAD_F cmd_listen_thread (void *arg)
|
||||||
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
if (cmd.hdr.portx >= 0 && cmd.hdr.portx < MAX_CHANS) {
|
if (cmd.hdr.portx >= 0 && cmd.hdr.portx < MAX_CHANS) {
|
||||||
n = tq_count (cmd.hdr.portx, -1, "", "");
|
n = tq_count (cmd.hdr.portx, -1, "", "", 0);
|
||||||
}
|
}
|
||||||
reply.data_NETLE = host2netle(n);
|
reply.data_NETLE = host2netle(n);
|
||||||
|
|
||||||
|
@ -1899,7 +1909,7 @@ static THREAD_F cmd_listen_thread (void *arg)
|
||||||
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
if (cmd.hdr.portx >= 0 && cmd.hdr.portx < MAX_CHANS) {
|
if (cmd.hdr.portx >= 0 && cmd.hdr.portx < MAX_CHANS) {
|
||||||
n = tq_count (cmd.hdr.portx, -1, source, dest);
|
n = tq_count (cmd.hdr.portx, -1, source, dest, 0);
|
||||||
}
|
}
|
||||||
reply.data_NETLE = host2netle(n);
|
reply.data_NETLE = host2netle(n);
|
||||||
|
|
||||||
|
|
49
tq.c
49
tq.c
|
@ -281,7 +281,7 @@ void tq_append (int chan, int prio, packet_t pp)
|
||||||
* Implementing the 6PACK protocol is probably the proper solution.
|
* 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,"","",0) > 100) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Transmit packet queue for channel %d is too long. Discarding packet.\n", chan);
|
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");
|
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?
|
* Is transmit queue out of control?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (tq_count(chan,prio,"","") > 250) {
|
if (tq_count(chan,prio,"","",0) > 250) {
|
||||||
text_color_set(DW_COLOR_ERROR);
|
text_color_set(DW_COLOR_ERROR);
|
||||||
dw_printf ("Warning: Transmit packet queue for channel %d is extremely long.\n", chan);
|
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");
|
dw_printf ("Perhaps the channel is so busy there is no opportunity to send.\n");
|
||||||
|
@ -912,7 +912,7 @@ static int tq_is_empty (int chan)
|
||||||
*
|
*
|
||||||
* Name: tq_count
|
* Name: tq_count
|
||||||
*
|
*
|
||||||
* Purpose: Return count of the number of packets in the specified transmit queue.
|
* Purpose: Return count of the number of packets (or bytes) in the specified transmit queue.
|
||||||
* This is used only for queries from KISS or AWG client applications.
|
* This is used only for queries from KISS or AWG client applications.
|
||||||
*
|
*
|
||||||
* Inputs: chan - Channel, 0 is first.
|
* Inputs: chan - Channel, 0 is first.
|
||||||
|
@ -924,56 +924,71 @@ static int tq_is_empty (int chan)
|
||||||
*
|
*
|
||||||
* dest - If specified, count only those with this destination address.
|
* dest - If specified, count only those with this destination address.
|
||||||
*
|
*
|
||||||
|
* bytes - If true, return number of bytes rather than packets.
|
||||||
|
*
|
||||||
* Returns: Number of items in specified queue.
|
* Returns: Number of items in specified queue.
|
||||||
*
|
*
|
||||||
*--------------------------------------------------------------------*/
|
*--------------------------------------------------------------------*/
|
||||||
|
|
||||||
int tq_count (int chan, int prio, char *source, char *dest)
|
int tq_count (int chan, int prio, char *source, char *dest, int bytes)
|
||||||
{
|
{
|
||||||
|
|
||||||
packet_t p;
|
packet_t pp;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
if (prio == -1) {
|
if (prio == -1) {
|
||||||
return (tq_count(chan, TQ_PRIO_0_HI, source, dest)
|
return (tq_count(chan, TQ_PRIO_0_HI, source, dest, bytes)
|
||||||
+ tq_count(chan, TQ_PRIO_1_LO, source, dest));
|
+ tq_count(chan, TQ_PRIO_1_LO, source, dest, bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Array bounds check. FIXME: TODO: should have internal error instead of dying.
|
// Array bounds check. FIXME: TODO: should have internal error instead of dying.
|
||||||
|
|
||||||
assert (chan >= 0 && chan < MAX_CHANS);
|
if (chan < 0 || chan >= MAX_CHANS || prio < 0 || prio >= TQ_NUM_PRIO) {
|
||||||
assert (prio >= 0 && prio < TQ_NUM_PRIO);
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
|
dw_printf ("INTERNAL ERROR - tq_count(%d, %d, \"%s\", \"%s\", %d)\n", chan, prio, source, dest, bytes);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queue_head[chan][prio] == 0) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
// Don't want lists being rearranged while we are traversing them.
|
// Don't want lists being rearranged while we are traversing them.
|
||||||
|
|
||||||
dw_mutex_lock (&tq_mutex);
|
dw_mutex_lock (&tq_mutex);
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
p = queue_head[chan][prio];
|
pp = queue_head[chan][prio];
|
||||||
while (p != NULL) {
|
while (pp != NULL) {
|
||||||
int count_it = 1;
|
int count_it = 1;
|
||||||
|
|
||||||
if (source != NULL && *source != '\0') {
|
if (source != NULL && *source != '\0') {
|
||||||
char frame_source[AX25_MAX_ADDR_LEN];
|
char frame_source[AX25_MAX_ADDR_LEN];
|
||||||
ax25_get_addr_with_ssid (p, AX25_SOURCE, frame_source);
|
ax25_get_addr_with_ssid (pp, AX25_SOURCE, frame_source);
|
||||||
if (strcmp(source,frame_source) != 0) count_it = 0;
|
if (strcmp(source,frame_source) != 0) count_it = 0;
|
||||||
}
|
}
|
||||||
if (count_it && dest != NULL && *dest != '\0') {
|
if (count_it && dest != NULL && *dest != '\0') {
|
||||||
char frame_dest[AX25_MAX_ADDR_LEN];
|
char frame_dest[AX25_MAX_ADDR_LEN];
|
||||||
ax25_get_addr_with_ssid (p, AX25_DESTINATION, frame_dest);
|
ax25_get_addr_with_ssid (pp, AX25_DESTINATION, frame_dest);
|
||||||
if (strcmp(dest,frame_dest) != 0) count_it = 0;
|
if (strcmp(dest,frame_dest) != 0) count_it = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count_it) n++;
|
if (count_it) {
|
||||||
p = ax25_get_nextp(p);
|
if (bytes) {
|
||||||
|
n += ax25_get_frame_len(pp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pp = ax25_get_nextp(pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
dw_mutex_unlock (&tq_mutex);
|
dw_mutex_unlock (&tq_mutex);
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
text_color_set(DW_COLOR_DEBUG);
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
dw_printf ("tq_count(%d, %d, \"%s\", \"%s\") returns %d\n", chan, prio, source, dest, n);
|
dw_printf ("tq_count(%d, %d, \"%s\", \"%s\", %d) returns %d\n", chan, prio, source, dest, bytes, n);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (n);
|
return (n);
|
||||||
|
|
Loading…
Reference in New Issue