aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--binding/afm-gps-binding.c82
1 files changed, 78 insertions, 4 deletions
diff --git a/binding/afm-gps-binding.c b/binding/afm-gps-binding.c
index f2a48fd..2ceb13f 100644
--- a/binding/afm-gps-binding.c
+++ b/binding/afm-gps-binding.c
@@ -25,6 +25,8 @@
#include <time.h>
#include <pthread.h>
#include <json-c/json.h>
+#include <sys/signal.h>
+#include <sys/time.h>
#define AFB_BINDING_VERSION 2
#include <afb/afb-binding.h>
@@ -39,7 +41,8 @@ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
struct {
FILE *current_file;
- char buffer[32];
+ char buffer[512];
+ int replaying;
int count;
} recording;
@@ -78,6 +81,10 @@ static json_object *populate_json_data(json_object *jresp)
{
json_object *value = NULL;
+ if (recording.replaying) {
+ return json_tokener_parse(recording.buffer);
+ }
+
if (data.fix.mode != MODE_3D) {
json_object_put(jresp);
return NULL;
@@ -162,6 +169,11 @@ static void record(struct afb_req request)
const char *value = afb_req_value(request, "state");
bool record = false;
+ if (recording.replaying) {
+ afb_req_fail(request, "failed", "Current in replaying mode");
+ return;
+ }
+
if (!value) {
pthread_mutex_lock(&mutex);
jresp = gps_recording_state(json_object_new_object());
@@ -289,13 +301,25 @@ static void *data_poll(void *ptr)
return NULL;
}
-static int init()
+static void replay_thread(union sigval arg)
+{
+ FILE *fp = recording.current_file;
+ char *s = fgets(recording.buffer, sizeof(recording.buffer), fp);
+
+ if (s == NULL) {
+ if (feof(fp))
+ rewind(fp);
+ return;
+ }
+
+ afb_event_push(location_event, json_tokener_parse(s));
+}
+
+static int gps_init()
{
const char *host, *port;
int ret, tries = 5;
- location_event = afb_daemon_make_event("location");
-
host = getenv("AFBGPS_HOST") ? : "localhost";
port = getenv("AFBGPS_SERVICE") ? : "2947";
@@ -313,6 +337,56 @@ static int init()
return pthread_create(&thread, NULL, &data_poll, NULL);
}
+static int replay_init()
+{
+ timer_t timer_id;
+ struct itimerspec ts;
+ struct sigevent se;
+ int ret;
+
+ recording.current_file = fopen("recording.log", "r");
+ if (recording.current_file == NULL)
+ return -EINVAL;
+
+ se.sigev_notify = SIGEV_THREAD;
+ se.sigev_value.sival_ptr = &timer_id;
+ se.sigev_notify_function = replay_thread;
+ se.sigev_notify_attributes = NULL;
+
+ // TODO: Allow detecting of an non-static 1 Hz GPS trace log
+
+ ts.it_value.tv_sec = 1;
+ ts.it_value.tv_nsec = 0;
+
+ ts.it_interval.tv_sec = 1;
+ ts.it_interval.tv_nsec = 0;
+
+ ret = timer_create(CLOCK_REALTIME, &se, &timer_id);
+ if (ret < 0)
+ return ret;
+
+ return timer_settime(timer_id, 0, &ts, NULL);
+}
+
+/*
+ * Test to see if in demo mode first, then enable if not enable gpsd
+ */
+
+static int init()
+{
+ int ret;
+ location_event = afb_daemon_make_event("location");
+
+ ret = replay_init();
+
+ if (!ret)
+ recording.replaying = 1;
+ else
+ gps_init();
+
+ return 0;
+}
+
static const struct afb_verb_v2 binding_verbs[] = {
{ .verb = "location", .callback = get_data, .info = "Get GNSS data" },
{ .verb = "record", .callback = record, .info = "Record GPS data" },