00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00025 #include "helpers2.h"
00026 #include "fap.h"
00027 #include "regs.h"
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <regex.h>
00036 #include <ctype.h>
00037 #include <math.h>
00038
00039
00040
00041 void fapint_clear_llist(fapint_llist_item_t* list)
00042 {
00043 fapint_llist_item_t* current_elem = list, *tmp_elem;
00044
00045 while ( current_elem != NULL )
00046 {
00047 if ( current_elem->text ) free(current_elem->text);
00048 tmp_elem = current_elem->next;
00049 free(current_elem);
00050 current_elem = tmp_elem;
00051 }
00052 }
00053
00054
00055
00056 double fapint_get_pos_resolution(int const minute_digit_count)
00057 {
00058 return KNOT_TO_KMH * 1000 * pow(10, -1*minute_digit_count);
00059 }
00060
00061
00062
00063 int fapint_parse_symbol_from_dst_callsign(fap_packet_t* packet)
00064 {
00065 int len;
00066 char leftover_str[3];
00067 char type;
00068
00069 char numberid_str[3];
00070 int numberid;
00071
00072 char dst_type[2];
00073 char overlay;
00074 char code[2];
00075 char tmp_2b[2];
00076
00077 unsigned int const matchcount = 3;
00078 regmatch_t matches[matchcount];
00079
00080
00081
00082 if ( !packet || !packet->dst_callsign )
00083 {
00084 return 0;
00085 }
00086
00087
00088 if ( regexec(&fapint_regex_nmea_dst, packet->dst_callsign, matchcount, (regmatch_t*)&matches, 0) == 0 )
00089 {
00090
00091 len = matches[2].rm_eo - matches[2].rm_so;
00092 memset(leftover_str, 0, 3);
00093 memcpy(leftover_str, packet->dst_callsign+matches[2].rm_so, len);
00094
00095 type = leftover_str[0];
00096
00097 if ( len == 3 )
00098 {
00099 if ( type == 'C' || type == 'E' )
00100 {
00101
00102 memset(numberid_str, 0, 3);
00103 numberid_str[0] = leftover_str[1];
00104 numberid_str[1] = leftover_str[2];
00105 numberid = atoi(numberid_str);
00106
00107
00108 if ( numberid > 0 && numberid < 95 )
00109 {
00110 packet->symbol_code = numberid + 32;
00111 if ( type == 'C' )
00112 {
00113 packet->symbol_table = '/';
00114 }
00115 else
00116 {
00117 packet->symbol_table = '\\';
00118 }
00119 return 1;
00120 }
00121 else
00122 {
00123
00124 return 0;
00125 }
00126 }
00127 else
00128 {
00129
00130 dst_type[0] = leftover_str[0];
00131 dst_type[1] = leftover_str[1];
00132 overlay = leftover_str[2];
00133 if ( (type == 'O' || type == 'A' || type == 'N' ||
00134 type == 'D' || type == 'S' || type == 'Q') &&
00135 isalnum(overlay) )
00136 {
00137 if ( fapint_symbol_from_dst_type(dst_type, code) )
00138 {
00139 packet->symbol_table = overlay;
00140 packet->symbol_code = code[1];
00141 return 1;
00142 }
00143 else
00144 {
00145
00146 return 0;
00147 }
00148 }
00149 else
00150 {
00151
00152 return 0;
00153 }
00154 }
00155 }
00156 else
00157 {
00158
00159 tmp_2b[0] = leftover_str[0];
00160 tmp_2b[1] = leftover_str[1];
00161 if ( fapint_symbol_from_dst_type(tmp_2b, code) )
00162 {
00163 packet->symbol_table = code[0];
00164 packet->symbol_code = code[1];
00165 return 1;
00166 }
00167 else
00168 {
00169
00170 return 0;
00171 }
00172 }
00173 }
00174 else
00175 {
00176 return 0;
00177 }
00178
00179
00180 return 0;
00181 }
00182
00183
00184
00185 int fapint_symbol_from_dst_type(char input[2], char* output)
00186 {
00187 switch ( input[0] )
00188 {
00189 case 'B':
00190 case 'O':
00191 if ( input[0] == 'B' )
00192 {
00193 output[0] = '/';
00194 }
00195 else
00196 {
00197 output[0] = '\\';
00198 }
00199 switch ( input[1] )
00200 {
00201 case 'B':
00202 output[1] = '!';
00203 return 1;
00204 case 'C':
00205 output[1] = '"';
00206 return 1;
00207 case 'D':
00208 output[1] = '#';
00209 return 1;
00210 case 'E':
00211 output[1] = '$';
00212 return 1;
00213 case 'F':
00214 output[1] = '%';
00215 return 1;
00216 case 'G':
00217 output[1] = '&';
00218 return 1;
00219 case 'H':
00220 output[1] = '\'';
00221 return 1;
00222 case 'I':
00223 output[1] = '(';
00224 return 1;
00225 case 'J':
00226 output[1] = ')';
00227 return 1;
00228 case 'K':
00229 output[1] = '*';
00230 return 1;
00231 case 'L':
00232 output[1] = '+';
00233 return 1;
00234 case 'M':
00235 output[1] = ',';
00236 return 1;
00237 case 'N':
00238 output[1] = '-';
00239 return 1;
00240 case 'O':
00241 output[1] = '.';
00242 return 1;
00243 case 'P':
00244 output[1] = '/';
00245 return 1;
00246 }
00247 return 0;
00248 case 'P':
00249 case 'A':
00250 if ( input[0] == 'P' )
00251 {
00252 output[0] = '/';
00253 }
00254 else
00255 {
00256 output[0] = '\\';
00257 }
00258 if ( isdigit(input[1]) || isupper(input[1]) )
00259 {
00260 output[1] = input[1];
00261 return 1;
00262 }
00263 return 0;
00264 case 'M':
00265 case 'N':
00266 if ( input[0] == 'M' )
00267 {
00268 output[0] = '/';
00269 }
00270 else
00271 {
00272 output[0] = '\\';
00273 }
00274 switch ( input[1] )
00275 {
00276 case 'R':
00277 output[1] = ':';
00278 return 1;
00279 case 'S':
00280 output[1] = ';';
00281 return 1;
00282 case 'T':
00283 output[1] = '<';
00284 return 1;
00285 case 'U':
00286 output[1] = '=';
00287 return 1;
00288 case 'V':
00289 output[1] = '>';
00290 return 1;
00291 case 'W':
00292 output[1] = '?';
00293 return 1;
00294 case 'X':
00295 output[1] = '@';
00296 return 1;
00297 }
00298 return 0;
00299 case 'H':
00300 case 'D':
00301 if ( input[0] == 'H' )
00302 {
00303 output[0] = '/';
00304 }
00305 else
00306 {
00307 output[0] = '\\';
00308 }
00309 switch ( input[1] )
00310 {
00311 case 'S':
00312 output[1] = '[';
00313 return 1;
00314 case 'T':
00315 output[1] = '\\';
00316 return 1;
00317 case 'U':
00318 output[1] = ']';
00319 return 1;
00320 case 'V':
00321 output[1] = '^';
00322 return 1;
00323 case 'W':
00324 output[1] = '_';
00325 return 1;
00326 case 'X':
00327 output[1] = '`';
00328 return 1;
00329 }
00330 return 0;
00331 case 'L':
00332 case 'S':
00333 if ( input[0] == 'L' )
00334 {
00335 output[0] = '/';
00336 }
00337 else
00338 {
00339 output[0] = '\\';
00340 }
00341 if ( isupper(input[1]) )
00342 {
00343 output[1] = tolower(input[1]);
00344 return 1;
00345 }
00346 return 0;
00347 case 'J':
00348 case 'Q':
00349 if ( input[0] == 'J' )
00350 {
00351 output[0] = '/';
00352 }
00353 else
00354 {
00355 output[0] = '\\';
00356 }
00357 switch ( input[1] )
00358 {
00359 case '1':
00360 output[1] = '{';
00361 return 1;
00362 case '2':
00363 output[1] = '|';
00364 return 1;
00365 case '3':
00366 output[1] = '}';
00367 return 1;
00368 case '4':
00369 output[1] = '~';
00370 return 1;
00371 }
00372 return 0;
00373 }
00374
00375 return 0;
00376 }
00377
00378
00379
00380 int fapint_is_number(char const* input)
00381 {
00382 int i;
00383
00384 if ( !input ) return 0;
00385
00386 for ( i = 0; i < strlen(input); ++i )
00387 {
00388 if ( !isdigit(input[i]) || ( i==0 && (input[i]=='-' || input[i]=='+') ) ) return 0;
00389 }
00390
00391 return 1;
00392 }
00393
00394
00395
00396 int fapint_check_date(unsigned int year, unsigned int month, unsigned int day)
00397 {
00398 return year < 10000 && month <= 12 && day <= 31;
00399 }
00400
00401
00402
00403 int fapint_get_nmea_latlon(fap_packet_t* packet, char* field1, char* field2)
00404 {
00405 double value;
00406 char direction;
00407
00408 char* tmp_str;
00409 unsigned int tmp_us;
00410 int len;
00411
00412 unsigned int matchcount = 4;
00413 regmatch_t matches[matchcount];
00414
00415
00416
00417 if ( !packet || !field1 || !field2 )
00418 {
00419 return 0;
00420 }
00421
00422
00423 if ( regexec(&fapint_regex_nmea_flag, field2, matchcount, (regmatch_t*)&matches, 0) == 0 )
00424 {
00425 direction = field2[matches[1].rm_so];
00426 }
00427 else
00428 {
00429 packet->error_code = malloc(sizeof(fap_error_code_t));
00430 if ( packet->error_code ) *packet->error_code = fapNMEA_INV_SIGN;
00431 return 0;
00432 }
00433
00434
00435
00436
00437 if ( regexec(&fapint_regex_nmea_coord, field1, matchcount, (regmatch_t*)&matches, 0) == 0 )
00438 {
00439 len = matches[1].rm_eo - matches[1].rm_so;
00440 tmp_str = malloc(len+1);
00441 if ( !tmp_str ) return 0;
00442 memcpy(tmp_str, field1+matches[1].rm_so, len);
00443 tmp_str[len] = 0;
00444 tmp_us = atoi(tmp_str);
00445 free(tmp_str);
00446
00447 len = matches[2].rm_eo - matches[2].rm_so;
00448 tmp_str = malloc(len+1);
00449 if ( !tmp_str ) return 0;
00450 memcpy(tmp_str, field1+matches[2].rm_so, len);
00451 tmp_str[len] = 0;
00452 value = atof(tmp_str);
00453 free(tmp_str);
00454
00455 len = matches[3].rm_eo - matches[3].rm_so;
00456
00457 value = tmp_us + value/60;
00458 if ( !packet->pos_resolution )
00459 {
00460 packet->pos_resolution = malloc(sizeof(double));
00461 if ( !packet->pos_resolution ) return 0;
00462 *packet->pos_resolution = fapint_get_pos_resolution(len);
00463 }
00464 }
00465 else
00466 {
00467 packet->error_code = malloc(sizeof(fap_error_code_t));
00468 if ( packet->error_code ) *packet->error_code = fapNMEA_INV_CVAL;
00469 return 0;
00470 }
00471
00472
00473 switch ( toupper(direction) )
00474 {
00475 case 'E':
00476 case 'W':
00477 if ( value > 179.999999 )
00478 {
00479 packet->error_code = malloc(sizeof(fap_error_code_t));
00480 if ( packet->error_code ) *packet->error_code = fapNMEA_LARGE_EW;
00481 return 0;
00482 }
00483 if ( toupper(direction) == 'W' )
00484 {
00485 value *= -1;
00486 }
00487 packet->longitude = malloc(sizeof(double));
00488 if ( !packet->longitude ) return 0;
00489 *packet->longitude = value;
00490 return 1;
00491 case 'N':
00492 case 'S':
00493 if ( value > 89.999999 )
00494 {
00495 packet->error_code = malloc(sizeof(fap_error_code_t));
00496 if ( packet->error_code ) *packet->error_code = fapNMEA_LARGE_NS;
00497 return 0;
00498 }
00499 if ( toupper(direction) == 'S' )
00500 {
00501 value *= -1;
00502 }
00503 packet->latitude = malloc(sizeof(double));
00504 if ( !packet->latitude ) return 0;
00505 *packet->latitude = value;
00506 return 1;
00507 }
00508
00509 return 0;
00510 }
00511
00512
00513
00514 void fapint_init_wx_report(fap_wx_report_t* wx_report)
00515 {
00516 wx_report->wind_gust = NULL;
00517 wx_report->wind_dir = NULL;
00518 wx_report->wind_speed = NULL;
00519 wx_report->temp = NULL;
00520 wx_report->temp_in = NULL;
00521 wx_report->rain_1h = NULL;
00522 wx_report->rain_24h = NULL;
00523 wx_report->rain_midnight = NULL;
00524 wx_report->humidity = NULL;
00525 wx_report->humidity_in = NULL;
00526 wx_report->pressure = NULL;
00527 wx_report->luminosity = NULL;
00528 wx_report->snow_24h = NULL;
00529 wx_report->soft = NULL;
00530 }