logo.png

Packets objects

Conf objects

Basic objects

Run objects

Misc modules

Home Up


Contents



1 Introduction

What: Managing packets content.

This library is a copy of the base software made by David Decotigny still available in the CVS's svn/calice/online-sw/trunk/daq/calice_packets/ directory. It is now copied at:

  • libLDA/include/packets/
  • libLDA/packets/

From svn/calice/online-sw/trunk/daq/calice_packets/calice_packets.hpp we can read:

   * Base class. Defines the notions of SDU and PDU common to all the
   * accessor objects.
   *
   * Typical topology of a SDU (aka. packet):
   *
   *  +-----------+--...-------...-----+--------+
   *  | Header    |       PDU          | Footer |
   *  +-----------+--...-------...-----+--------+
   *
   * The PktAccessor_Base class defines the access to the SDU and PDU
   * and allows to process the packet before it is actually sent. The
   * children classes would alow to access the various fields inside
   * the Header and Footer, and manipulate the packet attributes such
   * as the PDU size.

All the accessor objects inherit from the PktAccessor_Base ABC, which defines 2 notions: the SDU (Service Data Unit) and the PDU (Protocol Data Unit). The idea is that the whole packet is called the "SDU". It encapsulates a unique PDU, this PDU corresponding to the arbitrary data being transmitted by the packet. So packet=SDU, and data_carried_by_the_packet=PDU. The SDU is supposed to contain protocol data which have to be updated once the packet is ready to be sent, such as a CRC: the PktAccessor_Base interface declares the sync_crc() method to do just that.


2 API


2.1 PktAccessor_Base

 class PktAccessor_Base
  {
  public:
    virtual ~PktAccessor_Base() { }
    virtual void * get_sdu() const =0;
    virtual unsigned int get_sdu_nbytes() const =0;
    virtual void * get_pdu() const =0;
    virtual unsigned int get_pdu_nbytes() const =0;
    virtual void sync_crc() =0;

  protected:
    PktAccessor_Base() { }
  };


2.2 PktAccessor_LDA_pkt

 class PktAccessor_LDA_pkt
    : public PktAccessor_ODR_pkt
  {
  public:
    PktAccessor_LDA_pkt();
    PktAccessor_LDA_pkt(void const* sdu,
			unsigned int sdu_nbytes,
			bool sdu_is_garbage = false);
    PktAccessor_LDA_pkt(unsigned int min_pdu_nbytes);
    virtual void attach(void const* sdu,
			unsigned int sdu_nbytes,
			bool sdu_is_garbage = false); /* throw() */
    virtual void detach();
    virtual void * get_pdu() const;
    virtual unsigned int get_pdu_nbytes() const;
    virtual void set_pdu_nbytes(unsigned int min_pdu_nbytes);
    inline bool is_fast_command_request() const;

    /* Normal packets: */
    inline unsigned char get_LDA_subsystem() const;
    inline void set_LDA_subsystem(unsigned char);
    inline unsigned char get_LDA_optype() const;
    inline void set_LDA_optype(unsigned char);

    /* Same fields */
    inline unsigned short get_LDA_Modifier() const;
    inline void set_LDA_Modifier(unsigned short);
    inline unsigned short get_LDA_from_diflink_id() const; /* base 1 */
    inline void set_LDA_from_diflink_id(unsigned short /* base 1 */);
    inline unsigned short get_LDA_to_diflink_id() const; /* base 0 */
    inline void set_LDA_to_diflink_id(unsigned short /* base 0 */);
    inline unsigned short get_LDA_PktID() const;
    inline void set_LDA_PktID(unsigned short);
    inline unsigned short get_LDA_DataLength() const;
    inline void set_LDA_DataLength(unsigned short);

    /* Fast-command packets: */
    void init_LDA_FastCommand(unsigned short dif_mask,
			      unsigned char comma,
			      unsigned char data);
    inline bool unpack_LDA_FastCommand(unsigned short /*out*/& cmdw /*0xfa57*/,
				       unsigned short /*out*/& dif_mask,
				       unsigned char /*out*/& comma,
				       unsigned char /*out*/& data) const;

  private:
    struct LDA_pkt *   _pkt;
    unsigned int       _pdu_nbytes; // Related to ODR::_pdu_nbytes
    uint16_t _compute_FC_parity() const; // Host byte order
    PktAccessor_LDA_pkt(PktAccessor_LDA_pkt const&); // Not implemented
  };


