/ src / libserver / tpdu.cpp
tpdu.cpp
  1  /*
  2      EIBD eib bus access and management daemon
  3      Copyright (C) 2005-2011 Martin Koegler <mkoegler@auto.tuwien.ac.at>
  4  
  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.
  9  
 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.
 14  
 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.
 18  */
 19  
 20  #include "tpdu.h"
 21  
 22  #include "apdu.h"
 23  
 24  TPDUPtr
 25  TPDU::fromPacket (const EIB_AddrType address_type, const eibaddr_t destination_address, const CArray & c, TracePtr tr)
 26  {
 27    TPDUPtr t;
 28    if (c.size() >= 1)
 29      {
 30        if (address_type == GroupAddress)
 31          {
 32            if ((c[0] & 0xFC) == 0x00)
 33              {
 34                if (destination_address == 0)
 35                  t = TPDUPtr(new T_Data_Broadcast_PDU ()); // @todo T_Data_SystemBroadcast
 36                else
 37                  t = TPDUPtr(new T_Data_Group_PDU ());
 38              }
 39            else if ((c[0] & 0xFC) == 0x04)
 40              t = TPDUPtr(new T_Data_Tag_Group_PDU ());
 41          }
 42        else
 43          {
 44            if ((c[0] & 0xFC) == 0x00)
 45              t = TPDUPtr(new T_Data_Individual_PDU ());
 46            else if ((c[0] & 0xC0) == 0x40)
 47              t = TPDUPtr(new T_Data_Connected_PDU ());
 48            else if (c[0] == 0x80)
 49              t = TPDUPtr(new T_Connect_PDU ());
 50            else if (c[0] == 0x81)
 51              t = TPDUPtr(new T_Disconnect_PDU ());
 52            else if ((c[0] & 0xC3) == 0xC2)
 53              t = TPDUPtr(new T_ACK_PDU ());
 54            else if ((c[0] & 0xC3) == 0xC3)
 55              t = TPDUPtr(new T_NAK_PDU ());
 56          }
 57      }
 58    if (t && t->init (c, tr))
 59      return t;
 60  
 61    t = TPDUPtr(new T_Unknown_PDU ());
 62    t->init (c, tr);
 63    return t;
 64  }
 65  
 66  
 67  /* T_Unknown */
 68  
 69  bool
 70  T_Unknown_PDU::init (const CArray & c, TracePtr)
 71  {
 72    pdu = c;
 73    return true;
 74  }
 75  
 76  CArray T_Unknown_PDU::ToPacket () const
 77  {
 78    return pdu;
 79  }
 80  
 81  std::string T_Unknown_PDU::Decode (TracePtr) const
 82  {
 83    std::string s ("Unknown TPDU: ");
 84  
 85    if (pdu.size() == 0)
 86      return "empty TPDU";
 87  
 88    C_ITER (i,pdu)
 89    addHex (s, *i);
 90  
 91    return s;
 92  }
 93  
 94  /* T_Data_Broadcast */
 95  
 96  bool
 97  T_Data_Broadcast_PDU::init (const CArray & c, TracePtr)
 98  {
 99    if (c.size() < 1)
100      return false;
101  
102    tsdu = c;
103    return true;
104  }
105  
106  CArray T_Data_Broadcast_PDU::ToPacket () const
107  {
108    assert (tsdu.size() > 0);
109  
110    CArray pdu (tsdu);
111    pdu[0] = pdu[0] & 0x03;
112    return pdu;
113  }
114  
115  std::string T_Data_Broadcast_PDU::Decode (TracePtr tr) const
116  {
117    APDUPtr a = APDU::fromPacket (tsdu, tr);
118    std::string s ("T_Data_Broadcast ");
119    s += a->Decode (tr);
120    return s;
121  }
122  
123  /* T_Data_SystemBroadcast */
124  
125  bool
126  T_Data_SystemBroadcast_PDU::init (const CArray & c, TracePtr)
127  {
128    if (c.size() < 1)
129      return false;
130  
131    tsdu = c;
132    return true;
133  }
134  
135  CArray T_Data_SystemBroadcast_PDU::ToPacket () const
136  {
137    assert (tsdu.size() > 0);
138  
139    CArray pdu (tsdu);
140    pdu[0] = pdu[0] & 0x03;
141    return pdu;
142  }
143  
144  std::string T_Data_SystemBroadcast_PDU::Decode (TracePtr tr) const
145  {
146    APDUPtr a = APDU::fromPacket (tsdu, tr);
147    std::string s ("T_Data_SystemBroadcast ");
148    s += a->Decode (tr);
149    return s;
150  }
151  
152  /* T_Data_Group */
153  
154  bool
155  T_Data_Group_PDU::init (const CArray & c, TracePtr)
156  {
157    if (c.size() < 1)
158      return false;
159  
160    tsdu = c;
161    return true;
162  }
163  
164  CArray T_Data_Group_PDU::ToPacket () const
165  {
166    assert (tsdu.size() > 0);
167  
168    CArray pdu (tsdu);
169    pdu[0] = pdu[0] & 0x03;
170    return pdu;
171  }
172  
173  std::string T_Data_Group_PDU::Decode (TracePtr tr) const
174  {
175    APDUPtr a = APDU::fromPacket (tsdu, tr);
176    std::string s ("T_Data_Group ");
177    s += a->Decode (tr);
178    return s;
179  }
180  
181  /* T_Data_Tag_Group */
182  
183  bool
184  T_Data_Tag_Group_PDU::init (const CArray & c, TracePtr)
185  {
186    if (c.size() < 1)
187      return false;
188  
189    tsdu = c;
190    return true;
191  }
192  
193  CArray T_Data_Tag_Group_PDU::ToPacket () const
194  {
195    assert (tsdu.size() > 0);
196  
197    CArray pdu (tsdu);
198    pdu[0] = pdu[0] & 0x03;
199    return pdu;
200  }
201  
202  std::string T_Data_Tag_Group_PDU::Decode (TracePtr tr) const
203  {
204    APDUPtr a = APDU::fromPacket (tsdu, tr);
205    std::string s ("T_Data_Tag_Group ");
206    s += a->Decode (tr);
207    return s;
208  }
209  
210  /* T_Data_Individual */
211  
212  bool
213  T_Data_Individual_PDU::init (const CArray & c, TracePtr)
214  {
215    if (c.size() < 1)
216      return false;
217  
218    tsdu = c;
219    return true;
220  }
221  
222  CArray T_Data_Individual_PDU::ToPacket () const
223  {
224    assert (tsdu.size() > 0);
225  
226    CArray pdu (tsdu);
227    pdu[0] = pdu[0] & 0x03;
228    return pdu;
229  }
230  
231  std::string T_Data_Individual_PDU::Decode (TracePtr tr) const
232  {
233    APDUPtr a = APDU::fromPacket (tsdu, tr);
234    std::string s ("T_Data_Individual ");
235    s += a->Decode (tr);
236    return s;
237  }
238  
239  /* T_Data_Connected */
240  
241  bool
242  T_Data_Connected_PDU::init (const CArray & c, TracePtr)
243  {
244    if (c.size() < 1)
245      return false;
246  
247    tsdu = c;
248    sequence_number = (c[0] >> 2) & 0x0f;
249    return true;
250  }
251  
252  CArray T_Data_Connected_PDU::ToPacket () const
253  {
254    assert (tsdu.size() > 0);
255    assert ((sequence_number & 0xf0) == 0);
256  
257    CArray pdu (tsdu);
258    pdu[0] = 0x40 | ((sequence_number & 0x0f) << 2) | (pdu[0] & 0x03);
259    return pdu;
260  }
261  
262  std::string T_Data_Connected_PDU::Decode (TracePtr tr) const
263  {
264    assert ((sequence_number & 0xf0) == 0);
265  
266    APDUPtr a = APDU::fromPacket (tsdu, tr);
267    std::string s ("T_Data_Connected serno:");
268    addHex (s, sequence_number);
269    s += a->Decode (tr);
270    return s;
271  }
272  
273  /* T_Connect */
274  
275  bool
276  T_Connect_PDU::init (const CArray & c, TracePtr)
277  {
278    if (c.size() != 1)
279      return false;
280    return true;
281  }
282  
283  CArray T_Connect_PDU::ToPacket () const
284  {
285    CArray pdu;
286    pdu.resize(1);
287    pdu[0] = 0x80;
288    return pdu;
289  }
290  
291  std::string T_Connect_PDU::Decode (TracePtr) const
292  {
293    return "T_Connect";
294  }
295  
296  /* T_Disconnect */
297  
298  bool
299  T_Disconnect_PDU::init (const CArray & c, TracePtr)
300  {
301    if (c.size() != 1)
302      return false;
303    return true;
304  }
305  
306  CArray T_Disconnect_PDU::ToPacket () const
307  {
308    CArray pdu;
309    pdu.resize(1);
310    pdu[0] = 0x81;
311    return pdu;
312  }
313  
314  std::string T_Disconnect_PDU::Decode (TracePtr) const
315  {
316    return "T_Disconnect";
317  }
318  
319  /* T_ACK */
320  
321  bool
322  T_ACK_PDU::init (const CArray & c, TracePtr)
323  {
324    if (c.size() != 1)
325      return false;
326  
327    sequence_number = (c[0] >> 2) & 0x0f;
328    return true;
329  }
330  
331  CArray T_ACK_PDU::ToPacket () const
332  {
333    assert ((sequence_number & 0xf0) == 0);
334  
335    CArray pdu;
336    pdu.resize(1);
337    pdu[0] = 0xC2 | ((sequence_number & 0x0f) << 2);
338    return pdu;
339  }
340  
341  std::string T_ACK_PDU::Decode (TracePtr) const
342  {
343    assert ((sequence_number & 0xf0) == 0);
344  
345    std::string s ("T_ACK Serno:");
346    addHex (s, sequence_number);
347    return s;
348  }
349  
350  /* T_NAK  */
351  
352  bool T_NAK_PDU::init (const CArray & c, TracePtr)
353  {
354    if (c.size() != 1)
355      return false;
356  
357    sequence_number = (c[0] >> 2) & 0x0f;
358    return true;
359  }
360  
361  CArray T_NAK_PDU::ToPacket () const
362  {
363    assert ((sequence_number & 0xf0) == 0);
364  
365    CArray pdu;
366    pdu.resize(1);
367    pdu[0] = 0xC3 | ((sequence_number & 0x0f) << 2);
368    return pdu;
369  }
370  
371  std::string T_NAK_PDU::Decode (TracePtr) const
372  {
373    assert ((sequence_number & 0xf0) == 0);
374  
375    std::string s ("T_NAK Serno:");
376    addHex (s, sequence_number);
377    return s;
378  }