text:
/*******************************************************************************
Copyright(c) 2015-2020 Parker Hannifin Corp. All rights reserved.

MIT Licensed. See the included LICENSE.txt for a copy of the full MIT License.
*******************************************************************************/
#include "mscl/MicroStrain/Wireless/Packets/BufferedLdcPacket_v2.h"
#include "mscl/MicroStrain/Wireless/Packets/WirelessPacket.h"
#include "mscl/MicroStrain/Wireless/Packets/WirelessPacketCollector.h"
#include "mscl/MicroStrain/Wireless/Packets/WirelessDataPacket.h"
#include "mscl/Exceptions.h"

#include <boost/test/unit_test.hpp>

using namespace mscl;

BOOST_AUTO_TEST_SUITE(BufferedLdc16chPacket_Test)

BOOST_AUTO_TEST_CASE(BufferedLdc16ch_Constructor_4ByteFloat)
{
    Bytes payloadBytes;
    payloadBytes.push_back(0);        //channel mask
    payloadBytes.push_back(1);        //channel mask - 1 channel
    payloadBytes.push_back(112);    //sample rate
    payloadBytes.push_back(0x22);    //data type - 4 byte float
    payloadBytes.push_back(0);        //tick msb
    payloadBytes.push_back(1);        //tick lsb
    payloadBytes.push_back(0);        //channel data b1
    payloadBytes.push_back(0);        //channel data b2
    payloadBytes.push_back(0);        //channel data b3
    payloadBytes.push_back(0);        //channel data b4
    payloadBytes.push_back(1);        //channel data b1
    payloadBytes.push_back(1);        //channel data b2
    payloadBytes.push_back(1);        //channel data b3
    payloadBytes.push_back(1);        //channel data b4

    //build a WirelessPacket
    WirelessPacket packet;
    packet.nodeAddress(345);
    packet.deliveryStopFlags(DeliveryStopFlags::fromInvertedByte(0));
    packet.type(WirelessPacket::packetType_BufferedLDC_16ch);
    packet.nodeRSSI(1);
    packet.baseRSSI(1);
    packet.payload(payloadBytes);    //give the packet the payload bytes we created

    //call the addDataPacket() function to parse the packet as an LDC Packet
    WirelessPacketCollector collector;
    collector.addDataPacket(packet);

    DataSweeps sweeps;
    collector.getDataSweeps(sweeps);
    BOOST_CHECK_EQUAL(sweeps.size(), 2);

    DataSweep sweep = sweeps.at(0);

    //check that the sweep data matches the packet we added
    BOOST_CHECK_EQUAL(sweep.nodeAddress(), 345);
    BOOST_CHECK_EQUAL(sweep.tick(), 1);
    BOOST_CHECK_EQUAL(sweep.data()[0].storedAs(), valueType_float);

    sweep = sweeps.at(1);

    //check that the sweep data matches the packet we added
    BOOST_CHECK_EQUAL(sweep.nodeAddress(), 345);
    BOOST_CHECK_EQUAL(sweep.tick(), 2);    //check that the tick incremented (by MSCL, not by the packet)
    BOOST_CHECK_EQUAL(sweep.data()[0].storedAs(), valueType_float);
}

BOOST_AUTO_TEST_CASE(BufferedLdc16ch_Constructor_2ByteUint)
{
    Bytes payloadBytes;
    payloadBytes.push_back(0);        //channel mask
    payloadBytes.push_back(1);        //channel mask - 1 channel
    payloadBytes.push_back(112);    //sample rate
    payloadBytes.push_back(0x23);    //data type - 2 byte uint
    payloadBytes.push_back(0);        //tick msb
    payloadBytes.push_back(1);        //tick lsb
    payloadBytes.push_back(0);        //channel data b1
    payloadBytes.push_back(254);    //channel data b2

    //build a WirelessPacket
    WirelessPacket packet;
    packet.nodeAddress(345);
    packet.deliveryStopFlags(DeliveryStopFlags::fromInvertedByte(0));
    packet.type(WirelessPacket::packetType_BufferedLDC_16ch);
    packet.nodeRSSI(1);
    packet.baseRSSI(1);
    packet.payload(payloadBytes);    //give the packet the payload bytes we created

    //call the addDataPacket() function to parse the packet as an LDC Packet
    WirelessPacketCollector collector;
    collector.addDataPacket(packet);

    DataSweeps sweeps;
    collector.getDataSweeps(sweeps);
    BOOST_CHECK_EQUAL(sweeps.size(), 1);

    DataSweep sweep = sweeps.at(0);

    //check that the sweep data matches the packet we added
    BOOST_CHECK_EQUAL(sweep.nodeAddress(), 345);
    BOOST_CHECK_EQUAL(sweep.tick(), 1);
    BOOST_CHECK_EQUAL(sweep.data()[0].storedAs(), valueType_uint16);
    BOOST_CHECK_EQUAL(sweep.data()[0].as_uint16(), 254);    //check that the data was shifted (divided by 2)
}

BOOST_AUTO_TEST_CASE(BufferedLdc16ch_Constructor_2ByteUintShifted)
{
    Bytes payloadBytes;
    payloadBytes.push_back(0);        //channel mask
    payloadBytes.push_back(1);        //channel mask - 1 channel
    payloadBytes.push_back(112);    //sample rate
    payloadBytes.push_back(0x21);    //data type - 2 byte uint shifted
    payloadBytes.push_back(0);        //tick msb
    payloadBytes.push_back(1);        //tick lsb
    payloadBytes.push_back(0);        //channel data b1
    payloadBytes.push_back(254);    //channel data b2

    //build a WirelessPacket
    WirelessPacket packet;
    packet.nodeAddress(345);
    packet.deliveryStopFlags(DeliveryStopFlags::fromInvertedByte(0));
    packet.type(WirelessPacket::packetType_BufferedLDC_16ch);
    packet.nodeRSSI(1);
    packet.baseRSSI(1);
    packet.payload(payloadBytes);    //give the packet the payload bytes we created

    //call the addDataPacket() function to parse the packet as an LDC Packet
    WirelessPacketCollector collector;
    collector.addDataPacket(packet);

    DataSweeps sweeps;
    collector.getDataSweeps(sweeps);
    BOOST_CHECK_EQUAL(sweeps.size(), 1);

    DataSweep sweep = sweeps.at(0);

    //check that the sweep data matches the packet we added
    BOOST_CHECK_EQUAL(sweep.nodeAddress(), 345);
    BOOST_CHECK_EQUAL(sweep.tick(), 1);
    BOOST_CHECK_EQUAL(sweep.data()[0].storedAs(), valueType_uint16);
    BOOST_CHECK_EQUAL(sweep.data()[0].as_uint16(), 127);    //check that the data was shifted (divided by 2)
}

BOOST_AUTO_TEST_CASE(BufferedLdc16ch_Constructor_NoChannelMask)
{
    Bytes payloadBytes;
    payloadBytes.push_back(0);        //channel mask
    payloadBytes.push_back(0);        //channel mask - NO CHANNELS
    payloadBytes.push_back(112);    //sample rate
    payloadBytes.push_back(0x23);    //data type - 2 byte uint
    payloadBytes.push_back(0);        //tick msb
    payloadBytes.push_back(1);        //tick lsb

    //build a WirelessPacket
    WirelessPacket packet;
    packet.nodeAddress(345);
    packet.deliveryStopFlags(DeliveryStopFlags::fromInvertedByte(0));
    packet.type(WirelessPacket::packetType_BufferedLDC_16ch);
    packet.nodeRSSI(1);
    packet.baseRSSI(1);
    packet.payload(payloadBytes);    //give the packet the payload bytes we created

    //call the addDataPacket() function to parse the packet as an LDC Packet
    WirelessPacketCollector collector;
    collector.addDataPacket(packet);

    DataSweeps sweeps;
    collector.getDataSweeps(sweeps);
    BOOST_CHECK_EQUAL(sweeps.size(), 1);

    DataSweep sweep = sweeps.at(0);

    //check that the sweep data matches the packet we added
    BOOST_CHECK_EQUAL(sweep.nodeAddress(), 345);
    BOOST_CHECK_EQUAL(sweep.tick(), 1);
    BOOST_CHECK_EQUAL(sweep.data().size(), 0);
}

BOOST_AUTO_TEST_CASE(BufferedLdc16ch_IntegrityCheck_Good)
{
    Bytes payloadBytes;
    payloadBytes.push_back(0);
    payloadBytes.push_back(1);        //channel mask - 1 channel
    payloadBytes.push_back(112);    //sample rate
    payloadBytes.push_back(0x23);    //data type - 2 byte uint32 shifted
    payloadBytes.push_back(0);        //tick msb
    payloadBytes.push_back(1);        //tick lsb
    payloadBytes.push_back(0);        //channel data b1
    payloadBytes.push_back(0);        //channel data b2

    //build a WirelessPacket
    WirelessPacket packet;
    packet.nodeAddress(345);
    packet.deliveryStopFlags(DeliveryStopFlags::fromInvertedByte(0));
    packet.type(WirelessPacket::packetType_BufferedLDC_16ch);
    packet.nodeRSSI(1);
    packet.baseRSSI(1);
    packet.payload(payloadBytes);    //give the packet the payload bytes we created

    //check that the integrity check failed
    BOOST_CHECK_EQUAL(BufferedLdcPacket_v2::integrityCheck(packet), true);
}

BOOST_AUTO_TEST_CASE(BufferedLdc16ch_IntegrityCheck_SmallPayload)
{
    Bytes payloadBytes;
    payloadBytes.push_back(0);        //app id
    payloadBytes.push_back(1);        //channel mask - 1 channel
    payloadBytes.push_back(112);    //sample rate

    //build a WirelessPacket
    WirelessPacket packet;
    packet.nodeAddress(345);
    packet.deliveryStopFlags(DeliveryStopFlags::fromInvertedByte(0));
    packet.type(WirelessPacket::packetType_BufferedLDC_16ch);
    packet.nodeRSSI(1);
    packet.baseRSSI(1);
    packet.payload(payloadBytes);    //give the packet the payload bytes we created

    //check that the integrity check failed
    BOOST_CHECK_EQUAL(BufferedLdcPacket_v2::integrityCheck(packet), false);
}

BOOST_AUTO_TEST_CASE(BufferedLdc16ch_IntegrityCheck_BadAppID)
{
    Bytes payloadBytes;
    payloadBytes.push_back(0);
    payloadBytes.push_back(1);        //channel mask - 1 channel
    payloadBytes.push_back(112);    //sample rate
    payloadBytes.push_back(0xA3);    //BAD app id / data type - 2 byte uint32 shifted
    payloadBytes.push_back(0);        //tick msb
    payloadBytes.push_back(1);        //tick lsb
    payloadBytes.push_back(0);        //channel data b1
    payloadBytes.push_back(0);        //channel data b2

    //build a WirelessPacket
    WirelessPacket packet;
    packet.nodeAddress(345);
    packet.deliveryStopFlags(DeliveryStopFlags::fromInvertedByte(0));
    packet.type(WirelessPacket::packetType_BufferedLDC_16ch);
    packet.nodeRSSI(1);
    packet.baseRSSI(1);
    packet.payload(payloadBytes);    //give the packet the payload bytes we created

    //check that the integrity check failed
    BOOST_CHECK_EQUAL(BufferedLdcPacket_v2::integrityCheck(packet), false);
}

BOOST_AUTO_TEST_CASE(BufferedLdc16ch_IntegrityCheck_BadStopFlags)
{
    Bytes payloadBytes;
    payloadBytes.push_back(0);        //app id
    payloadBytes.push_back(1);        //channel mask - 1 channel
    payloadBytes.push_back(112);    //sample rate
    payloadBytes.push_back(0x23);    //data type - 2 byte uint32 shifted
    payloadBytes.push_back(0);        //tick msb
    payloadBytes.push_back(1);        //tick lsb
    payloadBytes.push_back(0);        //channel data b1
    payloadBytes.push_back(0);        //channel data b2

    //build a WirelessPacket
    WirelessPacket packet;
    packet.nodeAddress(345);
    packet.deliveryStopFlags(DeliveryStopFlags::fromInvertedByte(15));    //INVALID DELIVERY STOP FLAGS
    packet.type(WirelessPacket::packetType_BufferedLDC_16ch);
    packet.nodeRSSI(1);
    packet.baseRSSI(1);
    packet.payload(payloadBytes);    //give the packet the payload bytes we created

    //check that the integrity check failed
    BOOST_CHECK_EQUAL(BufferedLdcPacket_v2::integrityCheck(packet), false);
}

