Program Listing for File UDPFormat.h

Return to documentation for file (/home/docs/checkouts/readthedocs.org/user_builds/ska-telescope-ska-pst-recv/checkouts/latest/src/ska/pst/recv/formats/UDPFormat.h)

/*
 * Copyright 2022 Square Kilometre Array Observatory
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <cstring>
#include <utility>

#include "ska/pst/common/utils/AsciiHeader.h"
#include "ska/pst/common/utils/Time.h"
#include "ska/pst/common/utils/PacketLayout.h"
#include "ska/pst/common/utils/ValidationContext.h"
#include "ska/pst/recv/formats/PacketStructure.h"

#ifndef SKA_PST_RECV_FORMATS_UDPFormat_h
#define SKA_PST_RECV_FORMATS_UDPFormat_h

#define UDP_FORMAT_MIN_BEAM 1
#define UDP_FORMAT_MAX_BEAM 16
#define UDP_FORMAT_MAX_NBEAM 16
#define UDP_FORMAT_CBFPSR_NDIM 2
#define UDP_FORMAT_CBFPSR_NPOL 2
#define UDP_FORMAT_CBFPSR_WEIGHT_NBIT 16

#define UDP_FORMAT_CBFPSR_LOW_PSS 0
#define UDP_FORMAT_CBFPSR_MID_PSS 1
#define UDP_FORMAT_CBFPSR_LOW_PST 2
#define UDP_FORMAT_CBFPSR_MID_PST 3

namespace ska::pst::recv {

  class UDPFormat : public common::PacketLayout
  {
    public:

      enum PacketState {
        Ok,
        Malformed,
        Misdirected,
        Misordered,
        Ignored,
      };

      typedef struct data_and_weights
      {
        int64_t data;

        int64_t weights;

      } data_and_weights_t;

      UDPFormat();

      ~UDPFormat() = default;

      void validate_configure_beam(const ska::pst::common::AsciiHeader& beam_config, ska::pst::common::ValidationContext *context);
      void validate_configure_scan(const ska::pst::common::AsciiHeader& scan_config, ska::pst::common::ValidationContext *context);

      virtual void configure_beam(const ska::pst::common::AsciiHeader& beam_config);

      void configure_scan(const ska::pst::common::AsciiHeader& scan_config);

      void conclude();

      /* TODO: implement on new story
      void deconfigure_scan();
      void deconfigure_beam();
      */

      void reset();

      uint64_t get_samples_for_bytes(uint64_t nbytes);

      uint64_t get_resolution();

      uint64_t get_weights_resolution();

      void encode_header(char * buf);

      PacketState process_stream_start(char * buffer);

      ska::pst::common::Time get_start_timestamp() { return start_timestamp; };

      virtual PacketState decode_packet(char * buffer, data_and_weights_t * offsets, data_and_weights_t * received);

      virtual void insert_last_packet(char * data, char * weights);

      void clear_scales_buffer(char * buffer, uint64_t bufsz);

      void print_packet_header();

      unsigned get_os_numerator() const { return os_numerator; };

      unsigned get_os_denominator() const { return os_denominator; };

      unsigned get_destination() const { return destination; };

      bool get_increment_psn_every_packet() const { return increment_psn_every_packet; };

      ska::pst::common::AsciiHeader& get_weights_scan_config();

      void set_scan_id(uint64_t scan_id);

      inline bool is_misdirected();

    protected:

      virtual unsigned get_expected_nbit() = 0;

      virtual std::pair<unsigned, unsigned> get_expected_os_factor() = 0;

      inline void check_beam_configured(bool expected);

      inline void check_scan_configured(bool expected);

      inline void check_scan_started(bool expected);

      cbf_psr_packet_t packet{nullptr, nullptr, nullptr};

      unsigned beam_id{0};

      uint64_t scan_id{0};

      unsigned nant{0};

      unsigned nbeam{0};

      unsigned ndim{0};

      unsigned npol{0};

      unsigned nbit{0};

      unsigned os_numerator{0};

      unsigned os_denominator{0};

      unsigned start_channel{0};

      unsigned end_channel{0};

      unsigned nchan{0};

      double tsamp{0};

      double bw{0};

      double freq{0};

      uint64_t bytes_per_second{0};

      bool beam_configured{false};

      bool scan_configured{false};

      bool scan_started{false};

      unsigned data_channel_stride{0};

      unsigned data_psn_stride{0};

      unsigned weights_channel_stride{0};

      unsigned weights_psn_stride{0};

      uint32_t destination{5};

      int64_t start_psn{-1};

      ska::pst::common::Time start_timestamp;

      ska::pst::common::AsciiHeader weights_beam_config;

      ska::pst::common::AsciiHeader weights_scan_config;

      uint64_t attoseconds_per_packet{0};

      bool increment_psn_every_packet{false};

    private:

      unsigned packet_weights_size_remainder{0};

  };

} // ska::pst::recv

#endif