]> mj.ucw.cz Git - home-hw.git/blob - bsb/daemon/burrow-bsb.c
BSB: Receiving of frames and passing of statistics
[home-hw.git] / bsb / daemon / burrow-bsb.c
1 /*
2  *      Boiler System Bus Interface Daemon
3  *
4  *      (c) 2020 Martin Mares <mj@ucw.cz>
5  */
6
7 #include <stdarg.h>
8 #include <stdio.h>
9 #include <stdint.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13
14 #include <libusb-1.0/libusb.h>
15
16 static struct libusb_context *usb_ctxt;
17 static struct libusb_device_handle *devh;
18
19 typedef unsigned char byte;
20 typedef unsigned int uint;
21
22 static void die(const char *msg, ...)
23 {
24         va_list args;
25         va_start(args, msg);
26
27         vfprintf(stderr, msg, args);
28         fputc('\n', stderr);
29
30         exit(1);
31 }
32
33 static void usb_error(const char *msg, ...)
34 {
35         va_list args;
36         va_start(args, msg);
37         vfprintf(stderr, msg, args);
38         fputc('\n', stderr);
39         va_end(args);
40
41         if (devh) {
42                 libusb_close(devh);
43                 devh = NULL;
44         }
45 }
46
47 static void open_device(void)
48 {
49         int err;
50         libusb_device **devlist;
51         ssize_t devn = libusb_get_device_list(usb_ctxt, &devlist);
52         if (devn < 0)
53                 die("Cannot enumerate USB devices: error %d", (int) devn);
54
55         for (ssize_t i=0; i<devn; i++) {
56                 struct libusb_device_descriptor desc;
57                 libusb_device *dev = devlist[i];
58                 if (!libusb_get_device_descriptor(dev, &desc)) {
59                         if (desc.idVendor == 0x4242 && desc.idProduct == 0x0003) {
60                                 fprintf(stderr, "Found device at usb%d.%d\n", libusb_get_bus_number(dev), libusb_get_device_address(dev));
61
62                                 if (err = libusb_open(dev, &devh)) {
63                                         usb_error("Cannot open device: error %d", err);
64                                         goto out;
65                                 }
66                                 libusb_reset_device(devh);
67                                 if (err = libusb_claim_interface(devh, 0)) {
68                                         usb_error("Cannot claim interface: error %d", err);
69                                         goto out;
70                                 }
71
72                                 goto out;
73                         }
74                 }
75         }
76
77 out:
78         libusb_free_device_list(devlist, 1);
79 }
80
81 static inline uint get_u32_le(byte *p)
82 {
83         return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
84 }
85
86 int main(void)
87 {
88         int err;
89         if (err = libusb_init(&usb_ctxt))
90                 die("Cannot initialize libusb: error %d", err);
91         // libusb_set_debug(usb_ctxt, 3);
92         open_device();
93
94         for (;;) {
95                 if (!devh) {
96                         fprintf(stderr, "Waiting for device to appear...\n");
97                         while (!devh) {
98                                 sleep(5);
99                                 open_device();
100                         }
101                 }
102
103 #if 0
104                 int received;
105                 byte resp[64];
106                 if (err = libusb_bulk_transfer(devh, 0x81, resp, 64, &received, 2000)) {
107                         usb_error("Receive failed: error %d", err);
108                         continue;
109                 }
110
111                 printf("Received %d bytes\n", received);
112                 if (received < 4) {
113                         usb_error("Receive failed: unexpected response size %d", received);
114                         continue;
115                 }
116
117                 printf("-> %02x%02x%02x%02x\n", resp[0], resp[1], resp[2], resp[3]);
118 #elif 0
119                 int received;
120                 byte resp[64];
121                 if (err = libusb_interrupt_transfer(devh, 0x82, resp, 64, &received, 100)) {
122                         usb_error("Receive failed: error %d", err);
123                         continue;
124                 }
125
126                 printf("Interrupt received %d bytes\n", received);
127                 if (received < 4) {
128                         usb_error("Receive failed: unexpected response size %d", received);
129                         continue;
130                 }
131
132                 printf("-> %02x%02x%02x%02x\n", resp[0], resp[1], resp[2], resp[3]);
133 #else
134                 byte resp[64];
135                 int received;
136                 if ((received = libusb_control_transfer(devh, 0xc0, 0x00, 0, 0, resp, sizeof(resp), 100)) < 0) {
137                         usb_error("Receive failed: error %d", received);
138                         continue;
139                 }
140
141                 printf("Stats:");
142                 for (int i=0; i+3 < received; i+=4)
143                         printf(" %u", get_u32_le(resp+i));
144                 printf("\n");
145 #endif
146
147                 sleep(1);
148         }
149 }