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