net_dgpsip.c 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /* net_dgpsip.c -- gather and dispatch DGPS data from DGPSIP servers
  2. *
  3. * This file is Copyright 2010 by the GPSD project
  4. * SPDX-License-Identifier: BSD-2-clause
  5. */
  6. #include "gpsd_config.h" /* must be before all includes */
  7. #include <fcntl.h>
  8. #include <netdb.h>
  9. #include <stdbool.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <sys/socket.h>
  14. #include <sys/types.h>
  15. #include <unistd.h>
  16. #include "gpsd.h"
  17. int dgpsip_open(struct gps_device_t *device, const char *dgpsserver)
  18. /* open a connection to a DGPSIP server */
  19. {
  20. char *colon, *dgpsport = "rtcm-sc104";
  21. int opts;
  22. device->dgpsip.reported = false;
  23. if ((colon = strchr(dgpsserver, ':')) != NULL) {
  24. dgpsport = colon + 1;
  25. *colon = '\0';
  26. }
  27. if (!getservbyname(dgpsport, "tcp"))
  28. dgpsport = DEFAULT_RTCM_PORT;
  29. device->gpsdata.gps_fd =
  30. netlib_connectsock(AF_UNSPEC, dgpsserver, dgpsport, "tcp");
  31. // cppcheck-suppress pointerPositive
  32. if (device->gpsdata.gps_fd >= 0) {
  33. char hn[256], buf[BUFSIZ];
  34. GPSD_LOG(LOG_PROG, &device->context->errout,
  35. "connection to DGPS server %s established.\n",
  36. dgpsserver);
  37. (void)gethostname(hn, sizeof(hn));
  38. /* greeting required by some RTCM104 servers; others will ignore it */
  39. (void)snprintf(buf, sizeof(buf), "HELO %s gpsd %s\r\nR\r\n", hn,
  40. VERSION);
  41. if (write(device->gpsdata.gps_fd, buf, strlen(buf)) !=
  42. (ssize_t) strlen(buf))
  43. GPSD_LOG(LOG_ERROR, &device->context->errout,
  44. "hello to DGPS server %s failed\n",
  45. dgpsserver);
  46. } else
  47. GPSD_LOG(LOG_ERROR, &device->context->errout,
  48. "can't connect to DGPS server %s, netlib error %d.\n",
  49. dgpsserver, device->gpsdata.gps_fd);
  50. opts = fcntl(device->gpsdata.gps_fd, F_GETFL);
  51. if (opts >= 0)
  52. (void)fcntl(device->gpsdata.gps_fd, F_SETFL, opts | O_NONBLOCK);
  53. device->servicetype = service_dgpsip;
  54. return device->gpsdata.gps_fd;
  55. }
  56. void dgpsip_report(struct gps_context_t *context,
  57. struct gps_device_t *gps,
  58. struct gps_device_t *dgpsip)
  59. /* may be time to ship a usage report to the DGPSIP server */
  60. {
  61. /*
  62. * 10 is an arbitrary number, the point is to have gotten several good
  63. * fixes before reporting usage to our DGPSIP server.
  64. */
  65. if (context->fixcnt > 10 && !dgpsip->dgpsip.reported) {
  66. dgpsip->dgpsip.reported = true;
  67. if (dgpsip->gpsdata.gps_fd > -1) {
  68. char buf[BUFSIZ];
  69. (void)snprintf(buf, sizeof(buf), "R %0.8f %0.8f %0.2f\r\n",
  70. gps->gpsdata.fix.latitude,
  71. gps->gpsdata.fix.longitude,
  72. gps->gpsdata.fix.altMSL);
  73. if (write(dgpsip->gpsdata.gps_fd, buf, strlen(buf)) ==
  74. (ssize_t) strlen(buf))
  75. GPSD_LOG(LOG_IO, &context->errout, "=> dgps %s\n", buf);
  76. else
  77. GPSD_LOG(LOG_IO, &context->errout, "write to dgps FAILED\n");
  78. }
  79. }
  80. }
  81. // vim: set expandtab shiftwidth=4