#include #include #include #include #include #include #include #include #include #include #include #define AFB_BINDING_VERSION 2 #include #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, };