Copyright update for 2011
[bcusdk.git] / eibd / backend / tpuart.cpp
blob941ec195dadc8e20e671b4894550dc9bfe65657e
1 /*
2 EIBD eib bus access and management daemon
3 Copyright (C) 2005-2011 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include <fcntl.h>
21 #include <unistd.h>
22 #include <sys/ioctl.h>
23 #include "tpuart.h"
25 #define TPUART_MAGIC 'E'
26 #define TPUART_SET_PH_ADDR _IOW (TPUART_MAGIC, 2, unsigned short)
27 #define TPUART_UNSET_PH_ADDR _IOW (TPUART_MAGIC, 18, unsigned short)
28 #define TPUART_SET_GR_ADDR _IOW (TPUART_MAGIC, 4, unsigned short)
29 #define TPUART_UNSET_GR_ADDR _IOW (TPUART_MAGIC, 5, unsigned short)
30 #define TPUART_RESET _IO (TPUART_MAGIC, 8)
31 #define TPUART_BUSMON_ON _IO (TPUART_MAGIC, 9)
32 #define TPUART_BUSMON_OFF _IO (TPUART_MAGIC, 10)
34 struct message
36 struct timespec timestamp;
37 unsigned short length;
38 unsigned char data[64];
42 TPUARTLayer2Driver::TPUARTLayer2Driver (int version, const char *device,
43 eibaddr_t a, Trace * tr)
45 t = tr;
46 TRACEPRINTF (t, 2, this, "Open");
47 addr = a;
48 ver = version;
50 pth_sem_init (&in_signal);
51 pth_sem_init (&out_signal);
52 getwait = pth_event (PTH_EVENT_SEM, &out_signal);
54 fd = open (device, O_RDWR);
55 if (fd == -1)
56 return;
58 addAddress (a);
59 Start ();
60 mode = 0;
61 vmode = 0;
62 TRACEPRINTF (t, 2, this, "Opened");
65 TPUARTLayer2Driver::~TPUARTLayer2Driver ()
67 TRACEPRINTF (t, 2, this, "Close");
68 Stop ();
69 pth_event_free (getwait, PTH_FREE_THIS);
70 while (!inqueue.isempty ())
71 delete inqueue.get ();
72 while (!outqueue.isempty ())
73 delete outqueue.get ();
75 if (fd != -1)
77 removeAddress (addr);
78 close (fd);
82 bool
83 TPUARTLayer2Driver::init ()
85 return fd != -1;
88 bool
89 TPUARTLayer2Driver::openVBusmonitor ()
91 vmode = 1;
92 return 1;
95 bool
96 TPUARTLayer2Driver::closeVBusmonitor ()
98 vmode = 0;
99 return 1;
102 bool TPUARTLayer2Driver::addAddress (eibaddr_t addr)
104 return ioctl (fd, TPUART_SET_PH_ADDR, &addr) != -1;
107 bool TPUARTLayer2Driver::addGroupAddress (eibaddr_t addr)
109 return ioctl (fd, TPUART_UNSET_PH_ADDR, &addr) != -1;
112 bool TPUARTLayer2Driver::removeAddress (eibaddr_t addr)
114 return ioctl (fd, TPUART_SET_GR_ADDR, &addr) != -1;
117 bool TPUARTLayer2Driver::removeGroupAddress (eibaddr_t addr)
119 return ioctl (fd, TPUART_UNSET_GR_ADDR, &addr) != -1;
122 bool TPUARTLayer2Driver::enterBusmonitor ()
124 mode = 1;
125 return ioctl (fd, TPUART_BUSMON_ON) != -1;
128 bool TPUARTLayer2Driver::leaveBusmonitor ()
130 mode = 0;
131 return ioctl (fd, TPUART_BUSMON_OFF) != -1;
134 bool TPUARTLayer2Driver::Open ()
136 return ioctl (fd, TPUART_RESET) != -1;
139 bool TPUARTLayer2Driver::Close ()
141 return ioctl (fd, TPUART_RESET) != -1;
144 eibaddr_t TPUARTLayer2Driver::getDefaultAddr ()
146 return addr;
149 bool TPUARTLayer2Driver::Connection_Lost ()
151 return 0;
154 bool TPUARTLayer2Driver::Send_Queue_Empty ()
156 return inqueue.isempty ();
159 void
160 TPUARTLayer2Driver::Send_L_Data (LPDU * l)
162 TRACEPRINTF (t, 2, this, "Send %s", l->Decode ()());
163 inqueue.put (l);
164 pth_sem_inc (&in_signal, 1);
167 LPDU *
168 TPUARTLayer2Driver::Get_L_Data (pth_event_t stop)
170 if (stop != NULL)
171 pth_event_concat (getwait, stop, NULL);
173 pth_wait (getwait);
175 if (stop)
176 pth_event_isolate (getwait);
178 if (pth_event_status (getwait) == PTH_STATUS_OCCURRED)
180 pth_sem_dec (&out_signal);
181 LPDU *l = outqueue.get ();
182 TRACEPRINTF (t, 2, this, "Recv %s", l->Decode ()());
183 return l;
185 else
186 return 0;
189 void
190 TPUARTLayer2Driver::Run (pth_sem_t * stop1)
192 struct message m;
193 int l;
194 pth_event_t stop = pth_event (PTH_EVENT_SEM, stop1);
195 pth_event_t input = pth_event (PTH_EVENT_SEM, &in_signal);
196 while (pth_event_status (stop) != PTH_STATUS_OCCURRED)
198 pth_event_concat (stop, input, NULL);
199 l = pth_read_ev (fd, &m, sizeof (m), stop);
200 if (l >= 0)
202 LPDU *l1;
203 if (m.length > sizeof (m.data))
204 m.length = sizeof (m.data);
205 t->TracePacket (0, this, "Recv", m.length, m.data);
206 if (vmode && mode == 0)
208 L_Busmonitor_PDU *l2 = new L_Busmonitor_PDU;
209 l2->pdu.set (m.data, m.length);
210 outqueue.put (l2);
211 pth_sem_inc (&out_signal, 1);
213 if (mode == 0)
214 l1 = LPDU::fromPacket (CArray (m.data, m.length));
215 else
217 l1 = new L_Busmonitor_PDU;
218 ((L_Busmonitor_PDU *) l1)->pdu.set (m.data, m.length);
220 outqueue.put (l1);
221 pth_sem_inc (&out_signal, 1);
223 pth_event_isolate (stop);
224 if (!inqueue.isempty ())
226 LPDU *l1 = inqueue.top ();
227 CArray c = l1->ToPacket ();
228 unsigned len = c ();
229 if (len > sizeof (m.data))
230 len = sizeof (m.data);
231 memcpy (m.data, c.array (), len);
232 m.length = len;
233 if (ver)
234 m.length--;
235 t->TracePacket (0, this, "Send", m.length, m.data);
236 l = pth_write_ev (fd, &m, sizeof (m), stop);
237 if (l >= 0)
239 if (vmode)
241 L_Busmonitor_PDU *l2 = new L_Busmonitor_PDU;
242 l2->pdu.set (c);
243 outqueue.put (l2);
244 pth_sem_inc (&out_signal, 1);
246 pth_sem_dec (&in_signal);
247 delete inqueue.get ();
251 pth_event_free (stop, PTH_FREE_THIS);
252 pth_event_free (input, PTH_FREE_THIS);