Program Listing for File SickSafetyscanners.h

Return to documentation for file (/tmp/ws/src/sick_safetyscanners_base/include/sick_safetyscanners_base/SickSafetyscanners.h)

// this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-

// -- BEGIN LICENSE BLOCK ----------------------------------------------

// -- END LICENSE BLOCK ------------------------------------------------

//----------------------------------------------------------------------
//----------------------------------------------------------------------


#ifndef SICK_SAFETYSCANNERS_BASE_SICKSAFETYSCANNERS_H
#define SICK_SAFETYSCANNERS_BASE_SICKSAFETYSCANNERS_H

#include <chrono>
#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include <vector>

#include <boost/asio.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/thread.hpp>

#include "sick_safetyscanners_base/Generics.h"
#include "sick_safetyscanners_base/Logging.h"
#include "sick_safetyscanners_base/Types.h"

#include "sick_safetyscanners_base/communication/TCPClient.h"
#include "sick_safetyscanners_base/communication/UDPClient.h"
#include "sick_safetyscanners_base/data_processing/ParseData.h"
#include "sick_safetyscanners_base/data_processing/UDPPacketMerger.h"

#include "sick_safetyscanners_base/cola2/Cola2Session.h"
#include "sick_safetyscanners_base/cola2/Command.h"
#include "sick_safetyscanners_base/datastructure/Datastructure.h"


namespace sick {

using io_service_ptr = std::shared_ptr<boost::asio::io_service>;

using namespace sick::datastructure;

class SickSafetyscannersBase
{
public:
  SickSafetyscannersBase()                              = delete;
  SickSafetyscannersBase(const SickSafetyscannersBase&) = delete;
  SickSafetyscannersBase& operator=(const SickSafetyscannersBase&) = delete;

  SickSafetyscannersBase(sick::types::ip_address_t sensor_ip,
                         sick::types::port_t sensor_tcp_port,
                         CommSettings comm_settings,
                         boost::asio::io_service& io_service);
  SickSafetyscannersBase(sick::types::ip_address_t sensor_ip,
                         sick::types::port_t sensor_tcp_port,
                         CommSettings comm_settings);

  SickSafetyscannersBase(sick::types::ip_address_t sensor_ip,
                         sick::types::port_t sensor_tcp_port,
                         CommSettings comm_settings,
                         boost::asio::ip::address_v4 interface_ip);

  // virtual ~SickSafetyscannersBase();

  void changeSensorSettings(const CommSettings& settings);

  void requestTypeCode(datastructure::TypeCode& type_code);

  void requestApplicationName(datastructure::ApplicationName& application_name);

  void requestSerialNumber(datastructure::SerialNumber& serial_number);

  void requestFirmwareVersion(datastructure::FirmwareVersion& firmware_version);

  void requestOrderNumber(datastructure::OrderNumber& order_number);

  void requestProjectName(datastructure::ProjectName& project_name);

  void requestUserName(datastructure::UserName& user_name);

  void requestConfigMetadata(datastructure::ConfigMetadata& config_metadata);

  void requestStatusOverview(datastructure::StatusOverview& status_overview);

  void requestDeviceStatus(datastructure::DeviceStatus& device_status);

  void requestRequiredUserAction(datastructure::RequiredUserAction& required_user_action);

  void requestLatestTelegram(datastructure::Data& data, int8_t channel_index = 0);

  void findSensor(uint16_t blink_time);

  void requestFieldData(std::vector<FieldData>& field_data);

  void requestDeviceName(datastructure::DeviceName& device_name);

  void requestPersistentConfig(ConfigData& config_data);

  void requestMonitoringCases(std::vector<MonitoringCaseData>& monitoring_cases);

private:
  sick::types::ip_address_t m_sensor_ip;
  sick::types::port_t m_sensor_tcp_port;
  CommSettings m_comm_settings;
  bool m_is_initialized;
  std::unique_ptr<boost::asio::io_service> m_io_service_ptr;

  template <class CommandT, typename... Args>
  void inline createAndExecuteCommand(Args&&... args)
  {
    m_session.open();
    CommandT cmd(std::forward<Args>(args)...);
    m_session.sendCommand(cmd);
    m_session.close();
  }

protected:
  boost::asio::io_service& m_io_service;
  sick::communication::UDPClient m_udp_client;
  sick::cola2::Cola2Session m_session;
  sick::data_processing::UDPPacketMerger m_packet_merger;
};

class AsyncSickSafetyScanner final : public SickSafetyscannersBase
{
public:
  AsyncSickSafetyScanner()                              = delete;
  AsyncSickSafetyScanner(const AsyncSickSafetyScanner&) = delete;
  AsyncSickSafetyScanner& operator=(const AsyncSickSafetyScanner&) = delete;

  AsyncSickSafetyScanner(sick::types::ip_address_t sensor_ip,
                         sick::types::port_t sensor_tcp_port,
                         CommSettings comm_settings,
                         sick::types::ScanDataCb callback);

  AsyncSickSafetyScanner(sick::types::ip_address_t sensor_ip,
                         sick::types::port_t sensor_tcp_port,
                         CommSettings comm_settings,
                         boost::asio::ip::address_v4 interface_ip,
                         sick::types::ScanDataCb callback);

  AsyncSickSafetyScanner(sick::types::ip_address_t sensor_ip,
                         sick::types::port_t sensor_tcp_port,
                         CommSettings comm_settings,
                         sick::types::ScanDataCb callback,
                         boost::asio::io_service& io_service);

  ~AsyncSickSafetyScanner();

  void run();

  void stop();

private:
  void processUDPPacket(const sick::datastructure::PacketBuffer& buffer);

  sick::types::ScanDataCb m_scan_data_cb;
  std::unique_ptr<boost::asio::io_service> m_io_service_ptr;
  boost::thread m_service_thread;
  std::unique_ptr<boost::asio::io_service::work> m_work;
};

class SyncSickSafetyScanner final : public SickSafetyscannersBase
{
public:
  // This adds the base class constructors to the local overload resolution set and threats local
  // initialization like default construction would do.
  using SickSafetyscannersBase::SickSafetyscannersBase;


  // Deleted constructor
  SyncSickSafetyScanner(sick::types::ip_address_t sensor_ip,
                        sick::types::port_t sensor_tcp_port,
                        CommSettings comm_settings,
                        boost::asio::io_service& io_service) = delete;
  bool isDataAvailable() const;

  const Data receive(sick::types::time_duration_t timeout = boost::posix_time::pos_infin);
};
} // namespace sick

#endif // SICK_SAFETYSCANNERS_BASE_SICKSAFETYSCANNERS_H