libusb-based driver for HM-CFG-USB and an initial HM-CFG-LAN emulation
[hmcfgusb] / hmland.c
1 /* HM-CFG-LAN emuldation 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>
32 #include <libusb-1.0/libusb.h>
33
34 #include "hexdump.h"
35 #include "hmcfgusb.h"
36
37 void hmlan_format_out(uint8_t *buf, int buf_len, void *data)
38 {
39 int len;
40 int i;
41
42 if (buf_len < 1)
43 return;
44
45 //FIXME: Buffer here and write to fd_out
46 printf("%c", buf[0]);
47 switch(buf[0]) {
48 case 'H':
49 buf[5]='L';
50 buf[6]='A';
51 buf[7]='N';
52 len = buf[1];
53 for (i = 2; i < len + 2; i++) {
54 printf("%c", buf[i]);
55 }
56 printf(",%02X%02X,", buf[i],
57 buf[i+1]);
58 i+=2;
59 len = buf[i]+i+1;
60 i++;
61 for (; i < len; i++) {
62 printf("%c", buf[i]);
63 }
64 printf(",");
65 len = i+12;
66 for (; i < len; i++) {
67 printf("%02X", buf[i]);
68 switch(len-i) {
69 case 10:
70 case 7:
71 case 3:
72 printf(",");
73 break;
74 default:
75 break;
76 }
77 }
78
79 break;
80 case 'E':
81 len = 13 + buf[13];
82 for (i = 0; i < len; i++) {
83 if (i != 12)
84 printf("%02X", buf[1+i]);
85 switch(i) {
86 case 2:
87 case 4:
88 case 8:
89 case 9:
90 case 11:
91 printf(",");
92 break;
93 default:
94 break;
95 }
96 }
97 break;
98 case 'R':
99 len = 14 + buf[14];
100 for (i = 0; i < len; i++) {
101 if (i != 13)
102 printf("%02X", buf[1+i]);
103 switch(i) {
104 case 3:
105 case 5:
106 case 9:
107 case 10:
108 case 12:
109 printf(",");
110 break;
111 default:
112 break;
113 }
114 }
115 break;
116 case 'I':
117 //HM> 0x0000: 49 00 00 00 00 55 53 42 2d 49 46 03 bc 0a 4a 45 I....USB-IF...JE
118 //HM> 0x0010: 51 30 35 33 35 31 32 32 1d b1 55 68 ea 13 00 14 Q0535122..Uh....
119 //HM> 0x0020: 9f a6 00 03 00 00 00 00 00 00 00 00 00 00 00 00 ................
120 //HM> 0x0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
121 default:
122 for (i = 1; i < buf_len; i++)
123 printf("%02X", buf[i]);
124 hexdump(buf, buf_len, "Unknown> ");
125 break;
126 }
127 printf("\n");
128 }
129
130 void hmlan_parse_in(int fd, void *data)
131 {
132 struct hmcfgusb_dev *dev = data;
133 unsigned char buf[1024];
134 unsigned char send_buf[0x40]; //FIXME!!!
135 char tmp[3];
136 int i;
137 int r;
138
139 r = read(fd, buf, sizeof(buf));
140 if (r > 0) {
141 int cnt;
142
143 memset(send_buf, 0, sizeof(send_buf));
144 for (i = 0; i < r; i++) {
145 if ((buf[i] == 0x0a) ||
146 (buf[i] == 0x0d)) {
147 r = i;
148 break;
149 }
150 }
151
152 send_buf[0] = buf[0];
153
154 cnt = 0;
155 for (i = 1; i < r; i++) {
156 if (buf[i] == ',') {
157 switch (buf[0]) {
158 case 'S':
159 if (cnt == 4) {
160 /* Add msg length */
161 memmove(buf+i+2, buf+i+1, r-(i+1));
162 snprintf(tmp, 3, "%02X", (int)((r-(i+1))/2));
163 memcpy(buf+i, tmp, 2);
164 r++;
165 break;
166 }
167 default:
168 memmove(buf+i, buf+i+1, r-(i+1));
169 r--;
170 break;
171 }
172 cnt++;
173 }
174 }
175
176 memset(tmp, 0, sizeof(tmp));
177 for (i = 1; i < r; i+=2) {
178 memcpy(tmp, buf + i, 2);
179 send_buf[1+(i/2)] = strtoul(tmp, NULL, 16);
180 }
181 hmcfgusb_send(dev, send_buf, 1+(i/2), 1);
182 } else if (r < 0) {
183 perror("read");
184 }
185 }
186
187 int main(int argc, char **argv)
188 {
189 struct hmcfgusb_dev *dev;
190 int quit = 0;
191
192 dev = hmcfgusb_init(hmlan_format_out, NULL);
193 if (!dev) {
194 fprintf(stderr, "Can't initialize HM-CFG-USB!\n");
195 exit(EXIT_FAILURE);
196 }
197
198 if (!hmcfgusb_add_pfd(dev, STDIN_FILENO, POLLIN)) {
199 fprintf(stderr, "Can't add stdin to pollfd!\n");
200 exit(EXIT_FAILURE);
201 }
202
203 hmcfgusb_send(dev, (unsigned char*)"K", 1, 1);
204
205 while(!quit) {
206 int fd;
207
208 fd = hmcfgusb_poll(dev, 3600);
209 if (fd >= 0) {
210 hmlan_parse_in(fd, dev);
211 } else if (fd == -1) {
212 if (errno) {
213 perror("hmcfgusb_poll");
214 quit = 1;
215 }
216 }
217 }
218
219 libusb_close(NULL);
220
221 return EXIT_SUCCESS;
222 }
Impressum, Datenschutz