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