/ src / libserver / apdu.cpp
apdu.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 "apdu.h"
  21  
  22  #include <cstdio>
  23  #include <cstring>
  24  
  25  APDUPtr
  26  APDU::fromPacket (const CArray & c, TracePtr tr)
  27  {
  28    /* @todo provide additional parameter or split function to differentiate:
  29     * - multicast
  30     * - broadcast
  31     * - system broadcast
  32     * - p2p connectionless
  33     * - p2p connection-oriented
  34     */
  35    APDUPtr a;
  36    if (c.size() >= 2)
  37      {
  38        uint16_t apci = ((c[0] & 0x03) << 8) | c[1];
  39        switch (apci)
  40          {
  41          case A_GroupValue_Read:
  42            a = APDUPtr(new A_GroupValue_Read_PDU ());
  43            break;
  44          case A_GroupValue_Response ... A_GroupValue_Response | 0x03F:
  45            a = APDUPtr(new A_GroupValue_Response_PDU ());
  46            break;
  47          case A_GroupValue_Write ... A_GroupValue_Write | 0x03F:
  48            a = APDUPtr(new A_GroupValue_Write_PDU ());
  49            break;
  50          case A_IndividualAddress_Write:
  51            a = APDUPtr(new A_IndividualAddress_Write_PDU ());
  52            break;
  53          case A_IndividualAddress_Read:
  54            a = APDUPtr(new A_IndividualAddress_Read_PDU ());
  55            break;
  56          case A_IndividualAddress_Response:
  57            a = APDUPtr(new A_IndividualAddress_Response_PDU ());
  58            break;
  59          case A_ADC_Read ... A_ADC_Read | 0x03F:
  60            a = APDUPtr(new A_ADC_Read_PDU ());
  61            break;
  62          case A_ADC_Response ... A_ADC_Response | 0x03F:
  63            a = APDUPtr(new A_ADC_Response_PDU ());
  64            break;
  65          /* @todo
  66          case A_SystemNetworkParameter_Read: // same as A_ADC_Response with channel_nr=0x80
  67            a = APDUPtr(new A_SystemNetworkParameter_Read_PDU ());
  68            break;
  69          case A_SystemNetworkParameter_Response: // same as A_ADC_Response with channel_nr=0x81
  70            a = APDUPtr(new A_SystemNetworkParameter_Response_PDU ());
  71            break;
  72          case A_SystemNetworkParameter_Write: // same as A_ADC_Response with channel_nr=0x82
  73            a = APDUPtr(new A_SystemNetworkParameter_Write_PDU ());
  74            break;
  75          */
  76          case A_Memory_Read ... A_Memory_Read | 0x00F:
  77            a = APDUPtr(new A_Memory_Read_PDU ());
  78            break;
  79          case A_Memory_Response ... A_Memory_Response | 0x00F:
  80            a = APDUPtr(new A_Memory_Response_PDU ());
  81            break;
  82          case A_Memory_Write ... A_Memory_Write | 0x00F:
  83            a = APDUPtr(new A_Memory_Write_PDU ());
  84            break;
  85          case A_UserMemory_Read:
  86            a = APDUPtr(new A_UserMemory_Read_PDU ());
  87            break;
  88          case A_UserMemory_Response:
  89            a = APDUPtr(new A_UserMemory_Response_PDU ());
  90            break;
  91          case A_UserMemory_Write:
  92            a = APDUPtr(new A_UserMemory_Write_PDU ());
  93            break;
  94          case A_UserMemoryBit_Write:
  95            a = APDUPtr(new A_UserMemoryBit_Write_PDU ());
  96            break;
  97          case A_UserManufacturerInfo_Read:
  98            a = APDUPtr(new A_UserManufacturerInfo_Read_PDU ());
  99            break;
 100          case A_UserManufacturerInfo_Response:
 101            a = APDUPtr(new A_UserManufacturerInfo_Response_PDU ());
 102            break;
 103          case A_FunctionPropertyCommand:
 104            a = APDUPtr(new A_FunctionPropertyCommand_PDU ());
 105            break;
 106          case A_FunctionPropertyState_Read:
 107            a = APDUPtr(new A_FunctionPropertyState_Read_PDU ());
 108            break;
 109          case A_FunctionPropertyState_Response:
 110            a = APDUPtr(new A_FunctionPropertyState_Response_PDU ());
 111            break;
 112          case A_DeviceDescriptor_Read ... A_DeviceDescriptor_Read | 0x03F:
 113            a = APDUPtr(new A_DeviceDescriptor_Read_PDU ());
 114            break;
 115          case A_DeviceDescriptor_Response ... A_DeviceDescriptor_Response | 0x03F:
 116            a = APDUPtr(new A_DeviceDescriptor_Response_PDU ());
 117            break;
 118          case A_Restart ... A_Restart | 0x01F:
 119            a = APDUPtr(new A_Restart_PDU ());
 120            break;
 121          case A_Restart_Response ... A_Restart_Response | 0x01F:
 122            a = APDUPtr(new A_Restart_Response_PDU ());
 123            break;
 124          case A_Open_Routing_Table_Request:
 125            a = APDUPtr(new A_Open_Routing_Table_Request_PDU ());
 126            break;
 127          case A_Read_Routing_Table_Request:
 128            a = APDUPtr(new A_Read_Routing_Table_Request_PDU ());
 129            break;
 130          case A_Read_Routing_Table_Response:
 131            a = APDUPtr(new A_Read_Routing_Table_Response_PDU ());
 132            break;
 133          case A_Write_Routing_Table_Request:
 134            a = APDUPtr(new A_Write_Routing_Table_Request_PDU ());
 135            break;
 136          case A_Read_Router_Memory_Request:
 137            a = APDUPtr(new A_Read_Router_Memory_Request_PDU ());
 138            break;
 139          case A_Read_Router_Memory_Response:
 140            a = APDUPtr(new A_Read_Router_Memory_Response_PDU ());
 141            break;
 142          case A_Write_Router_Memory_Request:
 143            a = APDUPtr(new A_Write_Router_Memory_Request_PDU ());
 144            break;
 145          case A_Read_Router_Status_Request:
 146            a = APDUPtr(new A_Read_Router_Status_Request_PDU ());
 147            break;
 148          case A_Read_Router_Status_Response:
 149            a = APDUPtr(new A_Read_Router_Status_Response_PDU ());
 150            break;
 151          case A_Write_Router_Status_Request:
 152            a = APDUPtr(new A_Write_Router_Status_Request_PDU ());
 153            break;
 154          case A_MemoryBit_Write:
 155            a = APDUPtr(new A_MemoryBit_Write_PDU ());
 156            break;
 157          case A_Authorize_Request:
 158            a = APDUPtr(new A_Authorize_Request_PDU ());
 159            break;
 160          case A_Authorize_Response:
 161            a = APDUPtr(new A_Authorize_Response_PDU ());
 162            break;
 163          case A_Key_Write:
 164            a = APDUPtr(new A_Key_Write_PDU ());
 165            break;
 166          case A_Key_Response:
 167            a = APDUPtr(new A_Key_Response_PDU ());
 168            break;
 169          case A_PropertyValue_Read:
 170            a = APDUPtr(new A_PropertyValue_Read_PDU ());
 171            break;
 172          case A_PropertyValue_Response:
 173            a = APDUPtr(new A_PropertyValue_Response_PDU ());
 174            break;
 175          case A_PropertyValue_Write:
 176            a = APDUPtr(new A_PropertyValue_Write_PDU ());
 177            break;
 178          case A_PropertyDescription_Read:
 179            a = APDUPtr(new A_PropertyDescription_Read_PDU ());
 180            break;
 181          case A_PropertyDescription_Response:
 182            a = APDUPtr(new A_PropertyDescription_Response_PDU ());
 183            break;
 184          case A_NetworkParameter_Read:
 185            a = APDUPtr(new A_NetworkParameter_Read_PDU ());
 186            break;
 187          case A_NetworkParameter_Response:
 188            a = APDUPtr(new A_NetworkParameter_Response_PDU ());
 189            break;
 190          case A_IndividualAddressSerialNumber_Read:
 191            a = APDUPtr(new A_IndividualAddressSerialNumber_Read_PDU ());
 192            break;
 193          case A_IndividualAddressSerialNumber_Response:
 194            a = APDUPtr(new A_IndividualAddressSerialNumber_Response_PDU ());
 195            break;
 196          case A_IndividualAddressSerialNumber_Write:
 197            a = APDUPtr(new A_IndividualAddressSerialNumber_Write_PDU ());
 198            break;
 199          case A_ServiceInformation_Indication_Write:
 200            a = APDUPtr(new A_ServiceInformation_Indication_Write_PDU ());
 201            break;
 202          case A_DomainAddress_Write:
 203            a = APDUPtr(new A_DomainAddress_Write_PDU ());
 204            break;
 205          case A_DomainAddress_Read:
 206            a = APDUPtr(new A_DomainAddress_Read_PDU ());
 207            break;
 208          case A_DomainAddress_Response:
 209            a = APDUPtr(new A_DomainAddress_Response_PDU ());
 210            break;
 211          case A_DomainAddressSelective_Read:
 212            a = APDUPtr(new A_DomainAddressSelective_Read_PDU ());
 213            break;
 214          case A_NetworkParameter_Write:
 215            a = APDUPtr(new A_NetworkParameter_Write_PDU ());
 216            break;
 217          case A_Link_Read:
 218            a = APDUPtr(new A_Link_Read_PDU ());
 219            break;
 220          case A_Link_Response:
 221            a = APDUPtr(new A_Link_Response_PDU ());
 222            break;
 223          case A_Link_Write:
 224            a = APDUPtr(new A_Link_Write_PDU ());
 225            break;
 226          case A_GroupPropValue_Read:
 227            a = APDUPtr(new A_GroupPropValue_Read_PDU ());
 228            break;
 229          case A_GroupPropValue_Response:
 230            a = APDUPtr(new A_GroupPropValue_Response_PDU ());
 231            break;
 232          case A_GroupPropValue_Write:
 233            a = APDUPtr(new A_GroupPropValue_Write_PDU ());
 234            break;
 235          case A_GroupPropValue_InfoReport:
 236            a = APDUPtr(new A_GroupPropValue_InfoReport_PDU ());
 237            break;
 238          case A_DomainAddressSerialNumber_Read:
 239            a = APDUPtr(new A_DomainAddressSerialNumber_Read_PDU ());
 240            break;
 241          case A_DomainAddressSerialNumber_Response:
 242            a = APDUPtr(new A_DomainAddressSerialNumber_Response_PDU ());
 243            break;
 244          case A_DomainAddressSerialNumber_Write:
 245            a = APDUPtr(new A_DomainAddressSerialNumber_Write_PDU ());
 246            break;
 247          case A_FileStream_InfoReport:
 248            a = APDUPtr(new A_FileStream_InfoReport_PDU ());
 249            break;
 250          default:
 251            break;
 252          }
 253      }
 254    if (a && a->init (c, tr))
 255      return a;
 256    a = APDUPtr(new A_Unknown_PDU);
 257    a->init (c, tr);
 258    return a;
 259  }
 260  
 261  /* A_Unknown_PDU */
 262  
 263  bool
 264  A_Unknown_PDU::init (const CArray & c, TracePtr)
 265  {
 266    pdu = c;
 267    return true;
 268  }
 269  
 270  CArray A_Unknown_PDU::ToPacket () const
 271  {
 272    return pdu;
 273  }
 274  
 275  std::string A_Unknown_PDU::Decode (TracePtr) const
 276  {
 277    if (pdu.size() == 0)
 278      return "empty APDU";
 279  
 280    std::string s ("Unknown APDU: ");
 281    C_ITER (i, pdu)
 282    addHex (s, *i);
 283  
 284    return s;
 285  }
 286  
 287  bool A_Unknown_PDU::isResponse (const APDU *) const
 288  {
 289    return false;
 290  }
 291  
 292  /* A_GroupValue_Read */
 293  
 294  bool
 295  A_GroupValue_Read_PDU::init (const CArray & c, TracePtr)
 296  {
 297    if (c.size() != 2)
 298      return false;
 299    return true;
 300  }
 301  
 302  CArray A_GroupValue_Read_PDU::ToPacket () const
 303  {
 304    CArray pdu;
 305    pdu.resize(2);
 306    pdu[0] = A_GroupValue_Read >> 8;
 307    pdu[1] = A_GroupValue_Read & 0xff;
 308    return pdu;
 309  }
 310  
 311  std::string A_GroupValue_Read_PDU::Decode (TracePtr) const
 312  {
 313    return "A_GroupValue_Read";
 314  }
 315  
 316  bool A_GroupValue_Read_PDU::isResponse (const APDU *) const
 317  {
 318    return false;
 319  }
 320  
 321  /* A_GroupValue_Response */
 322  
 323  bool
 324  A_GroupValue_Response_PDU::init (const CArray & c, TracePtr)
 325  {
 326    if (c.size() < 2)
 327      return false;
 328  
 329    issmall = (c.size() == 2);
 330    if (issmall)
 331      {
 332        data.resize(1);
 333        data[0] = c[1] & 0x3f;
 334      }
 335    else
 336      {
 337        data.set (c.data() + 2, c.size() - 2);
 338      }
 339    return true;
 340  }
 341  
 342  CArray A_GroupValue_Response_PDU::ToPacket () const
 343  {
 344    assert (!issmall || (data.size() == 1 && (data[0] & 0xC0) == 0));
 345  
 346    CArray pdu;
 347    pdu.resize (2);
 348    pdu[0] = A_GroupValue_Response >> 8;
 349    pdu[1] = A_GroupValue_Response & 0xc0;
 350    if (issmall)
 351      {
 352        pdu[1] |= data[0] & 0x3f;
 353      }
 354    else
 355      {
 356        pdu.resize (2 + data.size());
 357        pdu.setpart (data.data(), 2, data.size());
 358      }
 359    return pdu;
 360  }
 361  
 362  std::string A_GroupValue_Response_PDU::Decode (TracePtr) const
 363  {
 364    assert (!issmall || (data.size() == 1 && (data[0] & 0xC0) == 0));
 365  
 366    std::string s ("A_GroupValue_Response ");
 367    if (issmall)
 368      s += "(small) ";
 369    C_ITER (i, data)
 370    addHex (s, *i);
 371    return s;
 372  }
 373  
 374  bool A_GroupValue_Response_PDU::isResponse (const APDU * req) const
 375  {
 376    if (req->getType () != A_GroupValue_Read)
 377      return false;
 378    return true;
 379  }
 380  
 381  /* A_GroupValue_Write */
 382  
 383  bool
 384  A_GroupValue_Write_PDU::init (const CArray & c, TracePtr)
 385  {
 386    if (c.size() < 2)
 387      return false;
 388  
 389    issmall = (c.size() == 2);
 390    if (issmall)
 391      {
 392        data.resize(1);
 393        data[0] = c[1] & 0x3f;
 394      }
 395    else
 396      {
 397        data.set (c.data() + 2, c.size() - 2);
 398      }
 399    return true;
 400  }
 401  
 402  CArray A_GroupValue_Write_PDU::ToPacket () const
 403  {
 404    assert (!issmall || (data.size() == 1 && (data[0] & 0xC0) == 0));
 405  
 406    CArray pdu;
 407    pdu.resize (2);
 408    pdu[0] = A_GroupValue_Write >> 8;
 409    pdu[1] = A_GroupValue_Write & 0xc0;
 410    if (issmall)
 411      {
 412        pdu[1] |= data[0] & 0x3F;
 413      }
 414    else
 415      {
 416        pdu.resize (2 + data.size());
 417        pdu.setpart (data.data(), 2, data.size());
 418      }
 419    return pdu;
 420  }
 421  
 422  std::string A_GroupValue_Write_PDU::Decode (TracePtr) const
 423  {
 424    assert (!issmall || (data.size() == 1 && (data[0] & 0xC0) == 0));
 425  
 426    std::string s ("A_GroupValue_Write ");
 427    if (issmall)
 428      s += "(small) ";
 429    C_ITER (i, data)
 430    addHex (s, *i);
 431    return s;
 432  }
 433  
 434  bool A_GroupValue_Write_PDU::isResponse (const APDU *) const
 435  {
 436    return false;
 437  }
 438  
 439  /* A_IndividualAddress_Write */
 440  
 441  bool
 442  A_IndividualAddress_Write_PDU::init (const CArray & c, TracePtr)
 443  {
 444    if (c.size() != 4)
 445      return false;
 446  
 447    newaddress = (c[2] << 8) | (c[3]);
 448    return true;
 449  }
 450  
 451  CArray A_IndividualAddress_Write_PDU::ToPacket () const
 452  {
 453    CArray pdu;
 454    pdu.resize (4);
 455    pdu[0] = A_IndividualAddress_Write >> 8;
 456    pdu[1] = A_IndividualAddress_Write & 0xff;
 457    pdu[2] = newaddress >> 8;
 458    pdu[3] = newaddress & 0xff;
 459    return pdu;
 460  }
 461  
 462  std::string A_IndividualAddress_Write_PDU::Decode (TracePtr) const
 463  {
 464    std::string s ("A_IndividualAddress_Write ");
 465    return s + FormatEIBAddr (newaddress);
 466  }
 467  
 468  bool A_IndividualAddress_Write_PDU::isResponse (const APDU *) const
 469  {
 470    return false;
 471  }
 472  
 473  /* A_IndividualAddress_Read */
 474  
 475  bool
 476  A_IndividualAddress_Read_PDU::init (const CArray & c, TracePtr)
 477  {
 478    if (c.size() != 2)
 479      return false;
 480    return true;
 481  }
 482  
 483  CArray A_IndividualAddress_Read_PDU::ToPacket () const
 484  {
 485    CArray pdu;
 486    pdu.resize(2);
 487    pdu[0] = A_IndividualAddress_Read >> 8;
 488    pdu[1] = A_IndividualAddress_Read & 0xff;
 489    return pdu;
 490  }
 491  
 492  std::string A_IndividualAddress_Read_PDU::Decode (TracePtr) const
 493  {
 494    return "A_IndividualAddress_Read";
 495  }
 496  
 497  bool A_IndividualAddress_Read_PDU::isResponse (const APDU *) const
 498  {
 499    return false;
 500  }
 501  
 502  /* A_IndividualAddress_Response */
 503  
 504  bool A_IndividualAddress_Response_PDU::init (const CArray & c, TracePtr tr)
 505  {
 506    if (c.size() != 2)
 507      {
 508        TRACEPRINTF (tr, 3, "BadLen %d",c.size());
 509        return false;
 510      }
 511    return true;
 512  }
 513  
 514  CArray A_IndividualAddress_Response_PDU::ToPacket () const
 515  {
 516    CArray pdu;
 517    pdu.resize(2);
 518    pdu[0] = A_IndividualAddress_Response >> 8;
 519    pdu[1] = A_IndividualAddress_Response & 0xff;
 520    return pdu;
 521  }
 522  
 523  std::string A_IndividualAddress_Response_PDU::Decode (TracePtr) const
 524  {
 525    return "A_IndividualAddress_Response";
 526  }
 527  
 528  bool A_IndividualAddress_Response_PDU::isResponse (const APDU * req) const
 529  {
 530    if (req->getType () != A_IndividualAddress_Read)
 531      return false;
 532    return true;
 533  }
 534  
 535  /* A_ADC_Read */
 536  
 537  bool
 538  A_ADC_Read_PDU::init (const CArray & c, TracePtr)
 539  {
 540    if (c.size() != 3)
 541      return false;
 542  
 543    channel_nr = c[1] & 0x3F;
 544    read_count = c[2];
 545    return true;
 546  }
 547  
 548  CArray
 549  A_ADC_Read_PDU::ToPacket () const
 550  {
 551    assert ((channel_nr & 0xC0) == 0);
 552  
 553    CArray pdu;
 554    pdu.resize (3);
 555    pdu[0] = A_ADC_Read >> 8;
 556    pdu[1] = (A_ADC_Read & 0xc0) | (channel_nr & 0x3F);
 557    pdu[2] = read_count;
 558    return pdu;
 559  }
 560  
 561  std::string
 562  A_ADC_Read_PDU::Decode (TracePtr) const
 563  {
 564    assert ((channel_nr & 0xC0) == 0);
 565  
 566    std::string s ("A_ADC_Read Channel:");
 567    addHex (s, channel_nr);
 568    s += " Count: ";
 569    addHex (s, read_count);
 570    return s;
 571  }
 572  
 573  bool A_ADC_Read_PDU::isResponse (const APDU *) const
 574  {
 575    return false;
 576  }
 577  
 578  /* A_ADC_Response */
 579  
 580  bool
 581  A_ADC_Response_PDU::init (const CArray & c, TracePtr)
 582  {
 583    if (c.size() != 5)
 584      return false;
 585  
 586    channel_nr = c[1] & 0x3F;
 587    read_count = c[2];
 588    sum = (c[3] << 8) | (c[4]);
 589    return true;
 590  }
 591  
 592  CArray
 593  A_ADC_Response_PDU::ToPacket () const
 594  {
 595    assert ((channel_nr & 0xC0) == 0);
 596  
 597    CArray pdu;
 598    pdu.resize (5);
 599    pdu[0] = A_ADC_Read >> 8;
 600    pdu[1] = (A_ADC_Read & 0xc0) | (channel_nr & 0x3F);
 601    pdu[2] = read_count;
 602    pdu[3] = sum >> 8;
 603    pdu[4] = sum & 0xff;
 604    return pdu;
 605  }
 606  
 607  std::string
 608  A_ADC_Response_PDU::Decode (TracePtr) const
 609  {
 610    assert ((channel_nr & 0xC0) == 0);
 611  
 612    std::string s ("A_ADC_Response Channel:");
 613    addHex (s, channel_nr);
 614    s += " Count: ";
 615    addHex (s, read_count);
 616    s += "Value: ";
 617    addHex (s, sum);
 618    return s;
 619  }
 620  
 621  bool A_ADC_Response_PDU::isResponse (const APDU * req) const
 622  {
 623    if (req->getType () != A_ADC_Read)
 624      return false;
 625    const A_ADC_Read_PDU * a = (const A_ADC_Read_PDU *) req;
 626    if (a->channel_nr != channel_nr)
 627      return false;
 628    if (a->read_count != read_count)
 629      return false;
 630    return true;
 631  }
 632  
 633  /* A_SystemNetworkParameter_Read */
 634  
 635  bool
 636  A_SystemNetworkParameter_Read_PDU::init (const CArray & c, TracePtr)
 637  {
 638    if (c.size() < 5)
 639      return false;
 640    // @todo
 641    return true;
 642  }
 643  
 644  CArray
 645  A_SystemNetworkParameter_Read_PDU::ToPacket () const
 646  {
 647    CArray pdu;
 648    pdu.resize(2);
 649    pdu[0] = A_SystemNetworkParameter_Read >> 8;
 650    pdu[1] = A_SystemNetworkParameter_Read & 0xff;
 651    // @todo
 652    return pdu;
 653  }
 654  
 655  std::string
 656  A_SystemNetworkParameter_Read_PDU::Decode (TracePtr) const
 657  {
 658    std::string s ("A_SystemNetworkParameter_Read");
 659    // @todo
 660    return s;
 661  }
 662  
 663  bool A_SystemNetworkParameter_Read_PDU::isResponse (const APDU *) const
 664  {
 665    return false;
 666  }
 667  
 668  /* A_SystemNetworkParameter_Response */
 669  
 670  bool
 671  A_SystemNetworkParameter_Response_PDU::init (const CArray & c, TracePtr)
 672  {
 673    if (c.size() < 5)
 674      return false;
 675    // @todo
 676    return true;
 677  }
 678  
 679  CArray
 680  A_SystemNetworkParameter_Response_PDU::ToPacket () const
 681  {
 682    CArray pdu;
 683    pdu.resize(2);
 684    pdu[0] = A_SystemNetworkParameter_Response >> 8;
 685    pdu[1] = A_SystemNetworkParameter_Response & 0xff;
 686    // @todo
 687    return pdu;
 688  }
 689  
 690  std::string
 691  A_SystemNetworkParameter_Response_PDU::Decode (TracePtr) const
 692  {
 693    std::string s ("A_SystemNetworkParameter_Response");
 694    // @todo
 695    return s;
 696  }
 697  
 698  bool A_SystemNetworkParameter_Response_PDU::isResponse (const APDU * req) const
 699  {
 700    if (req->getType () != A_SystemNetworkParameter_Read)
 701      return false;
 702    return true;
 703  }
 704  
 705  /* A_SystemNetworkParameter_Write */
 706  
 707  bool
 708  A_SystemNetworkParameter_Write_PDU::init (const CArray & c, TracePtr)
 709  {
 710    if (c.size() < 6)
 711      return false;
 712    // @todo
 713    return true;
 714  }
 715  
 716  CArray
 717  A_SystemNetworkParameter_Write_PDU::ToPacket () const
 718  {
 719    CArray pdu;
 720    pdu.resize(2);
 721    pdu[0] = A_SystemNetworkParameter_Write >> 8;
 722    pdu[1] = A_SystemNetworkParameter_Write & 0xff;
 723    // @todo
 724    return pdu;
 725  }
 726  
 727  std::string
 728  A_SystemNetworkParameter_Write_PDU::Decode (TracePtr) const
 729  {
 730    std::string s ("A_SystemNetworkParameter_Write");
 731    // @todo
 732    return s;
 733  }
 734  
 735  bool A_SystemNetworkParameter_Write_PDU::isResponse (const APDU *) const
 736  {
 737    return false;
 738  }
 739  
 740  /* A_Memory_Read */
 741  
 742  bool
 743  A_Memory_Read_PDU::init (const CArray & c, TracePtr)
 744  {
 745    if (c.size() != 4)
 746      return false;
 747  
 748    number = c[1] & 0xf;
 749    address = (c[2] << 8) | c[3];
 750    return true;
 751  }
 752  
 753  CArray
 754  A_Memory_Read_PDU::ToPacket () const
 755  {
 756    assert ((number & 0xf0) == 0);
 757  
 758    CArray pdu;
 759    pdu.resize (4);
 760    pdu[0] = A_Memory_Read >> 8;
 761    pdu[1] = (A_Memory_Read & 0xf0) | (number & 0x0f);
 762    pdu[2] = address >> 8;
 763    pdu[3] = address & 0xff;
 764    return pdu;
 765  }
 766  
 767  std::string
 768  A_Memory_Read_PDU::Decode (TracePtr) const
 769  {
 770    assert ((number & 0xf0) == 0);
 771  
 772    std::string s ("A_Memory_Read Len: ");
 773    addHex (s, number);
 774    s += " Addr: ";
 775    add16Hex (s, address);
 776    return s;
 777  }
 778  
 779  bool A_Memory_Read_PDU::isResponse (const APDU *) const
 780  {
 781    return false;
 782  }
 783  
 784  /* A_Memory_Response */
 785  
 786  bool
 787  A_Memory_Response_PDU::init (const CArray & c, TracePtr)
 788  {
 789    if (c.size() < 4)
 790      return false;
 791  
 792    number = c[1] & 0xf;
 793    address = (c[2] << 8) | c[3];
 794    data.set (c.data() + 4, c.size() - 4);
 795    if (data.size() != number)
 796      return false;
 797    return true;
 798  }
 799  
 800  CArray
 801  A_Memory_Response_PDU::ToPacket () const
 802  {
 803    assert ((number & 0xf0) == 0);
 804    assert (data.size() == number);
 805  
 806    CArray pdu;
 807    pdu.resize (4 + data.size());
 808    pdu[0] = A_Memory_Response >> 8;
 809    pdu[1] = (A_Memory_Response & 0xf0) | (number & 0x0f);
 810    pdu[2] = address >> 8;
 811    pdu[3] = address & 0xff;
 812    pdu.setpart (data.data(), 4, data.size());
 813    return pdu;
 814  }
 815  
 816  std::string
 817  A_Memory_Response_PDU::Decode (TracePtr) const
 818  {
 819    assert ((number & 0xf0) == 0);
 820    assert (data.size() == number);
 821  
 822    std::string s ("A_Memory_Response Len:");
 823    addHex (s, number);
 824    s += " Addr: ";
 825    add16Hex (s, address);
 826    s += "Data: ";
 827    C_ITER (i,data)
 828    addHex (s, *i);
 829    return s;
 830  }
 831  
 832  bool A_Memory_Response_PDU::isResponse (const APDU * req) const
 833  {
 834    if (req->getType () != A_Memory_Read)
 835      return false;
 836    const A_Memory_Read_PDU *
 837    a = (const A_Memory_Read_PDU *) req;
 838    if (a->number != number)
 839      return false;
 840    if (a->address != address)
 841      return false;
 842    return true;
 843  }
 844  
 845  /* A_Memory_Write */
 846  
 847  bool
 848  A_Memory_Write_PDU::init (const CArray & c, TracePtr)
 849  {
 850    if (c.size() < 4)
 851      return false;
 852  
 853    number = c[1] & 0xf;
 854    address = (c[2] << 8) | c[3];
 855    data.set (c.data() + 4, c.size() - 4);
 856    if (data.size() != number)
 857      return false;
 858    return true;
 859  }
 860  
 861  CArray
 862  A_Memory_Write_PDU::ToPacket () const
 863  {
 864    assert ((number & 0xf0) == 0);
 865    assert (data.size() == number);
 866  
 867    CArray pdu;
 868    pdu.resize (4 + data.size());
 869    pdu[0] = A_Memory_Write >> 8;
 870    pdu[1] = (A_Memory_Write & 0xf0) | (number & 0x0f);
 871    pdu[2] = address >> 8;
 872    pdu[3] = address & 0xff;
 873    pdu.setpart (data.data(), 4, data.size());
 874    return pdu;
 875  }
 876  
 877  std::string
 878  A_Memory_Write_PDU::Decode (TracePtr) const
 879  {
 880    assert ((number & 0xf0) == 0);
 881    assert (data.size() == number);
 882  
 883    std::string s ("A_Memory_Write Len:");
 884    addHex (s, number);
 885    s += " Addr: ";
 886    add16Hex (s, address);
 887    s += "Data: ";
 888    C_ITER (i,data)
 889    addHex (s, *i);
 890    return s;
 891  }
 892  
 893  bool A_Memory_Write_PDU::isResponse (const APDU *) const
 894  {
 895    return false;
 896  }
 897  
 898  /* A_UserMemory_Read */
 899  
 900  bool
 901  A_UserMemory_Read_PDU::init (const CArray & c, TracePtr)
 902  {
 903    if (c.size() != 5)
 904      return false;
 905  
 906    address_extension = (c[2] >> 4) & 0xf;
 907    number = c[2] & 0xf;
 908    address = (c[3] << 8) | c[4];
 909    return true;
 910  }
 911  
 912  CArray
 913  A_UserMemory_Read_PDU::ToPacket () const
 914  {
 915    assert ((address_extension & 0xf0) == 0);
 916    assert ((number & 0xf0) == 0);
 917  
 918    CArray pdu;
 919    pdu.resize (5);
 920    pdu[0] = A_UserMemory_Read >> 8;
 921    pdu[1] = A_UserMemory_Read & 0xff;
 922    pdu[2] = (address_extension & 0x0f) << 4 | (number & 0x0f);
 923    pdu[3] = address >> 8;
 924    pdu[4] = address & 0xff;
 925    return pdu;
 926  }
 927  
 928  std::string
 929  A_UserMemory_Read_PDU::Decode (TracePtr) const
 930  {
 931    assert ((address_extension & 0xf0) == 0);
 932    assert ((number & 0xf0) == 0);
 933  
 934    std::string s ("A_UserMemory_Read Addr_ext:");
 935    addHex (s, address_extension);
 936    s += " Len: ";
 937    addHex (s, number);
 938    s += " Addr: ";
 939    add16Hex (s, address);
 940    return s;
 941  }
 942  
 943  bool A_UserMemory_Read_PDU::isResponse (const APDU *) const
 944  {
 945    return false;
 946  }
 947  
 948  /* A_UserMemory_Response */
 949  
 950  bool
 951  A_UserMemory_Response_PDU::init (const CArray & c, TracePtr)
 952  {
 953    if (c.size() < 5)
 954      return false;
 955  
 956    address_extension = (c[2] >> 4) & 0xf;
 957    number = c[2] & 0xf;
 958    address = (c[3] << 8) | c[4];
 959    data.set (c.data() + 5, c.size() - 5);
 960    if (data.size() != number)
 961      return false;
 962    return true;
 963  }
 964  
 965  CArray
 966  A_UserMemory_Response_PDU::ToPacket () const
 967  {
 968    assert ((address_extension & 0xf0) == 0);
 969    assert ((number & 0xf0) == 0);
 970    assert (data.size() == number);
 971  
 972    CArray pdu;
 973    pdu.resize (5 + data.size());
 974    pdu[0] = A_UserMemory_Response >> 8;
 975    pdu[1] = A_UserMemory_Response & 0xff;
 976    pdu[2] = (address_extension & 0x0f) << 4 | (number & 0x0f);
 977    pdu[3] = address >> 8;
 978    pdu[4] = address & 0xff;
 979    pdu.setpart (data.data(), 5, data.size());
 980    return pdu;
 981  }
 982  
 983  std::string
 984  A_UserMemory_Response_PDU::Decode (TracePtr) const
 985  {
 986    assert ((address_extension & 0xf0) == 0);
 987    assert ((number & 0xf0) == 0);
 988    assert (data.size() == number);
 989  
 990    std::string s ("A_UserMemory_Response Addr_ext:");
 991    addHex (s, address_extension);
 992    s += " Len: ";
 993    addHex (s, number);
 994    s += " Addr: ";
 995    add16Hex (s, address);
 996    s += " Data: ";
 997    C_ITER(i,data)
 998    addHex (s, *i);
 999    return s;
1000  }
1001  
1002  bool A_UserMemory_Response_PDU::isResponse (const APDU * req) const
1003  {
1004    if (req->getType () != A_UserMemory_Read)
1005      return false;
1006    const A_UserMemory_Read_PDU *
1007    a = (const A_UserMemory_Read_PDU *) req;
1008    if (a->address_extension != address_extension)
1009      return false;
1010    if (a->number != number)
1011      return false;
1012    if (a->address != address)
1013      return false;
1014    return true;
1015  }
1016  
1017  /* A_UserMemory_Write */
1018  
1019  bool
1020  A_UserMemory_Write_PDU::init (const CArray & c, TracePtr)
1021  {
1022    if (c.size() < 5)
1023      return false;
1024  
1025    address_extension = (c[2] >> 4) & 0xf;
1026    number = c[2] & 0xf;
1027    address = (c[3] << 8) | c[4];
1028    data.set (c.data() + 5, c.size() - 5);
1029    if (data.size() != number)
1030      return false;
1031    return true;
1032  }
1033  
1034  CArray
1035  A_UserMemory_Write_PDU::ToPacket () const
1036  {
1037    assert ((address_extension & 0xf0) == 0);
1038    assert ((number & 0xf0) == 0);
1039    assert (data.size() == number);
1040  
1041    CArray pdu;
1042    pdu.resize (5 + data.size());
1043    pdu[0] = A_UserMemory_Write >> 8;
1044    pdu[1] = A_UserMemory_Write & 0xff;
1045    pdu[2] = (address_extension & 0x0f) << 4 | (number & 0x0f);
1046    pdu[3] = address >> 8;
1047    pdu[4] = address & 0xff;
1048    pdu.setpart (data.data(), 5, data.size());
1049    return pdu;
1050  }
1051  
1052  std::string
1053  A_UserMemory_Write_PDU::Decode (TracePtr) const
1054  {
1055    assert ((address_extension & 0xf0) == 0);
1056    assert ((number & 0xf0) == 0);
1057    assert (data.size() == number);
1058  
1059    std::string s ("A_UserMemory_Write Addr_ext:");
1060    addHex (s, address_extension);
1061    s += " Len: ";
1062    addHex (s, number);
1063    s += " Addr: ";
1064    add16Hex (s, address);
1065    s += " Data: ";
1066    C_ITER (i,data)
1067    addHex (s, *i);
1068    return s;
1069  }
1070  
1071  bool A_UserMemory_Write_PDU::isResponse (const APDU *) const
1072  {
1073    return false;
1074  }
1075  
1076  /* A_UserMemoryBit_Write */
1077  
1078  bool
1079  A_UserMemoryBit_Write_PDU::init (const CArray & c, TracePtr)
1080  {
1081    if (c.size() < 5)
1082      return false;
1083  
1084    number = c[2];
1085    address = (c[3] << 8) | c[4];
1086    if (c.size() - 5 != number * 2)
1087      return false;
1088    and_data.set (c.data() + 5, number);
1089    xor_data.set (c.data() + 5 + number, number);
1090    return true;
1091  }
1092  
1093  CArray
1094  A_UserMemoryBit_Write_PDU::ToPacket () const
1095  {
1096    assert (and_data.size() == number);
1097    assert (xor_data.size() == number);
1098  
1099    CArray pdu;
1100    pdu.resize (5 + 2 * number);
1101    pdu[0] = A_UserMemoryBit_Write >> 8;
1102    pdu[1] = A_UserMemoryBit_Write & 0xff;
1103    pdu[2] = number;
1104    pdu[3] = address >> 8;
1105    pdu[4] = address & 0xff;
1106    pdu.setpart (and_data.data(), 5, number);
1107    pdu.setpart (xor_data.data(), 5 + number, number);
1108    return pdu;
1109  }
1110  
1111  std::string
1112  A_UserMemoryBit_Write_PDU::Decode (TracePtr) const
1113  {
1114    assert (and_data.size() == number);
1115    assert (xor_data.size() == number);
1116  
1117    std::string s ("A_UserMemoryBit_Write Len:");
1118    addHex (s, number);
1119    s += "Addr: ";
1120    add16Hex (s, address);
1121    s += "And: ";
1122    C_ITER(i, and_data)
1123    addHex (s, *i);
1124    s += "xor: ";
1125    C_ITER(i, xor_data)
1126    addHex (s, *i);
1127    return s;
1128  }
1129  
1130  bool A_UserMemoryBit_Write_PDU::isResponse (const APDU *) const
1131  {
1132    return false;
1133  }
1134  
1135  /* A_UserManufacturerInfo_Read */
1136  
1137  bool A_UserManufacturerInfo_Read_PDU::init (const CArray & c, TracePtr)
1138  {
1139    if (c.size() != 2)
1140      return false;
1141    return true;
1142  }
1143  
1144  CArray
1145  A_UserManufacturerInfo_Read_PDU::ToPacket () const
1146  {
1147    CArray pdu;
1148    pdu.resize (2);
1149    pdu[0] = A_UserManufacturerInfo_Read >> 8;
1150    pdu[1] = A_UserManufacturerInfo_Read & 0xff;
1151    return pdu;
1152  }
1153  
1154  std::string
1155  A_UserManufacturerInfo_Read_PDU::Decode (TracePtr) const
1156  {
1157    std::string s ("A_UserManufacturerInfo_Read");
1158    return s;
1159  }
1160  
1161  bool A_UserManufacturerInfo_Read_PDU::isResponse (const APDU *) const
1162  {
1163    return false;
1164  }
1165  
1166  /* A_UserManufacturerInfo_Response */
1167  
1168  bool
1169  A_UserManufacturerInfo_Response_PDU::init (const CArray & c, TracePtr)
1170  {
1171    if (c.size() != 5)
1172      return false;
1173  
1174    manufacturer_id = c[2];
1175    manufacturer_data = (c[3] << 8) | c[4];
1176    return true;
1177  }
1178  
1179  CArray
1180  A_UserManufacturerInfo_Response_PDU::ToPacket () const
1181  {
1182    CArray pdu;
1183    pdu.resize (5);
1184    pdu[0] = A_UserManufacturerInfo_Response >> 8;
1185    pdu[1] = A_UserManufacturerInfo_Response & 0xff;
1186    pdu[2] = manufacturer_id;
1187    pdu[3] = manufacturer_data >> 8;
1188    pdu[4] = manufacturer_data & 0xff;
1189    return pdu;
1190  }
1191  
1192  std::string
1193  A_UserManufacturerInfo_Response_PDU::Decode (TracePtr) const
1194  {
1195    std::string s ("A_UserManufactueerInfo_Response Manufacturer:");
1196    addHex (s, manufacturer_id);
1197    s += " data: ";
1198    add16Hex (s, manufacturer_data);
1199    return s;
1200  }
1201  
1202  bool A_UserManufacturerInfo_Response_PDU::isResponse (const APDU * req) const
1203  {
1204    if (req->getType () != A_UserManufacturerInfo_Read)
1205      return false;
1206    return true;
1207  }
1208  
1209  /* A_FunctionPropertyCommand */
1210  
1211  bool
1212  A_FunctionPropertyCommand_PDU::init (const CArray & c, TracePtr)
1213  {
1214    if (c.size() < 4)
1215      return false;
1216  
1217    object_index = c[2];
1218    property_id = c[3];
1219    data.set (c.data() + 4, c.size() - 4);
1220    return true;
1221  }
1222  
1223  CArray
1224  A_FunctionPropertyCommand_PDU::ToPacket () const
1225  {
1226    CArray pdu;
1227    pdu.resize(4 + data.size());
1228    pdu[0] = A_FunctionPropertyCommand >> 8;
1229    pdu[1] = A_FunctionPropertyCommand & 0xff;
1230    pdu[2] = object_index;
1231    pdu[3] = property_id;
1232    pdu.setpart (data.data(), 4, data.size());
1233    return pdu;
1234  }
1235  
1236  std::string
1237  A_FunctionPropertyCommand_PDU::Decode (TracePtr) const
1238  {
1239    std::string s ("A_FunctionPropertyCommand");
1240    // @todo
1241    return s;
1242  }
1243  
1244  bool A_FunctionPropertyCommand_PDU::isResponse (const APDU *) const
1245  {
1246    return false;
1247  }
1248  
1249  /* A_FunctionPropertyState_Read */
1250  
1251  bool
1252  A_FunctionPropertyState_Read_PDU::init (const CArray & c, TracePtr)
1253  {
1254    if (c.size() < 4)
1255      return false;
1256  
1257    object_index = c[2];
1258    property_id = c[3];
1259    data.set (c.data() + 4, c.size() - 4);
1260    return true;
1261  }
1262  
1263  CArray
1264  A_FunctionPropertyState_Read_PDU::ToPacket () const
1265  {
1266    CArray pdu;
1267    pdu.resize(4 + data.size());
1268    pdu[0] = A_FunctionPropertyState_Read >> 8;
1269    pdu[1] = A_FunctionPropertyState_Read & 0xff;
1270    pdu[2] = object_index;
1271    pdu[3] = property_id;
1272    pdu.setpart (data.data(), 4, data.size());
1273    return pdu;
1274  }
1275  
1276  std::string
1277  A_FunctionPropertyState_Read_PDU::Decode (TracePtr) const
1278  {
1279    std::string s ("A_FunctionPropertyState_Read");
1280    // @todo
1281    return s;
1282  }
1283  
1284  bool A_FunctionPropertyState_Read_PDU::isResponse (const APDU *) const
1285  {
1286    return false;
1287  }
1288  
1289  /* A_FunctionPropertyState_Response */
1290  
1291  bool
1292  A_FunctionPropertyState_Response_PDU::init (const CArray & c, TracePtr)
1293  {
1294    if (c.size() < 5)
1295      return false;
1296  
1297    object_index = c[2];
1298    property_id = c[3];
1299    return_code = c[4];
1300    data.set (c.data() + 5, c.size() - 5);
1301    return true;
1302  }
1303  
1304  CArray
1305  A_FunctionPropertyState_Response_PDU::ToPacket () const
1306  {
1307    CArray pdu;
1308    pdu.resize(5 + data.size());
1309    pdu[0] = A_FunctionPropertyState_Response >> 8;
1310    pdu[1] = A_FunctionPropertyState_Response & 0xff;
1311    pdu[2] = object_index;
1312    pdu[3] = property_id;
1313    pdu[4] = return_code;
1314    pdu.setpart (data.data(), 5, data.size());
1315    return pdu;
1316  }
1317  
1318  std::string
1319  A_FunctionPropertyState_Response_PDU::Decode (TracePtr) const
1320  {
1321    std::string s ("A_FunctionPropertyState_Response");
1322    // @todo
1323    return s;
1324  }
1325  
1326  bool A_FunctionPropertyState_Response_PDU::isResponse (const APDU * req) const
1327  {
1328    if (req->getType () != A_FunctionPropertyState_Read)
1329      return false;
1330    const A_FunctionPropertyState_Read_PDU *
1331    a = (const A_FunctionPropertyState_Read_PDU *) req;
1332    if (a->object_index != object_index)
1333      return false;
1334    if (a->property_id != property_id)
1335      return false;
1336    return true;
1337  }
1338  
1339  /* A_DeviceDescriptor_Read */
1340  
1341  bool
1342  A_DeviceDescriptor_Read_PDU::init (const CArray & c, TracePtr)
1343  {
1344    if (c.size() != 2)
1345      return false;
1346  
1347    descriptor_type = c[1] & 0x3F;
1348    return true;
1349  }
1350  
1351  CArray
1352  A_DeviceDescriptor_Read_PDU::ToPacket () const
1353  {
1354    assert ((descriptor_type & 0xC0) == 0);
1355  
1356    CArray pdu;
1357    pdu.resize (2);
1358    pdu[0] = A_DeviceDescriptor_Read >> 8;
1359    pdu[1] = (A_DeviceDescriptor_Read & 0xc0) | (descriptor_type & 0x3f);
1360    return pdu;
1361  }
1362  
1363  std::string
1364  A_DeviceDescriptor_Read_PDU::Decode (TracePtr) const
1365  {
1366    assert ((descriptor_type & 0xC0) == 0);
1367  
1368    std::string s ("A_DeviceDescriptor_Read Type:");
1369    addHex (s, descriptor_type);
1370    return s;
1371  }
1372  
1373  bool A_DeviceDescriptor_Read_PDU::isResponse (const APDU *) const
1374  {
1375    return false;
1376  }
1377  
1378  /* A_DeviceDescriptor_Response */
1379  
1380  bool A_DeviceDescriptor_Response_PDU::init (const CArray & c, TracePtr tr)
1381  {
1382    if (c.size() != 4)
1383      {
1384        TRACEPRINTF (tr, 3, "BadLen %d",c.size());
1385        return false;
1386      }
1387  
1388    descriptor_type = c[1] & 0x3F;
1389    device_descriptor = (c[2] << 8) | c[3];
1390    return true;
1391  }
1392  
1393  CArray
1394  A_DeviceDescriptor_Response_PDU::ToPacket () const
1395  {
1396    assert ((descriptor_type & 0xC0) == 0);
1397  
1398    CArray pdu;
1399    pdu.resize (4);
1400    pdu[0] = A_DeviceDescriptor_Response >> 8;
1401    pdu[1] = (A_DeviceDescriptor_Response & 0xc0) | (descriptor_type & 0x3f);
1402    pdu[2] = device_descriptor >> 8;
1403    pdu[3] = device_descriptor & 0xff;
1404    return pdu;
1405  }
1406  
1407  std::string
1408  A_DeviceDescriptor_Response_PDU::Decode (TracePtr) const
1409  {
1410    assert ((descriptor_type & 0xC0) == 0);
1411  
1412    std::string s ("A_DeviceDescriptor_Response Type:");
1413    addHex (s, descriptor_type);
1414    s += " Descriptor: ";
1415    add16Hex (s, device_descriptor);
1416    return s;
1417  }
1418  
1419  bool A_DeviceDescriptor_Response_PDU::isResponse (const APDU * req) const
1420  {
1421    if (req->getType () != A_DeviceDescriptor_Read)
1422      return false;
1423    const A_DeviceDescriptor_Read_PDU *
1424    a = (const A_DeviceDescriptor_Read_PDU *) req;
1425    if (a->descriptor_type != descriptor_type)
1426      return false;
1427    return true;
1428  }
1429  
1430  /* A_Restart */
1431  
1432  bool
1433  A_Restart_PDU::init (const CArray & c, TracePtr)
1434  {
1435    if ((c.size() != 2) || (c.size() != 4))
1436      return false;
1437  
1438    restart_type = c[1] & 0x01;
1439    if (restart_type == 1)
1440      {
1441        erase_code = c[2];
1442        channel_number = c[3];
1443      }
1444    return true;
1445  }
1446  
1447  CArray
1448  A_Restart_PDU::ToPacket () const
1449  {
1450    CArray pdu;
1451    pdu.resize (2);
1452    pdu[0] = A_Restart >> 8;
1453    pdu[1] = (A_Restart & 0xc0) | restart_type;
1454    if (restart_type == 1)
1455      {
1456        pdu.resize (4);
1457        pdu[2] = erase_code;
1458        pdu[3] = channel_number;
1459      }
1460    return pdu;
1461  }
1462  
1463  std::string
1464  A_Restart_PDU::Decode (TracePtr) const
1465  {
1466    std::string s ("A_Restart");
1467    return s;
1468  }
1469  
1470  bool A_Restart_PDU::isResponse (const APDU *) const
1471  {
1472    return false;
1473  }
1474  
1475  /* A_Restart_Response */
1476  
1477  bool
1478  A_Restart_Response_PDU::init (const CArray & c, TracePtr)
1479  {
1480    if (c.size() != 5)
1481      return false;
1482  
1483    restart_type = c[1] & 0x01;
1484    error_code = c[2];
1485    process_time = (c[3] << 8) | c[4];
1486    return true;
1487  }
1488  
1489  CArray
1490  A_Restart_Response_PDU::ToPacket () const
1491  {
1492    CArray pdu;
1493    pdu.resize (2);
1494    pdu[0] = A_Restart_Response >> 8;
1495    pdu[1] = (A_Restart_Response & 0xc0) | restart_type;
1496    pdu[2] = error_code;
1497    pdu[3] = process_time >> 8;
1498    pdu[4] = process_time & 0xff;
1499    return pdu;
1500  }
1501  
1502  std::string
1503  A_Restart_Response_PDU::Decode (TracePtr) const
1504  {
1505    std::string s ("A_Restart_Response");
1506    return s;
1507  }
1508  
1509  bool A_Restart_Response_PDU::isResponse (const APDU * req) const
1510  {
1511    if (req->getType () != A_Restart)
1512      return false;
1513    return true;
1514  }
1515  
1516  /* A_Open_Routing_Table_Request */
1517  
1518  bool
1519  A_Open_Routing_Table_Request_PDU::init (const CArray & c, TracePtr)
1520  {
1521    if (c.size() < 2)
1522      return false;
1523  
1524    data.set (c.data() + 2, c.size() - 2);
1525    return true;
1526  }
1527  
1528  CArray
1529  A_Open_Routing_Table_Request_PDU::ToPacket () const
1530  {
1531    CArray pdu;
1532    pdu.resize (2 + data.size());
1533    pdu[0] = A_Open_Routing_Table_Request >> 8;
1534    pdu[1] = A_Open_Routing_Table_Request & 0xff;
1535    pdu.setpart (data.data(), 2, data.size());
1536    return pdu;
1537  }
1538  
1539  std::string
1540  A_Open_Routing_Table_Request_PDU::Decode (TracePtr) const
1541  {
1542    std::string s ("A_Open_Routing_Table_Request: ");
1543    C_ITER (i, data)
1544    addHex (s, *i);
1545    return s;
1546  }
1547  
1548  bool A_Open_Routing_Table_Request_PDU::isResponse (const APDU *) const
1549  {
1550    return false;
1551  }
1552  
1553  /* A_Read_Routing_Table_Request */
1554  
1555  bool
1556  A_Read_Routing_Table_Request_PDU::init (const CArray & c, TracePtr)
1557  {
1558    if (c.size() < 2)
1559      return false;
1560  
1561    data.set (c.data() + 2, c.size() - 2);
1562    return true;
1563  }
1564  
1565  CArray
1566  A_Read_Routing_Table_Request_PDU::ToPacket () const
1567  {
1568    CArray pdu;
1569    pdu.resize (2 + data.size());
1570    pdu[0] = A_Read_Routing_Table_Request >> 8;
1571    pdu[1] = A_Read_Routing_Table_Request & 0xff;
1572    pdu.setpart (data.data(), 2, data.size());
1573    return pdu;
1574  }
1575  
1576  std::string
1577  A_Read_Routing_Table_Request_PDU::Decode (TracePtr) const
1578  {
1579    std::string s ("A_Read_Routing_Table_Request");
1580    C_ITER (i, data)
1581    addHex (s, *i);
1582    return s;
1583  }
1584  
1585  bool A_Read_Routing_Table_Request_PDU::isResponse (const APDU *) const
1586  {
1587    return false;
1588  }
1589  
1590  /* A_Read_Routing_Table_Response */
1591  
1592  bool
1593  A_Read_Routing_Table_Response_PDU::init (const CArray & c, TracePtr)
1594  {
1595    if (c.size() < 2)
1596      return false;
1597  
1598    data.set (c.data() + 2, c.size() - 2);
1599    return true;
1600  }
1601  
1602  CArray
1603  A_Read_Routing_Table_Response_PDU::ToPacket () const
1604  {
1605    CArray pdu;
1606    pdu.resize (2 + data.size());
1607    pdu[0] = A_Read_Routing_Table_Response >> 8;
1608    pdu[1] = A_Read_Routing_Table_Response & 0xff;
1609    pdu.setpart (data.data(), 2, data.size());
1610    return pdu;
1611  }
1612  
1613  std::string
1614  A_Read_Routing_Table_Response_PDU::Decode (TracePtr) const
1615  {
1616    std::string s ("A_Read_Routing_Table_Response");
1617    C_ITER (i, data)
1618    addHex (s, *i);
1619    return s;
1620  }
1621  
1622  bool A_Read_Routing_Table_Response_PDU::isResponse (const APDU * req) const
1623  {
1624    if (req->getType () != A_Read_Routing_Table_Request)
1625      return false;
1626    return true;
1627  }
1628  
1629  /* A_Write_Routing_Table_Request */
1630  
1631  bool
1632  A_Write_Routing_Table_Request_PDU::init (const CArray & c, TracePtr)
1633  {
1634    if (c.size() < 2)
1635      return false;
1636  
1637    data.set (c.data() + 2, c.size() - 2);
1638    return true;
1639  }
1640  
1641  CArray
1642  A_Write_Routing_Table_Request_PDU::ToPacket () const
1643  {
1644    CArray pdu;
1645    pdu.resize (2 + data.size());
1646    pdu[0] = A_Write_Routing_Table_Request >> 8;
1647    pdu[1] = A_Write_Routing_Table_Request & 0xff;
1648    pdu.setpart (data.data(), 2, data.size());
1649    return pdu;
1650  }
1651  
1652  std::string
1653  A_Write_Routing_Table_Request_PDU::Decode (TracePtr) const
1654  {
1655    std::string s ("A_Write_Routing_Table_Request");
1656    C_ITER (i, data)
1657    addHex (s, *i);
1658    return s;
1659  }
1660  
1661  bool A_Write_Routing_Table_Request_PDU::isResponse (const APDU *) const
1662  {
1663    return false;
1664  }
1665  
1666  /* A_Read_Router_Memory_Request */
1667  
1668  bool
1669  A_Read_Router_Memory_Request_PDU::init (const CArray & c, TracePtr)
1670  {
1671    if (c.size() < 2)
1672      return false;
1673  
1674    data.set (c.data() + 2, c.size() - 2);
1675    return true;
1676  }
1677  
1678  CArray
1679  A_Read_Router_Memory_Request_PDU::ToPacket () const
1680  {
1681    CArray pdu;
1682    pdu.resize (2 + data.size());
1683    pdu[0] = A_Read_Router_Memory_Request >> 8;
1684    pdu[1] = A_Read_Router_Memory_Request & 0xff;
1685    pdu.setpart (data.data(), 2, data.size());
1686    return pdu;
1687  }
1688  
1689  std::string
1690  A_Read_Router_Memory_Request_PDU::Decode (TracePtr) const
1691  {
1692    std::string s ("A_Read_Router_Memory_Request");
1693    C_ITER (i, data)
1694    addHex (s, *i);
1695    return s;
1696  }
1697  
1698  bool A_Read_Router_Memory_Request_PDU::isResponse (const APDU *) const
1699  {
1700    return false;
1701  }
1702  
1703  /* A_Read_Router_Memory_Response */
1704  
1705  bool
1706  A_Read_Router_Memory_Response_PDU::init (const CArray & c, TracePtr)
1707  {
1708    if (c.size() < 2)
1709      return false;
1710  
1711    data.set (c.data() + 2, c.size() - 2);
1712    return true;
1713  }
1714  
1715  CArray
1716  A_Read_Router_Memory_Response_PDU::ToPacket () const
1717  {
1718    CArray pdu;
1719    pdu.resize (2 + data.size());
1720    pdu[0] = A_Read_Router_Memory_Response >> 8;
1721    pdu[1] = A_Read_Router_Memory_Response & 0xff;
1722    pdu.setpart (data.data(), 2, data.size());
1723    return pdu;
1724  }
1725  
1726  std::string
1727  A_Read_Router_Memory_Response_PDU::Decode (TracePtr) const
1728  {
1729    std::string s ("A_Read_Router_Memory_Response");
1730    C_ITER (i, data)
1731    addHex (s, *i);
1732    return s;
1733  }
1734  
1735  bool A_Read_Router_Memory_Response_PDU::isResponse (const APDU * req) const
1736  {
1737    if (req->getType () != A_Read_Router_Memory_Request)
1738      return false;
1739    return true;
1740  }
1741  
1742  /* A_Write_Router_Memory_Request */
1743  
1744  bool
1745  A_Write_Router_Memory_Request_PDU::init (const CArray & c, TracePtr)
1746  {
1747    if (c.size() < 2)
1748      return false;
1749  
1750    data.set (c.data() + 2, c.size() - 2);
1751    return true;
1752  }
1753  
1754  CArray
1755  A_Write_Router_Memory_Request_PDU::ToPacket () const
1756  {
1757    CArray pdu;
1758    pdu.resize (2 + data.size());
1759    pdu[0] = A_Write_Router_Memory_Request >> 8;
1760    pdu[1] = A_Write_Router_Memory_Request & 0xff;
1761    pdu.setpart (data.data(), 2, data.size());
1762    return pdu;
1763  }
1764  
1765  std::string
1766  A_Write_Router_Memory_Request_PDU::Decode (TracePtr) const
1767  {
1768    std::string s ("A_Write_Router_Memory_Request");
1769    C_ITER (i, data)
1770    addHex (s, *i);
1771    return s;
1772  }
1773  
1774  bool A_Write_Router_Memory_Request_PDU::isResponse (const APDU *) const
1775  {
1776    return false;
1777  }
1778  
1779  /* A_Read_Router_Status_Request */
1780  
1781  bool
1782  A_Read_Router_Status_Request_PDU::init (const CArray & c, TracePtr)
1783  {
1784    if (c.size() < 2)
1785      return false;
1786  
1787    data.set (c.data() + 2, c.size() - 2);
1788    return true;
1789  }
1790  
1791  CArray
1792  A_Read_Router_Status_Request_PDU::ToPacket () const
1793  {
1794    CArray pdu;
1795    pdu.resize (2 + data.size());
1796    pdu[0] = A_Read_Router_Status_Request >> 8;
1797    pdu[1] = A_Read_Router_Status_Request & 0xff;
1798    pdu.setpart (data.data(), 2, data.size());
1799    return pdu;
1800  }
1801  
1802  std::string
1803  A_Read_Router_Status_Request_PDU::Decode (TracePtr) const
1804  {
1805    std::string s ("A_Read_Router_Status_Request");
1806    C_ITER (i, data)
1807    addHex (s, *i);
1808    return s;
1809  }
1810  
1811  bool A_Read_Router_Status_Request_PDU::isResponse (const APDU *) const
1812  {
1813    return false;
1814  }
1815  
1816  /* A_Read_Router_Status_Response */
1817  
1818  bool
1819  A_Read_Router_Status_Response_PDU::init (const CArray & c, TracePtr)
1820  {
1821    if (c.size() < 2)
1822      return false;
1823  
1824    data.set (c.data() + 2, c.size() - 2);
1825    return true;
1826  }
1827  
1828  CArray
1829  A_Read_Router_Status_Response_PDU::ToPacket () const
1830  {
1831    CArray pdu;
1832    pdu.resize (2 + data.size());
1833    pdu[0] = A_Read_Router_Status_Response >> 8;
1834    pdu[1] = A_Read_Router_Status_Response & 0xff;
1835    pdu.setpart (data.data(), 2, data.size());
1836    return pdu;
1837  }
1838  
1839  std::string
1840  A_Read_Router_Status_Response_PDU::Decode (TracePtr) const
1841  {
1842    std::string s ("A_Read_Router_Status_Response");
1843    C_ITER (i, data)
1844    addHex (s, *i);
1845    return s;
1846  }
1847  
1848  bool A_Read_Router_Status_Response_PDU::isResponse (const APDU * req) const
1849  {
1850    if (req->getType () != A_Read_Router_Status_Request)
1851      return false;
1852    return true;
1853  }
1854  
1855  /* A_Write_Router_Status_Request */
1856  
1857  bool
1858  A_Write_Router_Status_Request_PDU::init (const CArray & c, TracePtr)
1859  {
1860    if (c.size() < 2)
1861      return false;
1862  
1863    data.set (c.data() + 2, c.size() - 2);
1864    return true;
1865  }
1866  
1867  CArray
1868  A_Write_Router_Status_Request_PDU::ToPacket () const
1869  {
1870    CArray pdu;
1871    pdu.resize (2 + data.size());
1872    pdu[0] = A_Read_Router_Status_Request >> 8;
1873    pdu[1] = A_Read_Router_Status_Request & 0xff;
1874    pdu.setpart (data.data(), 2, data.size());
1875    return pdu;
1876  }
1877  
1878  std::string
1879  A_Write_Router_Status_Request_PDU::Decode (TracePtr) const
1880  {
1881    std::string s ("A_Write_Router_Status_Request");
1882    C_ITER (i, data)
1883    addHex (s, *i);
1884    return s;
1885  }
1886  
1887  bool A_Write_Router_Status_Request_PDU::isResponse (const APDU *) const
1888  {
1889    return false;
1890  }
1891  
1892  /* A_MemoryBit_Write */
1893  
1894  bool
1895  A_MemoryBit_Write_PDU::init (const CArray & c, TracePtr)
1896  {
1897    if (c.size() < 5)
1898      return false;
1899  
1900    number = c[2];
1901    address = (c[3] << 8) | c[4];
1902    if (c.size() - 5 != number * 2)
1903      return false;
1904    and_data.set (c.data() + 5, number);
1905    xor_data.set (c.data() + 5 + number, number);
1906    return true;
1907  }
1908  
1909  CArray
1910  A_MemoryBit_Write_PDU::ToPacket () const
1911  {
1912    assert (and_data.size() == number);
1913    assert (xor_data.size() == number);
1914  
1915    CArray pdu;
1916    pdu.resize (number * 2 + 5);
1917    pdu[0] = A_MemoryBit_Write >> 8;
1918    pdu[1] = A_MemoryBit_Write & 0xff;
1919    pdu[2] = number;
1920    pdu[3] = address >> 8;
1921    pdu[4] = address & 0xff;
1922    pdu.setpart (and_data.data(), 5, number);
1923    pdu.setpart (xor_data.data(), 5 + number, number);
1924    return pdu;
1925  }
1926  
1927  std::string
1928  A_MemoryBit_Write_PDU::Decode (TracePtr) const
1929  {
1930    assert (and_data.size() == number);
1931    assert (xor_data.size() == number);
1932  
1933    std::string s ("A_MemoryBit_Write Len:");
1934    addHex (s, number);
1935    s += "Addr: ";
1936    add16Hex (s, address);
1937    s += "And: ";
1938    C_ITER (i, and_data)
1939    addHex (s, *i);
1940    s += "xor: ";
1941    C_ITER (i, xor_data)
1942    addHex (s, *i);
1943    return s;
1944  }
1945  
1946  bool A_MemoryBit_Write_PDU::isResponse (const APDU *) const
1947  {
1948    return false;
1949  }
1950  
1951  /* A_Authorize_Request */
1952  
1953  bool
1954  A_Authorize_Request_PDU::init (const CArray & c, TracePtr)
1955  {
1956    if (c.size() != 7)
1957      return false;
1958  
1959    key = (c[3] << 24) | (c[4] << 16) | (c[5] << 8) | c[6];
1960    return true;
1961  }
1962  
1963  CArray
1964  A_Authorize_Request_PDU::ToPacket () const
1965  {
1966    CArray pdu;
1967    pdu.resize (7);
1968    pdu[0] = A_Authorize_Request >> 8;
1969    pdu[1] = A_Authorize_Request & 0xff;
1970    pdu[2] = 0x00;
1971    pdu[3] = key >> 24;
1972    pdu[4] = (key >> 16) & 0xff;
1973    pdu[5] = (key >> 8) & 0xff;
1974    pdu[6] = key & 0xff;
1975    return pdu;
1976  }
1977  
1978  std::string
1979  A_Authorize_Request_PDU::Decode (TracePtr) const
1980  {
1981    std::string s ("A_Authorize_Request Key:");
1982    return s + FormatEIBKey (key);
1983  }
1984  
1985  bool A_Authorize_Request_PDU::isResponse (const APDU *) const
1986  {
1987    return false;
1988  }
1989  
1990  /* A_Authorize_Response */
1991  
1992  bool
1993  A_Authorize_Response_PDU::init (const CArray & c, TracePtr)
1994  {
1995    if (c.size() != 3)
1996      return false;
1997  
1998    level = c[2];
1999    return true;
2000  }
2001  
2002  CArray
2003  A_Authorize_Response_PDU::ToPacket () const
2004  {
2005    CArray pdu;
2006    pdu.resize (3);
2007    pdu[0] = A_Authorize_Response >> 8;
2008    pdu[1] = A_Authorize_Response & 0xff;
2009    pdu[2] = level;
2010    return pdu;
2011  }
2012  
2013  std::string
2014  A_Authorize_Response_PDU::Decode (TracePtr) const
2015  {
2016    std::string s ("A_Authorize_Response Level:");
2017    addHex (s, level);
2018    return s;
2019  }
2020  
2021  bool A_Authorize_Response_PDU::isResponse (const APDU * req) const
2022  {
2023    if (req->getType () != A_Authorize_Request)
2024      return false;
2025    return true;
2026  }
2027  
2028  /* A_Key_Write */
2029  
2030  bool
2031  A_Key_Write_PDU::init (const CArray & c, TracePtr)
2032  {
2033    if (c.size() != 7)
2034      return false;
2035  
2036    level = c[2];
2037    key = (c[3] << 24) | (c[4] << 16) | (c[5] << 8) | c[6];
2038    return true;
2039  }
2040  
2041  CArray
2042  A_Key_Write_PDU::ToPacket () const
2043  {
2044    CArray pdu;
2045    pdu.resize (7);
2046    pdu[0] = A_Key_Write >> 8;
2047    pdu[1] = A_Key_Write & 0xff;
2048    pdu[2] = level;
2049    pdu[3] = key >> 24;
2050    pdu[4] = (key >> 16) & 0xff;
2051    pdu[5] = (key >> 8) & 0xff;
2052    pdu[6] = key & 0xff;
2053    return pdu;
2054  }
2055  
2056  std::string
2057  A_Key_Write_PDU::Decode (TracePtr) const
2058  {
2059    std::string s ("A_Key_Write Level:");
2060    addHex (s, level);
2061    s += " Key: ";
2062    return s + FormatEIBKey (key);
2063  }
2064  
2065  bool A_Key_Write_PDU::isResponse (const APDU *) const
2066  {
2067    return false;
2068  }
2069  
2070  /* A_Key_Response */
2071  
2072  bool
2073  A_Key_Response_PDU::init (const CArray & c, TracePtr)
2074  {
2075    if (c.size() != 3)
2076      return false;
2077  
2078    level = c[2];
2079    return true;
2080  }
2081  
2082  CArray
2083  A_Key_Response_PDU::ToPacket () const
2084  {
2085    CArray pdu;
2086    pdu.resize (3);
2087    pdu[0] = A_Key_Response >> 8;
2088    pdu[1] = A_Key_Response & 0xff;
2089    pdu[2] = level;
2090    return pdu;
2091  }
2092  
2093  std::string
2094  A_Key_Response_PDU::Decode (TracePtr) const
2095  {
2096    std::string s ("A_Key_Response Level:");
2097    addHex (s, level);
2098    return s;
2099  }
2100  
2101  bool A_Key_Response_PDU::isResponse (const APDU * req) const
2102  {
2103    if (req->getType () != A_Key_Write)
2104      return false;
2105    const A_Key_Write_PDU *
2106    a = (const A_Key_Write_PDU *) req;
2107    return a->level == level;
2108  }
2109  
2110  /* A_PropertyValue_Read */
2111  
2112  bool
2113  A_PropertyValue_Read_PDU::init (const CArray & c, TracePtr)
2114  {
2115    if (c.size() != 6)
2116      return false;
2117  
2118    object_index = c[2];
2119    property_id = c[3];
2120    nr_of_elem = c[4] >> 4;
2121    start_index = (c[4] & 0x0f) << 8 | c[5];
2122    return true;
2123  }
2124  
2125  CArray
2126  A_PropertyValue_Read_PDU::ToPacket () const
2127  {
2128    assert ((nr_of_elem & 0xf0) == 0);
2129    assert ((start_index & 0xf000) == 0);
2130  
2131    CArray pdu;
2132    pdu.resize (6);
2133    pdu[0] = A_PropertyValue_Read >> 8;
2134    pdu[1] = A_PropertyValue_Read & 0xff;
2135    pdu[2] = object_index;
2136    pdu[3] = property_id;
2137    pdu[4] = (nr_of_elem << 4) | (start_index >> 8);
2138    pdu[5] = start_index & 0xff;
2139    return pdu;
2140  }
2141  
2142  std::string
2143  A_PropertyValue_Read_PDU::Decode (TracePtr) const
2144  {
2145    assert ((nr_of_elem & 0xf0) == 0);
2146    assert ((start_index & 0xf000) == 0);
2147  
2148    std::string s ("A_PropertyValue_Read Obj:");
2149    addHex (s, object_index);
2150    s += " Prop: ";
2151    addHex (s, property_id);
2152    s += " start: ";
2153    addHex (s, start_index);
2154    s += " max_nr: ";
2155    addHex (s, nr_of_elem);
2156    return s;
2157  }
2158  
2159  bool A_PropertyValue_Read_PDU::isResponse (const APDU *) const
2160  {
2161    return false;
2162  }
2163  
2164  /* A_PropertyValue_Response */
2165  
2166  bool
2167  A_PropertyValue_Response_PDU::init (const CArray & c, TracePtr)
2168  {
2169    if (c.size() < 6)
2170      return false;
2171  
2172    object_index = c[2];
2173    property_id = c[3];
2174    nr_of_elem = c[4] >> 4;
2175    start_index = ((c[4] & 0x0f) << 8) | c[5];
2176    data.set (c.data() + 6, c.size() - 6);
2177    return true;
2178  }
2179  
2180  CArray
2181  A_PropertyValue_Response_PDU::ToPacket () const
2182  {
2183    assert ((nr_of_elem & 0xf0) == 0);
2184    assert ((start_index & 0xf000) == 0);
2185  
2186    CArray pdu;
2187    pdu.resize (6 + data.size());
2188    pdu[0] = A_PropertyValue_Response >> 8;
2189    pdu[1] = A_PropertyValue_Response & 0xff;
2190    pdu[2] = object_index;
2191    pdu[3] = property_id;
2192    pdu[4] = (nr_of_elem << 4) | (start_index >> 8);
2193    pdu[5] = start_index & 0xff;
2194    pdu.setpart (data.data(), 6, data.size());
2195    return pdu;
2196  }
2197  
2198  std::string
2199  A_PropertyValue_Response_PDU::Decode (TracePtr) const
2200  {
2201    assert ((nr_of_elem & 0xf0) == 0);
2202    assert ((start_index & 0xf000) == 0);
2203  
2204    std::string s ("A_PropertyValue_Response Obj:");
2205    addHex (s, object_index);
2206    s += " Prop: ";
2207    addHex (s, property_id);
2208    s += " start: ";
2209    addHex (s, start_index);
2210    s += " max_nr: ";
2211    addHex (s, nr_of_elem);
2212    s += "data: ";
2213    C_ITER (i,data)
2214    addHex (s, *i);
2215    return s;
2216  }
2217  
2218  bool A_PropertyValue_Response_PDU::isResponse (const APDU * req) const
2219  {
2220    if (req->getType () == A_PropertyValue_Write)
2221      {
2222        const A_PropertyValue_Write_PDU *
2223        a = (const A_PropertyValue_Write_PDU *) req;
2224        if (a->object_index != object_index)
2225          return false;
2226        if (a->property_id != property_id)
2227          return false;
2228        if (a->nr_of_elem != nr_of_elem)
2229          return false;
2230        if (a->start_index != start_index)
2231          return false;
2232        return true;
2233      }
2234    if (req->getType () == A_PropertyValue_Read)
2235      {
2236        const A_PropertyValue_Read_PDU *
2237        a = (const A_PropertyValue_Read_PDU *) req;
2238        if (a->object_index != object_index)
2239          return false;
2240        if (a->property_id != property_id)
2241          return false;
2242        if (a->nr_of_elem != nr_of_elem)
2243          return false;
2244        if (a->start_index != start_index)
2245          return false;
2246        return true;
2247      }
2248    return false;
2249  }
2250  
2251  /* A_PropertyValue_Write */
2252  
2253  bool
2254  A_PropertyValue_Write_PDU::init (const CArray & c, TracePtr)
2255  {
2256    if (c.size() < 6)
2257      return false;
2258  
2259    object_index = c[2];
2260    property_id = c[3];
2261    nr_of_elem = c[4] >> 4;
2262    start_index = ((c[4] & 0x0f) << 8) | c[5];
2263    data.set (c.data() + 6, c.size() - 6);
2264    return true;
2265  }
2266  
2267  CArray
2268  A_PropertyValue_Write_PDU::ToPacket () const
2269  {
2270    assert ((nr_of_elem & 0xf0) == 0);
2271    assert ((start_index & 0xf000) == 0);
2272  
2273    CArray pdu;
2274    pdu.resize (6 + data.size());
2275    pdu[0] = A_PropertyValue_Write >> 8;
2276    pdu[1] = A_PropertyValue_Write & 0xff;
2277    pdu[2] = object_index;
2278    pdu[3] = property_id;
2279    pdu[4] = (nr_of_elem << 4) | (start_index >> 8);
2280    pdu[5] = start_index & 0xff;
2281    pdu.setpart (data.data(), 6, data.size());
2282    return pdu;
2283  }
2284  
2285  std::string
2286  A_PropertyValue_Write_PDU::Decode (TracePtr) const
2287  {
2288    assert ((nr_of_elem & 0xf0) == 0);
2289    assert ((start_index & 0xf000) == 0);
2290  
2291    std::string s ("A_PropertyValue_Write Obj:");
2292    addHex (s, object_index);
2293    s += " Prop: ";
2294    addHex (s, property_id);
2295    s += " start: ";
2296    addHex (s, start_index);
2297    s += " max_nr: ";
2298    addHex (s, nr_of_elem);
2299    s += "data: ";
2300    C_ITER (i,data)
2301    addHex (s, *i);
2302    return s;
2303  }
2304  
2305  bool A_PropertyValue_Write_PDU::isResponse (const APDU *) const
2306  {
2307    return false;
2308  }
2309  
2310  /* A_PropertyDescription_Read */
2311  
2312  bool
2313  A_PropertyDescription_Read_PDU::init (const CArray & c, TracePtr)
2314  {
2315    if (c.size() != 5)
2316      return false;
2317  
2318    object_index = c[2];
2319    property_id = c[3];
2320    property_index = c[4];
2321    return true;
2322  }
2323  
2324  CArray
2325  A_PropertyDescription_Read_PDU::ToPacket () const
2326  {
2327    CArray pdu;
2328    pdu.resize (5);
2329    pdu[0] = A_PropertyDescription_Read >> 8;
2330    pdu[1] = A_PropertyDescription_Read & 0xff;
2331    pdu[2] = object_index;
2332    pdu[3] = property_id;
2333    pdu[4] = property_index;
2334    return pdu;
2335  }
2336  
2337  std::string
2338  A_PropertyDescription_Read_PDU::Decode (TracePtr) const
2339  {
2340    std::string s ("A_PropertyDescription_Read Obj: ");
2341    addHex (s, object_index);
2342    s += " Property: ";
2343    addHex (s, property_id);
2344    s += " Property_index: ";
2345    addHex (s, property_index);
2346    return s;
2347  }
2348  
2349  bool A_PropertyDescription_Read_PDU::isResponse (const APDU *) const
2350  {
2351    return false;
2352  }
2353  
2354  /* A_PropertyDescription_Response */
2355  
2356  bool
2357  A_PropertyDescription_Response_PDU::init (const CArray & c, TracePtr)
2358  {
2359    if (c.size() != 9)
2360      return false;
2361  
2362    object_index = c[2];
2363    property_id = c[3];
2364    property_index = c[4];
2365    write_enable = c[5] >> 7;
2366    type = c[5] & 0x3f;
2367    max_nr_of_elem = ((c[6] & 0x0f) << 8) | c[7];
2368    access = c[8];
2369    return true;
2370  }
2371  
2372  CArray
2373  A_PropertyDescription_Response_PDU::ToPacket () const
2374  {
2375    CArray pdu;
2376    pdu.resize (9);
2377    pdu[0] = A_PropertyDescription_Response >> 8;
2378    pdu[1] = A_PropertyDescription_Response & 0xff;
2379    pdu[2] = object_index;
2380    pdu[3] = property_id;
2381    pdu[4] = property_index;
2382    pdu[5] = (write_enable << 7) | (type & 0x3f);
2383    pdu[6] = max_nr_of_elem >> 8;
2384    pdu[7] = max_nr_of_elem & 0xff;
2385    pdu[8] = access;
2386    return pdu;
2387  }
2388  
2389  std::string
2390  A_PropertyDescription_Response_PDU::Decode (TracePtr) const
2391  {
2392    std::string s ("A_PropertyDescription_Response Obj:");
2393    addHex (s, object_index);
2394    s += " Property: ";
2395    addHex (s, property_id);
2396    s += " Property_index: ";
2397    addHex (s, property_index);
2398    // @todo write_enable
2399    s += " Type: ";
2400    addHex (s, type);
2401    s += "max_elements: ";
2402    add16Hex (s, max_nr_of_elem);
2403    s += " access: ";
2404    addHex (s, access);
2405    return s;
2406  }
2407  
2408  bool A_PropertyDescription_Response_PDU::isResponse (const APDU * req) const
2409  {
2410    if (req->getType () != A_PropertyDescription_Read)
2411      return false;
2412    const A_PropertyDescription_Read_PDU *
2413    a = (const A_PropertyDescription_Read_PDU *) req;
2414    if (a->object_index != object_index)
2415      return false;
2416    return true;
2417  }
2418  
2419  /* A_NetworkParameter_Read */
2420  
2421  bool
2422  A_NetworkParameter_Read_PDU::init (const CArray & c, TracePtr)
2423  {
2424    if (c.size() < 5)
2425      return false;
2426  
2427    parameter_type.set (c.data() + 2, 3);
2428    test_info.set (c.data() + 5, c.size() - 5);
2429    return true;
2430  }
2431  
2432  CArray
2433  A_NetworkParameter_Read_PDU::ToPacket () const
2434  {
2435    CArray pdu;
2436    pdu.resize (5 + test_info.size());
2437    pdu[0] = A_NetworkParameter_Read >> 8;
2438    pdu[1] = A_NetworkParameter_Read & 0xff;
2439    pdu.setpart (parameter_type.data(), 3, 3);
2440    pdu.setpart (test_info.data(), 5, test_info.size());
2441    return pdu;
2442  }
2443  
2444  std::string
2445  A_NetworkParameter_Read_PDU::Decode (TracePtr) const
2446  {
2447    std::string s ("A_NetworkParameter_Read");
2448    // @todo
2449    return s;
2450  }
2451  
2452  bool A_NetworkParameter_Read_PDU::isResponse (const APDU *) const
2453  {
2454    return false;
2455  }
2456  
2457  /* A_NetworkParameter_Response */
2458  
2459  bool
2460  A_NetworkParameter_Response_PDU::init (const CArray & c, TracePtr)
2461  {
2462    if (c.size() != 16)
2463      return false;
2464  
2465    parameter_type.set (c.data() + 2, 3);
2466    test_info_result.set (c.data() + 5, c.size() - 5);
2467    return true;
2468  }
2469  
2470  CArray
2471  A_NetworkParameter_Response_PDU::ToPacket () const
2472  {
2473    CArray pdu;
2474    pdu.resize (5 + test_info_result.size());
2475    pdu[0] = A_NetworkParameter_Response >> 8;
2476    pdu[1] = A_NetworkParameter_Response & 0xff;
2477    pdu.setpart (parameter_type.data(), 3, 3);
2478    pdu.setpart (test_info_result.data(), 5, test_info_result.size());
2479    return pdu;
2480  }
2481  
2482  std::string
2483  A_NetworkParameter_Response_PDU::Decode (TracePtr) const
2484  {
2485    std::string s ("A_NetworkParameter_Response");
2486    // @todo
2487    return s;
2488  }
2489  
2490  bool A_NetworkParameter_Response_PDU::isResponse (const APDU * req) const
2491  {
2492    if (req->getType () != A_NetworkParameter_Read)
2493      return false;
2494    const A_NetworkParameter_Read_PDU *
2495    a = (const A_NetworkParameter_Read_PDU *) req;
2496    if (a->parameter_type != parameter_type)
2497      return false;
2498    // @todo compare test_info
2499    return true;
2500  }
2501  
2502  /* A_IndividualAddressSerialNumber_Read */
2503  
2504  A_IndividualAddressSerialNumber_Read_PDU::
2505  A_IndividualAddressSerialNumber_Read_PDU ()
2506  {
2507    serial_number.fill(0);
2508  }
2509  
2510  bool
2511  A_IndividualAddressSerialNumber_Read_PDU::init (const CArray & c, TracePtr)
2512  {
2513    if (c.size() != 8)
2514      return false;
2515  
2516    std::copy(c.begin() + 2, c.begin() + 8, serial_number.begin());
2517    return true;
2518  }
2519  
2520  CArray A_IndividualAddressSerialNumber_Read_PDU::ToPacket () const
2521  {
2522    CArray pdu;
2523    pdu.resize (8);
2524    pdu[0] = A_IndividualAddressSerialNumber_Read >> 8;
2525    pdu[1] = A_IndividualAddressSerialNumber_Read & 0xff;
2526    pdu.setpart (serial_number.data(), 2, 6);
2527    return pdu;
2528  }
2529  
2530  std::string A_IndividualAddressSerialNumber_Read_PDU::Decode (TracePtr) const
2531  {
2532    std::string
2533    s ("A_IndividualAddressSerialNumber_Read ");
2534    addHex (s, serial_number[0]);
2535    addHex (s, serial_number[1]);
2536    addHex (s, serial_number[2]);
2537    addHex (s, serial_number[3]);
2538    addHex (s, serial_number[4]);
2539    addHex (s, serial_number[5]);
2540    return s;
2541  }
2542  
2543  bool
2544  A_IndividualAddressSerialNumber_Read_PDU::isResponse (const APDU *)
2545  const
2546  {
2547    return false;
2548  }
2549  
2550  /* A_IndividualAddressSerialNumber_Response */
2551  
2552  A_IndividualAddressSerialNumber_Response_PDU::
2553  A_IndividualAddressSerialNumber_Response_PDU ()
2554  {
2555    serial_number.fill(0);
2556  }
2557  
2558  bool
2559  A_IndividualAddressSerialNumber_Response_PDU::init (const CArray & c, TracePtr)
2560  {
2561    if (c.size() != 12)
2562      return false;
2563  
2564    std::copy(c.begin() + 2, c.begin() + 8, serial_number.begin());
2565    domain_address = (c[8] << 8) | (c[9]);
2566    reserved.set (c.data() + 10, 2);
2567    return true;
2568  }
2569  
2570  CArray A_IndividualAddressSerialNumber_Response_PDU::ToPacket () const
2571  {
2572    CArray pdu;
2573    pdu.resize (12);
2574    pdu[0] = A_IndividualAddressSerialNumber_Response >> 8;
2575    pdu[1] = A_IndividualAddressSerialNumber_Response & 0xff;
2576    pdu.setpart (serial_number.data(), 2, 6);
2577    pdu[8] = domain_address >> 8;
2578    pdu[9] = domain_address & 0xff;
2579    pdu[10] = reserved[0];
2580    pdu[11] = reserved[1];
2581    return pdu;
2582  }
2583  
2584  std::string A_IndividualAddressSerialNumber_Response_PDU::Decode (TracePtr) const
2585  {
2586    std::string
2587    s ("A_IndividualAddressSerialNumber_Response ");
2588    addHex (s, serial_number[0]);
2589    addHex (s, serial_number[1]);
2590    addHex (s, serial_number[2]);
2591    addHex (s, serial_number[3]);
2592    addHex (s, serial_number[4]);
2593    addHex (s, serial_number[5]);
2594    s += "Addr: ";
2595    add16Hex (s, domain_address);
2596    return s;
2597  }
2598  
2599  bool
2600  A_IndividualAddressSerialNumber_Response_PDU::isResponse (const APDU * req) const
2601  {
2602    if (req->getType () != A_IndividualAddressSerialNumber_Read)
2603      return false;
2604    const A_IndividualAddressSerialNumber_Read_PDU *a =
2605      (const A_IndividualAddressSerialNumber_Read_PDU *) req;
2606    if (a->serial_number != serial_number)
2607      return false;
2608    return true;
2609  }
2610  
2611  /* A_IndividualAddressSerialNumber_Write */
2612  
2613  A_IndividualAddressSerialNumber_Write_PDU::
2614  A_IndividualAddressSerialNumber_Write_PDU ()
2615  {
2616    serial_number.fill(0);
2617  }
2618  
2619  bool A_IndividualAddressSerialNumber_Write_PDU::init (const CArray & c, TracePtr)
2620  {
2621    if (c.size() != 14)
2622      return false;
2623  
2624    std::copy(c.begin() + 2, c.begin() + 8, serial_number.begin());
2625    newaddress = (c[8] << 8) | (c[9]);
2626    reserved.set (c.data() + 10, 4);
2627    return true;
2628  }
2629  
2630  CArray A_IndividualAddressSerialNumber_Write_PDU::ToPacket () const
2631  {
2632    CArray pdu;
2633    pdu.resize (14);
2634    pdu[0] = A_IndividualAddressSerialNumber_Write >> 8;
2635    pdu[1] = A_IndividualAddressSerialNumber_Write & 0xff;
2636    pdu.setpart (serial_number.data(), 2, 6);
2637    pdu[8] = newaddress >> 8;
2638    pdu[9] = newaddress & 0xff;
2639    pdu[10] = reserved[0];
2640    pdu[11] = reserved[1];
2641    pdu[12] = reserved[2];
2642    pdu[13] = reserved[3];
2643    return pdu;
2644  }
2645  
2646  std::string A_IndividualAddressSerialNumber_Write_PDU::Decode (TracePtr) const
2647  {
2648    std::string
2649    s ("A_IndividualAddressSerialNumber_Write ");
2650    addHex (s, serial_number[0]);
2651    addHex (s, serial_number[1]);
2652    addHex (s, serial_number[2]);
2653    addHex (s, serial_number[3]);
2654    addHex (s, serial_number[4]);
2655    addHex (s, serial_number[5]);
2656    s += "Addr: ";
2657    s += FormatEIBAddr (newaddress);
2658    return s;
2659  }
2660  
2661  bool
2662  A_IndividualAddressSerialNumber_Write_PDU::isResponse (const APDU *)
2663  const
2664  {
2665    return false;
2666  }
2667  
2668  /* A_ServiceInformation_Indication_Write_PDU */
2669  
2670  bool
2671  A_ServiceInformation_Indication_Write_PDU::init (const CArray & c, TracePtr)
2672  {
2673    if (c.size() != 5)
2674      return false;
2675  
2676    verify_mode = (c[2] & 0x04) ? true : false;
2677    duplicate_address = (c[3] & 0x02) ? true : false;
2678    appl_stopped = (c[2] & 0x01) ? true : false;
2679    return true;
2680  }
2681  
2682  CArray
2683  A_ServiceInformation_Indication_Write_PDU::ToPacket () const
2684  {
2685    CArray pdu;
2686    pdu.resize (5);
2687    pdu[0] = A_ServiceInformation_Indication_Write >> 8;
2688    pdu[1] = A_ServiceInformation_Indication_Write & 0xff;
2689    pdu[2] = (verify_mode << 2) | (duplicate_address << 1) | appl_stopped;
2690    pdu[3] = 0x00;
2691    pdu[4] = 0x00;
2692    return pdu;
2693  }
2694  
2695  std::string
2696  A_ServiceInformation_Indication_Write_PDU::Decode (TracePtr) const
2697  {
2698    std::string s ("A_ServiceInformation_Indication_Write ");
2699    if (verify_mode)
2700      s += "verify ";
2701    if (duplicate_address)
2702      s += "dupplicate_address ";
2703    if (appl_stopped)
2704      s += "appl_stopped ";
2705  
2706    return s;
2707  }
2708  
2709  bool
2710  A_ServiceInformation_Indication_Write_PDU::isResponse (const APDU *)
2711  const
2712  {
2713    return false;
2714  }
2715  
2716  /* A_DomainAddress_Write */
2717  
2718  bool
2719  A_DomainAddress_Write_PDU::init (const CArray & c, TracePtr)
2720  {
2721    if (c.size() != 4)
2722      return false;
2723  
2724    domain_address = (c[2] << 8) | (c[3]);
2725    return true;
2726  }
2727  
2728  CArray A_DomainAddress_Write_PDU::ToPacket () const
2729  {
2730    CArray pdu;
2731    pdu.resize (4);
2732    pdu[0] = A_DomainAddress_Write >> 8;
2733    pdu[1] = A_DomainAddress_Write & 0xff;
2734    pdu[2] = domain_address >> 8;
2735    pdu[3] = domain_address & 0xff;
2736    return pdu;
2737  }
2738  
2739  std::string A_DomainAddress_Write_PDU::Decode (TracePtr) const
2740  {
2741    std::string s ("A_DomainAddress_Write ");
2742    return s + FormatDomainAddr (domain_address);
2743  }
2744  
2745  
2746  bool A_DomainAddress_Write_PDU::isResponse (const APDU *) const
2747  {
2748    return false;
2749  }
2750  
2751  /* A_DomainAddress_Read */
2752  
2753  bool
2754  A_DomainAddress_Read_PDU::init (const CArray & c, TracePtr)
2755  {
2756    if (c.size() != 2)
2757      return false;
2758    return true;
2759  }
2760  
2761  CArray A_DomainAddress_Read_PDU::ToPacket () const
2762  {
2763    CArray pdu;
2764    pdu.resize(2);
2765    pdu[0] = A_DomainAddress_Read >> 8;
2766    pdu[1] = A_DomainAddress_Read & 0xff;
2767    return pdu;
2768  }
2769  
2770  std::string A_DomainAddress_Read_PDU::Decode (TracePtr) const
2771  {
2772    return "A_DomainAddress_Read";
2773  }
2774  
2775  bool A_DomainAddress_Read_PDU::isResponse (const APDU *) const
2776  {
2777    return false;
2778  }
2779  
2780  /* A_DomainAddress_Response */
2781  
2782  bool
2783  A_DomainAddress_Response_PDU::init (const CArray & c, TracePtr)
2784  {
2785    if (c.size() != 4)
2786      return false;
2787  
2788    domain_address = (c[2] << 8) | c[3];
2789    return true;
2790  }
2791  
2792  CArray A_DomainAddress_Response_PDU::ToPacket () const
2793  {
2794    CArray pdu;
2795    pdu.resize (4);
2796    pdu[0] = A_DomainAddress_Response >> 8;
2797    pdu[1] = A_DomainAddress_Response & 0xff;
2798    pdu[2] = domain_address >> 8;
2799    pdu[3] = domain_address & 0xff;
2800    return pdu;
2801  }
2802  
2803  std::string A_DomainAddress_Response_PDU::Decode (TracePtr) const
2804  {
2805    std::string s ("A_DomainAddress_Response");
2806    s += FormatDomainAddr (domain_address);
2807    return s;
2808  }
2809  
2810  bool A_DomainAddress_Response_PDU::isResponse (const APDU * req) const
2811  {
2812    if (req->getType () != A_DomainAddress_Read)
2813      return false;
2814    return true;
2815  }
2816  
2817  /* A_DomainAddressSelective_Read */
2818  
2819  bool
2820  A_DomainAddressSelective_Read_PDU::init (const CArray & c, TracePtr)
2821  {
2822    if (c.size() != 7)
2823      return false;
2824  
2825    domain_address = (c[2] << 8) | c[3];
2826    start_address = (c[4] << 8) | c[5];
2827    range = c[6];
2828    return true;
2829  }
2830  
2831  CArray A_DomainAddressSelective_Read_PDU::ToPacket () const
2832  {
2833    CArray pdu;
2834    pdu.resize (7);
2835    pdu[0] = A_DomainAddressSelective_Read >> 8;
2836    pdu[1] = A_DomainAddressSelective_Read & 0xff;
2837    pdu[2] = domain_address >> 8;
2838    pdu[3] = domain_address & 0xff;
2839    pdu[2] = start_address >> 8;
2840    pdu[3] = start_address & 0xff;
2841    pdu[6] = range;
2842    return pdu;
2843  }
2844  
2845  std::string
2846  A_DomainAddressSelective_Read_PDU::Decode (TracePtr) const
2847  {
2848    std::string s ("A_DomainAddressSelective_Read ");
2849    s += FormatDomainAddr (domain_address);
2850    s += " ";
2851    s += FormatEIBAddr (start_address);
2852    s += " ";
2853    addHex (s, range);
2854    return s;
2855  }
2856  
2857  bool A_DomainAddressSelective_Read_PDU::isResponse (const APDU *) const
2858  {
2859    return false;
2860  }
2861  
2862  /* A_NetworkParameter_Write */
2863  
2864  bool
2865  A_NetworkParameter_Write_PDU::init (const CArray & c, TracePtr)
2866  {
2867    if (c.size() < 5)
2868      return false;
2869  
2870    parameter_type.set (c.data() + 2, 3);
2871    value.set (c.data() + 5, c.size() - 5);
2872    return true;
2873  }
2874  
2875  CArray
2876  A_NetworkParameter_Write_PDU::ToPacket () const
2877  {
2878    CArray pdu;
2879    pdu.resize (5 + value.size());
2880    pdu[0] = A_NetworkParameter_Write >> 8;
2881    pdu[1] = A_NetworkParameter_Write & 0xff;
2882    pdu.setpart (parameter_type.data(), 3, 3);
2883    pdu.setpart (value.data(), 5, value.size());
2884    return pdu;
2885  }
2886  
2887  std::string
2888  A_NetworkParameter_Write_PDU::Decode (TracePtr) const
2889  {
2890    std::string s ("A_NetworkParameter_Write");
2891    // @todo
2892    return s;
2893  }
2894  
2895  bool A_NetworkParameter_Write_PDU::isResponse (const APDU *) const
2896  {
2897    return false;
2898  }
2899  
2900  /* A_Link_Read */
2901  
2902  bool
2903  A_Link_Read_PDU::init (const CArray & c, TracePtr)
2904  {
2905    if (c.size() != 4)
2906      return false;
2907  
2908    group_object_number = c[2];
2909    start_index = c[3] & 0x0f;
2910    return true;
2911  }
2912  
2913  CArray
2914  A_Link_Read_PDU::ToPacket () const
2915  {
2916    CArray pdu;
2917    pdu.resize(4);
2918    pdu[0] = A_Link_Read >> 8;
2919    pdu[1] = A_Link_Read & 0xff;
2920    pdu[2] = group_object_number;
2921    pdu[3] = start_index & 0x0f;
2922    return pdu;
2923  }
2924  
2925  std::string
2926  A_Link_Read_PDU::Decode (TracePtr) const
2927  {
2928    std::string s ("A_Link_Read");
2929    // @todo
2930    return s;
2931  }
2932  
2933  bool A_Link_Read_PDU::isResponse (const APDU *) const
2934  {
2935    return false;
2936  }
2937  
2938  /* A_Link_Response */
2939  
2940  bool
2941  A_Link_Response_PDU::init (const CArray & c, TracePtr)
2942  {
2943    if (c.size() < 4)
2944      return false;
2945  
2946    group_object_number = c[2];
2947    sending_address = c[3] >> 4;
2948    start_index = c[3] & 0x0f;
2949    group_address_list.set (c.data() + 4, c.size() - 4);
2950    return true;
2951  }
2952  
2953  CArray
2954  A_Link_Response_PDU::ToPacket () const
2955  {
2956    CArray pdu;
2957    pdu.resize(4 + group_address_list.size());
2958    pdu[0] = A_Link_Response >> 8;
2959    pdu[1] = A_Link_Response & 0xff;
2960    pdu[2] = group_object_number;
2961    pdu[3] = (sending_address << 4) | start_index;
2962    pdu.setpart (group_address_list.data(), 4, group_address_list.size());
2963    return pdu;
2964  }
2965  
2966  std::string
2967  A_Link_Response_PDU::Decode (TracePtr) const
2968  {
2969    std::string s ("A_Link_Response");
2970    // @todo
2971    return s;
2972  }
2973  
2974  bool A_Link_Response_PDU::isResponse (const APDU * req) const
2975  {
2976    if (req->getType () != A_Link_Read)
2977      return false;
2978    const A_Link_Read_PDU * a =
2979      (const A_Link_Read_PDU *) req;
2980    if (a->group_object_number != group_object_number)
2981      return false;
2982    if (a->start_index != start_index)
2983      return false;
2984    return true;
2985  }
2986  
2987  /* A_Link_Write */
2988  
2989  bool
2990  A_Link_Write_PDU::init (const CArray & c, TracePtr)
2991  {
2992    if (c.size() != 6)
2993      return false;
2994  
2995    group_object_number = c[2];
2996    flags = c[3] & 0x03;
2997    group_address = (c[4] << 8) | c[5];
2998    return true;
2999  }
3000  
3001  CArray
3002  A_Link_Write_PDU::ToPacket () const
3003  {
3004    CArray pdu;
3005    pdu.resize(6);
3006    pdu[0] = A_Link_Write >> 8;
3007    pdu[1] = A_Link_Write & 0xff;
3008    pdu[2] = group_object_number;
3009    pdu[3] = flags;
3010    pdu[4] = group_address >> 8;
3011    pdu[5] = group_address & 0xff;
3012    return pdu;
3013  }
3014  
3015  std::string
3016  A_Link_Write_PDU::Decode (TracePtr) const
3017  {
3018    std::string s ("A_Link_Write");
3019    // @todo
3020    return s;
3021  }
3022  
3023  bool A_Link_Write_PDU::isResponse (const APDU *) const
3024  {
3025    return false;
3026  }
3027  
3028  /* A_GroupPropValue_Read */
3029  
3030  bool
3031  A_GroupPropValue_Read_PDU::init (const CArray &, TracePtr)
3032  {
3033    // @todo
3034    return true;
3035  }
3036  
3037  CArray
3038  A_GroupPropValue_Read_PDU::ToPacket () const
3039  {
3040    CArray pdu;
3041    pdu.resize(2);
3042    pdu[0] = A_GroupPropValue_Read >> 8;
3043    pdu[1] = A_GroupPropValue_Read & 0xff;
3044    // @todo
3045    return pdu;
3046  }
3047  
3048  std::string
3049  A_GroupPropValue_Read_PDU::Decode (TracePtr) const
3050  {
3051    std::string s ("A_GroupPropValue_Read");
3052    // @todo
3053    return s;
3054  }
3055  
3056  bool A_GroupPropValue_Read_PDU::isResponse (const APDU *) const
3057  {
3058    return false;
3059  }
3060  
3061  /* A_GroupPropValue_Response */
3062  
3063  bool
3064  A_GroupPropValue_Response_PDU::init (const CArray &, TracePtr)
3065  {
3066    // @todo
3067    return true;
3068  }
3069  
3070  CArray
3071  A_GroupPropValue_Response_PDU::ToPacket () const
3072  {
3073    CArray pdu;
3074    pdu.resize(2);
3075    pdu[0] = A_GroupPropValue_Response >> 8;
3076    pdu[1] = A_GroupPropValue_Response & 0xff;
3077    // @todo
3078    return pdu;
3079  }
3080  
3081  std::string
3082  A_GroupPropValue_Response_PDU::Decode (TracePtr) const
3083  {
3084    std::string s ("A_GroupPropValue_Response");
3085    // @todo
3086    return s;
3087  }
3088  
3089  bool A_GroupPropValue_Response_PDU::isResponse (const APDU * req) const
3090  {
3091    if (req->getType () != A_GroupPropValue_Read)
3092      return false;
3093    // @todo
3094    return true;
3095  }
3096  
3097  /* A_GroupPropValue_Write */
3098  
3099  bool
3100  A_GroupPropValue_Write_PDU::init (const CArray &, TracePtr)
3101  {
3102    // @todo
3103    return true;
3104  }
3105  
3106  CArray
3107  A_GroupPropValue_Write_PDU::ToPacket () const
3108  {
3109    CArray pdu;
3110    pdu.resize(2);
3111    pdu[0] = A_GroupPropValue_Write >> 8;
3112    pdu[1] = A_GroupPropValue_Write & 0xff;
3113    // @todo
3114    return pdu;
3115  }
3116  
3117  std::string
3118  A_GroupPropValue_Write_PDU::Decode (TracePtr) const
3119  {
3120    std::string s ("A_GroupPropValue_Write");
3121    // @todo
3122    return s;
3123  }
3124  
3125  bool A_GroupPropValue_Write_PDU::isResponse (const APDU *) const
3126  {
3127    return false;
3128  }
3129  
3130  /* A_GroupPropValue_InfoReport */
3131  
3132  bool
3133  A_GroupPropValue_InfoReport_PDU::init (const CArray &, TracePtr)
3134  {
3135    // @todo
3136    return true;
3137  }
3138  
3139  CArray
3140  A_GroupPropValue_InfoReport_PDU::ToPacket () const
3141  {
3142    CArray pdu;
3143    pdu.resize(2);
3144    pdu[0] = A_GroupPropValue_InfoReport >> 8;
3145    pdu[1] = A_GroupPropValue_InfoReport & 0xff;
3146    // @todo
3147    return pdu;
3148  }
3149  
3150  std::string
3151  A_GroupPropValue_InfoReport_PDU::Decode (TracePtr) const
3152  {
3153    std::string s ("A_GroupPropValue_InfoReport");
3154    // @todo
3155    return s;
3156  }
3157  
3158  bool A_GroupPropValue_InfoReport_PDU::isResponse (const APDU *) const
3159  {
3160    // @todo
3161    return false;
3162  }
3163  
3164  /* A_DomainAddressSerialNumber_Read */
3165  
3166  bool
3167  A_DomainAddressSerialNumber_Read_PDU::init (const CArray &, TracePtr)
3168  {
3169    // @todo
3170    return true;
3171  }
3172  
3173  CArray
3174  A_DomainAddressSerialNumber_Read_PDU::ToPacket () const
3175  {
3176    CArray pdu;
3177    pdu.resize(2);
3178    pdu[0] = A_DomainAddressSerialNumber_Read >> 8;
3179    pdu[1] = A_DomainAddressSerialNumber_Read & 0xff;
3180    // @todo
3181    return pdu;
3182  }
3183  
3184  std::string
3185  A_DomainAddressSerialNumber_Read_PDU::Decode (TracePtr) const
3186  {
3187    std::string s ("A_DomainAddressSerialNumber_Read");
3188    // @todo
3189    return s;
3190  }
3191  
3192  bool A_DomainAddressSerialNumber_Read_PDU::isResponse (const APDU *) const
3193  {
3194    return false;
3195  }
3196  
3197  /* A_DomainAddressSerialNumber_Response */
3198  
3199  bool
3200  A_DomainAddressSerialNumber_Response_PDU::init (const CArray &, TracePtr)
3201  {
3202    // @todo
3203    return true;
3204  }
3205  
3206  CArray
3207  A_DomainAddressSerialNumber_Response_PDU::ToPacket () const
3208  {
3209    CArray pdu;
3210    pdu.resize(2);
3211    pdu[0] = A_DomainAddressSerialNumber_Response >> 8;
3212    pdu[1] = A_DomainAddressSerialNumber_Response & 0xff;
3213    // @todo
3214    return pdu;
3215  }
3216  
3217  std::string
3218  A_DomainAddressSerialNumber_Response_PDU::Decode (TracePtr) const
3219  {
3220    std::string s ("A_DomainAddressSerialNumber_Response");
3221    // @todo
3222    return s;
3223  }
3224  
3225  bool A_DomainAddressSerialNumber_Response_PDU::isResponse (const APDU * req) const
3226  {
3227    if (req->getType () != A_DomainAddressSerialNumber_Read)
3228      return false;
3229    // @todo
3230    return true;
3231  }
3232  
3233  /* A_DomainAddressSerialNumber_Write */
3234  
3235  bool
3236  A_DomainAddressSerialNumber_Write_PDU::init (const CArray &, TracePtr)
3237  {
3238    // @todo
3239    return true;
3240  }
3241  
3242  CArray
3243  A_DomainAddressSerialNumber_Write_PDU::ToPacket () const
3244  {
3245    CArray pdu;
3246    pdu.resize(2);
3247    pdu[0] = A_DomainAddressSerialNumber_Write >> 8;
3248    pdu[1] = A_DomainAddressSerialNumber_Write & 0xff;
3249    // @todo
3250    return pdu;
3251  }
3252  
3253  std::string
3254  A_DomainAddressSerialNumber_Write_PDU::Decode (TracePtr) const
3255  {
3256    std::string s ("A_DomainAddressSerialNumber_Write");
3257    // @todo
3258    return s;
3259  }
3260  
3261  bool A_DomainAddressSerialNumber_Write_PDU::isResponse (const APDU *) const
3262  {
3263    return false;
3264  }
3265  
3266  /* A_FileStream_InfoReport */
3267  
3268  bool
3269  A_FileStream_InfoReport_PDU::init (const CArray & c, TracePtr)
3270  {
3271    if (c.size() < 3)
3272      return false;
3273  
3274    file_handle = c[2] >> 4;
3275    file_block_sequence_number = c[2] & 0x0f;
3276    file_block.set (c.data() + 3, c.size() - 3);
3277    return true;
3278  }
3279  
3280  CArray
3281  A_FileStream_InfoReport_PDU::ToPacket () const
3282  {
3283    CArray pdu;
3284    pdu.resize(3 + file_block.size());
3285    pdu[0] = A_FileStream_InfoReport >> 8;
3286    pdu[1] = A_FileStream_InfoReport & 0xff;
3287    pdu[2] = (file_handle << 4) | file_block_sequence_number;
3288    pdu.setpart (file_block.data(), 3, file_block.size());
3289    return pdu;
3290  }
3291  
3292  std::string
3293  A_FileStream_InfoReport_PDU::Decode (TracePtr) const
3294  {
3295    std::string s ("A_FileStream_InfoReport");
3296    // @todo
3297    return s;
3298  }
3299  
3300  bool A_FileStream_InfoReport_PDU::isResponse (const APDU *) const
3301  {
3302    // @todo
3303    return false;
3304  }