1
1
//
2
2
// This file is part of Dire Wolf, an amateur radio packet TNC.
3
3
//
4
- // Copyright (C) 2011 , 2013, 2014, 2015 John Langner, WB2OSZ
4
+ // Copyright (C) 2011 , 2013, 2014, 2015, 2019 John Langner, WB2OSZ
5
5
//
6
6
// This program is free software: you can redistribute it and/or modify
7
7
// it under the terms of the GNU General Public License as published by
87
87
* http://www.aprs.org/aprs12/preemptive-digipeating.txt
88
88
* http://www.aprs.org/aprs12/RR-bits.txt
89
89
*
90
- * I don't recall why I originally intended to set the source/ destination C bits both to 1.
90
+ * I don't recall why I originally set the source & destination C bits both to 1.
91
91
* Reviewing this 5 years later, after spending more time delving into the
92
92
* AX.25 spec, I think it should be 1 for destination and 0 for source.
93
93
* In practice you see all four combinations being used by APRS stations
94
- * and no one really cares about these two bits.
94
+ * and everyone apparently ignores them for APRS. They do make a big
95
+ * difference for connected mode.
95
96
*
96
97
* The final octet of the Source has the form:
97
98
*
98
99
* C R R SSID 0, where,
99
100
*
100
- * C = command/response = 1 (originally, now I think it should be 0 for source.)
101
- * (Haven't gone back to check to see what code actually does.)
101
+ * C = command/response = 0
102
102
* R R = Reserved = 1 1
103
103
* SSID = substation ID
104
104
* 0 = zero (or 1 if no repeaters)
@@ -373,17 +373,18 @@ packet_t ax25_from_text (char *monitor, int strict)
373
373
* Tearing it apart is destructive so make our own copy first.
374
374
*/
375
375
char stuff [512 ];
376
-
377
376
char * pinfo ;
378
- char * pa ;
379
- char * saveptr ; /* Used with strtok_r because strtok is not thread safe. */
380
377
381
378
int ssid_temp , heard_temp ;
382
379
char atemp [AX25_MAX_ADDR_LEN ];
383
380
384
381
char info_part [AX25_MAX_INFO_LEN + 1 ];
385
382
int info_len ;
386
383
384
+ // text_color_set(DW_COLOR_DEBUG);
385
+ // dw_printf ("DEBUG: ax25_from_text ('%s', %d)\n", monitor, strict);
386
+ // fflush(stdout); sleep(1);
387
+
387
388
packet_t this_p = ax25_new ();
388
389
389
390
#if AX25MEMDEBUG
@@ -410,7 +411,7 @@ packet_t ax25_from_text (char *monitor, int strict)
410
411
this_p -> frame_data [AX25_DESTINATION * 7 + 6 ] = SSID_H_MASK | SSID_RR_MASK ;
411
412
412
413
memset (this_p -> frame_data + AX25_SOURCE * 7 , ' ' << 1 , 6 );
413
- this_p -> frame_data [AX25_SOURCE * 7 + 6 ] = SSID_H_MASK | SSID_RR_MASK | SSID_LAST_MASK ;
414
+ this_p -> frame_data [AX25_SOURCE * 7 + 6 ] = SSID_RR_MASK | SSID_LAST_MASK ;
414
415
415
416
this_p -> frame_data [14 ] = AX25_UI_FRAME ;
416
417
this_p -> frame_data [15 ] = AX25_PID_NO_LAYER_3 ;
@@ -440,9 +441,10 @@ packet_t ax25_from_text (char *monitor, int strict)
440
441
441
442
/*
442
443
* Source address.
443
- * Don't use traditional strtok because it is not thread safe.
444
444
*/
445
- pa = strtok_r (stuff , ">" , & saveptr );
445
+
446
+ char * pnxt = stuff ;
447
+ char * pa = strsep (& pnxt , ">" );
446
448
if (pa == NULL ) {
447
449
text_color_set (DW_COLOR_ERROR );
448
450
dw_printf ("Failed to create packet from text. No source address\n" );
@@ -465,7 +467,7 @@ packet_t ax25_from_text (char *monitor, int strict)
465
467
* Destination address.
466
468
*/
467
469
468
- pa = strtok_r ( NULL , "," , & saveptr );
470
+ pa = strsep ( & pnxt , "," );
469
471
if (pa == NULL ) {
470
472
text_color_set (DW_COLOR_ERROR );
471
473
dw_printf ("Failed to create packet from text. No destination address\n" );
@@ -487,11 +489,26 @@ packet_t ax25_from_text (char *monitor, int strict)
487
489
/*
488
490
* VIA path.
489
491
*/
490
- while (( pa = strtok_r (NULL , "," , & saveptr )) != NULL && this_p -> num_addr < AX25_MAX_ADDRS ) {
491
492
492
- int k ;
493
+ // Originally this used strtok_r.
494
+ // strtok considers all adjacent delimiters to be a single delimiter.
495
+ // This is handy for varying amounts of whitespace.
496
+ // It will never return a zero length string.
497
+ // All was good until this bizarre case came along:
498
+
499
+ // AISAT-1>CQ,,::CQ-0 :From AMSAT INDIA & Exseed Space |114304|48|45|42{962
500
+
501
+ // Apparently there are two digipeater fields but they are empty.
502
+ // When we parsed this text representation, the extra commas were ignored rather
503
+ // than pointed out as being invalid.
504
+
505
+ // Use strsep instead. This does not collapse adjacent delimiters.
506
+
507
+ while (( pa = strsep (& pnxt , "," )) != NULL && this_p -> num_addr < AX25_MAX_ADDRS ) {
493
508
494
- k = this_p -> num_addr ;
509
+ int k = this_p -> num_addr ;
510
+
511
+ // printf ("DEBUG: get digi loop, num addr = %d, address = '%s'\n", k, pa);// FIXME
495
512
496
513
if ( ! ax25_parse_addr (k , pa , strict , atemp , & ssid_temp , & heard_temp )) {
497
514
text_color_set (DW_COLOR_ERROR );
@@ -726,7 +743,7 @@ packet_t ax25_dup (packet_t copy_from)
726
743
* out_heard - True if "*" found.
727
744
*
728
745
* Returns: True (1) if OK, false (0) if any error.
729
- * When 0, out_addr, out_ssid, and out_heard are unpredictable .
746
+ * When 0, out_addr, out_ssid, and out_heard are undefined .
730
747
*
731
748
*
732
749
*------------------------------------------------------------------------------*/
@@ -747,10 +764,17 @@ int ax25_parse_addr (int position, char *in_addr, int strict, char *out_addr, in
747
764
* out_ssid = 0 ;
748
765
* out_heard = 0 ;
749
766
767
+ // dw_printf ("ax25_parse_addr in: position=%d, '%s', strict=%d\n", position, in_addr, strict);
768
+
750
769
if (position < -1 ) position = -1 ;
751
770
if (position > AX25_REPEATER_8 ) position = AX25_REPEATER_8 ;
752
771
position ++ ; /* Adjust for position_name above. */
753
772
773
+ if (strlen (in_addr ) == 0 ) {
774
+ text_color_set (DW_COLOR_ERROR );
775
+ dw_printf ("%sAddress \"%s\" is empty.\n" , position_name [position ], in_addr );
776
+ return 0 ;
777
+ }
754
778
755
779
if (strict && strlen (in_addr ) >= 2 && strncmp (in_addr , "qA" , 2 ) == 0 ) {
756
780
@@ -759,8 +783,7 @@ int ax25_parse_addr (int position, char *in_addr, int strict, char *out_addr, in
759
783
dw_printf ("APRS Internet Servers. It should never appear when going over the radio.\n" );
760
784
}
761
785
762
- //dw_printf ("ax25_parse_addr in: %s\n", in_addr);
763
-
786
+ // dw_printf ("ax25_parse_addr in: %s\n", in_addr);
764
787
765
788
maxlen = strict ? 6 : (AX25_MAX_ADDR_LEN - 1 );
766
789
p = in_addr ;
@@ -838,7 +861,7 @@ int ax25_parse_addr (int position, char *in_addr, int strict, char *out_addr, in
838
861
return 0 ;
839
862
}
840
863
841
- //dw_printf ("ax25_parse_addr out: %s %d %d\n", out_addr, *out_ssid, *out_heard);
864
+ // dw_printf ("ax25_parse_addr out: '%s' %d %d\n", out_addr, *out_ssid, *out_heard);
842
865
843
866
return (1 );
844
867
@@ -984,6 +1007,11 @@ void ax25_set_addr (packet_t this_p, int n, char *ad)
984
1007
985
1008
//dw_printf ("ax25_set_addr (%d, %s) num_addr=%d\n", n, ad, this_p->num_addr);
986
1009
1010
+ if (strlen (ad ) == 0 ) {
1011
+ text_color_set (DW_COLOR_ERROR );
1012
+ dw_printf ("Set address error! Station address for position %d is empty!\n" , n );
1013
+ }
1014
+
987
1015
if (n >= 0 && n < this_p -> num_addr ) {
988
1016
989
1017
//dw_printf ("ax25_set_addr , existing case\n");
@@ -1065,6 +1093,11 @@ void ax25_insert_addr (packet_t this_p, int n, char *ad)
1065
1093
1066
1094
//dw_printf ("ax25_insert_addr (%d, %s)\n", n, ad);
1067
1095
1096
+ if (strlen (ad ) == 0 ) {
1097
+ text_color_set (DW_COLOR_ERROR );
1098
+ dw_printf ("Set address error! Station address for position %d is empty!\n" , n );
1099
+ }
1100
+
1068
1101
/* Don't do it if we already have the maximum number. */
1069
1102
/* Should probably return success/fail code but currently the caller doesn't care. */
1070
1103
@@ -1305,6 +1338,11 @@ void ax25_get_addr_with_ssid (packet_t this_p, int n, char *station)
1305
1338
break ;
1306
1339
}
1307
1340
1341
+ if (strlen (station ) == 0 ) {
1342
+ text_color_set (DW_COLOR_ERROR );
1343
+ dw_printf ("Station address, in position %d, is empty! This is not a valid AX.25 frame.\n" , n );
1344
+ }
1345
+
1308
1346
ssid = ax25_get_ssid (this_p , n );
1309
1347
if (ssid != 0 ) {
1310
1348
snprintf (sstr , sizeof (sstr ), "-%d" , ssid );
@@ -1379,6 +1417,11 @@ void ax25_get_addr_no_ssid (packet_t this_p, int n, char *station)
1379
1417
break ;
1380
1418
}
1381
1419
1420
+ if (strlen (station ) == 0 ) {
1421
+ text_color_set (DW_COLOR_ERROR );
1422
+ dw_printf ("Station address, in position %d, is empty! This is not a valid AX.25 frame.\n" , n );
1423
+ }
1424
+
1382
1425
} /* end ax25_get_addr_no_ssid */
1383
1426
1384
1427
@@ -1918,6 +1961,8 @@ void ax25_format_addrs (packet_t this_p, char *result)
1918
1961
}
1919
1962
1920
1963
strcat (result , ":" );
1964
+
1965
+ // dw_printf ("DEBUG ax25_format_addrs, num_addr = %d, result = '%s'\n", this_p->num_addr, result);
1921
1966
}
1922
1967
1923
1968
0 commit comments