diff options
Diffstat (limited to 'CAN-binder/low-can-demo/binding/stat-binding.c')
-rw-r--r-- | CAN-binder/low-can-demo/binding/stat-binding.c | 272 |
1 files changed, 0 insertions, 272 deletions
diff --git a/CAN-binder/low-can-demo/binding/stat-binding.c b/CAN-binder/low-can-demo/binding/stat-binding.c deleted file mode 100644 index 1e5b2db..0000000 --- a/CAN-binder/low-can-demo/binding/stat-binding.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (C) 2016 "IoT.bzh" - * Author José Bollo <jose.bollo@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. - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <netdb.h> -#include <fcntl.h> -#include <math.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/timerfd.h> - -#include <json-c/json.h> - -#include <systemd/sd-event.h> - -#include <afb/afb-binding.h> -#include <afb/afb-service-itf.h> - -/* - * the interface to afb-daemon - */ -const struct afb_binding_interface *afbitf; - -#define DEFAULT_PERIOD 1 /* 1 second */ - -struct event; - -const char *cpu_fields[]= { - "user", - "nice", - "system", - "idle", - "iowait", - "irq", - "softirq", - "steal", - "guest", - "guest_nice" -}; - -#define CPU_FIELD_COUNT (sizeof cpu_fields / sizeof *cpu_fields) - -struct status { - uint64_t cpu[CPU_FIELD_COUNT]; -}; - -static int fd_proc; -static int fd_timer; -static struct sd_event_source *source = NULL; - -static struct status older; -static struct status newer; -static struct status diff; -static struct afb_event event; - -/***************************************************************************************/ -/***************************************************************************************/ -/** **/ -/** **/ -/** SECTION: BINDING VERBS IMPLEMENTATION **/ -/** **/ -/** **/ -/***************************************************************************************/ -/***************************************************************************************/ - -static int read_status(int fd, struct status *s) -{ - int n; - ssize_t sz; - off_t off; - char buffer[8192]; - long long unsigned x[CPU_FIELD_COUNT]; - - off = lseek(fd, 0, SEEK_SET); - if (off == (off_t)-1) - return -1; - - sz = read(fd, buffer, sizeof buffer); - if (sz == -1) - return -1; - - n = sscanf(buffer, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &x[8], &x[9]); - if (n != CPU_FIELD_COUNT) - return -1; - while(n) { - n--; - s->cpu[n] = x[n]; - } - return 0; -} - -static void stop() -{ - sd_event_source_unref(source); - afb_event_drop(event); - close(fd_timer); - close(fd_proc); - fd_timer = -1; - fd_proc = -1; - event.itf = NULL; - source = NULL; -} - -static int emit(sd_event_source *src, int fd, uint32_t revents, void *userdata) -{ - int f, rc, p; - struct json_object *obj; - uint64_t u, s, i; - - read(fd, &i, sizeof i); - - memcpy(&older, &newer, sizeof older); - rc = read_status(fd_proc, &newer); - for(f = 0; f < (int)CPU_FIELD_COUNT ; f++) - diff.cpu[f] = newer.cpu[f] - older.cpu[f]; - - u = 0; - s = 0; - i = 0; - u += diff.cpu[0]; // "user", - u += diff.cpu[1]; // "nice", - s += diff.cpu[2]; // "system", - i += diff.cpu[3]; // "idle", - i += diff.cpu[4]; // "iowait", - s += diff.cpu[5]; // "irq", - s += diff.cpu[6]; // "softirq", - i += diff.cpu[7]; // "steal", - u += diff.cpu[8]; // "guest", - u += diff.cpu[9]; // "guest_nice" - p = (int)(unsigned)((100 * (u + s)) / (u + s + i)); - - obj = json_object_new_int(p); - if (afb_event_push(event, obj) == 0) - stop(); - return 0; -} - -static int start() -{ - int fdp, fdt, rc; - struct itimerspec ts; - struct sd_event_source *src; - - fdp = open("/proc/stat", O_RDONLY|O_CLOEXEC); - if (fdp >= 0) { - rc = read_status(fdp, &newer); - if (rc >= 0) { - fdt = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC); - if (fdt >= 0) { - ts.it_interval.tv_sec = 1; - ts.it_value.tv_sec = 1; - ts.it_interval.tv_nsec = 0; - ts.it_value.tv_nsec = 0; - rc = timerfd_settime(fdt, 0, &ts, NULL); - if (rc >= 0) { - event = afb_daemon_make_event(afbitf->daemon, "stat"); - if (afb_event_is_valid(event)) { - rc = sd_event_add_io(afb_daemon_get_event_loop(afbitf->daemon), &src, fdt, EPOLLIN, emit, NULL); - if (rc >= 0) { - fd_proc = fdp; - fd_timer = fdt; - source = src; - return 0; - } - afb_event_drop(event); - } - } - close(fdt); - } - } - close(fdp); - } - return -1; -} - -static int ensure_started() -{ - return source == NULL ? start() : 0; -} - -/***************************************************************************************/ -/***************************************************************************************/ -/** **/ -/** **/ -/** SECTION: BINDING VERBS IMPLEMENTATION **/ -/** **/ -/** **/ -/***************************************************************************************/ -/***************************************************************************************/ - -/* - * subscribe to notification of stat - */ -static void subscribe(struct afb_req req) -{ - int rc; - - rc = ensure_started(); - if (rc < 0) { - afb_req_fail(req, "failed", "Can't start"); - } else if (afb_req_subscribe(req, event) != 0) { - afb_req_fail_f(req, "failed", "afb_req_subscribe returned an error: %m"); - } else { - afb_req_success(req, NULL, NULL); - } -} - -/* - * unsubscribe a previous subscription - * - * parameters of the unsubscription are: - * - * id: integer: the numeric identifier of the event as returned when subscribing - */ -static void unsubscribe(struct afb_req req) -{ - if (afb_event_is_valid(event)) - afb_req_unsubscribe(req, event); - afb_req_success(req, NULL, NULL); -} - -/* - * array of the verbs exported to afb-daemon - */ -static const struct afb_verb_desc_v1 binding_verbs[] = { - /* VERB'S NAME SESSION MANAGEMENT FUNCTION TO CALL SHORT DESCRIPTION */ - { .name= "subscribe", .session= AFB_SESSION_NONE, .callback= subscribe, .info= "subscribe to notification of statistics" }, - { .name= "unsubscribe", .session= AFB_SESSION_NONE, .callback= unsubscribe, .info= "unsubscribe a previous subscription" }, - { .name= NULL } /* marker for end of the array */ -}; - -/* - * description of the binding for afb-daemon - */ -static const struct afb_binding binding_description = -{ - /* description conforms to VERSION 1 */ - .type= AFB_BINDING_VERSION_1, - .v1= { /* fills the v1 field of the union when AFB_BINDING_VERSION_1 */ - .prefix= "stat", /* the API name (or binding name or prefix) */ - .info= "Get system statistics", /* short description of of the binding */ - .verbs = binding_verbs /* the array describing the verbs of the API */ - } -}; - -/* - * activation function for registering the binding called by afb-daemon - */ -const struct afb_binding *afbBindingV1Register(const struct afb_binding_interface *itf) -{ - afbitf = itf; /* records the interface for accessing afb-daemon */ - return &binding_description; /* returns the description of the binding */ -} - |