gpsutils.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  1. /* gpsutils.c -- code shared between low-level and high-level interfaces
  2. *
  3. * This file is Copyright 2010 by the GPSD project
  4. * SPDX-License-Identifier: BSD-2-clause
  5. */
  6. /* The strptime prototype is not provided unless explicitly requested.
  7. * We also need to set the value high enough to signal inclusion of
  8. * newer features (like clock_gettime). See the POSIX spec for more info:
  9. * http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_02_01_02 */
  10. #include "../include/gpsd_config.h" /* must be before all includes */
  11. #include <ctype.h>
  12. #include <errno.h>
  13. #include <math.h>
  14. #include <stdbool.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <sys/select.h> /* for to have a pselect(2) prototype a la POSIX */
  19. #include <sys/time.h> /* for to have a pselect(2) prototype a la SuS */
  20. #include <time.h>
  21. #include "../include/gps.h"
  22. #include "../include/libgps.h"
  23. #include "../include/os_compat.h"
  24. #include "../include/timespec.h"
  25. #ifdef USE_QT
  26. #include <QDateTime>
  27. #include <QStringList>
  28. #endif
  29. /*
  30. * Berkeley implementation of strtod(), inlined to avoid locale problems
  31. * with the decimal point and stripped down to an atof()-equivalent.
  32. */
  33. /* Takes a decimal ASCII floating-point number, optionally
  34. * preceded by white space. Must have form "SI.FE-X",
  35. * S may be ither of the signs may be "+", "-", or omitted.
  36. * I is the integer part of the mantissa,
  37. * F is the fractional part of the mantissa,
  38. * X is the exponent.
  39. * Either I or F may be omitted, or both.
  40. * The decimal point isn't necessary unless F is
  41. * present. The "E" may actually be an "e". E and X
  42. * may both be omitted (but not just one).
  43. *
  44. * returns NaN if:
  45. * *string is zero length,
  46. * the first non-white space is not negative sign ('-'), positive sign ('_')
  47. * or a digit
  48. */
  49. double safe_atof(const char *string)
  50. {
  51. static int maxExponent = 511; /* Largest possible base 10 exponent. Any
  52. * exponent larger than this will already
  53. * produce underflow or overflow, so there's
  54. * no need to worry about additional digits.
  55. */
  56. /* Table giving binary powers of 10. Entry is 10^2^i.
  57. * Used to convert decimal exponents into floating-point numbers. */
  58. static double powersOf10[] = {
  59. 10.,
  60. 100.,
  61. 1.0e4,
  62. 1.0e8,
  63. 1.0e16,
  64. 1.0e32,
  65. 1.0e64,
  66. 1.0e128,
  67. 1.0e256
  68. };
  69. bool sign = false, expSign = false;
  70. double fraction, dblExp, *d;
  71. const char *p;
  72. int c;
  73. int exp = 0; /* Exponent read from "EX" field. */
  74. int fracExp = 0; /* Exponent that derives from the fractional
  75. * part. Under normal circumstatnces, it is
  76. * the negative of the number of digits in F.
  77. * However, if I is very long, the last digits
  78. * of I get dropped (otherwise a long I with a
  79. * large negative exponent could cause an
  80. * unnecessary overflow on I alone). In this
  81. * case, fracExp is incremented one for each
  82. * dropped digit. */
  83. int mantSize; /* Number of digits in mantissa. */
  84. int decPt; /* Number of mantissa digits BEFORE decimal
  85. * point. */
  86. const char *pExp; /* Temporarily holds location of exponent
  87. * in string. */
  88. /*
  89. * Strip off leading blanks and check for a sign.
  90. */
  91. p = string;
  92. while (isspace((int)*p)) {
  93. p += 1;
  94. }
  95. if (isdigit((int)*p)) {
  96. // ignore
  97. } else if ('-' == *p) {
  98. sign = true;
  99. p += 1;
  100. } else if ('+' == *p) {
  101. p += 1;
  102. } else if ('.' == *p) {
  103. // ignore
  104. } else {
  105. return NAN;
  106. }
  107. /*
  108. * Count the number of digits in the mantissa (including the decimal
  109. * point), and also locate the decimal point.
  110. */
  111. decPt = -1;
  112. for (mantSize = 0; ; mantSize += 1) {
  113. c = *p;
  114. if (!isdigit((int)c)) {
  115. if ((c != '.') || (decPt >= 0)) {
  116. break;
  117. }
  118. decPt = mantSize;
  119. }
  120. p += 1;
  121. }
  122. /*
  123. * Now suck up the digits in the mantissa. Use two integers to
  124. * collect 9 digits each (this is faster than using floating-point).
  125. * If the mantissa has more than 18 digits, ignore the extras, since
  126. * they can't affect the value anyway.
  127. */
  128. pExp = p;
  129. p -= mantSize;
  130. if (decPt < 0) {
  131. decPt = mantSize;
  132. } else {
  133. mantSize -= 1; /* One of the digits was the point. */
  134. }
  135. if (mantSize > 18) {
  136. fracExp = decPt - 18;
  137. mantSize = 18;
  138. } else {
  139. fracExp = decPt - mantSize;
  140. }
  141. if (mantSize == 0) {
  142. fraction = 0.0;
  143. //p = string;
  144. goto done;
  145. } else {
  146. int frac1, frac2;
  147. frac1 = 0;
  148. for ( ; mantSize > 9; mantSize -= 1)
  149. {
  150. c = *p;
  151. p += 1;
  152. if (c == '.') {
  153. c = *p;
  154. p += 1;
  155. }
  156. frac1 = 10*frac1 + (c - '0');
  157. }
  158. frac2 = 0;
  159. for (; mantSize > 0; mantSize -= 1)
  160. {
  161. c = *p;
  162. p += 1;
  163. if (c == '.') {
  164. c = *p;
  165. p += 1;
  166. }
  167. frac2 = 10*frac2 + (c - '0');
  168. }
  169. fraction = (1.0e9 * frac1) + frac2;
  170. }
  171. /*
  172. * Skim off the exponent.
  173. */
  174. p = pExp;
  175. if ((*p == 'E') || (*p == 'e')) {
  176. p += 1;
  177. if (*p == '-') {
  178. expSign = true;
  179. p += 1;
  180. } else {
  181. if (*p == '+') {
  182. p += 1;
  183. }
  184. expSign = false;
  185. }
  186. while (isdigit((int) *p)) {
  187. exp = exp * 10 + (*p - '0');
  188. p += 1;
  189. }
  190. }
  191. if (expSign) {
  192. exp = fracExp - exp;
  193. } else {
  194. exp = fracExp + exp;
  195. }
  196. /*
  197. * Generate a floating-point number that represents the exponent.
  198. * Do this by processing the exponent one bit at a time to combine
  199. * many powers of 2 of 10. Then combine the exponent with the
  200. * fraction.
  201. */
  202. if (exp < 0) {
  203. expSign = true;
  204. exp = -exp;
  205. } else {
  206. expSign = false;
  207. }
  208. if (exp > maxExponent) {
  209. exp = maxExponent;
  210. errno = ERANGE;
  211. }
  212. dblExp = 1.0;
  213. for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
  214. if (exp & 01) {
  215. dblExp *= *d;
  216. }
  217. }
  218. if (expSign) {
  219. fraction /= dblExp;
  220. } else {
  221. fraction *= dblExp;
  222. }
  223. done:
  224. if (sign) {
  225. return -fraction;
  226. }
  227. return fraction;
  228. }
  229. #define MONTHSPERYEAR 12 /* months per calendar year */
  230. /* stuff a fix structure with recognizable out-of-band values */
  231. void gps_clear_fix(struct gps_fix_t *fixp)
  232. {
  233. memset(fixp, 0, sizeof(struct gps_fix_t));
  234. fixp->altitude = NAN; // DEPRECATED, undefined
  235. fixp->altHAE = NAN;
  236. fixp->altMSL = NAN;
  237. fixp->climb = NAN;
  238. fixp->depth = NAN;
  239. fixp->epc = NAN;
  240. fixp->epd = NAN;
  241. fixp->eph = NAN;
  242. fixp->eps = NAN;
  243. fixp->ept = NAN;
  244. fixp->epv = NAN;
  245. fixp->epx = NAN;
  246. fixp->epy = NAN;
  247. fixp->latitude = NAN;
  248. fixp->longitude = NAN;
  249. fixp->magnetic_track = NAN;
  250. fixp->magnetic_var = NAN;
  251. fixp->mode = MODE_NOT_SEEN;
  252. fixp->sep = NAN;
  253. fixp->speed = NAN;
  254. fixp->track = NAN;
  255. /* clear ECEF too */
  256. fixp->ecef.x = NAN;
  257. fixp->ecef.y = NAN;
  258. fixp->ecef.z = NAN;
  259. fixp->ecef.vx = NAN;
  260. fixp->ecef.vy = NAN;
  261. fixp->ecef.vz = NAN;
  262. fixp->ecef.pAcc = NAN;
  263. fixp->ecef.vAcc = NAN;
  264. fixp->NED.relPosN = NAN;
  265. fixp->NED.relPosE = NAN;
  266. fixp->NED.relPosD = NAN;
  267. fixp->NED.velN = NAN;
  268. fixp->NED.velE = NAN;
  269. fixp->NED.velD = NAN;
  270. fixp->geoid_sep = NAN;
  271. fixp->dgps_age = NAN;
  272. fixp->dgps_station = -1;
  273. fixp->wanglem = NAN;
  274. fixp->wangler = NAN;
  275. fixp->wanglet = NAN;
  276. fixp->wspeedr = NAN;
  277. fixp->wspeedt = NAN;
  278. }
  279. /* stuff an attitude structure with recognizable out-of-band values */
  280. void gps_clear_att(struct attitude_t *attp)
  281. {
  282. memset(attp, 0, sizeof(struct attitude_t));
  283. attp->pitch = NAN;
  284. attp->roll = NAN;
  285. attp->yaw = NAN;
  286. attp->dip = NAN;
  287. attp->mag_len = NAN;
  288. attp->mag_x = NAN;
  289. attp->mag_y = NAN;
  290. attp->mag_z = NAN;
  291. attp->acc_len = NAN;
  292. attp->acc_x = NAN;
  293. attp->acc_y = NAN;
  294. attp->acc_z = NAN;
  295. attp->gyro_x = NAN;
  296. attp->gyro_y = NAN;
  297. attp->temp = NAN;
  298. attp->depth = NAN;
  299. }
  300. void gps_clear_dop( struct dop_t *dop)
  301. {
  302. dop->xdop = dop->ydop = dop->vdop = dop->tdop = dop->hdop = dop->pdop =
  303. dop->gdop = NAN;
  304. }
  305. /* stuff a log structure with recognizable out-of-band values */
  306. void gps_clear_log(struct gps_log_t *logp)
  307. {
  308. memset(logp, 0, sizeof(struct gps_log_t));
  309. logp->lon = NAN;
  310. logp->lat = NAN;
  311. logp->altHAE = NAN;
  312. logp->altMSL = NAN;
  313. logp->gSpeed = NAN;
  314. logp->heading = NAN;
  315. logp->tAcc = NAN;
  316. logp->hAcc = NAN;
  317. logp->vAcc = NAN;
  318. logp->sAcc = NAN;
  319. logp->headAcc = NAN;
  320. logp->velN = NAN;
  321. logp->velE = NAN;
  322. logp->velD = NAN;
  323. logp->pDOP = NAN;
  324. logp->distance = NAN;
  325. logp->totalDistance = NAN;
  326. logp->distanceStd = NAN;
  327. logp->fixType = -1;
  328. }
  329. /* merge new data (from) into current fix (to)
  330. * Being careful not to lose information */
  331. void gps_merge_fix(struct gps_fix_t *to,
  332. gps_mask_t transfer,
  333. struct gps_fix_t *from)
  334. {
  335. if ((NULL == to) || (NULL == from))
  336. return;
  337. if ((transfer & TIME_SET) != 0)
  338. to->time = from->time;
  339. if ((transfer & LATLON_SET) != 0) {
  340. to->latitude = from->latitude;
  341. to->longitude = from->longitude;
  342. }
  343. if (0 != (transfer & MODE_SET)) {
  344. /* FIXME? Maybe only upgrade mode, not downgrade it */
  345. to->mode = from->mode;
  346. }
  347. /* Some messages only report mode, some mode and status, some only status.
  348. * Only upgrade status, not downgrade it */
  349. if (0 != (transfer & STATUS_SET)) {
  350. if (to->status < from->status) {
  351. to->status = from->status;
  352. }
  353. }
  354. if ((transfer & ALTITUDE_SET) != 0) {
  355. if (0 != isfinite(from->altHAE)) {
  356. to->altHAE = from->altHAE;
  357. }
  358. if (0 != isfinite(from->altMSL)) {
  359. to->altMSL = from->altMSL;
  360. }
  361. if (0 != isfinite(from->depth)) {
  362. to->depth = from->depth;
  363. }
  364. }
  365. if ((transfer & TRACK_SET) != 0)
  366. to->track = from->track;
  367. if ((transfer & MAGNETIC_TRACK_SET) != 0) {
  368. if (0 != isfinite(from->magnetic_track)) {
  369. to->magnetic_track = from->magnetic_track;
  370. }
  371. if (0 != isfinite(from->magnetic_var)) {
  372. to->magnetic_var = from->magnetic_var;
  373. }
  374. }
  375. if ((transfer & SPEED_SET) != 0)
  376. to->speed = from->speed;
  377. if ((transfer & CLIMB_SET) != 0)
  378. to->climb = from->climb;
  379. if ((transfer & TIMERR_SET) != 0)
  380. to->ept = from->ept;
  381. if (0 != isfinite(from->epx) &&
  382. 0 != isfinite(from->epy)) {
  383. to->epx = from->epx;
  384. to->epy = from->epy;
  385. }
  386. if (0 != isfinite(from->epd)) {
  387. to->epd = from->epd;
  388. }
  389. if (0 != isfinite(from->eph)) {
  390. to->eph = from->eph;
  391. }
  392. if (0 != isfinite(from->eps)) {
  393. to->eps = from->eps;
  394. }
  395. /* spherical error probability, not geoid separation */
  396. if (0 != isfinite(from->sep)) {
  397. to->sep = from->sep;
  398. }
  399. /* geoid separation, not spherical error probability */
  400. if (0 != isfinite(from->geoid_sep)) {
  401. to->geoid_sep = from->geoid_sep;
  402. }
  403. if (0 != isfinite(from->epv)) {
  404. to->epv = from->epv;
  405. }
  406. if ((transfer & SPEEDERR_SET) != 0)
  407. to->eps = from->eps;
  408. if ((transfer & ECEF_SET) != 0) {
  409. to->ecef.x = from->ecef.x;
  410. to->ecef.y = from->ecef.y;
  411. to->ecef.z = from->ecef.z;
  412. to->ecef.pAcc = from->ecef.pAcc;
  413. }
  414. if ((transfer & VECEF_SET) != 0) {
  415. to->ecef.vx = from->ecef.vx;
  416. to->ecef.vy = from->ecef.vy;
  417. to->ecef.vz = from->ecef.vz;
  418. to->ecef.vAcc = from->ecef.vAcc;
  419. }
  420. if (0 != (transfer & NED_SET)) {
  421. to->NED.relPosN = from->NED.relPosN;
  422. to->NED.relPosE = from->NED.relPosE;
  423. to->NED.relPosD = from->NED.relPosD;
  424. if ((0 != isfinite(from->NED.relPosH)) &&
  425. (0 != isfinite(from->NED.relPosL))) {
  426. to->NED.relPosH = from->NED.relPosH;
  427. to->NED.relPosL = from->NED.relPosL;
  428. }
  429. }
  430. if ((transfer & VNED_SET) != 0) {
  431. to->NED.velN = from->NED.velN;
  432. to->NED.velE = from->NED.velE;
  433. to->NED.velD = from->NED.velD;
  434. }
  435. if ('\0' != from->datum[0]) {
  436. strlcpy(to->datum, from->datum, sizeof(to->datum));
  437. }
  438. if (0 != isfinite(from->dgps_age) &&
  439. 0 <= from->dgps_station) {
  440. /* both, or neither */
  441. to->dgps_age = from->dgps_age;
  442. to->dgps_station = from->dgps_station;
  443. }
  444. // navdata stuff. just wind angle and angle for now
  445. if (0 != (transfer & NAVDATA_SET)) {
  446. if (0 != isfinite(from->wanglem)) {
  447. to->wanglem = from->wanglem;
  448. }
  449. if (0 != isfinite(from->wangler)) {
  450. to->wangler = from->wangler;
  451. }
  452. if (0 != isfinite(from->wanglet)) {
  453. to->wanglet = from->wanglet;
  454. }
  455. if (0 != isfinite(from->wspeedr)) {
  456. to->wspeedr = from->wspeedr;
  457. }
  458. if (0 != isfinite(from->wspeedt)) {
  459. to->wspeedt = from->wspeedt;
  460. }
  461. }
  462. }
  463. /* mkgmtime(tm)
  464. * convert struct tm, as UTC, to seconds since Unix epoch
  465. * This differs from mktime() from libc.
  466. * mktime() takes struct tm as localtime.
  467. *
  468. * The inverse of gmtime(time_t)
  469. */
  470. time_t mkgmtime(struct tm * t)
  471. {
  472. int year;
  473. time_t result;
  474. static const int cumdays[MONTHSPERYEAR] =
  475. { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
  476. year = 1900 + t->tm_year + t->tm_mon / MONTHSPERYEAR;
  477. result = (year - 1970) * 365 + cumdays[t->tm_mon % MONTHSPERYEAR];
  478. result += (year - 1968) / 4;
  479. result -= (year - 1900) / 100;
  480. result += (year - 1600) / 400;
  481. if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0) &&
  482. (t->tm_mon % MONTHSPERYEAR) < 2)
  483. result--;
  484. result += t->tm_mday - 1;
  485. result *= 24;
  486. result += t->tm_hour;
  487. result *= 60;
  488. result += t->tm_min;
  489. result *= 60;
  490. result += t->tm_sec;
  491. /* this is UTC, no DST
  492. * if (t->tm_isdst == 1)
  493. * result -= 3600;
  494. */
  495. return (result);
  496. }
  497. timespec_t iso8601_to_timespec(char *isotime)
  498. /* ISO8601 UTC to Unix timespec, no leapsecond correction. */
  499. {
  500. timespec_t ret;
  501. #ifndef __clang_analyzer__
  502. #ifndef USE_QT
  503. char *dp = NULL;
  504. double usec = 0;
  505. struct tm tm;
  506. memset(&tm,0,sizeof(tm));
  507. #ifdef HAVE_STRPTIME
  508. dp = strptime(isotime, "%Y-%m-%dT%H:%M:%S", &tm);
  509. #else
  510. /* Fallback for systems without strptime (i.e. Windows)
  511. * This is a simplistic conversion for iso8601 strings only,
  512. * rather than embedding a full copy of strptime() that handles
  513. * all formats */
  514. /* Thus avoiding needing to test for (broken) negative date/time
  515. * numbers in token reading - only need to check the upper range */
  516. bool failed = false;
  517. char *isotime_tokenizer = strdup(isotime);
  518. if (isotime_tokenizer) {
  519. char *tmpbuf;
  520. char *pch = strtok_r(isotime_tokenizer, "-T:", &tmpbuf);
  521. int token_number = 0;
  522. while (pch != NULL) {
  523. double sec;
  524. unsigned int tmp;
  525. token_number++;
  526. // Give up if encountered way too many tokens.
  527. if (token_number > 10) {
  528. failed = true;
  529. break;
  530. }
  531. switch (token_number) {
  532. case 1: // Year token
  533. tmp = atoi(pch);
  534. if (tmp < 9999)
  535. tm.tm_year = tmp - 1900; // Adjust to tm year
  536. else
  537. failed = true;
  538. break;
  539. case 2: // Month token
  540. tmp = atoi(pch);
  541. if (tmp < 13)
  542. tm.tm_mon = tmp - 1; // Month indexing starts from zero
  543. else
  544. failed = true;
  545. break;
  546. case 3: // Day token
  547. tmp = atoi(pch);
  548. if (tmp < 32)
  549. tm.tm_mday = tmp;
  550. else
  551. failed = true;
  552. break;
  553. case 4: // Hour token
  554. tmp = atoi(pch);
  555. if (tmp < 24)
  556. tm.tm_hour = tmp;
  557. else
  558. failed = true;
  559. break;
  560. case 5: // Minute token
  561. tmp = atoi(pch);
  562. if (tmp < 60)
  563. tm.tm_min = tmp;
  564. else
  565. failed = true;
  566. break;
  567. case 6: // Seconds token
  568. sec = safe_atof(pch);
  569. // NB To handle timestamps with leap seconds
  570. if (0 == isfinite(sec) &&
  571. sec >= 0.0 && sec < 61.5 ) {
  572. tm.tm_sec = (unsigned int)sec; // Truncate to get integer value
  573. usec = sec - (unsigned int)sec; // Get the fractional part (if any)
  574. }
  575. else
  576. failed = true;
  577. break;
  578. default: break;
  579. }
  580. pch = strtok_r(NULL, "-T:", &tmpbuf);
  581. }
  582. free(isotime_tokenizer);
  583. // Split may result in more than 6 tokens if the TZ has any t's in it
  584. // So check that we've seen enough tokens rather than an exact number
  585. if (token_number < 6)
  586. failed = true;
  587. }
  588. if (failed)
  589. memset(&tm,0,sizeof(tm));
  590. else {
  591. // When successful this normalizes tm so that tm_yday is set
  592. // and thus tm is valid for use with other functions
  593. if (mktime(&tm) == (time_t)-1)
  594. // Failed mktime - so reset the timestamp
  595. memset(&tm,0,sizeof(tm));
  596. }
  597. #endif
  598. if (dp != NULL && *dp == '.')
  599. usec = strtod(dp, NULL);
  600. /*
  601. * It would be nice if we could say mktime(&tm) - timezone + usec instead,
  602. * but timezone is not available at all on some BSDs. Besides, when working
  603. * with historical dates the value of timezone after an ordinary tzset(3)
  604. * can be wrong; you have to do a redirect through the IANA historical
  605. * timezone database to get it right.
  606. */
  607. ret.tv_sec = mkgmtime(&tm);
  608. ret.tv_nsec = usec * 1e9;;
  609. #else
  610. double usec = 0;
  611. QString t(isotime);
  612. QDateTime d = QDateTime::fromString(isotime, Qt::ISODate);
  613. QStringList sl = t.split(".");
  614. if (sl.size() > 1)
  615. usec = sl[1].toInt() / pow(10., (double)sl[1].size());
  616. ret.tv_sec = d.toTime_t();
  617. ret.tv_nsec = usec * 1e9;;
  618. #endif
  619. #endif /* __clang_analyzer__ */
  620. return ret;
  621. }
  622. /* Unix timespec UTC time to ISO8601, no timezone adjustment */
  623. /* example: 2007-12-11T23:38:51.033Z */
  624. char *timespec_to_iso8601(timespec_t fixtime, char isotime[], size_t len)
  625. {
  626. struct tm when;
  627. char timestr[30];
  628. long fracsec;
  629. if (0 > fixtime.tv_sec) {
  630. // Allow 0 for testing of 1970-01-01T00:00:00.000Z
  631. return strncpy(isotime, "NaN", len);
  632. }
  633. if (999499999 < fixtime.tv_nsec) {
  634. /* round up */
  635. fixtime.tv_sec++;
  636. fixtime.tv_nsec = 0;
  637. }
  638. #ifdef HAVE_GMTIME_R
  639. (void)gmtime_r(&fixtime.tv_sec, &when);
  640. #else
  641. /* Fallback to try with gmtime_s - primarily for Windows */
  642. (void)gmtime_s(&when, &fixtime.tv_sec);
  643. #endif
  644. /*
  645. * Do not mess casually with the number of decimal digits in the
  646. * format! Most GPSes report over serial links at 0.01s or 0.001s
  647. * precision. Round to 0.001s
  648. */
  649. fracsec = (fixtime.tv_nsec + 500000) / 1000000;
  650. (void)strftime(timestr, sizeof(timestr), "%Y-%m-%dT%H:%M:%S", &when);
  651. (void)snprintf(isotime, len, "%s.%03ldZ",timestr, fracsec);
  652. return isotime;
  653. }
  654. /* return time now as ISO8601, no timezone adjustment */
  655. /* example: 2007-12-11T23:38:51.033Z */
  656. char *now_to_iso8601(char *tbuf, size_t tbuf_sz)
  657. {
  658. timespec_t ts_now;
  659. (void)clock_gettime(CLOCK_REALTIME, &ts_now);
  660. return timespec_to_iso8601(ts_now, tbuf, tbuf_sz);
  661. }
  662. #define Deg2Rad(n) ((n) * DEG_2_RAD)
  663. /* Distance in meters between two points specified in degrees, optionally
  664. * with initial and final bearings. */
  665. double earth_distance_and_bearings(double lat1, double lon1,
  666. double lat2, double lon2,
  667. double *ib, double *fb)
  668. {
  669. /*
  670. * this is a translation of the javascript implementation of the
  671. * Vincenty distance formula by Chris Veness. See
  672. * http://www.movable-type.co.uk/scripts/latlong-vincenty.html
  673. */
  674. double a, b, f; // WGS-84 ellipsoid params
  675. double L, L_P, U1, U2, s_U1, c_U1, s_U2, c_U2;
  676. double uSq, A, B, d_S, lambda;
  677. // cppcheck-suppress variableScope
  678. double s_L, c_L, s_A, C;
  679. double c_S, S, s_S, c_SqA, c_2SM;
  680. int i = 100;
  681. a = WGS84A;
  682. b = WGS84B;
  683. f = 1 / WGS84F;
  684. L = Deg2Rad(lon2 - lon1);
  685. U1 = atan((1 - f) * tan(Deg2Rad(lat1)));
  686. U2 = atan((1 - f) * tan(Deg2Rad(lat2)));
  687. s_U1 = sin(U1);
  688. c_U1 = cos(U1);
  689. s_U2 = sin(U2);
  690. c_U2 = cos(U2);
  691. lambda = L;
  692. do {
  693. s_L = sin(lambda);
  694. c_L = cos(lambda);
  695. s_S = sqrt((c_U2 * s_L) * (c_U2 * s_L) +
  696. (c_U1 * s_U2 - s_U1 * c_U2 * c_L) *
  697. (c_U1 * s_U2 - s_U1 * c_U2 * c_L));
  698. if (s_S == 0)
  699. return 0;
  700. c_S = s_U1 * s_U2 + c_U1 * c_U2 * c_L;
  701. S = atan2(s_S, c_S);
  702. s_A = c_U1 * c_U2 * s_L / s_S;
  703. c_SqA = 1 - s_A * s_A;
  704. c_2SM = c_S - 2 * s_U1 * s_U2 / c_SqA;
  705. if (0 == isfinite(c_2SM))
  706. c_2SM = 0;
  707. C = f / 16 * c_SqA * (4 + f * (4 - 3 * c_SqA));
  708. L_P = lambda;
  709. lambda = L + (1 - C) * f * s_A *
  710. (S + C * s_S * (c_2SM + C * c_S * (2 * c_2SM * c_2SM - 1)));
  711. } while ((fabs(lambda - L_P) > 1.0e-12) && (--i > 0));
  712. if (i == 0)
  713. return NAN; // formula failed to converge
  714. uSq = c_SqA * ((a * a) - (b * b)) / (b * b);
  715. A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
  716. B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
  717. d_S = B * s_S * (c_2SM + B / 4 *
  718. (c_S * (-1 + 2 * c_2SM * c_2SM) - B / 6 * c_2SM *
  719. (-3 + 4 * s_S * s_S) * (-3 + 4 * c_2SM * c_2SM)));
  720. if (ib != NULL)
  721. *ib = atan2(c_U2 * sin(lambda), c_U1 * s_U2 - s_U1 * c_U2 * cos(lambda));
  722. if (fb != NULL)
  723. *fb = atan2(c_U1 * sin(lambda), c_U1 * s_U2 * cos(lambda) - s_U1 * c_U2);
  724. return (WGS84B * A * (S - d_S));
  725. }
  726. /* Distance in meters between two points specified in degrees. */
  727. double earth_distance(double lat1, double lon1, double lat2, double lon2)
  728. {
  729. return earth_distance_and_bearings(lat1, lon1, lat2, lon2, NULL, NULL);
  730. }
  731. // Wait for data until timeout, ignoring signals.
  732. bool nanowait(int fd, struct timespec *to)
  733. {
  734. fd_set fdset;
  735. FD_ZERO(&fdset);
  736. FD_SET(fd, &fdset);
  737. TS_NORM(to); // just in case
  738. // sigmask is NULL, so equivalent to select()
  739. return pselect(fd + 1, &fdset, NULL, NULL, to, NULL) == 1;
  740. }
  741. /* Accept a datum code, return matching string
  742. *
  743. * There are a ton of these, only a few are here
  744. *
  745. */
  746. void datum_code_string(int code, char *buffer, size_t len)
  747. {
  748. const char *datum_str;
  749. switch (code) {
  750. case 0:
  751. datum_str = "WGS84";
  752. break;
  753. case 21:
  754. datum_str = "WGS84";
  755. break;
  756. case 178:
  757. datum_str = "Tokyo Mean";
  758. break;
  759. case 179:
  760. datum_str = "Tokyo-Japan";
  761. break;
  762. case 180:
  763. datum_str = "Tokyo-Korea";
  764. break;
  765. case 181:
  766. datum_str = "Tokyo-Okinawa";
  767. break;
  768. case 182:
  769. datum_str = "PZ90.11";
  770. break;
  771. case 999:
  772. datum_str = "User Defined";
  773. break;
  774. default:
  775. datum_str = NULL;
  776. break;
  777. }
  778. if (NULL == datum_str) {
  779. /* Fake it */
  780. snprintf(buffer, len, "%d", code);
  781. } else {
  782. strlcpy(buffer, datum_str, len);
  783. }
  784. }
  785. /* end */
  786. // vim: set expandtab shiftwidth=4