BOOST_AUTO_TEST_CASE(BufferedLdc16ch_IntegrityCheck_BadDataType)
{
    Bytes payloadBytes;
    payloadBytes.push_back(0);
    payloadBytes.push_back(1);        //channel mask - 1 channel
    payloadBytes.push_back(112);    //sample rate
    payloadBytes.push_back(0x2B);    //(INVALID DATA TYPE)
    payloadBytes.push_back(0);        //tick msb
    payloadBytes.push_back(1);        //tick lsb
    payloadBytes.push_back(0);        //channel data b1
    payloadBytes.push_back(0);        //channel data b2

    //build a WirelessPacket
    WirelessPacket packet;
    packet.nodeAddress(345);
    packet.deliveryStopFlags(DeliveryStopFlags::fromInvertedByte(0));
    packet.type(WirelessPacket::packetType_BufferedLDC_16ch);
    packet.nodeRSSI(1);
    packet.baseRSSI(1);
    packet.payload(payloadBytes);    //give the packet the payload bytes we created

    //check that the integrity check failed
    BOOST_CHECK_EQUAL(BufferedLdcPacket_v2::integrityCheck(packet), false);
}

BOOST_AUTO_TEST_CASE(BufferedLdc16ch_IntegrityCheck_BadPacketType)
{
    Bytes payloadBytes;
    payloadBytes.push_back(0);
    payloadBytes.push_back(1);        //channel mask - 1 channel
    payloadBytes.push_back(112);    //sample rate
    payloadBytes.push_back(0x23);    //data type - 2 byte uint32 shifted
    payloadBytes.push_back(0);        //tick msb
    payloadBytes.push_back(1);        //tick lsb
    payloadBytes.push_back(0);        //channel data b1
    payloadBytes.push_back(0);        //channel data b2

    //build a WirelessPacket
    WirelessPacket packet;
    packet.nodeAddress(345);
    packet.deliveryStopFlags(DeliveryStopFlags::fromInvertedByte(0));
    packet.type(WirelessPacket::packetType_BufferedLDC); //INVALID packet type
    packet.nodeRSSI(1);
    packet.baseRSSI(1);
    packet.payload(payloadBytes);    //give the packet the payload bytes we created

    //check that the integrity check failed
    BOOST_CHECK_EQUAL(BufferedLdcPacket_v2::integrityCheck(packet), false);
}

BOOST_AUTO_TEST_CASE(BufferedLdc16ch_IntegrityCheck_NoChannelsActive)
{
    Bytes payloadBytes;
    payloadBytes.push_back(0);
    payloadBytes.push_back(0);        //channel mask (NO CHANNELS)
    payloadBytes.push_back(112);    //sample rate
    payloadBytes.push_back(0x23);    //data type - 2 byte uint32 shifted
    payloadBytes.push_back(0);        //tick msb
    payloadBytes.push_back(1);        //tick lsb

    //build a WirelessPacket
    WirelessPacket packet;
    packet.nodeAddress(345);
    packet.deliveryStopFlags(DeliveryStopFlags::fromInvertedByte(0));
    packet.type(WirelessPacket::packetType_BufferedLDC_16ch);
    packet.nodeRSSI(1);
    packet.baseRSSI(1);
    packet.payload(payloadBytes);    //give the packet the payload bytes we created

    //check that the integrity check failed
    BOOST_CHECK_EQUAL(BufferedLdcPacket_v2::integrityCheck(packet), false);
}

