|
@@ -2,17 +2,17 @@
|
|
|
* Copyright (c) 2019 Clementine Computing LLC.
|
|
* Copyright (c) 2019 Clementine Computing LLC.
|
|
|
*
|
|
*
|
|
|
* This file is part of PopuFare.
|
|
* This file is part of PopuFare.
|
|
|
- *
|
|
|
|
|
|
|
+ *
|
|
|
* PopuFare is free software: you can redistribute it and/or modify
|
|
* 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
|
|
* 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
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
* (at your option) any later version.
|
|
* (at your option) any later version.
|
|
|
- *
|
|
|
|
|
|
|
+ *
|
|
|
* PopuFare is distributed in the hope that it will be useful,
|
|
* PopuFare is distributed in the hope that it will be useful,
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
* GNU Affero General Public License for more details.
|
|
* GNU Affero General Public License for more details.
|
|
|
- *
|
|
|
|
|
|
|
+ *
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
* along with PopuFare. If not, see <https://www.gnu.org/licenses/>.
|
|
* along with PopuFare. If not, see <https://www.gnu.org/licenses/>.
|
|
|
*
|
|
*
|
|
@@ -42,16 +42,16 @@
|
|
|
|
|
|
|
|
typedef struct stop_struct //structure for loading stop definitions
|
|
typedef struct stop_struct //structure for loading stop definitions
|
|
|
{
|
|
{
|
|
|
- int hour; //scheduled arrival time
|
|
|
|
|
|
|
+ int hour; //scheduled arrival time
|
|
|
int min;
|
|
int min;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
double lat; //coordinates
|
|
double lat; //coordinates
|
|
|
double lon;
|
|
double lon;
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
int route; //route
|
|
int route; //route
|
|
|
int trip; //trip number
|
|
int trip; //trip number
|
|
|
int stop; //stop
|
|
int stop; //stop
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
char name[STOP_NAME_LEN]; //human readable stop name
|
|
char name[STOP_NAME_LEN]; //human readable stop name
|
|
|
|
|
|
|
|
} stop;
|
|
} stop;
|
|
@@ -68,424 +68,428 @@ stop current_paddle[MAX_PADDLE_SIZE] = {{0}}; //Data block to hold loaded paddl
|
|
|
|
|
|
|
|
int load_paddle(int paddlenum)
|
|
int load_paddle(int paddlenum)
|
|
|
{
|
|
{
|
|
|
- char buffer[LINE_BUFFER_SIZE];
|
|
|
|
|
- char buffer2[LINE_BUFFER_SIZE];
|
|
|
|
|
- FILE *f;
|
|
|
|
|
-
|
|
|
|
|
- int i, eol;
|
|
|
|
|
- int n;
|
|
|
|
|
-
|
|
|
|
|
- sprintf(buffer, "%s%d.paddle", CONFIG_FILE_PATH, paddlenum);
|
|
|
|
|
-
|
|
|
|
|
- f = fopen(buffer, "rb");
|
|
|
|
|
-
|
|
|
|
|
- if(!f)
|
|
|
|
|
- {
|
|
|
|
|
- printf("Paddle not found: %s\n", buffer);
|
|
|
|
|
- return -1;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ char buffer[LINE_BUFFER_SIZE];
|
|
|
|
|
+ char buffer2[LINE_BUFFER_SIZE];
|
|
|
|
|
+ FILE *f;
|
|
|
|
|
+
|
|
|
|
|
+ int i, eol;
|
|
|
|
|
+ int n;
|
|
|
|
|
|
|
|
- current_paddle_num = paddlenum;
|
|
|
|
|
- current_paddle_idx = 0;
|
|
|
|
|
- current_paddle_len = 0;
|
|
|
|
|
- n = 0;
|
|
|
|
|
|
|
+ sprintf(buffer, "%s%d.paddle", CONFIG_FILE_PATH, paddlenum);
|
|
|
|
|
|
|
|
- //For each line in the input file
|
|
|
|
|
- while( fgets(buffer, LINE_BUFFER_SIZE, f) )
|
|
|
|
|
|
|
+ f = fopen(buffer, "rb");
|
|
|
|
|
+
|
|
|
|
|
+ if(!f)
|
|
|
|
|
+ {
|
|
|
|
|
+ printf("Paddle not found: %s\n", buffer);
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ current_paddle_num = paddlenum;
|
|
|
|
|
+ current_paddle_idx = 0;
|
|
|
|
|
+ current_paddle_len = 0;
|
|
|
|
|
+ n = 0;
|
|
|
|
|
+
|
|
|
|
|
+ //For each line in the input file
|
|
|
|
|
+ while( fgets(buffer, LINE_BUFFER_SIZE, f) )
|
|
|
|
|
+ {
|
|
|
|
|
+ if(current_paddle_idx >= MAX_PADDLE_SIZE)
|
|
|
{
|
|
{
|
|
|
- if(current_paddle_idx >= MAX_PADDLE_SIZE)
|
|
|
|
|
- {
|
|
|
|
|
- fprintf(stderr, "Paddle %d has overflowed its maximum size of %d stops and has been truncated!\n", current_paddle_num, MAX_PADDLE_SIZE);
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- strip_crlf(buffer); //get rid of any trailing CR/LF characters
|
|
|
|
|
-
|
|
|
|
|
- n++;
|
|
|
|
|
-
|
|
|
|
|
- i = eol = 0;
|
|
|
|
|
-
|
|
|
|
|
- i += get_field(buffer2, buffer + i, LINE_BUFFER_SIZE, &eol);
|
|
|
|
|
-
|
|
|
|
|
- //Skip any blank or comment lines
|
|
|
|
|
- if(eol || buffer2[0] == '#') { continue; }
|
|
|
|
|
-
|
|
|
|
|
- //Clear this row
|
|
|
|
|
- memset(current_paddle + current_paddle_len, 0, sizeof(stop));
|
|
|
|
|
-
|
|
|
|
|
- current_paddle[current_paddle_len].hour = strtol(buffer2, NULL, 10);
|
|
|
|
|
-
|
|
|
|
|
- i += get_field(buffer2, buffer + i, LINE_BUFFER_SIZE, &eol);
|
|
|
|
|
- if(eol) { printf("Line %d too short in paddle %d: \"%s\"\n", n, paddlenum, buffer); continue; }
|
|
|
|
|
- current_paddle[current_paddle_len].min = strtol(buffer2, NULL, 10);
|
|
|
|
|
-
|
|
|
|
|
- i += get_field(buffer2, buffer + i, LINE_BUFFER_SIZE, &eol);
|
|
|
|
|
- if(eol) { printf("Line %d too short in paddle %d: \"%s\"\n", n, paddlenum, buffer); continue; }
|
|
|
|
|
- current_paddle[current_paddle_len].lat = strtod(buffer2, NULL);
|
|
|
|
|
-
|
|
|
|
|
- i += get_field(buffer2, buffer + i, LINE_BUFFER_SIZE, &eol);
|
|
|
|
|
- if(eol) { printf("Line %d too short in paddle %d: \"%s\"\n", n, paddlenum, buffer); continue; }
|
|
|
|
|
- current_paddle[current_paddle_len].lon = strtod(buffer2, NULL);
|
|
|
|
|
-
|
|
|
|
|
- i += get_field(buffer2, buffer + i, LINE_BUFFER_SIZE, &eol);
|
|
|
|
|
- if(eol) { printf("Line %d too short in paddle %d: \"%s\"\n", n, paddlenum, buffer); continue; }
|
|
|
|
|
- current_paddle[current_paddle_len].route = strtol(buffer2, NULL, 10);
|
|
|
|
|
-
|
|
|
|
|
- i += get_field(buffer2, buffer + i, LINE_BUFFER_SIZE, &eol);
|
|
|
|
|
- if(eol) { printf("Line %d too short in paddle %d: \"%s\"\n", n, paddlenum, buffer); continue; }
|
|
|
|
|
- current_paddle[current_paddle_len].trip = strtol(buffer2, NULL, 10);
|
|
|
|
|
-
|
|
|
|
|
- i += get_field(buffer2, buffer + i, LINE_BUFFER_SIZE, &eol);
|
|
|
|
|
- if(eol) { printf("Line %d too short in paddle %d: \"%s\"\n", n, paddlenum, buffer); continue; }
|
|
|
|
|
- current_paddle[current_paddle_len].stop = strtol(buffer2, NULL, 10);
|
|
|
|
|
-
|
|
|
|
|
- i += get_field(buffer2, buffer + i, LINE_BUFFER_SIZE, &eol);
|
|
|
|
|
- strncpy(current_paddle[current_paddle_len].name, buffer2, STOP_NAME_LEN - 1);
|
|
|
|
|
-
|
|
|
|
|
- current_paddle_len++;
|
|
|
|
|
|
|
+ fprintf(stderr, "Paddle %d has overflowed its maximum size of %d stops and has been truncated!\n", current_paddle_num, MAX_PADDLE_SIZE);
|
|
|
|
|
+ break;
|
|
|
}
|
|
}
|
|
|
- fclose(f);
|
|
|
|
|
|
|
|
|
|
- return paddlenum;
|
|
|
|
|
|
|
+ strip_crlf(buffer); //get rid of any trailing CR/LF characters
|
|
|
|
|
+
|
|
|
|
|
+ n++;
|
|
|
|
|
+
|
|
|
|
|
+ i = eol = 0;
|
|
|
|
|
+
|
|
|
|
|
+ i += get_field(buffer2, buffer + i, LINE_BUFFER_SIZE, &eol);
|
|
|
|
|
+
|
|
|
|
|
+ //Skip any blank or comment lines
|
|
|
|
|
+ if(eol || buffer2[0] == '#') { continue; }
|
|
|
|
|
+
|
|
|
|
|
+ //Clear this row
|
|
|
|
|
+ memset(current_paddle + current_paddle_len, 0, sizeof(stop));
|
|
|
|
|
+
|
|
|
|
|
+ current_paddle[current_paddle_len].hour = strtol(buffer2, NULL, 10);
|
|
|
|
|
+
|
|
|
|
|
+ i += get_field(buffer2, buffer + i, LINE_BUFFER_SIZE, &eol);
|
|
|
|
|
+ if(eol) { printf("Line %d too short in paddle %d: \"%s\"\n", n, paddlenum, buffer); continue; }
|
|
|
|
|
+ current_paddle[current_paddle_len].min = strtol(buffer2, NULL, 10);
|
|
|
|
|
+
|
|
|
|
|
+ i += get_field(buffer2, buffer + i, LINE_BUFFER_SIZE, &eol);
|
|
|
|
|
+ if(eol) { printf("Line %d too short in paddle %d: \"%s\"\n", n, paddlenum, buffer); continue; }
|
|
|
|
|
+ current_paddle[current_paddle_len].lat = strtod(buffer2, NULL);
|
|
|
|
|
+
|
|
|
|
|
+ i += get_field(buffer2, buffer + i, LINE_BUFFER_SIZE, &eol);
|
|
|
|
|
+ if(eol) { printf("Line %d too short in paddle %d: \"%s\"\n", n, paddlenum, buffer); continue; }
|
|
|
|
|
+ current_paddle[current_paddle_len].lon = strtod(buffer2, NULL);
|
|
|
|
|
+
|
|
|
|
|
+ i += get_field(buffer2, buffer + i, LINE_BUFFER_SIZE, &eol);
|
|
|
|
|
+ if(eol) { printf("Line %d too short in paddle %d: \"%s\"\n", n, paddlenum, buffer); continue; }
|
|
|
|
|
+ current_paddle[current_paddle_len].route = strtol(buffer2, NULL, 10);
|
|
|
|
|
+
|
|
|
|
|
+ i += get_field(buffer2, buffer + i, LINE_BUFFER_SIZE, &eol);
|
|
|
|
|
+ if(eol) { printf("Line %d too short in paddle %d: \"%s\"\n", n, paddlenum, buffer); continue; }
|
|
|
|
|
+ current_paddle[current_paddle_len].trip = strtol(buffer2, NULL, 10);
|
|
|
|
|
+
|
|
|
|
|
+ i += get_field(buffer2, buffer + i, LINE_BUFFER_SIZE, &eol);
|
|
|
|
|
+ if(eol) { printf("Line %d too short in paddle %d: \"%s\"\n", n, paddlenum, buffer); continue; }
|
|
|
|
|
+ current_paddle[current_paddle_len].stop = strtol(buffer2, NULL, 10);
|
|
|
|
|
+
|
|
|
|
|
+ i += get_field(buffer2, buffer + i, LINE_BUFFER_SIZE, &eol);
|
|
|
|
|
+ strncpy(current_paddle[current_paddle_len].name, buffer2, STOP_NAME_LEN - 1);
|
|
|
|
|
+
|
|
|
|
|
+ current_paddle_len++;
|
|
|
|
|
+ }
|
|
|
|
|
+ fclose(f);
|
|
|
|
|
+
|
|
|
|
|
+ return paddlenum;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int clear_paddle()
|
|
int clear_paddle()
|
|
|
{
|
|
{
|
|
|
- current_paddle_num = 0;
|
|
|
|
|
- current_paddle_idx = 0;
|
|
|
|
|
- current_paddle_len = 0;
|
|
|
|
|
-
|
|
|
|
|
- return 0;
|
|
|
|
|
|
|
+ current_paddle_num = 0;
|
|
|
|
|
+ current_paddle_idx = 0;
|
|
|
|
|
+ current_paddle_len = 0;
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int where_the_hell_are_we()
|
|
int where_the_hell_are_we()
|
|
|
{
|
|
{
|
|
|
- int i;
|
|
|
|
|
- int found_stop = current_paddle_idx; //by default, we will report that we are still at our last known stop
|
|
|
|
|
-
|
|
|
|
|
- struct tm temp;
|
|
|
|
|
- time_t now;
|
|
|
|
|
- time_t sched;
|
|
|
|
|
-
|
|
|
|
|
- now = time(NULL);
|
|
|
|
|
-
|
|
|
|
|
- if(current_paddle_num == 0)
|
|
|
|
|
- {
|
|
|
|
|
- return -1;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ int i;
|
|
|
|
|
+ int found_stop = current_paddle_idx; //by default, we will report that we are still at our last known stop
|
|
|
|
|
+
|
|
|
|
|
+ struct tm temp;
|
|
|
|
|
+ time_t now;
|
|
|
|
|
+ time_t sched;
|
|
|
|
|
+
|
|
|
|
|
+ now = time(NULL);
|
|
|
|
|
|
|
|
- #ifdef ROLLOVER_FORWARD_ONLY
|
|
|
|
|
- //If we are in rollover-forward mode, we will not actively re-select any previous stops, nor the current one.
|
|
|
|
|
- //This allows two stops to have the same location but different route numbers for places where the route changes at a stop.
|
|
|
|
|
- i = current_paddle_idx;
|
|
|
|
|
- #else
|
|
|
|
|
- i = 0;
|
|
|
|
|
- #endif
|
|
|
|
|
|
|
+ if(current_paddle_num == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ #ifdef ROLLOVER_FORWARD_ONLY
|
|
|
|
|
+ //If we are in rollover-forward mode, we will not actively re-select any previous stops, nor the current one.
|
|
|
|
|
+ //This allows two stops to have the same location but different route numbers for places where the route changes at a stop.
|
|
|
|
|
+ i = current_paddle_idx;
|
|
|
|
|
+ #else
|
|
|
|
|
+ i = 0;
|
|
|
|
|
+ #endif
|
|
|
|
|
|
|
|
- for( /*see ifdef block above*/; i < current_paddle_len; i++)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ for( /*see ifdef block above*/; i < current_paddle_len; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ localtime_r(&now,&temp); //populate our time structure based on now
|
|
|
|
|
+ //so the date will be correct
|
|
|
|
|
+
|
|
|
|
|
+ temp.tm_hour = current_paddle[i].hour; //Set the expected arrival time
|
|
|
|
|
+ temp.tm_min = current_paddle[i].min; //Set the expected arrival time
|
|
|
|
|
+
|
|
|
|
|
+ sched = mktime( &temp ); //and convert it back to a scheduled arrival time in UTC unix timestamp format
|
|
|
|
|
+
|
|
|
|
|
+ if( (abs(now - sched) <= ROLLOVER_TIME_WINDOW) && //First we do the time check, because that's cheap integer math
|
|
|
|
|
+ (GPS_Dist(gps_stat.lat, gps_stat.lon, current_paddle[i].lat, current_paddle[i].lon) <= ROLLOVER_DISTANCE) //The GPS distance last because that's expensive trig
|
|
|
|
|
+ )
|
|
|
{
|
|
{
|
|
|
- localtime_r(&now,&temp); //populate our time structure based on now
|
|
|
|
|
- //so the date will be correct
|
|
|
|
|
-
|
|
|
|
|
- temp.tm_hour = current_paddle[i].hour; //Set the expected arrival time
|
|
|
|
|
- temp.tm_min = current_paddle[i].min; //Set the expected arrival time
|
|
|
|
|
-
|
|
|
|
|
- sched = mktime( &temp ); //and convert it back to a scheduled arrival time in UTC unix timestamp format
|
|
|
|
|
-
|
|
|
|
|
- if( (abs(now - sched) <= ROLLOVER_TIME_WINDOW) && //First we do the time check, because that's cheap integer math
|
|
|
|
|
- (GPS_Dist(gps_stat.lat, gps_stat.lon, current_paddle[i].lat, current_paddle[i].lon) <= ROLLOVER_DISTANCE) //The GPS distance last because that's expensive trig
|
|
|
|
|
- )
|
|
|
|
|
- {
|
|
|
|
|
- found_stop = i; //update our found_stop index to the matching stop
|
|
|
|
|
-
|
|
|
|
|
- #ifndef ROLLOVER_TO_FURTHEST_STOP
|
|
|
|
|
-
|
|
|
|
|
- break; //if ROLLOVER_TO_FURTHEST_STOP is NOT defined, we break as soon as
|
|
|
|
|
- //we've found ANY matching stop (even the one we started at)
|
|
|
|
|
- #endif
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ found_stop = i; //update our found_stop index to the matching stop
|
|
|
|
|
+
|
|
|
|
|
+ #ifndef ROLLOVER_TO_FURTHEST_STOP
|
|
|
|
|
+
|
|
|
|
|
+ break; //if ROLLOVER_TO_FURTHEST_STOP is NOT defined, we break as soon as
|
|
|
|
|
+ //we've found ANY matching stop (even the one we started at)
|
|
|
|
|
+ #endif
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- return found_stop; //Return found_stop
|
|
|
|
|
|
|
+ return found_stop; //Return found_stop
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int send_status_update()
|
|
int send_status_update()
|
|
|
{
|
|
{
|
|
|
- struct message_record outgoing_msg;
|
|
|
|
|
- stop_status current = {0};
|
|
|
|
|
-
|
|
|
|
|
- if(commhub_fd < 0)
|
|
|
|
|
- {
|
|
|
|
|
- return -1;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- current.paddle = current_paddle_num;
|
|
|
|
|
-
|
|
|
|
|
- if(current_paddle_num)
|
|
|
|
|
- {
|
|
|
|
|
- current.route = current_paddle[current_paddle_idx].route;
|
|
|
|
|
- current.trip = current_paddle[current_paddle_idx].trip;
|
|
|
|
|
- current.stop = current_paddle[current_paddle_idx].stop;
|
|
|
|
|
|
|
+ struct message_record outgoing_msg;
|
|
|
|
|
+ stop_status current = {0};
|
|
|
|
|
|
|
|
- current.lat = current_paddle[current_paddle_idx].lat;
|
|
|
|
|
- current.lon = current_paddle[current_paddle_idx].lon;
|
|
|
|
|
|
|
+ if(commhub_fd < 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- strncpy(current.stopname, current_paddle[current_paddle_idx].name, STOP_NAME_LEN - 1);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- prepare_message(&outgoing_msg, MAILBOX_STOP_STATUS, ¤t, sizeof(current));
|
|
|
|
|
- return send_message(commhub_fd, &outgoing_msg);
|
|
|
|
|
|
|
+ current.paddle = current_paddle_num;
|
|
|
|
|
+
|
|
|
|
|
+ if(current_paddle_num)
|
|
|
|
|
+ {
|
|
|
|
|
+ current.route = current_paddle[current_paddle_idx].route;
|
|
|
|
|
+ current.trip = current_paddle[current_paddle_idx].trip;
|
|
|
|
|
+ current.stop = current_paddle[current_paddle_idx].stop;
|
|
|
|
|
+
|
|
|
|
|
+ current.lat = current_paddle[current_paddle_idx].lat;
|
|
|
|
|
+ current.lon = current_paddle[current_paddle_idx].lon;
|
|
|
|
|
+
|
|
|
|
|
+ strncpy(current.stopname, current_paddle[current_paddle_idx].name, STOP_NAME_LEN - 1);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ prepare_message(&outgoing_msg, MAILBOX_STOP_STATUS, ¤t, sizeof(current));
|
|
|
|
|
+ return send_message(commhub_fd, &outgoing_msg);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//This function sends an update to the driver and to the diagnostic log saying we're doing a stop rollover
|
|
//This function sends an update to the driver and to the diagnostic log saying we're doing a stop rollover
|
|
|
int send_driver_update()
|
|
int send_driver_update()
|
|
|
{
|
|
{
|
|
|
- struct message_record outgoing_msg;
|
|
|
|
|
-
|
|
|
|
|
- if(commhub_fd < 0)
|
|
|
|
|
- {
|
|
|
|
|
- return -1;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ struct message_record outgoing_msg;
|
|
|
|
|
|
|
|
- if(current_paddle_num)
|
|
|
|
|
- {
|
|
|
|
|
- format_log_message(&outgoing_msg, LOGLEVEL_DEBUG, "%02d:%02d %s", current_paddle[current_paddle_idx].hour, current_paddle[current_paddle_idx].min, current_paddle[current_paddle_idx].name);
|
|
|
|
|
- send_message(commhub_fd, &outgoing_msg);
|
|
|
|
|
-
|
|
|
|
|
- format_driver_message(&outgoing_msg, LOGLEVEL_EVENT, "%02d:%02d %s", current_paddle[current_paddle_idx].hour, current_paddle[current_paddle_idx].min, current_paddle[current_paddle_idx].name);
|
|
|
|
|
- return send_message(commhub_fd, &outgoing_msg);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return -1;
|
|
|
|
|
|
|
+ if(commhub_fd < 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(current_paddle_num)
|
|
|
|
|
+ {
|
|
|
|
|
+ format_log_message(&outgoing_msg, LOGLEVEL_DEBUG, "%02d:%02d %s", current_paddle[current_paddle_idx].hour, current_paddle[current_paddle_idx].min, current_paddle[current_paddle_idx].name);
|
|
|
|
|
+ send_message(commhub_fd, &outgoing_msg);
|
|
|
|
|
+
|
|
|
|
|
+ format_driver_message(&outgoing_msg, LOGLEVEL_EVENT, "%02d:%02d %s", current_paddle[current_paddle_idx].hour, current_paddle[current_paddle_idx].min, current_paddle[current_paddle_idx].name);
|
|
|
|
|
+ return send_message(commhub_fd, &outgoing_msg);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return -1;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int send_vault_drop()
|
|
int send_vault_drop()
|
|
|
{
|
|
{
|
|
|
- struct message_record outgoing_msg;
|
|
|
|
|
-
|
|
|
|
|
- if(commhub_fd < 0)
|
|
|
|
|
- {
|
|
|
|
|
- return -1;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ struct message_record outgoing_msg;
|
|
|
|
|
+
|
|
|
|
|
+ if(commhub_fd < 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ return -1;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- prepare_message(&outgoing_msg, MAILBOX_VAULT_DROP, "", 0);
|
|
|
|
|
- return send_message(commhub_fd, &outgoing_msg);
|
|
|
|
|
|
|
+ prepare_message(&outgoing_msg, MAILBOX_VAULT_DROP, "", 0);
|
|
|
|
|
+ return send_message(commhub_fd, &outgoing_msg);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
message_callback_return handle_status_req(struct message_record *msg, void *param)
|
|
message_callback_return handle_status_req(struct message_record *msg, void *param)
|
|
|
{
|
|
{
|
|
|
- send_status_update();
|
|
|
|
|
- return MESSAGE_HANDLED_CONT;
|
|
|
|
|
|
|
+ send_status_update();
|
|
|
|
|
+ return MESSAGE_HANDLED_CONT;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
message_callback_return handle_gps_update(struct message_record *msg, void *param)
|
|
message_callback_return handle_gps_update(struct message_record *msg, void *param)
|
|
|
{
|
|
{
|
|
|
- int tempidx;
|
|
|
|
|
-
|
|
|
|
|
- //The system callback will have already handled this message and put it into the correct data structure
|
|
|
|
|
-
|
|
|
|
|
- //If either we have no current paddle, or no real GPS data, ignore this message
|
|
|
|
|
- if( (!current_paddle_num) || (!gps_stat.gps_good) )
|
|
|
|
|
- {
|
|
|
|
|
- return MESSAGE_HANDLED_CONT;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- tempidx = where_the_hell_are_we();
|
|
|
|
|
-
|
|
|
|
|
- if(tempidx < 0)
|
|
|
|
|
- {
|
|
|
|
|
- return MESSAGE_HANDLED_CONT;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if(tempidx != current_paddle_idx)
|
|
|
|
|
- {
|
|
|
|
|
- current_paddle_idx = tempidx;
|
|
|
|
|
- send_status_update();
|
|
|
|
|
- send_driver_update();
|
|
|
|
|
- send_vault_drop();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ int tempidx;
|
|
|
|
|
+
|
|
|
|
|
+ //The system callback will have already handled this message and put it into the correct data structure
|
|
|
|
|
+
|
|
|
|
|
+ //If either we have no current paddle, or no real GPS data, ignore this message
|
|
|
|
|
+ if( (!current_paddle_num) || (!gps_stat.gps_good) )
|
|
|
|
|
+ {
|
|
|
|
|
+ return MESSAGE_HANDLED_CONT;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ tempidx = where_the_hell_are_we();
|
|
|
|
|
+
|
|
|
|
|
+ if(tempidx < 0)
|
|
|
|
|
+ {
|
|
|
return MESSAGE_HANDLED_CONT;
|
|
return MESSAGE_HANDLED_CONT;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(tempidx != current_paddle_idx)
|
|
|
|
|
+ {
|
|
|
|
|
+ current_paddle_idx = tempidx;
|
|
|
|
|
+ send_status_update();
|
|
|
|
|
+ send_driver_update();
|
|
|
|
|
+ send_vault_drop();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return MESSAGE_HANDLED_CONT;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
message_callback_return handle_next_req(struct message_record *msg, void *param)
|
|
message_callback_return handle_next_req(struct message_record *msg, void *param)
|
|
|
{
|
|
{
|
|
|
- if(current_paddle_idx < (current_paddle_len - 1))
|
|
|
|
|
- {
|
|
|
|
|
- current_paddle_idx++;
|
|
|
|
|
- send_driver_update();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- send_status_update();
|
|
|
|
|
- return MESSAGE_HANDLED_CONT;
|
|
|
|
|
|
|
+ if(current_paddle_idx < (current_paddle_len - 1))
|
|
|
|
|
+ {
|
|
|
|
|
+ current_paddle_idx++;
|
|
|
|
|
+ send_driver_update();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ send_status_update();
|
|
|
|
|
+ return MESSAGE_HANDLED_CONT;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
message_callback_return handle_prev_req(struct message_record *msg, void *param)
|
|
message_callback_return handle_prev_req(struct message_record *msg, void *param)
|
|
|
{
|
|
{
|
|
|
- if(current_paddle_idx > 0)
|
|
|
|
|
- {
|
|
|
|
|
- current_paddle_idx--;
|
|
|
|
|
- send_driver_update();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- send_status_update();
|
|
|
|
|
- return MESSAGE_HANDLED_CONT;
|
|
|
|
|
|
|
+ if(current_paddle_idx > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ current_paddle_idx--;
|
|
|
|
|
+ send_driver_update();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ send_status_update();
|
|
|
|
|
+ return MESSAGE_HANDLED_CONT;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
message_callback_return handle_set_paddle_req(struct message_record *msg, void *param)
|
|
message_callback_return handle_set_paddle_req(struct message_record *msg, void *param)
|
|
|
{
|
|
{
|
|
|
- struct message_record outgoing_msg;
|
|
|
|
|
- set_paddle_req *req = (set_paddle_req *)msg->payload;
|
|
|
|
|
|
|
+ struct message_record outgoing_msg;
|
|
|
|
|
+ set_paddle_req *req = (set_paddle_req *)msg->payload;
|
|
|
|
|
|
|
|
- clear_paddle();
|
|
|
|
|
- req->result = load_paddle(req->request);
|
|
|
|
|
|
|
+ clear_paddle();
|
|
|
|
|
+ req->result = load_paddle(req->request);
|
|
|
|
|
|
|
|
- if(req->result > 0)
|
|
|
|
|
- {
|
|
|
|
|
- send_driver_update();
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if(req->result > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ send_driver_update();
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- prepare_message(&outgoing_msg, MAILBOX_PADDLE_ACK, req, sizeof(set_paddle_req));
|
|
|
|
|
- send_message(commhub_fd, &outgoing_msg);
|
|
|
|
|
|
|
+ prepare_message(&outgoing_msg, MAILBOX_PADDLE_ACK, req, sizeof(set_paddle_req));
|
|
|
|
|
+ send_message(commhub_fd, &outgoing_msg);
|
|
|
|
|
|
|
|
- send_status_update();
|
|
|
|
|
- return MESSAGE_HANDLED_CONT;
|
|
|
|
|
|
|
+ send_status_update();
|
|
|
|
|
+ return MESSAGE_HANDLED_CONT;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
void maintain_ipc_hub_connect(char *progname)
|
|
void maintain_ipc_hub_connect(char *progname)
|
|
|
{
|
|
{
|
|
|
- struct message_record outgoing_msg;
|
|
|
|
|
|
|
+ struct message_record outgoing_msg;
|
|
|
|
|
+
|
|
|
|
|
+ if(commhub_fd < 0) //if we have no connection to the communication hub
|
|
|
|
|
+ {
|
|
|
|
|
+ commhub_fd = connect_to_message_server(progname); //try and get one
|
|
|
|
|
|
|
|
- if(commhub_fd < 0) //if we have no connection to the communication hub
|
|
|
|
|
|
|
+// printf("commhub_fd = %d\n", commhub_fd);
|
|
|
|
|
+
|
|
|
|
|
+ if(commhub_fd >= 0) //if it worked
|
|
|
{
|
|
{
|
|
|
- commhub_fd = connect_to_message_server(progname); //try and get one
|
|
|
|
|
-
|
|
|
|
|
-// printf("commhub_fd = %d\n", commhub_fd);
|
|
|
|
|
-
|
|
|
|
|
- if(commhub_fd >= 0) //if it worked
|
|
|
|
|
- {
|
|
|
|
|
- //Subscribe to the command mailboxes we act on
|
|
|
|
|
- prepare_message(&outgoing_msg, MAILBOX_SUBSCRIBE, MAILBOX_SET_PADDLE, strlen(MAILBOX_SET_PADDLE));
|
|
|
|
|
- send_message(commhub_fd,&outgoing_msg);
|
|
|
|
|
-
|
|
|
|
|
- prepare_message(&outgoing_msg, MAILBOX_SUBSCRIBE, MAILBOX_NEXT_STOP, strlen(MAILBOX_NEXT_STOP));
|
|
|
|
|
- send_message(commhub_fd,&outgoing_msg);
|
|
|
|
|
-
|
|
|
|
|
- prepare_message(&outgoing_msg, MAILBOX_SUBSCRIBE, MAILBOX_PREV_STOP, strlen(MAILBOX_PREV_STOP));
|
|
|
|
|
- send_message(commhub_fd,&outgoing_msg);
|
|
|
|
|
-
|
|
|
|
|
- //Subscribe to the relevant status management mailboxes
|
|
|
|
|
- subscribe_to_default_messages(commhub_fd);
|
|
|
|
|
-
|
|
|
|
|
- //Request updated status information...
|
|
|
|
|
- prepare_message(&outgoing_msg, MAILBOX_STATUS_REQUEST, "", 0);
|
|
|
|
|
- send_message(commhub_fd,&outgoing_msg);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ //Subscribe to the command mailboxes we act on
|
|
|
|
|
+ prepare_message(&outgoing_msg, MAILBOX_SUBSCRIBE, MAILBOX_SET_PADDLE, strlen(MAILBOX_SET_PADDLE));
|
|
|
|
|
+ send_message(commhub_fd,&outgoing_msg);
|
|
|
|
|
+
|
|
|
|
|
+ prepare_message(&outgoing_msg, MAILBOX_SUBSCRIBE, MAILBOX_NEXT_STOP, strlen(MAILBOX_NEXT_STOP));
|
|
|
|
|
+ send_message(commhub_fd,&outgoing_msg);
|
|
|
|
|
+
|
|
|
|
|
+ prepare_message(&outgoing_msg, MAILBOX_SUBSCRIBE, MAILBOX_PREV_STOP, strlen(MAILBOX_PREV_STOP));
|
|
|
|
|
+ send_message(commhub_fd,&outgoing_msg);
|
|
|
|
|
+
|
|
|
|
|
+ //Subscribe to the relevant status management mailboxes
|
|
|
|
|
+ subscribe_to_default_messages(commhub_fd);
|
|
|
|
|
+
|
|
|
|
|
+ //Request updated status information...
|
|
|
|
|
+ prepare_message(&outgoing_msg, MAILBOX_STATUS_REQUEST, "", 0);
|
|
|
|
|
+ send_message(commhub_fd,&outgoing_msg);
|
|
|
}
|
|
}
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
int main(int argc, char **argv)
|
|
|
{
|
|
{
|
|
|
- struct pollfd fds[2];
|
|
|
|
|
- int nfds = 0;
|
|
|
|
|
- int poll_return = 0;
|
|
|
|
|
- int read_return = 0;
|
|
|
|
|
|
|
+ struct pollfd fds[2];
|
|
|
|
|
+ int nfds = 0;
|
|
|
|
|
+ int poll_return = 0;
|
|
|
|
|
+ int read_return = 0;
|
|
|
|
|
+
|
|
|
|
|
+ int i;
|
|
|
|
|
+
|
|
|
|
|
+ struct message_record incoming_msg;
|
|
|
|
|
+
|
|
|
|
|
+ configure_signal_handlers(argv[0]);
|
|
|
|
|
+ maintain_ipc_hub_connect(argv[0]);
|
|
|
|
|
+
|
|
|
|
|
+ //Register our default keep-up-with-system status callbacks
|
|
|
|
|
+ register_system_status_callbacks();
|
|
|
|
|
+
|
|
|
|
|
+ //Add our module-specific callbacks
|
|
|
|
|
+ register_dispatch_callback(MAILBOX_GPS_STATUS, CALLBACK_USER(1), handle_gps_update, NULL);
|
|
|
|
|
+ register_dispatch_callback(MAILBOX_STATUS_REQUEST, CALLBACK_USER(2), handle_status_req, NULL);
|
|
|
|
|
+ register_dispatch_callback(MAILBOX_SET_PADDLE, CALLBACK_USER(3), handle_set_paddle_req, NULL);
|
|
|
|
|
+ register_dispatch_callback(MAILBOX_NEXT_STOP, CALLBACK_USER(4), handle_next_req, NULL);
|
|
|
|
|
+ register_dispatch_callback(MAILBOX_PREV_STOP, CALLBACK_USER(5), handle_prev_req, NULL);
|
|
|
|
|
|
|
|
- int i;
|
|
|
|
|
|
|
+ while( exit_request_status == EXIT_REQUEST_NONE ) {
|
|
|
|
|
|
|
|
- struct message_record incoming_msg;
|
|
|
|
|
|
|
+ RESET_WATCHDOG();
|
|
|
|
|
+
|
|
|
|
|
+ //DEBUG
|
|
|
|
|
+ printf("[%lli] paddlemgr: heartbeat\n", get_usec_time());
|
|
|
|
|
+ //DEBUG
|
|
|
|
|
|
|
|
- configure_signal_handlers(argv[0]);
|
|
|
|
|
maintain_ipc_hub_connect(argv[0]);
|
|
maintain_ipc_hub_connect(argv[0]);
|
|
|
-
|
|
|
|
|
- //Register our default keep-up-with-system status callbacks
|
|
|
|
|
- register_system_status_callbacks();
|
|
|
|
|
-
|
|
|
|
|
- //Add our module-specific callbacks
|
|
|
|
|
- register_dispatch_callback(MAILBOX_GPS_STATUS, CALLBACK_USER(1), handle_gps_update, NULL);
|
|
|
|
|
- register_dispatch_callback(MAILBOX_STATUS_REQUEST, CALLBACK_USER(2), handle_status_req, NULL);
|
|
|
|
|
- register_dispatch_callback(MAILBOX_SET_PADDLE, CALLBACK_USER(3), handle_set_paddle_req, NULL);
|
|
|
|
|
- register_dispatch_callback(MAILBOX_NEXT_STOP, CALLBACK_USER(4), handle_next_req, NULL);
|
|
|
|
|
- register_dispatch_callback(MAILBOX_PREV_STOP, CALLBACK_USER(5), handle_prev_req, NULL);
|
|
|
|
|
-
|
|
|
|
|
- while( exit_request_status == EXIT_REQUEST_NONE )
|
|
|
|
|
|
|
+
|
|
|
|
|
+ nfds=0;
|
|
|
|
|
+
|
|
|
|
|
+ if(commhub_fd >= 0)
|
|
|
{
|
|
{
|
|
|
- RESET_WATCHDOG();
|
|
|
|
|
-
|
|
|
|
|
- maintain_ipc_hub_connect(argv[0]);
|
|
|
|
|
-
|
|
|
|
|
- nfds=0;
|
|
|
|
|
-
|
|
|
|
|
- if(commhub_fd >= 0)
|
|
|
|
|
- {
|
|
|
|
|
- fds[nfds].fd = commhub_fd;
|
|
|
|
|
- fds[nfds].events = POLLIN;
|
|
|
|
|
- nfds++;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if(nfds > 0)
|
|
|
|
|
- {
|
|
|
|
|
- poll_return = poll(fds, nfds, POLL_TIMEOUT);
|
|
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- usleep(POLL_TIMEOUT * 1000);
|
|
|
|
|
- poll_return = 0;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ fds[nfds].fd = commhub_fd;
|
|
|
|
|
+ fds[nfds].events = POLLIN;
|
|
|
|
|
+ nfds++;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(nfds > 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ poll_return = poll(fds, nfds, POLL_TIMEOUT);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ usleep(POLL_TIMEOUT * 1000);
|
|
|
|
|
+ poll_return = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(poll_return <= 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //---- If we got a message
|
|
|
|
|
|
|
|
- if(poll_return <= 0)
|
|
|
|
|
|
|
+ for(i=0; i < nfds; i++)
|
|
|
|
|
+ {
|
|
|
|
|
+ if( fds[i].fd == commhub_fd )
|
|
|
|
|
+ {
|
|
|
|
|
+ //If we've lost connection, break this loop and poll all over again
|
|
|
|
|
+ if(fds[i].revents & (POLLERR | POLLHUP | POLLNVAL))
|
|
|
{
|
|
{
|
|
|
- continue;
|
|
|
|
|
|
|
+ close(commhub_fd);
|
|
|
|
|
+ commhub_fd = -1;
|
|
|
|
|
+ break;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- //---- If we got a message
|
|
|
|
|
-
|
|
|
|
|
- for(i=0; i < nfds; i++)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if(fds[i].revents & POLLIN)
|
|
|
{
|
|
{
|
|
|
- if( fds[i].fd == commhub_fd )
|
|
|
|
|
- {
|
|
|
|
|
- //If we've lost connection, break this loop and poll all over again
|
|
|
|
|
- if(fds[i].revents & (POLLERR | POLLHUP | POLLNVAL))
|
|
|
|
|
- {
|
|
|
|
|
- close(commhub_fd);
|
|
|
|
|
- commhub_fd = -1;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if(fds[i].revents & POLLIN)
|
|
|
|
|
- {
|
|
|
|
|
- read_return = get_message(commhub_fd, &incoming_msg);
|
|
|
|
|
-
|
|
|
|
|
- if( read_return < 0 )
|
|
|
|
|
- {
|
|
|
|
|
- close(commhub_fd);
|
|
|
|
|
- commhub_fd = -1;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- process_message(&incoming_msg); //This passes the received message through the callback list
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ read_return = get_message(commhub_fd, &incoming_msg);
|
|
|
|
|
+
|
|
|
|
|
+ if( read_return < 0 )
|
|
|
|
|
+ {
|
|
|
|
|
+ close(commhub_fd);
|
|
|
|
|
+ commhub_fd = -1;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ process_message(&incoming_msg); //This passes the received message through the callback list
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if(commhub_fd >= 0)
|
|
|
|
|
- {
|
|
|
|
|
- close(commhub_fd);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- printf("Goodbye.\n");
|
|
|
|
|
-
|
|
|
|
|
- return 0;
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if(commhub_fd >= 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ close(commhub_fd);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ printf("Goodbye.\n");
|
|
|
|
|
+
|
|
|
|
|
+ return 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|