commhub.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. /*
  2. * Copyright (c) 2019 Clementine Computing LLC.
  3. *
  4. * This file is part of PopuFare.
  5. *
  6. * PopuFare is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * PopuFare is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Affero General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Affero General Public License
  17. * along with PopuFare. If not, see <https://www.gnu.org/licenses/>.
  18. *
  19. */
  20. //Check to make sure we haven't already defined these things
  21. #ifndef _COMMHUB_API
  22. #define _COMMHUB_API (1)
  23. #define MSG_NO_ACTION (0)
  24. #define MSG_ERROR (-1)
  25. #define MSG_SEND (POLLOUT)
  26. #define MSG_RECV (POLLIN)
  27. #define TOTAL_MESSAGE_SIZE (0x1000) //Each message can be a maximum of 4K including header
  28. //This is the maximum lenght of a mailbox name (excluding the terminating NUL)
  29. //The mailbox name field will always be one longer than this value to accomodate the NUL.
  30. #define MAILBOX_NAME_MAX (31)
  31. //The message_header_record structure contains the timestamp, routing, and data size for a message
  32. //being passed either client->server or server->client
  33. struct message_header_record
  34. {
  35. long long int usec_time; //When the message was sent
  36. char mailbox_name[MAILBOX_NAME_MAX + 1]; //What mailbox was it sent to?
  37. unsigned int payload_length; //How many octets of the payload are populated?
  38. pid_t sender; //The PID of the sender
  39. int from_fd; //The file descriptor of the IPC socket the message came in on
  40. };
  41. //This is convenient because it allows the total message length to be something sane including the header.
  42. #define MAX_PAYLOAD_LENGTH ((TOTAL_MESSAGE_SIZE - sizeof(char)) - sizeof(struct message_header_record))
  43. #define MAX_MODULE_NAME_LENGTH (1024)
  44. //The message_record structure is what is passed from client to server to send a message out to a mailbox
  45. //The same structure is passed from the server to each client that has a subscription to the mailbox
  46. struct message_record
  47. {
  48. struct message_header_record header;
  49. unsigned char payload[MAX_PAYLOAD_LENGTH];
  50. unsigned char nul;
  51. };
  52. typedef struct message_record message;
  53. //This defines the number of supported client sockets. We will have to replace our flat lists with hashes or trees
  54. //long before we hit this limit. We would also need a hell of a lot more RAM than exists on a viper to have this
  55. //many meaningful processes
  56. #define NUM_SUPPORTED_CLIENTS (128)
  57. //The subscriber_record structure is a linear linked list of file descriptors represinting all of the
  58. //clients who have subscribed to any given mailbox
  59. struct subscriber_record
  60. {
  61. int clientfd;
  62. pid_t pid;
  63. char progname[MAX_MODULE_NAME_LENGTH];
  64. struct subscriber_record *next;
  65. };
  66. typedef struct subscriber_record subscriber;
  67. //The mailbox_record structure holds a mailbox name and a list of subscribers
  68. struct mailbox_record
  69. {
  70. char mailbox_name[MAILBOX_NAME_MAX + 1];
  71. struct subscriber_record *clients;
  72. struct mailbox_record *next;
  73. };
  74. //This function creates a connection to the message server and returns a file descriptor
  75. //the progname parameter should be passed argv[0] to make it easier for anybody listening
  76. //in on the server side to identify which module corresponds to which PID, but it is acceptable
  77. //to pass NULL if this information is not available or this functionality not desired.
  78. int connect_to_message_server(char *progname);
  79. //This function gets the number of microseconds since epoch for storing in message headers and
  80. //comparison to determine how timely a message is.
  81. long long int get_usec_time();
  82. //This function does a non-blocking poll to determine if the message passing socket is
  83. //ready for input or output (depending on
  84. //since it is much more efficient to block on the entire list of your I/O file descriptors
  85. //and service any that cause you to unblock.
  86. //
  87. // Returns: MSG_NO_ACTION = no message
  88. // MSG_ERROR = fatal error (passed fd is no good)
  89. //
  90. // If the socket is ready, the return value will be
  91. // whatever combination of events specified in mask (MSG_SEND, MSG_RECV)
  92. // that is actually ready.
  93. //
  94. int message_socket_status(int message_socket_fd, int mask);
  95. //this function will pack a mailbox address and a payload into the supplied message structure and
  96. //set the correct timestamp.
  97. int prepare_message(struct message_record *target, char *mailbox, void *payload, unsigned int payload_len);
  98. //the send_message function will transmit a message and its header (trimmed to the specified payload length).
  99. //zero will be returned on success, -1 on failure.
  100. int send_message(int message_socket_fd, struct message_record *message);
  101. //the get_message function will receive a message from the opposite end of the socket and place it in the
  102. //supplied message structure incliding its header. -1 is returned on failure, 0 on success.
  103. int get_message(int message_socket_fd, struct message_record *message);
  104. //This is a utility function to get the number of microseconds since the epoch
  105. long long int get_usec_time();
  106. //------------------------------------------------ SPECIAL MAILBOXES
  107. #define MAILBOX_HELLO "_HELLO"
  108. #define MAILBOX_SUBSCRIBE "_SUBSCRIBE"
  109. #define MAILBOX_UNSUBSCRIBE "_UNSUBSCRIBE"
  110. #define MAILBOX_BROADCAST "_BROADCAST"
  111. #define MAILBOX_WIRETAP "_WIRETAP"
  112. #define MAILBOX_ERROR "_ERROR"
  113. //------------------------------------------------ MAILBOXES USED FOR COMMUNICATION BETWEEN MODULES
  114. //--------- PROCESS STATUS RELATED
  115. #define MAILBOX_PING "_PING" //A process should ALWAYS respond to this message. The payload will be echoed back
  116. //in the PONG message, so sticking a unique identifier (or sequence number) in there may be useful
  117. #define MAILBOX_PONG "_PONG" //A PONG message is the appropriate respoonse to the above PING message.
  118. #define MAILBOX_EXIT "_EXIT" //A process should catch this message and make a graceful exit
  119. #define MAILBOX_HUP "_HUP" //A process should catch this and reload its config file
  120. //--------- SYSTEM STATUS RELATED
  121. #define MAILBOX_STATUS_REQUEST "STATUS_REQ" //Requests all modules report their status
  122. #define MAILBOX_PASS_STATUS "PASS_STATUS" //This message indicates the current passdb status. Payload is struct pass_status_struct
  123. #define MAILBOX_BILL_STATUS "BILL_STATUS" //This message indicates the current billdb status. Payload is struct bill_status_struct
  124. #define MAILBOX_DRIVER_STATUS "DRIVER_STATUS" //This message indicates the current driver login status. Payload is struct driver_status_struct
  125. #define MAILBOX_GPS_STATUS "GPS_STATUS" //This mailbox indicates that there is a new GPS datum available. Payload is struct gps_status_struct
  126. #define MAILBOX_STOP_STATUS "STOP_STATUS" //This mailbox indicates that there is a new bus stop arrival event. Payload is stop_status_struct
  127. //--------- ACTION MESSAGES
  128. #define MAILBOX_TOKEN_MAG "TOKEN_MAG" //A Magstripe has been presented. Parameter is the magstripe output
  129. #define MAILBOX_TOKEN_RFID "TOKEN_RFID" //An RFID card has been presented. Parameter is the RFID output
  130. #define MAILBOX_FLUSH_PASSES "FLUSH_PASSES" //A request has been made to flush the pass database
  131. #define MAILBOX_UPDATE_PASSES "UPDATE_PASSES" //A request has been made to try to update the pass database
  132. #define MAILBOX_DRIVER_NOTIFY "DRIVER_NOTIFY" //A message is being transmitted to the user
  133. #define MAILBOX_BILLING_LOG "BILLING_LOG" //A billing long entry is ready to dispatch
  134. #define MAILBOX_PIU_MESSAGE "PIU_MESSAGE" //A message to display on line 0 of the PIU. Payload is piu_message_struct
  135. #define MAILBOX_SET_PADDLE "SET_PADDLE" //A message to request a paddle change. Payload is set_paddle_req_struct
  136. #define MAILBOX_PADDLE_ACK "PADDLE_ACK" //A reply to the above message. Payload is the same, but with result field populated.
  137. #define MAILBOX_NEXT_STOP "NEXT_STOP" //Request to advance to the next stop on the paddle
  138. #define MAILBOX_PREV_STOP "PREV_STOP" //Request to advance to the previous stop on the paddle
  139. #define MAILBOX_RULE_CALL "RULE_CALL" //Request the passdb module to execute a rule. Payload is driver_rulecall_struct
  140. #define MAILBOX_VAULT_DROP "VAULT_DROP" //Request the cash vault drop
  141. #define MAILBOX_PASSDB_CONSISTENCY "PASSDB_CONSIST" //Have the passdb do a consistency check
  142. #define MAILBOX_PASSDB_PULSE "PASSDB_PULSE" //Generate a 'pulse' string to stderr
  143. //------------------------------------------------ MESSAGE BODY DATA STRUCTURES
  144. typedef struct gps_status_struct
  145. {
  146. //GPS location data
  147. double lat, lon, heading, velocity;
  148. //GPS Quality data
  149. int num_sats; //Number of sats in view
  150. int gps_good; //GPS fix considered valid
  151. time_t stamp; //System timestamp at last valid received fix
  152. time_t gpstime; //GPS timestamp from last valid received GPS time
  153. } gps_status;
  154. #define STOP_NAME_LEN (64)
  155. typedef struct stop_status_struct
  156. {
  157. //Paddle data
  158. int paddle;
  159. //Current stop data
  160. int route, trip, stop;
  161. double lat,lon;
  162. char stopname[STOP_NAME_LEN];
  163. } stop_status;
  164. #define DRIVER_NAME_LEN (64)
  165. typedef struct driver_status_struct
  166. {
  167. //Information on the currently logged in driver
  168. int logged_in_driver;
  169. char driver_name[DRIVER_NAME_LEN];
  170. //Information on the current equipment number
  171. int equip_num;
  172. } driver_status;
  173. #define PIU_PRIORITY_NOTIFY (100)
  174. #define PIU_PRIORITY_FARE (200)
  175. #define PIU_MESSAGE_LEN (64) //this is optimistic since our display is only 20 characters wide...
  176. typedef struct piu_message_struct
  177. {
  178. //If this message is of greater or equal priority than the currently displayed one, it will clobber it
  179. int priority;
  180. //Which line do we want to display this on?
  181. int line;
  182. //And for how long? 0 seconds = set default for that line
  183. int seconds;
  184. //And now for the actual message...
  185. char message[PIU_MESSAGE_LEN];
  186. } piu_message;
  187. #define FLUSH_STATUS_NORMAL (0) //we are not in the process of a flush operation
  188. #define FLUSH_STATUS_LEGACY (1) //we are in the process of an old-style flush, pass checking won't work
  189. #define FLUSH_STATUS_DOWNLOAD (2) //we are in the process of downloading a ZFLUSH datablob, pass checking will work with old database
  190. #define FLUSH_STATUS_APPLY (3) //we are in the process of applying a downloaded ZFLUSH datablob, pass checking won't work
  191. #define FLUSH_STATUS_WRITE (4) //we are done applying, but waiting for the disk write to complete, pass checking won't work
  192. #define PASSDB_OPERABLE(x) ( ((x) == FLUSH_STATUS_NORMAL) || ((x) == FLUSH_STATUS_DOWNLOAD) )
  193. typedef struct pass_status_struct
  194. {
  195. //This indicates what our flush status is
  196. int flush_status;
  197. //This is a generic progress bar counter, expected to be in the range of 0-100 (for percent).
  198. int progress_indicator;
  199. //Last server contact
  200. time_t last_sync_time;
  201. time_t last_ack_time;
  202. } pass_status;
  203. typedef struct bill_status_struct
  204. {
  205. //Last server contact
  206. time_t last_sync_time;
  207. time_t last_ack_time;
  208. //Number of undelivered billing / log messages bound for the server
  209. int unsynced_messages;
  210. } bill_status;
  211. typedef struct set_paddle_req_struct
  212. {
  213. int request;
  214. int result;
  215. } set_paddle_req;
  216. #define DRIVER_RULECALL_LEN (24)
  217. typedef struct driver_rulecall_struct
  218. {
  219. char rulename[DRIVER_RULECALL_LEN];
  220. char ruleparam[DRIVER_RULECALL_LEN];
  221. } driver_rulecall;
  222. #define STATE_INFO_FIELD_SIZE (64)
  223. typedef struct state_info_struct {
  224. double lat, lon, heading, velocity;
  225. int num_sats;
  226. int gps_good;
  227. time_t stamp;
  228. time_t gpstime;
  229. int paddle;
  230. int route, trip, stop;
  231. double stop_lat, stop_lon;
  232. char stopname[STATE_INFO_FIELD_SIZE];
  233. int logged_in_driver;
  234. char driver_name[STATE_INFO_FIELD_SIZE];
  235. int equip_num;
  236. char comment[STATE_INFO_FIELD_SIZE];
  237. } state_info_t;
  238. int get_state_info(state_info_t *);
  239. int set_state_info(state_info_t *);
  240. int print_state_info(state_info_t *);
  241. #endif //#ifdef _TRANSIT_COMMHUB_API