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 }