mirror of https://github.com/wb2osz/direwolf.git
Look past third party header for packet filtering.
This commit is contained in:
parent
f9cf42b291
commit
e84a622515
|
@ -30,6 +30,14 @@
|
||||||
> Add: "FX25TX 1" (or 16 or 32 or 64)
|
> Add: "FX25TX 1" (or 16 or 32 or 64)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Bugs Fixed: ###
|
||||||
|
|
||||||
|
- The t/m packet filter incorrectly included bulletins. It now allows only "messages" to specific stations. Use of t/m is discouraged. i/180 is the preferred filter for messages to users recently heard locally.
|
||||||
|
|
||||||
|
- Packet filtering now skips over any third party header before classifying packet types.
|
||||||
|
|
||||||
|
|
||||||
## Version 1.6 -- October 2020 ##
|
## Version 1.6 -- October 2020 ##
|
||||||
|
|
||||||
### New Build Procedure: ###
|
### New Build Procedure: ###
|
||||||
|
|
|
@ -169,7 +169,9 @@ void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet, char *third_party_sr
|
||||||
|
|
||||||
//dw_printf ("DEBUG decode_aprs info=\"%s\"\n", pinfo);
|
//dw_printf ("DEBUG decode_aprs info=\"%s\"\n", pinfo);
|
||||||
|
|
||||||
memset (A, 0, sizeof (*A));
|
if (third_party_src == NULL) {
|
||||||
|
memset (A, 0, sizeof (*A));
|
||||||
|
}
|
||||||
|
|
||||||
A->g_quiet = quiet;
|
A->g_quiet = quiet;
|
||||||
|
|
||||||
|
@ -234,6 +236,7 @@ void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet, char *third_party_sr
|
||||||
memcpy(payload_src, (char*)pinfo+1, sizeof(payload_src)-1);
|
memcpy(payload_src, (char*)pinfo+1, sizeof(payload_src)-1);
|
||||||
char *q = strchr(payload_src, '>');
|
char *q = strchr(payload_src, '>');
|
||||||
if (q != NULL) *q = '\0';
|
if (q != NULL) *q = '\0';
|
||||||
|
A->g_has_thirdparty_header = 1;
|
||||||
decode_aprs (A, pp_payload, quiet, payload_src); // 1 means used recursively
|
decode_aprs (A, pp_payload, quiet, payload_src); // 1 means used recursively
|
||||||
ax25_delete (pp_payload);
|
ax25_delete (pp_payload);
|
||||||
return;
|
return;
|
||||||
|
@ -318,6 +321,7 @@ void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet, char *third_party_sr
|
||||||
{
|
{
|
||||||
aprs_ll_pos (A, pinfo, info_len);
|
aprs_ll_pos (A, pinfo, info_len);
|
||||||
}
|
}
|
||||||
|
A->g_packet_type = packet_type_position;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
@ -330,10 +334,12 @@ void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet, char *third_party_sr
|
||||||
if (strncmp((char*)pinfo, "$ULTW", 5) == 0)
|
if (strncmp((char*)pinfo, "$ULTW", 5) == 0)
|
||||||
{
|
{
|
||||||
aprs_ultimeter (A, (char*)pinfo, info_len); // TODO: produce obsolete error.
|
aprs_ultimeter (A, (char*)pinfo, info_len); // TODO: produce obsolete error.
|
||||||
|
A->g_packet_type = packet_type_weather;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
aprs_raw_nmea (A, pinfo, info_len);
|
aprs_raw_nmea (A, pinfo, info_len);
|
||||||
|
A->g_packet_type = packet_type_position;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -341,17 +347,20 @@ void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet, char *third_party_sr
|
||||||
case '`': /* Current Mic-E Data (not used in TM-D700) */
|
case '`': /* Current Mic-E Data (not used in TM-D700) */
|
||||||
|
|
||||||
aprs_mic_e (A, pp, pinfo, info_len);
|
aprs_mic_e (A, pp, pinfo, info_len);
|
||||||
|
A->g_packet_type = packet_type_position;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ')': /* Item. */
|
case ')': /* Item. */
|
||||||
|
|
||||||
aprs_item (A, pinfo, info_len);
|
aprs_item (A, pinfo, info_len);
|
||||||
|
A->g_packet_type = packet_type_item;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '/': /* Position with timestamp (no APRS messaging) */
|
case '/': /* Position with timestamp (no APRS messaging) */
|
||||||
case '@': /* Position with timestamp (with APRS messaging) */
|
case '@': /* Position with timestamp (with APRS messaging) */
|
||||||
|
|
||||||
aprs_ll_pos_time (A, pinfo, info_len);
|
aprs_ll_pos_time (A, pinfo, info_len);
|
||||||
|
A->g_packet_type = packet_type_position;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
@ -360,42 +369,76 @@ void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet, char *third_party_sr
|
||||||
/* Telemetry metadata. */
|
/* Telemetry metadata. */
|
||||||
|
|
||||||
aprs_message (A, pinfo, info_len, quiet);
|
aprs_message (A, pinfo, info_len, quiet);
|
||||||
|
|
||||||
|
switch (A->g_message_subtype) {
|
||||||
|
case message_subtype_message:
|
||||||
|
case message_subtype_ack:
|
||||||
|
case message_subtype_rej:
|
||||||
|
A->g_packet_type = packet_type_message;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case message_subtype_nws:
|
||||||
|
A->g_packet_type = packet_type_nws;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case message_subtype_bulletin:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case message_subtype_telem_parm:
|
||||||
|
case message_subtype_telem_unit:
|
||||||
|
case message_subtype_telem_eqns:
|
||||||
|
case message_subtype_telem_bits:
|
||||||
|
A->g_packet_type = packet_type_telemetry;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case message_subtype_directed_query:
|
||||||
|
A->g_packet_type = packet_type_query;
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ';': /* Object */
|
case ';': /* Object */
|
||||||
|
|
||||||
aprs_object (A, pinfo, info_len);
|
aprs_object (A, pinfo, info_len);
|
||||||
|
A->g_packet_type = packet_type_object;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '<': /* Station Capabilities */
|
case '<': /* Station Capabilities */
|
||||||
|
|
||||||
aprs_station_capabilities (A, (char*)pinfo, info_len);
|
aprs_station_capabilities (A, (char*)pinfo, info_len);
|
||||||
|
A->g_packet_type = packet_type_capabilities;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '>': /* Status Report */
|
case '>': /* Status Report */
|
||||||
|
|
||||||
aprs_status_report (A, (char*)pinfo, info_len);
|
aprs_status_report (A, (char*)pinfo, info_len);
|
||||||
|
A->g_packet_type = packet_type_status;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case '?': /* General Query */
|
case '?': /* General Query */
|
||||||
|
|
||||||
aprs_general_query (A, (char*)pinfo, info_len, quiet);
|
aprs_general_query (A, (char*)pinfo, info_len, quiet);
|
||||||
|
A->g_packet_type = packet_type_query;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'T': /* Telemetry */
|
case 'T': /* Telemetry */
|
||||||
|
|
||||||
aprs_telemetry (A, (char*)pinfo, info_len, quiet);
|
aprs_telemetry (A, (char*)pinfo, info_len, quiet);
|
||||||
|
A->g_packet_type = packet_type_telemetry;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '_': /* Positionless Weather Report */
|
case '_': /* Positionless Weather Report */
|
||||||
|
|
||||||
aprs_positionless_weather_report (A, pinfo, info_len);
|
aprs_positionless_weather_report (A, pinfo, info_len);
|
||||||
|
A->g_packet_type = packet_type_weather;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '{': /* user defined data */
|
case '{': /* user defined data */
|
||||||
|
|
||||||
aprs_user_defined (A, (char*)pinfo, info_len);
|
aprs_user_defined (A, (char*)pinfo, info_len);
|
||||||
|
A->g_packet_type = packet_type_userdefined;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't': /* Raw touch tone data - NOT PART OF STANDARD */
|
case 't': /* Raw touch tone data - NOT PART OF STANDARD */
|
||||||
|
@ -404,6 +447,7 @@ void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet, char *third_party_sr
|
||||||
/* Might move into user defined data, above. */
|
/* Might move into user defined data, above. */
|
||||||
|
|
||||||
aprs_raw_touch_tone (A, (char*)pinfo, info_len);
|
aprs_raw_touch_tone (A, (char*)pinfo, info_len);
|
||||||
|
// no packet type for t/ filter
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'm': /* Morse Code data - NOT PART OF STANDARD */
|
case 'm': /* Morse Code data - NOT PART OF STANDARD */
|
||||||
|
@ -413,6 +457,7 @@ void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet, char *third_party_sr
|
||||||
/* Might move into user defined data, above. */
|
/* Might move into user defined data, above. */
|
||||||
|
|
||||||
aprs_morse_code (A, (char*)pinfo, info_len);
|
aprs_morse_code (A, (char*)pinfo, info_len);
|
||||||
|
// no packet type for t/ filter
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//case '}': /* third party header */
|
//case '}': /* third party header */
|
||||||
|
@ -1091,7 +1136,9 @@ static void aprs_raw_nmea (decode_aprs_t *A, unsigned char *info, int ilen)
|
||||||
*
|
*
|
||||||
* Function: aprs_mic_e
|
* Function: aprs_mic_e
|
||||||
*
|
*
|
||||||
* Purpose: Decode MIC-E (also Kenwood D7 & D700) packet.
|
* Purpose: Decode MIC-E (e.g. Kenwood D7 & D700) packet.
|
||||||
|
* This format is an overzelous quest to make the packet as short as possible.
|
||||||
|
* It uses non-printable characters and hacks wrapped in kludges.
|
||||||
*
|
*
|
||||||
* Inputs: info - Pointer to Information field.
|
* Inputs: info - Pointer to Information field.
|
||||||
* ilen - Information field length.
|
* ilen - Information field length.
|
||||||
|
@ -1100,31 +1147,120 @@ static void aprs_raw_nmea (decode_aprs_t *A, unsigned char *info, int ilen)
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
*
|
*
|
||||||
* Destination Address Field -
|
* AX.25 Destination Address Field -
|
||||||
*
|
*
|
||||||
* The 7-byte Destination Address field contains
|
* The 6-byte Destination Address field contains
|
||||||
* the following encoded information:
|
* the following encoded information:
|
||||||
*
|
*
|
||||||
* * The 6 latitude digits.
|
* Byte 1: Lat digit 1, message bit A
|
||||||
* * A 3-bit Mic-E message identifier, specifying one of 7 Standard Mic-E
|
* Byte 2: Lat digit 2, message bit B
|
||||||
* Message Codes or one of 7 Custom Message Codes or an Emergency
|
* Byte 3: Lat digit 3, message bit C
|
||||||
* Message Code.
|
* Byte 4: Lat digit 4, N/S lat indicator
|
||||||
* * The North/South and West/East Indicators.
|
* Byte 5: Lat digit 5, Longitude offset
|
||||||
* * The Longitude Offset Indicator.
|
* Byte 6: Lat digit 6, W/E Long indicator
|
||||||
* * The generic APRS digipeater path code.
|
* *
|
||||||
*
|
|
||||||
* "Although the destination address appears to be quite unconventional, it is
|
* "Although the destination address appears to be quite unconventional, it is
|
||||||
* still a valid AX.25 address, consisting only of printable 7-bit ASCII values."
|
* still a valid AX.25 address, consisting only of printable 7-bit ASCII values."
|
||||||
*
|
*
|
||||||
* References: Mic-E TYPE CODES -- http://www.aprs.org/aprs12/mic-e-types.txt
|
* AX.25 Information Field - Starts with ' or `
|
||||||
*
|
*
|
||||||
* This is up to date with the 24 Aug 16 version mentioning the TH-D74.
|
* Bytes 1,2,3: Longitude
|
||||||
|
* Bytes 4,5,6: Speed and Course
|
||||||
|
* Byte 6: Symbol code
|
||||||
|
* Byte 7: Symbol Table ID
|
||||||
|
*
|
||||||
|
* The rest of it is a complicated comment field which can hold various information
|
||||||
|
* and must be intrepreted in a particular order. At this point we look for any
|
||||||
|
* prefix and/or suffix to identify the equipment type.
|
||||||
|
*
|
||||||
|
* References: Mic-E TYPE CODES -- http://www.aprs.org/aprs12/mic-e-types.txt
|
||||||
|
* Mic-E TEST EXAMPLES -- http://www.aprs.org/aprs12/mic-e-examples.txt
|
||||||
|
*
|
||||||
|
* Next, we have what Addedum 1.2 calls the "type byte." This prefix can be
|
||||||
|
* space Original MIC-E.
|
||||||
|
* > Kenwood HT.
|
||||||
|
* ] Kenwood Mobile.
|
||||||
|
* none.
|
||||||
|
*
|
||||||
|
* We also need to look at the last byte or two
|
||||||
|
* for a possible suffix to distinguish equipment types. Examples:
|
||||||
|
* >...... is D7
|
||||||
|
* >......= is D72
|
||||||
|
* >......^ is D74
|
||||||
|
*
|
||||||
|
* For other brands, it gets worse. There might a 2 character suffix.
|
||||||
|
* The prefix indicates whether messaging-capable. Examples:
|
||||||
|
* `....._.% Yaesu FTM-400DR
|
||||||
|
* `......_) Yaesu FTM-100D
|
||||||
|
* `......_3 Yaesu FT5D
|
||||||
|
*
|
||||||
|
* '......|3 Byonics TinyTrack3
|
||||||
|
* '......|4 Byonics TinyTrack4
|
||||||
|
*
|
||||||
|
* Any prefix and suffix must be removed before futher processsing.
|
||||||
|
*
|
||||||
|
* Pick one: MIC-E Telemetry Data or "Status Text" (called a comment everywhere else).
|
||||||
|
*
|
||||||
|
* If the character after the symbol table id is "," (comma) or 0x1d, we have telemetry.
|
||||||
|
* (Is this obsoleted by the base-91 telemetry?)
|
||||||
|
*
|
||||||
|
* ` Two 2-character hexadecimal numbers. (Channels 1 & 3)
|
||||||
|
* ' Five 2-character hexadecimal numbers.
|
||||||
|
*
|
||||||
|
* Anything left over is a comment which can contain various types of information.
|
||||||
|
*
|
||||||
|
* If present, the MIC-E compressed altitude must be first.
|
||||||
|
* It is three base-91 characters followed by "}".
|
||||||
|
* Examples: "4T} "4T} ]"4T}
|
||||||
|
*
|
||||||
|
* We can also have frequency specification -- http://www.aprs.org/info/freqspec.tx
|
||||||
|
*
|
||||||
|
* Warning: Some Kenwood radios add CR at the end, in apparent violation of the spec.
|
||||||
|
* Watch out so it doesn't get included when looking for equipment type suffix.
|
||||||
*
|
*
|
||||||
* Mic-E TEST EXAMPLES -- http://www.aprs.org/aprs12/mic-e-examples.txt
|
* Mic-E TEST EXAMPLES -- http://www.aprs.org/aprs12/mic-e-examples.txt
|
||||||
*
|
*
|
||||||
* Examples: `b9Z!4y>/>"4N}Paul's_TH-D7
|
* Examples: Observed on the air.
|
||||||
*
|
*
|
||||||
* TODO: Destination SSID can contain generic digipeater path.
|
* KB1HNZ-9>TSSP5P,W1IMD,WIDE1,KQ1L-8,N3LLO-3,WIDE2*:`b6,l}#>/]"48}449.225MHz<0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff><0xff>=<0x0d>
|
||||||
|
*
|
||||||
|
* ` b6, l}# >/ ] "48} 449.225MHz ...... = <0x0d>
|
||||||
|
* mic-e long. cs sym prefix alt. freq comment suffix must-ignore
|
||||||
|
* Kenwood D710
|
||||||
|
*---------------
|
||||||
|
*
|
||||||
|
* N1JDU-9>ECCU8Y,W1MHL*,WIDE2-1:'cZ<0x7f>l#H>/]Go fly a kite!<0x0d>
|
||||||
|
*
|
||||||
|
* ' cZ<0x7f> l#H >/ ] ..... <0x0d>
|
||||||
|
* mic-e long. cs sym prefix comment no-suffix must-ignore
|
||||||
|
* Kenwood D700
|
||||||
|
*---------------
|
||||||
|
*
|
||||||
|
* KC1HHO-7>T2PX5R,WA1PLE-4,WIDE1*,WIDE2-1:`c_snp(k/`"4B}official relay station NTS_(<0x0d>
|
||||||
|
*
|
||||||
|
* ` c_s np( k/ ` "4B} ....... _( <0x0d>
|
||||||
|
* mic-e long. cs sym prefix alt comment suffix must-ignore
|
||||||
|
* FT2D
|
||||||
|
*---------------
|
||||||
|
*
|
||||||
|
* N1CMD-12>T3PQ1Y,KA1GJU-3,WIDE1,WA1PLE-4*:`cP#l!Fk/'"7H}|!%&-']|!w`&!|3
|
||||||
|
*
|
||||||
|
* ` cP# l!F k/ ' "7H} |!%&-']| !w`&! |3
|
||||||
|
* mic-e long. cs sym prefix alt base91telemetry DAO suffix
|
||||||
|
* TinyTrack3
|
||||||
|
*---------------
|
||||||
|
*
|
||||||
|
* W1STJ-3>T2UR4X,WA1PLE-4,WIDE1*,WIDE2-1:`c@&l#.-/`"5,}146.685MHz T100 -060 146.520 Simplex or Voice Alert_%<0x0d>
|
||||||
|
*
|
||||||
|
* ` c@& l#. -/ ` "5,} 146.685MHz T100 -060 .............. _% <0x0d>
|
||||||
|
* mic-e long. cs sym prefix alt frequency-specification comment suffix must-ignore
|
||||||
|
* FTM-400DR
|
||||||
|
*---------------
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* TODO: Destination SSID can contain generic digipeater path. (?)
|
||||||
*
|
*
|
||||||
* Bugs: Doesn't handle ambiguous position. "space" treated as zero.
|
* Bugs: Doesn't handle ambiguous position. "space" treated as zero.
|
||||||
* Invalid data results in a message but latitude is not set to unknown.
|
* Invalid data results in a message but latitude is not set to unknown.
|
||||||
|
@ -1507,6 +1643,8 @@ static void aprs_mic_e (decode_aprs_t *A, packet_t pp, unsigned char *info, int
|
||||||
// This does not change very often but I'm wondering if we could parse
|
// This does not change very often but I'm wondering if we could parse
|
||||||
// http://www.aprs.org/aprs12/mic-e-types.txt similar to how we use tocalls.txt.
|
// http://www.aprs.org/aprs12/mic-e-types.txt similar to how we use tocalls.txt.
|
||||||
|
|
||||||
|
// TODO: Use https://github.com/aprsorg/aprs-deviceid rather than hardcoding.
|
||||||
|
|
||||||
if (isT(*pfirst)) {
|
if (isT(*pfirst)) {
|
||||||
|
|
||||||
// "legacy" formats.
|
// "legacy" formats.
|
||||||
|
@ -1515,6 +1653,7 @@ static void aprs_mic_e (decode_aprs_t *A, packet_t pp, unsigned char *info, int
|
||||||
|
|
||||||
else if (*pfirst == '>' && *plast == '=') { strlcpy (A->g_mfr, "Kenwood TH-D72", sizeof(A->g_mfr)); pfirst++; plast--; }
|
else if (*pfirst == '>' && *plast == '=') { strlcpy (A->g_mfr, "Kenwood TH-D72", sizeof(A->g_mfr)); pfirst++; plast--; }
|
||||||
else if (*pfirst == '>' && *plast == '^') { strlcpy (A->g_mfr, "Kenwood TH-D74", sizeof(A->g_mfr)); pfirst++; plast--; }
|
else if (*pfirst == '>' && *plast == '^') { strlcpy (A->g_mfr, "Kenwood TH-D74", sizeof(A->g_mfr)); pfirst++; plast--; }
|
||||||
|
else if (*pfirst == '>' && *plast == '&') { strlcpy (A->g_mfr, "Kenwood TH-D75", sizeof(A->g_mfr)); pfirst++; plast--; }
|
||||||
else if (*pfirst == '>' ) { strlcpy (A->g_mfr, "Kenwood TH-D7A", sizeof(A->g_mfr)); pfirst++; }
|
else if (*pfirst == '>' ) { strlcpy (A->g_mfr, "Kenwood TH-D7A", sizeof(A->g_mfr)); pfirst++; }
|
||||||
|
|
||||||
else if (*pfirst == ']' && *plast == '=') { strlcpy (A->g_mfr, "Kenwood TM-D710", sizeof(A->g_mfr)); pfirst++; plast--; }
|
else if (*pfirst == ']' && *plast == '=') { strlcpy (A->g_mfr, "Kenwood TM-D710", sizeof(A->g_mfr)); pfirst++; plast--; }
|
||||||
|
@ -1540,6 +1679,7 @@ static void aprs_mic_e (decode_aprs_t *A, packet_t pp, unsigned char *info, int
|
||||||
|
|
||||||
// ' should be used for trackers (not message capable).
|
// ' should be used for trackers (not message capable).
|
||||||
|
|
||||||
|
else if (*pfirst == '\'' && *(plast-1) == '(' && *plast == '5') { strlcpy (A->g_mfr, "Anytone D578UV", sizeof(A->g_mfr)); pfirst++; plast-=2; }
|
||||||
else if (*pfirst == '\'' && *(plast-1) == '(' && *plast == '8') { strlcpy (A->g_mfr, "Anytone D878UV", sizeof(A->g_mfr)); pfirst++; plast-=2; }
|
else if (*pfirst == '\'' && *(plast-1) == '(' && *plast == '8') { strlcpy (A->g_mfr, "Anytone D878UV", sizeof(A->g_mfr)); pfirst++; plast-=2; }
|
||||||
|
|
||||||
else if (*pfirst == '\'' && *(plast-1) == '|' && *plast == '3') { strlcpy (A->g_mfr, "Byonics TinyTrack3", sizeof(A->g_mfr)); pfirst++; plast-=2; }
|
else if (*pfirst == '\'' && *(plast-1) == '|' && *plast == '3') { strlcpy (A->g_mfr, "Byonics TinyTrack3", sizeof(A->g_mfr)); pfirst++; plast-=2; }
|
||||||
|
@ -1635,6 +1775,10 @@ static void aprs_mic_e (decode_aprs_t *A, packet_t pp, unsigned char *info, int
|
||||||
*
|
*
|
||||||
* Cases: :BLNxxxxxx: ... Bulletin.
|
* Cases: :BLNxxxxxx: ... Bulletin.
|
||||||
* :NWSxxxxxx: ... National Weather Service Bulletin.
|
* :NWSxxxxxx: ... National Weather Service Bulletin.
|
||||||
|
* http://www.aprs.org/APRS-docs/WX.TXT
|
||||||
|
* :SKYxxxxxx: ... Need reference.
|
||||||
|
* :CWAxxxxxx: ... Need reference.
|
||||||
|
* :BOMxxxxxx: ... Australian version.
|
||||||
*
|
*
|
||||||
* :xxxxxxxxx:PARM. Telemetry metadata, parameter name
|
* :xxxxxxxxx:PARM. Telemetry metadata, parameter name
|
||||||
* :xxxxxxxxx:UNIT. Telemetry metadata, unit/label
|
* :xxxxxxxxx:UNIT. Telemetry metadata, unit/label
|
||||||
|
@ -1768,19 +1912,36 @@ static void aprs_message (decode_aprs_t *A, unsigned char *info, int ilen, int q
|
||||||
strlcpy (A->g_comment, p->message, sizeof(A->g_comment));
|
strlcpy (A->g_comment, p->message, sizeof(A->g_comment));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#warning = double check.
|
||||||
|
|
||||||
|
// Weather bulletins have addressee starting with NWS, SKY, CWA, or BOM.
|
||||||
|
// The protocol spec and http://www.aprs.org/APRS-docs/WX.TXT state that
|
||||||
|
// the 3 letter prefix must be followed by a dash.
|
||||||
|
// However, https://www.aprs-is.net/WX/ also lists the underscore
|
||||||
|
// alternative for the compressed format. Xastir implements this.
|
||||||
|
|
||||||
else if (strlen(addressee) >= 3 && strncmp(addressee,"NWS",3) == 0) {
|
else if (strlen(addressee) >= 3 && strncmp(addressee,"NWS",3) == 0) {
|
||||||
// NWS-xxxxx
|
|
||||||
|
|
||||||
if (strlen(addressee) >=4 && addressee[3] == '-') {
|
if (strlen(addressee) >=4 && addressee[3] == '-') {
|
||||||
snprintf (A->g_data_type_desc, sizeof(A->g_data_type_desc), "NWS bulletin with identifier \"%s\"", addressee+4);
|
snprintf (A->g_data_type_desc, sizeof(A->g_data_type_desc), "Weather bulletin with identifier \"%s\"", addressee+4);
|
||||||
|
}
|
||||||
|
else if (strlen(addressee) >=4 && addressee[3] == '_') {
|
||||||
|
snprintf (A->g_data_type_desc, sizeof(A->g_data_type_desc), "Compressed Weather bulletin with identifier \"%s\"", addressee+4);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
snprintf (A->g_data_type_desc, sizeof(A->g_data_type_desc), "NWS bulletin with identifier \"%s\", missing - after NWS", addressee+3);
|
snprintf (A->g_data_type_desc, sizeof(A->g_data_type_desc), "Weather bulletin is missing - or _ after %.3s", addressee);
|
||||||
}
|
}
|
||||||
A->g_message_subtype = message_subtype_nws;
|
A->g_message_subtype = message_subtype_nws;
|
||||||
strlcpy (A->g_comment, p->message, sizeof(A->g_comment));
|
strlcpy (A->g_comment, p->message, sizeof(A->g_comment));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (strlen(addressee) >= 3 && (strncmp(addressee,"SKY",3) == 0 || strncmp(addressee,"CWA",3) == 0 || strncmp(addressee,"BOM",3) == 0)) {
|
||||||
|
// SKY... or CWA... https://www.aprs-is.net/WX/
|
||||||
|
snprintf (A->g_data_type_desc, sizeof(A->g_data_type_desc), "Weather bulletin with identifier \"%s\"", addressee+4);
|
||||||
|
A->g_message_subtype = message_subtype_nws;
|
||||||
|
strlcpy (A->g_comment, p->message, sizeof(A->g_comment));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Special message formats contain telemetry metadata.
|
* Special message formats contain telemetry metadata.
|
||||||
|
@ -1794,22 +1955,22 @@ static void aprs_message (decode_aprs_t *A, unsigned char *info, int ilen, int q
|
||||||
*/
|
*/
|
||||||
|
|
||||||
else if (strncmp(p->message,"PARM.",5) == 0) {
|
else if (strncmp(p->message,"PARM.",5) == 0) {
|
||||||
snprintf (A->g_data_type_desc, sizeof(A->g_data_type_desc), "Telemetry Parameter Name Message for \"%s\"", addressee);
|
snprintf (A->g_data_type_desc, sizeof(A->g_data_type_desc), "Telemetry Parameter Name for \"%s\"", addressee);
|
||||||
A->g_message_subtype = message_subtype_telem_parm;
|
A->g_message_subtype = message_subtype_telem_parm;
|
||||||
telemetry_name_message (addressee, p->message+5);
|
telemetry_name_message (addressee, p->message+5);
|
||||||
}
|
}
|
||||||
else if (strncmp(p->message,"UNIT.",5) == 0) {
|
else if (strncmp(p->message,"UNIT.",5) == 0) {
|
||||||
snprintf (A->g_data_type_desc, sizeof(A->g_data_type_desc), "Telemetry Unit/Label Message for \"%s\"", addressee);
|
snprintf (A->g_data_type_desc, sizeof(A->g_data_type_desc), "Telemetry Unit/Label for \"%s\"", addressee);
|
||||||
A->g_message_subtype = message_subtype_telem_unit;
|
A->g_message_subtype = message_subtype_telem_unit;
|
||||||
telemetry_unit_label_message (addressee, p->message+5);
|
telemetry_unit_label_message (addressee, p->message+5);
|
||||||
}
|
}
|
||||||
else if (strncmp(p->message,"EQNS.",5) == 0) {
|
else if (strncmp(p->message,"EQNS.",5) == 0) {
|
||||||
snprintf (A->g_data_type_desc, sizeof(A->g_data_type_desc), "Telemetry Equation Coefficients Message for \"%s\"", addressee);
|
snprintf (A->g_data_type_desc, sizeof(A->g_data_type_desc), "Telemetry Equation Coefficients for \"%s\"", addressee);
|
||||||
A->g_message_subtype = message_subtype_telem_eqns;
|
A->g_message_subtype = message_subtype_telem_eqns;
|
||||||
telemetry_coefficents_message (addressee, p->message+5, quiet);
|
telemetry_coefficents_message (addressee, p->message+5, quiet);
|
||||||
}
|
}
|
||||||
else if (strncmp(p->message,"BITS.",5) == 0) {
|
else if (strncmp(p->message,"BITS.",5) == 0) {
|
||||||
snprintf (A->g_data_type_desc, sizeof(A->g_data_type_desc), "Telemetry Bit Sense/Project Name Message for \"%s\"", addressee);
|
snprintf (A->g_data_type_desc, sizeof(A->g_data_type_desc), "Telemetry Bit Sense/Project Name for \"%s\"", addressee);
|
||||||
A->g_message_subtype = message_subtype_telem_bits;
|
A->g_message_subtype = message_subtype_telem_bits;
|
||||||
telemetry_bit_sense_message (addressee, p->message+5, quiet);
|
telemetry_bit_sense_message (addressee, p->message+5, quiet);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,8 @@ typedef struct decode_aprs_s {
|
||||||
|
|
||||||
int g_quiet; /* Suppress error messages when decoding. */
|
int g_quiet; /* Suppress error messages when decoding. */
|
||||||
|
|
||||||
char g_src[AX25_MAX_ADDR_LEN];
|
char g_src[AX25_MAX_ADDR_LEN]; // In the case of a packet encapsulated by a 3rd party
|
||||||
|
// header, this is the encapsulated source.
|
||||||
|
|
||||||
char g_dest[AX25_MAX_ADDR_LEN];
|
char g_dest[AX25_MAX_ADDR_LEN];
|
||||||
|
|
||||||
|
@ -66,6 +67,24 @@ typedef struct decode_aprs_s {
|
||||||
/* Also for Directed Station Query which is a */
|
/* Also for Directed Station Query which is a */
|
||||||
/* special case of message. */
|
/* special case of message. */
|
||||||
|
|
||||||
|
// This is so pfilter.c:filt_t does not need to duplicate the same work.
|
||||||
|
|
||||||
|
int g_has_thirdparty_header;
|
||||||
|
enum packet_type_e {
|
||||||
|
packet_type_none=0,
|
||||||
|
packet_type_position,
|
||||||
|
packet_type_weather,
|
||||||
|
packet_type_object,
|
||||||
|
packet_type_item,
|
||||||
|
packet_type_message,
|
||||||
|
packet_type_query,
|
||||||
|
packet_type_capabilities,
|
||||||
|
packet_type_status,
|
||||||
|
packet_type_telemetry,
|
||||||
|
packet_type_userdefined,
|
||||||
|
packet_type_nws
|
||||||
|
} g_packet_type;
|
||||||
|
|
||||||
enum message_subtype_e { message_subtype_invalid = 0,
|
enum message_subtype_e { message_subtype_invalid = 0,
|
||||||
message_subtype_message,
|
message_subtype_message,
|
||||||
message_subtype_ack,
|
message_subtype_ack,
|
||||||
|
|
62
src/igate.c
62
src/igate.c
|
@ -1749,9 +1749,34 @@ static void * satgate_delay_thread (void *arg)
|
||||||
*
|
*
|
||||||
*--------------------------------------------------------------------*/
|
*--------------------------------------------------------------------*/
|
||||||
|
|
||||||
// TODO: Use of "message" here is confusing because that term already
|
#warning - clean up
|
||||||
// has a special meaning for APRS. This could be an APRS message or
|
|
||||||
// some other APRS data type. Payload is already used.
|
// It is unforunate that the : data type indicator (DTI) was overloaded with
|
||||||
|
// so many different meanings. Simply looking at the DTI is not adequate for
|
||||||
|
// determining whether a packet is a message.
|
||||||
|
// We need to exclude the other special cases of telemetry metadata,
|
||||||
|
// bulletins, and weather bulletins.
|
||||||
|
|
||||||
|
static int is_message_message (char *infop)
|
||||||
|
{
|
||||||
|
if (*infop != ':') return (0);
|
||||||
|
if (strlen(infop) < 11) return (0); // too short for : addressee :
|
||||||
|
if (strlen(infop) >= 16) {
|
||||||
|
if (strncmp(infop+10, ":PARM.", 6) == 0) return (0);
|
||||||
|
if (strncmp(infop+10, ":UNIT.", 6) == 0) return (0);
|
||||||
|
if (strncmp(infop+10, ":EQNS.", 6) == 0) return (0);
|
||||||
|
if (strncmp(infop+10, ":BITS.", 6) == 0) return (0);
|
||||||
|
}
|
||||||
|
if (strlen(infop) >= 4) {
|
||||||
|
if (strncmp(infop+1, "BLN", 3) == 0) return (0);
|
||||||
|
if (strncmp(infop+1, "NWS", 3) == 0) return (0);
|
||||||
|
if (strncmp(infop+1, "SKY", 3) == 0) return (0);
|
||||||
|
if (strncmp(infop+1, "CWA", 3) == 0) return (0);
|
||||||
|
if (strncmp(infop+1, "BOM", 3) == 0) return (0);
|
||||||
|
}
|
||||||
|
return (1); // message, including ack, rej
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void maybe_xmit_packet_from_igate (char *message, int to_chan)
|
static void maybe_xmit_packet_from_igate (char *message, int to_chan)
|
||||||
{
|
{
|
||||||
|
@ -1843,7 +1868,7 @@ static void maybe_xmit_packet_from_igate (char *message, int to_chan)
|
||||||
* If we recently transmitted a 'message' from some station,
|
* If we recently transmitted a 'message' from some station,
|
||||||
* send the position of the message sender when it comes along later.
|
* send the position of the message sender when it comes along later.
|
||||||
*
|
*
|
||||||
* Some refer to this as a courtesy posit report but I don't
|
* Some refer to this as a "courtesy posit report" but I don't
|
||||||
* think that is an official term.
|
* think that is an official term.
|
||||||
*
|
*
|
||||||
* If we have a position report, look up the sender and see if we should
|
* If we have a position report, look up the sender and see if we should
|
||||||
|
@ -1988,10 +2013,7 @@ static void maybe_xmit_packet_from_igate (char *message, int to_chan)
|
||||||
#endif
|
#endif
|
||||||
stats_rf_xmit_packets++; // Any type of packet.
|
stats_rf_xmit_packets++; // Any type of packet.
|
||||||
|
|
||||||
// TEMP TEST: metadata temporarily allowed during testing.
|
if (is_message_message(pinfo)) {
|
||||||
|
|
||||||
if (*pinfo == ':' && ! is_telem_metadata(pinfo)) {
|
|
||||||
// temp test // if (*pinfo == ':') {
|
|
||||||
|
|
||||||
// We transmitted a "message." Telemetry metadata is excluded.
|
// We transmitted a "message." Telemetry metadata is excluded.
|
||||||
// Remember to pass along address of the sender later.
|
// Remember to pass along address of the sender later.
|
||||||
|
@ -2449,6 +2471,26 @@ void ig_to_tx_remember (packet_t pp, int chan, int bydigi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#warning remove
|
||||||
|
|
||||||
|
static int is_message_overload (char *infop)
|
||||||
|
{
|
||||||
|
if (*infop != ':') return (0);
|
||||||
|
if (strlen(infop) < 16) return (0);
|
||||||
|
if (strncmp(infop+10, ":PARM.", 6) == 0) return (1);
|
||||||
|
if (strncmp(infop+10, ":UNIT.", 6) == 0) return (1);
|
||||||
|
if (strncmp(infop+10, ":EQNS.", 6) == 0) return (1);
|
||||||
|
if (strncmp(infop+10, ":BITS.", 6) == 0) return (1);
|
||||||
|
if (strncmp(infop+1, "BLN", 3) == 0) return (1);
|
||||||
|
if (strncmp(infop+1, "NWS", 3) == 0) return (1);
|
||||||
|
if (strncmp(infop+1, "SKY", 3) == 0) return (1);
|
||||||
|
if (strncmp(infop+1, "CWA", 3) == 0) return (1);
|
||||||
|
if (strncmp(infop+1, "BOM", 3) == 0) return (1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ig_to_tx_allow (packet_t pp, int chan)
|
static int ig_to_tx_allow (packet_t pp, int chan)
|
||||||
{
|
{
|
||||||
unsigned short crc = ax25_dedupe_crc(pp);
|
unsigned short crc = ax25_dedupe_crc(pp);
|
||||||
|
@ -2481,7 +2523,7 @@ static int ig_to_tx_allow (packet_t pp, int chan)
|
||||||
|
|
||||||
/* We have a duplicate within some time period. */
|
/* We have a duplicate within some time period. */
|
||||||
|
|
||||||
if (*pinfo == ':' && ! is_telem_metadata((char*)pinfo)) {
|
if (is_message_message((char*)pinfo)) {
|
||||||
|
|
||||||
/* I think I want to avoid the duplicate suppression for "messages." */
|
/* I think I want to avoid the duplicate suppression for "messages." */
|
||||||
/* Suppose we transmit a message from station X and it doesn't get an ack back. */
|
/* Suppose we transmit a message from station X and it doesn't get an ack back. */
|
||||||
|
@ -2530,7 +2572,7 @@ static int ig_to_tx_allow (packet_t pp, int chan)
|
||||||
/* the normal limit for them. */
|
/* the normal limit for them. */
|
||||||
|
|
||||||
increase_limit = 1;
|
increase_limit = 1;
|
||||||
if (*pinfo == ':' && ! is_telem_metadata((char*)pinfo)) {
|
if (is_message_message((char*)pinfo)) {
|
||||||
increase_limit = 3;
|
increase_limit = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
50
src/mheard.c
50
src/mheard.c
|
@ -336,6 +336,52 @@ void mheard_save_rf (int chan, decode_aprs_t *A, packet_t pp, alevel_t alevel, r
|
||||||
*/
|
*/
|
||||||
|
|
||||||
hops = ax25_get_heard(pp) - AX25_SOURCE;
|
hops = ax25_get_heard(pp) - AX25_SOURCE;
|
||||||
|
/*
|
||||||
|
* Consider the following scenario:
|
||||||
|
*
|
||||||
|
* (1) We hear AA1PR-9 by a path of 4 digipeaters.
|
||||||
|
* Looking closer, it's probably only two because there are left over WIDE1-0 and WIDE2-0.
|
||||||
|
*
|
||||||
|
* Digipeater WIDE2 (probably N3LLO-3) audio level = 72(19/15) [NONE] _|||||___
|
||||||
|
* [0.3] AA1PR-9>APY300,K1EQX-7,WIDE1,N3LLO-3,WIDE2*,ARISS::ANSRVR :cq hotg vt aprsthursday{01<0x0d>
|
||||||
|
* ----- -----
|
||||||
|
*
|
||||||
|
* (2) APRS-IS sends a response to us.
|
||||||
|
*
|
||||||
|
* [ig>tx] ANSRVR>APWW11,KJ4ERJ-15*,TCPIP*,qAS,KJ4ERJ-15::AA1PR-9 :N:HOTG 161 Messages Sent{JL}
|
||||||
|
*
|
||||||
|
* (3) Here is our analysis of whether it should be sent to RF.
|
||||||
|
*
|
||||||
|
* Was message addressee AA1PR-9 heard in the past 180 minutes, with 2 or fewer digipeater hops?
|
||||||
|
* No, AA1PR-9 was last heard over the radio with 4 digipeater hops 0 minutes ago.
|
||||||
|
*
|
||||||
|
* The wrong hop count caused us to drop a packet that should have been transmitted.
|
||||||
|
* We could put in a hack to not count the "WIDEn-0" addresses.
|
||||||
|
* That is not correct because other prefixes could be used and we don't know
|
||||||
|
* what they are for other digipeaters.
|
||||||
|
* I think the best solution is to simply ignore the hop count.
|
||||||
|
* Maybe next release will have a major cleanup.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// HACK - Reduce hop count by number of used WIDEn-0 addresses.
|
||||||
|
|
||||||
|
if (hops > 1) {
|
||||||
|
for (int k = 0; k < ax25_get_num_repeaters(pp); k++) {
|
||||||
|
char digi[AX25_MAX_ADDR_LEN];
|
||||||
|
ax25_get_addr_no_ssid (pp, AX25_REPEATER_1 + k, digi);
|
||||||
|
int ssid = ax25_get_ssid (pp, AX25_REPEATER_1 + k);
|
||||||
|
int used = ax25_get_h (pp, AX25_REPEATER_1 + k);
|
||||||
|
|
||||||
|
//text_color_set(DW_COLOR_DEBUG);
|
||||||
|
//dw_printf ("Examining %s-%d used=%d.\n", digi, ssid, used);
|
||||||
|
|
||||||
|
if (used && strlen(digi) == 5 && strncmp(digi, "WIDE", 4) == 0 && isdigit(digi[4]) && ssid == 0) {
|
||||||
|
hops--;
|
||||||
|
//text_color_set(DW_COLOR_DEBUG);
|
||||||
|
//dw_printf ("Decrease hop count to %d for problematic %s.\n", hops, digi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mptr = mheard_ptr(source);
|
mptr = mheard_ptr(source);
|
||||||
if (mptr == NULL) {
|
if (mptr == NULL) {
|
||||||
|
@ -571,7 +617,7 @@ void mheard_save_is (char *ptext)
|
||||||
* 8 for RF_CNT.
|
* 8 for RF_CNT.
|
||||||
*
|
*
|
||||||
* time_limit - Include only stations heard within this many minutes.
|
* time_limit - Include only stations heard within this many minutes.
|
||||||
* Typically 30 or 60.
|
* Typically 180.
|
||||||
*
|
*
|
||||||
* Returns: Number to be used in the statistics report.
|
* Returns: Number to be used in the statistics report.
|
||||||
*
|
*
|
||||||
|
@ -649,7 +695,7 @@ int mheard_count (int max_hops, int time_limit)
|
||||||
* callsign - Callsign for station.
|
* callsign - Callsign for station.
|
||||||
*
|
*
|
||||||
* time_limit - Include only stations heard within this many minutes.
|
* time_limit - Include only stations heard within this many minutes.
|
||||||
* Typically 30 or 60.
|
* Typically 180.
|
||||||
*
|
*
|
||||||
* max_hops - Include only stations heard with this number of
|
* max_hops - Include only stations heard with this number of
|
||||||
* digipeater hops or less. For reporting, we might use:
|
* digipeater hops or less. For reporting, we might use:
|
||||||
|
|
252
src/pfilter.c
252
src/pfilter.c
|
@ -1,7 +1,7 @@
|
||||||
//
|
//
|
||||||
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
// This file is part of Dire Wolf, an amateur radio packet TNC.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2015, 2016 John Langner, WB2OSZ
|
// Copyright (C) 2015, 2016, 2023 John Langner, WB2OSZ
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// 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
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
@ -546,7 +546,8 @@ static int parse_filter_spec (pfstate_t *pf)
|
||||||
/* b - budlist */
|
/* b - budlist */
|
||||||
|
|
||||||
else if (pf->token_str[0] == 'b' && ispunct(pf->token_str[1])) {
|
else if (pf->token_str[0] == 'b' && ispunct(pf->token_str[1])) {
|
||||||
/* Budlist - source address */
|
/* Budlist - AX.25 source address */
|
||||||
|
/* Could be different than source encapsulated by 3rd party header. */
|
||||||
char addr[AX25_MAX_ADDR_LEN];
|
char addr[AX25_MAX_ADDR_LEN];
|
||||||
ax25_get_addr_with_ssid (pf->pp, AX25_SOURCE, addr);
|
ax25_get_addr_with_ssid (pf->pp, AX25_SOURCE, addr);
|
||||||
result = filt_bodgu (pf, addr);
|
result = filt_bodgu (pf, addr);
|
||||||
|
@ -572,7 +573,7 @@ static int parse_filter_spec (pfstate_t *pf)
|
||||||
|
|
||||||
else if (pf->token_str[0] == 'd' && ispunct(pf->token_str[1])) {
|
else if (pf->token_str[0] == 'd' && ispunct(pf->token_str[1])) {
|
||||||
int n;
|
int n;
|
||||||
// loop on all digipeaters
|
// Loop on all AX.25 digipeaters.
|
||||||
result = 0;
|
result = 0;
|
||||||
for (n = AX25_REPEATER_1; result == 0 && n < ax25_get_num_addr (pf->pp); n++) {
|
for (n = AX25_REPEATER_1; result == 0 && n < ax25_get_num_addr (pf->pp); n++) {
|
||||||
// Consider only those with the H (has-been-used) bit set.
|
// Consider only those with the H (has-been-used) bit set.
|
||||||
|
@ -599,7 +600,7 @@ static int parse_filter_spec (pfstate_t *pf)
|
||||||
|
|
||||||
else if (pf->token_str[0] == 'v' && ispunct(pf->token_str[1])) {
|
else if (pf->token_str[0] == 'v' && ispunct(pf->token_str[1])) {
|
||||||
int n;
|
int n;
|
||||||
// loop on all digipeaters (mnemonic Via)
|
// loop on all AX.25 digipeaters (mnemonic Via)
|
||||||
result = 0;
|
result = 0;
|
||||||
for (n = AX25_REPEATER_1; result == 0 && n < ax25_get_num_addr (pf->pp); n++) {
|
for (n = AX25_REPEATER_1; result == 0 && n < ax25_get_num_addr (pf->pp); n++) {
|
||||||
// This is different than the previous "d" filter.
|
// This is different than the previous "d" filter.
|
||||||
|
@ -623,10 +624,15 @@ static int parse_filter_spec (pfstate_t *pf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* g - Addressee of message. */
|
/* g - Addressee of message. e.g. "BLN*" for bulletins. */
|
||||||
|
|
||||||
else if (pf->token_str[0] == 'g' && ispunct(pf->token_str[1])) {
|
else if (pf->token_str[0] == 'g' && ispunct(pf->token_str[1])) {
|
||||||
if (ax25_get_dti(pf->pp) == ':') {
|
if (pf->decoded.g_message_subtype == message_subtype_message ||
|
||||||
|
pf->decoded.g_message_subtype == message_subtype_ack ||
|
||||||
|
pf->decoded.g_message_subtype == message_subtype_rej ||
|
||||||
|
pf->decoded.g_message_subtype == message_subtype_bulletin ||
|
||||||
|
pf->decoded.g_message_subtype == message_subtype_nws ||
|
||||||
|
pf->decoded.g_message_subtype == message_subtype_directed_query) {
|
||||||
result = filt_bodgu (pf, pf->decoded.g_addressee);
|
result = filt_bodgu (pf, pf->decoded.g_addressee);
|
||||||
|
|
||||||
if (s_debug >= 2) {
|
if (s_debug >= 2) {
|
||||||
|
@ -643,7 +649,7 @@ static int parse_filter_spec (pfstate_t *pf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* u - unproto (destination) */
|
/* u - unproto (AX.25 destination) */
|
||||||
|
|
||||||
else if (pf->token_str[0] == 'u' && ispunct(pf->token_str[1])) {
|
else if (pf->token_str[0] == 'u' && ispunct(pf->token_str[1])) {
|
||||||
/* Probably want to exclude mic-e types */
|
/* Probably want to exclude mic-e types */
|
||||||
|
@ -668,7 +674,7 @@ static int parse_filter_spec (pfstate_t *pf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* t - type: position, weather, etc. */
|
/* t - packet type: position, weather, telemetry, etc. */
|
||||||
|
|
||||||
else if (pf->token_str[0] == 't' && ispunct(pf->token_str[1])) {
|
else if (pf->token_str[0] == 't' && ispunct(pf->token_str[1])) {
|
||||||
|
|
||||||
|
@ -728,7 +734,7 @@ static int parse_filter_spec (pfstate_t *pf)
|
||||||
(void) ax25_get_info (pf->pp, (unsigned char **)(&infop));
|
(void) ax25_get_info (pf->pp, (unsigned char **)(&infop));
|
||||||
|
|
||||||
text_color_set(DW_COLOR_DEBUG);
|
text_color_set(DW_COLOR_DEBUG);
|
||||||
if (*infop == ':' && ! is_telem_metadata(infop)) {
|
if (pf->decoded.g_packet_type == packet_type_message) {
|
||||||
dw_printf (" %s returns %s for message to %s\n", pf->token_str, bool2text(result), pf->decoded.g_addressee);
|
dw_printf (" %s returns %s for message to %s\n", pf->token_str, bool2text(result), pf->decoded.g_addressee);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -832,31 +838,17 @@ static int filt_bodgu (pfstate_t *pf, char *arg)
|
||||||
* 0 = no
|
* 0 = no
|
||||||
* -1 = error detected
|
* -1 = error detected
|
||||||
*
|
*
|
||||||
* Description: The filter is based the type filtering described here:
|
* Description: The filter is loosely based the type filtering described here:
|
||||||
* http://www.aprs-is.net/javAPRSFilter.aspx
|
* http://www.aprs-is.net/javAPRSFilter.aspx
|
||||||
*
|
*
|
||||||
* Most of these simply check the first byte of the information part.
|
* Mostly use g_packet_type and g_message_subtype from decode_aprs.
|
||||||
* Trying to detect NWS information is a little trickier.
|
*
|
||||||
|
* References:
|
||||||
* http://www.aprs-is.net/WX/
|
* http://www.aprs-is.net/WX/
|
||||||
* http://wxsvr.aprs.net.au/protocol-new.html
|
* http://wxsvr.aprs.net.au/protocol-new.html (has disappeared)
|
||||||
*
|
*
|
||||||
*------------------------------------------------------------------------------*/
|
*------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* Telemetry metadata is a special case of message. */
|
|
||||||
/* We want to categorize it as telemetry rather than message. */
|
|
||||||
|
|
||||||
int is_telem_metadata (char *infop)
|
|
||||||
{
|
|
||||||
if (*infop != ':') return (0);
|
|
||||||
if (strlen(infop) < 16) return (0);
|
|
||||||
if (strncmp(infop+10, ":PARM.", 6) == 0) return (1);
|
|
||||||
if (strncmp(infop+10, ":UNIT.", 6) == 0) return (1);
|
|
||||||
if (strncmp(infop+10, ":EQNS.", 6) == 0) return (1);
|
|
||||||
if (strncmp(infop+10, ":BITS.", 6) == 0) return (1);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int filt_t (pfstate_t *pf)
|
static int filt_t (pfstate_t *pf)
|
||||||
{
|
{
|
||||||
char src[AX25_MAX_ADDR_LEN];
|
char src[AX25_MAX_ADDR_LEN];
|
||||||
|
@ -873,108 +865,60 @@ static int filt_t (pfstate_t *pf)
|
||||||
switch (*f) {
|
switch (*f) {
|
||||||
|
|
||||||
case 'p': /* Position */
|
case 'p': /* Position */
|
||||||
if (*infop == '!') return (1);
|
if (pf->decoded.g_packet_type == packet_type_position) return(1);
|
||||||
if (*infop == '/') return (1);
|
|
||||||
if (*infop == '=') return (1);
|
|
||||||
if (*infop == '@') return (1);
|
|
||||||
if (*infop == '\'') return (1); // MIC-E
|
|
||||||
if (*infop == '`') return (1); // MIC-E
|
|
||||||
|
|
||||||
// What if we have "_" symbol code for weather?
|
|
||||||
// Still consider as position.
|
|
||||||
// The same packet can match more than one type here.
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'o': /* Object */
|
case 'o': /* Object */
|
||||||
if (*infop == ';') return (1);
|
if (pf->decoded.g_packet_type == packet_type_object) return(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'i': /* Item */
|
case 'i': /* Item */
|
||||||
if (*infop == ')') return (1);
|
if (pf->decoded.g_packet_type == packet_type_item) return(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'm': /* Message */
|
case 'm': // Any "message."
|
||||||
if (*infop == ':' && ! is_telem_metadata(infop)) return (1);
|
if (pf->decoded.g_packet_type == packet_type_message) return(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'q': /* Query */
|
case 'q': /* Query */
|
||||||
if (*infop == '?') return (1);
|
if (pf->decoded.g_packet_type == packet_type_query) return(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'c': /* station Capabilities - my extension */
|
case 'c': /* station Capabilities - my extension */
|
||||||
/* Most often used for IGate statistics. */
|
/* Most often used for IGate statistics. */
|
||||||
if (*infop == '<') return (1);
|
if (pf->decoded.g_packet_type == packet_type_capabilities) return(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's': /* Status */
|
case 's': /* Status */
|
||||||
if (*infop == '>') return (1);
|
if (pf->decoded.g_packet_type == packet_type_status) return(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't': /* Telemetry */
|
case 't': /* Telemetry data or metadata */
|
||||||
if (*infop == 'T') return (1);
|
if (pf->decoded.g_packet_type == packet_type_telemetry) return(1);
|
||||||
if (is_telem_metadata(infop)) return (1);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'u': /* User-defined */
|
case 'u': /* User-defined */
|
||||||
if (*infop == '{') return (1);
|
if (pf->decoded.g_packet_type == packet_type_userdefined) return(1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'h': /* third party Header - my extension */
|
case 'h': /* has third party Header - my extension */
|
||||||
if (*infop == '}') return (1);
|
if (pf->decoded.g_has_thirdparty_header) return (1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'w': /* Weather */
|
case 'w': /* Weather */
|
||||||
|
|
||||||
if (*infop == '*') return (1); // Peet Bros
|
if (pf->decoded.g_packet_type == packet_type_weather) return(1);
|
||||||
if (*infop == '_') return (1); // Weather report, no position.
|
|
||||||
if (strncmp(infop, "!!", 2) == 0) return(1); // Ultimeter 2000.
|
|
||||||
|
|
||||||
/* '$' is normally raw GPS. Check for special case. */
|
|
||||||
|
|
||||||
if (strncmp(infop, "$ULTW", 5) == 0) return (1);
|
|
||||||
|
|
||||||
/* Positions !=/@ with symbol code _ are weather. */
|
|
||||||
|
|
||||||
if (strchr("!=/@", *infop) != NULL &&
|
|
||||||
pf->decoded.g_symbol_code == '_') return (1);
|
|
||||||
|
|
||||||
|
/* Positions !=/@ with symbol code _ are weather. */
|
||||||
/* Object with _ symbol is also weather. APRS protocol spec page 66. */
|
/* Object with _ symbol is also weather. APRS protocol spec page 66. */
|
||||||
|
// Can't use *infop because it would not work with 3rd party header.
|
||||||
|
|
||||||
if (*infop == ';' &&
|
if ((pf->decoded.g_packet_type == packet_type_position ||
|
||||||
pf->decoded.g_symbol_code == '_') return (1);
|
pf->decoded.g_packet_type == packet_type_object) && pf->decoded.g_symbol_code == '_') return (1);
|
||||||
|
|
||||||
// TODO: need more test cases at end for new weather cases.
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'n': /* NWS format */
|
case 'n': /* NWS format */
|
||||||
/*
|
if (pf->decoded.g_packet_type == packet_type_nws) return(1);
|
||||||
* This is the interesting case.
|
|
||||||
* The source must be exactly 6 upper case letters, no SSID.
|
|
||||||
*/
|
|
||||||
if (strlen(src) != 6) break;
|
|
||||||
if (! isupper(src[0])) break;
|
|
||||||
if (! isupper(src[1])) break;
|
|
||||||
if (! isupper(src[2])) break;
|
|
||||||
if (! isupper(src[3])) break;
|
|
||||||
if (! isupper(src[4])) break;
|
|
||||||
if (! isupper(src[5])) break;
|
|
||||||
/*
|
|
||||||
* We can have a "message" with addressee starting with NWS, SKY, or BOM (Australian version.)
|
|
||||||
*/
|
|
||||||
if (strncmp(infop, ":NWS", 4) == 0) return (1);
|
|
||||||
if (strncmp(infop, ":SKY", 4) == 0) return (1);
|
|
||||||
if (strncmp(infop, ":BOM", 4) == 0) return (1);
|
|
||||||
/*
|
|
||||||
* Or we can have an object.
|
|
||||||
* It's not exactly clear how to distinguish this from other objects.
|
|
||||||
* It looks like the first 3 characters of the source should be the same
|
|
||||||
* as the first 3 characters of the addressee.
|
|
||||||
*/
|
|
||||||
if (infop[0] == ';' &&
|
|
||||||
infop[1] == src[0] &&
|
|
||||||
infop[2] == src[1] &&
|
|
||||||
infop[3] == src[2]) return (1);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -990,6 +934,7 @@ static int filt_t (pfstate_t *pf)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Name: filt_r
|
* Name: filt_r
|
||||||
|
@ -1327,8 +1272,36 @@ static int filt_s (pfstate_t *pf)
|
||||||
*
|
*
|
||||||
* IMHO, the rules here are too restrictive.
|
* IMHO, the rules here are too restrictive.
|
||||||
*
|
*
|
||||||
* (1) The APRS-IS would send a "message" to my IGate only if the addressee
|
* The APRS-IS would send a "message" to my IGate only if the addressee
|
||||||
* has been heard nearby recently. 180 minutes, I believe.
|
* has been heard nearby recently. 180 minutes, I believe.
|
||||||
|
* Why would I not want to transmit it?
|
||||||
|
*
|
||||||
|
* Discussion: In retrospect, I think this is far too complicated.
|
||||||
|
* In a future release, I think at options other than time should be removed.
|
||||||
|
* Messages have more value than most packets. Why reduce the chance of successful delivery?
|
||||||
|
*
|
||||||
|
* Consider the following scenario:
|
||||||
|
*
|
||||||
|
* (1) We hear AA1PR-9 by a path of 4 digipeaters.
|
||||||
|
* Looking closer, it's probably only two because there are left over WIDE1-0 and WIDE2-0.
|
||||||
|
*
|
||||||
|
* Digipeater WIDE2 (probably N3LLO-3) audio level = 72(19/15) [NONE] _|||||___
|
||||||
|
* [0.3] AA1PR-9>APY300,K1EQX-7,WIDE1,N3LLO-3,WIDE2*,ARISS::ANSRVR :cq hotg vt aprsthursday{01<0x0d>
|
||||||
|
*
|
||||||
|
* (2) APRS-IS sends a response to us.
|
||||||
|
*
|
||||||
|
* [ig>tx] ANSRVR>APWW11,KJ4ERJ-15*,TCPIP*,qAS,KJ4ERJ-15::AA1PR-9 :N:HOTG 161 Messages Sent{JL}
|
||||||
|
*
|
||||||
|
* (3) Here is our analysis of whether it should be sent to RF.
|
||||||
|
*
|
||||||
|
* Was message addressee AA1PR-9 heard in the past 180 minutes, with 2 or fewer digipeater hops?
|
||||||
|
* No, AA1PR-9 was last heard over the radio with 4 digipeater hops 0 minutes ago.
|
||||||
|
*
|
||||||
|
* The wrong hop count caused us to drop a packet that should have been transmitted.
|
||||||
|
* We could put in a hack to not count the "WIDE*-0" addresses.
|
||||||
|
* That is not correct because other prefixes could be used and we don't know
|
||||||
|
* what they are for other digipeaters.
|
||||||
|
* I think the best solution is to simply ignore the hop count.
|
||||||
*
|
*
|
||||||
*------------------------------------------------------------------------------*/
|
*------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -1357,9 +1330,9 @@ static int filt_i (pfstate_t *pf)
|
||||||
double km = G_UNKNOWN;
|
double km = G_UNKNOWN;
|
||||||
|
|
||||||
|
|
||||||
char src[AX25_MAX_ADDR_LEN];
|
//char src[AX25_MAX_ADDR_LEN];
|
||||||
char *infop = NULL;
|
//char *infop = NULL;
|
||||||
int info_len;
|
//int info_len;
|
||||||
//char *f;
|
//char *f;
|
||||||
//char addressee[AX25_MAX_ADDR_LEN];
|
//char addressee[AX25_MAX_ADDR_LEN];
|
||||||
|
|
||||||
|
@ -1433,20 +1406,7 @@ static int filt_i (pfstate_t *pf)
|
||||||
* Get source address and info part.
|
* Get source address and info part.
|
||||||
* Addressee has already been extracted into pf->decoded.g_addressee.
|
* Addressee has already been extracted into pf->decoded.g_addressee.
|
||||||
*/
|
*/
|
||||||
|
if (pf->decoded.g_packet_type != packet_type_message) return(0);
|
||||||
memset (src, 0, sizeof(src));
|
|
||||||
ax25_get_addr_with_ssid (pf->pp, AX25_SOURCE, src);
|
|
||||||
info_len = ax25_get_info (pf->pp, (unsigned char **)(&infop));
|
|
||||||
|
|
||||||
if (infop == NULL) return (0);
|
|
||||||
if (info_len < 1) return (0);
|
|
||||||
|
|
||||||
// Determine packet type. We are interested only in "message."
|
|
||||||
// Telemetry metadata is not considered a message.
|
|
||||||
|
|
||||||
if (*infop != ':') return (0);
|
|
||||||
if (is_telem_metadata(infop)) return (0);
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(PFTEST) || defined(DIGITEST) // TODO: test functionality too, not just syntax.
|
#if defined(PFTEST) || defined(DIGITEST) // TODO: test functionality too, not just syntax.
|
||||||
|
|
||||||
|
@ -1486,7 +1446,7 @@ static int filt_i (pfstate_t *pf)
|
||||||
* the past minute, rather than the usual 180 minutes for the addressee.
|
* the past minute, rather than the usual 180 minutes for the addressee.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
was_heard = mheard_was_recently_nearby ("source", src, 1, 0, G_UNKNOWN, G_UNKNOWN, G_UNKNOWN);
|
was_heard = mheard_was_recently_nearby ("source", pf->decoded.g_src, 1, 0, G_UNKNOWN, G_UNKNOWN, G_UNKNOWN);
|
||||||
|
|
||||||
if (was_heard) return (0);
|
if (was_heard) return (0);
|
||||||
|
|
||||||
|
@ -1640,24 +1600,29 @@ int main ()
|
||||||
pftest (112, "t/t", "WM1X>APU25N:@210147z4235.39N/07106.58W_359/000g000t027r000P000p000h89b10234/WX REPORT {UIV32N}<0x0d>", 0);
|
pftest (112, "t/t", "WM1X>APU25N:@210147z4235.39N/07106.58W_359/000g000t027r000P000p000h89b10234/WX REPORT {UIV32N}<0x0d>", 0);
|
||||||
pftest (113, "t/w", "WM1X>APU25N:@210147z4235.39N/07106.58W_359/000g000t027r000P000p000h89b10234/WX REPORT {UIV32N}<0x0d>", 1);
|
pftest (113, "t/w", "WM1X>APU25N:@210147z4235.39N/07106.58W_359/000g000t027r000P000p000h89b10234/WX REPORT {UIV32N}<0x0d>", 1);
|
||||||
|
|
||||||
/* Telemetry metadata is a special case of message. */
|
/* Telemetry metadata should not be classified as message. */
|
||||||
pftest (114, "t/t", "KJ4SNT>APMI04::KJ4SNT :PARM.Vin,Rx1h,Dg1h,Eff1h,Rx10m,O1,O2,O3,O4,I1,I2,I3,I4", 1);
|
pftest (114, "t/t", "KJ4SNT>APMI04::KJ4SNT :PARM.Vin,Rx1h,Dg1h,Eff1h,Rx10m,O1,O2,O3,O4,I1,I2,I3,I4", 1);
|
||||||
pftest (115, "t/m", "KJ4SNT>APMI04::KJ4SNT :PARM.Vin,Rx1h,Dg1h,Eff1h,Rx10m,O1,O2,O3,O4,I1,I2,I3,I4", 0);
|
pftest (115, "t/m", "KJ4SNT>APMI04::KJ4SNT :PARM.Vin,Rx1h,Dg1h,Eff1h,Rx10m,O1,O2,O3,O4,I1,I2,I3,I4", 0);
|
||||||
pftest (116, "t/t", "KB1GKN-10>APRX27,UNCAN,WIDE1*:T#491,4.9,0.3,25.0,0.0,1.0,00000000", 1);
|
pftest (116, "t/t", "KB1GKN-10>APRX27,UNCAN,WIDE1*:T#491,4.9,0.3,25.0,0.0,1.0,00000000", 1);
|
||||||
|
|
||||||
|
/* Bulletins should not be considered to be messages. Was bug in 1.6. */
|
||||||
|
pftest (117, "t/m", "A>B::W1AW :test", 1);
|
||||||
|
pftest (118, "t/m", "A>B::BLN :test", 0);
|
||||||
|
pftest (119, "t/m", "A>B::NWS :test", 0);
|
||||||
|
|
||||||
pftest (120, "t/p", "CWAPID>APRS::NWS-TTTTT:DDHHMMz,ADVISETYPE,zcs{seq#", 0);
|
// https://www.aprs-is.net/WX/
|
||||||
|
pftest (121, "t/p", "CWAPID>APRS::NWS-TTTTT:DDHHMMz,ADVISETYPE,zcs{seq#", 0);
|
||||||
pftest (122, "t/p", "CWAPID>APRS::SKYCWA :DDHHMMz,ADVISETYPE,zcs{seq#", 0);
|
pftest (122, "t/p", "CWAPID>APRS::SKYCWA :DDHHMMz,ADVISETYPE,zcs{seq#", 0);
|
||||||
pftest (123, "t/p", "CWAPID>APRS:;CWAttttz *DDHHMMzLATLONICONADVISETYPE{seq#", 0);
|
pftest (123, "t/p", "CWAPID>APRS:;CWAttttz *DDHHMMzLATLONICONADVISETYPE{seq#", 0);
|
||||||
pftest (124, "t/n", "CWAPID>APRS::NWS-TTTTT:DDHHMMz,ADVISETYPE,zcs{seq#", 1);
|
pftest (124, "t/n", "CWAPID>APRS::NWS-TTTTT:DDHHMMz,ADVISETYPE,zcs{seq#", 1);
|
||||||
pftest (125, "t/n", "CWAPID>APRS::SKYCWA :DDHHMMz,ADVISETYPE,zcs{seq#", 1);
|
pftest (125, "t/n", "CWAPID>APRS::SKYCWA :DDHHMMz,ADVISETYPE,zcs{seq#", 1);
|
||||||
pftest (126, "t/n", "CWAPID>APRS:;CWAttttz *DDHHMMzLATLONICONADVISETYPE{seq#", 1);
|
//pftest (126, "t/n", "CWAPID>APRS:;CWAttttz *DDHHMMzLATLONICONADVISETYPE{seq#", 1);
|
||||||
pftest (127, "t/", "CWAPID>APRS:;CWAttttz *DDHHMMzLATLONICONADVISETYPE{seq#", 0);
|
pftest (127, "t/", "CWAPID>APRS:;CWAttttz *DDHHMMzLATLONICONADVISETYPE{seq#", 0);
|
||||||
|
|
||||||
pftest (128, "t/c", "S0RCE>DEST:<stationcapabilities", 1);
|
pftest (128, "t/c", "S0RCE>DEST:<stationcapabilities", 1);
|
||||||
pftest (129, "t/h", "S0RCE>DEST:<stationcapabilities", 0);
|
pftest (129, "t/h", "S0RCE>DEST:<stationcapabilities", 0);
|
||||||
pftest (130, "t/h", "S0RCE>DEST:}thirdpartyheaderwhatever", 1);
|
pftest (130, "t/h", "S0RCE>DEST:}WB2OSZ-5>APDW12,DIGI1,DIGI2*,DIGI3,DIGI4:!4237.14NS07120.83W#PHG7140Chelmsford MA", 1);
|
||||||
pftest (131, "t/c", "S0RCE>DEST:}thirdpartyheaderwhatever", 0);
|
pftest (131, "t/c", "S0RCE>DEST:}WB2OSZ-5>APDW12,DIGI1,DIGI2*,DIGI3,DIGI4:!4237.14NS07120.83W#PHG7140Chelmsford MA", 0);
|
||||||
|
|
||||||
pftest (140, "r/42.6/-71.3/10", "WB2OSZ-5>APDW12,WIDE1-1,WIDE2-1:!4237.14NS07120.83W#PHG7140Chelmsford MA", 1);
|
pftest (140, "r/42.6/-71.3/10", "WB2OSZ-5>APDW12,WIDE1-1,WIDE2-1:!4237.14NS07120.83W#PHG7140Chelmsford MA", 1);
|
||||||
pftest (141, "r/42.6/-71.3/10", "WA1PLE-5>APWW10,W1MHL,N8VIM,WIDE2*:@022301h4208.75N/07115.16WoAPRS-IS for Win32", 0);
|
pftest (141, "r/42.6/-71.3/10", "WA1PLE-5>APWW10,W1MHL,N8VIM,WIDE2*:@022301h4208.75N/07115.16WoAPRS-IS for Win32", 0);
|
||||||
|
@ -1712,13 +1677,13 @@ int main ()
|
||||||
pftest (203, "t/w t/w", "CWAPID>APRS:;CWAttttz *DDHHMMzLATLONICONADVISETYPE{seq#", -1);
|
pftest (203, "t/w t/w", "CWAPID>APRS:;CWAttttz *DDHHMMzLATLONICONADVISETYPE{seq#", -1);
|
||||||
pftest (204, "r/42.6/-71.3", "WA1PLE-5>APWW10,W1MHL,N8VIM,WIDE2*:@022301h4208.75N/07115.16WoAPRS-IS for Win32", -1);
|
pftest (204, "r/42.6/-71.3", "WA1PLE-5>APWW10,W1MHL,N8VIM,WIDE2*:@022301h4208.75N/07115.16WoAPRS-IS for Win32", -1);
|
||||||
|
|
||||||
pftest (220, "i/30/8/42.6/-71.3/50", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", 1);
|
pftest (210, "i/30/8/42.6/-71.3/50", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", 1);
|
||||||
pftest (222, "i/30/8/42.6/-71.3/", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", -1);
|
pftest (212, "i/30/8/42.6/-71.3/", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", -1);
|
||||||
pftest (223, "i/30/8/42.6/-71.3", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", -1);
|
pftest (213, "i/30/8/42.6/-71.3", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", -1);
|
||||||
pftest (224, "i/30/8/42.6/", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", -1);
|
pftest (214, "i/30/8/42.6/", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", -1);
|
||||||
pftest (225, "i/30/8/42.6", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", -1);
|
pftest (215, "i/30/8/42.6", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", -1);
|
||||||
pftest (226, "i/30/8/", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", 1);
|
pftest (216, "i/30/8/", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", 1);
|
||||||
pftest (227, "i/30/8", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", 1);
|
pftest (217, "i/30/8", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", 1);
|
||||||
|
|
||||||
// FIXME: behaves differently on Windows and Linux. Why?
|
// FIXME: behaves differently on Windows and Linux. Why?
|
||||||
// On Windows we have our own version of strsep because it's not in the MS library.
|
// On Windows we have our own version of strsep because it's not in the MS library.
|
||||||
|
@ -1726,7 +1691,12 @@ int main ()
|
||||||
//pftest (228, "i/30/", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", 1);
|
//pftest (228, "i/30/", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", 1);
|
||||||
|
|
||||||
pftest (229, "i/30", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", 1);
|
pftest (229, "i/30", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", 1);
|
||||||
pftest (230, "i/", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", -1);
|
pftest (230, "i/30", "X>X:}WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", 1);
|
||||||
|
pftest (231, "i/", "WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", -1);
|
||||||
|
|
||||||
|
// Besure bulletins and telemetry metadata don't get included.
|
||||||
|
pftest (234, "i/30", "KJ4SNT>APMI04::KJ4SNT :PARM.Vin,Rx1h,Dg1h,Eff1h,Rx10m,O1,O2,O3,O4,I1,I2,I3,I4", 0);
|
||||||
|
pftest (235, "i/30", "A>B::BLN :test", 0);
|
||||||
|
|
||||||
pftest (240, "s/", "WB2OSZ-5>APDW12:!4237.14N/07120.83WOPHG7140Chelmsford MA", -1);
|
pftest (240, "s/", "WB2OSZ-5>APDW12:!4237.14N/07120.83WOPHG7140Chelmsford MA", -1);
|
||||||
pftest (241, "s/'/O/-/#/_", "WB2OSZ-5>APDW12:!4237.14N/07120.83WOPHG7140Chelmsford MA", -1);
|
pftest (241, "s/'/O/-/#/_", "WB2OSZ-5>APDW12:!4237.14N/07120.83WOPHG7140Chelmsford MA", -1);
|
||||||
|
@ -1736,12 +1706,36 @@ int main ()
|
||||||
pftest (245, "s//", "WB2OSZ-5>APDW12:!4237.14N/07120.83WOPHG7140Chelmsford MA", -1);
|
pftest (245, "s//", "WB2OSZ-5>APDW12:!4237.14N/07120.83WOPHG7140Chelmsford MA", -1);
|
||||||
pftest (246, "s///", "WB2OSZ-5>APDW12:!4237.14N/07120.83WOPHG7140Chelmsford MA", -1);
|
pftest (246, "s///", "WB2OSZ-5>APDW12:!4237.14N/07120.83WOPHG7140Chelmsford MA", -1);
|
||||||
|
|
||||||
|
// Third party header - done properly in 1.7.
|
||||||
|
// Packet filter t/h is no longer a mutually exclusive packet type.
|
||||||
|
// Now it is an independent attribute and the encapsulated part is evaluated.
|
||||||
|
|
||||||
// TODO: to be continued...
|
pftest (250, "o/home", "A>B:}WB2OSZ>APDW12,WIDE1-1,WIDE2-1:;home *111111z4237.14N/07120.83W-Chelmsford MA", 1);
|
||||||
|
pftest (251, "t/p", "A>B:}W1WRA-7>TRSY3T,WIDE1-1,WIDE2-1:`c-:l!hK\\>\"4b}=<0x0d>", 1);
|
||||||
|
pftest (252, "i/180", "A>B:}WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", 1);
|
||||||
|
pftest (253, "t/m", "A>B:}WB2OSZ-5>APDW14::W2UB :Happy Birthday{001", 1);
|
||||||
|
pftest (254, "r/42.6/-71.3/10", "A>B:}WB2OSZ-5>APDW12,WIDE1-1,WIDE2-1:!4237.14NS07120.83W#PHG7140Chelmsford MA", 1);
|
||||||
|
pftest (254, "r/42.6/-71.3/10", "A>B:}WA1PLE-5>APWW10,W1MHL,N8VIM,WIDE2*:@022301h4208.75N/07115.16WoAPRS-IS for Win32", 0);
|
||||||
|
pftest (255, "t/h", "KB1GKN-10>APRX27,UNCAN,WIDE1*:T#491,4.9,0.3,25.0,0.0,1.0,00000000", 0);
|
||||||
|
pftest (256, "t/h", "A>B:}KB1GKN-10>APRX27,UNCAN,WIDE1*:T#491,4.9,0.3,25.0,0.0,1.0,00000000", 1);
|
||||||
|
pftest (258, "t/t", "A>B:}KB1GKN-10>APRX27,UNCAN,WIDE1*:T#491,4.9,0.3,25.0,0.0,1.0,00000000", 1);
|
||||||
|
pftest (259, "t/t", "A>B:}KJ4SNT>APMI04::KJ4SNT :PARM.Vin,Rx1h,Dg1h,Eff1h,Rx10m,O1,O2,O3,O4,I1,I2,I3,I4", 1);
|
||||||
|
|
||||||
|
pftest (270, "g/BLN*", "WB2OSZ>APDW17::BLN1xxxxx:bulletin text", 1);
|
||||||
|
pftest (271, "g/BLN*", "A>B:}WB2OSZ>APDW17::BLN1xxxxx:bulletin text", 1);
|
||||||
|
pftest (272, "g/BLN*", "A>B:}WB2OSZ>APDW17::W1AW :xxxx", 0);
|
||||||
|
|
||||||
|
pftest (273, "g/NWS*", "WB2OSZ>APDW17::NWS-xxxxx:weather bulletin", 1);
|
||||||
|
pftest (274, "g/NWS*", "A>B:}WB2OSZ>APDW17::NWS-xxxxx:weather bulletin", 1);
|
||||||
|
pftest (275, "g/NWS*", "A>B:}WB2OSZ>APDW17::W1AW :xxxx", 0);
|
||||||
|
|
||||||
|
// TODO: add b/ with 3rd party header.
|
||||||
|
|
||||||
|
// TODO: to be continued... directed query ...
|
||||||
|
|
||||||
if (error_count > 0) {
|
if (error_count > 0) {
|
||||||
text_color_set (DW_COLOR_ERROR);
|
text_color_set (DW_COLOR_ERROR);
|
||||||
dw_printf ("\nPacket Filtering Test - FAILED!\n");
|
dw_printf ("\nPacket Filtering Test - FAILED! %d errors\n", error_count);
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
text_color_set (DW_COLOR_REC);
|
text_color_set (DW_COLOR_REC);
|
||||||
|
|
Loading…
Reference in New Issue