BOOST_AUTO_TEST_CASE(BufferedLdc16ch_IntegrityCheck_InvalidPayloadBytes)
{
    Bytes payloadBytes;
    payloadBytes.push_back(0);
    payloadBytes.push_back(3);        //channel mask - 2 channels but not enough data for 2 channels
    payloadBytes.push_back(112);    //sample rate
    payloadBytes.push_back(0x23);    //data type - 2 byte uint32 shifted
    payloadBytes.push_back(0);        //tick msb
    payloadBytes.push_back(1);        //tick lsb
    payloadBytes.push_back(0);        //channel data b1
    payloadBytes.push_back(0);        //channel data b2

    //build a WirelessPacket
    WirelessPacket packet;
    packet.nodeAddress(345);
    packet.deliveryStopFlags(DeliveryStopFlags::fromInvertedByte(0));
    packet.type(WirelessPacket::packetType_BufferedLDC_16ch);
    packet.nodeRSSI(1);
    packet.baseRSSI(1);
    packet.payload(payloadBytes);    //give the packet the payload bytes we created

    //check that the integrity check failed
    BOOST_CHECK_EQUAL(BufferedLdcPacket_v2::integrityCheck(packet), false);
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: contagon/MSCL

max_stars_repo_licenses: BSL-1.0 OpenSSL MIT

max_issues_repo_name: contagon/MSCL

max_issues_repo_licenses: BSL-1.0 OpenSSL MIT

max_forks_repo_name: contagon/MSCL

max_forks_repo_licenses: BSL-1.0 OpenSSL MIT


text:
#include "net/ws/client/ClientSession.hpp" // IWYU pragma: associated
#include "net/ws/client/ClientSessionManager.hpp"
#include "algo/DispatchQueue.hpp"
#include "log/Logger.hpp"
#include "net/NetworkManagerBase.hpp"
#include "net/wrtc/WRTCServer.hpp"
#include "net/SessionPair.hpp"
#include <algorithm>
#include <boost/asio.hpp>
#include <boost/assert.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/system/error_code.hpp>
#include <chrono>
#include <cinttypes>
#include <cstdint>
#include <cstdio>
#include <enum.h>
#include <functional>
#include <iostream>
#include <map>
#include <new>
#include <rapidjson/document.h>
#include <rapidjson/error/error.h>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <utility>
#include <webrtc/rtc_base/bind.h>
#include <webrtc/rtc_base/checks.h>

namespace gloer {
namespace net {
namespace ws {

// @note ::tcp::socket socket represents the local end of a connection between two peers
// NOTE: Following the std::move, the moved-from object is in the same state
// as if constructed using the basic_stream_socket(io_service&) constructor.
// boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/basic_stream_socket/basic_stream_socket/overload5.html
ClientSession::ClientSession(boost::asio::io_context& ioc,
    ::boost::asio::ssl::context& ctx,
    net::WSClientNetworkManager* nm,
    const ws::SessionGUID& id)
    : SessionPair(id)
      , ctx_(ctx)
      , ws_(boost::asio::make_strand(ioc))
      , nm_(nm)
      , isSendBusy_(false)
      , resolver_(boost::asio::make_strand(ioc))
{

  // TODO: stopped() == false
  // RTC_DCHECK(socket.get_executor().context().stopped() == false);

  RTC_DCHECK(ws_.is_open() == false);

  RTC_DCHECK(nm_ != nullptr);

  RTC_DCHECK_GT(static_cast<std::string>(id).length(), 0);

  RTC_DCHECK_LT(static_cast<std::string>(id).length(), MAX_ID_LEN);
}

ClientSession::~ClientSession() {
  // LOG(INFO) << "~ClientSession";
  const ws::SessionGUID wsConnId = getId(); // remember id before session deletion

  close();

  if (!onCloseCallback_) {
    LOG(WARNING) << "WRTCSession::onDataChannelMessage: Not set onMessageCallback_!";
    return;
  }

  onCloseCallback_(wsConnId);

  if (nm_ && nm_->getRunner().get()) {
    nm_->sessionManager().unregisterSession(wsConnId);
  }
}

void ClientSession::on_session_fail(beast::error_code ec, char const* what) {
  // Don't report these
  if (ec == ::boost::asio::error::operation_aborted
      || ec == ::websocket::error::closed) {
    return;
  }

  if (ec == beast::error::timeout) {
      LOG(INFO) << "|idle timeout when read"; //idle_timeout
      isExpired_ = true;
  }

  close();

  LOG(WARNING) << "ClientSession: " << what << " : " << ec.message();
  // const std::string wsGuid = boost::lexical_cast<std::string>(getId());
  ws::SessionGUID copyId = getId();
  nm_->sessionManager().unregisterSession(copyId);
}

void ClientSession::connectAsClient(const std::string& host, const std::string& port) {
  host_ = host;

  // Look up the domain name
  resolver_.async_resolve(
      host.c_str(),
      port.c_str(),
      beast::bind_front_handler(
          &ClientSession::onClientResolve,
          shared_from_this()));

  // Look up the domain name
  /*resolver_.async_resolve(
      host, port,
      boost::asio::bind_executor(ws_.get_executor(), std::bind(&ClientSession::onClientResolve, shared_from_this(),
                                                    std::placeholders::_1, std::placeholders::_2)));
  */
}

void ClientSession::onClientResolve(beast::error_code ec, tcp::resolver::results_type results) {
  if (ec)
    return on_session_fail(ec, "resolve");

  RTC_DCHECK(created_cb_);
  created_cb_("resolve");

#if 0
  // Make the connection on the IP address we get from a lookup
  ::boost::asio::async_connect(
      ws_.next_layer(), results.begin(), results.end(),
      /*boost::asio::bind_executor(ws_.get_executor(), std::bind(&ClientSession::onClientConnect, shared_from_this(),
                                                    std::placeholders::_1)));*/
      beast::bind_front_handler(
          &ClientSession::onClientConnect,
          shared_from_this()));
#endif // 0

  // Set the timeout for the operation
  beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(5));

  // Make the connection on the IP address we get from a lookup
  beast::get_lowest_layer(ws_).async_connect(
      results,
      beast::bind_front_handler(
          &ClientSession::onClientConnect,
          shared_from_this()));
}

void ClientSession::onClientConnect(beast::error_code ec, tcp::resolver::results_type::endpoint_type) {
  if (ec)
    return on_session_fail(ec, "connect");

  RTC_DCHECK(created_cb_);
  created_cb_("connect");

  // Turn off the timeout on the tcp_stream, because
  // the websocket stream has its own timeout system.
  beast::get_lowest_layer(ws_).expires_never();

  // TODO: SSL as in
  // github.com/vinniefalco/beast/blob/master/example/server-framework/main.cpp
  // Set options before performing the handshake.
  /**
   * Determines if outgoing message payloads are broken up into
   * multiple pieces.
   **/
  // ws_.auto_fragment(false);
  /**
   * Permessage-deflate allows messages to be compressed.
   **/
  ::websocket::permessage_deflate pmd;
  pmd.client_enable = true;
  pmd.server_enable = true;
  pmd.compLevel = 3; /// Deflate compression level 0..9
  pmd.memLevel = 4;  // Deflate memory level, 1..9
  ws_.set_option(pmd);
  // ws.set_option(write_buffer_size{8192});
  /**
   * Set the maximum incoming message size option.
   * Message frame fields indicating a size that would bring the total message
   * size over this limit will cause a protocol failure.
   **/
  ws_.read_message_max(64 * 1024 * 1024);
  LOG(INFO) << "created ClientSession #" << static_cast<std::string>(id_);

  // Set a decorator to change the Server of the handshake
  ws_.set_option(websocket::stream_base::decorator(
      [](websocket::response_type& res)
      {
          res.set(http::field::user_agent,
              std::string(BOOST_BEAST_VERSION_STRING) +
                  " websocket-client-async");
      }));

  // Turn off the timeout on the tcp_stream, because
  // the websocket stream has its own timeout system.
  // beast::get_lowest_layer(ws_).expires_never();

  ///\see https://github.com/boostorg/beast/commit/f21358186ecad9744ed6c72618d4a4cfc36be5fb#diff-68c7d3776da215dd6d1b335448c77f3bR116
  ws_.set_option(websocket::stream_base::timeout{
                // Time limit on handshake, accept, and close operations
                std::chrono::seconds(30), // handshake_timeout
                // The time limit after which a connection is considered idle.
                std::chrono::seconds(300), // idle_timeout
                /*
                  If the idle interval is set, this setting affects the
                  behavior of the stream when no data is received for the
                  timeout interval as follows:
                  @li When `keep_alive_pings` is `true`, an idle ping will be
                  sent automatically. If another timeout interval elapses
                  with no received data then the connection will be closed.
                  An outstanding read operation must be pending, which will
                  complete immediately the error @ref beast::error::timeout.
                  @li When `keep_alive_pings` is `false`, the connection will be closed.
                  An outstanding read operation must be pending, which will
                  complete immediately the error @ref beast::error::timeout.
                */
                /// \note Prefer true on server and false on client.
                false} // keep_alive_pings.
  );

  // Perform the websocket handshake
  //auto host = beast::get_lowest_layer(ws_).local_endpoint().address().to_string();
  /*ws_.async_handshake(
      host, host,
      boost::asio::bind_executor(ws_.get_executor(), std::bind(&ClientSession::onClientHandshake,
                                                    shared_from_this(), std::placeholders::_1)));
  */
  ws_.async_handshake(
    host_, "/",
    //boost::asio::ssl::stream_base::client,
    beast::bind_front_handler(
        &ClientSession::onClientHandshake,
        shared_from_this()));
}

void ClientSession::onClientHandshake(beast::error_code ec) {
  if (ec)
    return on_session_fail(ec, "handshake");

  RTC_DCHECK(created_cb_);
  created_cb_("handshake");
}

void ClientSession::start_read() {
  LOG(INFO) << "WS session run as client";

  // Set the control callback. This will be called
  // on every incoming ping, pong, and close frame.
  /*ws_.control_callback(
      boost::asio::bind_executor(ws_.get_executor(),
        std::bind(&ClientSession::on_control_callback, this,
          std::placeholders::_1, std::placeholders::_2)));

  // Run the timer. The timer is operated
  // continuously, this simplifies the code.
  on_timer({});

  // Set the timer
  timer_.expires_after(std::chrono::seconds(WS_PING_FREQUENCY_SEC));*/

  setFullyCreated(true); // TODO

  // Read a message
  do_read();
}

bool ClientSession::waitForConnect(std::size_t maxWait_ms) const {
  auto end_time = std::chrono::high_resolution_clock::now() + std::chrono::milliseconds(maxWait_ms);
  auto current_time = std::chrono::high_resolution_clock::now();
  while (!isOpen() && (current_time < end_time)) {
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    current_time = std::chrono::high_resolution_clock::now();
  }
  return isOpen();
}

size_t ClientSession::MAX_IN_MSG_SIZE_BYTE = 16 * 1024;
size_t ClientSession::MAX_OUT_MSG_SIZE_BYTE = 16 * 1024;

#if 0
void ClientSession::on_control_callback(::websocket::frame_type kind, beast::string_view payload) {
  // LOG(INFO) << "WS on_control_callback";
  boost::ignore_unused(kind, payload);

  // Note that there is activity
  onRemoteActivity();
}

// Called to indicate activity from the remote peer
void ClientSession::onRemoteActivity() {
  // Note that the connection is alive
  pingState_ = PING_STATE::ALIVE;

  // Set the timer
  timer_.expires_after(std::chrono::seconds(WS_PING_FREQUENCY_SEC));
}

// Called after a ping is sent.
void ClientSession::on_ping(beast::error_code ec) {
  // Happens when the timer closes the socket
  if (ec == ::boost::asio::error::operation_aborted) {
    LOG(WARNING) << "ClientSession on_ping ec:" << ec.message();
    return;
  }

  if (ec) {
    LOG(WARNING) << "ClientSession on_ping ec:" << ec.message();
    return on_session_fail(ec, "ping");
  }

  // Note that the ping was sent.
  if (pingState_ == PING_STATE::SENDING) {
    pingState_ = PING_STATE::SENT;
  } else {
    // ping_state_ could have been set to 0
    // if an incoming control frame was received
    // at exactly the same time we sent a ping.
    BOOST_ASSERT(pingState_ == PING_STATE::ALIVE);
  }
}

// Called when the timer expires.
void ClientSession::on_timer(beast::error_code ec) {
  // LOG(INFO) << "ClientSession::on_timer";

  if (ec && ec != ::boost::asio::error::operation_aborted) {
    LOG(WARNING) << "ClientSession on_timer ec:" << ec.message();
    return on_session_fail(ec, "timer");
  }

  // See if the timer really expired since the deadline may have moved.
  if (timer_.expiry() <= std::chrono::steady_clock::now()) {
    // If this is the first time the timer expired,
    // send a ping to see if the other end is there.
    if (isOpen() && pingState_ == PING_STATE::ALIVE) {
      // Note that we are sending a ping
      pingState_ = PING_STATE::SENDING;

      // Set the timer
      timer_.expires_after(std::chrono::seconds(WS_PING_FREQUENCY_SEC));

      // Now send the ping
      ws_.async_ping(
          {}, ::boost::asio::bind_executor(ws_.get_executor(), std::bind(&ClientSession::on_ping, shared_from_this(),
                                                      std::placeholders::_1)));
    } else {
      // The timer expired while trying to handshake,
      // or we sent a ping and it never completed or
      // we never got back a control frame, so close.

      // Closing the socket cancels all outstanding operations. They
      // will complete with ::boost::asio::error::operation_aborted

      // LOG(INFO) << "Closing expired WS session";

      // LOG(INFO) << "on_timer: total ws sessions: " << nm_->sessionManager().getSessionsCount();
      // ws_.next_layer().shutdown(::tcp::socket::shutdown_both, ec);
      // ws_.next_layer().close(ec);

      close();

      ws::SessionGUID copyId = getId();
      nm_->sessionManager().unregisterSession(copyId);
      isExpired_ = true;
      return;
    }
  }

  // Wait on the timer
  timer_.async_wait(::boost::asio::bind_executor(
      ws_.get_executor(), std::bind(&ClientSession::on_timer, shared_from_this(), std::placeholders::_1)));
}
#endif // 0

void ClientSession::close() {
  if (!ws_.is_open()) {
    // LOG(WARNING) << "Close error: Tried to close already closed webSocket, ignoring...";
    return;
  }
  /*boost::system::error_code errorCode;
  ws_.close(boost::beast::websocket::close_reason(boost::beast::websocket::close_code::normal),
            errorCode);
  if (errorCode) {
    LOG(WARNING) << "ClientSession: Close error: " << errorCode.message();
  }*/

  // Close the WebSocket connection
  ws_.async_close(websocket::close_code::normal,
      beast::bind_front_handler(
          &ClientSession::on_close,
          shared_from_this()));
}

void ClientSession::on_close(beast::error_code ec)
{
  if(ec)
      return on_session_fail(ec, "close");

  // If we get here then the connection is closed gracefully

  // The make_printable() function helps print a ConstBufferSequence
  // LOG(INFO) << beast::make_printable(buffer_.data());
}

void ClientSession::do_read() {
  // LOG(INFO) << "WS session do_read";

  // Set the timer
  // timer_.expires_after(std::chrono::seconds(WS_PING_FREQUENCY_SEC));

  /*if (!isOpen()) {
    LOG(WARNING) << "!ws_.is_open()";
    return;
  }*/

  // Read a message into our buffer
  /*ws_.async_read(
      recievedBuffer_,
      ::boost::asio::bind_executor(ws_.get_executor(), std::bind(&ClientSession::on_read, shared_from_this(),
                                              std::placeholders::_1, std::placeholders::_2)));
  */

  // Read a message into our buffer
  ws_.async_read(
      recievedBuffer_,
      beast::bind_front_handler(
          &ClientSession::on_read,
          shared_from_this()));
}

void ClientSession::on_read(beast::error_code ec, std::size_t bytes_transferred) {
  // LOG(INFO) << "WS session on_read";

  boost::ignore_unused(bytes_transferred);

  // Happens when the timer closes the socket
  if (ec == ::boost::asio::error::operation_aborted) {
    LOG(WARNING) << "ClientSession on_read: ::boost::asio::error::operation_aborted";
    return;
  }

  // This indicates that the session was closed
  if (ec == ::websocket::error::closed) {
    LOG(WARNING) << "ClientSession on_read ec:" << ec.message();
    return; // on_session_fail(ec, "write");
  }

  if (ec)
    on_session_fail(ec, "read");

  // Note that there is activity
  // onRemoteActivity();

  // LOG(INFO) << "buffer: " <<
  // beast::buffers_to_string(recieved_buffer_.data());
  // send(beast::buffers_to_string(recieved_buffer_.data())); // ??????

  if (!recievedBuffer_.size()) {
    // may be empty if connection reset by peer
    // LOG(WARNING) << "ClientSession::on_read: empty messageBuffer";
    return;
  }

  if (recievedBuffer_.size() > MAX_IN_MSG_SIZE_BYTE) {
    LOG(WARNING) << "ClientSession::on_read: Too big messageBuffer of size " << recievedBuffer_.size();
    return;
  }

  // add incoming message callback into queue
  // TODO: use protobuf
  /*auto sharedBuffer =
      std::make_shared<std::string>(beast::buffers_to_string(recievedBuffer_.data()));*/
  const std::string data = beast::buffers_to_string(recievedBuffer_.data());

  // handleIncomingJSON(sharedBuffer);

  // handleIncomingJSON(data);
  if (!onMessageCallback_) {
    LOG(WARNING) << "ClientSession::on_read: Not set onMessageCallback_!";
    return;
  }

  LOG(WARNING) << "ClientSession on_read: " << data;

  onMessageCallback_(getId(), data);

  // Clear the buffer
  recievedBuffer_.consume(recievedBuffer_.size());

  // Do another read
  do_read();
}

/*std::shared_ptr<algo::DispatchQueue> ClientSession::getWRTCQueue() const {
  return getRunner()->getWRTCQueue();
}*/

//#if ENABLE_WRTC
void ClientSession::pairToWRTCSession(std::shared_ptr<wrtc::WRTCSession> WRTCSession) {
  rtc::CritScope lock(&wrtcSessMutex_);
  LOG(INFO) << "pairToWRTCSessionn...";
  // rtc::CritScope lock(&wrtcSessMutex_);
  if (!WRTCSession) {
    LOG(WARNING) << "pairToWRTCSession: Invalid WRTCSession";
    return;
  }
  wrtcSession_ = WRTCSession;
}

bool ClientSession::hasPairedWRTCSession() {
  rtc::CritScope lock(&wrtcSessMutex_);
  return wrtcSession_.lock().get() != nullptr;
}

std::weak_ptr<wrtc::WRTCSession> ClientSession::getWRTCSession() const {
  rtc::CritScope lock(&wrtcSessMutex_);
  if (!wrtcSession_.lock()) {
    LOG(WARNING) << "getWRTCSession: Invalid wrtcSession_";
    return wrtcSession_;
  }
  return wrtcSession_;
}
//#endif // ENABLE_WRTC

bool ClientSession::isOpen() const { return ws_.is_open(); }

void ClientSession::on_write(beast::error_code ec, std::size_t bytes_transferred) {
  // LOG(INFO) << "WS session on_write";
  boost::ignore_unused(bytes_transferred);

  // Happens when the timer closes the socket
  if (ec == ::boost::asio::error::operation_aborted) {
    LOG(WARNING) << "ClientSession on_write: ::boost::asio::error::operation_aborted: " << ec.message();
    return;
  }

  if (ec) {
    LOG(WARNING) << "ClientSession on_write: ec";
    return on_session_fail(ec, "write");
  }

  if (!isOpen()) {
    LOG(WARNING) << "!ws_.is_open()";
    return;
  }

  if (!sendQueue_.isEmpty()) {
    // Remove the already written string from the queue
    // sendQueue_.erase(sendQueue_.begin());
    sendQueue_.popFront();
  }

  if (!sendQueue_.isEmpty()) {

    if (!sendQueue_.frontPtr() || !sendQueue_.frontPtr()->get()) {
      LOG(WARNING) << "ws: invalid sendQueue_.frontPtr()";
      return;
    }

    // std::shared_ptr<const std::string> dp = *(sendQueue_.frontPtr());
    std::shared_ptr<const std::string> dp;
    sendQueue_.read(dp);

    if (!dp || !dp.get()) {
      LOG(WARNING) << "invalid sendQueue_.front()) ";
      return;
    }

    // LOG(INFO) << "write buffer: " << *dp;

    // This controls whether or not outgoing message opcodes are set to binary or text.
    ws_.text(true); // TODO: ws().text(derived().ws().got_text());
    ws_.async_write(
        ::boost::asio::buffer(*dp),
        /*::boost::asio::bind_executor(strand_, std::bind(&ClientSession::on_write, shared_from_this(),
                                                std::placeholders::_1, std::placeholders::_2)));
        */
        beast::bind_front_handler(
                        &ClientSession::on_write,
                        shared_from_this()));
  } else {
    LOG(INFO) << "write send_queue_.empty()";
    isSendBusy_ = false;
  }
}

/**
 * @brief starts async writing to client
 *
 * @param message message passed to client
 */
void ClientSession::send(const std::string& ss) {
  // LOG(WARNING) << "ClientSession::send:" << ss;
  std::shared_ptr<const std::string> ssShared =
      std::make_shared<const std::string>(ss); // TODO: std::move

  if (!ssShared || !ssShared.get() || ssShared->empty()) {
    LOG(WARNING) << "ClientSession::send: empty messageBuffer";
    return;
  }

  if (ssShared->size() > MAX_OUT_MSG_SIZE_BYTE) {
    LOG(WARNING) << "ClientSession::send: Too big messageBuffer of size " << ssShared->size();
    return;
  }

  // TODO: use folly fixed size queue
  if (!sendQueue_.isFull()) {
    sendQueue_.write(ssShared);
  } else {
    // Too many messages in queue
    LOG(WARNING) << "send_queue_ isFull!";
    return;
  }

  // Are we already writing?
  /*if (sendQueue_.size() > 1) {
    LOG(INFO) << "send_queue_.size() > 1";
    return;
  }*/

  if (!isOpen()) {
    LOG(WARNING) << "!ws_.is_open()";
    return;
  }

  if (!isSendBusy_ && !sendQueue_.isEmpty()) {
    isSendBusy_ = true;

    if (!sendQueue_.frontPtr() || !sendQueue_.frontPtr()->get()) {
      LOG(WARNING) << "ws: invalid sendQueue_.frontPtr()";
      return;
    }

    // std::shared_ptr<const std::string> dp = *(sendQueue_.frontPtr());
    std::shared_ptr<const std::string> dp;
    sendQueue_.read(dp);

    if (!dp || !dp.get()) {
      LOG(WARNING) << "invalid sendQueue_.front()) ";
      return;
    }

    // We are not currently writing, so send this immediately
    {
      // This controls whether or not outgoing message opcodes are set to binary or text.
      ws_.text(true); // TODO: ws().text(derived().ws().got_text());
      ws_.async_write(
          ::boost::asio::buffer(*dp),
          /*::boost::asio::bind_executor(strand_, std::bind(&ClientSession::on_write, shared_from_this(),
                                                  std::placeholders::_1, std::placeholders::_2)));
          */
          beast::bind_front_handler(
                          &ClientSession::on_write,
                          shared_from_this()));
    }
  }
}

bool ClientSession::isExpired() const { return isExpired_; }

} // namespace ws
} // namespace net
} // namespace gloer

