00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00033 #include "helpers.h"
00034 #include "helpers2.h"
00035 #include "regs.h"
00036 #ifdef HAVE_CONFIG_H
00037 #include <config.h>
00038 #endif
00039
00040 #include <stdlib.h>
00041 #include <stdio.h>
00042 #include <string.h>
00043 #include <stdint.h>
00044 #include <regex.h>
00045 #include <ctype.h>
00046 #include <math.h>
00047
00048
00049
00050 int fapint_parse_header(fap_packet_t* packet, short const is_ax25)
00051 {
00052 int i, len, startpos, retval = 1;
00053 char* rest = NULL;
00054 char* tmp = NULL;
00055 char buf_10b[10];
00056 fapint_llist_item_t* path;
00057 int path_len;
00058 fapint_llist_item_t* current_elem;
00059 short seenq = 0;
00060
00061 unsigned int const matchcount = 3;
00062 regmatch_t matches[matchcount];
00063
00064
00065 if ( regexec(&fapint_regex_header, packet->header, matchcount, (regmatch_t*)&matches, 0) == 0 )
00066 {
00067
00068 tmp = malloc(matches[1].rm_eo+1);
00069 if ( !tmp ) return 0;
00070 memcpy(tmp, packet->header, matches[1].rm_eo);
00071 tmp[matches[1].rm_eo] = 0;
00072 if ( is_ax25 )
00073 {
00074 packet->src_callsign = fap_check_ax25_call(tmp, 0);
00075 free(tmp);
00076 if ( !packet->src_callsign )
00077 {
00078 packet->error_code = malloc(sizeof(fap_error_code_t));
00079 if ( packet->error_code ) *packet->error_code = fapSRCCALL_NOAX25;
00080 retval = 0;
00081 }
00082 }
00083 else
00084 {
00085 packet->src_callsign = tmp;
00086 }
00087
00088
00089 len = matches[2].rm_eo - matches[2].rm_so;
00090 rest = malloc(len+1);
00091 if ( !rest ) return 0;
00092 memcpy(rest, packet->header + matches[2].rm_so, len);
00093 rest[len] = 0;
00094 }
00095 else
00096 {
00097 packet->error_code = malloc(sizeof(fap_error_code_t));
00098 if ( packet->error_code ) *packet->error_code = fapSRCCALL_BADCHARS;
00099 retval = 0;
00100 }
00101 if ( !retval )
00102 {
00103 if ( rest ) free(rest);
00104 return 0;
00105 }
00106
00107
00108 len = 0;
00109 startpos = 0;
00110 path = NULL;
00111 path_len = -1;
00112 current_elem = NULL;
00113 tmp = NULL;
00114 for ( i = 0; i < strlen(rest); ++i )
00115 {
00116 tmp = NULL;
00117
00118
00119 if ( rest[i] == ',' )
00120 {
00121
00122 len = i - startpos;
00123 tmp = malloc(len+1);
00124 if ( !tmp )
00125 {
00126 retval = 0;
00127 break;
00128 }
00129 memcpy(tmp, rest+startpos, len);
00130 tmp[len] = 0;
00131
00132
00133 startpos = i + 1;
00134 }
00135 else if ( i+1 == strlen(rest) )
00136 {
00137
00138 len = i+1 - startpos;
00139 tmp = malloc(len+1);
00140 if ( !tmp )
00141 {
00142 retval = 0;
00143 break;
00144 }
00145 memcpy(tmp, rest+startpos, len);
00146 tmp[len] = 0;
00147 }
00148
00149
00150 if ( tmp )
00151 {
00152
00153 if ( path == NULL )
00154 {
00155 path = malloc(sizeof(fapint_llist_item_t));
00156 if ( !path )
00157 {
00158 retval = 0;
00159 break;
00160 }
00161 current_elem = path;
00162 }
00163 else
00164 {
00165 current_elem->next = malloc(sizeof(fapint_llist_item_t));
00166 if ( !current_elem->next )
00167 {
00168 retval = 0;
00169 break;
00170 }
00171 current_elem = current_elem->next;
00172 }
00173 current_elem->next = NULL;
00174 current_elem->text = tmp;
00175
00176 ++path_len;
00177 }
00178 }
00179 if ( !retval )
00180 {
00181 if ( tmp ) free(tmp);
00182 fapint_clear_llist(path);
00183 free(rest);
00184 return 0;
00185 }
00186
00187
00188 if ( !path )
00189 {
00190
00191 packet->error_code = malloc(sizeof(fap_error_code_t));
00192 if ( packet->error_code ) *packet->error_code = fapDSTCALL_NONE;
00193 fapint_clear_llist(path);
00194 free(rest);
00195 return 0;
00196 }
00197
00198
00199
00200 packet->dst_callsign = fap_check_ax25_call(path->text, 0);
00201 if ( !packet->dst_callsign )
00202 {
00203 packet->error_code = malloc(sizeof(fap_error_code_t));
00204 if ( packet->error_code ) *packet->error_code = fapDSTCALL_NOAX25;
00205 fapint_clear_llist(path);
00206 free(rest);
00207 return 0;
00208 }
00209
00210
00211 if ( is_ax25 && path_len > MAX_DIGIS )
00212 {
00213 packet->error_code = malloc(sizeof(fap_error_code_t));
00214 if ( packet->error_code ) *packet->error_code = fapDSTPATH_TOOMANY;
00215 fapint_clear_llist(path);
00216 free(rest);
00217 return 0;
00218 }
00219
00220
00221 packet->path = calloc(path_len, sizeof(char*));
00222 if ( !packet->path )
00223 {
00224 fapint_clear_llist(path);
00225 free(rest);
00226 }
00227 for ( i = 0; i < path_len; ++i ) packet->path[i] = NULL;
00228 i = 0;
00229 current_elem = path->next;
00230 while ( current_elem != NULL )
00231 {
00232
00233 if ( regexec(&fapint_regex_digicall, current_elem->text, matchcount, (regmatch_t*)&matches, 0) == 0 )
00234 {
00235
00236 if ( is_ax25 )
00237 {
00238
00239 memset(buf_10b, 0, 10);
00240 memcpy(buf_10b, current_elem->text, matches[1].rm_eo);
00241
00242
00243 tmp = fap_check_ax25_call(buf_10b, 1);
00244 if ( !tmp )
00245 {
00246 packet->error_code = malloc(sizeof(fap_error_code_t));
00247 if ( packet->error_code ) *packet->error_code = fapDIGICALL_NOAX25;
00248 retval = 0;
00249 break;
00250 }
00251 free(tmp);
00252 }
00253
00254
00255 len = strlen(current_elem->text);
00256 packet->path[i] = malloc(len+1);
00257 if ( !packet->path[i] )
00258 {
00259 retval = 0;
00260 break;
00261 }
00262 strcpy(packet->path[i], current_elem->text);
00263
00264
00265 if ( !seenq && current_elem->text[0] == 'q' ) seenq = 1;
00266 }
00267
00268 else if ( seenq && regexec(&fapint_regex_digicallv6, current_elem->text, 0, NULL, 0) == 0 )
00269 {
00270
00271 len = strlen(current_elem->text);
00272 packet->path[i] = malloc(len+1);
00273 if ( !packet->path[i] )
00274 {
00275 retval = 0;
00276 break;
00277 }
00278 strcpy(packet->path[i], current_elem->text);
00279 }
00280 else
00281 {
00282 packet->error_code = malloc(sizeof(fap_error_code_t));
00283 if ( packet->error_code ) *packet->error_code = fapDIGICALL_BADCHARS;
00284 retval = 0;
00285 break;
00286 }
00287
00288
00289 current_elem = current_elem->next;
00290 ++i;
00291 }
00292 if ( !retval )
00293 {
00294 fapint_clear_llist(path);
00295 for ( len = 0; len <= i; ++len ) { free(packet->path[len]); }
00296 free(packet->path);
00297 packet->path = NULL;
00298 free(rest);
00299 return 0;
00300 }
00301 packet->path_len = path_len;
00302
00303
00304 fapint_clear_llist(path);
00305 free(rest);
00306 return 1;
00307 }
00308
00309
00310
00311 int fapint_parse_mice(fap_packet_t* packet, char const* input, unsigned int const input_len)
00312 {
00313 int len, error, i, lon;
00314 unsigned int tmp_us;
00315 char *rest, *tmp_str;
00316 char dstcall[7], latitude[7], buf_6b[6], longitude[6];
00317 double speed, course_speed, course_speed_tmp, course;
00318 char dao[3];
00319
00320 unsigned int const matchcount = 3;
00321 regmatch_t matches[matchcount];
00322
00323
00324 if ( input_len < 8 || packet->dst_callsign == NULL )
00325 {
00326 packet->error_code = malloc(sizeof(fap_error_code_t));
00327 if ( packet->error_code ) *packet->error_code = fapMICE_SHORT;
00328 return 0;
00329 }
00330
00331
00332 memset(dstcall, 0, 7);
00333 for ( i = 0; i < strlen(packet->dst_callsign) && i < 6; ++i )
00334 {
00335 if ( packet->dst_callsign[i] == '-' ) break;
00336 dstcall[i] = packet->dst_callsign[i];
00337 }
00338 if ( strlen(dstcall) != 6 )
00339 {
00340 packet->error_code = malloc(sizeof(fap_error_code_t));
00341 if ( packet->error_code ) *packet->error_code = fapMICE_SHORT;
00342 return 0;
00343 }
00344
00345
00346 if ( regexec(&fapint_regex_mice_dstcall, dstcall, 0, NULL, 0) != 0 )
00347 {
00348
00349 packet->error_code = malloc(sizeof(fap_error_code_t));
00350 if ( packet->error_code ) *packet->error_code = fapMICE_INV;
00351 return 0;
00352 }
00353
00354
00355 packet->symbol_table = input[7];
00356
00357
00358
00359 error = 0;
00360 if ( input[0] < 0x26 || (unsigned char)input[0] > 0x7f ) error = 1;
00361 if ( input[1] < 0x26 || input[1] > 0x61 ) error = 1;
00362 if ( input[2] < 0x1c || (unsigned char)input[2] > 0x7f ) error = 1;
00363 if ( input[3] < 0x1c || (unsigned char)input[3] > 0x7f ) error = 1;
00364 if ( input[4] < 0x1c || input[4] > 0x7d ) error = 1;
00365 if ( input[5] < 0x1c || (unsigned char)input[5] > 0x7f ) error = 1;
00366 if ( input[6] != 0x7d && (input[6] < 0x21 || input[6] > 0x7b) ) error = 1;
00367 if ( error || regexec(&fapint_regex_mice_body, input+7, 0, NULL, 0) != 0 )
00368 {
00369 packet->error_code = malloc(sizeof(fap_error_code_t));
00370 if ( packet->error_code )
00371 {
00372
00373 if ( ( packet->symbol_table == '/' ) ||
00374 ( packet->symbol_table == '\\' ) ||
00375 ( packet->symbol_table >= 'A' && packet->symbol_table <= 'Z' ) ||
00376 isdigit(packet->symbol_table) )
00377 {
00378
00379 *packet->error_code = fapMICE_INV_INFO;
00380 }
00381 else
00382 {
00383
00384 *packet->error_code = fapSYM_INV_TABLE;
00385 }
00386 }
00387 return 0;
00388 }
00389
00390
00391 packet->format = malloc(sizeof(fap_pos_format_t));
00392 if ( !packet->format )
00393 {
00394 return 0;
00395 }
00396 *packet->format = fapPOS_MICE;
00397
00398
00399
00400
00401
00402 memset(latitude, 0, 7);
00403 for ( i = 0; i < 6; ++i )
00404 {
00405 if ( dstcall[i] >= 'A' && dstcall[i] <= 'J' )
00406 {
00407
00408 latitude[i] = dstcall[i] - 17;
00409 }
00410 else if ( dstcall[i] >= 'P' && dstcall[i] <= 'Y' )
00411 {
00412
00413 latitude[i] = dstcall[i] - 32;
00414 }
00415 else if ( dstcall[i] == 'K' || dstcall[i] == 'L' || dstcall[i] == 'Z' )
00416 {
00417
00418 latitude[i] = '_';
00419 }
00420 else
00421 {
00422 latitude[i] = dstcall[i];
00423 }
00424 }
00425
00426
00427 packet->pos_ambiguity = malloc(sizeof(unsigned int));
00428 if ( !packet->pos_ambiguity ) return 0;
00429 if ( regexec(&fapint_regex_mice_amb, latitude, matchcount, (regmatch_t*)&matches, 0) != 0 )
00430 {
00431 packet->error_code = malloc(sizeof(fap_error_code_t));
00432 if ( packet->error_code ) *packet->error_code = fapMICE_AMB_LARGE;
00433 return 0;
00434 }
00435 *packet->pos_ambiguity = matches[2].rm_eo - matches[2].rm_so;
00436
00437
00438 if ( *packet->pos_ambiguity > 4 )
00439 {
00440 packet->error_code = malloc(sizeof(fap_error_code_t));
00441 if ( packet->error_code ) *packet->error_code = fapMICE_AMB_INV;
00442 return 0;
00443 }
00444
00445
00446 packet->pos_resolution = malloc(sizeof(double));
00447 if ( !packet->pos_resolution ) return 0;
00448 *packet->pos_resolution = fapint_get_pos_resolution(2 - *packet->pos_ambiguity);
00449
00450
00451 if ( *packet->pos_ambiguity >= 4 )
00452 {
00453
00454 tmp_str = strchr(latitude, '_');
00455 *tmp_str = '3';
00456 }
00457 else
00458 {
00459
00460 if ( (tmp_str = strchr(latitude, '_')) != NULL )
00461 {
00462 *tmp_str = '5';
00463 }
00464 }
00465
00466
00467 while ( (tmp_str = strchr(latitude, '_')) != NULL )
00468 {
00469 *tmp_str = '0';
00470 }
00471
00472
00473 buf_6b[0] = latitude[0]; buf_6b[1] = latitude[1];
00474 buf_6b[2] = 0;
00475 packet->latitude = malloc(sizeof(double));
00476 if ( !packet->latitude ) return 0;
00477 *packet->latitude = atof(buf_6b);
00478
00479
00480 buf_6b[0] = latitude[2]; buf_6b[1] = latitude[3];
00481 buf_6b[2] = '.';
00482 buf_6b[3] = latitude[4]; buf_6b[4] = latitude[5];
00483 buf_6b[5] = 0;
00484 *packet->latitude += atof(buf_6b)/60;
00485
00486
00487 if ( dstcall[3] <= 0x4c )
00488 {
00489 *packet->latitude = 0 - *packet->latitude;
00490 }
00491
00492
00493 packet->messagebits = malloc(4);
00494 if ( !packet->messagebits ) return 0;
00495 for ( i = 0; i < 3; ++i )
00496 {
00497 if ( (dstcall[i] >= '0' && dstcall[i] <= '9') || dstcall[i] == 'L' )
00498 {
00499 packet->messagebits[i] = '0';
00500 }
00501 else if ( dstcall[i] >= 'P' && dstcall[i] <= 'Z' )
00502 {
00503 packet->messagebits[i] = '1';
00504 }
00505 else if ( dstcall[i] >= 'A' && dstcall[i] <= 'K' )
00506 {
00507 packet->messagebits[i] = '2';
00508 }
00509 }
00510 packet->messagebits[3] = 0;
00511
00512
00513
00514 lon = input[0] - 28;
00515 if ( dstcall[4] >= 0x50 )
00516 {
00517 lon += 100;
00518 }
00519 if ( lon >= 180 && lon <= 189 )
00520 {
00521 lon -= 80;
00522 }
00523 else if ( lon >= 190 && lon <= 199 )
00524 {
00525 lon -= 190;
00526 }
00527 packet->longitude = malloc(sizeof(double));
00528 if ( !packet->longitude ) return 0;
00529 *packet->longitude = lon;
00530
00531
00532 memset(longitude, 0, 6);
00533 lon = input[1] - 28;
00534 if ( lon >= 60 )
00535 {
00536 lon -= 60;
00537 }
00538 sprintf(longitude, "%02d.%02d", lon, input[2] - 28);
00539
00540
00541 if ( *packet->pos_ambiguity == 4 )
00542 {
00543
00544 *packet->longitude += 0.5;
00545 }
00546 else if ( *packet->pos_ambiguity == 3 )
00547 {
00548
00549 tmp_str = malloc(3);
00550 tmp_str[0] = longitude[0]; tmp_str[1] = '5'; tmp_str[2] = 0;
00551 *packet->longitude += atof(tmp_str)/60;
00552 free(tmp_str);
00553 }
00554 else if ( *packet->pos_ambiguity == 2 )
00555 {
00556
00557 memset(buf_6b, 0, 6);
00558 buf_6b[0] = longitude[0];
00559 buf_6b[1] = longitude[1];
00560 buf_6b[2] = '.';
00561 buf_6b[3] = '5';
00562 *packet->longitude += atof(buf_6b)/60;
00563 }
00564 else if ( *packet->pos_ambiguity == 1 )
00565 {
00566
00567 longitude[4] = '5';
00568 *packet->longitude += atof(longitude)/60;
00569 }
00570 else if ( *packet->pos_ambiguity == 0 )
00571 {
00572 *packet->longitude += atof(longitude)/60;
00573 }
00574 else
00575 {
00576 packet->error_code = malloc(sizeof(fap_error_code_t));
00577 if ( packet->error_code ) *packet->error_code = fapMICE_AMB_ODD;
00578 return 0;
00579 }
00580
00581
00582 if ( dstcall[5] >= 0x50 )
00583 {
00584 *packet->longitude = 0 - *packet->longitude;
00585 }
00586
00587
00588 speed = (input[3] - 28) * 10;
00589 course_speed = input[4] - 28;
00590 course_speed_tmp = floor(course_speed / 10);
00591 speed += course_speed_tmp;
00592 course_speed -= course_speed_tmp * 10;
00593 course = 100 * course_speed;
00594 course += input[5] - 28;
00595
00596
00597 if ( speed >= 800 )
00598 {
00599 speed -= 800;
00600 }
00601 if ( course >= 400 )
00602 {
00603 course -= 400;
00604 }
00605
00606
00607 packet->speed = malloc(sizeof(double));
00608 if ( !packet->speed ) return 0;
00609 *packet->speed = speed * KNOT_TO_KMH;
00610 if ( course >= 0 )
00611 {
00612 packet->course = malloc(sizeof(unsigned int));
00613 if ( !packet->course ) return 0;
00614 *packet->course = course;
00615 }
00616
00617
00618 packet->symbol_code = input[6];
00619
00620
00621 if ( (len = input_len - 8) > 0 )
00622 {
00623 rest = malloc(len);
00624 memcpy(rest, input+8, len);
00625 }
00626 else
00627 {
00628
00629 return 1;
00630 }
00631
00632
00633
00634
00635 for ( i = 0; i+3 < len; ++i )
00636 {
00637
00638 if ( rest[i] >= 0x21 && rest[i] <= 0x7b )
00639 {
00640
00641 if ( (rest[i+1] >= 0x21 && rest[i+1] <= 0x7b) &&
00642 (rest[i+2] >= 0x21 && rest[i+2] <= 0x7b) &&
00643 rest[i+3] == '}' )
00644 {
00645
00646 packet->altitude = malloc(sizeof(double));
00647 if ( !packet->altitude )
00648 {
00649 free(rest);
00650 return 0;
00651 }
00652 *packet->altitude = ( (rest[i] - 33) * pow(91,2) +
00653 (rest[i+1] - 33) * 91 +
00654 (rest[i+2] - 33) ) - 10000;
00655
00656 tmp_str = fapint_remove_part(rest, len, i, i+4, &tmp_us);
00657 free(rest);
00658 rest = tmp_str;
00659 len = tmp_us;
00660
00661 break;
00662 }
00663 }
00664 }
00665
00666
00667 if ( len > 0 )
00668 {
00669 for ( i = len-1; i >= 0 ; --i )
00670 {
00671 if ( i + 4 < len && rest[i] == '!' &&
00672 0x21 <= rest[i+1] && rest[i+1] <= 0x7b &&
00673 0x20 <= rest[i+2] && rest[i+2] <= 0x7b &&
00674 0x20 <= rest[i+3] && rest[i+3] <= 0x7b &&
00675 rest[i+4] == '!' )
00676 {
00677 memcpy(dao, rest+i+1, 3);
00678
00679 if ( fapint_parse_dao(packet, dao) )
00680 {
00681
00682 tmp_str = fapint_remove_part(rest, len, i, i+5, &tmp_us);
00683 free(rest);
00684 rest = tmp_str;
00685 len = tmp_us;
00686 break;
00687 }
00688 }
00689 }
00690 }
00691
00692
00693
00694
00695
00696 if ( len > 0 )
00697 {
00698 packet->comment = rest;
00699 packet->comment_len = len;
00700 }
00701
00702 return 1;
00703 }
00704
00705
00706 time_t fapint_parse_timestamp(char const* input)
00707 {
00708 char buf_3b[3];
00709 unsigned int first, second, third;
00710 char type;
00711 struct tm now_struct, fwd_struct, back_struct, *tmp_struct;
00712 time_t now, fwd, back, result;
00713
00714 unsigned int const matchcount = 5;
00715 regmatch_t matches[matchcount];
00716
00717
00718
00719 if ( !input )
00720 {
00721 return 0;
00722 }
00723 if ( regexec(&fapint_regex_timestamp, input, matchcount, (regmatch_t*)&matches, 0) == 0 )
00724 {
00725 buf_3b[2] = 0;
00726
00727 memcpy(buf_3b, input+matches[1].rm_so, 2);
00728 first = atoi(buf_3b);
00729 memcpy(buf_3b, input+matches[2].rm_so, 2);
00730 second = atoi(buf_3b);
00731 memcpy(buf_3b, input+matches[3].rm_so, 2);
00732 third = atoi(buf_3b);
00733
00734
00735 type = input[matches[4].rm_so];
00736 }
00737 else
00738 {
00739 return 0;
00740 }
00741
00742
00743 if ( type == 'h' )
00744 {
00745
00746 if ( first > 23 || second > 59 || third > 59 )
00747 {
00748 return 0;
00749 }
00750
00751
00752 now = time(NULL);
00753 tmp_struct = gmtime(&now);
00754 memcpy((struct tm*)&now_struct, tmp_struct, sizeof(struct tm));
00755 now_struct.tm_sec = third;
00756 now_struct.tm_min = second;
00757 now_struct.tm_hour = first-1;
00758 result = mktime((struct tm*)&now_struct);
00759
00760
00761
00762 if ( now + 3900 < result )
00763 {
00764 result -= 86400;
00765 }
00766
00767
00768 else if ( now - 82500 > result )
00769 {
00770 result += 86400;
00771 }
00772 return result;
00773 }
00774 else if ( type == 'z' || type == '/' )
00775 {
00776
00777 if ( first < 1 || first > 31 || second > 23 || third > 59 )
00778 {
00779 return 0;
00780 }
00781
00782
00783
00784
00785
00786
00787
00788 now = time(NULL);
00789 if ( type == 'z' )
00790 {
00791 tmp_struct = gmtime(&now);
00792 }
00793 else
00794 {
00795 tmp_struct = localtime(&now);
00796 }
00797 memcpy((struct tm*)&now_struct, tmp_struct, sizeof(struct tm));
00798 now_struct.tm_mday = first;
00799 now_struct.tm_hour = second-1;
00800 now_struct.tm_min = third;
00801 now_struct.tm_sec = 0;
00802 now = mktime((struct tm*)&now_struct);
00803
00804
00805 memcpy((struct tm*)&fwd_struct, tmp_struct, sizeof(struct tm));
00806 fwd_struct.tm_mon += 1;
00807 fwd_struct.tm_mday = first;
00808 fwd_struct.tm_hour = second-1;
00809 fwd_struct.tm_min = third;
00810 fwd_struct.tm_sec = 0;
00811 fwd = mktime((struct tm*)&fwd_struct);
00812
00813
00814 memcpy((struct tm*)&back_struct, tmp_struct, sizeof(struct tm));
00815 if ( back_struct.tm_mon == 0 )
00816 {
00817 back_struct.tm_mon = 11;
00818 back_struct.tm_year -= 1;
00819 }
00820 else
00821 {
00822 back_struct.tm_mon -= 1;
00823 }
00824 back_struct.tm_mday = first;
00825 back_struct.tm_hour = second-1;
00826 back_struct.tm_min = third;
00827 back_struct.tm_sec = 0;
00828 back = mktime((struct tm*)&back_struct);
00829
00830
00831
00832 if ( fwd - now < 43400 )
00833 {
00834 result = fwd;
00835 }
00836 else if ( now - time(NULL) < 43400 )
00837 {
00838 result = now;
00839 }
00840 else
00841 {
00842 result = back;
00843 }
00844
00845 return result;
00846 }
00847
00848 return 0;
00849 }
00850
00851
00852 int fapint_parse_compressed(fap_packet_t* packet, char const* input)
00853 {
00854 int i;
00855 char symboltable, symbolcode;
00856 char lat[4], lon[4];
00857 char c1, s1, comptype;
00858 char cs;
00859
00860
00861 if ( strlen(input) < 13 )
00862 {
00863 packet->error_code = malloc(sizeof(fap_error_code_t));
00864 if ( packet->error_code ) *packet->error_code = fapCOMP_INV;
00865 return 0;
00866 }
00867 if ( !(
00868 (input[0] >= 'A' && input[0] <= 'Z') ||
00869 (input[0] >= 'a' && input[0] <= 'j') ||
00870 input[0] == '/' ||
00871 input[0] == '\\')
00872 )
00873 {
00874 packet->error_code = malloc(sizeof(fap_error_code_t));
00875 if ( packet->error_code ) *packet->error_code = fapCOMP_INV;
00876 return 0;
00877 }
00878 for ( i = 1; i <= 8; ++i )
00879 {
00880 if ( input[i] < 0x21 || input[i] > 0x7b )
00881 {
00882 packet->error_code = malloc(sizeof(fap_error_code_t));
00883 if ( packet->error_code ) *packet->error_code = fapCOMP_INV;
00884 return 0;
00885 }
00886 }
00887 if ( input[9] != 0x7d && (input[9] < 0x21 || input[9] > 0x7b) )
00888 {
00889 packet->error_code = malloc(sizeof(fap_error_code_t));
00890 if ( packet->error_code ) *packet->error_code = fapCOMP_INV;
00891 return 0;
00892 }
00893 for ( i = 10; i <= 12; ++i )
00894 {
00895 if ( input[i] < 0x20 || input[i] > 0x7b )
00896 {
00897 packet->error_code = malloc(sizeof(fap_error_code_t));
00898 if ( packet->error_code ) *packet->error_code = fapCOMP_INV;
00899 return 0;
00900 }
00901 }
00902
00903
00904 packet->format = malloc(sizeof(fap_pos_format_t));
00905 if ( !packet->format )
00906 {
00907 return 0;
00908 }
00909 *packet->format = fapPOS_COMPRESSED;
00910
00911
00912 symboltable = input[0];
00913 symbolcode = input[9];
00914
00915
00916 for ( i = 0; i < 4; ++i )
00917 {
00918 lat[i] = input[i+1] - 33;
00919 lon[i] = input[i+5] - 33;
00920 }
00921
00922
00923 c1 = input[10] - 33;
00924 s1 = input[11] - 33;
00925 comptype = input[12] - 33;
00926
00927
00928 if ( symboltable >= 'a' && symboltable <= 'j' )
00929 {
00930 symboltable -= 81;
00931 }
00932 packet->symbol_table = symboltable;
00933
00934
00935 packet->symbol_code = symbolcode;
00936
00937
00938
00939 packet->latitude = malloc(sizeof(double));
00940 if ( !packet->latitude ) return 0;
00941 *packet->latitude = 90 - ( (lat[0] * pow(91,3) + lat[1] * pow(91,2) + lat[2] * 91 + lat[3]) / 380926);
00942 packet->longitude = malloc(sizeof(double));
00943 if ( !packet->latitude ) return 0;
00944 *packet->longitude = -180 + ( (lon[0] * pow(91,3) + lon[1] * pow(91,2) + lon[2] * 91 + lon[3]) / 190463);
00945
00946
00947 packet->pos_resolution = malloc(sizeof(double));
00948 if ( !packet->pos_resolution ) return 0;
00949 *packet->pos_resolution = 0.291;
00950
00951
00952 if ( c1 != -1 )
00953 {
00954 packet->gps_fix_status = malloc(sizeof(short));
00955 if ( !packet->gps_fix_status ) return 0;
00956 if ( (comptype & 0x20) == 0x20 )
00957 {
00958 *packet->gps_fix_status = 1;
00959 }
00960 else
00961 {
00962 *packet->gps_fix_status = 0;
00963 }
00964 }
00965
00966
00967
00968
00969 if ( c1 == -1 || s1 == -1 )
00970 {
00971
00972 }
00973 else if ( (comptype & 0x18) == 0x10 )
00974 {
00975
00976 cs = c1 * 91 + s1;
00977 packet->altitude = malloc(sizeof(double));
00978 if ( !packet->altitude ) return 0;
00979
00980 *packet->altitude = pow(1.002, cs) * 0.3048;
00981 }
00982 else if ( c1 >= 0 && c1 <= 89 )
00983 {
00984 packet->course = malloc(sizeof(unsigned int));
00985 if ( !packet->course ) return 0;
00986 if ( c1 == 0 )
00987 {
00988
00989
00990 *packet->course = 360;
00991 }
00992 else
00993 {
00994 *packet->course = c1 * 4;
00995 }
00996
00997 packet->speed = malloc(sizeof(double));
00998 if ( !packet->speed ) return 0;
00999 *packet->speed = ( pow(1.08, s1) - 1 ) * KNOT_TO_KMH;
01000 }
01001 else if ( c1 == 90 )
01002 {
01003
01004 packet->radio_range = malloc(sizeof(unsigned int));
01005 if ( !packet->radio_range ) return 0;
01006 *packet->radio_range = 2 * pow(1.08, s1) * MPH_TO_KMH;
01007 }
01008
01009 return 1;
01010 }
01011
01012
01013 int fapint_parse_normal(fap_packet_t* packet, char const* input)
01014 {
01015 char sind, wind;
01016 short is_south = 0;
01017 short is_west = 0;
01018 char lat_deg[3], lat_min[6], lon_deg[4], lon_min[6], tmp_5b[5];
01019 double lat, lon;
01020
01021 unsigned int const matchcount = 9;
01022 regmatch_t matches[matchcount];
01023
01024
01025
01026 if ( strlen(input) < 19 )
01027 {
01028 packet->error_code = malloc(sizeof(fap_error_code_t));
01029 if ( packet->error_code ) *packet->error_code = fapLOC_SHORT;
01030 return 0;
01031 }
01032
01033
01034 packet->format = malloc(sizeof(fap_pos_format_t));
01035 if ( !packet->format )
01036 {
01037 return 0;
01038 }
01039 *packet->format = fapPOS_UNCOMPRESSED;
01040
01041
01042 if ( regexec(&fapint_regex_normalpos, input, matchcount, (regmatch_t*)&matches, 0) != 0 )
01043 {
01044 packet->error_code = malloc(sizeof(fap_error_code_t));
01045 if ( packet->error_code ) *packet->error_code = fapLOC_INV;
01046 return 0;
01047 }
01048 if ( input[18] != 0x7d && (input[18] < 0x21 || input[18] > 0x7b) )
01049 {
01050 packet->error_code = malloc(sizeof(fap_error_code_t));
01051 if ( packet->error_code ) *packet->error_code = fapLOC_INV;
01052 return 0;
01053 }
01054
01055
01056 sind = toupper(input[matches[3].rm_so]);
01057 wind = toupper(input[matches[7].rm_so]);
01058
01059
01060 packet->symbol_table = input[matches[4].rm_so];
01061 packet->symbol_code = input[18];
01062
01063
01064 memset(lat_deg, 0, 3);
01065 memcpy(lat_deg, input+matches[1].rm_so, 2);
01066 memset(lat_min, 0, 6);
01067 memcpy(lat_min, input+matches[2].rm_so, 5);
01068 memset(lon_deg, 0, 4);
01069 memcpy(lon_deg, input+matches[5].rm_so, 3);
01070 memset(lon_min, 0, 6);
01071 memcpy(lon_min, input+matches[6].rm_so, 5);
01072
01073
01074 if ( ( packet->symbol_table == '/' ) ||
01075 ( packet->symbol_table == '\\' ) ||
01076 ( packet->symbol_table >= 'A' && packet->symbol_table <= 'Z' ) ||
01077 isdigit(packet->symbol_table) )
01078 {
01079
01080 }
01081 else
01082 {
01083
01084 packet->error_code = malloc(sizeof(fap_error_code_t));
01085 if ( packet->error_code ) *packet->error_code = fapSYM_INV_TABLE;
01086 return 0;
01087 }
01088
01089
01090 if ( sind == 'S' ) is_south = 1;
01091 if ( wind == 'W' ) is_west = 1;
01092
01093
01094 lat = atoi(lat_deg);
01095 lon = atoi(lon_deg);
01096 if ( lat > 89 || lon > 179 )
01097 {
01098 packet->error_code = malloc(sizeof(fap_error_code_t));
01099 if ( packet->error_code ) *packet->error_code = fapLOC_LARGE;
01100 return 0;
01101 }
01102
01103
01104 packet->pos_ambiguity = malloc(sizeof(unsigned int));
01105 if ( !packet->pos_ambiguity ) return 0;
01106
01107
01108 tmp_5b[0] = lat_min[0];
01109 tmp_5b[1] = lat_min[1];
01110 tmp_5b[2] = lat_min[3];
01111 tmp_5b[3] = lat_min[4];
01112 tmp_5b[4] = 0;
01113
01114
01115 if ( regexec(&fapint_regex_normalamb, tmp_5b, matchcount, (regmatch_t*)&matches, 0) != 0 )
01116 {
01117 packet->error_code = malloc(sizeof(fap_error_code_t));
01118 if ( packet->error_code ) *packet->error_code = fapLOC_AMB_INV;
01119 return 0;
01120 }
01121 *packet->pos_ambiguity = matches[2].rm_eo - matches[2].rm_so;
01122
01123
01124 packet->latitude = malloc(sizeof(double));
01125 packet->longitude = malloc(sizeof(double));
01126 if ( !packet->latitude || !packet->longitude ) return 0;
01127 switch ( *packet->pos_ambiguity )
01128 {
01129 case 0:
01130
01131 if ( strchr(lon_min, ' ') != NULL )
01132 {
01133 packet->error_code = malloc(sizeof(fap_error_code_t));
01134 if ( packet->error_code ) *packet->error_code = fapLOC_AMB_INV;
01135 return 0;
01136 }
01137 else
01138 {
01139 *packet->latitude = lat + atof(lat_min)/60;
01140 *packet->longitude = lon + atof(lon_min)/60;
01141 }
01142 break;
01143 case 4:
01144
01145 *packet->latitude = lat + 0.5;
01146 *packet->longitude = lon + 0.5;
01147 break;
01148 case 1:
01149 case 2:
01150
01151 *packet->latitude = lat + atof(lat_min)/60;
01152 *packet->longitude = lon + atof(lon_min)/60;
01153 break;
01154 case 3:
01155
01156 lat_min[1] = '5';
01157 memset(lat_min+2, 0, 4);
01158 lon_min[1] = '5';
01159 memset(lon_min+2, 0, 4);
01160 *packet->latitude = lat + atof(lat_min)/60;
01161 *packet->longitude = lon + atof(lon_min)/60;
01162 break;
01163 default:
01164 packet->error_code = malloc(sizeof(fap_error_code_t));
01165 if ( packet->error_code ) *packet->error_code = fapLOC_AMB_INV;
01166 return 0;
01167 }
01168
01169
01170 if ( is_south )
01171 {
01172 *packet->latitude = 0 - *packet->latitude;
01173 }
01174 if ( is_west )
01175 {
01176 *packet->longitude = 0 - *packet->longitude;
01177 }
01178
01179
01180 packet->pos_resolution = malloc(sizeof(double));
01181 if ( !packet->pos_resolution ) return 0;
01182 *packet->pos_resolution = fapint_get_pos_resolution(2 - *packet->pos_ambiguity);
01183
01184 return 1;
01185 }
01186
01187
01188
01189 void fapint_parse_comment(fap_packet_t* packet, char const* input, unsigned int const input_len)
01190 {
01191 char course[4], speed[4], range[5], altitude[7], dao[3];
01192 int i, tmp_s;
01193 char* tmp_str, *rest = NULL;
01194 unsigned int rest_len = 0, tmp_us;
01195
01196 unsigned int const matchcount = 2;
01197 regmatch_t matches[matchcount];
01198
01199
01200
01201
01202 if ( input_len >= 7 )
01203 {
01204
01205 if ( regexec(&fapint_regex_comment, input, 0, NULL, 0) == 0 )
01206 {
01207
01208 if ( !packet->course )
01209 {
01210 memcpy(course, input, 3);
01211 course[3] = 0;
01212 packet->course = malloc(sizeof(unsigned int));
01213 if ( !packet->course ) return;
01214 *packet->course = 0;
01215 if ( isdigit(course[0]) && isdigit(course[1]) && isdigit(course[2]) )
01216 {
01217 tmp_s = atoi(course);
01218 if ( tmp_s >= 1 && tmp_s <= 360 )
01219 {
01220
01221 *packet->course = tmp_s;
01222 }
01223 }
01224 }
01225
01226
01227 if ( !packet->speed )
01228 {
01229
01230 memcpy(speed, input+4, 3);
01231 speed[3] = 0;
01232 if ( isdigit(speed[0]) && isdigit(speed[1]) && isdigit(speed[2]) )
01233 {
01234 tmp_s = atoi(&speed[0]);
01235 packet->speed = malloc(sizeof(double));
01236 if ( !packet->speed ) return;
01237 *packet->speed = tmp_s * KNOT_TO_KMH;
01238 }
01239 }
01240
01241
01242 rest = fapint_remove_part(input, input_len, 0, 7, &rest_len);
01243 }
01244
01245 else if ( regexec(&fapint_regex_phgr, input, 0, NULL, 0) == 0 &&
01246 input[4] >= 0x30 && input[4] <= 0x7e )
01247 {
01248
01249 packet->phg = malloc(6);
01250 if ( !packet->phg ) return;
01251 memcpy(packet->phg, input+3, 5);
01252 packet->phg[5] = 0;
01253
01254
01255 rest = fapint_remove_part(input, input_len, 0, 8, &rest_len);
01256 }
01257
01258 else if ( regexec(&fapint_regex_phg, input, 0, NULL, 0) == 0 &&
01259 input[4] >= 0x30 && input[4] <= 0x7e )
01260 {
01261
01262 packet->phg = malloc(5);
01263 if ( !packet->phg ) return;
01264 memcpy(packet->phg, input+3, 4);
01265 packet->phg[4] = 0;
01266
01267
01268 rest = fapint_remove_part(input, input_len, 0, 7, &rest_len);
01269 }
01270
01271 else if ( regexec(&fapint_regex_rng, input, 0, NULL, 0) == 0 )
01272 {
01273
01274 memcpy(range, input+3, 4);
01275 range[4] = 0;
01276 tmp_s = atoi(range);
01277 packet->radio_range = malloc(sizeof(unsigned int));
01278 if ( !packet->radio_range ) return;
01279 *packet->radio_range = tmp_s * MPH_TO_KMH;
01280
01281
01282 rest = fapint_remove_part(input, input_len, 0, 7, &rest_len);
01283 }
01284 else
01285 {
01286 rest = malloc(input_len+1);
01287 if ( !rest ) return;
01288 memcpy(rest, input, input_len);
01289 rest_len = input_len;
01290 rest[rest_len] = 0;
01291 }
01292 }
01293 else if ( input_len > 0 )
01294 {
01295 rest = malloc(input_len+1);
01296 if ( !rest ) return;
01297 memcpy(rest, input, input_len);
01298 rest_len = input_len;
01299 rest[rest_len] = 0;
01300 }
01301
01302
01303 if ( rest_len > 0 )
01304 {
01305
01306 if ( regexec(&fapint_regex_altitude, rest, matchcount, (regmatch_t*)&matches, 0) == 0 )
01307 {
01308
01309 if ( !packet->altitude )
01310 {
01311 memcpy(altitude, rest+matches[1].rm_so, 6);
01312 altitude[6] = 0;
01313 tmp_s = atoi(altitude);
01314 packet->altitude = malloc(sizeof(double));
01315 *packet->altitude = tmp_s * FT_TO_M;
01316 }
01317
01318
01319 tmp_str = fapint_remove_part(rest, rest_len, matches[1].rm_so-3, matches[1].rm_eo, &tmp_us);
01320 free(rest);
01321 rest = tmp_str;
01322 rest_len = tmp_us;
01323 }
01324 }
01325
01326
01327 if ( rest_len > 0 )
01328 {
01329 for ( i = rest_len-1; i >= 0 ; --i )
01330 {
01331 if ( i + 4 < rest_len && rest[i] == '!' &&
01332 0x21 <= rest[i+1] && rest[i+1] <= 0x7b &&
01333 0x20 <= rest[i+2] && rest[i+2] <= 0x7b &&
01334 0x20 <= rest[i+3] && rest[i+3] <= 0x7b &&
01335 rest[i+4] == '!' )
01336 {
01337 memcpy(dao, rest+i+1, 3);
01338
01339 if ( fapint_parse_dao(packet, dao) )
01340 {
01341
01342 tmp_str = fapint_remove_part(rest, rest_len, i, i+5, &tmp_us);
01343 free(rest);
01344 rest = tmp_str;
01345 rest_len = tmp_us;
01346 break;
01347 }
01348 }
01349 }
01350 }
01351
01352
01353
01354
01355
01356 if ( rest_len > 0 )
01357 {
01358 packet->comment = rest;
01359 packet->comment_len = rest_len;
01360 }
01361 }
01362
01363
01364
01365 int fapint_parse_nmea(fap_packet_t* packet, char const* input, unsigned int const input_len)
01366 {
01367 char* rest;
01368 unsigned int rest_len;
01369 int i, len, retval = 1;
01370
01371 char* checksum_area;
01372 char checksum_given_str[3];
01373 long int checksum_given;
01374 long int checksum_calculated = 0;
01375
01376 fapint_llist_item_t* nmea_field_list = NULL, *current_elem = NULL;
01377 char** nmea_fields = NULL;
01378 unsigned int nmea_field_count;
01379 char* tmp_str;
01380
01381 char buf_3b[3];
01382 unsigned int year, month, day, hours, mins, secs;
01383 struct tm timestamp;
01384
01385 unsigned int const matchcount = 5;
01386 regmatch_t matches[matchcount];
01387
01388
01389 for ( i = input_len-1; i >= 0; ++i )
01390 {
01391 if ( !isspace(input[i]) )
01392 {
01393 break;
01394 }
01395 }
01396 rest_len = i+1;
01397
01398 if ( rest_len > 0 )
01399 {
01400 rest = malloc(rest_len+1);
01401 if ( !rest ) return 0;
01402 memcpy(rest, input, rest_len);
01403 rest[rest_len] = 0;
01404 }
01405 else
01406 {
01407 return 0;
01408 }
01409
01410
01411 if ( regexec(&fapint_regex_nmea_chksum, rest, matchcount, (regmatch_t*)&matches, 0) == 0 )
01412 {
01413 len = matches[1].rm_eo - matches[1].rm_so;
01414 checksum_area = malloc(len+1);
01415 if ( !checksum_area )
01416 {
01417 free(rest);
01418 return 0;
01419 }
01420 memcpy(checksum_area, rest+matches[1].rm_so, len);
01421 checksum_area[len] = 0;
01422
01423 checksum_given_str[0] = rest[matches[2].rm_so];
01424 checksum_given_str[1] = rest[matches[2].rm_so+1];
01425 checksum_given_str[2] = 0;
01426 checksum_given = strtol(checksum_given_str, NULL, 16);
01427
01428 for ( i = 0; i < strlen(checksum_area); ++i )
01429 {
01430 checksum_calculated ^= checksum_area[i];
01431 }
01432 free(checksum_area);
01433
01434 if ( checksum_given != checksum_calculated )
01435 {
01436 packet->error_code = malloc(sizeof(fap_error_code_t));
01437 if ( packet->error_code ) *packet->error_code = fapNMEA_INV_CKSUM;
01438 free(rest);
01439 return 0;
01440 }
01441
01442
01443 packet->nmea_checksum_ok = malloc(sizeof(short));
01444 if ( !packet->nmea_checksum_ok )
01445 {
01446 free(rest);
01447 return 0;
01448 }
01449 *packet->nmea_checksum_ok = 1;
01450
01451
01452 rest = fapint_remove_part(rest, rest_len, matches[2].rm_so-1, matches[2].rm_eo, &rest_len);
01453 }
01454 else
01455 {
01456 printf("no checksum in (%s)", rest);
01457 }
01458
01459
01460 packet->format = malloc(sizeof(fap_pos_format_t));
01461 if ( !packet->format )
01462 {
01463 free(rest);
01464 return 0;
01465 }
01466 *packet->format = fapPOS_NMEA;
01467
01468
01469 if ( !fapint_parse_symbol_from_dst_callsign(packet) )
01470 {
01471 packet->symbol_table = '/';
01472 packet->symbol_code = '/';
01473 }
01474
01475
01476 tmp_str = strtok(rest, ",");
01477 nmea_field_count = 0;
01478 while ( tmp_str != NULL )
01479 {
01480
01481 if ( !nmea_field_list )
01482 {
01483 nmea_field_list = malloc(sizeof(fapint_llist_item_t));
01484 if ( !nmea_field_list ) return 0;
01485 current_elem = nmea_field_list;
01486 }
01487 else
01488 {
01489 current_elem->next = malloc(sizeof(fapint_llist_item_t));
01490 if ( !current_elem->next )
01491 {
01492 retval = 0;
01493 break;
01494 }
01495 current_elem = current_elem->next;
01496 }
01497 current_elem->next = NULL;
01498
01499
01500 current_elem->text = malloc(strlen(tmp_str)+1);
01501 if ( !current_elem->text )
01502 {
01503 retval = 0;
01504 break;
01505 }
01506 strcpy(current_elem->text, tmp_str);
01507 nmea_field_count++;
01508
01509
01510 tmp_str = strtok(NULL, ",");
01511 }
01512 if ( !retval )
01513 {
01514 fapint_clear_llist(nmea_field_list);
01515 free(rest);
01516 return 0;
01517 }
01518
01519
01520 do
01521 {
01522 if ( !nmea_field_count )
01523 {
01524 packet->error_code = malloc(sizeof(fap_error_code_t));
01525 if ( packet->error_code ) *packet->error_code = fapNMEA_NOFIELDS;
01526 retval = 0;
01527 break;
01528 }
01529 else
01530 {
01531 nmea_fields = calloc(nmea_field_count, sizeof(char*));
01532 if ( !nmea_fields )
01533 {
01534 retval = 0;
01535 break;
01536 }
01537 for ( i = 0; i < nmea_field_count; ++i ) nmea_fields[i] = NULL;
01538 current_elem = nmea_field_list;
01539 i = 0;
01540 while ( current_elem != NULL )
01541 {
01542 nmea_fields[i] = malloc(strlen(current_elem->text)+1);
01543 if ( !nmea_fields[i] )
01544 {
01545 retval = 0;
01546 break;
01547 }
01548 strcpy(nmea_fields[i], current_elem->text);
01549 current_elem = current_elem->next;
01550 i++;
01551 }
01552 }
01553 }
01554 while ( 0 );
01555 fapint_clear_llist(nmea_field_list);
01556 if ( !retval )
01557 {
01558 free(nmea_fields);
01559 free(rest);
01560 return 0;
01561 }
01562
01563
01564
01565 while ( retval )
01566 {
01567 if ( strcmp(nmea_fields[0], "GPRMC") == 0 )
01568 {
01569
01570 if ( nmea_field_count < 10 )
01571 {
01572 packet->error_code = malloc(sizeof(fap_error_code_t));
01573 if ( packet->error_code ) *packet->error_code = fapGPRMC_FEWFIELDS;
01574 retval = 0;
01575 break;
01576 }
01577
01578
01579 if ( strcmp(nmea_fields[2], "A" ) != 0 )
01580 {
01581 packet->error_code = malloc(sizeof(fap_error_code_t));
01582 if ( packet->error_code ) *packet->error_code = fapGPRMC_NOFIX;
01583 retval = 0;
01584 break;
01585 }
01586
01587
01588 if ( regexec(&fapint_regex_nmea_time, nmea_fields[1], matchcount, (regmatch_t*)&matches, 0) == 0 )
01589 {
01590 buf_3b[2] = 0;
01591 memcpy(buf_3b, nmea_fields[1]+matches[1].rm_so, 2);
01592 hours = atoi(buf_3b);
01593 memcpy(buf_3b, nmea_fields[1]+matches[2].rm_so, 2);
01594 mins = atoi(buf_3b);
01595 memcpy(buf_3b, nmea_fields[1]+matches[3].rm_so, 2);
01596 secs = atoi(buf_3b);
01597
01598 if ( hours > 23 || mins > 59 || secs > 59 )
01599 {
01600 packet->error_code = malloc(sizeof(fap_error_code_t));
01601 if ( packet->error_code ) *packet->error_code = fapGPRMC_INV_TIME;
01602 retval = 0;
01603 break;
01604 }
01605 }
01606 else
01607 {
01608 packet->error_code = malloc(sizeof(fap_error_code_t));
01609 if ( packet->error_code ) *packet->error_code = fapGPRMC_INV_TIME;
01610 retval = 0;
01611 break;
01612 }
01613
01614
01615 if ( regexec(&fapint_regex_nmea_date, nmea_fields[9], matchcount, (regmatch_t*)&matches, 0) == 0 )
01616 {
01617 buf_3b[2] = 0;
01618 memcpy(buf_3b, nmea_fields[9]+matches[1].rm_so, 2);
01619 day = atoi(buf_3b);
01620 memcpy(buf_3b, nmea_fields[9]+matches[2].rm_so, 2);
01621 month = atoi(buf_3b);
01622 memcpy(buf_3b, nmea_fields[9]+matches[3].rm_so, 2);
01623 year = atoi(buf_3b);
01624
01625
01626
01627 if ( year < 70 )
01628 {
01629 year += 2000;
01630 }
01631 else
01632 {
01633 year += 1900;
01634 }
01635 if ( !fapint_check_date(year, month, day) )
01636 {
01637 packet->error_code = malloc(sizeof(fap_error_code_t));
01638 if ( packet->error_code ) *packet->error_code = fapGPRMC_INV_DATE;
01639 retval = 0;
01640 break;
01641 }
01642 }
01643 else
01644 {
01645 packet->error_code = malloc(sizeof(fap_error_code_t));
01646 if ( packet->error_code ) *packet->error_code = fapGPRMC_INV_DATE;
01647 retval = 0;
01648 break;
01649 }
01650
01651
01652
01653 if ( year >= 2038 || year < 1970 )
01654 {
01655 packet->error_code = malloc(sizeof(fap_error_code_t));
01656 if ( packet->error_code ) *packet->error_code = fapGPRMC_DATE_OUT;
01657 retval = 0;
01658 break;
01659 }
01660 else
01661 {
01662 timestamp.tm_sec = secs;
01663 timestamp.tm_min = mins;
01664 timestamp.tm_hour = hours;
01665 timestamp.tm_mday = day;
01666 timestamp.tm_mon = month-1;
01667 timestamp.tm_year = year-1900;
01668 timestamp.tm_isdst = 0;
01669 packet->timestamp = malloc(sizeof(time_t));
01670 if ( !packet->timestamp )
01671 {
01672 retval = 0;
01673 break;
01674 }
01675 *packet->timestamp = (time_t)mktime(×tamp) - (time_t)timezone;
01676 }
01677
01678
01679 if ( regexec(&fapint_regex_nmea_specou, nmea_fields[7], matchcount, (regmatch_t*)&matches, 0) == 0 )
01680 {
01681 len = matches[1].rm_eo - matches[1].rm_so;
01682 tmp_str = malloc(len+1);
01683 if ( !tmp_str )
01684 {
01685 retval = 0;
01686 break;
01687 }
01688 memcpy(tmp_str, nmea_fields[7]+matches[1].rm_so, len);
01689 tmp_str[len] = 0;
01690
01691 packet->speed = malloc(sizeof(double));
01692 if ( !packet->speed )
01693 {
01694 retval = 0;
01695 break;
01696 }
01697 *packet->speed = atof(tmp_str) * KNOT_TO_KMH;
01698 free(tmp_str); tmp_str = NULL;
01699 }
01700
01701
01702 if ( regexec(&fapint_regex_nmea_specou, nmea_fields[8], matchcount, (regmatch_t*)&matches, 0) == 0 )
01703 {
01704 len = matches[1].rm_eo - matches[1].rm_so;
01705 tmp_str = malloc(len+1);
01706 if ( !tmp_str )
01707 {
01708 retval = 0;
01709 break;
01710 }
01711 memcpy(tmp_str, nmea_fields[8]+matches[1].rm_so, len);
01712 tmp_str[len] = 0;
01713
01714 packet->course = malloc(sizeof(unsigned int));
01715 if ( !packet->course )
01716 {
01717 retval = 0;
01718 break;
01719 }
01720 *packet->course = atof(tmp_str) + 0.5;
01721 free(tmp_str); tmp_str = NULL;
01722
01723
01724 if ( *packet->course == 0 )
01725 {
01726 *packet->course = 360;
01727 }
01728 else if ( *packet->course > 360 )
01729 {
01730 *packet->course = 0;
01731 }
01732 }
01733
01734
01735 if ( !fapint_get_nmea_latlon(packet, nmea_fields[3], nmea_fields[4]) )
01736 {
01737 retval = 0;
01738 break;
01739 }
01740 if ( !fapint_get_nmea_latlon(packet, nmea_fields[5], nmea_fields[6]) )
01741 {
01742 retval = 0;
01743 break;
01744 }
01745
01746
01747 break;
01748 }
01749 else if ( strcmp(nmea_fields[0], "GPGGA") == 0 )
01750 {
01751
01752 if ( nmea_field_count < 11 )
01753 {
01754 packet->error_code = malloc(sizeof(fap_error_code_t));
01755 if ( packet->error_code ) *packet->error_code = fapGPGGA_FEWFIELDS;
01756 retval = 0;
01757 break;
01758 }
01759
01760
01761 if ( regexec(&fapint_regex_nmea_fix, nmea_fields[6], matchcount, (regmatch_t*)&matches, 0) == 0 )
01762 {
01763 len = matches[1].rm_eo - matches[1].rm_so;
01764 tmp_str = malloc(len+1);
01765 if ( tmp_str )
01766 {
01767 retval = 0;
01768 break;
01769 }
01770 memcpy(tmp_str, nmea_fields[8]+matches[1].rm_so, len);
01771 tmp_str[len] = 0;
01772 if ( atoi(tmp_str) < 1 )
01773 {
01774 free(tmp_str);
01775 packet->error_code = malloc(sizeof(fap_error_code_t));
01776 if ( packet->error_code ) *packet->error_code = fapGPGGA_NOFIX;
01777 retval = 0;
01778 break;
01779 }
01780 free(tmp_str); tmp_str = NULL;
01781 }
01782 else
01783 {
01784 packet->error_code = malloc(sizeof(fap_error_code_t));
01785 if ( packet->error_code ) *packet->error_code = fapGPGGA_NOFIX;
01786 retval = 0;
01787 break;
01788 }
01789
01790
01791
01792
01793 if ( strlen(nmea_fields[1]) < 6 )
01794 {
01795 packet->error_code = malloc(sizeof(fap_error_code_t));
01796 if ( packet->error_code ) *packet->error_code = fapTIMESTAMP_INV_GPGGA;
01797 retval = 0;
01798 break;
01799 }
01800 tmp_str = malloc(8);
01801 if ( !tmp_str )
01802 {
01803 retval = 0;
01804 break;
01805 }
01806 memcpy(tmp_str, nmea_fields[1], 6);
01807 tmp_str[6] = 'h';
01808 tmp_str[7] = 0;
01809 packet->timestamp = malloc(sizeof(time_t));
01810 if ( !packet->timestamp )
01811 {
01812 retval = 0;
01813 break;
01814 }
01815 *packet->timestamp = fapint_parse_timestamp(tmp_str);
01816 free(tmp_str); tmp_str = NULL;
01817 if ( *packet->timestamp == 0 )
01818 {
01819 packet->error_code = malloc(sizeof(fap_error_code_t));
01820 if ( packet->error_code ) *packet->error_code = fapTIMESTAMP_INV_GPGGA;
01821 retval = 0;
01822 break;
01823 }
01824
01825
01826 if ( !fapint_get_nmea_latlon(packet, nmea_fields[2], nmea_fields[3]) )
01827 {
01828 retval = 0;
01829 break;
01830 }
01831 if ( !fapint_get_nmea_latlon(packet, nmea_fields[4], nmea_fields[5]) )
01832 {
01833 retval = 0;
01834 break;
01835 }
01836
01837
01838 if ( strcmp(nmea_fields[0], "M") == 0 &&
01839 regexec(&fapint_regex_nmea_altitude, nmea_fields[9], matchcount, (regmatch_t*)&matches, 0) == 0 )
01840 {
01841 len = matches[1].rm_eo - matches[1].rm_so;
01842 tmp_str = malloc(len+1);
01843 if ( !tmp_str )
01844 {
01845 retval = 0;
01846 break;
01847 }
01848 memcpy(tmp_str, nmea_fields[8]+matches[1].rm_so, len);
01849 tmp_str[len] = 0;
01850 packet->altitude = malloc(sizeof(double));
01851 if ( !packet->altitude )
01852 {
01853 retval = 0;
01854 break;
01855 }
01856 *packet->altitude = atoi(tmp_str);
01857 free(tmp_str); tmp_str = NULL;
01858 }
01859
01860
01861 break;
01862 }
01863 else if ( strcmp(nmea_fields[0], "GPGLL") == 0 )
01864 {
01865
01866 if ( nmea_field_count < 5 )
01867 {
01868 packet->error_code = malloc(sizeof(fap_error_code_t));
01869 if ( packet->error_code ) *packet->error_code = fapGPGLL_FEWFIELDS;
01870 retval = 0;
01871 break;
01872 }
01873
01874
01875 if ( !fapint_get_nmea_latlon(packet, nmea_fields[1], nmea_fields[2]) )
01876 {
01877 retval = 0;
01878 break;
01879 }
01880 if ( !fapint_get_nmea_latlon(packet, nmea_fields[3], nmea_fields[4]) )
01881 {
01882 retval = 0;
01883 break;
01884 }
01885
01886
01887
01888
01889 if ( nmea_field_count >= 6 && strlen(nmea_fields[5]) >= 6 )
01890 {
01891 tmp_str = malloc(8);
01892 if ( !tmp_str )
01893 {
01894 retval = 0;
01895 break;
01896 }
01897 memcpy(tmp_str, nmea_fields[5], 6);
01898 tmp_str[6] = 'h';
01899 tmp_str[7] = 0;
01900 packet->timestamp = malloc(sizeof(time_t));
01901 if ( !packet->timestamp )
01902 {
01903 retval = 0;
01904 break;
01905 }
01906 *packet->timestamp = fapint_parse_timestamp(tmp_str);
01907 free(tmp_str); tmp_str = NULL;
01908 if ( *packet->timestamp == 0 )
01909 {
01910 packet->error_code = malloc(sizeof(fap_error_code_t));
01911 if ( packet->error_code ) *packet->error_code = fapTIMESTAMP_INV_GPGLL;
01912 retval = 0;
01913 break;
01914 }
01915 }
01916
01917
01918 if ( nmea_field_count >= 7 )
01919 {
01920 if ( strcmp(nmea_fields[0], "GPGLL") == 0 )
01921 {
01922 packet->error_code = malloc(sizeof(fap_error_code_t));
01923 if ( packet->error_code ) *packet->error_code = fapGPGLL_NOFIX;
01924 retval = 0;
01925 break;
01926 }
01927 }
01928
01929
01930 break;
01931 }
01932 else
01933 {
01934 packet->error_code = malloc(sizeof(fap_error_code_t));
01935 if ( packet->error_code ) *packet->error_code = fapNMEA_UNSUPP;
01936 retval = 0;
01937 }
01938 break;
01939 }
01940
01941
01942 for ( i = 0; i < nmea_field_count; ++i )
01943 {
01944 free(nmea_fields[i]);
01945 }
01946 if ( tmp_str ) free(tmp_str);
01947 if ( nmea_fields ) free(nmea_fields);
01948 free(rest);
01949 return retval;
01950 }
01951
01952
01953
01954 int fapint_parse_object(fap_packet_t* packet, char const* input, unsigned int const input_len)
01955 {
01956 int i;
01957
01958
01959 if ( strlen(input) < 31 )
01960 {
01961 packet->error_code = malloc(sizeof(fap_error_code_t));
01962 if ( packet->error_code ) *packet->error_code = fapOBJ_SHORT;
01963 return 0;
01964 }
01965
01966
01967 for ( i = 1; i < 10; ++i )
01968 {
01969 if ( input[i] < 0x20 || input[i] > 0x7e )
01970 {
01971 packet->error_code = malloc(sizeof(fap_error_code_t));
01972 if ( packet->error_code ) *packet->error_code = fapOBJ_INV;
01973 return 0;
01974 }
01975 }
01976 packet->object_or_item_name = malloc(10);
01977 if ( !packet->object_or_item_name ) return 0;
01978 memcpy(packet->object_or_item_name, input+1, 9);
01979 packet->object_or_item_name[9] = 0;
01980
01981
01982 if ( input[i] == '*' )
01983 {
01984 packet->alive = malloc(sizeof(int));
01985 if ( !packet->alive ) return 0;
01986 *packet->alive = 1;
01987 }
01988 else if ( input[i] == '_' )
01989 {
01990 packet->alive = malloc(sizeof(int));
01991 if ( !packet->alive ) return 0;
01992 *packet->alive = 0;
01993 }
01994 else
01995 {
01996 packet->error_code = malloc(sizeof(fap_error_code_t));
01997 if ( packet->error_code ) *packet->error_code = fapOBJ_INV;
01998 return 0;
01999 }
02000
02001
02002 packet->timestamp = malloc(sizeof(time_t));
02003 if ( !packet->timestamp ) return 0;
02004 *packet->timestamp = fapint_parse_timestamp(input+11);
02005 if ( *packet->timestamp == 0)
02006 {
02007 packet->error_code = malloc(sizeof(fap_error_code_t));
02008 if ( packet->error_code ) *packet->error_code = fapTIMESTAMP_INV_OBJ;
02009 return 0;
02010 }
02011
02012
02013 i = 18;
02014 if ( input[i] == '/' || input[i] == '\\' ||
02015 (input[i] >= 'A' && input[i] <= 'Z') ||
02016 (input[i] >= 'a' && input[i] <= 'j')
02017 )
02018 {
02019
02020 if ( !fapint_parse_compressed(packet, input+i) )
02021 {
02022 return 0;
02023 }
02024 i += 13;
02025 }
02026 else if ( isdigit(input[i]) )
02027 {
02028
02029 if ( !fapint_parse_normal(packet, input+i) )
02030 {
02031 return 0;
02032 }
02033 i += 19;
02034 }
02035 else
02036 {
02037 packet->error_code = malloc(sizeof(fap_error_code_t));
02038 if ( packet->error_code ) *packet->error_code = fapOBJ_DEC_ERR;
02039 return 0;
02040 }
02041
02042
02043 if ( packet->symbol_code != '_' )
02044 {
02045 fapint_parse_comment(packet, (char*)input+i, input_len-i);
02046 }
02047 else
02048 {
02049 fapint_parse_wx(packet, (char*)input+i, input_len-i);
02050 }
02051
02052 return 1;
02053 }
02054
02055
02056 int fapint_parse_item(fap_packet_t* packet, char const* input, unsigned int const input_len)
02057 {
02058 int len, i;
02059
02060
02061 if ( input_len < 18 )
02062 {
02063 packet->error_code = malloc(sizeof(fap_error_code_t));
02064 if ( packet->error_code ) *packet->error_code = fapITEM_SHORT;
02065 return 0;
02066 }
02067
02068
02069 if ( input[0] != ')' )
02070 {
02071 packet->error_code = malloc(sizeof(fap_error_code_t));
02072 if ( packet->error_code ) *packet->error_code = fapITEM_INV;
02073 return 0;
02074 }
02075 len = 0;
02076 for ( i = 1; i <= 9; ++i )
02077 {
02078 if ( input[i] == 0x20 ||
02079 (input[i] >= 0x22 && input[i] <= 0x5e) ||
02080 (input[i] >= 0x60 && input[i] <= 0x7e) )
02081 {
02082 len = i;
02083 }
02084 else
02085 {
02086 break;
02087 }
02088 }
02089 if ( input[i] == '!' )
02090 {
02091 packet->alive = malloc(sizeof(int));
02092 if ( !packet->alive ) return 0;
02093 *packet->alive = 1;
02094 }
02095 else if ( input[i] == '_' )
02096 {
02097 packet->alive = malloc(sizeof(int));
02098 if ( !packet->alive ) return 0;
02099 *packet->alive = 0;
02100 }
02101 else
02102 {
02103 packet->error_code = malloc(sizeof(fap_error_code_t));
02104 if ( packet->error_code ) *packet->error_code = fapITEM_INV;
02105 return 0;
02106 }
02107
02108
02109 packet->object_or_item_name = malloc(len+1);
02110 if ( !packet->object_or_item_name ) return 0;
02111 memcpy(packet->object_or_item_name, input+1, len);
02112 packet->object_or_item_name[len] = 0;
02113
02114
02115 i = len + 2;
02116 if ( input[i] == '/' || input[i] == '\\' ||
02117 (input[i] >= 'A' && input[i] <= 'Z') ||
02118 (input[i] >= 'a' && input[i] <= 'j')
02119 )
02120 {
02121
02122 if ( !fapint_parse_compressed(packet, input+i) )
02123 {
02124 return 0;
02125 }
02126 i += 13;
02127 }
02128 else if ( isdigit(input[i]) )
02129 {
02130
02131 if ( !fapint_parse_normal(packet, input+i) )
02132 {
02133 return 0;
02134 }
02135 i += 19;
02136 }
02137 else
02138 {
02139 packet->error_code = malloc(sizeof(fap_error_code_t));
02140 if ( packet->error_code ) *packet->error_code = fapITEM_DEC_ERR;
02141 return 0;
02142 }
02143
02144
02145 if ( packet->symbol_code != '_' )
02146 {
02147 fapint_parse_comment(packet, (char*)input+i, input_len-i);
02148 }
02149
02150 return 1;
02151 }
02152
02153
02154 int fapint_parse_message(fap_packet_t* packet, char const* input, unsigned int const input_len)
02155 {
02156 int i, len;
02157 char* tmp;
02158 short skipping_spaces = 1;
02159
02160 unsigned int const matchcount = 3;
02161 regmatch_t matches[matchcount];
02162
02163
02164
02165 if ( input_len < 12 )
02166 {
02167 packet->error_code = malloc(sizeof(fap_error_code_t));
02168 if ( packet->error_code ) *packet->error_code = fapMSG_INV;
02169 return 0;
02170 }
02171
02172
02173 if ( regexec(&fapint_regex_mes_dst, input, matchcount, (regmatch_t*)&matches, 0) == 0 )
02174 {
02175
02176 len = matches[1].rm_eo - matches[1].rm_so;
02177 for ( i = matches[1].rm_eo-1; i > 0; --i )
02178 {
02179 if ( input[i] == ' ' )
02180 {
02181 --len;
02182 }
02183 else
02184 {
02185 break;
02186 }
02187 }
02188
02189
02190 packet->destination = malloc(len+1);
02191 if ( !packet->destination ) return 0;
02192 memcpy(packet->destination, input+matches[1].rm_so, len);
02193 packet->destination[len] = 0;
02194 }
02195 else
02196 {
02197 packet->error_code = malloc(sizeof(fap_error_code_t));
02198 if ( packet->error_code ) *packet->error_code = fapMSG_INV;
02199 return 0;
02200 }
02201
02202
02203 len = 0;
02204 for ( i = 11; i < input_len; ++i )
02205 {
02206 if ( (input[i] >= 0x20 && input[i] <= 0x7e) || ((unsigned char)input[i] >= 0x80 && (unsigned char)input[i] <= 0xfe) )
02207 {
02208 len = i - 10;
02209 }
02210 else
02211 {
02212 break;
02213 }
02214 }
02215 if ( len == 0 )
02216 {
02217 packet->error_code = malloc(sizeof(fap_error_code_t));
02218 if ( packet->error_code ) *packet->error_code = fapMSG_INV;
02219 return 0;
02220 }
02221
02222
02223 packet->message = malloc(len+1);
02224 if ( !packet->message ) return 0;
02225 memcpy(packet->message, input+11, len);
02226 packet->message[len] = 0;
02227
02228
02229 if ( regexec(&fapint_regex_mes_ack, packet->message, matchcount, (regmatch_t*)&matches, 0) == 0 )
02230 {
02231 len = matches[1].rm_eo - matches[1].rm_so;
02232 packet->message_ack = malloc(len+1);
02233 if ( !packet->message_ack ) return 0;
02234 memcpy(packet->message_ack, packet->message+matches[1].rm_so, len);
02235 packet->message_ack[len] = 0;
02236 }
02237
02238
02239 if ( regexec(&fapint_regex_mes_nack, packet->message, matchcount, (regmatch_t*)&matches, 0) == 0 )
02240 {
02241 len = matches[1].rm_eo - matches[1].rm_so;
02242 packet->message_nack = malloc(len+1);
02243 if ( !packet->message_nack ) return 0;
02244 memcpy(packet->message_nack, packet->message+matches[1].rm_so, len);
02245 packet->message_nack[len] = 0;
02246 }
02247
02248
02249 len = 0;
02250 for ( i = strlen(packet->message)-1; i >= 0 ; i-- )
02251 {
02252 if ( skipping_spaces && !isspace(packet->message[i]) )
02253 {
02254
02255 skipping_spaces = 0;
02256 }
02257 else if ( skipping_spaces )
02258 {
02259 continue;
02260 }
02261
02262
02263 if ( !(isalnum(packet->message[i]) || packet->message[i] == '{') )
02264 {
02265 break;
02266 }
02267
02268
02269 len++;
02270 if ( len > 6 )
02271 {
02272 break;
02273 }
02274
02275
02276 if ( packet->message[i] == '{' )
02277 {
02278
02279 tmp = packet->message;
02280 packet->message = malloc(i+1);
02281 if ( !packet->message )
02282 {
02283 free(tmp);
02284 return 0;
02285 }
02286 memcpy(packet->message, tmp, i);
02287 packet->message[i] = 0;
02288
02289
02290 packet->message_id = malloc(len+1);
02291 if ( !packet->message_id )
02292 {
02293 free(tmp);
02294 return 0;
02295 }
02296 memcpy(packet->message_id, tmp+i+1, len);
02297 packet->message_id[len] = 0;
02298
02299
02300 free(tmp);
02301
02302 break;
02303 }
02304 }
02305
02306
02307 if ( strcmp(packet->src_callsign, packet->destination) == 0 &&
02308 ( strstr(packet->message, "BITS.") != NULL ||
02309 strstr(packet->message, "PARM.") != NULL ||
02310 strstr(packet->message, "UNIT.") != NULL ||
02311 strstr(packet->message, "EQNS.") != NULL
02312 )
02313 )
02314 {
02315 if ( packet->type == NULL )
02316 {
02317 packet->type = malloc(sizeof(fap_packet_type_t));
02318 if ( !packet->type ) return 0;
02319 }
02320 *packet->type = fapTELEMETRY_MESSAGE;
02321 }
02322
02323 return 1;
02324 }
02325
02326 int fapint_parse_capabilities(fap_packet_t* packet, char const* input, unsigned int const input_len)
02327 {
02328 fapint_llist_item_t* caps = NULL;
02329 int cap_count = 0;
02330 fapint_llist_item_t* current_elem = NULL;
02331
02332 char* tmp_str, *sepa;
02333 int cap_len, cap_startpos, i, retval = 1;
02334 unsigned int foo, saved, sepa_pos;
02335
02336
02337 cap_startpos = 0;
02338 for ( i = 0; i < input_len; ++i )
02339 {
02340 tmp_str = NULL;
02341
02342
02343 if ( input[i] == ',' )
02344 {
02345
02346 cap_len = i - cap_startpos;
02347 tmp_str = malloc(cap_len+1);
02348 if ( !tmp_str )
02349 {
02350 retval = 0;
02351 break;
02352 }
02353 memcpy(tmp_str, input+cap_startpos, cap_len);
02354 tmp_str[cap_len] = 0;
02355
02356
02357 cap_startpos = i + 1;
02358 }
02359 else if ( i+1 == input_len )
02360 {
02361
02362 cap_len = i+1 - cap_startpos;
02363 tmp_str = malloc(cap_len+1);
02364 if ( !tmp_str )
02365 {
02366 retval = 0;
02367 break;
02368 }
02369 memcpy(tmp_str, input+cap_startpos, cap_len);
02370 tmp_str[cap_len] = 0;
02371 }
02372
02373
02374 if ( tmp_str )
02375 {
02376
02377 if ( caps == NULL )
02378 {
02379 caps = malloc(sizeof(fapint_llist_item_t));
02380 if ( !caps )
02381 {
02382 retval = 0;
02383 break;
02384 }
02385 current_elem = caps;
02386 }
02387 else
02388 {
02389 current_elem->next = malloc(sizeof(fapint_llist_item_t));
02390 if ( !current_elem->next )
02391 {
02392 retval = 0;
02393 break;
02394 }
02395 current_elem = current_elem->next;
02396 }
02397 current_elem->next = NULL;
02398 current_elem->text = tmp_str;
02399
02400 ++cap_count;
02401 }
02402 }
02403 if ( !retval )
02404 {
02405 fapint_clear_llist(caps);
02406 return 0;
02407 }
02408
02409
02410 if ( cap_count == 0 )
02411 {
02412 return 0;
02413 }
02414
02415
02416 packet->capabilities = calloc(cap_count*2, sizeof(char*));
02417 if ( !packet->capabilities )
02418 {
02419 fapint_clear_llist(caps);
02420 return 0;
02421 }
02422 for ( i = 0; i < cap_count; ++i ) packet->capabilities[i] = NULL;
02423 packet->capabilities_len = cap_count;
02424 i = 0;
02425 current_elem = caps;
02426 while ( current_elem != NULL )
02427 {
02428 saved = 0;
02429
02430 if ( (sepa = strchr(current_elem->text, '=')) != NULL )
02431 {
02432 sepa_pos = sepa - current_elem->text - 1;
02433
02434 if ( sepa_pos < input_len )
02435 {
02436 packet->capabilities[i] = fapint_remove_part(current_elem->text, strlen(current_elem->text), sepa_pos, strlen(current_elem->text), &foo);
02437 packet->capabilities[i+1] = fapint_remove_part(current_elem->text, strlen(current_elem->text), 0, sepa_pos+2, &foo);
02438 saved = 1;
02439 }
02440 }
02441
02442
02443 if ( !saved )
02444 {
02445 packet->capabilities[i] = malloc(strlen(current_elem->text)+1);
02446 if ( !packet->capabilities[i] )
02447 {
02448 retval = 0;
02449 break;
02450 }
02451 strcpy(packet->capabilities[i], current_elem->text);
02452 packet->capabilities[i+1] = NULL;
02453 }
02454
02455
02456 current_elem = current_elem->next;
02457 i += 2;
02458 }
02459 fapint_clear_llist(caps);
02460
02461 return retval;
02462 }
02463
02464
02465
02466 int fapint_parse_status(fap_packet_t* packet, char const* input, unsigned int const input_len)
02467 {
02468 short has_timestamp = 0;
02469 int i;
02470
02471
02472 if ( input_len > 6 )
02473 {
02474 has_timestamp = 1;
02475 for ( i = 0; i < 6; ++i )
02476 {
02477 if ( !isdigit(input[i]) )
02478 {
02479 has_timestamp = 0;
02480 break;
02481 }
02482 }
02483 if ( input[6] != 'z' )
02484 {
02485 has_timestamp = 0;
02486 }
02487 }
02488
02489
02490 if ( has_timestamp )
02491 {
02492 packet->timestamp = malloc(sizeof(time_t));
02493 if ( !packet->timestamp ) return 0;
02494 *packet->timestamp = fapint_parse_timestamp(input);
02495 if ( *packet->timestamp == 0 )
02496 {
02497 packet->error_code = malloc(sizeof(fap_error_code_t));
02498 if ( packet->error_code ) *packet->error_code = fapTIMESTAMP_INV_STA;
02499 return 0;
02500 }
02501 packet->status = fapint_remove_part(input, input_len, 0, 7, &packet->status_len);
02502 }
02503 else
02504 {
02505 packet->status = malloc(input_len);
02506 if ( !packet->status ) return 0;
02507 memcpy(packet->status, input, input_len);
02508 packet->status_len = input_len;
02509 }
02510
02511 return 1;
02512 }
02513
02514
02515
02516 int fapint_parse_wx(fap_packet_t* packet, char const* input, unsigned int const input_len)
02517 {
02518 char wind_dir[4], wind_speed[4], *wind_gust = NULL, *temp = NULL;
02519 char buf_5b[6];
02520 int len, retval = 1;
02521 char* rest = NULL, *tmp_str;
02522 unsigned int rest_len, tmp_us;
02523
02524 unsigned int const matchcount = 5;
02525 regmatch_t matches[matchcount];
02526
02527
02528 if ( !packet || !input || !input_len )
02529 {
02530 return 0;
02531 }
02532
02533
02534 memset(wind_dir, 0, 4);
02535 memset(wind_speed, 0, 4);
02536
02537
02538 if ( regexec(&fapint_regex_wx1, input, matchcount, (regmatch_t*)&matches, 0) == 0 )
02539 {
02540 memcpy(wind_dir, input+matches[1].rm_so, 3);
02541 wind_dir[3] = 0;
02542
02543 memcpy(wind_speed, input+matches[2].rm_so, 3);
02544 wind_speed[3] = 0;
02545
02546 len = matches[3].rm_eo - matches[3].rm_so;
02547 wind_gust = malloc(len+1);
02548 if ( !wind_gust ) return 0;
02549 memcpy(wind_gust, input+matches[3].rm_so, len);
02550 wind_gust[len] = 0;
02551
02552 len = matches[4].rm_eo - matches[4].rm_so;
02553 temp = malloc(len+1);
02554 if ( !temp )
02555 {
02556 free(wind_gust);
02557 return 0;
02558 }
02559 memcpy(temp, input+matches[4].rm_so, len);
02560 temp[len] = 0;
02561
02562 rest = fapint_remove_part(input, input_len, 0, matches[4].rm_eo, &rest_len);
02563 }
02564 else if ( regexec(&fapint_regex_wx2, input, 5, matches, 0) == 0 )
02565 {
02566 memcpy(wind_dir, input+matches[1].rm_so, 3);
02567 wind_dir[3] = 0;
02568
02569 memcpy(wind_speed, input+matches[2].rm_so, 3);
02570 wind_speed[3] = 0;
02571
02572 len = matches[3].rm_eo - matches[3].rm_so;
02573 wind_gust = malloc(len+1);
02574 if ( !wind_gust ) return 0;
02575 memcpy(wind_gust, input+matches[3].rm_so, len);
02576 wind_gust[len] = 0;
02577
02578 len = matches[4].rm_eo - matches[4].rm_so;
02579 temp = malloc(len+1);
02580 if ( !temp )
02581 {
02582 free(wind_gust);
02583 return 0;
02584 }
02585 memcpy(temp, input+matches[4].rm_so, len);
02586 temp[len] = 0;
02587
02588 rest = fapint_remove_part(input, input_len, 0, matches[4].rm_eo, &rest_len);
02589 }
02590 else if ( regexec(&fapint_regex_wx3, input, 4, matches, 0) == 0 )
02591 {
02592 memcpy(wind_dir, input+matches[1].rm_so, 3);
02593 wind_dir[3] = 0;
02594
02595 memcpy(wind_speed, input+matches[2].rm_so, 3);
02596 wind_speed[3] = 0;
02597
02598 len = matches[3].rm_eo - matches[3].rm_so;
02599 wind_gust = malloc(len+1);
02600 if ( !wind_gust ) return 0;
02601 memcpy(wind_gust, input+matches[3].rm_so, len);
02602 wind_gust[len] = 0;
02603
02604 rest = fapint_remove_part(input, input_len, 0, matches[3].rm_eo, &rest_len);
02605 }
02606 else if ( regexec(&fapint_regex_wx4, input, 4, matches, 0) == 0 )
02607 {
02608 memcpy(wind_dir, input+matches[1].rm_so, 3);
02609 wind_dir[3] = 0;
02610
02611 memcpy(wind_speed, input+matches[2].rm_so, 3);
02612 wind_speed[3] = 0;
02613
02614 len = matches[3].rm_eo - matches[3].rm_so;
02615 wind_gust = malloc(len+1);
02616 if ( !wind_gust ) return 0;
02617 memcpy(wind_gust, input+matches[3].rm_so, len);
02618 wind_gust[len] = 0;
02619
02620 rest = fapint_remove_part(input, input_len, 0, matches[3].rm_eo, &rest_len);
02621 }
02622 else if ( regexec(&fapint_regex_wx5, input, 3, matches, 0) == 0 )
02623 {
02624 len = matches[1].rm_eo - matches[1].rm_so;
02625 wind_gust = malloc(len+1);
02626 if ( !wind_gust ) return 0;
02627 memcpy(wind_gust, input+matches[1].rm_so, len);
02628 wind_gust[len] = 0;
02629
02630 len = matches[2].rm_eo - matches[2].rm_so;
02631 temp = malloc(len+1);
02632 if ( !temp )
02633 {
02634 free(wind_gust);
02635 return 0;
02636 }
02637 memcpy(temp, input+matches[2].rm_so, len);
02638 temp[len] = 0;
02639
02640 rest = fapint_remove_part(input, input_len, 0, matches[2].rm_eo, &rest_len);
02641 }
02642 else
02643 {
02644 return 0;
02645 }
02646
02647 if ( temp == NULL && rest_len > 0 && regexec(&fapint_regex_wx5, rest, matchcount, (regmatch_t*)&matches, 0) == 0 )
02648 {
02649 len = matches[1].rm_eo - matches[1].rm_so;
02650 temp = malloc(len+1);
02651 if ( !temp )
02652 {
02653 if ( wind_gust ) free(wind_gust);
02654 free(rest);
02655 return 0;
02656 }
02657 memcpy(temp, rest+matches[1].rm_so, len);
02658 temp[len] = 0;
02659
02660 tmp_str = fapint_remove_part(rest, rest_len, matches[1].rm_so-1, matches[1].rm_eo, &tmp_us);
02661 free(rest);
02662 rest = tmp_str;
02663 rest_len = tmp_us;
02664 }
02665
02666
02667 packet->wx_report = malloc(sizeof(fap_wx_report_t));
02668 if ( !packet->wx_report )
02669 {
02670 if ( wind_gust ) free(wind_gust);
02671 if ( temp ) free(temp);
02672 if ( rest ) free(rest);
02673 return 0;
02674 }
02675 fapint_init_wx_report(packet->wx_report);
02676
02677
02678 do
02679 {
02680 if ( fapint_is_number(wind_gust) )
02681 {
02682 packet->wx_report->wind_gust = malloc(sizeof(double));
02683 if ( !packet->wx_report->wind_gust )
02684 {
02685 retval = 0;
02686 break;
02687 }
02688 *packet->wx_report->wind_gust = atof(wind_gust) * MPH_TO_MS;
02689 }
02690 if ( fapint_is_number(wind_dir) )
02691 {
02692 packet->wx_report->wind_dir = malloc(sizeof(int));
02693 if ( !packet->wx_report->wind_dir )
02694 {
02695 retval = 0;
02696 break;
02697 }
02698 *packet->wx_report->wind_dir = atoi(wind_dir);
02699 }
02700 if ( fapint_is_number(wind_speed) )
02701 {
02702 packet->wx_report->wind_speed = malloc(sizeof(double));
02703 if ( !packet->wx_report->wind_speed )
02704 {
02705 retval = 0;
02706 break;
02707 }
02708 *packet->wx_report->wind_speed = atof(wind_speed) * MPH_TO_MS;
02709 }
02710 if ( fapint_is_number(temp) )
02711 {
02712 packet->wx_report->temp = malloc(sizeof(double));
02713 if ( !packet->wx_report->temp )
02714 {
02715 retval = 0;
02716 break;
02717 }
02718 *packet->wx_report->temp = FAHRENHEIT_TO_CELCIUS(atof(temp));
02719 }
02720 } while ( 0 );
02721 if ( wind_gust )
02722 {
02723 free(wind_gust);
02724 wind_gust = NULL;
02725 }
02726 if ( temp )
02727 {
02728 free(temp);
02729 temp = NULL;
02730 }
02731 if ( !retval )
02732 {
02733 free(rest);
02734 return 0;
02735 }
02736
02737
02738 do
02739 {
02740 if ( rest_len > 0 && regexec(&fapint_regex_wx_r1, rest, matchcount, (regmatch_t*)&matches, 0) == 0 )
02741 {
02742 len = matches[1].rm_eo - matches[1].rm_so;
02743 memset(buf_5b, 0, 6);
02744 memcpy(buf_5b, rest+matches[1].rm_so, len);
02745 packet->wx_report->rain_1h = malloc(sizeof(double));
02746 if ( !packet->wx_report->rain_1h )
02747 {
02748 retval = 0;
02749 break;
02750 }
02751 *packet->wx_report->rain_1h = atof(buf_5b) * HINCH_TO_MM;
02752
02753 tmp_str = fapint_remove_part(rest, rest_len, matches[1].rm_so-1, matches[1].rm_eo, &tmp_us);
02754 free(rest);
02755 rest = tmp_str;
02756 rest_len = tmp_us;
02757 }
02758 if ( rest_len > 0 && regexec(&fapint_regex_wx_r24, rest, 2, matches, 0) == 0 )
02759 {
02760 len = matches[1].rm_eo - matches[1].rm_so;
02761 memset(buf_5b, 0, 4);
02762 memcpy(buf_5b, rest+matches[1].rm_so, len);
02763 packet->wx_report->rain_24h = malloc(sizeof(double));
02764 if ( !packet->wx_report->rain_24h )
02765 {
02766 retval = 0;
02767 break;
02768 }
02769 *packet->wx_report->rain_24h = atof(buf_5b) * HINCH_TO_MM;
02770
02771 tmp_str = fapint_remove_part(rest, rest_len, matches[1].rm_so-1, matches[1].rm_eo, &tmp_us);
02772 free(rest);
02773 rest = tmp_str;
02774 rest_len = tmp_us;
02775 }
02776 if ( rest_len > 0 && regexec(&fapint_regex_wx_rami, rest, 2, matches, 0) == 0 )
02777 {
02778 len = matches[1].rm_eo - matches[1].rm_so;
02779 memset(buf_5b, 0, 4);
02780 memcpy(buf_5b, rest+matches[1].rm_so, len);
02781 packet->wx_report->rain_midnight = malloc(sizeof(double));
02782 if ( !packet->wx_report->rain_midnight )
02783 {
02784 retval = 0;
02785 break;
02786 }
02787 *packet->wx_report->rain_midnight = atof(buf_5b) * HINCH_TO_MM;
02788
02789 tmp_str = fapint_remove_part(rest, rest_len, matches[1].rm_so-1, matches[1].rm_eo, &tmp_us);
02790 free(rest);
02791 rest = tmp_str;
02792 rest_len = tmp_us;
02793 }
02794 } while ( 0 );
02795 if ( !retval )
02796 {
02797 free(rest);
02798 return 0;
02799 }
02800
02801
02802 if ( rest_len > 0 && regexec(&fapint_regex_wx_humi, rest, 2, matches, 0) == 0 )
02803 {
02804 len = matches[1].rm_eo - matches[1].rm_so;
02805 memset(buf_5b, 0, 6);
02806 memcpy(buf_5b, rest+matches[1].rm_so, len);
02807 if ( (tmp_us = atoi(buf_5b)) <= 100 )
02808 {
02809 packet->wx_report->humidity = malloc(sizeof(unsigned int));
02810 if ( !packet->wx_report->humidity )
02811 {
02812 free(rest);
02813 return 0;
02814 }
02815 if ( tmp_us == 0 ) tmp_us = 100;
02816 *packet->wx_report->humidity = tmp_us;
02817 }
02818
02819 tmp_str = fapint_remove_part(rest, rest_len, matches[1].rm_so-1, matches[1].rm_eo, &tmp_us);
02820 free(rest);
02821 rest = tmp_str;
02822 rest_len = tmp_us;
02823 }
02824
02825
02826 if ( rest_len > 0 && regexec(&fapint_regex_wx_pres, rest, 2, matches, 0) == 0 )
02827 {
02828 len = matches[1].rm_eo - matches[1].rm_so;
02829 memset(buf_5b, 0, 6);
02830 memcpy(buf_5b, rest+matches[1].rm_so, len);
02831 packet->wx_report->pressure = malloc(sizeof(double));
02832 if ( !packet->wx_report->pressure )
02833 {
02834 free(rest);
02835 return 0;
02836 }
02837 *packet->wx_report->pressure = atoi(buf_5b)/10.0;
02838
02839 tmp_str = fapint_remove_part(rest, rest_len, matches[1].rm_so-1, matches[1].rm_eo, &tmp_us);
02840 free(rest);
02841 rest = tmp_str;
02842 rest_len = tmp_us;
02843 }
02844
02845
02846 if ( rest_len > 0 && regexec(&fapint_regex_wx_lumi, rest, 3, matches, 0) == 0 )
02847 {
02848 len = matches[2].rm_eo - matches[2].rm_so;
02849 memset(buf_5b, 0, 6);
02850 memcpy(buf_5b, rest+matches[2].rm_so, len);
02851 packet->wx_report->luminosity = malloc(sizeof(unsigned int));
02852 if ( !packet->wx_report->luminosity )
02853 {
02854 free(rest);
02855 return 0;
02856 }
02857 *packet->wx_report->luminosity = atoi(buf_5b);
02858 if ( input[matches[1].rm_so] == 'l' )
02859 {
02860 *packet->wx_report->luminosity += 1000;
02861 }
02862
02863 tmp_str = fapint_remove_part(rest, rest_len, matches[1].rm_so, matches[2].rm_eo, &tmp_us);
02864 free(rest);
02865 rest = tmp_str;
02866 rest_len = tmp_us;
02867 }
02868
02869
02870 if ( rest_len > 0 && regexec(&fapint_regex_wx_what, rest, 2, matches, 0) == 0 )
02871 {
02872 tmp_str = fapint_remove_part(rest, rest_len, matches[1].rm_so-1, matches[1].rm_eo, &tmp_us);
02873 free(rest);
02874 rest = tmp_str;
02875 rest_len = tmp_us;
02876 }
02877
02878
02879 if ( rest_len > 0 && regexec(&fapint_regex_wx_snow, rest, 2, matches, 0) == 0 )
02880 {
02881 len = matches[1].rm_eo - matches[1].rm_so;
02882 if ( len > 5 ) len = 5;
02883 memset(buf_5b, 0, 6);
02884 memcpy(buf_5b, rest+matches[1].rm_so, len);
02885 packet->wx_report->snow_24h = malloc(sizeof(double));
02886 if ( !packet->wx_report->snow_24h )
02887 {
02888 free(rest);
02889 return 0;
02890 }
02891 *packet->wx_report->snow_24h = atof(buf_5b) * HINCH_TO_MM;
02892
02893 tmp_str = fapint_remove_part(rest, rest_len, matches[1].rm_so-1, matches[1].rm_eo, &tmp_us);
02894 free(rest);
02895 rest = tmp_str;
02896 rest_len = tmp_us;
02897 }
02898
02899
02900 if ( rest_len > 0 && regexec(&fapint_regex_wx_rrc, rest, 2, matches, 0) == 0 )
02901 {
02902 tmp_str = fapint_remove_part(rest, rest_len, matches[1].rm_so-1, matches[1].rm_eo, &tmp_us);
02903 free(rest);
02904 rest = tmp_str;
02905 rest_len = tmp_us;
02906 }
02907
02908
02909 if ( rest_len > 0 && regexec(&fapint_regex_wx_any, rest, 2, matches, 0) == 0 )
02910 {
02911 tmp_str = fapint_remove_part(rest, rest_len, matches[1].rm_so, matches[1].rm_eo, &tmp_us);
02912 free(rest);
02913 rest = tmp_str;
02914 rest_len = tmp_us;
02915 }
02916
02917
02918
02919
02920 if ( rest_len > 0 && regexec(&fapint_regex_wx_soft, rest, 0, NULL, 0) == 0 )
02921 {
02922 packet->wx_report->soft = rest;
02923 }
02924
02925 else if ( rest_len > 0 && packet->comment == NULL )
02926 {
02927 packet->comment = rest;
02928 packet->comment_len = rest_len;
02929 }
02930 else
02931 {
02932 free(rest);
02933 }
02934
02935 return 1;
02936 }
02937
02938
02939
02940 int fapint_parse_telemetry(fap_packet_t* packet, char const* input)
02941 {
02942 unsigned int matchcount = 13;
02943 regmatch_t matches[matchcount];
02944
02945 char* tmp_str;
02946 int len1, len2;
02947
02948
02949 if ( !packet || !input )
02950 {
02951 return 0;
02952 }
02953
02954 if ( regexec(&fapint_regex_telemetry, input, matchcount, (regmatch_t*)&matches, 0) == 0 )
02955 {
02956
02957 packet->telemetry = malloc(sizeof(fap_telemetry_t));
02958 if ( !packet->telemetry ) return 0;
02959 fapint_init_telemetry_report(packet->telemetry);
02960
02961
02962 len1 = matches[1].rm_eo - matches[1].rm_so;
02963 tmp_str = malloc(len1+1);
02964 if ( !tmp_str ) return 0;
02965 memcpy(tmp_str, input+matches[1].rm_so, len1);
02966 tmp_str[len1] = 0;
02967 packet->telemetry->seq = atoi(tmp_str);
02968 free(tmp_str);
02969
02970
02971 len1 = matches[2].rm_eo - matches[2].rm_so;
02972 len2 = matches[3].rm_eo - matches[3].rm_so;
02973 tmp_str = malloc(len1+len2+1);
02974 if ( !tmp_str ) return 0;
02975 memcpy(tmp_str, input+matches[2].rm_so, len1);
02976 memcpy(tmp_str+len1, input+matches[3].rm_so, len2);
02977 tmp_str[len1+len2] = 0;
02978 packet->telemetry->val1 = atof(tmp_str);
02979 free(tmp_str);
02980
02981
02982 len1 = matches[4].rm_eo - matches[4].rm_so;
02983 len2 = matches[5].rm_eo - matches[5].rm_so;
02984 tmp_str = malloc(len1+len2+1);
02985 if ( !tmp_str ) return 0;
02986 memcpy(tmp_str, input+matches[4].rm_so, len1);
02987 memcpy(tmp_str+len1, input+matches[5].rm_so, len2);
02988 tmp_str[len1+len2] = 0;
02989 packet->telemetry->val2 = atof(tmp_str);
02990 free(tmp_str);
02991
02992
02993 len1 = matches[6].rm_eo - matches[6].rm_so;
02994 len2 = matches[7].rm_eo - matches[7].rm_so;
02995 tmp_str = malloc(len1+len2+1);
02996 if ( !tmp_str ) return 0;
02997 memcpy(tmp_str, input+matches[6].rm_so, len1);
02998 memcpy(tmp_str+len1, input+matches[7].rm_so, len2);
02999 tmp_str[len1+len2] = 0;
03000 packet->telemetry->val3 = atof(tmp_str);
03001 free(tmp_str);
03002
03003
03004 len1 = matches[8].rm_eo - matches[8].rm_so;
03005 len2 = matches[9].rm_eo - matches[9].rm_so;
03006 tmp_str = malloc(len1+len2+1);
03007 if ( !tmp_str ) return 0;
03008 memcpy(tmp_str, input+matches[8].rm_so, len1);
03009 memcpy(tmp_str+len1, input+matches[9].rm_so, len2);
03010 tmp_str[len1+len2] = 0;
03011 packet->telemetry->val4 = atof(tmp_str);
03012 free(tmp_str);
03013
03014
03015 len1 = matches[10].rm_eo - matches[10].rm_so;
03016 len2 = matches[11].rm_eo - matches[11].rm_so;
03017 tmp_str = malloc(len1+len2+1);
03018 if ( !tmp_str ) return 0;
03019 memcpy(tmp_str, input+matches[10].rm_so, len1);
03020 memcpy(tmp_str+len1, input+matches[11].rm_so, len2);
03021 tmp_str[len1+len2] = 0;
03022 packet->telemetry->val5 = atof(tmp_str);
03023 free(tmp_str);
03024
03025
03026 len1 = matches[12].rm_eo - matches[12].rm_so;
03027 memcpy(packet->telemetry->bits, input+matches[12].rm_so, len1);
03028 }
03029 else
03030 {
03031 packet->error_code = malloc(sizeof(fap_error_code_t));
03032 if ( packet->error_code ) *packet->error_code = fapTLM_INV;
03033 return 0;
03034 }
03035
03036 return 1;
03037 }
03038
03039
03040
03041 int fapint_parse_wx_peet_logging(fap_packet_t* packet, char const* input)
03042 {
03043 fapint_llist_item_t* parts, *current_elem;
03044 unsigned int part_count;
03045
03046 int i, retval = 1;
03047
03048 unsigned int matchcount = 2;
03049 regmatch_t matches[matchcount];
03050
03051
03052
03053 parts = NULL;
03054 current_elem = NULL;
03055 part_count = 0;
03056 i = 0;
03057 while ( regexec(&fapint_regex_peet_splitter, input+i, matchcount, matches, 0) == 0 )
03058 {
03059 if ( !parts )
03060 {
03061 parts = malloc(sizeof(fapint_llist_item_t));
03062 if ( !parts )
03063 {
03064 retval = 0;
03065 break;
03066 }
03067 current_elem = parts;
03068 }
03069 else
03070 {
03071 current_elem->next = malloc(sizeof(fapint_llist_item_t));
03072 if ( !current_elem->next )
03073 {
03074 retval = 0;
03075 break;
03076 }
03077 current_elem = current_elem->next;
03078 }
03079 current_elem->next = NULL;
03080 if ( input[i+matches[1].rm_so] != '-' )
03081 {
03082 current_elem->text = malloc(5);
03083 memcpy(current_elem->text, input+i+matches[1].rm_so, 4);
03084 current_elem->text[4] = 0;
03085 }
03086 else
03087 {
03088 current_elem->text = NULL;
03089 }
03090 part_count++;
03091
03092
03093 i += 4;
03094 if ( i >= strlen(input) ) break;
03095 }
03096 if ( !retval || !part_count )
03097 {
03098 fapint_clear_llist(parts);
03099 return 0;
03100 }
03101
03102
03103 packet->wx_report = malloc(sizeof(fap_wx_report_t));
03104 if ( !packet->wx_report )
03105 {
03106 fapint_clear_llist(parts);
03107 return 0;
03108 }
03109 fapint_init_wx_report(packet->wx_report);
03110
03111
03112 do
03113 {
03114 current_elem = parts;
03115
03116
03117 if ( current_elem->text )
03118 {
03119 packet->wx_report->wind_speed = malloc(sizeof(double));
03120 if ( !packet->wx_report->wind_speed )
03121 {
03122 retval = 0;
03123 break;
03124 }
03125 *packet->wx_report->wind_speed = strtol(current_elem->text, NULL, 16) * KMH_TO_MS / 10.0;
03126 }
03127 current_elem = current_elem->next;
03128
03129
03130 if ( current_elem )
03131 {
03132 if ( current_elem->text )
03133 {
03134 packet->wx_report->wind_dir = malloc(sizeof(unsigned int));
03135 if ( !packet->wx_report->wind_dir )
03136 {
03137 retval = 0;
03138 break;
03139 }
03140 *packet->wx_report->wind_dir = floor(strtol(current_elem->text, NULL, 16) * 1.41176 + 0.5);
03141 }
03142 current_elem = current_elem->next;
03143 }
03144 else
03145 {
03146 break;
03147 }
03148
03149
03150 if ( current_elem )
03151 {
03152 if ( current_elem->text )
03153 {
03154 packet->wx_report->temp = malloc(sizeof(double));
03155 if ( !packet->wx_report->temp )
03156 {
03157 retval = 0;
03158 break;
03159 }
03160 *packet->wx_report->temp = FAHRENHEIT_TO_CELCIUS(strtol(current_elem->text, NULL, 16)/10.0);
03161 }
03162 current_elem = current_elem->next;
03163 }
03164 else
03165 {
03166 break;
03167 }
03168
03169
03170 if ( current_elem )
03171 {
03172 if ( current_elem->text )
03173 {
03174 packet->wx_report->rain_midnight = malloc(sizeof(double));
03175 if ( !packet->wx_report->rain_midnight )
03176 {
03177 retval = 0;
03178 break;
03179 }
03180 *packet->wx_report->rain_midnight = strtol(current_elem->text, NULL, 16) * HINCH_TO_MM;
03181 }
03182 current_elem = current_elem->next;
03183 }
03184 else
03185 {
03186 break;
03187 }
03188
03189
03190 if ( current_elem )
03191 {
03192 if ( current_elem->text )
03193 {
03194 packet->wx_report->pressure = malloc(sizeof(double));
03195 if ( !packet->wx_report->pressure )
03196 {
03197 retval = 0;
03198 break;
03199 }
03200 *packet->wx_report->pressure = strtol(current_elem->text, NULL, 16) / 10.0;
03201 }
03202 current_elem = current_elem->next;
03203 }
03204 else
03205 {
03206 break;
03207 }
03208
03209
03210 if ( current_elem )
03211 {
03212 if ( current_elem->text )
03213 {
03214 packet->wx_report->temp_in = malloc(sizeof(double));
03215 if ( !packet->wx_report->temp_in )
03216 {
03217 retval = 0;
03218 break;
03219 }
03220 *packet->wx_report->temp_in = FAHRENHEIT_TO_CELCIUS(strtol(current_elem->text, NULL, 16)/10.0);
03221 }
03222 current_elem = current_elem->next;
03223 }
03224 else
03225 {
03226 break;
03227 }
03228
03229
03230 if ( current_elem )
03231 {
03232 if ( current_elem->text )
03233 {
03234 packet->wx_report->humidity = malloc(sizeof(unsigned int));
03235 if ( !packet->wx_report->humidity )
03236 {
03237 retval = 0;
03238 break;
03239 }
03240 *packet->wx_report->humidity = strtol(current_elem->text, NULL, 16)/10.0;
03241 }
03242 current_elem = current_elem->next;
03243 }
03244 else
03245 {
03246 break;
03247 }
03248
03249
03250 if ( current_elem )
03251 {
03252 if ( current_elem->text )
03253 {
03254 packet->wx_report->humidity_in = malloc(sizeof(unsigned int));
03255 if ( !packet->wx_report->humidity_in )
03256 {
03257 retval = 0;
03258 break;
03259 }
03260 *packet->wx_report->humidity_in = strtol(current_elem->text, NULL, 16)/10.0;
03261 }
03262 current_elem = current_elem->next;
03263 }
03264 else
03265 {
03266 break;
03267 }
03268
03269
03270 if ( current_elem )
03271 {
03272 current_elem = current_elem->next;
03273 }
03274 else
03275 {
03276 break;
03277 }
03278
03279
03280 if ( current_elem )
03281 {
03282 current_elem = current_elem->next;
03283 }
03284 else
03285 {
03286 break;
03287 }
03288
03289
03290 if ( current_elem )
03291 {
03292 if ( current_elem->text )
03293 {
03294 *packet->wx_report->rain_midnight = strtol(current_elem->text, NULL, 16) * HINCH_TO_MM;
03295 }
03296 current_elem = current_elem->next;
03297
03298
03299 if ( current_elem->text )
03300 {
03301 *packet->wx_report->wind_speed = strtol(current_elem->text, NULL, 16) * KMH_TO_MS / 10.0;
03302 }
03303 current_elem = current_elem->next;
03304 }
03305
03306 } while ( 0 );
03307 fapint_clear_llist(parts);
03308
03309 return retval;
03310 }
03311
03312
03313
03314 int fapint_parse_wx_peet_packet(fap_packet_t* packet, char const* input)
03315 {
03316 fapint_llist_item_t* parts, *current_elem;
03317 unsigned int part_count;
03318
03319 int i, retval = 1;
03320 int16_t temp;
03321
03322 unsigned int matchcount = 2;
03323 regmatch_t matches[matchcount];
03324
03325
03326
03327 parts = NULL;
03328 current_elem = NULL;
03329 part_count = 0;
03330 i = 0;
03331 while ( regexec(&fapint_regex_peet_splitter, input+i, matchcount, matches, 0) == 0 )
03332 {
03333 if ( !parts )
03334 {
03335 parts = malloc(sizeof(fapint_llist_item_t));
03336 if ( !parts ) return 0;
03337 current_elem = parts;
03338 }
03339 else
03340 {
03341 current_elem->next = malloc(sizeof(fapint_llist_item_t));
03342 if ( !current_elem->next )
03343 {
03344 retval = 0;
03345 break;
03346 }
03347 current_elem = current_elem->next;
03348 }
03349 current_elem->next = NULL;
03350 if ( input[i+matches[1].rm_so] != '-' )
03351 {
03352 current_elem->text = malloc(5);
03353 if ( !current_elem->text )
03354 {
03355 retval = 0;
03356 break;
03357 }
03358 memcpy(current_elem->text, input+i+matches[1].rm_so, 4);
03359 current_elem->text[4] = 0;
03360 }
03361 else
03362 {
03363 current_elem->text = NULL;
03364 }
03365 part_count++;
03366
03367
03368 i += 4;
03369 if ( i >= strlen(input) ) break;
03370 }
03371 if ( !retval || !part_count )
03372 {
03373 fapint_clear_llist(parts);
03374 return 0;
03375 }
03376
03377
03378 packet->wx_report = malloc(sizeof(fap_wx_report_t));
03379 if ( !packet->wx_report )
03380 {
03381 fapint_clear_llist(parts);
03382 return 0;
03383 }
03384 fapint_init_wx_report(packet->wx_report);
03385
03386
03387 do
03388 {
03389 current_elem = parts;
03390
03391
03392 if ( current_elem->text )
03393 {
03394 packet->wx_report->wind_gust = malloc(sizeof(double));
03395 if ( !packet->wx_report->wind_gust )
03396 {
03397 retval = 0;
03398 break;
03399 }
03400 *packet->wx_report->wind_gust = strtol(current_elem->text, NULL, 16) * KMH_TO_MS / 10.0;
03401 }
03402 current_elem = current_elem->next;
03403
03404
03405 if ( current_elem )
03406 {
03407 if ( current_elem->text )
03408 {
03409 packet->wx_report->wind_dir = malloc(sizeof(unsigned int));
03410 if ( !packet->wx_report->wind_dir )
03411 {
03412 retval = 0;
03413 break;
03414 }
03415 *packet->wx_report->wind_dir = floor(strtol(current_elem->text, NULL, 16) * 1.41176 + 0.5);
03416 }
03417 current_elem = current_elem->next;
03418 }
03419 else
03420 {
03421 break;
03422 }
03423
03424
03425 if ( current_elem )
03426 {
03427 if ( current_elem->text )
03428 {
03429 packet->wx_report->temp = malloc(sizeof(double));
03430 if ( !packet->wx_report->temp )
03431 {
03432 retval = 0;
03433 break;
03434 }
03435 temp = strtol(current_elem->text, NULL, 16);
03436 *packet->wx_report->temp = FAHRENHEIT_TO_CELCIUS(temp/10.0);
03437 }
03438 current_elem = current_elem->next;
03439 }
03440 else
03441 {
03442 break;
03443 }
03444
03445
03446 if ( current_elem )
03447 {
03448 if ( current_elem->text )
03449 {
03450 packet->wx_report->rain_midnight = malloc(sizeof(double));
03451 if ( !packet->wx_report->rain_midnight )
03452 {
03453 retval = 0;
03454 break;
03455 }
03456 *packet->wx_report->rain_midnight = strtol(current_elem->text, NULL, 16) * HINCH_TO_MM;
03457 }
03458 current_elem = current_elem->next;
03459 }
03460 else
03461 {
03462 break;
03463 }
03464
03465
03466 if ( current_elem )
03467 {
03468 if ( current_elem->text )
03469 {
03470 packet->wx_report->pressure = malloc(sizeof(double));
03471 if ( !packet->wx_report->pressure )
03472 {
03473 retval = 0;
03474 break;
03475 }
03476 *packet->wx_report->pressure = strtol(current_elem->text, NULL, 16) / 10.0;
03477 }
03478 current_elem = current_elem->next;
03479 }
03480 else
03481 {
03482 break;
03483 }
03484
03485
03486 if ( current_elem )
03487 {
03488 current_elem = current_elem->next;
03489 }
03490 else
03491 {
03492 break;
03493 }
03494
03495
03496 if ( current_elem )
03497 {
03498 current_elem = current_elem->next;
03499 }
03500 else
03501 {
03502 break;
03503 }
03504
03505
03506 if ( current_elem )
03507 {
03508 current_elem = current_elem->next;
03509 }
03510 else
03511 {
03512 break;
03513 }
03514
03515
03516 if ( current_elem )
03517 {
03518 if ( current_elem->text )
03519 {
03520 packet->wx_report->humidity = malloc(sizeof(unsigned int));
03521 if ( !packet->wx_report->humidity )
03522 {
03523 retval = 0;
03524 break;
03525 }
03526 *packet->wx_report->humidity = strtol(current_elem->text, NULL, 16)/10.0;
03527 }
03528 current_elem = current_elem->next;
03529 }
03530 else
03531 {
03532 break;
03533 }
03534
03535
03536 if ( current_elem )
03537 {
03538 current_elem = current_elem->next;
03539 }
03540 else
03541 {
03542 break;
03543 }
03544
03545
03546 if ( current_elem )
03547 {
03548 current_elem = current_elem->next;
03549 }
03550 else
03551 {
03552 break;
03553 }
03554
03555
03556 if ( current_elem )
03557 {
03558 if ( current_elem->text )
03559 {
03560 *packet->wx_report->rain_midnight = strtol(current_elem->text, NULL, 16) * HINCH_TO_MM;
03561 }
03562 current_elem = current_elem->next;
03563 }
03564 else
03565 {
03566 break;
03567 }
03568
03569
03570 if ( current_elem )
03571 {
03572 if ( current_elem->text )
03573 {
03574 packet->wx_report->wind_speed = malloc(sizeof(double));
03575 if ( !packet->wx_report->wind_speed )
03576 {
03577 retval = 0;
03578 break;
03579 }
03580 *packet->wx_report->wind_speed = strtol(current_elem->text, NULL, 16) * KMH_TO_MS / 10.0;
03581 }
03582 current_elem = current_elem->next;
03583 }
03584 else
03585 {
03586 break;
03587 }
03588
03589 break;
03590 } while ( 0 );
03591 fapint_clear_llist(parts);
03592
03593 return retval;
03594 }
03595
03596
03597
03598 int fapint_parse_dao(fap_packet_t* packet, char input[3])
03599 {
03600 double lon_off = 0.0, lat_off = 0.0;
03601
03602
03603 if ( 'A' <= input[0] && input[0] <= 'Z' && isdigit(input[1]) && isdigit(input[2]) )
03604 {
03605
03606 packet->dao_datum_byte = input[0];
03607 if ( packet->pos_resolution == NULL )
03608 {
03609 packet->pos_resolution = malloc(sizeof(double));
03610 if ( !packet->pos_resolution ) return 0;
03611 }
03612 *packet->pos_resolution = fapint_get_pos_resolution(3);
03613 lat_off = (input[1]-48.0) * 0.001 / 60.0;
03614 lon_off = (input[2]-48.0) * 0.001 / 60.0;
03615 }
03616 else if ( 'a' <= input[0] && input[0] <= 'z' &&
03617 0x21 <= input[1] && input[1] <= 0x7b &&
03618 0x21 <= input[2] && input[2] <= 0x7b )
03619 {
03620
03621 packet->dao_datum_byte = toupper(input[0]);
03622 if ( packet->pos_resolution == NULL )
03623 {
03624 packet->pos_resolution = malloc(sizeof(double));
03625 if ( !packet->pos_resolution ) return 0;
03626 }
03627 *packet->pos_resolution = fapint_get_pos_resolution(4);
03628
03629 lat_off = (input[1]-33.0)/91.0 * 0.01 / 60.0;
03630 lon_off = (input[2]-33.0)/91.0 * 0.01 / 60.0;
03631 }
03632 else if ( 0x21 <= input[0] && input[0] <= 0x7b &&
03633 input[1] == ' ' && input[2] == ' ' )
03634 {
03635
03636 if ( 'a' <= input[0] && input[0] <= 'z' )
03637 {
03638 packet->dao_datum_byte = toupper(input[0]);
03639 }
03640 else
03641 {
03642 packet->dao_datum_byte = input[0];
03643 }
03644 }
03645 else
03646 {
03647
03648 return 0;
03649 }
03650
03651
03652 if ( packet->latitude )
03653 {
03654 if ( *packet->latitude < 0 )
03655 {
03656 *packet->latitude -= lat_off;
03657 }
03658 else
03659 {
03660 *packet->latitude += lat_off;
03661 }
03662 }
03663 if ( packet->longitude )
03664 {
03665 if ( *packet->longitude < 0 )
03666 {
03667 *packet->longitude -= lon_off;
03668 }
03669 else
03670 {
03671 *packet->longitude += lon_off;
03672 }
03673 }
03674
03675 return 1;
03676 }
03677
03678
03679
03680 char* fapint_check_kiss_callsign(char* input)
03681 {
03682 unsigned int matchcount = 3;
03683 regmatch_t matches[matchcount];
03684
03685 int len;
03686 char* tmp_str;
03687
03688
03689 if ( !input ) return NULL;
03690
03691 if ( regexec(&fapint_regex_kiss_callsign, input, matchcount, (regmatch_t*)&matches, 0) == 0 )
03692 {
03693
03694 len = matches[2].rm_eo - matches[2].rm_so;
03695 if ( len > 0 )
03696 {
03697 tmp_str = malloc(len+1);
03698 if ( !tmp_str ) return NULL;
03699 memcpy(tmp_str, input+matches[2].rm_so, len);
03700 tmp_str[len] = 0;
03701 if ( atoi(tmp_str) < -15 )
03702 {
03703 free(tmp_str);
03704 return NULL;
03705 }
03706 free(tmp_str);
03707 }
03708
03709
03710 len += matches[1].rm_eo - matches[1].rm_so;
03711 tmp_str = malloc(len+1);
03712 if ( !tmp_str ) return NULL;
03713 memcpy(tmp_str, input+matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
03714 memcpy(tmp_str+matches[1].rm_eo, input+matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so);
03715 tmp_str[len] = 0;
03716
03717 return tmp_str;
03718 }
03719
03720 return NULL;
03721 }
03722
03723
03724
03725
03726
03727
03728
03729 fap_packet_t* fapint_create_packet()
03730 {
03731 fap_packet_t* result = malloc(sizeof(fap_packet_t));
03732 if ( !result ) return NULL;
03733
03734
03735 result->error_code = NULL;
03736 result->type = NULL;
03737
03738 result->orig_packet = NULL;
03739 result->orig_packet_len = 0;
03740
03741 result->header = NULL;
03742 result->body = NULL;
03743 result->body_len = 0;
03744 result->src_callsign = NULL;
03745 result->dst_callsign = NULL;
03746 result->path = NULL;
03747 result->path_len = 0;
03748
03749 result->latitude = NULL;
03750 result->longitude = NULL;
03751 result->format = NULL;
03752 result->pos_resolution = NULL;
03753 result->pos_ambiguity = NULL;
03754 result->dao_datum_byte = 0;
03755
03756 result->altitude = NULL;
03757 result->course = NULL;
03758 result->speed = NULL;
03759
03760 result->symbol_table = 0;
03761 result->symbol_code = 0;
03762
03763 result->messaging = NULL;
03764 result->destination = NULL;
03765 result->message = NULL;
03766 result->message_ack = NULL;
03767 result->message_nack = NULL;
03768 result->message_id = NULL;
03769 result->comment = NULL;
03770 result->comment_len = 0;
03771
03772 result->object_or_item_name = NULL;
03773 result->alive = NULL;
03774
03775 result->gps_fix_status = NULL;
03776 result->radio_range = NULL;
03777 result->phg = NULL;
03778 result->timestamp = NULL;
03779 result->nmea_checksum_ok = NULL;
03780
03781 result->wx_report = NULL;
03782 result->telemetry = NULL;
03783
03784 result->messagebits = NULL;
03785 result->status = NULL;
03786 result->status_len = 0;
03787 result->capabilities = NULL;
03788 result->capabilities_len = 0;
03789
03790
03791 return result;
03792 }