monitor_proto.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. * Prototype file for a gpsmon monitor object.
  3. *
  4. * This file is Copyright 2010 by the GPSD project
  5. * SPDX-License-Identifier: BSD-2-clause
  6. */
  7. #include "gpsd_config.h" /* must be before all includes */
  8. #include <assert.h>
  9. #include <ctype.h>
  10. #include <math.h>
  11. #include <stdarg.h>
  12. #include <stdbool.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <unistd.h>
  17. #include "gpsd.h"
  18. #include "bits.h"
  19. #include "gpsmon.h"
  20. /*
  21. * Replace PROTO everywhere with the name of the GPSD driver describing
  22. * the device you want to support.
  23. *
  24. * gpsmon basically sits in a loop reading packets, using the same layer
  25. * as gpsd to dispatch on packet type to select an active device driver.
  26. * Your monitor object will become the handler for incoming packets whenever
  27. * the driver your object points at is selected.
  28. *
  29. * A comment following the method descriptions explains some available
  30. * helper functions.
  31. */
  32. extern const struct gps_type_t driver__proto_;
  33. static bool PROTO_initialize(void)
  34. {
  35. /*
  36. * This function is called when your monitor object is activated.
  37. *
  38. * When you enter it, two windows will be accessible to you; (1)
  39. * devicewin, just below the status and command line at top of
  40. * screen, and (2) packetwin, taking up the rest of the screen below
  41. * it; packetwin will be enabled for scrolling. Note, however,
  42. * that you cannot necessarily update packetwin safely, as it may be NULL
  43. * if the screen has no lines left over after allocating devicewin;
  44. * you'll need to check this in your code.
  45. *
  46. * Use this method to paint windowframes and legends on the
  47. * freshly initialized device window. You can also use this
  48. * method to send probes to the device, e.g. to elicit a response
  49. * telling you firmware rev levels or whatever.
  50. */
  51. /* return false if the window allocation failed; gpsmon will abort */
  52. return true;
  53. }
  54. static void PROTO_update(void)
  55. {
  56. /*
  57. * Called on each packet received. The packet will be accessible in
  58. * session.lexer.outbuffer and the length in session.lexer.outbuflen.
  59. * If the device is NMEA, session.driver.nmea.fields[] will contain the
  60. * array of unconverted field strings, including the tag in slot zero
  61. * but not including the checksum or trailing \r\n.
  62. *
  63. * Use this function to update devicewin. The packet will be echoed to
  64. * packetwin immediately after this function is called; you can use this
  65. * function to write a prefix on the line.
  66. *
  67. * Helpers available include (1) toff_update, for throwing the
  68. * TOFF data from the last time fix on the screen, and (2)
  69. * pps_update, for throwing the PPS data from the last 1PPS event on
  70. * the screen, and
  71. */
  72. }
  73. static int PROTO_command(char line[])
  74. {
  75. /*
  76. * Interpret a command line. Whatever characters the user types will
  77. * be echoed in the command buffer at the top right of the display. When
  78. * he/she presses enter the command line will be passed to this function
  79. * for interpretation. Note: packet receipt is suspended while this
  80. * function is executing.
  81. *
  82. * This method is optional. If you set the command method pointer to
  83. * NULL, gpsmon will behave sanely, accepting no device-specific commands.
  84. *
  85. * It is a useful convention to use uppercase letters for
  86. * driver-specific commands and leave lowercase ones for the
  87. * generic gpsmon ones.
  88. */
  89. assert(strlen(line));
  90. /*
  91. * Return COMMAND_UNKNOWN to tell gpsmon you can't interpret the line, and
  92. * it will be passed to the generic command interpreter to be handled there.
  93. * You can also return COMMAND_MATCH to tell it you handled the command,
  94. * or COMMAND_TERMINATE to tell gpsmon you handled it and gpsmon should
  95. * terminate.
  96. */
  97. return COMMAND_UNKNOWN;
  98. }
  99. static void PROTO_wrap(void)
  100. {
  101. /*
  102. * Deinitialize any windows you created in PROTO_initialize.
  103. * This will be called when gpsmon switches drivers due to seeing
  104. * a new packet type.
  105. */
  106. }
  107. /*
  108. * Use mmt = monitor method table as a suffix for naming these things
  109. * Yours will need to be added to the monitor_objects table in gpsmon.c,
  110. * then of course you need to link your module into gpsmon.
  111. */
  112. const struct monitor_object_t PROTO_mmt = {
  113. .initialize = PROTO_initialize,
  114. .update = PROTO_update,
  115. .command = PROTO_command,
  116. .wrap = PROTO_wrap,
  117. .min_y = 23, .min_x = 80, /* size of the device window */
  118. /*
  119. * The gpsd driver type for your device. gpsmon will use the mode_switcher
  120. * method for 'n', the speed_switcher for 's', and the control_send method
  121. * for 'c'. Additionally, the driver type name will be displayed before
  122. * the '>' command prompt in the top line of the display.
  123. */
  124. .driver = &PROTO_binary,
  125. };
  126. /*
  127. * Helpers:
  128. *
  129. * bool monitor_control_send(unsigned char *buf, size_t len)
  130. * Ship a packet payload to the device. Calls the driver send_control()
  131. * method to add headers/trailers/checksum; also dumps the sent
  132. * packet to the packet window, if the send_control() is playing
  133. * nice by using session.msgbuf to assemble the message.
  134. *
  135. * void monitor_log(const char *fmt, ...)
  136. * Write a message to the packet window. Safe if the packet window
  137. * is not on screen.
  138. *
  139. * void monitor_complain(const char *fmt, ...)
  140. * Post an error message to the command window, wait till user presses a key.
  141. * You get to make sure the message will fit.
  142. *
  143. * void monitor_fixframe(WINDOW *win)
  144. * Fix the frame of win to the right of the current location by redrawing
  145. * ACS_VLINE there. Useful after doing wclrtoeol() and writing on the
  146. * line.
  147. *
  148. * The libgpsd session object is accessible as the global variable 'session'.
  149. */
  150. // vim: set expandtab shiftwidth=4