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