EIBnet/IP Socket: don't use exceptions
[bcusdk.git] / eibd / backend / eibnetrouter.cpp
blob18370ada2f991b77b59aa2a0ce40769477e43755
1 /*
2 EIBD eib bus access and management daemon
3 Copyright (C) 2005-2008 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
20 #include "eibnetrouter.h"
21 #include "emi.h"
22 #include "config.h"
24 EIBNetIPRouter::EIBNetIPRouter (const char *multicastaddr, int port,
25 eibaddr_t a, Trace * tr)
27 struct sockaddr_in baddr;
28 struct ip_mreq mcfg;
29 t = tr;
30 TRACEPRINTF (t, 2, this, "Open");
31 addr = a;
32 mode = 0;
33 vmode = 0;
34 memset (&baddr, 0, sizeof (baddr));
35 #ifdef HAVE_SOCKADDR_IN_LEN
36 baddr.sin_len = sizeof (baddr);
37 #endif
38 baddr.sin_family = AF_INET;
39 baddr.sin_port = htons (port);
40 baddr.sin_addr.s_addr = htonl (INADDR_ANY);
41 sock = new EIBNetIPSocket (baddr, 1, t);
42 if (!sock->init ())
44 delete sock;
45 sock = 0;
46 throw Exception (DEV_OPEN_FAIL);
48 sock->recvall = 1;
49 if (GetHostIP (&sock->sendaddr, multicastaddr) == 0)
50 throw Exception (DEV_OPEN_FAIL);
51 sock->sendaddr.sin_port = htons (port);
53 mcfg.imr_multiaddr = sock->sendaddr.sin_addr;
54 mcfg.imr_interface.s_addr = htonl (INADDR_ANY);
55 if (!sock->SetMulticast (mcfg))
56 throw Exception (DEV_OPEN_FAIL);
57 pth_sem_init (&out_signal);
58 getwait = pth_event (PTH_EVENT_SEM, &out_signal);
59 Start ();
60 TRACEPRINTF (t, 2, this, "Opened");
63 EIBNetIPRouter::~EIBNetIPRouter ()
65 TRACEPRINTF (t, 2, this, "Destroy");
66 Stop ();
67 pth_event_free (getwait, PTH_FREE_THIS);
68 while (!outqueue.isempty ())
69 delete outqueue.get ();
70 if (sock)
71 delete sock;
74 void
75 EIBNetIPRouter::Send_L_Data (LPDU * l)
77 TRACEPRINTF (t, 2, this, "Send %s", l->Decode ()());
78 if (l->getType () != L_Data)
80 delete l;
81 return;
83 L_Data_PDU *l1 = (L_Data_PDU *) l;
84 EIBNetIPPacket p;
85 p.data = L_Data_ToCEMI (0x29, *l1);
86 p.service = ROUTING_INDICATION;
87 sock->Send (p);
88 delete l;
91 LPDU *
92 EIBNetIPRouter::Get_L_Data (pth_event_t stop)
94 if (stop != NULL)
95 pth_event_concat (getwait, stop, NULL);
97 pth_wait (getwait);
99 if (stop)
100 pth_event_isolate (getwait);
102 if (pth_event_status (getwait) == PTH_STATUS_OCCURRED)
104 pth_sem_dec (&out_signal);
105 LPDU *l = outqueue.get ();
106 TRACEPRINTF (t, 2, this, "Recv %s", l->Decode ()());
107 return l;
109 else
110 return 0;
114 void
115 EIBNetIPRouter::Run (pth_sem_t * stop1)
117 pth_event_t stop = pth_event (PTH_EVENT_SEM, stop1);
118 while (pth_event_status (stop) != PTH_STATUS_OCCURRED)
120 EIBNetIPPacket *p = sock->Get (stop);
121 if (p)
123 if (p->service != ROUTING_INDICATION)
125 delete p;
126 continue;
128 if (p->data () < 2 || p->data[0] != 0x29)
130 delete p;
131 continue;
133 const CArray data = p->data;
134 delete p;
135 L_Data_PDU *c = CEMI_to_L_Data (data);
136 if (c)
138 TRACEPRINTF (t, 2, this, "Recv %s", c->Decode ()());
139 if (mode == 0)
141 if (vmode)
143 L_Busmonitor_PDU *l2 = new L_Busmonitor_PDU;
144 l2->pdu.set (c->ToPacket ());
145 outqueue.put (l2);
146 pth_sem_inc (&out_signal, 1);
148 outqueue.put (c);
149 pth_sem_inc (&out_signal, 1);
150 continue;
152 L_Busmonitor_PDU *p1 = new L_Busmonitor_PDU;
153 p1->pdu = c->ToPacket ();
154 delete c;
155 outqueue.put (p1);
156 pth_sem_inc (&out_signal, 1);
157 continue;
161 pth_event_free (stop, PTH_FREE_THIS);
164 bool
165 EIBNetIPRouter::addAddress (eibaddr_t addr)
167 return 1;
170 bool
171 EIBNetIPRouter::addGroupAddress (eibaddr_t addr)
173 return 1;
176 bool
177 EIBNetIPRouter::removeAddress (eibaddr_t addr)
179 return 1;
182 bool
183 EIBNetIPRouter::removeGroupAddress (eibaddr_t addr)
185 return 1;
188 bool
189 EIBNetIPRouter::openVBusmonitor ()
191 vmode = 1;
192 return 1;
195 bool
196 EIBNetIPRouter::closeVBusmonitor ()
198 vmode = 0;
199 return 1;
202 bool
203 EIBNetIPRouter::enterBusmonitor ()
205 mode = 1;
206 return 1;
209 bool
210 EIBNetIPRouter::leaveBusmonitor ()
212 mode = 0;
213 return 1;
216 bool
217 EIBNetIPRouter::Open ()
219 mode = 0;
220 return 1;
223 bool
224 EIBNetIPRouter::Close ()
226 return 1;
229 eibaddr_t
230 EIBNetIPRouter::getDefaultAddr ()
232 return addr;
235 bool
236 EIBNetIPRouter::Connection_Lost ()
238 return 0;
241 bool
242 EIBNetIPRouter::Send_Queue_Empty ()
244 return 1;