From 00425f875eead4f208ea2f9b9372c950cb7f12f7 Mon Sep 17 00:00:00 2001 From: Shehbaaz Virk Date: Sat, 4 Apr 2026 16:13:21 -0400 Subject: [PATCH 1/2] Added logging features --- Makefile | 2 + kernel/elog.c | 78 ++++++++++++++++++++++++++++++ kernel/elog.h | 28 +++++++++++ kernel/main.c | 6 ++- kernel/syscall.c | 4 ++ kernel/syscall.h | 6 ++- kernel/sysfile.c | 43 +++++++++++++++++ test-xv6.py | 0 user/sustainlog.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++ user/user.h | 3 ++ user/usys.pl | 2 + 11 files changed, 287 insertions(+), 4 deletions(-) create mode 100644 kernel/elog.c create mode 100644 kernel/elog.h mode change 100755 => 100644 test-xv6.py create mode 100644 user/sustainlog.c mode change 100755 => 100644 user/usys.pl diff --git a/Makefile b/Makefile index b262c0a24e..7e7955f724 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ OBJS = \ $K/kalloc.o \ $K/spinlock.o \ $K/string.o \ + $K/elog.o \ $K/main.o \ $K/vm.o \ $K/proc.o \ @@ -142,6 +143,7 @@ UPROGS=\ $U/_grind\ $U/_wc\ $U/_zombie\ + $U/_sustainlog\ $U/_logstress\ $U/_forphan\ $U/_dorphan\ diff --git a/kernel/elog.c b/kernel/elog.c new file mode 100644 index 0000000000..1395d597fe --- /dev/null +++ b/kernel/elog.c @@ -0,0 +1,78 @@ +// kernel/elog.c +#include "types.h" +#include "riscv.h" +#include "spinlock.h" +#include "defs.h" +#include "elog.h" + +extern uint ticks; +extern struct spinlock tickslock; + +struct { + struct spinlock lock; + struct elog_entry buf[ELOG_SIZE]; + int next_index; // next position to write + int count; // number of valid entries +} elogsys; + +static int +getticksafe(void) +{ + int t; + acquire(&tickslock); + t = ticks; + release(&tickslock); + return t; +} + +void +eloginit(void) +{ + initlock(&elogsys.lock, "elog"); + elogsys.next_index = 0; + elogsys.count = 0; +} + +void +elogadd(int event_type, int sensor_id, int value) +{ + acquire(&elogsys.lock); + + struct elog_entry *e = &elogsys.buf[elogsys.next_index]; + e->timestamp = getticksafe(); + e->event_type = event_type; + e->sensor_id = sensor_id; + e->value = value; + + elogsys.next_index = (elogsys.next_index + 1) % ELOG_SIZE; + if(elogsys.count < ELOG_SIZE) + elogsys.count++; + + release(&elogsys.lock); +} + +// Copies logs from oldest -> newest into dst. +// Returns number of entries copied. +int +elogread(struct elog_entry *dst, int max) +{ + int i, n, start; + + if(dst == 0 || max <= 0) + return 0; + + acquire(&elogsys.lock); + + n = elogsys.count; + if(max < n) + n = max; + + start = (elogsys.next_index - elogsys.count + ELOG_SIZE) % ELOG_SIZE; + + for(i = 0; i < n; i++){ + dst[i] = elogsys.buf[(start + i) % ELOG_SIZE]; + } + + release(&elogsys.lock); + return n; +} \ No newline at end of file diff --git a/kernel/elog.h b/kernel/elog.h new file mode 100644 index 0000000000..7a866e2075 --- /dev/null +++ b/kernel/elog.h @@ -0,0 +1,28 @@ +#ifndef _ELOG_H_ +#define _ELOG_H_ + +#define ELOG_SIZE 64 + +#define SENSOR_TEMPERATURE 1 +#define SENSOR_AIR_QUALITY 2 +#define SENSOR_HUMIDITY 3 +#define SENSOR_ENERGY_USAGE 4 +#define SENSOR_WATER_USAGE 5 + +#define EVENT_SENSOR_UPDATE 1 +#define EVENT_THRESHOLD_EXCEEDED 2 +#define EVENT_BACK_TO_NORMAL 3 +#define EVENT_INVALID_READING 4 + +struct elog_entry { + int timestamp; + int event_type; + int sensor_id; + int value; +}; + +void eloginit(void); +void elogadd(int event_type, int sensor_id, int value); +int elogread(struct elog_entry *dst, int max); + +#endif \ No newline at end of file diff --git a/kernel/main.c b/kernel/main.c index f0d3171d4e..10e79721c0 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -3,6 +3,7 @@ #include "memlayout.h" #include "riscv.h" #include "defs.h" +#include "elog.h" volatile static int started = 0; @@ -28,6 +29,7 @@ main() iinit(); // inode table fileinit(); // file table virtio_disk_init(); // emulated hard disk + eloginit(); // initialize logging system userinit(); // first user process __sync_synchronize(); started = 1; @@ -41,5 +43,5 @@ main() plicinithart(); // ask PLIC for device interrupts } - scheduler(); -} + scheduler(); +} \ No newline at end of file diff --git a/kernel/syscall.c b/kernel/syscall.c index 076d9659a3..06b842ac66 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -101,6 +101,8 @@ extern uint64 sys_unlink(void); extern uint64 sys_link(void); extern uint64 sys_mkdir(void); extern uint64 sys_close(void); +extern uint64 sys_logevent(void); +extern uint64 sys_getlogs(void); // An array mapping syscall numbers from syscall.h // to the function that handles the system call. @@ -126,6 +128,8 @@ static uint64 (*syscalls[])(void) = { [SYS_link] sys_link, [SYS_mkdir] sys_mkdir, [SYS_close] sys_close, +[SYS_logevent] sys_logevent, +[SYS_getlogs] sys_getlogs, }; void diff --git a/kernel/syscall.h b/kernel/syscall.h index 3dd926d668..eeec2b16c9 100644 --- a/kernel/syscall.h +++ b/kernel/syscall.h @@ -18,5 +18,7 @@ #define SYS_mknod 17 #define SYS_unlink 18 #define SYS_link 19 -#define SYS_mkdir 20 -#define SYS_close 21 +#define SYS_mkdir 20 +#define SYS_close 21 +#define SYS_logevent 22 +#define SYS_getlogs 23 \ No newline at end of file diff --git a/kernel/sysfile.c b/kernel/sysfile.c index d8234ce92a..ea24c7182c 100644 --- a/kernel/sysfile.c +++ b/kernel/sysfile.c @@ -15,6 +15,7 @@ #include "sleeplock.h" #include "file.h" #include "fcntl.h" +#include "elog.h" // Fetch the nth word-sized system call argument as a file descriptor // and return both the descriptor and the corresponding struct file. @@ -503,3 +504,45 @@ sys_pipe(void) } return 0; } + +uint64 +sys_logevent(void) +{ + int event_type, sensor_id, value; + + argint(0, &event_type); + argint(1, &sensor_id); + argint(2, &value); + + if(event_type < EVENT_SENSOR_UPDATE || event_type > EVENT_INVALID_READING) + return -1; + if(sensor_id < SENSOR_TEMPERATURE || sensor_id > SENSOR_WATER_USAGE) + return -1; + + elogadd(event_type, sensor_id, value); + return 0; +} + +uint64 +sys_getlogs(void) +{ + uint64 dst; + int max, n; + struct proc *p = myproc(); + struct elog_entry entries[ELOG_SIZE]; + + argaddr(0, &dst); + argint(1, &max); + + if(max < 0) + return -1; + if(max > ELOG_SIZE) + max = ELOG_SIZE; + + n = elogread(entries, max); + if(n > 0 && copyout(p->pagetable, dst, (char *)entries, + n * sizeof(struct elog_entry)) < 0) + return -1; + + return n; +} \ No newline at end of file diff --git a/test-xv6.py b/test-xv6.py old mode 100755 new mode 100644 diff --git a/user/sustainlog.c b/user/sustainlog.c new file mode 100644 index 0000000000..821ffdba6f --- /dev/null +++ b/user/sustainlog.c @@ -0,0 +1,119 @@ +#include "kernel/types.h" +#include "kernel/stat.h" +#include "kernel/elog.h" +#include "user/user.h" + +static char * +event_name(int event_type) +{ + switch(event_type){ + case EVENT_SENSOR_UPDATE: + return "sensor-update"; + case EVENT_THRESHOLD_EXCEEDED: + return "threshold-exceeded"; + case EVENT_BACK_TO_NORMAL: + return "back-to-normal"; + case EVENT_INVALID_READING: + return "invalid-reading"; + default: + return "unknown"; + } +} + +static char * +sensor_name(int sensor_id) +{ + switch(sensor_id){ + case SENSOR_TEMPERATURE: + return "temperature"; + case SENSOR_AIR_QUALITY: + return "air-quality"; + case SENSOR_HUMIDITY: + return "humidity"; + case SENSOR_ENERGY_USAGE: + return "energy"; + case SENSOR_WATER_USAGE: + return "water"; + default: + return "unknown"; + } +} + +static void +usage(void) +{ + printf("usage:\n"); + printf(" sustainlog demo\n"); + printf(" sustainlog show\n"); + printf(" sustainlog log \n"); + printf("sensor ids: 1=temp 2=air 3=humidity 4=energy 5=water\n"); + exit(1); +} + +static void +print_logs(void) +{ + struct elog_entry entries[ELOG_SIZE]; + int n; + + n = getlogs(entries, ELOG_SIZE); + if(n < 0){ + printf("sustainlog: getlogs failed\n"); + exit(1); + } + + printf("sustainability log entries: %d\n", n); + for(int i = 0; i < n; i++){ + printf("[%d] sensor=%s event=%s value=%d\n", + entries[i].timestamp, + sensor_name(entries[i].sensor_id), + event_name(entries[i].event_type), + entries[i].value); + } +} + +static void +must_log(int event_type, int sensor_id, int value) +{ + if(logevent(event_type, sensor_id, value) < 0){ + printf("sustainlog: logevent failed\n"); + exit(1); + } +} + +static void +add_demo_entries(void) +{ + must_log(EVENT_SENSOR_UPDATE, SENSOR_TEMPERATURE, 24); + must_log(EVENT_SENSOR_UPDATE, SENSOR_HUMIDITY, 61); + must_log(EVENT_THRESHOLD_EXCEEDED, SENSOR_AIR_QUALITY, 151); + must_log(EVENT_THRESHOLD_EXCEEDED, SENSOR_ENERGY_USAGE, 92); + must_log(EVENT_BACK_TO_NORMAL, SENSOR_AIR_QUALITY, 73); + must_log(EVENT_INVALID_READING, SENSOR_WATER_USAGE, -1); +} + +int +main(int argc, char **argv) +{ + if(argc == 1 || strcmp(argv[1], "demo") == 0){ + add_demo_entries(); + print_logs(); + exit(0); + } + + if(strcmp(argv[1], "show") == 0){ + print_logs(); + exit(0); + } + + if(strcmp(argv[1], "log") == 0){ + if(argc != 5) + usage(); + must_log(atoi(argv[2]), atoi(argv[3]), atoi(argv[4])); + print_logs(); + exit(0); + } + + usage(); + return 0; +} diff --git a/user/user.h b/user/user.h index ac84de9609..a99ee1e528 100644 --- a/user/user.h +++ b/user/user.h @@ -1,6 +1,7 @@ #define SBRK_ERROR ((char *)-1) struct stat; +struct elog_entry; // system calls int fork(void); @@ -24,6 +25,8 @@ int getpid(void); char* sys_sbrk(int,int); int pause(int); int uptime(void); +int logevent(int event_type, int sensor_id, int value); +int getlogs(struct elog_entry *dst, int max); // ulib.c int stat(const char*, struct stat*); diff --git a/user/usys.pl b/user/usys.pl old mode 100755 new mode 100644 index c5d4c3a750..ef14de2f18 --- a/user/usys.pl +++ b/user/usys.pl @@ -42,3 +42,5 @@ sub entry { entry("sbrk"); entry("pause"); entry("uptime"); +entry("logevent"); +entry("getlogs"); From c83f4dbb7a357f3e60cde99a9fa83ffadec84e01 Mon Sep 17 00:00:00 2001 From: nathan-nw Date: Sat, 4 Apr 2026 16:37:04 -0400 Subject: [PATCH 2/2] test if working --- Makefile | 2 + kernel/alert.c | 125 +++++++++++++++++++++++++++++++++++ kernel/alert.h | 30 +++++++++ kernel/main.c | 2 + kernel/syscall.c | 4 ++ kernel/syscall.h | 4 +- kernel/sysfile.c | 42 ++++++++++++ user/alertsys.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++ user/user.h | 3 + user/usys.pl | 2 + 10 files changed, 379 insertions(+), 1 deletion(-) create mode 100644 kernel/alert.c create mode 100644 kernel/alert.h create mode 100644 user/alertsys.c diff --git a/Makefile b/Makefile index 7e7955f724..efda7899fe 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ OBJS = \ $K/spinlock.o \ $K/string.o \ $K/elog.o \ + $K/alert.o \ $K/main.o \ $K/vm.o \ $K/proc.o \ @@ -144,6 +145,7 @@ UPROGS=\ $U/_wc\ $U/_zombie\ $U/_sustainlog\ + $U/_alertsys\ $U/_logstress\ $U/_forphan\ $U/_dorphan\ diff --git a/kernel/alert.c b/kernel/alert.c new file mode 100644 index 0000000000..435a2ceee4 --- /dev/null +++ b/kernel/alert.c @@ -0,0 +1,125 @@ +// kernel/alert.c +#include "types.h" +#include "riscv.h" +#include "spinlock.h" +#include "defs.h" +#include "alert.h" +#include "elog.h" + +extern uint ticks; +extern struct spinlock tickslock; + +struct { + struct spinlock lock; + struct alert_threshold thresholds[MAX_SENSORS]; + struct alert_entry buf[ALERT_BUF_SIZE]; + int next_index; + int count; +} alertsys; + +static int +getticksafe(void) +{ + int t; + acquire(&tickslock); + t = ticks; + release(&tickslock); + return t; +} + +void +alertinit(void) +{ + initlock(&alertsys.lock, "alert"); + alertsys.next_index = 0; + alertsys.count = 0; + for(int i = 0; i < MAX_SENSORS; i++){ + alertsys.thresholds[i].active = 0; + } +} + +int +alertsetthreshold(int sensor_id, int min_val, int max_val) +{ + if(sensor_id < 1 || sensor_id > MAX_SENSORS) + return -1; + if(min_val > max_val) + return -1; + + acquire(&alertsys.lock); + + struct alert_threshold *t = &alertsys.thresholds[sensor_id - 1]; + t->sensor_id = sensor_id; + t->min_val = min_val; + t->max_val = max_val; + t->active = 1; + + release(&alertsys.lock); + return 0; +} + +void +alertcheck(int sensor_id, int value) +{ + int exceeded = 0; + int thresh_val = 0; + + if(sensor_id < 1 || sensor_id > MAX_SENSORS) + return; + + acquire(&alertsys.lock); + + struct alert_threshold *t = &alertsys.thresholds[sensor_id - 1]; + if(t->active){ + if(value > t->max_val){ + exceeded = 1; + thresh_val = t->max_val; + } else if(value < t->min_val){ + exceeded = 1; + thresh_val = t->min_val; + } + + if(exceeded){ + struct alert_entry *e = &alertsys.buf[alertsys.next_index]; + e->timestamp = getticksafe(); + e->sensor_id = sensor_id; + e->value = value; + e->threshold = thresh_val; + e->alert_type = ALERT_WARNING; + + alertsys.next_index = (alertsys.next_index + 1) % ALERT_BUF_SIZE; + if(alertsys.count < ALERT_BUF_SIZE) + alertsys.count++; + } + } + + release(&alertsys.lock); + + // Log threshold breach into elog system (after releasing alert lock) + if(exceeded) + elogadd(EVENT_THRESHOLD_EXCEEDED, sensor_id, value); +} + +int +alertgetpending(struct alert_entry *dst, int max) +{ + int i, n, start; + + if(dst == 0 || max <= 0) + return 0; + + acquire(&alertsys.lock); + + n = alertsys.count; + if(max < n) + n = max; + + start = (alertsys.next_index - alertsys.count + ALERT_BUF_SIZE) % ALERT_BUF_SIZE; + + for(i = 0; i < n; i++){ + dst[i] = alertsys.buf[(start + i) % ALERT_BUF_SIZE]; + } + + release(&alertsys.lock); + return n; +} diff --git a/kernel/alert.h b/kernel/alert.h new file mode 100644 index 0000000000..7d95dc98ad --- /dev/null +++ b/kernel/alert.h @@ -0,0 +1,30 @@ +#ifndef _ALERT_H_ +#define _ALERT_H_ + +#define MAX_SENSORS 5 +#define ALERT_BUF_SIZE 32 + +#define ALERT_WARNING 1 +#define ALERT_CRITICAL 2 + +struct alert_threshold { + int sensor_id; + int min_val; + int max_val; + int active; +}; + +struct alert_entry { + int timestamp; + int sensor_id; + int value; + int threshold; + int alert_type; +}; + +void alertinit(void); +void alertcheck(int sensor_id, int value); +int alertsetthreshold(int sensor_id, int min_val, int max_val); +int alertgetpending(struct alert_entry *dst, int max); + +#endif diff --git a/kernel/main.c b/kernel/main.c index 10e79721c0..dcd69c35c7 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -4,6 +4,7 @@ #include "riscv.h" #include "defs.h" #include "elog.h" +#include "alert.h" volatile static int started = 0; @@ -30,6 +31,7 @@ main() fileinit(); // file table virtio_disk_init(); // emulated hard disk eloginit(); // initialize logging system + alertinit(); // initialize alert system userinit(); // first user process __sync_synchronize(); started = 1; diff --git a/kernel/syscall.c b/kernel/syscall.c index 06b842ac66..2e5eeba18f 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -103,6 +103,8 @@ extern uint64 sys_mkdir(void); extern uint64 sys_close(void); extern uint64 sys_logevent(void); extern uint64 sys_getlogs(void); +extern uint64 sys_setalert(void); +extern uint64 sys_getalerts(void); // An array mapping syscall numbers from syscall.h // to the function that handles the system call. @@ -130,6 +132,8 @@ static uint64 (*syscalls[])(void) = { [SYS_close] sys_close, [SYS_logevent] sys_logevent, [SYS_getlogs] sys_getlogs, +[SYS_setalert] sys_setalert, +[SYS_getalerts] sys_getalerts, }; void diff --git a/kernel/syscall.h b/kernel/syscall.h index eeec2b16c9..a9f4cdd708 100644 --- a/kernel/syscall.h +++ b/kernel/syscall.h @@ -21,4 +21,6 @@ #define SYS_mkdir 20 #define SYS_close 21 #define SYS_logevent 22 -#define SYS_getlogs 23 \ No newline at end of file +#define SYS_getlogs 23 +#define SYS_setalert 24 +#define SYS_getalerts 25 \ No newline at end of file diff --git a/kernel/sysfile.c b/kernel/sysfile.c index ea24c7182c..c0ee0ab4a6 100644 --- a/kernel/sysfile.c +++ b/kernel/sysfile.c @@ -16,6 +16,7 @@ #include "file.h" #include "fcntl.h" #include "elog.h" +#include "alert.h" // Fetch the nth word-sized system call argument as a file descriptor // and return both the descriptor and the corresponding struct file. @@ -520,6 +521,11 @@ sys_logevent(void) return -1; elogadd(event_type, sensor_id, value); + + // Auto-check thresholds on normal sensor updates + if(event_type == EVENT_SENSOR_UPDATE) + alertcheck(sensor_id, value); + return 0; } @@ -544,5 +550,41 @@ sys_getlogs(void) n * sizeof(struct elog_entry)) < 0) return -1; + return n; +} + +uint64 +sys_setalert(void) +{ + int sensor_id, min_val, max_val; + + argint(0, &sensor_id); + argint(1, &min_val); + argint(2, &max_val); + + return alertsetthreshold(sensor_id, min_val, max_val); +} + +uint64 +sys_getalerts(void) +{ + uint64 dst; + int max, n; + struct proc *p = myproc(); + struct alert_entry entries[ALERT_BUF_SIZE]; + + argaddr(0, &dst); + argint(1, &max); + + if(max < 0) + return -1; + if(max > ALERT_BUF_SIZE) + max = ALERT_BUF_SIZE; + + n = alertgetpending(entries, max); + if(n > 0 && copyout(p->pagetable, dst, (char *)entries, + n * sizeof(struct alert_entry)) < 0) + return -1; + return n; } \ No newline at end of file diff --git a/user/alertsys.c b/user/alertsys.c new file mode 100644 index 0000000000..9870a1ff3f --- /dev/null +++ b/user/alertsys.c @@ -0,0 +1,166 @@ +#include "kernel/types.h" +#include "kernel/stat.h" +#include "kernel/alert.h" +#include "kernel/elog.h" +#include "user/user.h" + +static char * +sensor_name(int sensor_id) +{ + switch(sensor_id){ + case SENSOR_TEMPERATURE: + return "temperature"; + case SENSOR_AIR_QUALITY: + return "air-quality"; + case SENSOR_HUMIDITY: + return "humidity"; + case SENSOR_ENERGY_USAGE: + return "energy"; + case SENSOR_WATER_USAGE: + return "water"; + default: + return "unknown"; + } +} + +static void +usage(void) +{ + printf("usage:\n"); + printf(" alertsys demo\n"); + printf(" alertsys show\n"); + printf(" alertsys setthresh \n"); + printf("sensor ids: 1=temp 2=air 3=humidity 4=energy 5=water\n"); + exit(1); +} + +static void +print_alerts(void) +{ + struct alert_entry entries[ALERT_BUF_SIZE]; + int n; + + n = getalerts(entries, ALERT_BUF_SIZE); + if(n < 0){ + printf("alertsys: getalerts failed\n"); + exit(1); + } + + printf("--- alerts: %d ---\n", n); + for(int i = 0; i < n; i++){ + printf("[tick %d] ALERT: sensor=%s value=%d exceeded threshold=%d\n", + entries[i].timestamp, + sensor_name(entries[i].sensor_id), + entries[i].value, + entries[i].threshold); + } +} + +static void +print_logs(void) +{ + struct elog_entry entries[ELOG_SIZE]; + int n; + + n = getlogs(entries, ELOG_SIZE); + if(n < 0){ + printf("alertsys: getlogs failed\n"); + exit(1); + } + + printf("--- event log: %d entries ---\n", n); + for(int i = 0; i < n; i++){ + char *etype; + switch(entries[i].event_type){ + case EVENT_SENSOR_UPDATE: etype = "sensor-update"; break; + case EVENT_THRESHOLD_EXCEEDED: etype = "threshold-exceeded"; break; + case EVENT_BACK_TO_NORMAL: etype = "back-to-normal"; break; + case EVENT_INVALID_READING: etype = "invalid-reading"; break; + default: etype = "unknown"; break; + } + printf("[tick %d] sensor=%s event=%s value=%d\n", + entries[i].timestamp, + sensor_name(entries[i].sensor_id), + etype, + entries[i].value); + } +} + +static void +demo(void) +{ + printf("Setting thresholds for all sensors...\n"); + setalert(SENSOR_TEMPERATURE, 0, 35); + printf(" temperature: min=0 max=35\n"); + setalert(SENSOR_AIR_QUALITY, 0, 150); + printf(" air-quality: min=0 max=150\n"); + setalert(SENSOR_HUMIDITY, 20, 80); + printf(" humidity: min=20 max=80\n"); + setalert(SENSOR_ENERGY_USAGE, 0, 90); + printf(" energy: min=0 max=90\n"); + setalert(SENSOR_WATER_USAGE, 0, 100); + printf(" water: min=0 max=100\n"); + printf("\n"); + + printf("Logging sensor readings...\n"); + + // Normal readings (no alert) + logevent(EVENT_SENSOR_UPDATE, SENSOR_TEMPERATURE, 24); + printf(" temperature=24 (normal)\n"); + + logevent(EVENT_SENSOR_UPDATE, SENSOR_HUMIDITY, 55); + printf(" humidity=55 (normal)\n"); + + logevent(EVENT_SENSOR_UPDATE, SENSOR_WATER_USAGE, 50); + printf(" water=50 (normal)\n"); + + // Readings that exceed thresholds (trigger alerts) + logevent(EVENT_SENSOR_UPDATE, SENSOR_TEMPERATURE, 38); + printf(" temperature=38 (EXCEEDS max=35)\n"); + + logevent(EVENT_SENSOR_UPDATE, SENSOR_AIR_QUALITY, 160); + printf(" air-quality=160 (EXCEEDS max=150)\n"); + + logevent(EVENT_SENSOR_UPDATE, SENSOR_ENERGY_USAGE, 95); + printf(" energy=95 (EXCEEDS max=90)\n"); + + printf("\n"); + print_alerts(); + printf("\n"); + print_logs(); +} + +int +main(int argc, char **argv) +{ + if(argc < 2) + usage(); + + if(strcmp(argv[1], "demo") == 0){ + demo(); + exit(0); + } + + if(strcmp(argv[1], "show") == 0){ + print_alerts(); + exit(0); + } + + if(strcmp(argv[1], "setthresh") == 0){ + if(argc != 5) + usage(); + int sid = atoi(argv[2]); + int lo = atoi(argv[3]); + int hi = atoi(argv[4]); + if(setalert(sid, lo, hi) < 0){ + printf("alertsys: setalert failed (bad args)\n"); + exit(1); + } + printf("threshold set: sensor=%s min=%d max=%d\n", + sensor_name(sid), lo, hi); + exit(0); + } + + usage(); + return 0; +} diff --git a/user/user.h b/user/user.h index a99ee1e528..bffcd9e3cf 100644 --- a/user/user.h +++ b/user/user.h @@ -2,6 +2,7 @@ struct stat; struct elog_entry; +struct alert_entry; // system calls int fork(void); @@ -27,6 +28,8 @@ int pause(int); int uptime(void); int logevent(int event_type, int sensor_id, int value); int getlogs(struct elog_entry *dst, int max); +int setalert(int sensor_id, int min_val, int max_val); +int getalerts(struct alert_entry *dst, int max); // ulib.c int stat(const char*, struct stat*); diff --git a/user/usys.pl b/user/usys.pl index ef14de2f18..07115eb7eb 100644 --- a/user/usys.pl +++ b/user/usys.pl @@ -44,3 +44,5 @@ sub entry { entry("uptime"); entry("logevent"); entry("getlogs"); +entry("setalert"); +entry("getalerts");