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