IEEE 802.15.4 subsystem
Sign in or create your account | Project List | Help
IEEE 802.15.4 subsystem Commit Details
Date: | 2011-04-10 22:45:19 (12 years 11 months ago) |
---|---|
Author: | Werner Almesberger |
Commit: | 39319e145a658a8eb149de7b43ac36af06a4da5e |
Message: | tools/lib/: added network proxy-based driver (in progress) - atnet.c: driver "net", which accessed hardware via atrf-proxy - Makefile (OBJS): added atnet.o - driver.h (atnet_driver), atrf.c (drivers): added the atnet driver - atrf.c (drivers): moved the driver list closer to the top |
Files: |
tools/lib/Makefile (1 diff) tools/lib/atnet.c (1 diff) tools/lib/atrf.c (2 diffs) tools/lib/driver.h (1 diff) |
Change Details
tools/lib/Makefile | ||
---|---|---|
19 | 19 | OBJS_ben_jlime = atben.o |
20 | 20 | OBJS_ben_openwrt = atben.o |
21 | 21 | |
22 | OBJS = atrf.o misctxrx.o cwtest.o netio.o $(OBJS_$(TARGET)) | |
22 | OBJS = atrf.o atnet.o misctxrx.o cwtest.o netio.o $(OBJS_$(TARGET)) | |
23 | 23 | |
24 | 24 | .PHONY: all clean spotless |
25 | 25 |
tools/lib/atnet.c | ||
---|---|---|
1 | /* | |
2 | * lib/atnet.c - Access functions library for network proxy | |
3 | * | |
4 | * Written 2011 by Werner Almesberger | |
5 | * Copyright 2011 Werner Almesberger | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation; either version 2 of the License, or | |
10 | * (at your option) any later version. | |
11 | */ | |
12 | ||
13 | ||
14 | #include <stdarg.h> | |
15 | #include <stdlib.h> | |
16 | #include <stdio.h> | |
17 | #include <string.h> | |
18 | #include <assert.h> | |
19 | #include <sys/types.h> | |
20 | #include <sys/socket.h> | |
21 | #include <netdb.h> | |
22 | ||
23 | #include "netio.h" | |
24 | ||
25 | #include "driver.h" | |
26 | ||
27 | ||
28 | #define DEFAULT_PORT "5440" | |
29 | ||
30 | ||
31 | static char reply[1000]; | |
32 | ||
33 | ||
34 | static int dialog_vsend(struct netio *netio, const char *fmt, va_list ap) | |
35 | { | |
36 | va_list ap2; | |
37 | char *buf; | |
38 | int n; | |
39 | ||
40 | va_copy(ap2, ap); | |
41 | n = vsnprintf(NULL, 0, fmt, ap2); | |
42 | ||
43 | buf = malloc(n+1); | |
44 | if (!buf) { | |
45 | perror("malloc"); | |
46 | return -1; | |
47 | } | |
48 | ||
49 | vsprintf(buf, fmt, ap); | |
50 | ||
51 | buf[n] = '\n'; | |
52 | if (netio_write(netio, buf, n+1) < 0) | |
53 | return -1; | |
54 | return 0; | |
55 | } | |
56 | ||
57 | ||
58 | static int dialog_send(struct netio *netio, const char *fmt, ...) | |
59 | { | |
60 | va_list ap; | |
61 | int res; | |
62 | ||
63 | va_start(ap, fmt); | |
64 | res = dialog_vsend(netio, fmt, ap); | |
65 | va_end(ap); | |
66 | return res; | |
67 | } | |
68 | ||
69 | ||
70 | static int dialog_recv(struct netio *netio) | |
71 | { | |
72 | int n; | |
73 | ||
74 | n = netio_read_until(netio, "\n", reply, sizeof(reply)-1, NULL); | |
75 | if (n < 0) | |
76 | return -1; | |
77 | reply[n] = 0; | |
78 | ||
79 | return reply[0] == '+' ? 0 : -1; | |
80 | } | |
81 | ||
82 | ||
83 | static int dialog(struct netio *netio, const char *fmt, ...) | |
84 | { | |
85 | va_list ap; | |
86 | int res; | |
87 | ||
88 | va_start(ap, fmt); | |
89 | res = dialog_vsend(netio, fmt, ap); | |
90 | va_end(ap); | |
91 | if (res < 0) | |
92 | return res; | |
93 | ||
94 | return dialog_recv(netio); | |
95 | } | |
96 | ||
97 | ||
98 | /* ----- error handling ---------------------------------------------------- */ | |
99 | ||
100 | ||
101 | static int error; | |
102 | ||
103 | ||
104 | static int atnet_error(void *dsc) | |
105 | { | |
106 | return error; | |
107 | } | |
108 | ||
109 | ||
110 | static int atnet_clear_error(void *dsc) | |
111 | { | |
112 | int ret; | |
113 | ||
114 | ret = error; | |
115 | error = 0; | |
116 | return ret; | |
117 | } | |
118 | ||
119 | ||
120 | /* ----- open/close -------------------------------------------------------- */ | |
121 | ||
122 | ||
123 | static void *atnet_open(const char *arg) | |
124 | { | |
125 | char *host = NULL, *comma; | |
126 | const char *port = DEFAULT_PORT; | |
127 | struct addrinfo *addrs; | |
128 | const struct addrinfo *addr; | |
129 | static struct addrinfo hint = { .ai_socktype = SOCK_STREAM }; | |
130 | int res, s; | |
131 | struct netio *netio; | |
132 | ||
133 | if (arg) { | |
134 | host = strdup(arg); | |
135 | if (!host) { | |
136 | perror("strdup"); | |
137 | return NULL; | |
138 | } | |
139 | comma = strchr(host, ','); | |
140 | if (comma) { | |
141 | *comma = 0; | |
142 | port = comma+1; | |
143 | } | |
144 | } | |
145 | res = getaddrinfo(arg && *host ? host : NULL, port, &hint, &addrs); | |
146 | if (res < 0) { | |
147 | fprintf(stderr, "%s: %s\n", arg, gai_strerror(res)); | |
148 | free(host); | |
149 | return NULL; | |
150 | } | |
151 | free(host); | |
152 | ||
153 | for (addr = addrs; addr; addr = addr->ai_next) { | |
154 | s = socket(addr->ai_family, addr->ai_socktype, | |
155 | addr->ai_protocol); | |
156 | if (s < 0) | |
157 | continue; | |
158 | if (connect(s, addr->ai_addr, addr->ai_addrlen) >= 0) | |
159 | break; | |
160 | close(s); | |
161 | } | |
162 | if (!addr) { | |
163 | perror(arg); | |
164 | freeaddrinfo(addrs); | |
165 | return NULL; | |
166 | } | |
167 | ||
168 | freeaddrinfo(addrs); | |
169 | ||
170 | netio = netio_open(s); | |
171 | if (!netio) | |
172 | return NULL; | |
173 | ||
174 | if (dialog_recv(netio) < 0) { | |
175 | netio_close(netio); | |
176 | return NULL; | |
177 | } | |
178 | ||
179 | error = 0; | |
180 | return netio; | |
181 | } | |
182 | ||
183 | ||
184 | static void atnet_close(void *dsc) | |
185 | { | |
186 | struct netio *netio = dsc; | |
187 | ||
188 | netio_close(netio); | |
189 | } | |
190 | ||
191 | ||
192 | /* ----- device mode ------------------------------------------------------- */ | |
193 | ||
194 | ||
195 | static void atnet_reset(void *dsc) | |
196 | { | |
197 | struct netio *netio = dsc; | |
198 | ||
199 | if (error) | |
200 | return; | |
201 | if (dialog(netio, "RESET") < 0) | |
202 | error = 1; | |
203 | } | |
204 | ||
205 | ||
206 | static void atnet_reset_rf(void *dsc) | |
207 | { | |
208 | struct netio *netio = dsc; | |
209 | ||
210 | if (error) | |
211 | return; | |
212 | if (dialog(netio, "RESET_RF") < 0) | |
213 | error = 1; | |
214 | } | |
215 | ||
216 | ||
217 | static void atnet_test_mode(void *dsc) | |
218 | { | |
219 | struct netio *netio = dsc; | |
220 | ||
221 | if (error) | |
222 | return; | |
223 | if (dialog(netio, "TEST") < 0) | |
224 | error = 1; | |
225 | } | |
226 | ||
227 | ||
228 | static void atnet_slp_tr(void *dsc, int on) | |
229 | { | |
230 | struct netio *netio = dsc; | |
231 | ||
232 | if (error) | |
233 | return; | |
234 | if (dialog(netio, "SLP_TR %d", on) < 0) | |
235 | error = 1; | |
236 | } | |
237 | ||
238 | ||
239 | /* ----- register access --------------------------------------------------- */ | |
240 | ||
241 | ||
242 | static void atnet_reg_write(void *dsc, uint8_t reg, uint8_t value) | |
243 | { | |
244 | struct netio *netio = dsc; | |
245 | ||
246 | if (error) | |
247 | return; | |
248 | if (dialog(netio, "SET 0x%02x 0x%02x", reg, value) < 0) | |
249 | error = 1; | |
250 | } | |
251 | ||
252 | ||
253 | static uint8_t atnet_reg_read(void *dsc, uint8_t reg) | |
254 | { | |
255 | struct netio *netio = dsc; | |
256 | unsigned long value; | |
257 | char *end; | |
258 | ||
259 | if (error) | |
260 | return; | |
261 | if (dialog(netio, "GET 0x%02x", reg) < 0) { | |
262 | error = 1; | |
263 | return 0; | |
264 | } | |
265 | value = strtoul(reply+1, &end, 0); | |
266 | if (*end || value > 255) { | |
267 | fprintf(stderr, "invalid response \"%s\"\n", reply); | |
268 | error = 1; | |
269 | return 0; | |
270 | } | |
271 | return value; | |
272 | } | |
273 | ||
274 | ||
275 | /* ----- frame buffer access ----------------------------------------------- */ | |
276 | ||
277 | ||
278 | static void atnet_buf_write(void *dsc, const void *buf, int size) | |
279 | { | |
280 | struct netio *netio = dsc; | |
281 | char tmp[20]; | |
282 | int n; | |
283 | ||
284 | if (error) | |
285 | return; | |
286 | ||
287 | n = snprintf(tmp, sizeof(tmp), "WRITE %d ", size); | |
288 | assert(n < sizeof(tmp)); | |
289 | if (netio_write(netio, tmp, n) < 0) { | |
290 | error = 1; | |
291 | return; | |
292 | } | |
293 | ||
294 | if (netio_write(netio, buf, size) < 0) { | |
295 | error = 1; | |
296 | return; | |
297 | } | |
298 | ||
299 | if (netio_write(netio, "\n", 1) < 0) { | |
300 | error = 1; | |
301 | return; | |
302 | } | |
303 | ||
304 | if (dialog_recv(netio) < 0) | |
305 | error = 1; | |
306 | } | |
307 | ||
308 | ||
309 | static int atnet_buf_read(void *dsc, void *buf, int size) | |
310 | { | |
311 | struct netio *netio = dsc; | |
312 | uint8_t tmp[200]; | |
313 | int n, got = 0; | |
314 | unsigned long len = 0; | |
315 | char *end; | |
316 | ||
317 | if (error) | |
318 | return -1; | |
319 | ||
320 | if (dialog_send(netio, "READ") < 0) | |
321 | goto fail; | |
322 | ||
323 | n = netio_read_until(netio, " ", tmp, sizeof(tmp)-1, NULL); | |
324 | if (*tmp == '-') { | |
325 | tmp[n] = 0; | |
326 | fprintf(stderr, "%s\n", tmp+1); | |
327 | goto fail; | |
328 | } | |
329 | if (*tmp != '+' || n < 3) /* +0<spc> */ | |
330 | goto invalid; | |
331 | len = strtoul(tmp+1, &end, 0); | |
332 | if (*end != ' ') | |
333 | goto invalid; | |
334 | if (len > size) { | |
335 | fprintf(stderr, "buffer overflow\n"); | |
336 | goto fail; | |
337 | } | |
338 | ||
339 | got = netio_read(netio, buf, len); | |
340 | if (got < 0) | |
341 | goto fail; | |
342 | ||
343 | if (netio_getc(netio, tmp) < 0) | |
344 | goto fail; | |
345 | if (*tmp == '\n') | |
346 | return len; | |
347 | ||
348 | invalid: | |
349 | fprintf(stderr, "invalid reponse\n"); | |
350 | fail: | |
351 | error = 1; | |
352 | return -1; | |
353 | } | |
354 | ||
355 | ||
356 | /* ----- RF interrupt ------------------------------------------------------ */ | |
357 | ||
358 | ||
359 | static int atnet_interrupt(void *dsc) | |
360 | { | |
361 | struct netio *netio = dsc; | |
362 | unsigned long value; | |
363 | char *end; | |
364 | ||
365 | if (error) | |
366 | return -1; | |
367 | if (dialog(netio, "POLL") < 0) { | |
368 | error = 1; | |
369 | return -1; | |
370 | } | |
371 | value = strtoul(reply+1, &end, 0); | |
372 | if (*end || value > 1) { | |
373 | fprintf(stderr, "invalid response \"%s\"\n", reply); | |
374 | error = 1; | |
375 | return -1; | |
376 | } | |
377 | return value; | |
378 | } | |
379 | ||
380 | ||
381 | /* ----- CLKM handling ----------------------------------------------------- */ | |
382 | ||
383 | ||
384 | static int atnet_set_clkm(void *dsc, int mhz) | |
385 | { | |
386 | struct netio *netio = dsc; | |
387 | ||
388 | return dialog(netio, "CLKM %d", mhz); | |
389 | } | |
390 | ||
391 | ||
392 | /* ----- driver interface -------------------------------------------------- */ | |
393 | ||
394 | ||
395 | struct atrf_driver atnet_driver = { | |
396 | .name = "net", | |
397 | .open = atnet_open, | |
398 | .close = atnet_close, | |
399 | .error = atnet_error, | |
400 | .clear_error = atnet_clear_error, | |
401 | .reset = atnet_reset, | |
402 | .reset_rf = atnet_reset_rf, | |
403 | .test_mode = atnet_test_mode, | |
404 | .slp_tr = atnet_slp_tr, | |
405 | .set_clkm = atnet_set_clkm, | |
406 | .reg_write = atnet_reg_write, | |
407 | .reg_read = atnet_reg_read, | |
408 | .buf_write = atnet_buf_write, | |
409 | .buf_read = atnet_buf_read, | |
410 | .interrupt = atnet_interrupt, | |
411 | }; |
tools/lib/atrf.c | ||
---|---|---|
28 | 28 | }; |
29 | 29 | |
30 | 30 | |
31 | static const struct atrf_driver *drivers[] = { | |
32 | #ifdef HAVE_BEN | |
33 | &atben_driver, | |
34 | #endif | |
35 | #ifdef HAVE_USB | |
36 | &atusb_driver, | |
37 | #endif | |
38 | &atnet_driver, | |
39 | NULL | |
40 | }; | |
41 | ||
42 | ||
31 | 43 | void *atrf_usb_handle(struct atrf_dsc *dsc) |
32 | 44 | { |
33 | 45 | #ifdef HAVE_USB |
... | ... | |
92 | 104 | } |
93 | 105 | |
94 | 106 | |
95 | const static struct atrf_driver *drivers[] = { | |
96 | #ifdef HAVE_BEN | |
97 | &atben_driver, | |
98 | #endif | |
99 | #ifdef HAVE_USB | |
100 | &atusb_driver, | |
101 | #endif | |
102 | NULL | |
103 | }; | |
104 | ||
105 | ||
106 | 107 | const char *atrf_default_driver_name(void) |
107 | 108 | { |
108 | 109 | return drivers[0] ? drivers[0]->name : "none"; |
tools/lib/driver.h | ||
---|---|---|
38 | 38 | |
39 | 39 | extern struct atrf_driver atusb_driver; |
40 | 40 | extern struct atrf_driver atben_driver; |
41 | extern struct atrf_driver atnet_driver; | |
41 | 42 | |
42 | 43 | |
43 | 44 | int atrf_set_clkm_generic( |