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.
22 #include <sys/ioctl.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)
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
)
46 TRACEPRINTF (t
, 2, this, "Open");
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
);
62 TRACEPRINTF (t
, 2, this, "Opened");
65 TPUARTLayer2Driver::~TPUARTLayer2Driver ()
67 TRACEPRINTF (t
, 2, this, "Close");
69 pth_event_free (getwait
, PTH_FREE_THIS
);
70 while (!inqueue
.isempty ())
71 delete inqueue
.get ();
72 while (!outqueue
.isempty ())
73 delete outqueue
.get ();
83 TPUARTLayer2Driver::init ()
89 TPUARTLayer2Driver::openVBusmonitor ()
96 TPUARTLayer2Driver::closeVBusmonitor ()
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 ()
125 return ioctl (fd
, TPUART_BUSMON_ON
) != -1;
128 bool TPUARTLayer2Driver::leaveBusmonitor ()
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 ()
149 bool TPUARTLayer2Driver::Connection_Lost ()
154 bool TPUARTLayer2Driver::Send_Queue_Empty ()
156 return inqueue
.isempty ();
160 TPUARTLayer2Driver::Send_L_Data (LPDU
* l
)
162 TRACEPRINTF (t
, 2, this, "Send %s", l
->Decode ()());
164 pth_sem_inc (&in_signal
, 1);
168 TPUARTLayer2Driver::Get_L_Data (pth_event_t stop
)
171 pth_event_concat (getwait
, stop
, NULL
);
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 ()());
190 TPUARTLayer2Driver::Run (pth_sem_t
* stop1
)
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
);
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
);
211 pth_sem_inc (&out_signal
, 1);
214 l1
= LPDU::fromPacket (CArray (m
.data
, m
.length
));
217 l1
= new L_Busmonitor_PDU
;
218 ((L_Busmonitor_PDU
*) l1
)->pdu
.set (m
.data
, m
.length
);
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 ();
229 if (len
> sizeof (m
.data
))
230 len
= sizeof (m
.data
);
231 memcpy (m
.data
, c
.array (), len
);
235 t
->TracePacket (0, this, "Send", m
.length
, m
.data
);
236 l
= pth_write_ev (fd
, &m
, sizeof (m
), stop
);
241 L_Busmonitor_PDU
*l2
= new L_Busmonitor_PDU
;
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
);