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