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