]>
cvs.zerfleddert.de Git - hmcfgusb/blob - hmsniff.c
638ae1d4e96847e7c7ac178a5a95496abd3be78f
   1 /* HM-sniffer for HM-CFG-USB 
   3  * Copyright (c) 2013-16 Michael Gernoth <michael@gernoth.net> 
   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: 
  12  * The above copyright notice and this permission notice shall be included in 
  13  * all copies or substantial portions of the Software. 
  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 
  34 #include <libusb-1.0/libusb.h> 
  39 #include "hmuartlgw.h" 
  42 static int verbose 
= 0; 
  45 char *hm_message_types(uint8_t type
, uint8_t subtype
) 
  52                         return "Configuration"; 
  55                         if (subtype 
>= 0x80 && subtype 
<= 0x8f) { 
  57                         } else if (subtype 
== 0x01) { 
  59                         } else if (subtype 
== 0x04) { 
  92                         return "Water sensor"; 
  98                         return "Climate event"; 
 101                         return "Thermal control"; 
 105                         return "Power event"; 
 108                         return "Weather event"; 
 114                         return "Rf configuration"; 
 122 static void dissect_hm(uint8_t *buf
, int len
) 
 127         static int count 
= 0; 
 130         gettimeofday(&tv
, NULL
); 
 131         tmp 
= localtime(&tv
.tv_sec
); 
 132         memset(ts
, 0, sizeof(ts
)); 
 133         strftime(ts
, sizeof(ts
)-1, "%Y-%m-%d %H:%M:%S", tmp
); 
 136                 printf("%s.%06ld: ", ts
, tv
.tv_usec
); 
 138                 for (i 
= 0; i 
< len
; i
++) { 
 139                         printf("%02X", buf
[i
]); 
 142                 printf("Packet information:\n"); 
 143                 printf("\tLength: %u\n", buf
[0]); 
 144                 printf("\tMessage ID: %u\n", buf
[1]); 
 145                 printf("\tSender: %02x%02x%02x\n", buf
[4], buf
[5], buf
[6]); 
 146                 printf("\tReceiver: %02x%02x%02x\n", buf
[7], buf
[8], buf
[9]); 
 147                 printf("\tControl Byte: 0x%02x\n", buf
[2]); 
 148                 printf("\t\tFlags: "); 
 149                 if (buf
[2] & (1 << 0)) printf("WAKEUP "); 
 150                 if (buf
[2] & (1 << 1)) printf("WAKEMEUP "); 
 151                 if (buf
[2] & (1 << 2)) printf("CFG "); 
 152                 if (buf
[2] & (1 << 3)) printf("? "); 
 153                 if (buf
[2] & (1 << 4)) printf("BURST "); 
 154                 if (buf
[2] & (1 << 5)) printf("BIDI "); 
 155                 if (buf
[2] & (1 << 6)) printf("RPTED "); 
 156                 if (buf
[2] & (1 << 7)) printf("RPTEN "); 
 158                 printf("\tMessage type: %s (0x%02x 0x%02x)\n", hm_message_types(buf
[3], buf
[10]), buf
[3], buf
[10]); 
 159                 printf("\tMessage: "); 
 160                 for (i 
= 10; i 
< len
; i
++) { 
 161                         printf("%02X", buf
[i
]); 
 168                         printf("                         LL NR FL CM sender recvr  payload\n"); 
 170                 printf("%s.%03ld: %02X %02X %02X %02X %02X%02X%02X %02X%02X%02X ", 
 172                                 buf
[0], buf
[1], buf
[2], buf
[3], 
 173                                 buf
[4], buf
[5], buf
[6], 
 174                                 buf
[7], buf
[8], buf
[9]); 
 176                 for (i 
= 10; i 
< len
; i
++) { 
 177                         printf("%02X", buf
[i
]); 
 179                 printf("%s(%s)\n", (i
>10)?" ":"", hm_message_types(buf
[3], buf
[10])); 
 187 static int parse_hmcfgusb(uint8_t *buf
, int buf_len
, void *data
) 
 189         struct recv_data 
*rdata 
= data
; 
 196                         dissect_hm(buf 
+ 13, buf
[13] + 1); 
 199                         if ((buf
[27] != 0x00) || 
 202                                 printf("hmId is currently set to: %02x%02x%02x\n", buf
[27], buf
[28], buf
[29]); 
 203                                 rdata
->wrong_hmid 
= 1; 
 211                         hexdump(buf
, buf_len
, "Unknown> "); 
 218 static int parse_hmuartlgw(enum hmuartlgw_dst dst
, uint8_t *buf
, int buf_len
, void *data
) 
 220         if (dst 
== HMUARTLGW_OS
) { 
 221                 if ((buf
[0] != HMUARTLGW_OS_ACK
) || 
 223                         hexdump(buf
, buf_len
, "OS> "); 
 228         if (dst 
!= HMUARTLGW_APP
) { 
 233                 case HMUARTLGW_APP_RECV
: 
 234                         dissect_hm(buf 
+ 3, buf_len 
- 3); 
 235                 case HMUARTLGW_APP_ACK
: 
 238                         hexdump(buf
, buf_len
, "Unknown> "); 
 244 void hmsniff_syntax(char *prog
) 
 246         fprintf(stderr
, "Syntax: %s options\n\n", prog
); 
 247         fprintf(stderr
, "Possible options:\n"); 
 248         fprintf(stderr
, "\t-f\t\tfast (100k/firmware update) mode\n"); 
 249         fprintf(stderr
, "\t-S serial\tuse HM-CFG-USB with given serial\n"); 
 250         fprintf(stderr
, "\t-U device\tuse HM-MOD-UART on given device\n"); 
 251         fprintf(stderr
, "\t-v\t\tverbose mode\n"); 
 252         fprintf(stderr
, "\t-V\t\tshow version (" VERSION 
")\n"); 
 256 int main(int argc
, char **argv
) 
 258         struct hm_dev dev 
= { 0 }; 
 259         struct recv_data rdata
; 
 267         dev
.type 
= DEVICE_TYPE_HMCFGUSB
; 
 269         while((opt 
= getopt(argc
, argv
, "fS:U:vV")) != -1) { 
 279                                 dev
.type 
= DEVICE_TYPE_HMUARTLGW
; 
 285                                 printf("hmsniff " VERSION 
"\n"); 
 286                                 printf("Copyright (c) 2013-16 Michael Gernoth\n\n"); 
 292                                 hmsniff_syntax(argv
[0]); 
 298         if (dev
.type 
== DEVICE_TYPE_HMCFGUSB
) { 
 299                 hmcfgusb_set_debug(0); 
 301                 hmuartlgw_set_debug(0); 
 305                 memset(&rdata
, 0, sizeof(rdata
)); 
 306                 rdata
.wrong_hmid 
= 0; 
 308                 if (dev
.type 
== DEVICE_TYPE_HMCFGUSB
) { 
 309                         dev
.hmcfgusb 
= hmcfgusb_init(parse_hmcfgusb
, &rdata
, serial
); 
 311                                 fprintf(stderr
, "Can't initialize HM-CFG-USB, retrying in 1s...\n"); 
 315                         printf("HM-CFG-USB opened!\n"); 
 317                         hmcfgusb_send_null_frame(dev
.hmcfgusb
, 1); 
 318                         hmcfgusb_send(dev
.hmcfgusb
, (unsigned char*)"K", 1, 1); 
 320                         hmcfgusb_send_null_frame(dev
.hmcfgusb
, 1); 
 323                         hmcfgusb_send(dev
.hmcfgusb
, buf
, 2, 1); 
 325                         dev
.hmuartlgw 
= hmuart_init(uart
, parse_hmuartlgw
, &rdata
); 
 326                         if (!dev
.hmuartlgw
) { 
 327                                 fprintf(stderr
, "Can't initialize HM-MOD-UART!\n"); 
 330                         printf("HM-MOD-UART opened!\n"); 
 332                         buf
[0] = HMUARTLGW_APP_SET_HMID
; 
 336                         hmuartlgw_send(dev
.hmuartlgw
, buf
, 4, HMUARTLGW_APP
); 
 337                         do { hmuartlgw_poll(dev
.hmuartlgw
, 500); } while (errno 
!= ETIMEDOUT
); 
 339                                 buf
[0] = HMUARTLGW_OS_UPDATE_MODE
; 
 342                                 hmuartlgw_send(dev
.hmuartlgw
, buf
, 3, HMUARTLGW_OS
); 
 344                                 buf
[0] = HMUARTLGW_OS_NORMAL_MODE
; 
 345                                 hmuartlgw_send(dev
.hmuartlgw
, buf
, 1, HMUARTLGW_OS
); 
 352                         if (rdata
.wrong_hmid
) { 
 353                                 printf("changing hmId to 000000, this might reboot the device!\n"); 
 354                                 if (dev
.type 
== DEVICE_TYPE_HMCFGUSB
) { 
 355                                         hmcfgusb_send(dev
.hmcfgusb
, (unsigned char*)"A\00\00\00", 4, 1); 
 356                                         rdata
.wrong_hmid 
= 0; 
 357                                         hmcfgusb_send(dev
.hmcfgusb
, (unsigned char*)"K", 1, 1); 
 359                                         buf
[0] = HMUARTLGW_APP_SET_HMID
; 
 363                                         hmuartlgw_send(dev
.hmuartlgw
, buf
, 4, HMUARTLGW_APP
); 
 366                         if (dev
.type 
== DEVICE_TYPE_HMCFGUSB
) { 
 367                                 fd 
= hmcfgusb_poll(dev
.hmcfgusb
, 1000); 
 369                                 fd 
= hmuartlgw_poll(dev
.hmuartlgw
, 60000); 
 372                                 fprintf(stderr
, "activity on unknown fd %d!\n", fd
); 
 374                         } else if (fd 
== -1) { 
 376                                         if (errno 
!= ETIMEDOUT
) { 
 377                                                 perror("hmsniff_poll"); 
 380                                                 /* periodically wakeup the device */ 
 381                                                 if (dev
.type 
== DEVICE_TYPE_HMCFGUSB
) { 
 382                                                         hmcfgusb_send_null_frame(dev
.hmcfgusb
, 1); 
 389                 if (dev
.type 
== DEVICE_TYPE_HMCFGUSB
) { 
 391                                 hmcfgusb_close(dev
.hmcfgusb
); 
 394                                 hmuartlgw_close(dev
.hmuartlgw
); 
 398         if (dev
.type 
== DEVICE_TYPE_HMCFGUSB
) {