ext: cpp

max_stars_repo_name: lineCode/webrtc-datachannels

max_issues_repo_name: lineCode/webrtc-datachannels

max_forks_repo_name: lineCode/webrtc-datachannels


text:
/*
 * Copyright 2013 Matthew Harvey
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef GUARD_transaction_type_ctrl_hpp_8775560031074826
#define GUARD_transaction_type_ctrl_hpp_8775560031074826

#include "transaction_type.hpp"
#include "gui/combo_box.hpp"
#include <boost/optional.hpp>
#include <wx/event.h>
#include <wx/gdicmn.h>
#include <wx/window.h>
#include <wx/windowid.h>
#include <vector>

namespace dcm
{

// Begin forward declarations

class DcmDatabaseConnection;

// End forward declarations

namespace gui
{

/**
 * Widget to enable the user to select a TransactionType.
 *
 * Note, there is no way to insert additional TransactionTypes
 * into a TransactionTypeCtrl after it has been constructed.
 */
class TransactionTypeCtrl: public ComboBox
{
public:

    /**
     * \e p_parent must be a TransactionCtrl*. Make sure that the vector
     * passed to p_transaction_types does not contain any TransactionTypes
     * that are not in available_transaction_types(p_database_connection) -
     * this is the caller's responsibility.
     *
     * \e p_transaction_types should not be empty.
     */
    TransactionTypeCtrl
    (   wxWindow* p_parent,
        wxWindowID p_id,
        wxSize const& p_size,
        DcmDatabaseConnection& p_database_connection,
        std::vector<TransactionType> const& p_transaction_types
    );

    TransactionTypeCtrl(TransactionTypeCtrl const&) = delete;
    TransactionTypeCtrl(TransactionTypeCtrl&&) = delete;
    TransactionTypeCtrl& operator=(TransactionTypeCtrl const&) = delete;
    TransactionTypeCtrl& operator=(TransactionTypeCtrl&&) = delete;
    virtual ~TransactionTypeCtrl();

    /**
     * @returns the currently selected TransactionType, wrapped in a
     * boost::optional. This may be an uninitialized optional in case
     * we are in Windows and the underlying ComboBox is in a
     * transitional state.
     */
    boost::optional<TransactionType> transaction_type() const;

    /**
     * Sets the TransactionType displayed in the control.
     */
    void set_transaction_type(TransactionType p_transaction_type);

private:
    void on_change(wxCommandEvent& event);
    std::vector<TransactionType> m_transaction_types;
    DcmDatabaseConnection& m_database_connection;
    DECLARE_EVENT_TABLE()

};  // class TransactionTypeCtrl

}  // namespace gui
}  // namespace dcm

#endif  // GUARD_transaction_type_ctrl_hpp_8775560031074826

ext: hpp

max_stars_repo_name: skybaboon/dailycashmanager

max_issues_repo_name: skybaboon/dailycashmanager

max_forks_repo_name: skybaboon/dailycashmanager


text: #include <boost/fiber/cuda/waitfor.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
// Spear: Statistical Platform for Elucidating moleculAr Reactivity
// Copyright (C) Purdue University -- BSD license

#ifndef SPEAR_TYPEDEFS_HPP
#define SPEAR_TYPEDEFS_HPP

#include <boost/graph/undirected_graph.hpp>
#include "spear/Constants.hpp"

namespace Spear {

// Note: If more atom/bond properties are need other than atomic number and bond order,
// change the lines below:
using VertexProperty = boost::property<boost::vertex_name_t, Element::Symbol>;
using EdgeProperty = boost::property<boost::edge_name_t, Bond::Order>;

// setS is used because we do **NOT** want parallel graphs (bonds represented multiple times)
// vecS is used because we do **WANT** verticies to be one-to-one with their index
// Molecules are naturally undirected, with the exception of dative bonds (handled by the edge property)
using Graph = boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS,
                                    VertexProperty, EdgeProperty>;

using Traits = boost::graph_traits<Graph>;
using VertexDescriptor = Traits::vertex_descriptor;
using EdgeDescriptor = Traits::edge_descriptor;

using VertexIterator = Traits::vertex_iterator;
using AdjacencyIterator = Traits::adjacency_iterator;
using EdgeIterator = Traits::edge_iterator;
using OutEdgeIterator = Traits::out_edge_iterator;

using AdjacencyIteratorPair = std::pair<AdjacencyIterator, AdjacencyIterator>;
using BondIteratorPair = std::pair<EdgeIterator, EdgeIterator>;
using OutBondIteratorPair = std::pair<OutEdgeIterator, OutEdgeIterator>;

}

#endif

max_stars_repo_name: chopralab/spear

max_issues_repo_name: chopralab/spear

max_forks_repo_name: chopralab/spear


text:
/*
 *   test_output.cpp
 *
 *   Created: 11/2/2017
 *   Author: Michael E. Tryby
 *           US EPA - ORD/NRMRL
 *
 *   Unit testing for SWMM outputapi using Boost Test.
 */

#define BOOST_TEST_MODULE "output"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#include <boost/test/included/unit_test.hpp>

#include "swmm_output.h"

// NOTE: Reference data for the unit tests is currently tied to SWMM 5.1.7
#define DATA_PATH "./test_example1.out"

using namespace std;

// Custom test to check the minimum number of correct decimal digits between
// the test and the ref vectors.
boost::test_tools::predicate_result check_cdd_float(std::vector<float>& test,
    std::vector<float>& ref, long cdd_tol)
{
    float tmp, min_cdd = 10.0f;

    // TODO: What is the vectors aren't the same length?

    std::vector<float>::iterator test_it;
    std::vector<float>::iterator ref_it;

    for (test_it = test.begin(), ref_it = ref.begin();
    (test_it < test.end()) && (ref_it < ref.end());
    ++test_it, ++ref_it)
    {

        if (*test_it != *ref_it)
        {
            // Compute log absolute error
            tmp = abs(*test_it - *ref_it);
            if (tmp < 1.0e-7)
                tmp = 1.0e-7f;

            else if (tmp > 2.0)
                tmp = 1.0f;

            tmp = - log10f(tmp);
            if (tmp < 0.0)
                tmp = 0.0f;

            if (tmp < min_cdd)
                min_cdd = tmp;
        }
    }

    return floor(min_cdd) >= cdd_tol;
}

boost::test_tools::predicate_result check_string(std::string test, std::string ref)
{
    if (ref.compare(test) == 0)
        return true;
    else
        return false;
}

BOOST_AUTO_TEST_SUITE (test_output_auto)

BOOST_AUTO_TEST_CASE(InitTest) {
    SMO_Handle p_handle = NULL;

    int error = SMO_init(&p_handle);
    BOOST_REQUIRE(error == 0);
    BOOST_CHECK(p_handle != NULL);

    SMO_close(&p_handle);
}

BOOST_AUTO_TEST_CASE(CloseTest) {
    SMO_Handle p_handle = NULL;
    SMO_init(&p_handle);

    int error = SMO_close(&p_handle);
    BOOST_REQUIRE(error == 0);
    BOOST_CHECK(p_handle == NULL);
}

BOOST_AUTO_TEST_CASE(InitOpenCloseTest) {
    std::string path = std::string(DATA_PATH);
    SMO_Handle p_handle = NULL;
    SMO_init(&p_handle);

    int error = SMO_open(p_handle, path.c_str());
    BOOST_REQUIRE(error == 0);

    SMO_close(&p_handle);
}

BOOST_AUTO_TEST_SUITE_END()

struct Fixture{
    Fixture() {
        std::string path = std::string(DATA_PATH);

        error = SMO_init(&p_handle);
        SMO_clearError(p_handle);
        error = SMO_open(p_handle, path.c_str());

        array = NULL;
        array_dim = 0;
    }
    ~Fixture() {
        SMO_free((void**)&array);
        error = SMO_close(&p_handle);
    }

    std::string path;
    int error;
    SMO_Handle p_handle;

    float* array;
    int array_dim;
};

BOOST_AUTO_TEST_SUITE(test_output_fixture)

BOOST_FIXTURE_TEST_CASE(test_getVersion, Fixture) {
    int version;

    error = SMO_getVersion(p_handle, &version);
    BOOST_REQUIRE(error == 0);

    BOOST_CHECK_EQUAL(51000, version);
}

BOOST_FIXTURE_TEST_CASE(test_getProjectSize, Fixture) {
    int* i_array = NULL;

    error = SMO_getProjectSize(p_handle, &i_array, &array_dim);
    BOOST_REQUIRE(error == 0);

    std::vector<int> test;
    test.assign(i_array, i_array + array_dim);

    // subcatchs, nodes, links, pollutants
    const int ref_dim = 4;
    int ref_array[ref_dim] = {8,14,13,2};

    std::vector<int> ref;
    ref.assign(ref_array, ref_array + ref_dim);

    BOOST_CHECK_EQUAL_COLLECTIONS(ref.begin(), ref.end(), test.begin(), test.end());

    SMO_free((void**)&i_array);
}

BOOST_FIXTURE_TEST_CASE(test_getFlowUnits, Fixture) {
    int units = -1;

    error = SMO_getFlowUnits(p_handle, &units);
    BOOST_REQUIRE(error == 0);
    BOOST_CHECK_EQUAL(0, units);
}

BOOST_FIXTURE_TEST_CASE(test_getPollutantUnits, Fixture) {
    int* i_array = NULL;

    error = SMO_getPollutantUnits(p_handle, &i_array, &array_dim);
    BOOST_REQUIRE(error == 0);

    std::vector<int> test;
    test.assign(i_array, i_array + array_dim);

    const int ref_dim = 2;
    int ref_array[ref_dim] = {0, 1};

    std::vector<int> ref;
    ref.assign(ref_array, ref_array + ref_dim);

    BOOST_CHECK_EQUAL_COLLECTIONS(ref.begin(), ref.end(), test.begin(), test.end());

    SMO_free((void**)&i_array);
    BOOST_CHECK(i_array == NULL);
}

BOOST_FIXTURE_TEST_CASE(test_getStartDate, Fixture) {
    double date = -1;

    error = SMO_getStartDate(p_handle, &date);
    BOOST_REQUIRE(error == 0);

    BOOST_CHECK_EQUAL(35796., date);
}

