diff options
author | Clément Bénier <clement.benier@iot.bzh> | 2018-05-28 14:32:22 +0200 |
---|---|---|
committer | cle©mentbeénier <clement.benier@iot.bzh> | 2018-06-21 14:23:37 +0200 |
commit | 4bea2d73a5de0f8ec83c61edc37653718d34f31b (patch) | |
tree | 27bcf6901c168face30b593cb97c2460cb63a5b1 /binding | |
parent | 42407a7e9f7e0bf29c7d8c679536eecb9c899e86 (diff) |
initial commit: draft work in progress
Change-Id: I8c0c17c66a484df9bc152046466d80224cf65498
Signed-off-by: Clément Bénier <clement.benier@iot.bzh>
Diffstat (limited to 'binding')
-rw-r--r-- | binding/CMakeLists.txt | 42 | ||||
-rw-r--r-- | binding/accelero-binding.c | 167 |
2 files changed, 209 insertions, 0 deletions
diff --git a/binding/CMakeLists.txt b/binding/CMakeLists.txt new file mode 100644 index 0000000..05992ff --- /dev/null +++ b/binding/CMakeLists.txt @@ -0,0 +1,42 @@ +########################################################################### +# Copyright 2015, 2016, 2017 IoT.bzh +# +# author: Fulup Ar Foll <fulup@iot.bzh> +# contrib: Romain Forlot <romain.forlot@iot.bzh> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################### + +# Add target to project dependency list +PROJECT_TARGET_ADD(accelero-binding) + + # Define project Targets + set(accelero_SOURCES + accelero-binding.c) + + add_library(${TARGET_NAME} MODULE ${accelero_SOURCES}) + + # Binder exposes a unique public entry point + SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES + PREFIX "" + LABELS "BINDING" + LINK_FLAGS ${BINDINGS_LINK_FLAG} + OUTPUT_NAME ${TARGET_NAME} + ) + + # Library dependencies (include updates automatically) + TARGET_LINK_LIBRARIES(${TARGET_NAME} ${link_libraries}) + + # installation directory + INSTALL(TARGETS ${TARGET_NAME} + LIBRARY DESTINATION ${BINDINGS_INSTALL_DIR}) diff --git a/binding/accelero-binding.c b/binding/accelero-binding.c new file mode 100644 index 0000000..d7f05e9 --- /dev/null +++ b/binding/accelero-binding.c @@ -0,0 +1,167 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <unistd.h> +#include <sys/types.h> +#include <fcntl.h> +#include <pthread.h> +#include <sys/ioctl.h> +#include <glib.h> + +#include <json-c/json.h> +#define AFB_BINDING_VERSION 2 +#include <afb/afb-binding.h> + +#define IIODEVICE "/sys/bus/iio/devices/iio:device" +#define IIODEVICE0 "/sys/bus/iio/devices/iio:device0/" +#define IIODEVICE1 "/sys/bus/iio/devices/iio:device1/" + +static struct afb_event accel_event; +static struct afb_event magn_event; +static struct afb_event anglvel_event; + +static pthread_t thread; +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +static void get_buffer(const char *iio_file, const char *sub_name, + void *buffer, size_t count) +{ + int fd; + fd = open(iio_file, O_RDONLY); + if(fd < 0) { + AFB_ERROR("Cannot open %s\n", iio_file); + return; + } + if(read(fd, buffer, count) < 0){ + AFB_ERROR("cannot read %s\n", iio_file); + return; + } + close(fd); +} + +static void get_subdata_string(const char * iio_device_path, const char *sub_name, + json_object *jresp) { + char iio_file[100]; + sprintf(iio_file, "%s%s", iio_device_path, sub_name); + size_t buffer_size = 1000; + char buffer[buffer_size]; + + get_buffer(iio_file, sub_name, buffer, buffer_size); + + json_object *value = json_object_new_string(buffer); + if(jresp) + json_object_object_add(jresp, sub_name, value); +} + +static void get_subdata_int(const char * iio_device_path, const char *sub_name, + json_object *jresp) { + char iio_file[100]; + sprintf(iio_file, "%s%s", iio_device_path, sub_name); + AFB_INFO("iio_file=%s", iio_file); + size_t buffer_size = 1000; + char buffer[buffer_size]; + + get_buffer(iio_file, sub_name, buffer, buffer_size); + + json_object *value = json_object_new_int(atoi(buffer)); + if(jresp) + json_object_object_add(jresp, sub_name, value); +} + +static void get_data(const char *name, const int iio_device, json_object *jresp) { + char iio_device_path[100]; + sprintf(iio_device_path, IIODEVICE"%d/in_%s_", iio_device, name); + + get_subdata_string(iio_device_path, "scale", jresp); + get_subdata_string(iio_device_path, "scale_available", jresp); + get_subdata_int(iio_device_path, "x_raw", jresp); + get_subdata_int(iio_device_path, "y_raw", jresp); + get_subdata_int(iio_device_path, "z_raw", jresp); +} + +static int treat_event(const char *name, const int device_number, + struct afb_event event) +{ + json_object *jresp = json_object_new_object(); + get_data(name, device_number, jresp); + AFB_INFO("push event %s\n", name); + pthread_mutex_lock(&mutex); + afb_event_push(event, json_object_get(jresp)); + pthread_mutex_unlock(&mutex); + return 0; +} + +gboolean data_poll(gpointer ptr) +{ + AFB_INFO("data_poll"); + treat_event("accel", 0, accel_event); + treat_event("magn", 0, magn_event); + treat_event("anglvel", 1, anglvel_event); + return TRUE; +} + +static void *data_thread(void *ptr) +{ + g_timeout_add_seconds(1, data_poll, NULL); + g_main_loop_run(g_main_loop_new(NULL, FALSE)); + return NULL; +} + +static void subscribe(struct afb_req request) +{ + const char *value = afb_req_value(request, "event"); + if(value) { + if(!strcasecmp(value, "accel")) { + afb_req_subscribe(request, accel_event); + } else if(!strcasecmp(value, "magn")) { + afb_req_subscribe(request, magn_event); + } else if(!strcasecmp(value, "anglvel")) { + afb_req_subscribe(request, anglvel_event); + } else { + afb_req_fail(request, "failed", "Invalid event"); + return; + } + } + afb_req_success(request, NULL, NULL); +} + +static void unsubscribe(struct afb_req request) +{ + const char *value = afb_req_value(request, "value"); + if(value) { + if(!strcasecmp(value, "accel")) { + afb_req_unsubscribe(request, accel_event); + } else if(!strcasecmp(value, "magn")) { + afb_req_unsubscribe(request, magn_event); + } else { + afb_req_fail(request, "failed", "Invalid event"); + return; + } + } + afb_req_success(request, NULL, NULL); +} + +const afb_verb_v2 verbs[] = { + { .verb = "subscribe", .session = AFB_SESSION_NONE, .callback = subscribe, .info = "Subscribe for an event" }, + { .verb = "unsubscribe", .session = AFB_SESSION_NONE, .callback = unsubscribe, .info = "Unsubscribe for an event" }, + { .verb=NULL } +}; + +static int init() +{ + accel_event = afb_daemon_make_event("accel"); + magn_event = afb_daemon_make_event("magn"); + anglvel_event = afb_daemon_make_event("anglvel"); + + pthread_create(&thread, NULL, &data_thread, NULL); + + return 0; +} + +const afb_binding_v2 afbBindingV2 = { + .info = "accelero service", + .api = "accelero", + .verbs = verbs, + .init = init, +}; |