#include "moisture_sensor.h" #include #include /* the most readings one session can send; the sensor keeps its own copy */ #define SENSOR_LIMIT 64 static int total; static int sent; static int minute; static int level; static int sent_times[SENSOR_LIMIT]; static int sent_levels[SENSOR_LIMIT]; /* * srand() fixes where rand() starts, so the same seed sends the same readings * every run on one machine. Different C libraries may still send different ones. * Reference: https://en.cppreference.com/w/c/numeric/random/rand */ void sensor_start(unsigned int seed, int readings) { srand(seed); total = readings < 0 ? 0 : (readings > SENSOR_LIMIT ? SENSOR_LIMIT : readings); sent = 0; minute = 0; } static int next_level(void) { int kind = rand() % 20; if (kind < 2) { return -(1 + rand() % 5); /* a sensor fault */ } if (kind < 4) { return 0; /* dry */ } if (kind < 7) { return 101 + rand() % 20; /* saturated */ } return 1 + rand() % 100; } int sensor_has_next(void) { if (sent >= total) { return 0; } minute = minute + 1 + rand() % 15; level = next_level(); sent_times[sent] = minute; sent_levels[sent] = level; sent = sent + 1; printf("sensor: minute %d, level %d\n", minute, level); return 1; } int sensor_time(void) { return minute; } int sensor_level(void) { return level; } void sensor_check_log(int times[], int levels[], size_t count) { size_t want = 0; int i; for (i = 0; i < sent; i++) { if (sent_levels[i] < 0) { continue; } if (want == count) { printf("check: FAIL, minute %d (level %d) is valid but was not stored\n", sent_times[i], sent_levels[i]); return; } if (times[want] != sent_times[i] || levels[want] != sent_levels[i]) { printf("check: FAIL, slot %zu holds minute %d level %d; expected minute %d level %d\n", want, times[want], levels[want], sent_times[i], sent_levels[i]); return; } want = want + 1; } if (want != count) { printf("check: FAIL, count is %zu but the sensor sent %zu valid reading(s)\n", count, want); return; } printf("check: PASS, all %zu valid reading(s) stored in order\n", count); }