94 #define DEG2RAD(x) (x/360*2*PI)
96 #define RAD2DEG(x) (x*(180/PI))
107 #define FRAME_MAXLEN 512
110 #define AX25_FRAME_UI 0x03
112 #define AX25_PID_APRS 0xf0
117 regex_t fapint_regex_header, fapint_regex_ax25call, fapint_regex_digicall, fapint_regex_digicallv6;
118 regex_t fapint_regex_normalpos, fapint_regex_normalamb, fapint_regex_timestamp;
119 regex_t fapint_regex_mice_dstcall, fapint_regex_mice_body, fapint_regex_mice_amb;
120 regex_t fapint_regex_comment, fapint_regex_phgr, fapint_regex_phg, fapint_regex_rng, fapint_regex_altitude;
121 regex_t fapint_regex_mes_dst, fapint_regex_mes_ack, fapint_regex_mes_nack;
122 regex_t fapint_regex_wx1, fapint_regex_wx2, fapint_regex_wx3, fapint_regex_wx4, fapint_regex_wx5;
123 regex_t fapint_regex_wx_r1, fapint_regex_wx_r24, fapint_regex_wx_rami;
124 regex_t fapint_regex_wx_humi, fapint_regex_wx_pres, fapint_regex_wx_lumi, fapint_regex_wx_what;
125 regex_t fapint_regex_wx_snow, fapint_regex_wx_rrc, fapint_regex_wx_any, fapint_regex_wx_soft;
126 regex_t fapint_regex_nmea_chksum, fapint_regex_nmea_dst, fapint_regex_nmea_time, fapint_regex_nmea_date;
127 regex_t fapint_regex_nmea_specou, fapint_regex_nmea_fix, fapint_regex_nmea_altitude, fapint_regex_nmea_flag, fapint_regex_nmea_coord;
128 regex_t fapint_regex_telemetry, fapint_regex_peet_splitter, fapint_regex_kiss_callsign, fapint_regex_kiss_digi;
129 regex_t fapint_regex_base91_telemetry;
132 regex_t fapint_regex_detect_comp, fapint_regex_detect_wx, fapint_regex_detect_telem, fapint_regex_detect_exp;
133 regex_t fapint_regex_kiss_hdrbdy, fapint_regex_hdr_detail;
134 regex_t fapint_regex_hopcount1, fapint_regex_hopcount2;
137 short fapint_initialized = 0;
145 unsigned int splitpos, body_len;
148 char poschar, typechar;
151 if ( !fapint_initialized )
160 if ( input == NULL || input_len == 0 )
174 for ( i = 0; i < input_len; ++i )
182 if ( input[i] ==
':' )
189 if ( splitpos == 0 || splitpos + 1 == input_len )
208 body = malloc(body_len + 1);
209 memcpy(body, result->
body, body_len);
216 if ( (typechar == 0x27 || typechar == 0x60) &&
220 if ( !result->
type )
return result;
221 *result->
type = fapLOCATION;
225 else if ( typechar ==
'!' || typechar ==
'=' || typechar ==
'/' || typechar ==
'@' )
228 result->
messaging = malloc(
sizeof(
short));
230 if ( typechar ==
'=' || typechar ==
'@' )
239 if ( body_len >= 14 )
242 if ( !result->
type )
return result;
243 *result->
type = fapLOCATION;
246 if ( typechar ==
'/' || typechar ==
'@' )
249 result->
timestamp = malloc(
sizeof(time_t));
281 if ( poschar >= 48 && poschar <= 57 )
284 if ( body_len >= 19 )
288 if ( body_len > 19 && i && result->
symbol_code !=
'_' )
292 else if ( body_len > 19 && i )
298 else if ( poschar == 47 || poschar == 92 || (poschar >= 65 && poschar <= 90) || (poschar >= 97 && poschar <= 106) )
301 if ( body_len >= 13 )
305 if ( body_len > 13 && i && result->
symbol_code !=
'_' )
309 else if ( body_len > 13 && i )
320 else if ( poschar == 33 )
323 if ( result->
type == NULL )
326 if ( !result->
type )
return result;
328 *result->
type = fapWX;
346 else if ( typechar ==
'$' )
348 if ( body_len > 3 && body[0] ==
'$' && body[1] ==
'G' && body[2] ==
'P' )
351 if ( !result->
type )
return result;
352 *result->
type = fapLOCATION;
355 else if ( body_len > 5 && body[0] ==
'$' && body[1] ==
'U' && body[2] ==
'L' && body[3] ==
'T' && body[4] ==
'W' )
358 if ( !result->
type )
return result;
359 *result->
type = fapWX;
364 else if ( typechar ==
';' )
366 if ( body_len >= 31 )
369 if ( !result->
type )
return result;
370 *result->
type = fapOBJECT;
375 else if ( typechar ==
')' )
377 if ( body_len >= 18 )
380 if ( !result->
type )
return result;
381 *result->
type = fapITEM;
386 else if ( typechar ==
':' )
388 if ( body_len >= 11 )
392 if ( !result->
type )
return result;
393 *result->
type = fapMESSAGE;
398 else if ( typechar ==
'<' )
404 if ( !result->
type )
return result;
405 *result->
type = fapCAPABILITIES;
410 else if ( typechar ==
'>' )
416 if ( !result->
type )
return result;
417 *result->
type = fapSTATUS;
422 else if ( typechar ==
'_' )
424 if ( regexec(&fapint_regex_detect_wx, body, 0, NULL, 0) == 0 )
427 if ( !result->
type )
return result;
428 *result->
type = fapWX;
438 else if ( regexec(&fapint_regex_detect_telem, body, 0, NULL, 0) == 0 )
441 if ( !result->
type )
return result;
442 *result->
type = fapTELEMETRY;
446 else if ( regexec(&fapint_regex_detect_exp, body, 0, NULL, 0) == 0 )
449 if ( !result->
type )
return result;
450 *result->
type = fapEXPERIMENTAL;
455 else if ( typechar ==
'}' )
463 tmp = strchr(body,
'!');
464 if ( tmp != NULL && (pos = tmp-body) < 40 && pos+1 < body_len )
467 if ( !result->
type )
return result;
468 *result->
type = fapLOCATION;
472 if ( poschar == 47 || poschar == 92 || (poschar >= 65 && poschar <= 90) || (poschar >= 97 && poschar <= 106) )
475 if ( body_len >= pos + 1 + 13 )
479 if ( body_len - (pos+1) > 13 && i && result->
symbol_code !=
'_' )
485 else if ( isdigit(poschar) )
488 if ( body_len >= pos + 1 + 19 )
492 if ( body_len - (pos+1) > 19 && i && result->
symbol_code !=
'_' )
518 if ( output == NULL )
526 sprintf(output,
"No packet given to parse");
528 case fapPACKET_SHORT:
529 sprintf(output,
"Too short packet");
531 case fapPACKET_NOBODY:
532 sprintf(output,
"No body in packet");
535 case fapSRCCALL_NOAX25:
536 sprintf(output,
"Source callsign is not a valid AX.25 call");
538 case fapSRCCALL_BADCHARS:
539 sprintf(output,
"Source callsign contains bad characters");
542 case fapDSTPATH_TOOMANY:
543 sprintf(output,
"Too many destination path components to be AX.25");
545 case fapDSTCALL_NONE:
546 sprintf(output,
"No destination field in packet");
548 case fapDSTCALL_NOAX25:
549 sprintf(output,
"Destination callsign is not a valid AX.25 call");
552 case fapDIGICALL_NOAX25:
553 sprintf(output,
"Digipeater callsign is not a valid AX.25 call");
555 case fapDIGICALL_BADCHARS:
556 sprintf(output,
"Digipeater callsign contains bad characters");
559 case fapTIMESTAMP_INV_LOC:
560 sprintf(output,
"Invalid timestamp in location");
562 case fapTIMESTAMP_INV_OBJ:
563 sprintf(output,
"Invalid timestamp in object");
565 case fapTIMESTAMP_INV_STA:
566 sprintf(output,
"Invalid timestamp in status");
568 case fapTIMESTAMP_INV_GPGGA:
569 sprintf(output,
"Invalid timestamp in GPGGA sentence");
571 case fapTIMESTAMP_INV_GPGLL:
572 sprintf(output,
"Invalid timestamp in GPGLL sentence");
575 case fapPACKET_INVALID:
576 sprintf(output,
"Invalid packet");
579 case fapNMEA_INV_CVAL:
580 sprintf(output,
"Invalid coordinate value in NMEA sentence");
582 case fapNMEA_LARGE_EW:
583 sprintf(output,
"Too large value in NMEA sentence (east/west)");
585 case fapNMEA_LARGE_NS:
586 sprintf(output,
"Too large value in NMEA sentence (north/south)");
588 case fapNMEA_INV_SIGN:
589 sprintf(output,
"Invalid lat/long sign in NMEA sentence");
591 case fapNMEA_INV_CKSUM:
592 sprintf(output,
"Invalid checksum in NMEA sentence");
595 case fapGPRMC_FEWFIELDS:
596 sprintf(output,
"Less than ten fields in GPRMC sentence");
599 sprintf(output,
"No GPS fix in GPRMC sentence");
601 case fapGPRMC_INV_TIME:
602 sprintf(output,
"Invalid timestamp in GPRMC sentence");
604 case fapGPRMC_INV_DATE:
605 sprintf(output,
"Invalid date in GPRMC sentence");
607 case fapGPRMC_DATE_OUT:
608 sprintf(output,
"GPRMC date does not fit in an Unix timestamp");
611 case fapGPGGA_FEWFIELDS:
612 sprintf(output,
"Less than 11 fields in GPGGA sentence");
615 sprintf(output,
"No GPS fix in GPGGA sentence");
618 case fapGPGLL_FEWFIELDS:
619 sprintf(output,
"Less than 5 fields in GPGLL sentence");
622 sprintf(output,
"No GPS fix in GPGLL sentence");
626 sprintf(output,
"Unsupported NMEA sentence type");
630 sprintf(output,
"Too short object");
633 sprintf(output,
"Invalid object");
636 sprintf(output,
"Error in object location decoding");
640 sprintf(output,
"Too short item");
643 sprintf(output,
"Invalid item");
645 case fapITEM_DEC_ERR:
646 sprintf(output,
"Error in item location decoding");
650 sprintf(output,
"Too short uncompressed location");
653 sprintf(output,
"Invalid uncompressed location");
656 sprintf(output,
"Degree value too large");
659 sprintf(output,
"Invalid position ambiguity");
663 sprintf(output,
"Too short mic-e packet");
666 sprintf(output,
"Invalid characters in mic-e packet");
668 case fapMICE_INV_INFO:
669 sprintf(output,
"Invalid characters in mic-e information field");
671 case fapMICE_AMB_LARGE:
672 sprintf(output,
"Too much position ambiguity in mic-e packet");
674 case fapMICE_AMB_INV:
675 sprintf(output,
"Invalid position ambiguity in mic-e packet");
677 case fapMICE_AMB_ODD:
678 sprintf(output,
"Odd position ambiguity in mic-e packet");
682 sprintf(output,
"Invalid compressed packet");
685 sprintf(output,
"Short compressed packet");
689 sprintf(output,
"Invalid message packet");
693 sprintf(output,
"Unsupported weather format");
696 sprintf(output,
"Unsupported user format");
700 sprintf(output,
"Invalid DX spot source callsign");
703 sprintf(output,
"Invalid DX spot frequency");
706 sprintf(output,
"No DX spot callsign found");
710 sprintf(output,
"Invalid telemetry packet");
713 sprintf(output,
"Too large telemetry value");
716 sprintf(output,
"Unsupported telemetry");
720 sprintf(output,
"Unsupported experimental");
722 case fapSYM_INV_TABLE:
723 sprintf(output,
"Invalid symbol table or overlay");
726 case fapNOT_IMPLEMENTED:
727 sprintf(output,
"Sorry, feature not implemented yet.");
729 case fapNMEA_NOFIELDS:
730 sprintf(output,
"No fields in NMEA fields in NMEA packet.");
734 sprintf(output,
"Not an APRS packet");
738 sprintf(output,
"Default error message.");
748 if ( bits == NULL || output == NULL )
754 if ( strcmp(bits,
"111") == 0 ) sprintf(output,
"off duty");
755 else if ( strcmp(bits,
"222") == 0 ) sprintf(output,
"custom 0");
756 else if ( strcmp(bits,
"110") == 0 ) sprintf(output,
"en route");
757 else if ( strcmp(bits,
"220") == 0 ) sprintf(output,
"custom 1");
758 else if ( strcmp(bits,
"101") == 0 ) sprintf(output,
"in service");
759 else if ( strcmp(bits,
"202") == 0 ) sprintf(output,
"custom 2");
760 else if ( strcmp(bits,
"100") == 0 ) sprintf(output,
"returning");
761 else if ( strcmp(bits,
"200") == 0 ) sprintf(output,
"custom 3");
762 else if ( strcmp(bits,
"011") == 0 ) sprintf(output,
"committed");
763 else if ( strcmp(bits,
"022") == 0 ) sprintf(output,
"custom 4");
764 else if ( strcmp(bits,
"010") == 0 ) sprintf(output,
"special");
765 else if ( strcmp(bits,
"020") == 0 ) sprintf(output,
"custom 5");
766 else if ( strcmp(bits,
"001") == 0 ) sprintf(output,
"priority");
767 else if ( strcmp(bits,
"002") == 0 ) sprintf(output,
"custom 6");
768 else if ( strcmp(bits,
"000") == 0 ) sprintf(output,
"emergency");
769 else sprintf(output,
"unknown");
774 double fap_distance(
double lon0,
double lat0,
double lon1,
double lat1)
784 double dlon = lon1 - lon0;
785 double dlat = lat1 - lat0;
786 double a = pow(sin(dlat/2),2) + cos(lat0) * cos(lat1) * pow(sin(dlon/2), 2);
787 double c = 2 * atan2(sqrt(a), sqrt(1-a));
806 direction = atan2(sin(lon1-lon0)*cos(lat1), cos(lat0)*sin(lat1)-sin(lat0)*cos(lat1)*cos(lon1-lon0));
821 unsigned int hopcount = 0, n, N;
826 unsigned int const matchcount = 3;
827 regmatch_t matches[matchcount];
831 if ( !fapint_initialized || packet == NULL || packet->
path == NULL )
837 for ( i = 0; i < packet->
path_len; ++i )
842 if ( regexec(&fapint_regex_hopcount1, packet->
path[i], matchcount, (regmatch_t*)&matches, 0) == 0 )
847 len = matches[1].rm_eo - matches[1].rm_so;
848 element = malloc(len+1);
849 if ( !element )
return -1;
850 memcpy(element, packet->
path[i]+matches[1].rm_so, len);
863 if ( call_ssid == NULL )
869 if ( regexec(&fapint_regex_hopcount2, call_ssid, matchcount, (regmatch_t*)&matches, 0) == 0 )
872 n = call_ssid[matches[1].rm_so] - 48;
873 N = call_ssid[matches[2].rm_so] - 48;
876 if ( (i = n - N) >= 0 )
901 unsigned int const matchcount = 3;
902 regmatch_t matches[matchcount];
905 char call[7], ssid_str[4];
912 if ( !fapint_initialized )
918 if ( !input || !strlen(input) )
924 if ( regexec(&fapint_regex_ax25call, input, matchcount, (regmatch_t*)&matches, 0) == 0 )
928 len = matches[1].rm_eo - matches[1].rm_so;
929 memcpy(call, input+matches[1].rm_so, len);
932 memset(ssid_str, 0, 4);
933 len = matches[2].rm_eo - matches[2].rm_so;
934 memcpy(ssid_str, input+matches[2].rm_so, len);
939 ssid = atoi(ssid_str);
949 if ( !add_ssid0 && ssid == 0 )
951 sprintf(buf,
"%s", call);
955 sprintf(buf,
"%s-%d", call, ssid);
958 result = malloc( strlen(buf)+1 );
959 if ( !result )
return NULL;
970 char* tnc2frame,
unsigned int* tnc2frame_len,
unsigned int* tnc_id)
973 unsigned int input_len = 0;
976 unsigned int output_len = 0;
978 int i = 0, j = 0, escape_mode = 0;
981 if ( !kissframe || !kissframe_len || !tnc2frame || !tnc2frame_len || !tnc_id )
989 sprintf(output,
"Too long KISS frame.");
990 output_len = strlen(output)+1;
991 if ( output_len > *tnc2frame_len ) output_len = *tnc2frame_len;
992 memcpy(tnc2frame, output, output_len);
993 *tnc2frame_len = output_len;
998 if ( kissframe_len > 0 && (kissframe[0] & 0xff) ==
FEND )
1005 for ( i = 0; i < kissframe_len; ++i )
1007 if ( (kissframe[i] & 0xff) ==
FEND )
1014 if ( kissframe_len > 0 )
1016 *tnc_id = kissframe[0];
1023 for ( i = 0; i < kissframe_len; ++i )
1025 if ( (kissframe[i] & 0xff) ==
FESC )
1033 if ( (kissframe[i] & 0xff) ==
TFEND )
1037 else if ( (kissframe[i] & 0xff) ==
TFESC )
1046 input[j] = kissframe[i];
1052 if ( input_len < 16 )
1054 sprintf(output,
"Too short KISS frame (%d bytes after unstuffing).", input_len);
1055 output_len = strlen(output)+1;
1056 if ( output_len > *tnc2frame_len ) output_len = *tnc2frame_len;
1057 memcpy(tnc2frame, output, output_len);
1058 *tnc2frame_len = output_len;
1069 char* tnc2frame,
unsigned int* tnc2frame_len)
1071 int i, j, retval = 1;
1072 char *checked_call, *dst_callsign = NULL;
1073 int part_no, header_len, ssid, digi_count;
1074 char tmp_callsign[10];
1078 unsigned int output_len = 0;
1081 if ( !ax25frame || !ax25frame_len || !tnc2frame || !tnc2frame_len )
1089 sprintf(output,
"Too long AX.25 frame.");
1090 output_len = strlen(output)+1;
1091 if ( output_len > *tnc2frame_len ) output_len = *tnc2frame_len;
1092 memcpy(tnc2frame, output, output_len);
1093 *tnc2frame_len = output_len;
1096 if ( ax25frame_len < 16 )
1098 sprintf(output,
"Too short AX.25 frame (%d bytes).", ax25frame_len);
1099 output_len = strlen(output)+1;
1100 if ( output_len > *tnc2frame_len ) output_len = *tnc2frame_len;
1101 memcpy(tnc2frame, output, output_len);
1102 *tnc2frame_len = output_len;
1109 memset(tmp_callsign, 0, 10);
1112 for ( i = 0; i < ax25frame_len; ++i )
1114 charri = ax25frame[i];
1125 if ( header_len < 14 || header_len % 7 != 0 )
1127 sprintf(output,
"Invalid header lenght (%d).", header_len);
1128 output_len = strlen(output)+1;
1138 if ( header_len && header_len % 7 == 0 )
1141 ssid = (charri >> 1) & 0xf;
1144 sprintf(tmp_callsign+6,
"-%d", ssid);
1148 if ( !checked_call )
1150 sprintf(output,
"Invalid callsign in header (%s).", tmp_callsign);
1151 output_len = strlen(output)+1;
1156 if ( header_len == 7 )
1159 dst_callsign = checked_call;
1161 else if ( header_len == 14 )
1164 sprintf(output,
"%s>%s", checked_call, dst_callsign);
1165 output_len = strlen(checked_call) + 1 + strlen(dst_callsign);
1169 else if ( header_len > 14 )
1172 sprintf(output+output_len,
"%s", checked_call);
1173 output_len += strlen(checked_call);
1176 if ( charri & 0x80 )
1178 output[output_len] =
'*';
1185 sprintf(output,
"Internal error.");
1186 output_len = strlen(output)+1;
1194 if ( digi_count >= 8 )
1196 sprintf(output,
"Too many digis.");
1197 output_len = strlen(output)+1;
1201 output[output_len] =
',';
1207 output[output_len] =
':';
1211 memset(tmp_callsign, 0, 10);
1216 tmp_callsign[j] = (charri & 0xff) >> 1;
1219 else if ( part_no == 1 )
1229 else if ( part_no == 2 )
1241 output[output_len] = charri;
1247 if ( output_len > *tnc2frame_len ) output_len = *tnc2frame_len;
1248 memcpy(tnc2frame, output, output_len);
1249 *tnc2frame_len = output_len;
1256 int fap_tnc2_to_kiss(
char const* tnc2frame,
unsigned int tnc2frame_len,
unsigned int const tnc_id,
1257 char* kissframe,
unsigned int* kissframe_len)
1260 unsigned int ax25frame_len;
1265 memset(ax25frame, 0, 2);
1268 if ( !
fap_tnc2_to_ax25(tnc2frame, tnc2frame_len, ax25frame+2, &ax25frame_len) )
1270 strcpy(kissframe, ax25frame);
1271 *kissframe_len = strlen(kissframe);
1277 if ( *kissframe_len <= ax25frame_len )
1284 for ( i = 2; i < ax25frame_len; ++i )
1286 if ( (ax25frame[i] & 0xff) ==
FEND || (ax25frame[i] & 0xff) ==
FESC )
1288 kissframe[*kissframe_len] =
FESC;
1290 if ( (ax25frame[i] & 0xff) ==
FEND )
1292 kissframe[*kissframe_len] =
TFEND;
1296 kissframe[*kissframe_len] =
TFESC;
1302 kissframe[*kissframe_len] = ax25frame[i];
1308 kissframe[0] =
FEND;
1309 kissframe[1] = tnc_id;
1310 kissframe[*kissframe_len] =
FEND;
1319 char* ax25frame,
unsigned int* ax25frame_len)
1324 unsigned int output_len = 0;
1326 char *header = NULL, *digipeaters = NULL, *body = NULL;
1327 unsigned int digi_count, body_len;
1329 char sender[6], sender_ssid[4], receiver[6], receiver_ssid[4];
1330 int sender_ssid_num = 0, receiver_ssid_num = 0;
1332 char digicall[6], digicall_ssid[4], hbit;
1333 int digicall_ssid_num = 0;
1335 int retval = 1, len, i;
1338 unsigned int const matchcount = 6;
1339 regmatch_t matches[matchcount];
1343 if ( !tnc2frame || !tnc2frame_len || tnc2frame_len >=
FRAME_MAXLEN || !ax25frame || !ax25frame_len )
1350 memcpy(input, tnc2frame, tnc2frame_len );
1353 if ( regexec(&fapint_regex_kiss_hdrbdy, input, matchcount, (regmatch_t*)&matches, 0) == 0 )
1355 len = matches[1].rm_eo - matches[1].rm_so;
1356 header = malloc(len+1);
1357 if ( !header )
return 0;
1358 memcpy(header, input+matches[1].rm_so, len);
1361 body_len = matches[2].rm_eo - matches[2].rm_so;
1362 body = malloc(body_len);
1368 memcpy(body, input+matches[2].rm_so, body_len);
1372 sprintf(output,
"Failed to separate header and body of TNC-2 packet.");
1373 output_len = strlen(output)+1;
1374 if ( output_len > *ax25frame_len ) output_len = *ax25frame_len;
1375 strcpy(ax25frame, output);
1376 *ax25frame_len = output_len;
1381 if ( regexec(&fapint_regex_hdr_detail, header, matchcount, (regmatch_t*)&matches, 0) == 0 )
1383 len = matches[1].rm_eo - matches[1].rm_so;
1384 memset(sender,
' ', 6);
1385 memcpy(sender, header+matches[1].rm_so, len);
1387 len = matches[2].rm_eo - matches[2].rm_so;
1388 memset(sender_ssid, 0, 4);
1391 memcpy(sender_ssid, header+matches[2].rm_so, len);
1394 len = matches[3].rm_eo - matches[3].rm_so;
1395 memset(receiver,
' ', 6);
1396 memcpy(receiver, header+matches[3].rm_so, len);
1398 len = matches[4].rm_eo - matches[4].rm_so;
1399 memset(receiver_ssid, 0, 4);
1402 memcpy(receiver_ssid, header+matches[4].rm_so, len);
1405 len = matches[5].rm_eo - matches[5].rm_so;
1408 digipeaters = malloc(len+5);
1415 memcpy(digipeaters, header+matches[5].rm_so, len);
1416 digipeaters[len] = 0;
1431 if ( sender_ssid[0] ==
'-' )
1433 sender_ssid_num = 0 - atoi(sender_ssid);
1434 if ( sender_ssid_num > 15 )
1440 if ( receiver_ssid[0] ==
'-' )
1442 receiver_ssid_num = 0 - atoi(receiver_ssid);
1443 if ( receiver_ssid_num > 15 )
1451 for ( i = 0; i < 6; ++i )
1453 output[output_len] = receiver[i] << 1;
1456 output[output_len] = 0xe0 | (receiver_ssid_num << 1);
1458 for ( i = 0; i < 6; ++i )
1460 output[output_len] = sender[i] << 1;
1465 output[output_len] = 0x60 | (sender_ssid_num << 1);
1469 output[output_len] = 0x61 | (sender_ssid_num << 1);
1477 tmp_str = strtok(digipeaters+1,
",");
1479 while ( tmp_str != NULL )
1482 if ( regexec(&fapint_regex_kiss_digi, tmp_str, matchcount, (regmatch_t*)&matches, 0) == 0 )
1485 len = matches[1].rm_eo - matches[1].rm_so;
1486 memset(digicall,
' ', 6);
1487 memcpy(digicall, tmp_str+matches[1].rm_so, len);
1490 digicall_ssid_num = 0;
1491 len = matches[2].rm_eo - matches[2].rm_so;
1494 memset(digicall_ssid, 0, 4);
1495 memcpy(digicall_ssid, tmp_str+matches[2].rm_so, len);
1497 digicall_ssid_num = 0 - atoi(digicall_ssid);
1498 if ( digicall_ssid_num > 15 )
1507 if ( tmp_str[matches[3].rm_so] ==
'*' )
1513 tmp_str = strtok(NULL,
",");
1516 for ( i = 0; i < 6; ++i )
1518 output[output_len] = digicall[i] << 1;
1525 output[output_len] = 0x60 | (digicall_ssid_num << 1) | hbit;
1530 output[output_len] = 0x61 | (digicall_ssid_num << 1) | hbit;
1546 if ( digipeaters ) free(digipeaters);
1556 memcpy(output+output_len, body, body_len);
1557 output_len += body_len;
1567 if ( output_len > *ax25frame_len ) output_len = *ax25frame_len;
1568 memcpy(ax25frame, output, output_len);
1569 *ax25frame_len = output_len;
1577 if ( !fapint_initialized )
1580 regcomp(&fapint_regex_header,
"^([A-Z0-9\\-]{1,9})>(.*)$", REG_EXTENDED);
1581 regcomp(&fapint_regex_ax25call,
"^([A-Z0-9]{1,6})(-[0-9]{1,2}|())$", REG_EXTENDED);
1582 regcomp(&fapint_regex_digicall,
"^([a-zA-Z0-9-]{1,9})([*]?)$", REG_EXTENDED);
1583 regcomp(&fapint_regex_digicallv6,
"^([0-9A-F]{32})$", REG_EXTENDED|REG_NOSUB);
1585 regcomp(&fapint_regex_normalpos,
"^([0-9]{2})([0-7 ][0-9 ]\\.[0-9 ]{2})([NnSs])(.)([0-9]{3})([0-7 ][0-9 ]\\.[0-9 ]{2})([EeWw])(.)", REG_EXTENDED);
1586 regcomp(&fapint_regex_normalamb,
"^([0-9]{0,4})( {0,4})$", REG_EXTENDED);
1587 regcomp(&fapint_regex_timestamp,
"^([0-9]{2})([0-9]{2})([0-9]{2})([zh\\/])", REG_EXTENDED);
1589 regcomp(&fapint_regex_mice_dstcall,
"^[0-9A-LP-Z]{3}[0-9LP-Z]{3}$", REG_EXTENDED|REG_NOSUB);
1590 regcomp(&fapint_regex_mice_body,
"^[\\/\\\\A-Z0-9]", REG_EXTENDED|REG_NOSUB);
1591 regcomp(&fapint_regex_mice_amb,
"^([0-9]+)(_*)$", REG_EXTENDED);
1593 regcomp(&fapint_regex_comment,
"^([0-9\\. ]{3})\\/([0-9\\. ]{3})", REG_EXTENDED|REG_NOSUB);
1594 regcomp(&fapint_regex_phgr,
"^PHG([0-9].[0-9]{2}[1-9A-Z])\\/", REG_EXTENDED|REG_NOSUB);
1595 regcomp(&fapint_regex_phg,
"^PHG([0-9].[0-9]{2})", REG_EXTENDED|REG_NOSUB);
1596 regcomp(&fapint_regex_rng,
"^RNG([0-9]{4})", REG_EXTENDED|REG_NOSUB);
1597 regcomp(&fapint_regex_altitude,
"\\/A=(-[0-9]{5}|[0-9]{6})", REG_EXTENDED);
1599 regcomp(&fapint_regex_mes_dst,
"^:([A-Za-z0-9_ -]{9}):", REG_EXTENDED);
1600 regcomp(&fapint_regex_mes_ack,
"^ack([A-Za-z0-9}]{1,5}) *$", REG_EXTENDED);
1601 regcomp(&fapint_regex_mes_nack,
"^rej([A-Za-z0-9}]{1,5}) *$", REG_EXTENDED);
1603 regcomp(&fapint_regex_wx1,
"^_{0,1}([0-9 \\.\\-]{3})\\/([0-9 \\.]{3})g([0-9 \\.]+)t(-{0,1}[0-9 \\.]+)", REG_EXTENDED);
1604 regcomp(&fapint_regex_wx2,
"^_{0,1}c([0-9 \\.\\-]{3})s([0-9 \\.]{3})g([0-9 \\.]+)t(-{0,1}[0-9 \\.]+)", REG_EXTENDED);
1605 regcomp(&fapint_regex_wx3,
"^_{0,1}([0-9 \\.\\-]{3})\\/([0-9 \\.]{3})t(-{0,1}[0-9 \\.]+)", REG_EXTENDED);
1606 regcomp(&fapint_regex_wx4,
"^_{0,1}([0-9 \\.\\-]{3})\\/([0-9 \\.]{3})g([0-9 \\.]+)", REG_EXTENDED);
1607 regcomp(&fapint_regex_wx5,
"^g([0-9]+)t(-?[0-9 \\.]{1,3})", REG_EXTENDED);
1609 regcomp(&fapint_regex_wx_r1,
"r([0-9]{1,3})", REG_EXTENDED);
1610 regcomp(&fapint_regex_wx_r24,
"p([0-9]{1,3})", REG_EXTENDED);
1611 regcomp(&fapint_regex_wx_rami,
"P([0-9]{1,3})", REG_EXTENDED);
1613 regcomp(&fapint_regex_wx_humi,
"h([0-9]{1,3})", REG_EXTENDED);
1614 regcomp(&fapint_regex_wx_pres,
"b([0-9]{4,5})", REG_EXTENDED);
1615 regcomp(&fapint_regex_wx_lumi,
"([lL])([0-9]{1,3})", REG_EXTENDED);
1616 regcomp(&fapint_regex_wx_what,
"v([\\-\\+]{0,1}[0-9]+)", REG_EXTENDED);
1618 regcomp(&fapint_regex_wx_snow,
"s([0-9]+)", REG_EXTENDED);
1619 regcomp(&fapint_regex_wx_rrc,
"#([0-9]+)", REG_EXTENDED);
1620 regcomp(&fapint_regex_wx_any,
"^([rPphblLs#][\\. ]{1,5})+", REG_EXTENDED);
1621 regcomp(&fapint_regex_wx_soft,
"^[a-zA-Z0-9\\-\\_]{3,5}$", REG_EXTENDED|REG_NOSUB);
1623 regcomp(&fapint_regex_nmea_chksum,
"^(.+)\\*([0-9A-F]{2})$", REG_EXTENDED);
1624 regcomp(&fapint_regex_nmea_dst,
"^(GPS|SPC)([A-Z0-9]{2,3})", REG_EXTENDED);
1625 regcomp(&fapint_regex_nmea_time,
"^[:space:]*([0-9]{2})([0-9]{2})([0-9]{2})(()|\\.[0-9]+)[:space:]*$", REG_EXTENDED);
1626 regcomp(&fapint_regex_nmea_date,
"^[:space:]*([0-9]{2})([0-9]{2})([0-9]{2})[:space:]*$", REG_EXTENDED);
1628 regcomp(&fapint_regex_nmea_specou,
"^[:space:]*([0-9]+(()|\\.[0-9]+))[:space:]*$", REG_EXTENDED);
1629 regcomp(&fapint_regex_nmea_fix,
"^[:space:]*([0-9]+)[:space:]*$", REG_EXTENDED);
1630 regcomp(&fapint_regex_nmea_altitude,
"^(-?[0-9]+(()|\\.[0-9]+))$", REG_EXTENDED);
1631 regcomp(&fapint_regex_nmea_flag,
"^[:space:]*([NSEWnsew])[:space:]*$", REG_EXTENDED);
1632 regcomp(&fapint_regex_nmea_coord,
"^[:space:]*([0-9]{1,3})([0-5][0-9]\\.([0-9]+))[:space:]*$", REG_EXTENDED);
1634 regcomp(&fapint_regex_telemetry,
"^([0-9]+),(-?)([0-9]{1,6}|[0-9]+\\.[0-9]+|\\.[0-9]+)?,(-?)([0-9]{1,6}|[0-9]+\\.[0-9]+|\\.[0-9]+)?,(-?)([0-9]{1,6}|[0-9]+\\.[0-9]+|\\.[0-9]+)?,(-?)([0-9]{1,6}|[0-9]+\\.[0-9]+|\\.[0-9]+)?,(-?)([0-9]{1,6}|[0-9]+\\.[0-9]+|\\.[0-9]+)?,([01]{0,8})", REG_EXTENDED);
1635 regcomp(&fapint_regex_peet_splitter,
"^([0-9a-f]{4}|----)", REG_EXTENDED|REG_ICASE);
1636 regcomp(&fapint_regex_kiss_callsign,
"^([A-Z0-9]+) *(-[0-9]+)?$", REG_EXTENDED);
1638 regcomp(&fapint_regex_detect_comp,
"^[\\/\\\\A-Za-j]$", REG_EXTENDED|REG_NOSUB);
1639 regcomp(&fapint_regex_detect_wx,
"^_([0-9]{8})c[- .0-9]{1,3}s[- .0-9]{1,3}", REG_EXTENDED|REG_NOSUB);
1640 regcomp(&fapint_regex_detect_telem,
"^T#(.*?),(.*)$", REG_EXTENDED|REG_NOSUB);
1641 regcomp(&fapint_regex_detect_exp,
"^\\{\\{", REG_EXTENDED|REG_NOSUB);
1643 regcomp(&fapint_regex_kiss_hdrbdy,
"^([A-Z0-9,*>-]+):(.+)$", REG_EXTENDED);
1644 regcomp(&fapint_regex_hdr_detail,
"^([A-Z0-9]{1,6})(-[0-9]{1,2})?>([A-Z0-9]{1,6})(-[0-9]{1,2})?(,.*)?$", REG_EXTENDED);
1645 regcomp(&fapint_regex_kiss_digi,
"^([A-Z0-9]{1,6})(-[0-9]{1,2})?(\\*)?$", REG_EXTENDED);
1647 regcomp(&fapint_regex_base91_telemetry,
"\\|([!-{]{2})([!-{]{2})([!-{]{2}|)([!-{]{2}|)([!-{]{2}|)([!-{]{2}|)([!-{]{2}|)\\|", REG_EXTENDED);
1649 regcomp(&fapint_regex_hopcount1,
"^([A-Z0-9-]+)\\*$", REG_EXTENDED);
1650 regcomp(&fapint_regex_hopcount2,
"^WIDE([1-7])-([0-7])$", REG_EXTENDED);
1654 fapint_initialized = 1;
1662 if ( fapint_initialized )
1665 regfree(&fapint_regex_header);
1666 regfree(&fapint_regex_ax25call);
1667 regfree(&fapint_regex_digicall);
1668 regfree(&fapint_regex_digicallv6);
1670 regfree(&fapint_regex_normalpos);
1671 regfree(&fapint_regex_normalamb);
1672 regfree(&fapint_regex_timestamp);
1674 regfree(&fapint_regex_mice_dstcall);
1675 regfree(&fapint_regex_mice_body);
1676 regfree(&fapint_regex_mice_amb);
1678 regfree(&fapint_regex_comment);
1679 regfree(&fapint_regex_phgr);
1680 regfree(&fapint_regex_phg);
1681 regfree(&fapint_regex_rng);
1682 regfree(&fapint_regex_altitude);
1684 regfree(&fapint_regex_mes_dst);
1685 regfree(&fapint_regex_mes_ack);
1686 regfree(&fapint_regex_mes_nack);
1688 regfree(&fapint_regex_wx1);
1689 regfree(&fapint_regex_wx2);
1690 regfree(&fapint_regex_wx3);
1691 regfree(&fapint_regex_wx4);
1692 regfree(&fapint_regex_wx5);
1694 regfree(&fapint_regex_wx_r1);
1695 regfree(&fapint_regex_wx_r24);
1696 regfree(&fapint_regex_wx_rami);
1698 regfree(&fapint_regex_wx_humi);
1699 regfree(&fapint_regex_wx_pres);
1700 regfree(&fapint_regex_wx_lumi);
1701 regfree(&fapint_regex_wx_what);
1703 regfree(&fapint_regex_wx_snow);
1704 regfree(&fapint_regex_wx_rrc);
1705 regfree(&fapint_regex_wx_any);
1706 regfree(&fapint_regex_wx_soft);
1708 regfree(&fapint_regex_nmea_chksum);
1709 regfree(&fapint_regex_nmea_dst);
1710 regfree(&fapint_regex_nmea_time);
1711 regfree(&fapint_regex_nmea_date);
1713 regfree(&fapint_regex_nmea_specou);
1714 regfree(&fapint_regex_nmea_fix);
1715 regfree(&fapint_regex_nmea_altitude);
1716 regfree(&fapint_regex_nmea_flag);
1717 regfree(&fapint_regex_nmea_coord);
1719 regfree(&fapint_regex_telemetry);
1720 regfree(&fapint_regex_peet_splitter);
1721 regfree(&fapint_regex_kiss_callsign);
1723 regfree(&fapint_regex_detect_comp);
1724 regfree(&fapint_regex_detect_wx);
1725 regfree(&fapint_regex_detect_telem);
1726 regfree(&fapint_regex_detect_exp);
1728 regfree(&fapint_regex_kiss_hdrbdy);
1729 regfree(&fapint_regex_hdr_detail);
1730 regfree(&fapint_regex_kiss_digi);
1732 regfree(&fapint_regex_base91_telemetry);
1734 regfree(&fapint_regex_hopcount1);
1735 regfree(&fapint_regex_hopcount2);
1738 fapint_initialized = 0;
1748 if ( packet == NULL )
1754 if ( packet->
type ) { free(packet->
type); }
1759 if ( packet->
body ) { free(packet->
body); }
1762 for ( i = 0; i < packet->
path_len; ++i )
1764 if ( packet->
path[i] ) { free(packet->
path[i]); }
1766 if ( packet->
path ) { free(packet->
path); }
1776 if ( packet->
speed ) { free(packet->
speed); }
1787 if ( packet->
alive ) { free(packet->
alive); }
1791 if ( packet->
phg ) { free(packet->
phg); }