BOOST_FIXTURE_TEST_CASE(test_getTimes, Fixture) {
    int time = -1;

    error = SMO_getTimes(p_handle, SMO_reportStep, &time);
    BOOST_REQUIRE(error == 0);

    BOOST_CHECK_EQUAL(3600, time);

    error = SMO_getTimes(p_handle, SMO_numPeriods, &time);
    BOOST_REQUIRE(error == 0);

    BOOST_CHECK_EQUAL(36, time);
}

BOOST_FIXTURE_TEST_CASE(test_getElementName, Fixture) {
    char* c_array = NULL;
    int index = 1;

    error = SMO_getElementName(p_handle, SMO_node, index, &c_array, &array_dim);
    BOOST_REQUIRE(error == 0);

    std::string test(c_array);
    std::string ref("10");
    BOOST_CHECK(check_string(test, ref));

    SMO_free((void**)&c_array);
}

BOOST_FIXTURE_TEST_CASE(test_getSubcatchSeries, Fixture) {

    error = SMO_getSubcatchSeries(p_handle, 1, SMO_runoff_rate, 0, 10, &array, &array_dim);
    BOOST_REQUIRE(error == 0);

    const int ref_dim = 10;
    float ref_array[ref_dim] = {0.0f,
                                1.2438242f,
                                2.5639679f,
                                4.524055f,
                                2.5115132f,
                                0.69808137f,
                                0.040894926f,
                                0.011605669f,
                                0.00509294f,
                                0.0027438672f};
    std::vector<float> ref_vec;
    ref_vec.assign(ref_array, ref_array + 10);

    std::vector<float> test_vec;
    test_vec.assign(array, array + array_dim);

    BOOST_CHECK(check_cdd_float(test_vec, ref_vec, 2));
}

BOOST_FIXTURE_TEST_CASE(test_getSubcatchResult, Fixture) {

    error = SMO_getSubcatchResult(p_handle, 1, 1, &array, &array_dim);
    BOOST_REQUIRE(error == 0);

    const int ref_dim = 10;
    float ref_array[ref_dim] = {0.5f,
                                0.0f,
                                0.0f,
                                0.125f,
                                1.2438242f,
                                0.0f,
                                0.0f,
                                0.0f,
                                33.481991f,
                                6.6963983f};
    std::vector<float> ref_vec;
    ref_vec.assign(ref_array, ref_array + ref_dim);

    std::vector<float> test_vec;
    test_vec.assign(array, array + array_dim);

    BOOST_CHECK(check_cdd_float(test_vec, ref_vec, 3));
}

BOOST_FIXTURE_TEST_CASE(test_getNodeResult, Fixture) {

    error = SMO_getNodeResult(p_handle, 2, 2, &array, &array_dim);
    BOOST_REQUIRE(error == 0);

    const int ref_dim = 8;
    float ref_array[ref_dim] = {0.296234f,
                                995.296204f,
                                0.0f,
                                1.302650f,
                                1.302650f,
                                0.0f,
                                15.361463f,
                                3.072293f};
    std::vector<float> ref_vec;
    ref_vec.assign(ref_array, ref_array + ref_dim);

    std::vector<float> test_vec;
    test_vec.assign(array, array + array_dim);

    BOOST_CHECK(check_cdd_float(test_vec, ref_vec, 3));
}

BOOST_FIXTURE_TEST_CASE(test_getLinkResult, Fixture) {

    error = SMO_getLinkResult(p_handle, 3, 3, &array, &array_dim);
    BOOST_REQUIRE(error == 0);

    const int ref_dim = 7;
    float ref_array[ref_dim] = {4.631762f,
                                1.0f,
                                5.8973422f,
                                314.15927f,
                                1.0f,
                                19.070757f,
                                3.8141515f};
    std::vector<float> ref_vec;
    ref_vec.assign(ref_array, ref_array + ref_dim);

    std::vector<float> test_vec;
    test_vec.assign(array, array + array_dim);

    BOOST_CHECK(check_cdd_float(test_vec, ref_vec, 3));
}

BOOST_FIXTURE_TEST_CASE(test_getSystemResult, Fixture) {

    error = SMO_getSystemResult(p_handle, 4, 4, &array, &array_dim);
    BOOST_REQUIRE(error == 0);

    const int ref_dim = 14;
    float ref_array[ref_dim] = {70.0f,
                                0.1f,
                                0.0f,
                                0.19042271f,
                                14.172027f,
                                0.0f,
                                0.0f,
                                0.0f,
                                0.0f,
                                14.172027f,
                                0.55517411f,
                                13.622702f,
                                2913.0793f,
                                0.0f};
    std::vector<float> ref_vec;
    ref_vec.assign(ref_array, ref_array + ref_dim);

    std::vector<float> test_vec;
    test_vec.assign(array, array + array_dim);

    BOOST_CHECK(check_cdd_float(test_vec, ref_vec, 3));
}

BOOST_AUTO_TEST_SUITE_END()


text:
//==================================================================================================
/*!
  @file

  @copyright 2016 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#ifndef BOOST_SIMD_ARCH_COMMON_SIMD_FUNCTION_MODF_HPP_INCLUDED
#define BOOST_SIMD_ARCH_COMMON_SIMD_FUNCTION_MODF_HPP_INCLUDED
#include <boost/simd/detail/overload.hpp>

#include <boost/simd/meta/hierarchy/simd.hpp>
#include <boost/simd/function/trunc.hpp>
#include <boost/fusion/include/std_pair.hpp>

namespace boost { namespace simd { namespace ext
{
   namespace bd = boost::dispatch;
   namespace bs = boost::simd;

   BOOST_DISPATCH_OVERLOAD(modf_
                          , (typename A0, typename X)
                          , bd::cpu_
                          , bs::pack_<bd::arithmetic_<A0>, X>
                          )
   {
     using result = std::pair < A0, A0>;
     BOOST_FORCEINLINE result operator()(A0 const& a0) const
      {
        A0 ent = bs::trunc(a0);
        A0 frac = a0-ent;
        return result(frac, ent);
      }
   };

} } }

#endif

max_stars_repo_name: xmar/pythran

max_issues_repo_name: xmar/pythran

max_forks_repo_name: xmar/pythran


text:
//
// Copyright (c) 2021 Waldemar Schneider (w-schneider1987 at web dot de)
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef A0BAA2CA_6E62_4337_B0BE_F4AFE5469841
#define A0BAA2CA_6E62_4337_B0BE_F4AFE5469841
#include <boost/algorithm/string.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <iostream>
#include <string_view>
namespace confu_json
{

template <typename T> concept IsPrintable = requires(T t) { std::cout << t; };

template <typename T> concept IsOptional = requires(T t) { t.has_value (); };

template <typename T> concept IsPair = requires(T t) { t.second; };

template <class, template <class...> class> constexpr bool is_specialization = false;

template <template <class...> class T, class... Args> inline constexpr bool is_specialization<T<Args...>, T> = true;

template <class T> concept isVector = is_specialization<T, std::vector>;

template <typename T> using is_adapted_struct = std::is_same<typename boost::fusion::traits::tag_of<T>::type, boost::fusion::struct_tag>;

template <typename T> concept IsFusionStruct = requires(T t) { T::self_type; };

}
#endif /* A0BAA2CA_6E62_4337_B0BE_F4AFE5469841 */

ext: hxx


text:
/* vim:set ts=3 sw=3 sts=3 et: */
/**
 * Copyright © 2008-2013 Last.fm Limited
 *
 * This file is part of libmoost.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp>

#include <vector>
#include <fstream>

#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
#include <boost/bind.hpp>

#include "../../include/moost/io/file_watcher.hpp"
#include "../../include/moost/thread/xtime_util.hpp"

using namespace moost::io;
using namespace moost::thread;

BOOST_AUTO_TEST_SUITE( file_watcher_test )

struct Fixture
{
   file_watcher fw;
   std::string test_path;
   std::ofstream out;

   int Creates;
   int Changes;
   int Deletes;

   void file_changed(file_watcher::file_action action, const std::string & /*path*/)
   {
     switch (action)
     {
     case file_watcher::CREATED: ++Creates; break;
     case file_watcher::CHANGED: ++Changes; break;
     case file_watcher::DELETED: ++Deletes; break;
     }
   }

   Fixture()
   : test_path("file_watcher_Test_File"),
     Creates(0),
     Changes(0),
     Deletes(0)
   {
      fw.insert(test_path, boost::bind(&Fixture::file_changed, this, _1, _2));

      // start up the file_watcher
      fw.start();
   }
   ~Fixture()
   {
      // stop the file_watcher
      fw.stop();

      if (out.is_open())
         out.close();
      boost::filesystem::remove(boost::filesystem::path(test_path));
   }

   void sleep(int seconds)
   {
      boost::thread::sleep(xtime_util::add_sec(xtime_util::now(), seconds));
   }
};

// what happens when we do nothing?
BOOST_FIXTURE_TEST_CASE( test_nothing, Fixture )
{
   sleep(1);
   BOOST_REQUIRE_EQUAL(Creates, 0);
   BOOST_REQUIRE_EQUAL(Changes, 0);
   BOOST_REQUIRE_EQUAL(Deletes, 0);
}

// what happens when we create a file?
BOOST_FIXTURE_TEST_CASE( test_create, Fixture )
{
   out.open(test_path.c_str());
   sleep(1);

   BOOST_REQUIRE_EQUAL(Creates, 1);
   BOOST_REQUIRE_EQUAL(Changes, 0);
   BOOST_REQUIRE_EQUAL(Deletes, 0);
}

BOOST_FIXTURE_TEST_CASE( test_change, Fixture )
{
   out.open(test_path.c_str());
   sleep(2);

   out << "wasssaaaaapp!!!" << std::flush;

   sleep(2);

   BOOST_REQUIRE_EQUAL(Creates, 1);
   BOOST_REQUIRE_EQUAL(Changes, 1);
   BOOST_REQUIRE_EQUAL(Deletes, 0);
}

