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