2.3 PktAccessor_DIF_pkt_block_transfer

  class PktAccessor_DIF_pkt_block_transfer
    : public virtual PktAccessor_Base
  {
  public:
    PktAccessor_DIF_pkt_block_transfer(void const* sdu,
				       unsigned int buff_nbytes,
				       bool buff_is_garbage = false,
				       bool check_crc_ignore_dcc_nibble=false);
    explicit PktAccessor_DIF_pkt_block_transfer(unsigned int pdu_nbytes);
    virtual void * get_sdu() const;
    virtual unsigned int get_sdu_nbytes() const;
    virtual void * get_pdu() const;
    virtual unsigned int get_pdu_nbytes() const;
    virtual void sync_crc();
    inline unsigned short get_packettype() const;
    inline void set_packettype(unsigned short);
    inline unsigned short get_dcc_nibble() const;
    inline void set_dcc_nibble(unsigned short dcc_nibble);
    inline unsigned short get_pktID() const;
    inline void set_pktID(unsigned short);
    inline unsigned short get_type_modifier() const;
    inline void set_type_modifier(unsigned short);
    inline unsigned short get_data_length() const; // Number of 16b-words
    virtual void set_data_length(unsigned short num_16b_words);

  private:
    struct DIF_pkt_block_transfer * _pkt;
    const unsigned int _buff_nbytes; // Allocated mem size (FIXED)
    unsigned int       _sdu_nbytes;  // Related to _pdu_nbytes
    unsigned int       _pdu_nbytes;  // Related to _sdu_nbytes
  };


3 Compilation


3.1 Flags

There is two pre-compilation flags:

  • CHECK_DIF_CRC: make the libLDA checking the CRC.
    Note: This will slow the DAQ acquisition and may imply data lost.
  • DIF_FIRMWARE: make the libLDA compatible with both ECAL and DHCAL.

/include/packets/all.hh:

/* Check DIF CRC or not (faster) */
#define CHECK_DIF_CRC 0

/* Firmware version we use */
#define DIF_FIRMWARE DHCAL_v20


3.2 Ubuntu

# aptitude install g++ flex bison libboost-dev
$ make
$ make tests


3.3 SLC 5.5

# yum install gcc-c++ boost-devel
  Installing     : libstdc++-devel
  Installing     : kernel-headers 
  Installing     : glibc-headers  
  Installing     : glibc-devel    
  Installing     : gcc            
  Installing     : gcc-c++ 
  Installing     : libicu
  Installing     : boost
  Installing     : boost-devel

$ cd ~/libLDA/packets
$ make
$ make tests


3.4 Gcc flag used

It seems to me that these flags are not needed, as I didn't mention diference with or without.

  • -fno-strict-aliasing:
    Allow the compiler to assume the strictest aliasing rules applicable to the language being compiled. For C (and C++), this activates optimizations based on the type of expressions.
  • -pipe:
    Use pipes rather than temporary files for communication between the various stages of compilation. This fails to work on some systems where the assembler is unable to read from a pipe; but the GNU assembler has no trouble.
  • -fomit-frame-pointer:
    Don't keep the frame pointer in a register for functions that don't need one. This avoids the instructions to save, set up and restore frame pointers; it also makes an extra register available in many functions. It also makes debugging impossible on some machines.
  • -fno-delete-null-pointer-check
    Use global dataflow analysis to identify and eliminate useless checks for null pointers. The compiler assumes that dereferencing a null pointer would have halted the program. If a pointer is checked after it has already been dereferenced, it cannot be null. In some environments, this assumption is not true, and programs can safely dereference null pointers. Use -fno-delete-null-pointer-checks to disable this optimization for programs which depend on that behavior.


4 Unitary tests

Here we can test the CRC computation of packet. This unit test is optimized for copy/past from the tcpdump output (where DIF bytes are inversed).

$ libLDA/src/packets/computeCrc 
1234
crc= 0xd219
5678
crc= 0xe70b
^C

Home Up

This document is also available in PDF and PostScript format.



2015-10-29