2 EIBD eib bus access and management daemon
3 Copyright (C) 2005-2007 Martin Koegler <mkoegler@auto.tuwien.ac.at>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "localserver.h"
29 #include "inetserver.h"
30 #include "eibnetserver.h"
31 #include "groupcacheclient.h"
33 /** structure to store the arguments */
38 /** path for unix domain socket */
40 /** path to pid file */
42 /** path to trace log file */
46 /** EIB address (for some backends) */
48 /* EIBnet/IP server */
55 /** storage for the arguments*/
58 /** aborts program with a printf like message */
60 die (const char *msg
, ...)
75 #include "layer2conf.h"
77 /** structure to store layer 2 backends */
82 /** factory function */
83 Layer2_Create_Func Create
;
87 struct urldef URLs
[] = {
89 #define L2_NAME(a) { a##_PREFIX, a##_CREATE },
90 #include "layer2create.h"
94 /** determines the right backend for the url and creates it */
96 Create (const char *url
, Trace
* t
)
99 struct urldef
*u
= URLs
;
100 while (url
[p
] && url
[p
] != ':')
103 die ("not a valid url");
106 if (strlen (u
->prefix
) == p
&& !memcmp (u
->prefix
, url
, p
))
108 return u
->Create (url
+ p
+ 1, t
);
112 die ("url not supported");
116 /** parses an EIB individual address */
118 readaddr (const char *addr
)
121 sscanf (addr
, "%d.%d.%d", &a
, &b
, &c
);
122 return ((a
& 0x0f) << 12) | ((b
& 0x0f) << 8) | ((c
& 0xff));
126 const char *argp_program_version
= "eibd " VERSION
;
129 "eibd -- a commonication stack for EIB\n"
130 "(C) 2005-2007 Martin Koegler <mkoegler@auto.tuwien.ac.at>\n"
131 "supported URLs are:\n"
133 #define L2_NAME(a) a##_URL
134 #include "layer2create.h"
137 #define L2_NAME(a) a##_DOC
138 #include "layer2create.h"
141 /** documentation for arguments*/
142 static char args_doc
[] = "URL";
145 static struct argp_option options
[] = {
146 {"listen-tcp", 'i', "PORT", OPTION_ARG_OPTIONAL
,
147 "listen at TCP port PORT (default 6720)"},
148 {"listen-local", 'u', "FILE", OPTION_ARG_OPTIONAL
,
149 "listen at Unix domain socket FILE (default /tmp/eib)"},
150 {"trace", 't', "LEVEL", 0, "set trace level"},
151 {"eibaddr", 'e', "EIBADDR", 0,
152 "set our own EIB-address to EIBADDR (default 0.0.1), for drivers, which need an address"},
153 {"pid-file", 'p', "FILE", 0, "write the PID of the process to FILE"},
154 {"daemon", 'd', "FILE", OPTION_ARG_OPTIONAL
,
155 "start the programm as daemon, the output will be written to FILE, if the argument present"},
156 #ifdef HAVE_EIBNETIPSERVER
157 {"Tunnelling", 'T', 0, 0,
158 "enable EIBnet/IP Tunneling in the EIBnet/IP server"},
159 {"Routing", 'R', 0, 0, "enable EIBnet/IP Routing in the EIBnet/IP server"},
160 {"Discovery", 'D', 0, 0,
161 "enable the EIBnet/IP server to answer discovery and description requests (SEARCH, DESCRIPTION)"},
162 {"Server", 'S', "ip[:port]", OPTION_ARG_OPTIONAL
,
163 "starts the EIBnet/IP server part"},
165 #ifdef HAVE_GROUPCACHE
166 {"GroupCache", 'c', 0, 0,
167 "enable caching of group communication network state"},
172 /** parses and stores an option */
174 parse_opt (int key
, char *arg
, struct argp_state
*state
)
176 struct arguments
*arguments
= (struct arguments
*) state
->input
;
180 arguments
->tunnel
= 1;
183 arguments
->route
= 1;
186 arguments
->discover
= 1;
189 arguments
->serverip
= (arg
? arg
: "224.0.23.12");
192 arguments
->name
= (char *) (arg
? arg
: "/tmp/eib");
195 arguments
->port
= (arg
? atoi (arg
) : 6720);
198 arguments
->tracelevel
= (arg
? atoi (arg
) : 0);
201 arguments
->addr
= readaddr (arg
);
204 arguments
->pidfile
= arg
;
207 arguments
->daemon
= (char *) (arg
? arg
: "/dev/null");
210 arguments
->groupcache
= 1;
213 return ARGP_ERR_UNKNOWN
;
218 /** information for the argument parser*/
219 static struct argp argp
= { options
, parse_opt
, args_doc
, doc
};
221 #ifdef HAVE_EIBNETIPSERVER
223 startServer (Layer3
* l3
, Trace
* t
)
231 char *a
= strdup (arg
.serverip
);
234 die ("out of memory");
245 c
= new EIBnetServer (a
, port
, arg
.tunnel
, arg
.route
, arg
.discover
, l3
, t
);
252 main (int ac
, char *ag
[])
255 Queue
< Server
* >server
;
258 #ifdef HAVE_EIBNETIPSERVER
259 EIBnetServer
*serv
= 0;
262 memset (&arg
, 0, sizeof (arg
));
265 argp_parse (&argp
, ac
, ag
, 0, &index
, &arg
);
267 die ("url expected");
269 die ("unexpected parameter");
271 if (arg
.port
== 0 && arg
.name
== 0 && arg
.serverip
== 0)
272 die ("No listen-address given");
274 signal (SIGPIPE
, SIG_IGN
);
278 t
.SetTraceLevel (arg
.tracelevel
);
282 int fd
= open (arg
.daemon
, O_WRONLY
| O_APPEND
| O_CREAT
);
284 die ("Can not open file %s", arg
.daemon
);
301 if ((pidf
= fopen (arg
.pidfile
, "w")) != NULL
)
303 fprintf (pidf
, "%d", getpid ());
309 l2
= Create (ag
[index
], &t
);
310 l3
= new Layer3 (l2
, &t
);
312 server
.put (new InetServer (l3
, &t
, arg
.port
));
314 server
.put (new LocalServer (l3
, &t
, arg
.name
));
315 #ifdef HAVE_EIBNETIPSERVER
316 serv
= startServer (l3
, &t
);
318 #ifdef HAVE_GROUPCACHE
319 CreateGroupCache (l3
, &t
, arg
.groupcache
);
324 die ("initialisation failed");
329 sigaddset (&t1
, SIGINT
);
330 sigaddset (&t1
, SIGTERM
);
331 signal (SIGINT
, SIG_IGN
);
332 signal (SIGTERM
, SIG_IGN
);
335 pth_sigwait (&t1
, &x
);
337 signal (SIGINT
, SIG_DFL
);
338 signal (SIGTERM
, SIG_DFL
);
340 while (!server
.isempty ())
341 delete server
.get ();
342 #ifdef HAVE_EIBNETIPSERVER
346 #ifdef HAVE_GROUPCACHE
353 unlink (arg
.pidfile
);