| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- /*
- * Copyright (c) 2019 Clementine Computing LLC.
- *
- * This file is part of PopuFare.
- *
- * PopuFare is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * PopuFare is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with PopuFare. If not, see <https://www.gnu.org/licenses/>.
- *
- */
- //Check to make sure we haven't already defined these things
- #ifndef _COMMHUB_API
- #define _COMMHUB_API (1)
- #define MSG_NO_ACTION (0)
- #define MSG_ERROR (-1)
- #define MSG_SEND (POLLOUT)
- #define MSG_RECV (POLLIN)
- #define TOTAL_MESSAGE_SIZE (0x1000) //Each message can be a maximum of 4K including header
- //This is the maximum lenght of a mailbox name (excluding the terminating NUL)
- //The mailbox name field will always be one longer than this value to accomodate the NUL.
- #define MAILBOX_NAME_MAX (31)
- //The message_header_record structure contains the timestamp, routing, and data size for a message
- //being passed either client->server or server->client
- struct message_header_record
- {
- long long int usec_time; //When the message was sent
- char mailbox_name[MAILBOX_NAME_MAX + 1]; //What mailbox was it sent to?
- unsigned int payload_length; //How many octets of the payload are populated?
- pid_t sender; //The PID of the sender
- int from_fd; //The file descriptor of the IPC socket the message came in on
- };
- //This is convenient because it allows the total message length to be something sane including the header.
- #define MAX_PAYLOAD_LENGTH ((TOTAL_MESSAGE_SIZE - sizeof(char)) - sizeof(struct message_header_record))
- #define MAX_MODULE_NAME_LENGTH (1024)
- //The message_record structure is what is passed from client to server to send a message out to a mailbox
- //The same structure is passed from the server to each client that has a subscription to the mailbox
- struct message_record
- {
- struct message_header_record header;
- unsigned char payload[MAX_PAYLOAD_LENGTH];
- unsigned char nul;
- };
- typedef struct message_record message;
- //This defines the number of supported client sockets. We will have to replace our flat lists with hashes or trees
- //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
- //many meaningful processes
- #define NUM_SUPPORTED_CLIENTS (128)
- //The subscriber_record structure is a linear linked list of file descriptors represinting all of the
- //clients who have subscribed to any given mailbox
- struct subscriber_record
- {
- int clientfd;
- pid_t pid;
- char progname[MAX_MODULE_NAME_LENGTH];
- struct subscriber_record *next;
- };
- typedef struct subscriber_record subscriber;
- //The mailbox_record structure holds a mailbox name and a list of subscribers
- struct mailbox_record
- {
- char mailbox_name[MAILBOX_NAME_MAX + 1];
- struct subscriber_record *clients;
-
- struct mailbox_record *next;
- };
- //This function creates a connection to the message server and returns a file descriptor
- //the progname parameter should be passed argv[0] to make it easier for anybody listening
- //in on the server side to identify which module corresponds to which PID, but it is acceptable
- //to pass NULL if this information is not available or this functionality not desired.
- int connect_to_message_server(char *progname);
- //This function gets the number of microseconds since epoch for storing in message headers and
- //comparison to determine how timely a message is.
- long long int get_usec_time();
- //This function does a non-blocking poll to determine if the message passing socket is
- //ready for input or output (depending on
- //since it is much more efficient to block on the entire list of your I/O file descriptors
- //and service any that cause you to unblock.
- //
- // Returns: MSG_NO_ACTION = no message
- // MSG_ERROR = fatal error (passed fd is no good)
- //
- // If the socket is ready, the return value will be
- // whatever combination of events specified in mask (MSG_SEND, MSG_RECV)
- // that is actually ready.
- //
- int message_socket_status(int message_socket_fd, int mask);
- //this function will pack a mailbox address and a payload into the supplied message structure and
- //set the correct timestamp.
- int prepare_message(struct message_record *target, char *mailbox, void *payload, unsigned int payload_len);
- //the send_message function will transmit a message and its header (trimmed to the specified payload length).
- //zero will be returned on success, -1 on failure.
- int send_message(int message_socket_fd, struct message_record *message);
- //the get_message function will receive a message from the opposite end of the socket and place it in the
- //supplied message structure incliding its header. -1 is returned on failure, 0 on success.
- int get_message(int message_socket_fd, struct message_record *message);
- //This is a utility function to get the number of microseconds since the epoch
- long long int get_usec_time();
- //------------------------------------------------ SPECIAL MAILBOXES
- #define MAILBOX_HELLO "_HELLO"
- #define MAILBOX_SUBSCRIBE "_SUBSCRIBE"
- #define MAILBOX_UNSUBSCRIBE "_UNSUBSCRIBE"
- #define MAILBOX_BROADCAST "_BROADCAST"
- #define MAILBOX_WIRETAP "_WIRETAP"
- #define MAILBOX_ERROR "_ERROR"
- //------------------------------------------------ MAILBOXES USED FOR COMMUNICATION BETWEEN MODULES
- //--------- PROCESS STATUS RELATED
- #define MAILBOX_PING "_PING" //A process should ALWAYS respond to this message. The payload will be echoed back
- //in the PONG message, so sticking a unique identifier (or sequence number) in there may be useful
- #define MAILBOX_PONG "_PONG" //A PONG message is the appropriate respoonse to the above PING message.
- #define MAILBOX_EXIT "_EXIT" //A process should catch this message and make a graceful exit
- #define MAILBOX_HUP "_HUP" //A process should catch this and reload its config file
- //--------- SYSTEM STATUS RELATED
- #define MAILBOX_STATUS_REQUEST "STATUS_REQ" //Requests all modules report their status
- #define MAILBOX_PASS_STATUS "PASS_STATUS" //This message indicates the current passdb status. Payload is struct pass_status_struct
- #define MAILBOX_BILL_STATUS "BILL_STATUS" //This message indicates the current billdb status. Payload is struct bill_status_struct
- #define MAILBOX_DRIVER_STATUS "DRIVER_STATUS" //This message indicates the current driver login status. Payload is struct driver_status_struct
- #define MAILBOX_GPS_STATUS "GPS_STATUS" //This mailbox indicates that there is a new GPS datum available. Payload is struct gps_status_struct
- #define MAILBOX_STOP_STATUS "STOP_STATUS" //This mailbox indicates that there is a new bus stop arrival event. Payload is stop_status_struct
-
- //--------- ACTION MESSAGES
- #define MAILBOX_TOKEN_MAG "TOKEN_MAG" //A Magstripe has been presented. Parameter is the magstripe output
- #define MAILBOX_TOKEN_RFID "TOKEN_RFID" //An RFID card has been presented. Parameter is the RFID output
- #define MAILBOX_FLUSH_PASSES "FLUSH_PASSES" //A request has been made to flush the pass database
- #define MAILBOX_UPDATE_PASSES "UPDATE_PASSES" //A request has been made to try to update the pass database
- #define MAILBOX_DRIVER_NOTIFY "DRIVER_NOTIFY" //A message is being transmitted to the user
- #define MAILBOX_BILLING_LOG "BILLING_LOG" //A billing long entry is ready to dispatch
- #define MAILBOX_PIU_MESSAGE "PIU_MESSAGE" //A message to display on line 0 of the PIU. Payload is piu_message_struct
- #define MAILBOX_SET_PADDLE "SET_PADDLE" //A message to request a paddle change. Payload is set_paddle_req_struct
- #define MAILBOX_PADDLE_ACK "PADDLE_ACK" //A reply to the above message. Payload is the same, but with result field populated.
- #define MAILBOX_NEXT_STOP "NEXT_STOP" //Request to advance to the next stop on the paddle
- #define MAILBOX_PREV_STOP "PREV_STOP" //Request to advance to the previous stop on the paddle
- #define MAILBOX_RULE_CALL "RULE_CALL" //Request the passdb module to execute a rule. Payload is driver_rulecall_struct
- #define MAILBOX_VAULT_DROP "VAULT_DROP" //Request the cash vault drop
- #define MAILBOX_PASSDB_CONSISTENCY "PASSDB_CONSIST" //Have the passdb do a consistency check
- #define MAILBOX_PASSDB_PULSE "PASSDB_PULSE" //Generate a 'pulse' string to stderr
- //------------------------------------------------ MESSAGE BODY DATA STRUCTURES
- typedef struct gps_status_struct
- {
- //GPS location data
- double lat, lon, heading, velocity;
-
- //GPS Quality data
- int num_sats; //Number of sats in view
- int gps_good; //GPS fix considered valid
- time_t stamp; //System timestamp at last valid received fix
- time_t gpstime; //GPS timestamp from last valid received GPS time
-
- } gps_status;
- #define STOP_NAME_LEN (64)
- typedef struct stop_status_struct
- {
- //Paddle data
- int paddle;
-
- //Current stop data
- int route, trip, stop;
- double lat,lon;
- char stopname[STOP_NAME_LEN];
- } stop_status;
- #define DRIVER_NAME_LEN (64)
- typedef struct driver_status_struct
- {
- //Information on the currently logged in driver
- int logged_in_driver;
- char driver_name[DRIVER_NAME_LEN];
- //Information on the current equipment number
- int equip_num;
- } driver_status;
- #define PIU_PRIORITY_NOTIFY (100)
- #define PIU_PRIORITY_FARE (200)
- #define PIU_MESSAGE_LEN (64) //this is optimistic since our display is only 20 characters wide...
- typedef struct piu_message_struct
- {
- //If this message is of greater or equal priority than the currently displayed one, it will clobber it
- int priority;
-
- //Which line do we want to display this on?
- int line;
-
- //And for how long? 0 seconds = set default for that line
- int seconds;
-
- //And now for the actual message...
- char message[PIU_MESSAGE_LEN];
- } piu_message;
- #define FLUSH_STATUS_NORMAL (0) //we are not in the process of a flush operation
- #define FLUSH_STATUS_LEGACY (1) //we are in the process of an old-style flush, pass checking won't work
- #define FLUSH_STATUS_DOWNLOAD (2) //we are in the process of downloading a ZFLUSH datablob, pass checking will work with old database
- #define FLUSH_STATUS_APPLY (3) //we are in the process of applying a downloaded ZFLUSH datablob, pass checking won't work
- #define FLUSH_STATUS_WRITE (4) //we are done applying, but waiting for the disk write to complete, pass checking won't work
- #define PASSDB_OPERABLE(x) ( ((x) == FLUSH_STATUS_NORMAL) || ((x) == FLUSH_STATUS_DOWNLOAD) )
- typedef struct pass_status_struct
- {
- //This indicates what our flush status is
- int flush_status;
-
- //This is a generic progress bar counter, expected to be in the range of 0-100 (for percent).
- int progress_indicator;
- //Last server contact
- time_t last_sync_time;
- time_t last_ack_time;
-
- } pass_status;
- typedef struct bill_status_struct
- {
- //Last server contact
- time_t last_sync_time;
- time_t last_ack_time;
-
-
- //Number of undelivered billing / log messages bound for the server
- int unsynced_messages;
-
- } bill_status;
- typedef struct set_paddle_req_struct
- {
- int request;
- int result;
- } set_paddle_req;
- #define DRIVER_RULECALL_LEN (24)
- typedef struct driver_rulecall_struct
- {
- char rulename[DRIVER_RULECALL_LEN];
- char ruleparam[DRIVER_RULECALL_LEN];
- } driver_rulecall;
- #define STATE_INFO_FIELD_SIZE (64)
- typedef struct state_info_struct {
- double lat, lon, heading, velocity;
- int num_sats;
- int gps_good;
- time_t stamp;
- time_t gpstime;
- int paddle;
- int route, trip, stop;
- double stop_lat, stop_lon;
- char stopname[STATE_INFO_FIELD_SIZE];
- int logged_in_driver;
- char driver_name[STATE_INFO_FIELD_SIZE];
- int equip_num;
- char comment[STATE_INFO_FIELD_SIZE];
- } state_info_t;
- int get_state_info(state_info_t *);
- int save_state_info(state_info_t *);
- int print_state_info(state_info_t *);
- #endif //#ifdef _TRANSIT_COMMHUB_API
|