summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--binding/afm-geofence-binding.c76
1 files changed, 71 insertions, 5 deletions
diff --git a/binding/afm-geofence-binding.c b/binding/afm-geofence-binding.c
index a154147..7c148ef 100644
--- a/binding/afm-geofence-binding.c
+++ b/binding/afm-geofence-binding.c
@@ -32,20 +32,26 @@
#define AFB_BINDING_VERSION 2
#include <afb/afb-binding.h>
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof(void *))
+#define SECS_TO_USECS(x) (x * 1000000)
+#define USECS_TO_SECS(x) (x / 1000000)
+
static struct afb_event fence_event;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static GList *fences = NULL;
-#define ARRAY_SIZE(x) (sizeof(x)/sizeof(void *))
+static long dwell_transition_in_usecs = SECS_TO_USECS(20);
/*
* @name - geofence name
* @triggered - geofence is currently triggered
+ * @timestamp - timestamp of last geofence 'entered' transition
* @bbox - struct of bounding box coordinates
*/
struct geofence {
gchar *name;
bool triggered;
+ gint64 timestamp;
struct {
double min_latitude, max_latitude;
double min_longitude, max_longitude;
@@ -180,6 +186,7 @@ static void add_fence(struct afb_req request)
}
fence->name = g_strdup(name);
+ fence->timestamp = -1;
fences = g_list_append(fences, fence);
pthread_mutex_unlock(&mutex);
@@ -241,6 +248,8 @@ static void list_fences(struct afb_req request)
json_object_object_add(item, "within",
json_object_new_boolean(g->triggered));
+ json_object_object_add(item, "dwell",
+ json_object_new_boolean(g->triggered && g->timestamp == -1));
json_object_object_add(item, "bbox", json_bbox);
json_object_object_add(jresp, g->name, item);
}
@@ -277,6 +286,49 @@ static int init()
return 0;
}
+static inline bool dwell_transition_state(struct geofence *g)
+{
+ // zero dwell_transition_in_usecs means disabled
+ if (dwell_transition_in_usecs == 0)
+ return false;
+
+ if (g->timestamp == -1)
+ return false;
+
+ if ((g_get_monotonic_time() - g->timestamp) < dwell_transition_in_usecs)
+ return false;
+
+ return true;
+}
+
+static void dwell_transition(struct afb_req request)
+{
+ const char *value = afb_req_value(request, "value");
+ json_object *jresp = NULL;
+
+ pthread_mutex_lock(&mutex);
+
+ if (value) {
+ long seconds = strtol(value, NULL, 10);
+ if (seconds < 0) {
+ afb_req_fail(request, "failed", "invalid input");
+ pthread_mutex_unlock(&mutex);
+ return;
+ }
+
+ dwell_transition_in_usecs = SECS_TO_USECS(seconds);
+ }
+
+ jresp = json_object_new_object();
+ json_object_object_add(jresp, "seconds",
+ json_object_new_int64(USECS_TO_SECS(dwell_transition_in_usecs)));
+
+ pthread_mutex_unlock(&mutex);
+
+ afb_req_success(request, jresp,
+ "loitering time in seconds to enter dwell transition");
+}
+
static void onevent(const char *event, struct json_object *object)
{
json_object *val = NULL;
@@ -304,16 +356,29 @@ static void onevent(const char *event, struct json_object *object)
struct json_object *jresp;
bool current = within_bounding_box(latitude, longitude, g);
- if (current == g->triggered)
+ if (current == g->triggered && !dwell_transition_state(g))
continue;
jresp = json_object_new_object();
- g->triggered = current;
json_object_object_add(jresp, "name",
json_object_new_string(g->name));
- json_object_object_add(jresp, "state",
- json_object_new_string(current ? "entered" : "exited"));
+
+ if (current && g->triggered) {
+ json_object_object_add(jresp, "state",
+ json_object_new_string("dwell"));
+ g->timestamp = -1;
+ } else if (current) {
+ json_object_object_add(jresp, "state",
+ json_object_new_string("entered"));
+ g->timestamp = g_get_monotonic_time();
+ } else {
+ json_object_object_add(jresp, "state",
+ json_object_new_string("exited"));
+ g->timestamp = -1;
+ }
+
+ g->triggered = current;
afb_event_push(fence_event, jresp);
}
@@ -327,6 +392,7 @@ static const struct afb_verb_v2 binding_verbs[] = {
{ .verb = "add_fence", .callback = add_fence, .info = "Add geofence" },
{ .verb = "remove_fence", .callback = remove_fence, .info = "Remove geofence" },
{ .verb = "list_fences", .callback = list_fences, .info = "List all curent geofences" },
+ { .verb = "dwell_transition", .callback = dwell_transition, .info = "Set/get dwell transition delay" },
{ }
};