BOOST_FIXTURE_TEST_CASE( test_delete, Fixture )
{
   out.open(test_path.c_str());
   sleep(1);

   out.close();
   boost::filesystem::remove(boost::filesystem::path(test_path));

   sleep(1);

   BOOST_REQUIRE_EQUAL(Creates, 1);
   BOOST_REQUIRE_EQUAL(Changes, 0);
   BOOST_REQUIRE_EQUAL(Deletes, 1);
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: lastfm/libmoost

max_issues_repo_name: lastfm/libmoost

max_forks_repo_name: lastfm/libmoost


text: #include <boost/ptr_container/serialize_ptr_array.hpp>


text:
#include <iostream>
#include <fstream>
#include<iomanip>

#include <cstdlib>
#include <stdio.h>
#include <string>
#include <vector>

#include <time.h>
#include <sys/time.h>

#include "mkl.h"
#include <omp.h>
//#include "mkl_service.h"
#include <fftw3.h>
#include <armadillo>
using namespace std;
using namespace arma;

double gettime(){
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return tv.tv_sec*1000+tv.tv_usec/1000.0;
};

double *** al(int &n1,int &n2,int &n3){
    double ***p;
    p=new double**[n1];
    for (int i=0;i<n1;i++){
        p[i] = new double *[n2];
        for (int j=0;j<n2;j++) {
            p[i][j] = new double[n3];
        }
    }
    return p;
}

//template <typename T>
void del(double *** p, int &n1,int &n2){
    for(int i=0; i<n1; i++) {
        for (int j = 0; j < n2; j++) {
            delete [] p[i][j];
        }
        delete [] p[i];
    }
    delete  [] p;
    p=NULL;
}

double *** loadfile(int &n1, int &n2, int &n3, char *path){

    int count = 0;
    FILE* fp;
    char str[100];

    double ***v = al(n1,n2,n3);

    fp = fopen(path,"r");

    string tmp;
    while (fscanf(fp, "%s", str) != EOF)
    {
        int NUM=count;
        int k=NUM%(n1*n2);
        k=(NUM-k)/(n1*n2);
        int j=(NUM-k*n1*n2)%n2;
        int i=(NUM-k*n1*n2)/n2;
        tmp=str;
        v[i][j][k]=(double)atof(tmp.c_str());
        count++;
        if(count==n1*n2*n3){break;}
    }

    fclose(fp);

    return v;
}

void display(double *** v, int &n1, int &n2, int &n3){

    cout << "Tensor: " << endl;

    for (int k = 0; k < n3; k++) {
        for (int i = 0; i < n1; i++) {
            for (int j = 0; j < n2; j++) {
                cout << v[i][j][k] << " ";
            }
            cout << endl;
        }
        cout << endl;
    }
}

int main()
{
    double t0, t1, t2, t3, t4;
    int turn=2000;
    int n1 = turn, n2 = turn, n3 = 110;
    int N0 = floor(n3/2.0) + 1;

    char path[1000] = "/home/jcfei/Documents/MATLAB/data/a2000.txt";

    double ***M = loadfile(n1, n2, n3, path);
    cout << "loadfile" << endl;

    double ***v_t = al(n1, n2, N0);
    double ***v_t1 = al(n1, n2, N0);

    t0 = gettime();
    fftw_complex out[N0]; //fftw_alloc_real()
    double *in = fftw_alloc_real(n3);

    fftw_plan p_fft;
    p_fft = fftw_plan_dft_r2c_1d(n3, in, out, FFTW_ESTIMATE);
//    p=fftw_plan_dft_1d(n3,in,out,FFTW_FORWARD,FFTW_MEASURE);

//#pragma omp parallel for num_threads(8)
    for (int i = 0; i < n1; i++) {
        for (int j = 0; j < n2; j++) {
            in = M[i][j];
            fftw_execute_dft_r2c(p_fft, in, out);
            for (int k = 0; k < N0; k++) {
                v_t[i][j][k] = out[k][0];
                v_t1[i][j][k] = out[k][1];
            }
        }
    }
    del(M,n1,n2);
//    t1=gettime();
//    cout<<"fft time: "<<t1-t0<<endl;

    double ***uf = al(n1, n1, N0);
    double ***uf1 = al(n1, n1, N0);
    double ***theta = al(n1, n2, N0);
    double ***vf = al(n2, n2, N0);
    double ***vf1 = al(n2, n2, N0);

    cx_mat TMP = zeros<cx_mat>(n1, n2);
    cx_mat TMPU = zeros<cx_mat>(n1, n1);
    cx_mat TMPV = zeros<cx_mat>(n2, n2);
    colvec TMPT;

//    t2=gettime();
//    cout<<"alloc space: "<<t2-t1<<endl;

//#pragma omp parallel for num_threads(8)
    for (int k = 0; k < N0; k++) {
        for (int i = 0; i < n1; i++) {
            for (int j = 0; j < n2; j++) {
                TMP(i, j).real(v_t[i][j][k]);
                TMP(i, j).imag(v_t1[i][j][k]);
            }
        }
        svd(TMPU, TMPT, TMPV, TMP, "dc");
//        svd(TMPU,TMPT,TMPV,TMP,"std");

        for (int i = 0; i < n1; i++) {
            for (int j = 0; j < n1; j++) {
                uf[i][j][k] = TMPU(i, j).real();
                uf1[i][j][k] = TMPU(i, j).imag();
            }
        }
        for (int i = 0; i < n2; i++) {
            for (int j = 0; j < n2; j++) {
                vf[i][j][k] = TMPV(i, j).real();
                vf1[i][j][k] = TMPV(i, j).imag();
            }
        }
        if (n1 <= n2) {
            for (int i = 0; i < n1; i++) {
                theta[i][i][k] = TMPT(i);
            }
        } else {
            for (int i = 0; i < n2; i++) {
                theta[i][i][k] = TMPT(i);
            }
        }
    }

    del(v_t, n1, n2);
    del(v_t1, n1, n2);

    fftw_complex out1[N0]; //fftw_alloc_real()
    double *in1 = fftw_alloc_real(n3);
    p_fft = fftw_plan_dft_c2r_1d(n3, out1, in1, FFTW_ESTIMATE);

//    #pragma omp parallel for num_threads(8)
//    #pragma omp parallel for num_threads(2)

    double ***U = al(n1, n1, n3);

    for (int i = 0; i < n1; i++) {
        for (int j = 0; j < n1; j++) {
            for (int k = 0; k < N0; k++) {
                out1[k][0] = uf[i][j][k];
                out1[k][1] = uf1[i][j][k];
            }
            fftw_execute_dft_c2r(p_fft, out1, in1);

            for (int k = 0; k < n3; k++) {
                U[i][j][k] = 1.0 / n3 * in1[k];
            }
        }
    }

    del(uf, n1, n1);
    del(uf1, n1, n1);

    double ***V = al(n2, n2, n3);
    for (int i = 0; i < n2; i++) {
        for (int j = 0; j < n2; j++) {
            for (int k = 0; k < N0; k++) {
                out1[k][0] = vf[i][j][k];
                out1[k][1] = vf1[i][j][k];
            }
            fftw_execute_dft_c2r(p_fft, out1, in1);
            for (int k = 0; k < n3; k++) {
                V[i][j][k] = 1.0 / n3 * in1[k];
            }
        }
    }
    del(vf, n2, n2);
    del(vf1, n2, n2);

    double ***Theta = al(n1, n2, n3);
    for (int i = 0; i < n1; i++) {
        for (int j = 0; j < n2; j++) {
            for (int k = 0; k < N0; k++) {
                out1[k][0] = theta[i][j][k];
                out1[k][1] = 0;
            }
            fftw_execute_dft_c2r(p_fft, out1, in1);
            for (int k = 0; k < n3; k++) {
                Theta[i][j][k] = 1.0 / n3 * in1[k];
            }
        }
    }
    del(theta, n1, n2);

    fftw_destroy_plan(p_fft);

    t4 = gettime();
//    cout<<"ifft time: "<<t4-t3<<endl;
    cout << "Total time: " << t4 - t0 << endl;

    //fft transform result write to txt
//    ofstream a;
//    a.open("/home/jcfei/Desktop/TensorC++/txtToarray/Theta-video.txt");
//    for (int k=0; k<n3;k++){
//        for (int i=0; i<n1;i++){
//            for(int j=0; j<n2;j++){
//                a<<setiosflags(ios::right)<<setw(15)<<Theta[i][j][k]<<"  ";
//            }
//            a<<endl;
//        }
//    }
//    a.close();
//
//    ofstream b;
//    b.open("/home/jcfei/Desktop/TensorC++/txtToarray/U-video.txt");
//    for (int k=0; k<n3;k++){
//        for (int i=0; i<n1;i++){
//            for(int j=0; j<n1;j++){
//                b<<setiosflags(ios::right)<<setw(10)<<U[i][j][k]<<"  ";
//            }
//            b<<endl;
//        }
//    }
//    b.close();
//
//    ofstream c;
//    c.open("/home/jcfei/Desktop/TensorC++/txtToarray/V-video.txt");
//    for (int k=0; k<n3;k++){
//        for (int i=0; i<n2;i++){
//            for(int j=0; j<n2;j++){
//                c<<setiosflags(ios::right)<<setw(10)<<V[i][j][k]<<"  ";
//            }
//            c<<endl;
//        }
//    }
//    c.close();
    return 0;
}

max_stars_repo_name: Forsworns/Transform-based-Tensor-Model

max_issues_repo_name: Forsworns/Transform-based-Tensor-Model

max_forks_repo_name: Forsworns/Transform-based-Tensor-Model


text:
//
// Copyright (c) 2002-2018 WEINZIERL ENGINEERING GmbH
// All rights reserved.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY,
// WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
//

#include "pch/kdrive_pch.h"
#include "kdrive/baos/core/DataPacket.h"
#include "kdrive/baos/core/API.h"
#include "kdrive/baos/core/Exception.h"
#include "kdrive/baos/protocols/Protocol.h"
#include <boost/assert.hpp>

using namespace kdrive::baos;
using namespace kdrive::connector;

/*************************************
** Data Packet
**************************************/

DataPacket::~DataPacket()
{
}

void DataPacket::setMainService(unsigned char mainService)
{
	mainService_ = mainService;
}

unsigned char DataPacket::getMainService() const
{
	return mainService_;
}

void DataPacket::setSubService(unsigned char subService)
{
	subService_ = subService;
}

unsigned char DataPacket::getSubService() const
{
	return subService_;
}

void DataPacket::setOffset(unsigned short offset)
{
	offset_ = offset;
}

unsigned short DataPacket::getOffset() const
{
	return offset_;
}

void DataPacket::setCount(unsigned short count)
{
	count_ = count;
}

unsigned short DataPacket::getCount() const
{
	return count_;
}

void DataPacket::setBuffer(const Buffer& buffer)
{
	buffer_ = buffer;
}

DataPacket::Buffer& DataPacket::getBuffer()
{
	return buffer_;
}

const DataPacket::Buffer& DataPacket::getBuffer() const
{
	return buffer_;
}

void DataPacket::setHeaderPolicy(std::shared_ptr<HeaderPolicy> headerPolicy)
{
	headerPolicy_ = headerPolicy;
}

void DataPacket::setVersion(unsigned char version)
{
	version_ = version;
}

unsigned char DataPacket::getVersion() const
{
	return version_;
}

DataPacket::DataPacket()

	: version_(0),
	  mainService_(ProtocolConstants::MainService),
	  subService_(0),
	  offset_(0),
	  count_(0)
{
	setProtocol("baos");
}

std::size_t DataPacket::sizeImpl() const
{
	return sizeOfHeader() + sizeOfBody();
}

std::size_t DataPacket::readFromBufferImpl(const unsigned char* buffer, std::size_t bufferSize)
{
	std::size_t size = readHeader(buffer, bufferSize);
	size += readBody(buffer + size, bufferSize - size);
	return size;
}

std::size_t DataPacket::writeToBufferImpl(unsigned char* buffer, std::size_t bufferSize) const
{
	std::size_t size = writeHeader(buffer, bufferSize);
	size += writeBody(buffer + size, bufferSize - size);
	return size;
}

std::size_t DataPacket::sizeOfHeader() const
{
	BOOST_ASSERT(headerPolicy_.get() && "Invalid Data Packet Header Policy");
	return headerPolicy_->size(*this);
}

std::size_t DataPacket::readHeader(const unsigned char* buffer, std::size_t bufferSize)
{
	BOOST_ASSERT(headerPolicy_.get() && "Invalid Data Packet Header Policy");
	return headerPolicy_->read(*this, buffer, bufferSize);
}

std::size_t DataPacket::writeHeader(unsigned char* buffer, std::size_t bufferSize) const
{
	BOOST_ASSERT(headerPolicy_.get() && "Invalid Data Packet Header Policy");
	return headerPolicy_->write(*this, buffer, bufferSize);
}

std::size_t DataPacket::sizeOfBody() const
{
	return buffer_.size();
}

std::size_t DataPacket::readBody(const unsigned char* buffer, std::size_t bufferSize)
{
	if (bufferSize)
	{
		buffer_.resize(bufferSize);
		std::copy(buffer, buffer + bufferSize, buffer_.begin());
	}
	else
	{
		buffer_.clear();
	}
	return bufferSize;
}

std::size_t DataPacket::writeBody(unsigned char* buffer, std::size_t bufferSize) const
{
	std::size_t size = buffer_.size();

	if (size)
	{
		if (size > bufferSize)
		{
			throw ClientException("Buffer Overflow");
		}

		std::uninitialized_copy(buffer_.begin(), buffer_.end(), buffer);
	}

	return size;
}

/*************************************
** Error Response
**************************************/

unsigned char ErrorResponse::getErrorCode() const
{
	const Buffer& buffer = getBuffer();
	return buffer.at(0);
}

max_stars_repo_name: weinzierl-engineering/baos

max_issues_repo_name: weinzierl-engineering/baos

max_forks_repo_name: weinzierl-engineering/baos


text:
/*
 * Copyright 2013 Southwest Research Institute

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */

//#include <mtconnect_msgs/CncStatus.h>
#include <mtconnect_msgs/CloseChuckAction.h>
#include <mtconnect_msgs/OpenChuckAction.h>
#include <mtconnect_msgs/CloseDoorAction.h>
#include <mtconnect_msgs/OpenDoorAction.h>
#include <mtconnect_msgs/MaterialLoadAction.h>
#include <mtconnect_msgs/MaterialUnloadAction.h>
#include <object_manipulation_msgs/PickupAction.h>
#include <object_manipulation_msgs/PlaceAction.h>
#include <arm_navigation_msgs/MoveArmAction.h>
#include <mtconnect_cnc_robot_example/utilities/utilities.h>
#include <actionlib/client/simple_action_client.h>
#include <actionlib/server/simple_action_server.h>
#include <ros/ros.h>
#include <boost/assign/list_inserter.hpp>
#include <boost/assign/list_of.hpp>
#include <mtconnect_msgs/RobotSpindle.h>
#include <mtconnect_msgs/RobotStates.h>
#include <boost/thread.hpp>

// aliases
typedef actionlib::SimpleActionClient<arm_navigation_msgs::MoveArmAction> MoveArmClient;
typedef actionlib::SimpleActionClient<object_manipulation_msgs::PickupAction> MovePickupClient;
typedef actionlib::SimpleActionClient<object_manipulation_msgs::PlaceAction> MovePlaceClient;
typedef actionlib::SimpleActionClient<mtconnect_msgs::OpenDoorAction> CncOpenDoorClient;
typedef actionlib::SimpleActionClient<mtconnect_msgs::CloseDoorAction> CncCloseDoorClient;
typedef actionlib::SimpleActionClient<mtconnect_msgs::OpenChuckAction> CncOpenChuckClient;
typedef actionlib::SimpleActionClient<mtconnect_msgs::CloseChuckAction> CncCloseChuckClient;
typedef actionlib::SimpleActionServer<mtconnect_msgs::MaterialLoadAction> MaterialLoadServer;
typedef actionlib::SimpleActionServer<mtconnect_msgs::MaterialUnloadAction> MaterialUnloadServer;
typedef boost::shared_ptr<MoveArmClient> MoveArmClientPtr;
typedef boost::shared_ptr<MovePickupClient> MovePickupClientPtr;
typedef boost::shared_ptr<MovePlaceClient> MovePlaceClientPtr;
typedef boost::shared_ptr<CncOpenDoorClient> CncOpenDoorClientPtr;
typedef boost::shared_ptr<CncCloseDoorClient> CncCloseDoorClientPtr;
typedef boost::shared_ptr<CncOpenChuckClient> CncOpenChuckClientPtr;
typedef boost::shared_ptr<CncCloseChuckClient> CncCloseChuckClientPtr;
typedef boost::shared_ptr<MaterialLoadServer> MaterialLoadServerPtr;
typedef boost::shared_ptr<MaterialUnloadServer> MaterialUnloadServerPtr;
typedef std::vector<int> MaterialHandlingSequence;

// defaults
static const std::string PARAM_ARM_GROUP = "arm_group";
static const std::string PARAM_UNLOAD_PICKUP_GOAL = "unload_pickup_goal";
static const std::string PARAM_UNLOAD_PLACE_GOAL = "unload_place_goal";
static const std::string PARAM_LOAD_PICKUP_GOAL = "load_pickup_goal";
static const std::string PARAM_LOAD_PLACE_GOAL = "load_place_goal";
static const std::string PARAM_JOINT_HOME_POSITION = "/joint_home_position";
static const std::string PARAM_JOINT_WAIT_POSITION = "/joint_wait_position";
static const std::string DEFAULT_MOVE_ARM_ACTION = "move_arm_action";
static const std::string DEFAULT_PICKUP_ACTION = "pickup_action_service";
static const std::string DEFAULT_PLACE_ACTION = "place_action_service";
static const std::string DEFAULT_MATERIAL_LOAD_ACTION= "material_load_action";
static const std::string DEFAULT_MATERIAL_UNLOAD_ACTION= "material_unload_action";
static const std::string DEFAULT_CNC_OPEN_DOOR_ACTION = "cnc_open_door_action";
static const std::string DEFAULT_CNC_CLOSE_DOOR_ACTION = "cnc_close_door_action";
static const std::string DEFAULT_CNC_OPEN_CHUCK_ACTION = "cnc_open_chuck_action";
static const std::string DEFAULT_CNC_CLOSE_CHUCK_ACTION = "cnc_close_chuck_action";
static const std::string DEFAULT_ROBOT_STATES_TOPIC = "robot_states";
static const std::string DEFAULT_ROBOT_SPINDLE_TOPIC = "robot_spindle";
static const std::string CNC_ACTION_ACTIVE_FLAG = "ACTIVE";
static const double DEFAULT_JOINT_ERROR_TOLERANCE = 0.01f; // radians
static const int DEFAULT_PATH_PLANNING_ATTEMPTS = 2;
static const std::string DEFAULT_PATH_PLANNER = "/ompl_planning/plan_kinematic_path";
static const double DURATION_LOOP_PAUSE = 2.0f;
static const double DURATION_TIMER_INTERVAL = 4.0f;
static const double DURATION_WAIT_SERVER = 2.0f;
static const double DURATION_PLANNING_TIME = 5.0f;
static const double DURATION_WAIT_RESULT = 40.0f;
static const double DURATION_PATH_COMPLETION = 2.0f;
static const int MAX_WAIT_ATTEMPTS = 40;

class SimpleMaterialHandlingServer
{
public:
	SimpleMaterialHandlingServer():
		material_load_pickup_goal_(),
		material_unload_pickup_goal_(),
		material_load_place_goal_(),
		material_unload_place_goal_(),
		joint_home_pos_(),
		joint_wait_pos_()

	{

	}

	~SimpleMaterialHandlingServer()
	{

	}

	void run()
	{
		if(!setup())
		{
			return;
		}

		ros::AsyncSpinner spinner(4);
		spinner.start();

		// starting material handling servers
		material_load_server_ptr_->start();
		material_unload_server_ptr_->start();

		// moving the arm home
		move_arm_goal_.motion_plan_request.goal_constraints.joint_constraints.clear();
		joint_home_pos_.toJointConstraints(DEFAULT_JOINT_ERROR_TOLERANCE,DEFAULT_JOINT_ERROR_TOLERANCE,
				move_arm_goal_.motion_plan_request.goal_constraints.joint_constraints);

		move_arm_client_ptr_->sendGoal(move_arm_goal_);
		if(move_arm_client_ptr_->waitForResult(ros::Duration(DURATION_WAIT_RESULT)) &&
				(move_arm_client_ptr_->getResult()->error_code.val == arm_navigation_msgs::ArmNavigationErrorCodes::SUCCESS))
		{
			ROS_INFO_STREAM("Move home succeeded, proceeding");
		}
		else
		{
			ROS_ERROR_STREAM("Move home failed, exiting");
			return;
		}

		// spinning node
		while(ros::ok())
		{
			ros::Duration(DURATION_LOOP_PAUSE).sleep();
		}
	}

public:

	MaterialHandlingSequence material_load_sequence_;
	MaterialHandlingSequence material_unload_sequence_;

protected:

	bool fetchParameters(std::string ns = "")
	{
		ros::NodeHandle ph("~");
		return ph.getParam(PARAM_ARM_GROUP,arm_group_) &&
				material_load_pickup_goal_.fetchParameters(PARAM_LOAD_PICKUP_GOAL) && material_load_place_goal_.fetchParameters(PARAM_LOAD_PLACE_GOAL) &&
				material_unload_pickup_goal_.fetchParameters(PARAM_UNLOAD_PICKUP_GOAL) && material_unload_place_goal_.fetchParameters(PARAM_UNLOAD_PLACE_GOAL) &&
				joint_home_pos_.fetchParameters(PARAM_JOINT_HOME_POSITION) && joint_wait_pos_.fetchParameters(PARAM_JOINT_WAIT_POSITION);
	}

	bool setup()
	{
		using namespace boost::assign;
		using namespace industrial_msgs;
		typedef mtconnect_msgs::MaterialHandlingFeedback Feedback;

		ros::NodeHandle nh;
		int wait_attempts = 0;

		if(fetchParameters())
		{
			ROS_INFO_STREAM("Read all parameters successfully");
		}
		else
		{
			ROS_ERROR_STREAM("Failed to read parameters, exiting");
			return false;
		}

		// initializing task sequence lists
		material_load_sequence_ =
				list_of((int)Feedback::TRANSPORTING_MATERIAL)
				((int)Feedback::PLACING_MATERIAL)
				((int)Feedback::CLOSING_CHUCK)
				((int)Feedback::CLEARING_WORK_AREA)
				((int)Feedback::CLOSING_DOOR);

		material_unload_sequence_ =
				list_of((int)Feedback::OPENNING_DOOR)
				((int)Feedback::OPENNING_CHUCK)
				((int)Feedback::RETRIEVING_WORKPIECE)
				((int)Feedback::TRANSPORTING_WORKPIECE)
				((int)Feedback::CLOSING_CHUCK)((int)Feedback::CLOSING_DOOR);

		// setting up move arm goal
		move_arm_goal_.motion_plan_request.group_name = arm_group_;
		move_arm_goal_.motion_plan_request.num_planning_attempts = DEFAULT_PATH_PLANNING_ATTEMPTS;
		move_arm_goal_.planner_service_name = DEFAULT_PATH_PLANNER;
		move_arm_goal_.motion_plan_request.allowed_planning_time = ros::Duration(DURATION_PLANNING_TIME);
		move_arm_goal_.motion_plan_request.planner_id = "";
		move_arm_goal_.motion_plan_request.expected_path_duration = ros::Duration(DURATION_PATH_COMPLETION);

		// initializing service servers
		material_load_server_ptr_ = MaterialLoadServerPtr(new MaterialLoadServer(nh,DEFAULT_MATERIAL_LOAD_ACTION,
				boost::bind(&SimpleMaterialHandlingServer::materialLoadGoalCallback,this,_1),false));

		material_unload_server_ptr_ = MaterialUnloadServerPtr(new  MaterialUnloadServer(nh,DEFAULT_MATERIAL_UNLOAD_ACTION,
						boost::bind(&SimpleMaterialHandlingServer::materialUnloadGoalCallback,this,_1),false));

		// initializing service clients
		move_arm_client_ptr_ = MoveArmClientPtr(new MoveArmClient(DEFAULT_MOVE_ARM_ACTION,true));
		arm_pickup_client_ptr_ = MovePickupClientPtr(new MovePickupClient(DEFAULT_PICKUP_ACTION,true));
		arm_place_client_ptr_ = MovePlaceClientPtr(new MovePlaceClient(DEFAULT_PLACE_ACTION,true));
		open_door_client_ptr_ =CncOpenDoorClientPtr(new CncOpenDoorClient(DEFAULT_CNC_OPEN_DOOR_ACTION,true));
		close_door_client_ptr_ =CncCloseDoorClientPtr(new CncCloseDoorClient(DEFAULT_CNC_CLOSE_DOOR_ACTION,true));
		open_chuck_client_ptr_ =CncOpenChuckClientPtr(new CncOpenChuckClient(DEFAULT_CNC_OPEN_CHUCK_ACTION,true));
		close_chuck_client_ptr_ =CncCloseChuckClientPtr(new CncCloseChuckClient(DEFAULT_CNC_CLOSE_CHUCK_ACTION,true));

		// initializing publishers
		robot_states_pub_ = nh.advertise<mtconnect_msgs::RobotStates>(DEFAULT_ROBOT_STATES_TOPIC,1);
		robot_spindle_pub_ = nh.advertise<mtconnect_msgs::RobotSpindle>(DEFAULT_ROBOT_SPINDLE_TOPIC,1);

		// initializing mtconnect robot messages
		robot_state_msg_.avail.val = TriState::ENABLED;
		robot_state_msg_.mode.val = RobotMode::AUTO;
		robot_state_msg_.rexec.val = TriState::HIGH;
		robot_spindle_msg_.c_unclamp.val = TriState::HIGH;
		robot_spindle_msg_.s_inter.val = TriState::HIGH;

		// initializing timers
		publish_timer_ = nh.createTimer(ros::Duration(DURATION_TIMER_INTERVAL),
				&SimpleMaterialHandlingServer::publishTimerCallback,this,false,false);

		// waiting for robot related service servers
		while(	ros::ok() && (
				(!move_arm_client_ptr_->isServerConnected() && !move_arm_client_ptr_->waitForServer(ros::Duration(DURATION_WAIT_SERVER))) ||
				(!arm_pickup_client_ptr_->isServerConnected() && !arm_pickup_client_ptr_->waitForServer(ros::Duration(DURATION_WAIT_SERVER))) ||
				(!arm_place_client_ptr_->isServerConnected() && !arm_place_client_ptr_->waitForServer(ros::Duration(DURATION_WAIT_SERVER))) ||
				(!open_door_client_ptr_->isServerConnected() && !open_door_client_ptr_->waitForServer(ros::Duration(DURATION_WAIT_SERVER))) ||
				(!close_door_client_ptr_->isServerConnected() && !close_door_client_ptr_->waitForServer(ros::Duration(DURATION_WAIT_SERVER))) ||
				(!open_chuck_client_ptr_->isServerConnected() && !open_chuck_client_ptr_->waitForServer(ros::Duration(DURATION_WAIT_SERVER))) ||
				(!close_chuck_client_ptr_->isServerConnected() && !close_chuck_client_ptr_->waitForServer(ros::Duration(DURATION_WAIT_SERVER)))
				))
		{
			if(wait_attempts++ > MAX_WAIT_ATTEMPTS)
			{
				ROS_ERROR_STREAM("One or more action cnc/robot servers were not found, exiting");
				return false;
			}
			ROS_WARN_STREAM("Waiting for cnc/robot action servers");
			ros::Duration(DURATION_WAIT_SERVER).sleep();
		}

		publish_timer_.start();

		ROS_INFO_STREAM("Found all action servers");
		return true;
	}

	void materialLoadGoalCallback(const MaterialLoadServer::GoalConstPtr &gh)
	{
		// declaring result
		MaterialLoadServer::Result res;

		ROS_INFO_STREAM("MATERIAL LOAD request in progress");
		//material_load_server_ptr_->acceptNewGoal();
		if(executeMaterialHandlingTasks(material_load_sequence_))
		{
			res.load_state = "Succeeded";
			material_load_server_ptr_->setSucceeded(res);
			ROS_INFO_STREAM("MATERIAL LOAD request succeeded");
		}
		else
		{
			res.load_state = "Failed";
			material_load_server_ptr_->setAborted(res);
			ROS_ERROR_STREAM("MATERIAL LOAD request failed");
		}
	}

	void materialUnloadGoalCallback(const MaterialUnloadServer::GoalConstPtr &gh)
	{
		// declaring result
		MaterialUnloadServer::Result res;

		//material_unload_server_ptr_->acceptNewGoal();
		ROS_INFO_STREAM("MATERIAL UNLOAD request in progress");
		if(executeMaterialHandlingTasks(material_unload_sequence_))
		{
			res.unload_state= "Succeeded";
			material_unload_server_ptr_->setSucceeded(res);
			ROS_INFO_STREAM("MATERIAL UNLOAD request succeeded");
		}
		else
		{
			res.unload_state = "Failed";
			material_unload_server_ptr_->setAborted(res);
			ROS_ERROR_STREAM("MATERIAL UNLOAD request failed");
		}
	}

	bool executeMaterialHandlingTasks(const MaterialHandlingSequence &seq)
	{
		// local aliases
		typedef mtconnect_msgs::MaterialHandlingFeedback Feedback;
		typedef MaterialHandlingSequence::const_iterator ConstSequenceIterator;

		// strings
		std::string task_name;

		// action messages
		mtconnect_msgs::OpenDoorGoal open_door_goal;
		mtconnect_msgs::CloseDoorGoal close_door_goal;
		mtconnect_msgs::OpenChuckGoal open_chuck_goal;
		mtconnect_msgs::CloseChuckGoal close_chuck_goal;
		open_door_goal.open_door = CNC_ACTION_ACTIVE_FLAG;
		close_door_goal.close_door = CNC_ACTION_ACTIVE_FLAG;
		open_chuck_goal.open_chuck = CNC_ACTION_ACTIVE_FLAG;
		close_chuck_goal.close_chuck = CNC_ACTION_ACTIVE_FLAG;

		for(ConstSequenceIterator i = seq.begin(); i != seq.end(); i++)
		{
			switch (*i)
			{
			case Feedback::TRANSPORTING_MATERIAL:

				task_name = "TRANSPORTING_MATERIAL";
				ROS_INFO_STREAM(task_name <<" task in progress");
				arm_pickup_client_ptr_->sendGoal(material_load_pickup_goal_);
				if(arm_pickup_client_ptr_->waitForResult(ros::Duration(DURATION_WAIT_RESULT)))
				{
					if(arm_pickup_client_ptr_->getResult()->manipulation_result.value != object_manipulation_msgs::ManipulationResult::SUCCESS)
					{
						ROS_ERROR_STREAM(task_name <<" task failed with status '"<< arm_pickup_client_ptr_->getResult()->manipulation_result.value
								<<"', exiting");
						return false;
					}

					ROS_INFO_STREAM(task_name <<" task completed");
				}
				else
				{
					ROS_ERROR_STREAM(task_name <<" task failed, exiting");
					return false;
				}
				break;

			case Feedback::TRANSPORTING_WORKPIECE:

				task_name = "TRANSPORTING_WORKPIECE";
				ROS_INFO_STREAM(task_name <<" task in progress");
				arm_place_client_ptr_->sendGoal(material_unload_place_goal_);
				if(arm_place_client_ptr_->waitForResult(ros::Duration(DURATION_WAIT_RESULT)))
				{
					if(arm_place_client_ptr_->getResult()->manipulation_result.value != object_manipulation_msgs::ManipulationResult::SUCCESS)
					{
						ROS_ERROR_STREAM(task_name <<" task failed with status '"<< arm_place_client_ptr_->getResult()->manipulation_result.value
								<<"', exiting");
						return false;
					}

					ROS_INFO_STREAM(task_name <<" task completed");
				}
				else
				{
					ROS_ERROR_STREAM(task_name <<" task failed, exiting");
					return false;
				}
				break;

			case Feedback::OPENNING_DOOR:

				task_name = "OPENNING_DOOR";
				ROS_INFO_STREAM(task_name <<" task in progress");
				open_door_client_ptr_->sendGoal(open_door_goal);
				if(open_door_client_ptr_->waitForResult(ros::Duration(DURATION_WAIT_RESULT)))
				{
					ROS_INFO_STREAM(task_name <<" task completed");
				}
				else
				{
					ROS_ERROR_STREAM(task_name <<" task failed due to timeout, exiting");
					return false;
				}
				break;

			case Feedback::OPENNING_CHUCK:

				task_name = "OPENNING_CHUCK";
				ROS_INFO_STREAM(task_name <<" task in progress");
				open_chuck_client_ptr_->sendGoal(open_chuck_goal);
				if(open_chuck_client_ptr_->waitForResult(ros::Duration(DURATION_WAIT_RESULT)))
				{
					ROS_INFO_STREAM(task_name <<" task completed");
				}
				else
				{
					ROS_ERROR_STREAM(task_name <<" task failed due to timeout, exiting");
					return false;
				}
				break;

				break;
			case Feedback::CLOSING_CHUCK:

				task_name = "CLOSING_CHUCK";
				ROS_INFO_STREAM(task_name <<" task in progress");
				close_chuck_client_ptr_->sendGoal(close_chuck_goal);
				if(close_chuck_client_ptr_->waitForResult(ros::Duration(DURATION_WAIT_RESULT)))
				{
					ROS_INFO_STREAM(task_name <<" task completed");
				}
				else
				{
					ROS_ERROR_STREAM(task_name <<" task failed due to timeout, exiting");
					return false;
				}
				break;

			case Feedback::CLOSING_DOOR:

				task_name = "CLOSING_DOOR";
				ROS_INFO_STREAM(task_name <<" task in progress");
				close_door_client_ptr_->sendGoal(close_door_goal);
				if(close_door_client_ptr_->waitForResult(ros::Duration(DURATION_WAIT_RESULT)))
				{
					ROS_INFO_STREAM(task_name <<" task completed");
				}
				else
				{
					ROS_ERROR_STREAM(task_name <<" task failed due to timeout, exiting");
					return false;
				}
				break;

			case Feedback::PLACING_MATERIAL:

				task_name = "PLACING_MATERIAL";
				ROS_INFO_STREAM(task_name <<" task in progress");
				arm_place_client_ptr_->sendGoal(material_load_place_goal_);
				if(arm_place_client_ptr_->waitForResult(ros::Duration(DURATION_WAIT_RESULT)))
				{
					if(arm_place_client_ptr_->getResult()->manipulation_result.value != object_manipulation_msgs::ManipulationResult::SUCCESS)
					{
						ROS_ERROR_STREAM(task_name <<" task failed with status '"<< arm_place_client_ptr_->getResult()->manipulation_result.value
								<<"', exiting");
						return false;
					}

					ROS_INFO_STREAM(task_name <<" task completed");
				}
				else
				{
					ROS_ERROR_STREAM(task_name <<" task failed, exiting");
					return false;
				}
				break;

			case Feedback::RETRIEVING_WORKPIECE:

				task_name = "RETRIEVING_WORKPIECE";
				ROS_INFO_STREAM(task_name <<" task in progress");
				arm_pickup_client_ptr_->sendGoal(material_unload_pickup_goal_);
				if(arm_pickup_client_ptr_->waitForResult(ros::Duration(DURATION_WAIT_RESULT)))
				{
					if(arm_pickup_client_ptr_->getResult()->manipulation_result.value != object_manipulation_msgs::ManipulationResult::SUCCESS)
					{
						ROS_ERROR_STREAM(task_name <<" task failed with status '"<< arm_pickup_client_ptr_->getResult()->manipulation_result.value
								<<"', exiting");
						return false;
					}

					ROS_INFO_STREAM(task_name <<" task completed");
				}
				else
				{
					ROS_ERROR_STREAM(task_name <<" task failed, exiting");
					return false;
				}
				break;

			case Feedback::WAITING_ON_EXTERNAL_DEVICE:
				break;
			case Feedback::CLEARING_WORK_AREA:

				task_name = "CLEARING_WORK_AREA";
				ROS_INFO_STREAM(task_name <<" task in progress");

				// setting goal joint constraints
				move_arm_goal_.motion_plan_request.goal_constraints.joint_constraints.clear();
				joint_wait_pos_.toJointConstraints(DEFAULT_JOINT_ERROR_TOLERANCE,DEFAULT_JOINT_ERROR_TOLERANCE,
						move_arm_goal_.motion_plan_request.goal_constraints.joint_constraints);

				move_arm_client_ptr_->sendGoal(move_arm_goal_);
				if(move_arm_client_ptr_->waitForResult(ros::Duration(DURATION_WAIT_RESULT)))
				{
					if(move_arm_client_ptr_->getResult()->error_code.val != arm_navigation_msgs::ArmNavigationErrorCodes::SUCCESS)
					{
						ROS_ERROR_STREAM(task_name <<" task failed, exiting");
						return false;
					}

					ROS_INFO_STREAM(task_name <<" task completed");
				}
				else
				{
					ROS_ERROR_STREAM(task_name <<" task failed, exiting");
					return false;
				}
				break;

			}
		}
		return true;
	}

	void publishTimerCallback(const ros::TimerEvent &evnt)
	{
		// updating header time stamps
		robot_state_msg_.header.stamp = ros::Time::now();
		robot_spindle_msg_.header.stamp = ros::Time::now();

		// publishing
		robot_states_pub_.publish(robot_state_msg_);
		robot_spindle_pub_.publish(robot_spindle_msg_);
	}

protected:

	// action servers
	MaterialLoadServerPtr material_load_server_ptr_;
	MaterialUnloadServerPtr material_unload_server_ptr_;

	// action clients
	MoveArmClientPtr move_arm_client_ptr_;
	MovePickupClientPtr arm_pickup_client_ptr_;
	MovePlaceClientPtr arm_place_client_ptr_;
	CncOpenDoorClientPtr open_door_client_ptr_;
	CncCloseDoorClientPtr close_door_client_ptr_;
	CncOpenChuckClientPtr open_chuck_client_ptr_;
	CncCloseChuckClientPtr close_chuck_client_ptr_;

	// topic publishers (ros bridge components wait for these topics)
	ros::Publisher robot_states_pub_;
	ros::Publisher robot_spindle_pub_;

	// robot state messages
	mtconnect_msgs::RobotStates robot_state_msg_;
	mtconnect_msgs::RobotSpindle robot_spindle_msg_;

	// timers
	ros::Timer publish_timer_;

	// arm group, pick, place and joint info members
	std::string arm_group_;
	arm_navigation_msgs::MoveArmGoal move_arm_goal_;
	move_arm_utils::PickupGoalInfo material_load_pickup_goal_;
	move_arm_utils::PlaceGoalInfo material_load_place_goal_;
	move_arm_utils::PickupGoalInfo material_unload_pickup_goal_;
	move_arm_utils::PlaceGoalInfo material_unload_place_goal_;
	move_arm_utils::JointStateInfo joint_home_pos_;
	move_arm_utils::JointStateInfo joint_wait_pos_;

};

int main(int argc,char** argv)
{
	ros::init(argc,argv,"material_hanlding_server_test");

	SimpleMaterialHandlingServer material_handling_server;
	material_handling_server.run();
	return 0;
}