commit be9e7a3db765ad5bc860b8a6311725996756f0e1
parent f215c8bfb3234cf083fb492cf27b8cbf8fd8fe4e
Author: amin <dev@aminmesbah.com>
Date: Sat, 15 Jan 2022 06:41:34 +0000
Get data from co2mini and write it to tmp files
FossilOrigin-Name: 63c61e3c471aff0e29b97813ff1bd255a466fe24d8b84f3e127cc1b974f9d4de
Diffstat:
M | main.c | | | 148 | ++++++++++++++++++++++++++++++++++++++++++++----------------------------------- |
1 file changed, 83 insertions(+), 65 deletions(-)
diff --git a/main.c b/main.c
@@ -4,98 +4,116 @@
#include <stdio.h>
#include <stdint.h>
-#include <fcntl.h> // open()
-#include <sys/ioctl.h> // ioctl()
-#include <unistd.h> // close()
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+// https://www.kernel.org/doc/Documentation/hid/hidraw.txt
#include <linux/hidraw.h>
-typedef uint8_t buffer[8];
+static bool running = true;
+
+void stop_running(int sig)
+{
+ running = false;
+}
// Made possible by Henryk Plötz' excellent work:
// https://hackaday.io/project/5301-reverse-engineering-a-low-cost-usb-co-monitor
+int main(void)
+{
+ {
+ struct sigaction act = {0};
+ act.sa_handler = stop_running;
+ sigaction(SIGINT, &act, NULL);
+ sigaction(SIGKILL, &act, NULL);
+ sigaction(SIGTERM, &act, NULL);
+ }
-// references
-// https://www.kernel.org/doc/Documentation/hid/hidraw.txt
-int main(void) {
// NOTE: Included udev rules create this symlink to the appropriate hidraw
// entry.
int device_handle = open("/dev/co2mini0", O_RDWR);
- if (device_handle < 0) {
- printf("ERROR: Failed to open hid\n");
+ if (device_handle < 0)
+ {
+ printf("ERROR: Failed to open HID.\n");
return 1;
}
- buffer key = {0};
- int result = ioctl(device_handle, HIDIOCSFEATURE(sizeof(key)), key);
- if (result < 0 || result != sizeof(buffer)) {
- printf("ERROR: Failed to send feature report\n");
- return 1;
+ {
+ uint8_t key[8] = {0};
+ int result = ioctl(device_handle, HIDIOCSFEATURE(sizeof(key)), key);
+ if (result < 0 || result != sizeof(key))
+ {
+ printf("ERROR: Failed to send feature report.\n");
+ return 1;
+ }
}
- while (true) {
- buffer data = {0};
- int bytes_read = read(device_handle, &data, sizeof(buffer));
- if (bytes_read < 0 && (errno == EAGAIN || errno == EINPROGRESS)) {
+ const char *temperature_file_path = "/tmp/co2mini_temp";
+ const char *co2_file_path = "/tmp/co2mini_co2";
+
+ while (running)
+ {
+ uint8_t data[8] = {0};
+ int bytes_read = read(device_handle, &data, sizeof(data));
+ if (bytes_read < 0 && (errno == EAGAIN || errno == EINPROGRESS))
+ {
bytes_read = 0;
- } else {
- assert(bytes_read == sizeof(buffer));
}
- if (bytes_read == sizeof(buffer)) {
- buffer decoded = {0};
- {
- {
- uint8_t tmp;
- tmp = data[0]; data[0] = data[2]; data[2] = tmp;
- tmp = data[1]; data[1] = data[4]; data[4] = tmp;
- tmp = data[3]; data[3] = data[7]; data[7] = tmp;
- tmp = data[5]; data[5] = data[6]; data[6] = tmp;
- }
+ uint8_t item = data[0];
+ uint8_t msb = data[1];
+ uint8_t lsb = data[2];
+ uint8_t checksum = data[3];
+ uint8_t end = data[4];
- for (int i = 0; i < sizeof(buffer); ++i) {
- data[i] ^= key[i];
- }
+ if (bytes_read == sizeof(data)
+ && end == 0x0d
+ && (item == 0x42 || item == 0x50)
+ && item + msb + lsb == checksum)
+ {
- {
- uint8_t tmp = (data[7] << 5);
- decoded[7] = (data[6] << 5) | (data[7] >> 3);
- decoded[6] = (data[5] << 5) | (data[6] >> 3);
- decoded[5] = (data[4] << 5) | (data[5] >> 3);
- decoded[4] = (data[3] << 5) | (data[4] >> 3);
- decoded[3] = (data[2] << 5) | (data[3] >> 3);
- decoded[2] = (data[1] << 5) | (data[2] >> 3);
- decoded[1] = (data[0] << 5) | (data[1] >> 3);
- decoded[0] = tmp | (data[0] >> 3);
- }
+ uint16_t value = (((uint16_t)msb) << 8) | lsb;
+ char buf[1024] = {0};
+ int str_len = 0;
+ mode_t create_mode = S_IRUSR | S_IWUSR;
+ int open_mode = O_WRONLY | O_CREAT | O_TRUNC;
- buffer dumb_proprietary_bullshit_secret_word = "Htemp99e";
- for (int i = 0; i < sizeof(buffer); ++i)
+ switch(item)
+ {
+ case 0x42:
{
- decoded[i] -= (dumb_proprietary_bullshit_secret_word[i] << 4) | (dumb_proprietary_bullshit_secret_word[i] >> 4);
- }
- }
+ double t_celsius = value / 16.0 - 273.15;
+ str_len = snprintf(buf, sizeof(buf), "%.2f", t_celsius);
+ assert(str_len > 0);
+ int f = open(temperature_file_path, open_mode, create_mode);
+ if (f == -1)
+ {
+ return 1;
+ }
+ write(f, buf, str_len);
+ close(f);
+ } break;
- if (decoded[4] != 0x0d) {
- printf("BAD DATA: ");
- } else {
- switch(decoded[0]) {
- case 0x42:
- printf("Temperature: ");
- break; case 0x50:
- printf("CO2: ");
- break;
- }
- }
-
- for (int i = 0; i < sizeof(buffer); i++) {
- printf("[%i]: %X ", i, decoded[i]);
+ case 0x50:
+ {
+ str_len = snprintf(buf, sizeof(buf), "%d", value);
+ assert(str_len > 0);
+ int f = open(co2_file_path, open_mode, create_mode);
+ if (f == -1)
+ {
+ return 1;
+ }
+ write(f, buf, str_len);
+ close(f);
+ } break;
}
-
- printf("\n");
}
}
+ unlink(co2_file_path);
+ unlink(temperature_file_path);
close(device_handle);
return 0;
}