PageRenderTime 59ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/evadeo-affix.c

https://github.com/jedisct1/evadeo-tools
C | 1375 lines | 1273 code | 100 blank | 2 comment | 108 complexity | aef88e12b4d00f4baec04e904cb27018 MD5 | raw file
Possible License(s): 0BSD
  1. #define COBJMACROS 1
  2. #include <windows.h>
  3. #include <winable.h>
  4. #include <ntdef.h>
  5. #include <winreg.h>
  6. #include <shellapi.h>
  7. #include <commctrl.h>
  8. #include <unistd.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <time.h>
  12. #include <winuser.h>
  13. #include <math.h>
  14. #define EPHEMERIS_NUMBER 32
  15. #define POWER_MASK 20
  16. #define FRAME_RATE (1000 / 2)
  17. #define GRIBOUILLI 0
  18. #define DEBUG 0
  19. #if DEBUG
  20. # warning DEBUG BUILD
  21. #endif
  22. extern VOID ForcePageout(void);
  23. static HWND h_test;
  24. static UINT timer = 0;
  25. static HANDLE global_hcom;
  26. static BOOL taskbar_init_enabled = FALSE;
  27. typedef double Coord;
  28. typedef struct MinDecCoord_ {
  29. int deg;
  30. int min;
  31. int dec;
  32. } MinDecCoord;
  33. typedef struct LastPos_ {
  34. Coord lon;
  35. Coord lat;
  36. double hdop;
  37. } LastPos;
  38. static BOOL hide_taskbar(void)
  39. {
  40. HWND taskBarHWnd = FindWindow(L"HHTaskBar", L"");
  41. if (taskBarHWnd == NULL) {
  42. return FALSE;
  43. }
  44. if (IsWindowEnabled(taskBarHWnd)) {
  45. taskbar_init_enabled = TRUE;
  46. }
  47. // ShowWindow(taskBarHWnd, SW_HIDE);
  48. EnableWindow(taskBarHWnd, FALSE);
  49. return TRUE;
  50. }
  51. static BOOL restore_taskbar(void)
  52. {
  53. HWND taskBarHWnd = FindWindow(L"HHTaskBar", L"");
  54. if (taskBarHWnd == NULL) {
  55. return FALSE;
  56. }
  57. if (taskbar_init_enabled == FALSE) {
  58. return TRUE;
  59. }
  60. ShowWindow(taskBarHWnd, SW_SHOW);
  61. EnableWindow(taskBarHWnd, TRUE);
  62. return TRUE;
  63. }
  64. static MinDecCoord coord_dec_to_mindec(const double a)
  65. {
  66. MinDecCoord mindec;
  67. double min_f;
  68. mindec.deg = (int) a;
  69. min_f = (a - mindec.deg) * 60.0;
  70. mindec.min = (int) min_f;
  71. mindec.dec = ((min_f - mindec.min + 0.0005) * 1000);
  72. return mindec;
  73. }
  74. static MinDecCoord coord_nmea_to_mindec(const double a)
  75. {
  76. MinDecCoord mindec;
  77. double min_f;
  78. mindec.deg = (int) a / 100;
  79. mindec.min = (int) a % 100;
  80. min_f = a - (int) a;
  81. mindec.dec = ((min_f + 0.0005) * 1000);
  82. return mindec;
  83. }
  84. static size_t strlcpy(char *dst, const char *src, size_t siz)
  85. {
  86. char *d = dst;
  87. const char *s = src;
  88. size_t n = siz;
  89. if (n != 0) {
  90. while (--n != 0) {
  91. if ((*d++ = *s++) == '\0')
  92. break;
  93. }
  94. }
  95. if (n == 0) {
  96. if (siz != 0) {
  97. *d = 0;
  98. }
  99. while (*s++);
  100. }
  101. return s - src - 1;
  102. }
  103. static char *tokenize(char *str, int chr_)
  104. {
  105. static char *part;
  106. static int chr;
  107. char *oldpart;
  108. char *sep;
  109. if (str == NULL) {
  110. return NULL;
  111. }
  112. if (chr_ != 0) {
  113. chr = chr_;
  114. part = str;
  115. }
  116. if (*part == 0) {
  117. return "";
  118. }
  119. oldpart = part;
  120. if ((sep = strchr(part, chr)) != NULL) {
  121. *sep = 0;
  122. part = sep + 1;
  123. } else {
  124. part = "";
  125. }
  126. return oldpart;
  127. }
  128. static double tokenize_double(char *str)
  129. {
  130. return atof(tokenize(str, 0));
  131. }
  132. static WCHAR *tokenize_string(char *str)
  133. {
  134. char *tokenized;
  135. static WCHAR wstr[2000];
  136. tokenized = tokenize(str, 0);
  137. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, tokenized, -1, wstr, sizeof wstr);
  138. return wstr;
  139. }
  140. static int tokenize_int(char *str)
  141. {
  142. return (int) strtol(tokenize(str, 0), NULL, 0);
  143. }
  144. typedef enum FixQuality_ {
  145. FQ_INVALID = 0,
  146. FQ_GPS = 1,
  147. FQ_DGPS = 2,
  148. FQ_PPS = 3,
  149. FQ_RTK = 4,
  150. FQ_FLOAT = 5,
  151. FQ_ESTIMATED = 6,
  152. FQ_MANUAL = 7,
  153. FQ_SIMULATION = 8
  154. } FixQuality;
  155. typedef enum TridiFix_ {
  156. TDFX_NOFIX = 1,
  157. TDFX_2D = 2,
  158. TDFX_3D = 3
  159. } TridiFix;
  160. typedef struct GPStatus_ {
  161. BOOL initialized;
  162. Coord lat;
  163. WCHAR lat_dir[4];
  164. Coord lon;
  165. WCHAR lon_dir[4];
  166. FixQuality fix_quality;
  167. int tracked_sat_count;
  168. double hdop;
  169. double vdop;
  170. int altitude;
  171. time_t dgps_since;
  172. int dgps_station_id;
  173. TridiFix tridifix;
  174. int useful_sat_count;
  175. int time_valid_flag;
  176. int tow;
  177. int found_ephemeris;
  178. double decibels;
  179. double masked_decibels;
  180. Coord avg_total_lat;
  181. Coord avg_total_lon;
  182. double avg_lonlat_counts;
  183. long int avg_total_altitude;
  184. double avg_altitude_counts;
  185. } GPStatus;
  186. static GPStatus gpstatus;
  187. int nmea_cb_gpgga(char *sentence)
  188. {
  189. char *str;
  190. WCHAR *wstr;
  191. tokenize_double(sentence); /* fix_date */
  192. str = tokenize(sentence, 0);
  193. if (*str != 0) {
  194. gpstatus.lat = atof(str);
  195. }
  196. wstr = tokenize_string(sentence);
  197. if (wcslen(wstr) > 0) {
  198. _snwprintf(gpstatus.lat_dir, sizeof gpstatus.lat_dir, L"%s", wstr);
  199. }
  200. str = tokenize(sentence, 0);
  201. if (*str != 0) {
  202. gpstatus.lon = atof(str);
  203. }
  204. wstr = tokenize_string(sentence);
  205. if (wcslen(wstr) > 0) {
  206. _snwprintf(gpstatus.lon_dir, sizeof gpstatus.lon_dir, L"%s", wstr);
  207. }
  208. gpstatus.fix_quality = tokenize_int(sentence);
  209. gpstatus.tracked_sat_count = tokenize_int(sentence);
  210. gpstatus.hdop = tokenize_double(sentence);
  211. gpstatus.altitude = (int) (tokenize_double(sentence) + 0.5);
  212. tokenize_string(sentence); /* unité */
  213. tokenize_double(sentence); /* geoid separation */
  214. tokenize_string(sentence); /* unité */
  215. gpstatus.dgps_since = tokenize_int(sentence);
  216. gpstatus.dgps_station_id = tokenize_int(sentence);
  217. return 0;
  218. }
  219. int nmea_cb_gpgsa(char *sentence)
  220. {
  221. int sats = 0;
  222. int sat_count = 12;
  223. tokenize_string(sentence); /* auto-selection */
  224. gpstatus.tridifix = tokenize_int(sentence);
  225. do {
  226. if (*(tokenize(sentence, 0)) != 0) {
  227. sats++;
  228. }
  229. } while (--sat_count != 0);
  230. gpstatus.useful_sat_count = sats;
  231. tokenize_double(sentence); /* pdop */
  232. tokenize_double(sentence); /* hdop */
  233. gpstatus.vdop = tokenize_double(sentence);
  234. return 0;
  235. }
  236. int nmea_cb_gprmc(char *sentence)
  237. {
  238. double gptime;
  239. int gpdate;
  240. SYSTEMTIME stime;
  241. gptime = tokenize_double(sentence);
  242. if (*(tokenize_string(sentence)) != L'V') {
  243. return 0;
  244. }
  245. tokenize_double(sentence); /* latitude */
  246. tokenize_string(sentence); /* N/S */
  247. tokenize_double(sentence); /* longitude */
  248. tokenize_string(sentence); /* E/W */
  249. tokenize_double(sentence); /* vitesse */
  250. tokenize_double(sentence); /* cap */
  251. gpdate = tokenize_int(sentence);
  252. ZeroMemory(&stime, sizeof stime);
  253. stime.wYear = 2000 + gpdate % 100;
  254. if (stime.wYear < 2009) {
  255. return -1;
  256. }
  257. stime.wMonth = (gpdate / 100) % 100;
  258. stime.wDay = (gpdate / 10000) % 100;
  259. stime.wHour = (int) (gptime / 10000) % 100;
  260. stime.wMinute = (int) (gptime / 100) % 100;
  261. stime.wSecond = (int) gptime % 100;
  262. stime.wMilliseconds = (int) ((gptime - (int) gptime) * 1000.0);
  263. SetSystemTime(&stime);
  264. return 0;
  265. }
  266. int nmea_cb_psrf151(char *sentence)
  267. {
  268. unsigned int ephemeris;
  269. int found_ephemeris = 0;
  270. int bits = 32;
  271. gpstatus.time_valid_flag = tokenize_int(sentence);
  272. tokenize_int(sentence); /* week number */
  273. gpstatus.tow = tokenize_int(sentence);
  274. ephemeris = (unsigned int) tokenize_int(sentence);
  275. if (ephemeris == 0U && (gpstatus.tow == 0 || gpstatus.time_valid_flag == 0)) {
  276. ephemeris = 0xffffffff;
  277. }
  278. do {
  279. if ((ephemeris & 0x80000000) == 0) {
  280. found_ephemeris++;
  281. }
  282. ephemeris <<= 1;
  283. } while (--bits != 0);
  284. if (found_ephemeris > EPHEMERIS_NUMBER) {
  285. found_ephemeris = EPHEMERIS_NUMBER;
  286. }
  287. gpstatus.found_ephemeris = found_ephemeris;
  288. return 0;
  289. }
  290. int nmea_cb_gpgsv(char *sentence)
  291. {
  292. static double decibels = 0.0;
  293. static double masked_decibels = 0.0;
  294. double dp;
  295. int nb;
  296. int total_nb;
  297. int sats_per_sentence = 4;
  298. int snr;
  299. char *str;
  300. total_nb = tokenize_int(sentence); /* number of sentences */
  301. nb = tokenize_int(sentence);
  302. tokenize_int(sentence); /* number of stats in view */
  303. if (nb < 2) {
  304. decibels = 0.0;
  305. masked_decibels = 0.0;
  306. }
  307. do {
  308. tokenize_int(sentence); /* PRN */
  309. tokenize_int(sentence); /* elevation */
  310. tokenize_int(sentence); /* azimuth */
  311. str = tokenize(sentence, 0);
  312. if (*str == 0) {
  313. continue;
  314. }
  315. snr = atoi(str);
  316. if (snr > 100) {
  317. snr = 100;
  318. }
  319. dp = pow(10.0, (double) snr / 10.0);
  320. decibels += dp;
  321. if (snr >= POWER_MASK) {
  322. masked_decibels += dp;
  323. }
  324. } while (--sats_per_sentence != 0);
  325. if (decibels == 0.0) {
  326. decibels = -10000000.0;
  327. } else {
  328. decibels = 10.0 * log10(decibels);
  329. }
  330. if (masked_decibels == 0.0) {
  331. masked_decibels = -10000000.0;
  332. } else {
  333. masked_decibels = 10.0 * log10(masked_decibels);
  334. }
  335. if (total_nb == nb) {
  336. gpstatus.decibels = max(decibels, 0.0);
  337. gpstatus.masked_decibels = max(masked_decibels, 0.0);
  338. }
  339. return 0;
  340. }
  341. typedef int (*NmeaCallback)(char *str);
  342. typedef struct NmeaSentence_ {
  343. const char *keyword;
  344. NmeaCallback callback;
  345. } NmeaSentence;
  346. NmeaSentence nmea_sentences[] = {
  347. { "$GPGGA", nmea_cb_gpgga },
  348. { "$GPGSA", nmea_cb_gpgsa },
  349. { "$PSRF151", nmea_cb_psrf151 },
  350. { "$GPGSV", nmea_cb_gpgsv },
  351. { "$GPRMC", nmea_cb_gprmc },
  352. { NULL, (NmeaCallback) NULL }
  353. };
  354. static BOOL wait_any_data(HANDLE hcom)
  355. {
  356. CHAR k[8192];
  357. DWORD readen;
  358. #ifdef USHUAIA
  359. Sleep(100);
  360. #else
  361. ReadFile(hcom, k, sizeof k - 1, &readen, NULL);
  362. #endif
  363. PurgeComm(hcom, PURGE_RXCLEAR);
  364. /* PSRF154 */
  365. return TRUE;
  366. }
  367. static BOOL send_nmea_command(HANDLE hcom, const char *cmd)
  368. {
  369. char strbuf[1000];
  370. DWORD written;
  371. DWORD length;
  372. unsigned char cksum = 0U;
  373. unsigned char c;
  374. const char *pnt = cmd;
  375. while ((c = (unsigned char) *pnt++) != 0) {
  376. cksum ^= c;
  377. }
  378. _snprintf(strbuf, sizeof strbuf, "$%s*%02X\r\n", cmd, cksum);
  379. length = strlen(strbuf);
  380. WriteFile(hcom, strbuf, length, &written, NULL);
  381. for (;;) {
  382. if (written != length) {
  383. Sleep(1000);
  384. wait_any_data(hcom);
  385. continue;
  386. }
  387. break;
  388. }
  389. FlushFileBuffers(hcom);
  390. return TRUE;
  391. }
  392. static BOOL send_sirf_command(HANDLE hcom, const unsigned char *cmd,
  393. const size_t length)
  394. {
  395. unsigned char strbuf[1000];
  396. unsigned char *pnts = strbuf;
  397. WORD cksum = 0U;
  398. size_t t = 0U;
  399. unsigned char c;
  400. DWORD written;
  401. DWORD size;
  402. if (length > sizeof strbuf - 8U) {
  403. return FALSE;
  404. }
  405. *pnts++ = 0xa0;
  406. *pnts++ = 0xa2;
  407. *pnts++ = length >> 8;
  408. *pnts++ = length & 0xff;
  409. do {
  410. c = *cmd++;
  411. cksum += (WORD) c;
  412. *pnts++ = c;
  413. } while (++t != length);
  414. cksum &= 0x7fff;
  415. *pnts++ = cksum >> 8;
  416. *pnts++ = cksum & 0xff;
  417. *pnts++ = 0xb0;
  418. *pnts++ = 0xb3;
  419. size = pnts - strbuf;
  420. for (;;) {
  421. WriteFile(hcom, strbuf, size, &written, NULL);
  422. if (written != size) {
  423. Sleep(1000);
  424. wait_any_data(hcom);
  425. continue;
  426. }
  427. break;
  428. }
  429. FlushFileBuffers(hcom);
  430. return TRUE;
  431. }
  432. static HANDLE open_port(const WCHAR **ports_list, BOOL is_virtual)
  433. {
  434. const WCHAR **port = ports_list;
  435. HANDLE hcom;
  436. DCB dcb;
  437. do {
  438. hcom = CreateFile(*port, GENERIC_READ | GENERIC_WRITE,
  439. 0, NULL, OPEN_EXISTING, 0, NULL);
  440. if (hcom == INVALID_HANDLE_VALUE) {
  441. continue;
  442. }
  443. if (!GetCommState(hcom, &dcb)) {
  444. if (is_virtual) {
  445. goto commstate_initialized;
  446. }
  447. CloseHandle(hcom);
  448. hcom = INVALID_HANDLE_VALUE;
  449. continue;
  450. }
  451. dcb.DCBlength = sizeof dcb;
  452. #ifdef USHUAIA
  453. dcb.BaudRate = 4800;
  454. #else
  455. dcb.BaudRate = 57600;
  456. #endif
  457. dcb.fBinary = TRUE;
  458. dcb.fParity = TRUE;
  459. dcb.fOutxCtsFlow = FALSE;
  460. dcb.fOutxDsrFlow = FALSE;
  461. dcb.fDtrControl = DTR_CONTROL_ENABLE;
  462. dcb.fTXContinueOnXoff = TRUE;
  463. dcb.fOutX = FALSE;
  464. dcb.fInX = FALSE;
  465. dcb.fErrorChar = FALSE;
  466. dcb.fNull = FALSE;
  467. dcb.fRtsControl = RTS_CONTROL_DISABLE;
  468. dcb.fAbortOnError = TRUE;
  469. dcb.ByteSize = 8;
  470. dcb.Parity = NOPARITY;
  471. dcb.StopBits = ONESTOPBIT;
  472. if (!SetCommState(hcom, &dcb)) {
  473. CloseHandle(hcom);
  474. hcom = INVALID_HANDLE_VALUE;
  475. continue;
  476. }
  477. commstate_initialized:
  478. PurgeComm(hcom, PURGE_RXCLEAR);
  479. PurgeComm(hcom, PURGE_TXCLEAR);
  480. break;
  481. } while (*++port != NULL);
  482. return hcom;
  483. }
  484. static BOOL setup_sirf(const WCHAR **ports_list)
  485. {
  486. WCHAR strbuf[1000];
  487. MSG msg;
  488. HANDLE hcom;
  489. hcom = open_port(ports_list, FALSE);
  490. if (hcom == INVALID_HANDLE_VALUE) {
  491. MessageBox(NULL, L"Impossible d'acceder a la puce SiRF",
  492. TEXT("Evadeo Affix"), MB_OK);
  493. return FALSE;
  494. }
  495. #if 1
  496. _snwprintf(strbuf, sizeof strbuf, L"Configuration de la Puce SiRF");
  497. SendMessage(h_test, WM_SETTEXT, 0, (LPARAM) strbuf);
  498. if (GetMessageW(&msg, NULL, 0, 0)) {
  499. TranslateMessage(&msg);
  500. DispatchMessageW(&msg);
  501. }
  502. #endif
  503. #if 0
  504. {
  505. CHAR k[1000];
  506. WCHAR wk[1000];
  507. DWORD readen;
  508. ReadFile(hcom, k, sizeof k - 1, &readen, NULL);
  509. k[readen] = 0;
  510. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, k, -1, wk, sizeof wk);
  511. }
  512. #endif
  513. wait_any_data(hcom);
  514. #if 1
  515. send_nmea_command(hcom, "PSRF151,01");
  516. send_nmea_command(hcom, "PSRF108,01");
  517. #endif
  518. #ifdef USHUAIA
  519. send_nmea_command(hcom, "PSRF100,0,4800,8,1,0");
  520. Sleep(100);
  521. send_nmea_command(hcom, "PSRF100,0,4800,8,1,0");
  522. Sleep(100);
  523. send_nmea_command(hcom, "PSRF100,0,4800,8,1,0");
  524. Sleep(100);
  525. #else
  526. send_nmea_command(hcom, "PSRF100,0,57600,8,1,0");
  527. Sleep(100);
  528. send_nmea_command(hcom, "PSRF100,0,57600,8,1,0");
  529. Sleep(100);
  530. send_nmea_command(hcom, "PSRF100,0,57600,8,1,0");
  531. Sleep(100);
  532. #endif
  533. {
  534. const unsigned char sc_nop[] = {
  535. 0x00
  536. };
  537. send_sirf_command(hcom, sc_nop, sizeof sc_nop);
  538. }
  539. #if 0
  540. {
  541. const unsigned char sc_production_operating_mode[] = {
  542. 0x96,
  543. 0x00,
  544. 0x00, 0x06,
  545. 0x00, 0x1E
  546. };
  547. send_sirf_command(hcom, sc_production_operating_mode, sizeof sc_production_operating_mode);
  548. }
  549. #endif
  550. {
  551. const unsigned char sc_enable_sbas[] = {
  552. 0x85,
  553. 0x01,
  554. 0x00, 0x00, 0x00, 0x00,
  555. 0x00 };
  556. send_sirf_command(hcom, sc_enable_sbas, sizeof sc_enable_sbas);
  557. }
  558. #if 0
  559. {
  560. const unsigned char sc_set_trickle_parameters[] = {
  561. 0x97, 0x00, 0x01, 0x03, 0xE8, 0x00, 0x00, 0x00, 0xC8
  562. };
  563. send_sirf_command(hcom, sc_set_trickle_parameters, sizeof sc_set_trickle_parameters);
  564. }
  565. #endif
  566. {
  567. const unsigned char sc_fast_push_to_fix[] = {
  568. 0xA7, 0x00, 0x01, 0xD4, 0xC0, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00,
  569. 0x01, 0x2C, 0x00, 0x00
  570. };
  571. send_sirf_command(hcom, sc_fast_push_to_fix, sizeof sc_fast_push_to_fix);
  572. }
  573. {
  574. const unsigned char sc_set_low_power_acquisition_params[] = {
  575. 0xA7, 0x00, 0x01, 0xD4, 0xC0, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0x01,
  576. 0x2C, 0x00, 0x00
  577. };
  578. send_sirf_command(hcom, sc_set_low_power_acquisition_params, sizeof sc_set_low_power_acquisition_params);
  579. }
  580. #if 1
  581. {
  582. const unsigned char sc_exit_push_to_fix[] = {
  583. 0x97, 0x00, 0x00, 0x03, 0xE8, 0x00, 0x00,0x00, 0xC8
  584. };
  585. send_sirf_command(hcom, sc_exit_push_to_fix, sizeof sc_exit_push_to_fix);
  586. }
  587. #endif
  588. {
  589. #if 0
  590. const unsigned char sc_enable_static_mode[] = {
  591. 0x8F, 0x01
  592. };
  593. const unsigned char sc_disable_static_mode[] = {
  594. 0x8F, 0x00
  595. };
  596. send_sirf_command(hcom, sc_disable_static_mode, sizeof sc_disable_static_mode);
  597. #endif
  598. }
  599. #if 1
  600. {
  601. const unsigned char sc_mode_control[] = {
  602. 0x88, 0x00, 0x00,
  603. 0x01, /* Degraded mode 0 - 4 (4 = disallow) */
  604. 0x00, 0x00,
  605. 0x00, 0x00, /* user-altitude */
  606. 0x00, /* altitude hold mode 0 = auto */
  607. 0x00, /* user last computed altitude */
  608. 0x00,
  609. 0x0a, /* degraded mode pendant 10 secondes (max 120) */
  610. 0x03, /* dead reckoning (max 120) */
  611. 0x01 /* track smoothing */
  612. };
  613. send_sirf_command(hcom, sc_mode_control, sizeof sc_mode_control);
  614. }
  615. #endif
  616. {
  617. const unsigned char sc_mask_control[] = {
  618. 0x89,
  619. 0x00, /* auto PDOP/HDOP */
  620. 0x08, /* GDOP (1-50) */
  621. 0x08, /* PDOP */
  622. 0x08 /* HDOP */
  623. };
  624. send_sirf_command(hcom, sc_mask_control, sizeof sc_mask_control);
  625. }
  626. {
  627. const unsigned char sc_dgps_control[] = {
  628. 0x8a,
  629. 0x00, /* auto (1 = exclusive) */
  630. 0x1E /* timeout */
  631. };
  632. send_sirf_command(hcom, sc_dgps_control, sizeof sc_dgps_control);
  633. }
  634. #if 0
  635. {
  636. const unsigned char sc_elevation_mask[] = {
  637. 0x8b,
  638. 0x00, 0x16, /* tracking mask */
  639. 0x00, 0x32 /* navigation mask */
  640. };
  641. send_sirf_command(hcom, sc_elevation_mask, sizeof sc_elevation_mask);
  642. }
  643. #endif
  644. {
  645. const unsigned char sc_power_mask[] = {
  646. 0x8c,
  647. 0x14, /* tracking mask (pas gere) */
  648. 0x14
  649. };
  650. send_sirf_command(hcom, sc_power_mask, sizeof sc_power_mask);
  651. }
  652. #if 1
  653. {
  654. const unsigned char sc_back_to_nmea[] = {
  655. 0x81, 0x02, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  656. 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01,
  657. #ifdef USHUAIA
  658. 0x12, 0xC0 /* 4800 */
  659. #else
  660. 0xE1, 0x00 /* 57600 */
  661. #endif
  662. };
  663. send_sirf_command(hcom, sc_back_to_nmea, sizeof sc_back_to_nmea);
  664. send_sirf_command(hcom, sc_back_to_nmea, sizeof sc_back_to_nmea);
  665. send_sirf_command(hcom, sc_back_to_nmea, sizeof sc_back_to_nmea);
  666. }
  667. #endif
  668. send_nmea_command(hcom, "PSRF103,0,0,0,1"); // GGA
  669. send_nmea_command(hcom, "PSRF103,1,0,1,1"); // GLL
  670. send_nmea_command(hcom, "PSRF103,2,0,5,1"); // GSA
  671. send_nmea_command(hcom, "PSRF103,3,0,5,1"); // GSV
  672. send_nmea_command(hcom, "PSRF103,4,0,1,1"); // RMC
  673. send_nmea_command(hcom, "PSRF103,5,0,1,1"); // VTG
  674. send_nmea_command(hcom, "PSRF103,6,0,1,1"); // MSS
  675. send_nmea_command(hcom, "PSRF103,7,0,1,1"); // ?
  676. send_nmea_command(hcom, "PSRF103,8,0,1,1"); // ZDA
  677. send_nmea_command(hcom, "PSRF103,9,0,1,1"); // ?
  678. wait_any_data(hcom);
  679. send_nmea_command(hcom, "PSRF112,140,6,1"); // message rate for ephemeris
  680. wait_any_data(hcom);
  681. PurgeComm(hcom, PURGE_RXCLEAR);
  682. CloseHandle(hcom);
  683. #if 1
  684. _snwprintf(strbuf, sizeof strbuf, L"Puce SiRF configurée");
  685. SendMessage(h_test, WM_SETTEXT, 0, (LPARAM) strbuf);
  686. if (GetMessageW(&msg, NULL, 0, 0)) {
  687. TranslateMessage(&msg);
  688. DispatchMessageW(&msg);
  689. }
  690. #endif
  691. return TRUE;
  692. }
  693. static BOOL parse_nmea_messages(HANDLE hcom)
  694. {
  695. char serbuf[8192];
  696. DWORD readen;
  697. char *serbuf_p = serbuf;
  698. char sentence[4096];
  699. char *tok;
  700. size_t sentence_len;
  701. NmeaSentence *scanned_nmea_sentence;
  702. char *keyword;
  703. char *sep;
  704. if (ReadFile(hcom, serbuf, sizeof serbuf - 1U, &readen, NULL) == FALSE) {
  705. return FALSE;
  706. }
  707. serbuf[readen] = 0;
  708. gpstatus.initialized = TRUE;
  709. #if DEBUG
  710. {
  711. FILE *fp = fopen("\\Evadeo\\debug.log", "at");
  712. fprintf(fp, "%s", serbuf);
  713. fclose(fp);
  714. }
  715. #endif
  716. while (*serbuf_p != 0) {
  717. tok = strchr(serbuf_p, '\r');
  718. if (tok == NULL) {
  719. sentence_len = strlen(serbuf_p);
  720. } else {
  721. sentence_len = (size_t) (tok - serbuf);
  722. }
  723. if (sentence_len > sizeof sentence) {
  724. goto next;
  725. }
  726. if (tok != NULL) {
  727. *tok = 0;
  728. }
  729. memcpy(sentence, serbuf_p, sentence_len + 1);
  730. scanned_nmea_sentence = nmea_sentences;
  731. if ((sep = strrchr(sentence, '*')) != NULL) {
  732. *sep = 0;
  733. }
  734. #if 0
  735. {
  736. FILE *fp = fopen("\\Evadeo\\position.log", "a");
  737. fprintf(fp, "[%s]\n", sentence);
  738. fclose(fp);
  739. }
  740. #endif
  741. keyword = tokenize(sentence, ',');
  742. do {
  743. if (strcasecmp(scanned_nmea_sentence->keyword, keyword) == 0) {
  744. scanned_nmea_sentence->callback(sentence);
  745. break;
  746. }
  747. scanned_nmea_sentence++;
  748. } while (scanned_nmea_sentence->keyword != NULL);
  749. next:
  750. if (tok == NULL) {
  751. break;
  752. }
  753. if (tok[1] == '\n') {
  754. tok++;
  755. }
  756. serbuf_p = tok + 1;
  757. }
  758. return TRUE;
  759. }
  760. LRESULT wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  761. {
  762. static HDC hdc = NULL;
  763. static HDC bmap_dc = NULL;
  764. static HBITMAP hbmap = NULL;
  765. static WORD width, height;
  766. static RECT rect;
  767. PAINTSTRUCT ps;
  768. static LOGFONT lf;
  769. static HFONT font;
  770. static HFONT location_font;
  771. static HFONT oldfont = NULL;
  772. const COLORREF bg_color = 0x000000;
  773. const COLORREF font_color = 0x7744bb;
  774. const COLORREF font_location_color = 0xff88cc;
  775. WCHAR strbuf[4000];
  776. Coord xlon = 0, xlat = 0;
  777. Coord xlon_diff, xlat_diff;
  778. int xaltitude = 0;
  779. int xaltitude_diff;
  780. MinDecCoord lon, lat;
  781. static const WCHAR *turner[] = {
  782. L" ... |",
  783. L" ... /",
  784. L" ... -",
  785. L" ... \\",
  786. NULL
  787. };
  788. static const WCHAR **turnerpnt = turner;
  789. switch(msg){
  790. case WM_CREATE:
  791. hdc = GetDC(hWnd);
  792. bmap_dc = CreateCompatibleDC(hdc);
  793. GetClientRect(hWnd, &rect);
  794. width = rect.right;
  795. height = rect.bottom;
  796. hbmap = CreateCompatibleBitmap(hdc, width, height);
  797. SelectObject(bmap_dc, hbmap);
  798. ZeroMemory(&lf, sizeof lf);
  799. #if 0
  800. {
  801. CHOOSEFONT cf;
  802. ZeroMemory(&cf, sizeof cf);
  803. cf.lStructSize = sizeof cf;
  804. cf.hwndOwner = hWnd;
  805. cf.lpLogFont = &lf;
  806. cf.rgbColors = 0;
  807. cf.Flags = CF_SCREENFONTS;
  808. ChooseFont(&cf);
  809. }
  810. #else
  811. lf.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
  812. _snwprintf(lf.lfFaceName, sizeof lf.lfFaceName, L"%s", L"Arial");
  813. lf.lfWeight = FW_NORMAL;
  814. lf.lfHeight = 24;
  815. #endif
  816. lf.lfQuality = ANTIALIASED_QUALITY;
  817. font = CreateFontIndirect(&lf);
  818. oldfont = SelectObject(bmap_dc, font);
  819. lf.lfWidth = 16;
  820. lf.lfHeight = 96;
  821. location_font = CreateFontIndirect(&lf);
  822. #if 0
  823. SelectObject(bmap_dc, CreateSolidBrush(0xaaffcc)); // XXX - leak
  824. #else
  825. SelectObject(bmap_dc, GetStockObject(HOLLOW_BRUSH)); // XXX - leak
  826. #endif
  827. ReleaseDC(hWnd, hdc);
  828. return 0;
  829. case WM_CLOSE:
  830. PostQuitMessage(0);
  831. // DestroyWindow(hWnd);
  832. break;
  833. case WM_DESTROY:
  834. #if 0
  835. if (oldfont != NULL) {
  836. SelectObject(bmap_dc, oldfont);
  837. oldfont = NULL;
  838. }
  839. DeleteObject(font);
  840. DeleteObject(hbmap);
  841. DeleteDC(bmap_dc);
  842. #endif
  843. PostQuitMessage(0);
  844. break;
  845. case WM_ERASEBKGND:
  846. return 1;
  847. case WM_PAINT:
  848. hdc = BeginPaint(hWnd, &ps);
  849. PatBlt(bmap_dc, 0, 0, width, height, BLACKNESS);
  850. SetBkColor(bmap_dc, bg_color);
  851. SetTextColor(bmap_dc, font_color);
  852. SelectObject(bmap_dc, font);
  853. {
  854. const WCHAR *fix_quality_s;
  855. const WCHAR *tridifix_s;
  856. const WCHAR *tow_s;
  857. WCHAR dgps_details[1000];
  858. if (gpstatus.useful_sat_count > gpstatus.tracked_sat_count) {
  859. gpstatus.tracked_sat_count = gpstatus.useful_sat_count;
  860. }
  861. switch (gpstatus.fix_quality) {
  862. case FQ_INVALID:
  863. fix_quality_s = *turnerpnt++;
  864. if (*turnerpnt == NULL) {
  865. turnerpnt = turner;
  866. }
  867. break;
  868. case FQ_GPS:
  869. fix_quality_s = L"- GPS"; break;
  870. case FQ_DGPS:
  871. if (gpstatus.dgps_station_id > 0) {
  872. _snwprintf(dgps_details, sizeof dgps_details, L"+ EGNOS n°%d", gpstatus.dgps_station_id);
  873. } else {
  874. _snwprintf(dgps_details, sizeof dgps_details, L"+ EGNOS");
  875. }
  876. fix_quality_s = dgps_details;
  877. break;
  878. case FQ_PPS:
  879. fix_quality_s = L"- PPS"; break;
  880. case FQ_RTK:
  881. fix_quality_s = L"- RTK"; break;
  882. case FQ_FLOAT:
  883. fix_quality_s = L"- flottant"; break;
  884. case FQ_ESTIMATED:
  885. fix_quality_s = L"- estimation"; break;
  886. case FQ_MANUAL:
  887. fix_quality_s = L"- manuel"; break;
  888. case FQ_SIMULATION:
  889. fix_quality_s = L"- simulation"; break;
  890. default:
  891. fix_quality_s = L"";
  892. }
  893. switch (gpstatus.tridifix) {
  894. case TDFX_NOFIX:
  895. if (gpstatus.fix_quality == FQ_INVALID) {
  896. if (gpstatus.useful_sat_count > 0) {
  897. tridifix_s = L"instable";
  898. } else if (gpstatus.tracked_sat_count > 0) {
  899. tridifix_s = L"signal brouillé";
  900. } else {
  901. tridifix_s = L"pas de fix";
  902. }
  903. } else {
  904. tridifix_s = L"approximatif";
  905. }
  906. break;
  907. case TDFX_2D:
  908. tridifix_s = L"2D"; break;
  909. case TDFX_3D:
  910. tridifix_s = L"3D"; break;
  911. default:
  912. tridifix_s = L"initialisation";
  913. }
  914. switch (gpstatus.time_valid_flag) {
  915. case 0:
  916. tow_s = L"Date inconnue"; break;
  917. case 1:
  918. tow_s = L"Heure inconnue"; break;
  919. case 2:
  920. tow_s = L"Heure OK"; break;
  921. case 3:
  922. tow_s = L"Heure et date OK"; break;
  923. default:
  924. tow_s = L"OK"; break;
  925. }
  926. if (gpstatus.useful_sat_count <= 0 || gpstatus.tracked_sat_count <= 0) {
  927. gpstatus.lon = gpstatus.lat = 0;
  928. }
  929. if ((gpstatus.tridifix != TDFX_NOFIX || gpstatus.fix_quality != FQ_INVALID) &&
  930. (gpstatus.lat != 0 || gpstatus.lon != 0) &&
  931. gpstatus.useful_sat_count > 0 &&
  932. gpstatus.hdop != 0.0 && gpstatus.hdop < 7.5) {
  933. double weight;
  934. gpstatus.avg_total_altitude += gpstatus.altitude;
  935. gpstatus.avg_altitude_counts++;
  936. xaltitude = gpstatus.avg_total_altitude / gpstatus.avg_altitude_counts;
  937. weight = gpstatus.hdop * gpstatus.hdop;
  938. gpstatus.avg_total_lat += gpstatus.lat / weight;
  939. gpstatus.avg_total_lon += gpstatus.lon / weight;
  940. gpstatus.avg_lonlat_counts += weight;
  941. xlat = gpstatus.avg_total_lat / gpstatus.avg_lonlat_counts;
  942. xlon = gpstatus.avg_total_lon / gpstatus.avg_lonlat_counts;
  943. } else if (gpstatus.avg_lonlat_counts > 0) {
  944. xlat = gpstatus.avg_total_lat / gpstatus.avg_lonlat_counts;
  945. xlon = gpstatus.avg_total_lon / gpstatus.avg_lonlat_counts;
  946. } else {
  947. xaltitude = gpstatus.altitude;
  948. if (gpstatus.lat == 0 && gpstatus.lon == 0 && gpstatus.avg_lonlat_counts > 0) {
  949. xlat = gpstatus.avg_total_lat / gpstatus.avg_lonlat_counts;
  950. xlon = gpstatus.avg_total_lon / gpstatus.avg_lonlat_counts;
  951. } else {
  952. xlat = gpstatus.lat;
  953. xlon = gpstatus.lon;
  954. }
  955. }
  956. if (gpstatus.lat == 0 && gpstatus.lon == 0 && gpstatus.avg_lonlat_counts > 0) {
  957. xlat = gpstatus.avg_total_lat / gpstatus.avg_lonlat_counts;
  958. xlon = gpstatus.avg_total_lon / gpstatus.avg_lonlat_counts;
  959. } else if (gpstatus.lat != 0 || gpstatus.lon != 0) {
  960. xlon_diff = xlon - gpstatus.lon;
  961. xlat_diff = xlat - gpstatus.lat;
  962. if (xlon_diff < -0.050 || xlon_diff > 0.050 ||
  963. xlat_diff < -0.050 || xlat_diff > 0.050) {
  964. gpstatus.avg_total_lon = 0;
  965. gpstatus.avg_total_lat = 0;
  966. gpstatus.avg_lonlat_counts = 0;
  967. xlat = gpstatus.lat;
  968. xlon = gpstatus.lon;
  969. }
  970. }
  971. xaltitude_diff = xaltitude - gpstatus.altitude;
  972. if (xaltitude_diff < -50 || xaltitude_diff > 50) {
  973. gpstatus.avg_total_altitude = 0;
  974. gpstatus.avg_altitude_counts = 0;
  975. xaltitude = gpstatus.altitude;
  976. }
  977. if (gpstatus.found_ephemeris >= 0) {
  978. _snwprintf(strbuf, sizeof strbuf,
  979. L"Type de fix : %s %s\r\n"
  980. L"Satellites suivis : %d - utilisés : %d\r\n"
  981. L"Dilution horizontale : %.2f\r\n"
  982. L"Instant fix : %d %% - %s\r\n"
  983. L"Signal : %d (%s%.3f dB) - Alt : %d m",
  984. tridifix_s, fix_quality_s,
  985. gpstatus.tracked_sat_count,
  986. gpstatus.useful_sat_count,
  987. gpstatus.hdop,
  988. gpstatus.found_ephemeris * 100 / EPHEMERIS_NUMBER, tow_s,
  989. gpstatus.decibels <= 0.0 ? 0 : ((int) round(pow(10.0, gpstatus.decibels / 10.0))),
  990. gpstatus.decibels <= 0.0 ? L"< " : L"", gpstatus.decibels,
  991. xaltitude);
  992. } else {
  993. _snwprintf(strbuf, sizeof strbuf,
  994. L"Type de fix : %s %s\r\n"
  995. L"Satellites suivis : %d - utilisés : %d\r\n"
  996. L"Dilution horizontale : %.2f\r\n"
  997. L"Signal : %d (%s%.3f dB) - Alt : %d m",
  998. tridifix_s, fix_quality_s,
  999. gpstatus.tracked_sat_count,
  1000. gpstatus.useful_sat_count,
  1001. gpstatus.hdop,
  1002. gpstatus.decibels <= 0.0 ? 0 : ((int) round(pow(10.0, gpstatus.decibels / 10.0))),
  1003. gpstatus.decibels <= 0.0 ? L"< " : L"", gpstatus.decibels,
  1004. xaltitude);
  1005. }
  1006. DrawText(bmap_dc, strbuf, -1, &rect, DT_LEFT | DT_TOP /* | DT_VCENTER | DT_SINGLELINE */);
  1007. }
  1008. SetTextColor(bmap_dc, font_location_color);
  1009. SelectObject(bmap_dc, location_font);
  1010. lat = coord_nmea_to_mindec(xlat);
  1011. lon = coord_nmea_to_mindec(xlon);
  1012. _snwprintf(strbuf, sizeof strbuf, L"%d°%02d.%03d %s %d°%02d.%03d %s",
  1013. lat.deg, lat.min, lat.dec, gpstatus.lat_dir, lon.deg, lon.min, lon.dec, gpstatus.lon_dir);
  1014. DrawText(bmap_dc, strbuf, -1, &rect, DT_CENTER | DT_BOTTOM /* | DT_VCENTER | DT_SINGLELINE */);
  1015. if (GRIBOUILLI && gpstatus.hdop != 0 && (xlat != 0 || xlon != 0) && gpstatus.fix_quality != FQ_INVALID) {
  1016. static LastPos last_pos[150];
  1017. static Coord min_lat = 1000000.0, min_lon = 1000000.0;
  1018. static Coord max_lat = -1000000.0, max_lon = -1000000.0;
  1019. double dx, dy;
  1020. double odx, ody;
  1021. double xxlon, xxlat;
  1022. int p;
  1023. #if 0
  1024. xlon = rand() % 1000;
  1025. xlat = rand() % 1000;
  1026. #endif
  1027. if (1) {
  1028. memmove(&last_pos[1], &last_pos[0], sizeof last_pos - sizeof last_pos[0]);
  1029. }
  1030. last_pos[0].lat = xlat;
  1031. last_pos[0].lon = xlon;
  1032. last_pos[0].hdop = gpstatus.hdop;
  1033. min_lat = 1000000.0;
  1034. min_lon = 1000000.0;
  1035. max_lat = -1000000.0;
  1036. max_lon = -1000000.0;
  1037. p = sizeof last_pos / sizeof last_pos[0];
  1038. do {
  1039. p--;
  1040. if (last_pos[p].hdop == 0) {
  1041. continue;
  1042. }
  1043. xxlon = last_pos[p].lon;
  1044. xxlat = last_pos[p].lat;
  1045. if (xxlon < min_lon) min_lon = xxlon;
  1046. if (xxlat < min_lat) min_lat = xxlat;
  1047. if (xxlon > max_lon) max_lon = xxlon;
  1048. if (xxlat > max_lat) max_lat = xxlat;
  1049. } while (p > 0);
  1050. if (max_lat == min_lat) {
  1051. min_lat -= 0.001;
  1052. max_lat += 0.001;
  1053. }
  1054. if (max_lon == min_lon) {
  1055. min_lon -= 0.001;
  1056. max_lon += 0.001;
  1057. }
  1058. odx = -1;
  1059. ody = -1;
  1060. p = sizeof last_pos / sizeof last_pos[0];
  1061. do {
  1062. double ray;
  1063. HPEN pen;
  1064. COLORREF color;
  1065. p--;
  1066. if (last_pos[p].hdop == 0) {
  1067. continue;
  1068. }
  1069. xxlon = last_pos[p].lon;
  1070. xxlat = last_pos[p].lat;
  1071. ray = round(10.0 / (double) (p + 1) + 1.0);
  1072. dx = round((xxlat - min_lat) * (double) width / (max_lat - min_lat));
  1073. dy = round((xxlon - min_lon) * (double) height / (max_lon - min_lon));
  1074. if (last_pos[p].hdop <= 1.0) {
  1075. color = 0x44ff44;
  1076. } else {
  1077. color = (COLORREF) round((double) 0xffffff / last_pos[p].hdop);
  1078. color <<= 8;
  1079. }
  1080. pen = CreatePen(PS_SOLID, 1, color);
  1081. SelectObject(bmap_dc, pen);
  1082. if (odx != -1) {
  1083. MoveToEx(bmap_dc, odx, ody, NULL);
  1084. LineTo(bmap_dc, dx, dy);
  1085. }
  1086. odx = dx;
  1087. ody = dy;
  1088. Ellipse(bmap_dc, dx - ray, dy - ray, dx + ray, dy + ray);
  1089. DeleteObject(pen);
  1090. } while (p > 0);
  1091. }
  1092. BitBlt(hdc, 0, 0, width, height, bmap_dc, 0, 0, SRCCOPY);
  1093. EndPaint(hWnd, &ps);
  1094. return 1;
  1095. case WM_TIMER:
  1096. parse_nmea_messages(global_hcom);
  1097. timer = SetTimer(hWnd, 1, FRAME_RATE, NULL);
  1098. InvalidateRect(hWnd, NULL, FALSE);
  1099. return 1;
  1100. default:
  1101. return DefWindowProc(hWnd,msg,wParam,lParam);
  1102. }
  1103. return 0;
  1104. }
  1105. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine,
  1106. int nCmdShow)
  1107. {
  1108. WNDCLASS wnd_cls;
  1109. HWND h_wnd;
  1110. MSG msg;
  1111. HANDLE hcom;
  1112. #ifdef USHUAIA
  1113. const WCHAR *sirf_ports[] = { L"COM2:", L"COM8:", L"COM7:", L"COM1:", NULL };
  1114. const WCHAR *comid_ports[] = { L"COM2:", L"COM1:", L"COM8:", L"COM7:", NULL };
  1115. #else
  1116. const WCHAR *sirf_ports[] = { L"COM8:", L"COM7:", L"COM1:", NULL };
  1117. const WCHAR *comid_ports[] = { L"COM1:", L"COM8:", L"COM7:", NULL };
  1118. #endif
  1119. (void) hInstance;
  1120. (void) hPrevInstance;
  1121. (void) lpCmdLine;
  1122. (void) nCmdShow;
  1123. ZeroMemory(&gpstatus, sizeof gpstatus);
  1124. gpstatus.avg_total_lat = gpstatus.avg_total_lon = 0;
  1125. gpstatus.avg_lonlat_counts = 0;
  1126. gpstatus.avg_total_altitude = 0;
  1127. gpstatus.avg_altitude_counts = 0;
  1128. gpstatus.found_ephemeris = -1;
  1129. gpstatus.initialized = FALSE;
  1130. ZeroMemory(&wnd_cls, sizeof wnd_cls);
  1131. wnd_cls.style = CS_HREDRAW | CS_VREDRAW;
  1132. wnd_cls.hInstance = hInstance;
  1133. wnd_cls.hCursor = LoadCursor(NULL, IDC_ARROW);
  1134. wnd_cls.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
  1135. wnd_cls.lpszClassName = L"Evadeo Affix";
  1136. wnd_cls.lpfnWndProc = (WNDPROC) wnd_proc;
  1137. RegisterClass(&wnd_cls);
  1138. h_wnd = FindWindow(L"Evadeo Affix", L"Evadeo Affix pour www.evadeiste.fr");
  1139. if (h_wnd) {
  1140. SetForegroundWindow((HWND) ((ULONG) h_wnd | 0x0001));
  1141. return 0;
  1142. }
  1143. hide_taskbar();
  1144. h_wnd = CreateWindowEx(WS_EX_NODRAG, L"Evadeo Affix", L"Evadeo Affix v0.91 pour www.evadeiste.fr",
  1145. WS_CAPTION | WS_SYSMENU | WS_EX_TOPMOST,
  1146. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
  1147. if (!h_wnd) {
  1148. MessageBox(NULL, L"Impossible de creer la fenetre",
  1149. TEXT("Evadeo Affix"), MB_OK);
  1150. restore_taskbar();
  1151. return 1;
  1152. }
  1153. #if 1
  1154. h_test = CreateWindow(WC_STATIC, L"Evadeo Affix",
  1155. WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_EX_CONTROLPARENT,
  1156. 0, 100, 480, 20, h_wnd, NULL, hInstance, NULL);
  1157. #endif
  1158. ShowWindow(h_wnd, SW_SHOW);
  1159. UpdateWindow(h_wnd);
  1160. ForcePageout();
  1161. #if 1
  1162. SendMessage(h_test, WM_SETTEXT, 0, (LPARAM) L"Démarrage en cours...");
  1163. if (GetMessageW(&msg, NULL, 0, 0)) {
  1164. TranslateMessage(&msg);
  1165. DispatchMessage(&msg);
  1166. }
  1167. #endif
  1168. if (setup_sirf(sirf_ports) == FALSE) {
  1169. DestroyWindow(h_wnd);
  1170. UnregisterClass(wnd_cls.lpszClassName, NULL);
  1171. restore_taskbar();
  1172. return 1;
  1173. }
  1174. Sleep(1500);
  1175. hcom = open_port(comid_ports, TRUE);
  1176. if (hcom == INVALID_HANDLE_VALUE) {
  1177. MessageBox(NULL, L"Impossible d'acceder au port du pilote intermediaire",
  1178. TEXT("Evadeo Affix"), MB_OK);
  1179. DestroyWindow(h_wnd);
  1180. UnregisterClass(wnd_cls.lpszClassName, NULL);
  1181. restore_taskbar();
  1182. return 1;
  1183. }
  1184. Sleep(1500);
  1185. SendMessage(h_test, WM_SETTEXT, 0, (LPARAM) L"Chargement des éphémérides...");
  1186. if (GetMessageW(&msg, NULL, 0, 0)) {
  1187. TranslateMessage(&msg);
  1188. DispatchMessage(&msg);
  1189. }
  1190. CloseHandle(hcom);
  1191. SendMessage(h_test, WM_SETTEXT, 0, (LPARAM) L"Tracking...");
  1192. if (GetMessageW(&msg, NULL, 0, 0)) {
  1193. TranslateMessage(&msg);
  1194. DispatchMessage(&msg);
  1195. }
  1196. Sleep(1500);
  1197. hcom = open_port(sirf_ports, TRUE);
  1198. if (hcom == INVALID_HANDLE_VALUE) {
  1199. MessageBox(NULL, L"Impossible d'acceder au port SiRF (tracking)",
  1200. TEXT("Evadeo Affix"), MB_OK);
  1201. DestroyWindow(h_wnd);
  1202. UnregisterClass(wnd_cls.lpszClassName, NULL);
  1203. restore_taskbar();
  1204. return 1;
  1205. }
  1206. #if 1
  1207. DestroyWindow(h_test);
  1208. #endif
  1209. global_hcom = hcom;
  1210. timer = SetTimer(h_wnd, 1, FRAME_RATE, NULL);
  1211. while (GetMessage(&msg, NULL, 0, 0)) {
  1212. TranslateMessage(&msg);
  1213. DispatchMessage(&msg);
  1214. }
  1215. PurgeComm(hcom, PURGE_RXCLEAR);
  1216. CloseHandle(hcom);
  1217. Sleep(1000);
  1218. hcom = open_port(comid_ports, TRUE);
  1219. if (hcom == INVALID_HANDLE_VALUE) {
  1220. MessageBox(NULL, L"Impossible d'acceder au port du pilote intermediaire",
  1221. TEXT("Evadeo Affix"), MB_OK);
  1222. DestroyWindow(h_wnd);
  1223. UnregisterClass(wnd_cls.lpszClassName, NULL);
  1224. restore_taskbar();
  1225. return 1;
  1226. }
  1227. DestroyWindow(h_wnd);
  1228. PurgeComm(hcom, PURGE_RXCLEAR);
  1229. PurgeComm(hcom, PURGE_TXCLEAR);
  1230. Sleep(500);
  1231. PurgeComm(hcom, PURGE_RXCLEAR);
  1232. CloseHandle(hcom);
  1233. UnregisterClass(wnd_cls.lpszClassName, NULL);
  1234. restore_taskbar();
  1235. return 0;
  1236. }