소스 검색

ser2net: add patch for LED activity support

This adds a patch for ser2net, so that ser2net can be configured
to flash leds on serial traffic. This could -for example- be used
to have an activity indicator, like netdev trigger.
Internally, the linux kernel's 'transient' led trigger is used.

Signed-off-by: Michael Heimpold <mhei@heimpold.de>
Michael Heimpold 10 년 전
부모
커밋
c380283137
2개의 변경된 파일419개의 추가작업 그리고 1개의 파일을 삭제
  1. 1
    1
      net/ser2net/Makefile
  2. 418
    0
      net/ser2net/patches/002-LED-trigger.patch

+ 1
- 1
net/ser2net/Makefile 파일 보기

@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
9 9
 
10 10
 PKG_NAME:=ser2net
11 11
 PKG_VERSION:=2.10.0
12
-PKG_RELEASE:=1
12
+PKG_RELEASE:=2
13 13
 
14 14
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
15 15
 PKG_SOURCE_URL:=@SF/ser2net

+ 418
- 0
net/ser2net/patches/002-LED-trigger.patch 파일 보기

@@ -0,0 +1,418 @@
1
+From fa68debd94d40299dd2a69abd0a820ccfaadcbe8 Mon Sep 17 00:00:00 2001
2
+From: Michael Heimpold <michael.heimpold@i2se.com>
3
+Date: Wed, 22 Apr 2015 13:35:43 +0200
4
+Subject: [PATCH] Add support for triggering LEDs during serial traffic
5
+
6
+Signed-off-by: Michael Heimpold <michael.heimpold@i2se.com>
7
+---
8
+
9
+Patch sent upstream:
10
+    http://sourceforge.net/p/ser2net/mailman/message/34064847/
11
+
12
+ Makefile.am  |    4 +--
13
+ dataxfer.c   |   20 ++++++++++++
14
+ readconfig.c |  100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
15
+ ser2net.conf |   13 ++++++++
16
+ sysfs-led.c  |   43 +++++++++++++++++++++++++
17
+ sysfs-led.h  |   11 +++++++
18
+ utils.c      |   30 ++++++++++++++++++
19
+ utils.h      |    9 ++++++
20
+ 8 files changed, 228 insertions(+), 2 deletions(-)
21
+ create mode 100644 sysfs-led.c
22
+ create mode 100644 sysfs-led.h
23
+
24
+diff --git a/Makefile.am b/Makefile.am
25
+index d56179f..866eb89 100644
26
+--- a/Makefile.am
27
++++ b/Makefile.am
28
+@@ -2,9 +2,9 @@ sbin_PROGRAMS = ser2net
29
+ ACLOCAL_AMFLAGS = -I m4
30
+ AM_CFLAGS=-Wall
31
+ ser2net_SOURCES = controller.c dataxfer.c devcfg.c readconfig.c selector.c \
32
+-	ser2net.c utils.c telnet.c buffer.c
33
++	ser2net.c utils.c telnet.c buffer.c sysfs-led.c
34
+ noinst_HEADERS = controller.h dataxfer.h devio.h readconfig.h selector.h \
35
+-	utils.h telnet.h buffer.h ser2net.h
36
++	utils.h telnet.h buffer.h sysfs-led.h ser2net.h
37
+ man_MANS = ser2net.8
38
+ EXTRA_DIST = $(man_MANS) ser2net.conf ser2net.spec ser2net.init
39
+ 
40
+diff --git a/dataxfer.c b/dataxfer.c
41
+index 646a71b..b99cabf 100644
42
+--- a/dataxfer.c
43
++++ b/dataxfer.c
44
+@@ -42,6 +42,7 @@
45
+ #include "telnet.h"
46
+ #include "devio.h"
47
+ #include "buffer.h"
48
++#include "sysfs-led.h"
49
+ 
50
+ #define SERIAL "term"
51
+ #define NET    "tcp "
52
+@@ -230,6 +231,12 @@ typedef struct port_info
53
+ #ifdef USE_RS485_FEATURE
54
+     struct serial_rs485 *rs485conf;
55
+ #endif
56
++
57
++    /*
58
++     * LED names to flash for serial traffic
59
++     */
60
++    char *led_tx;
61
++    char *led_rx;
62
+ } port_info_t;
63
+ 
64
+ port_info_t *ports = NULL; /* Linked list of ports. */
65
+@@ -311,6 +318,8 @@ init_port_data(port_info_t *port)
66
+ #ifdef USE_RS485_FEATURE
67
+     port->rs485conf = NULL;
68
+ #endif
69
++    port->led_tx = NULL;
70
++    port->led_rx = NULL;
71
+ }
72
+ 
73
+ static void
74
+@@ -530,6 +539,9 @@ handle_dev_fd_read(struct devio *io)
75
+ 	/* Do both tracing, ignore errors. */
76
+ 	do_trace(port, port->tb, port->dev_to_tcp.buf, count, SERIAL);
77
+ 
78
++    if (port->led_rx)
79
++	led_blink_kick(port->led_rx);
80
++
81
+     port->dev_bytes_received += count;
82
+ 
83
+     if (port->enabled == PORT_TELNET) {
84
+@@ -759,6 +771,8 @@ handle_tcp_fd_read(int fd, void *data)
85
+ 	    return;
86
+ 	}
87
+     } else {
88
++	if (port->led_tx)
89
++	    led_blink_kick(port->led_tx);
90
+ 	port->dev_bytes_sent += count;
91
+ 	port->tcp_to_dev.cursize -= count;
92
+ 	if (port->tcp_to_dev.cursize != 0) {
93
+@@ -1854,6 +1868,12 @@ myconfig(void *data, struct absout *eout, const char *pos)
94
+     } else if (strncmp(pos, "tb=", 3) == 0) {
95
+ 	/* trace both directions. */
96
+ 	port->trace_both.filename = find_tracefile(pos + 3);
97
++    } else if (strncmp(pos, "led-rx=", 7) == 0) {
98
++	/* LED for UART RX traffic */
99
++	port->led_rx = find_led(pos + 7);
100
++    } else if (strncmp(pos, "led-tx=", 7) == 0) {
101
++	/* LED for UART TX traffic */
102
++	port->led_tx = find_led(pos + 7);
103
+ #ifdef USE_RS485_FEATURE
104
+     } else if (strncmp(pos, "rs485=", 6) == 0) {
105
+ 	/* get RS485 configuration. */
106
+diff --git a/readconfig.c b/readconfig.c
107
+index d4ca0d4..62cff5c 100644
108
+--- a/readconfig.c
109
++++ b/readconfig.c
110
+@@ -31,6 +31,7 @@
111
+ #include "readconfig.h"
112
+ #include "utils.h"
113
+ #include "telnet.h"
114
++#include "sysfs-led.h"
115
+ 
116
+ #define MAX_LINE_SIZE 256	/* Maximum line length in the config file. */
117
+ 
118
+@@ -361,6 +362,89 @@ free_rs485confs(void)
119
+ }
120
+ #endif
121
+ 
122
++struct led_s
123
++{
124
++    char *name;
125
++    char *device;
126
++    unsigned int duration;
127
++    struct led_s *next;
128
++};
129
++
130
++/* all LEDs in the system. */
131
++struct led_s *leds = NULL;
132
++
133
++static void
134
++handle_led(char *name, char *cfg)
135
++{
136
++    struct led_s *new_led;
137
++    char devicename[256];
138
++
139
++    new_led = malloc(sizeof(*new_led));
140
++    if (!new_led) {
141
++	syslog(LOG_ERR, "Out of memory handling LED on %d", lineno);
142
++	return;
143
++    }
144
++
145
++    new_led->name = strdup(name);
146
++    if (!new_led->name) {
147
++	syslog(LOG_ERR, "Out of memory handling LED on %d", lineno);
148
++	free(new_led);
149
++	return;
150
++    }
151
++
152
++    if (sscanf(cfg, "%256s %u", devicename, &new_led->duration) != 2) {
153
++	syslog(LOG_ERR, "Couldn't parse LED config on %d", lineno);
154
++	free(new_led->name);
155
++	free(new_led);
156
++	return;
157
++    }
158
++
159
++    new_led->device = strdup(devicename);
160
++    if (!new_led->device) {
161
++	syslog(LOG_ERR, "Out of memory handling LED on %d", lineno);
162
++	free(new_led->name);
163
++	free(new_led);
164
++	return;
165
++    }
166
++
167
++    /* setup the led */
168
++    led_blink_prepare(new_led->device, new_led->duration);
169
++
170
++    new_led->next = leds;
171
++    leds = new_led;
172
++}
173
++
174
++char *
175
++find_led(const char *name)
176
++{
177
++    struct led_s *led = leds;
178
++
179
++    while (led) {
180
++	if (strcmp(name, led->name) == 0)
181
++	    return strdup(led->device);
182
++	led = led->next;
183
++    }
184
++    syslog(LOG_ERR, "LED %s not found, it will be ignored", name);
185
++    return NULL;
186
++}
187
++
188
++static void
189
++free_leds(void)
190
++{
191
++    struct led_s *led;
192
++
193
++    while (leds) {
194
++	led = leds;
195
++	leds = leds->next;
196
++
197
++	led_off(led->device);
198
++
199
++	free(led->name);
200
++	free(led->device);
201
++	free(led);
202
++    }
203
++}
204
++
205
+ static int
206
+ startswith(char *str, const char *test, char **strtok_data)
207
+ {
208
+@@ -503,6 +587,21 @@ handle_config_line(char *inbuf)
209
+ 	return;
210
+     }
211
+ 
212
++    if (startswith(inbuf, "LED", &strtok_data)) {
213
++	char *name = strtok_r(NULL, ":", &strtok_data);
214
++	char *str = strtok_r(NULL, "\n", &strtok_data);
215
++	if (name == NULL) {
216
++	    syslog(LOG_ERR, "No LED name given on line %d", lineno);
217
++	    return;
218
++	}
219
++	if ((str == NULL) || (strlen(str) == 0)) {
220
++	    syslog(LOG_ERR, "No LED given on line %d", lineno);
221
++	    return;
222
++	}
223
++	handle_led(name, str);
224
++	return;
225
++    }
226
++
227
+     comma = strchr(inbuf, ',');
228
+     if (comma) {
229
+ 	if (!strtok_r(comma, ":", &strtok_data)) {
230
+@@ -568,6 +667,7 @@ readconfig(char *filename)
231
+ #ifdef USE_RS485_FEATURE
232
+     free_rs485confs();
233
+ #endif
234
++    free_leds();
235
+ 
236
+     config_num++;
237
+ 
238
+diff --git a/ser2net.conf b/ser2net.conf
239
+index 870926c..dc2ba19 100644
240
+--- a/ser2net.conf
241
++++ b/ser2net.conf
242
+@@ -53,6 +53,8 @@
243
+ #            specified in TRACEFILE that will take all traced data.
244
+ #            tw is data written to the device, tr is data read from
245
+ #            the device, and tb is both.
246
++#            The "led-tx" and "led-rx" options allow to specify
247
++#            a LED defined above to trigger for traffic.
248
+ #
249
+ # or...
250
+ 
251
+@@ -79,6 +81,12 @@
252
+ #    This specifies a filename to trace output into, as tw=/tmp/trace1.
253
+ #    This takes the same escape sequences as banners.
254
+ #
255
++#  LED:<name>:sysfs-filename duration
256
++#    This specifies a LED which will be configured to use linux's transient trigger.
257
++#    The LED is always kicked when traffic is detected on serial side. The duration
258
++#    is given in milliseconds. See Linux's documentation for transient trigger for
259
++#    details.
260
++#
261
+ #  OPENSTR:<name>:str
262
+ #    This specifies a string to be transmitted to the device when the
263
+ #    port is opened.  This takes the same escape sequences as banners.
264
+@@ -108,6 +116,9 @@ SIGNATURE:signature1:ser2net port ttyS2
265
+ 
266
+ RS485CONF:rs485port1:0:0:0:0
267
+ 
268
++LED:rx:duckbill:green:rs485 10
269
++LED:tx:duckbill:red:rs485 10
270
++
271
+ TRACEFILE:tw1:/tmp/tw-\p-\Y-\M-\D-\H:\i:\s.\U
272
+ TRACEFILE:tr1:/tmp/tr-\p-\Y-\M-\D-\H:\i:\s.\U
273
+ 
274
+@@ -138,3 +149,5 @@ CLOSESTR:close1:close str\r\n
275
+ 
276
+ 3020:telnet:0:/dev/ttyUSB0:9600 banner1 remctl asdfasd
277
+ 3021:telnet:0:/dev/ttyUSB1:9600 banner2 open1 close1 remctl
278
++
279
++5000:telnet:0:/dev/ttyAPP0:9600 NONE 1STOPBIT 8DATABITS -XONXOFF LOCAL -RTSCTS led-tx=tx led-rx=rx
280
+diff --git a/sysfs-led.c b/sysfs-led.c
281
+new file mode 100644
282
+index 0000000..efe0b29
283
+--- /dev/null
284
++++ b/sysfs-led.c
285
+@@ -0,0 +1,43 @@
286
++/*
287
++ * Copyright (C) 2015 I2SE GmbH
288
++ */
289
++#include <stdio.h>
290
++#include <string.h>
291
++
292
++#include "utils.h"
293
++#include "sysfs-led.h"
294
++
295
++#define SYSFS_LED_BASE "/sys/class/leds"
296
++
297
++static int led_write(char *led, char *property, char *buf)
298
++{
299
++    char fn[255];
300
++
301
++    snprintf(fn, sizeof(fn), "%s/%s/%s", SYSFS_LED_BASE, led, property);
302
++    
303
++    return file_store(fn, buf, strlen(buf));
304
++}
305
++
306
++int led_off(char *led)
307
++{
308
++    led_write(led, "trigger", "none");
309
++    led_write(led, "brightness", "0");
310
++    return 0;
311
++}
312
++
313
++int led_blink_prepare(char *led, unsigned int duration)
314
++{
315
++    char buffer[10];
316
++
317
++    snprintf(buffer, sizeof(buffer), "%u", duration);
318
++    led_write(led, "trigger", "transient");
319
++    msleep(10);
320
++    led_write(led, "state", "1");
321
++    led_write(led, "duration", buffer);
322
++    return 0;
323
++}
324
++
325
++int led_blink_kick(char *led)
326
++{
327
++    return led_write(led, "activate", "1");
328
++}
329
+diff --git a/sysfs-led.h b/sysfs-led.h
330
+new file mode 100644
331
+index 0000000..00b21b6
332
+--- /dev/null
333
++++ b/sysfs-led.h
334
+@@ -0,0 +1,11 @@
335
++/*
336
++ * Copyright (C) 2015 I2SE GmbH
337
++ */
338
++#ifndef SYSFS_LED_H
339
++#define SYSFS_LED_H
340
++
341
++int led_off(char *led);
342
++int led_blink_prepare(char *led, unsigned int duration);
343
++int led_blink_kick(char *led);
344
++
345
++#endif /* SYSFS_LED_H */
346
+diff --git a/utils.c b/utils.c
347
+index c194c4c..c96cedb 100644
348
+--- a/utils.c
349
++++ b/utils.c
350
+@@ -25,6 +25,9 @@
351
+ #include <errno.h>
352
+ #include <unistd.h>
353
+ #include <fcntl.h>
354
++#include <time.h>
355
++#include <sys/types.h>
356
++#include <sys/stat.h>
357
+ 
358
+ #include "ser2net.h"
359
+ #include "utils.h"
360
+@@ -205,3 +208,30 @@ write_ignore_fail(int fd, const char *data, size_t count)
361
+ 	count -= written;
362
+     }
363
+ }
364
++
365
++int
366
++msleep(int msec)
367
++{
368
++    struct timespec req;
369
++
370
++    req.tv_sec = 0;
371
++    req.tv_nsec = msec * 1000000;
372
++
373
++    return nanosleep(&req, NULL);
374
++}
375
++
376
++int
377
++file_store(const char *filename, const char *buf, size_t count)
378
++{
379
++    int fd;
380
++
381
++    if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) == -1)
382
++            return -1;
383
++
384
++    if (write(fd, buf, count) != count) {
385
++            close(fd);
386
++            return -1;
387
++    }
388
++
389
++    return close(fd);
390
++}
391
+diff --git a/utils.h b/utils.h
392
+index 582ea88..8af65ec 100644
393
+--- a/utils.h
394
++++ b/utils.h
395
+@@ -64,6 +64,9 @@ char *find_tracefile(const char *name);
396
+ /* Search for RS485 configuration by name. */
397
+ struct serial_rs485 *find_rs485conf(const char *name);
398
+ 
399
++/* Search for a LED by name */
400
++char *find_led(const char *name);
401
++
402
+ void check_ipv6_only(int family, struct sockaddr *addr, int fd);
403
+ 
404
+ /* Make sure the full contents get written, return an error if it occurs. */
405
+@@ -72,4 +75,10 @@ int write_full(int fd, char *data, size_t count);
406
+ /* Write the data completely out, return without comment on error. */
407
+ void write_ignore_fail(int fd, const char *data, size_t count);
408
+ 
409
++/* Helper to sleep a given amount of milli-seconds */
410
++int msleep(int msec);
411
++
412
++/* Store the given data to a file */
413
++int file_store(const char *filename, const char *buf, size_t count);
414
++
415
+ #endif /* UTILS */
416
+-- 
417
+1.7.10.4
418
+