hmsniff: fix typo
[hmcfgusb] / hmsniff.c
CommitLineData
d57fdaf6
MG
1/* HM-sniffer for HM-CFG-USB
2 *
3 * Copyright (c) 2013 Michael Gernoth <michael@gernoth.net>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <unistd.h>
27#include <stdint.h>
28#include <string.h>
29#include <strings.h>
30#include <poll.h>
31#include <errno.h>
e2776af8 32#include <sys/time.h>
d57fdaf6
MG
33#include <libusb-1.0/libusb.h>
34
c44f15b8 35#include "version.h"
d57fdaf6
MG
36#include "hexdump.h"
37#include "hmcfgusb.h"
38
39/* See HMConfig.pm */
40char *hm_message_types(uint8_t type)
41{
42 switch(type) {
43 case 0x00:
44 return "Device Info";
45 break;
46 case 0x01:
47 return "Configuration";
48 break;
49 case 0x02:
50 return "Acknowledge";
51 break;
52 case 0x03:
53 return "AES";
54 break;
55 case 0x04:
56 return "AES-Key";
57 break;
58 case 0x10:
59 return "Information";
60 break;
61 case 0x11:
62 return "SET";
63 break;
64 case 0x12:
65 return "HAVE_DATA";
66 break;
67 case 0x3e:
68 return "Switch";
69 break;
70 case 0x3f:
71 return "Timestamp";
72 break;
73 case 0x40:
74 return "Remote";
75 break;
76 case 0x41:
77 return "Sensor";
78 break;
79 case 0x53:
80 return "Water sensor";
81 break;
82 case 0x58:
83 return "Climate event";
84 break;
85 case 0x70:
86 return "Weather event";
87 break;
88 default:
89 return "?";
90 break;
91 }
92}
93
94static void dissect_hm(uint8_t *buf, int len)
95{
e2776af8
MG
96 struct timeval tv;
97 struct tm *tmp;
98 char ts[32];
d57fdaf6
MG
99 int i;
100
e2776af8
MG
101 gettimeofday(&tv, NULL);
102 tmp = localtime(&tv.tv_sec);
103 memset(ts, 0, sizeof(ts));
104 strftime(ts, sizeof(ts)-1, "%Y-%m-%d %H:%M:%S", tmp);
105 printf("%s.%06ld: ", ts, tv.tv_usec);
106
d57fdaf6
MG
107 for (i = 0; i < len; i++) {
108 printf("%02X", buf[i]);
109 }
110 printf("\n");
111 printf("Packet information:\n");
112 printf("\tLength: %u\n", buf[0]);
113 printf("\tMessage ID: %u\n", buf[1]);
114 printf("\tSender: %02x%02x%02x\n", buf[4], buf[5], buf[6]);
115 printf("\tReceiver: %02x%02x%02x\n", buf[7], buf[8], buf[9]);
116 printf("\tControl Byte: 0x%02x\n", buf[2]);
117 printf("\t\tFlags: ");
118 if (buf[2] & (1 << 0)) printf("WAKEUP ");
119 if (buf[2] & (1 << 1)) printf("WAKEMEUP ");
82922278 120 if (buf[2] & (1 << 2)) printf("CFG ");
d57fdaf6
MG
121 if (buf[2] & (1 << 3)) printf("? ");
122 if (buf[2] & (1 << 4)) printf("BURST ");
123 if (buf[2] & (1 << 5)) printf("BIDI ");
124 if (buf[2] & (1 << 6)) printf("RPTED ");
125 if (buf[2] & (1 << 7)) printf("RPTEN ");
126 printf("\n");
127 printf("\tMessage type: %s (0x%02x)\n", hm_message_types(buf[3]), buf[3]);
63351c23 128 printf("\tMessage: ");
d57fdaf6
MG
129 for (i = 10; i < len; i++) {
130 printf("%02X", buf[i]);
131 }
132 printf("\n");
133
134 printf("\n");
135
136}
137
885a84e3
MG
138struct recv_data {
139 int wrong_hmid;
140};
141
4371275b 142static int parse_hmcfgusb(uint8_t *buf, int buf_len, void *data)
d57fdaf6 143{
885a84e3
MG
144 struct recv_data *rdata = data;
145
d57fdaf6 146 if (buf_len < 1)
4371275b 147 return 1;
d57fdaf6
MG
148
149 switch(buf[0]) {
150 case 'E':
151 dissect_hm(buf + 13, buf[13] + 1);
152 break;
153 case 'H':
885a84e3
MG
154 if ((buf[27] != 0x00) ||
155 (buf[28] != 0x00) ||
156 (buf[29] != 0x00)) {
157 printf("hmId is currently set to: %02x%02x%02x\n", buf[27], buf[28], buf[29]);
158 rdata->wrong_hmid = 1;
159 }
160 break;
d57fdaf6
MG
161 case 'R':
162 case 'I':
163 break;
164 default:
165 hexdump(buf, buf_len, "Unknown> ");
166 break;
167 }
4371275b
MG
168
169 return 1;
d57fdaf6
MG
170}
171
d57fdaf6
MG
172int main(int argc, char **argv)
173{
174 struct hmcfgusb_dev *dev;
885a84e3 175 struct recv_data rdata;
d57fdaf6
MG
176 int quit = 0;
177
178 hmcfgusb_set_debug(0);
179
885a84e3
MG
180 do {
181 memset(&rdata, 0, sizeof(rdata));
182 rdata.wrong_hmid = 0;
d57fdaf6 183
885a84e3
MG
184 dev = hmcfgusb_init(parse_hmcfgusb, &rdata);
185 if (!dev) {
186 fprintf(stderr, "Can't initialize HM-CFG-USB, retrying in 1s...\n");
187 sleep(1);
188 continue;
189 }
190 printf("HM-CFG-USB opened!\n");
d57fdaf6 191
6262005e 192 hmcfgusb_send_null_frame(dev, 1);
885a84e3 193 hmcfgusb_send(dev, (unsigned char*)"K", 1, 1);
d57fdaf6 194
885a84e3
MG
195 while(!quit) {
196 int fd;
197
198 if (rdata.wrong_hmid) {
199 printf("changing hmId to 000000, this might reboot the device!\n");
200 hmcfgusb_send(dev, (unsigned char*)"A\00\00\00", 4, 1);
201 rdata.wrong_hmid = 0;
202 hmcfgusb_send(dev, (unsigned char*)"K", 1, 1);
203 }
3b35a8c1 204 fd = hmcfgusb_poll(dev, 1000);
885a84e3
MG
205 if (fd >= 0) {
206 fprintf(stderr, "activity on unknown fd %d!\n", fd);
207 continue;
208 } else if (fd == -1) {
209 if (errno) {
1e79d00a
MG
210 if (errno != ETIMEDOUT) {
211 perror("hmcfgusb_poll");
212 break;
213 } else {
214 /* periodically wakeup the device */
215 hmcfgusb_send_null_frame(dev, 1);
216 }
885a84e3 217 }
d57fdaf6
MG
218 }
219 }
d57fdaf6 220
885a84e3
MG
221 hmcfgusb_close(dev);
222 } while (!quit);
223
018f85fa
MG
224 hmcfgusb_exit();
225
d57fdaf6
MG
226 return EXIT_SUCCESS;
227}
Impressum, Datenschutz