Commit 804b4ad3 authored by Yann Garcia's avatar Yann Garcia
Browse files

Big fixed in LIB_NG_NAS_CommonFunctions_ext.cc; Add ImsMonitorHttpPort support

parent d7975bc7
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
#include "rijndael.hh"
#include "opc.hh"

namespace LIB__NG__NAS__CommonFunctions {
namespace Lib__NG__NAS__CommonFunctions {

  static uint8_t OP[16] = {0}; // FIXME FSCOM To be refined. This is a Q&D implementation

@@ -319,4 +319,4 @@ namespace LIB__NG__NAS__CommonFunctions {
    return 0;
  }

} // End of namespace LIB__NG__NAS__Functions
} // End of namespace Lib__NG__NAS__CommonFunctions
+12 −6
Original line number Diff line number Diff line
#include "ImsMonitorHttpPort.hh"

#include "http_layer_factory.hh"
#include "ims_http_monitor_layer.hh"
#include "http_codec_emtel.hh"
#include "loggers.hh"

namespace AtsIms5gIot__TestSystem {
@@ -45,21 +49,23 @@ namespace AtsIms5gIot__TestSystem {
  {
    loggers::get_instance().log(">>> ImsMonitorHttpPort::user_map: %s", system_port);
    // Build layer stack
    /*params::iterator it = _cfg_params.find(std::string("params"));
    params::iterator it = _cfg_params.find(std::string("params"));
    if (it != _cfg_params.end()) {
      loggers::get_instance().log("ImsMonitorHttpPort::user_map: %s", it->second.c_str());
      // Setup parameters
      params::convert(_layer_params, it->second); // TODO This _layer_params seems to be useless
      // Create layer
      _layer = layer_stack_builder::get_instance()->create_layer_stack(it->second.c_str());
      if (static_cast<diameter_layer *>(_layer) == nullptr) {
      if (static_cast<ims_http_monitor_layer*>(_layer) == nullptr) {
        loggers::get_instance().error("ImsMonitorHttpPort::user_map: Invalid stack configuration: %s", it->second.c_str());
      }
      static_cast<diameter_layer *>(_layer)->add_upper_port(this);

    } else {*/
      if (!static_cast<ims_http_monitor_layer*>(_layer)->set_codec(new http_codec_emtel())) {
        loggers::get_instance().error("ImsMonitorHttpPort::user_map: Null codec");
      }
      static_cast<ims_http_monitor_layer *>(_layer)->add_upper_port(this);
    } else {
      loggers::get_instance().error("ImsMonitorHttpPort::user_map: No layers defined in configuration file");
    /*}*/
    }
  } // End of user_map method

  void ImsMonitorHttpPort::user_unmap(const char * system_port)
+143 −0
Original line number Diff line number Diff line
#include "LibHttp_TypesAndValues.hh"

#include "codec_stack_builder.hh"
#include "ims_http_monitor_layer_factory.hh"

#include "loggers.hh"

#include "converter.hh"

using namespace std; // Required for isnan()
#include "AtsIms5gIot_TestSystem.hh"
#include "LibHttp_TypesAndValues.hh"

ims_http_monitor_layer::ims_http_monitor_layer(const std::string& p_type, const std::string& param)
  : t_layer<AtsIms5gIot__TestSystem::ImsMonitorHttpPort>(p_type), _params(), _codec(nullptr), _device_mode{false} {
  loggers::get_instance().log(">>> ims_http_monitor_layer::ims_http_monitor_layer: '%s', %s", to_string().c_str(), param.c_str());
  // Setup parameters
  params::convert(_params, param);

  params::const_iterator it = _params.find(params::method);
  if (it == _params.cend()) {
    _params[params::method] = "POST";
  }
  it = _params.find(params::uri);
  if (it == _params.cend()) {
    _params[params::uri] = "/";
  }
  it = _params.find(params::host);
  if (it == _params.cend()) {
    _params[params::host] = "127.0.0.1";
  }
  it = _params.find(params::content_type);
  if (it == _params.cend()) {
    _params[params::content_type] = "application/text";
  }
}

bool ims_http_monitor_layer::set_codec(http_codec *p_codec) { 
  loggers::get_instance().log(">>> ims_http_monitor_layer::set_codec: %p", (void*)p_codec);

  // Sanity check that
  if (p_codec == nullptr) { 
    loggers::get_instance().error("ims_http_monitor_layer::set_codec: Wrong parameter");
    return false;
  }

  _codec = p_codec;
  params::const_iterator it = _params.find(params::codecs);
  if (it != _params.cend()) {
    _codec->set_payload_codecs(it->second);
  }

  return true;
}

void ims_http_monitor_layer::sendMsg(const LibHttp__TypesAndValues::HttpMessage &p_http_message, params &p_param) {
  loggers::get_instance().log_msg(">>> ims_http_monitor_layer::sendMsg: ", p_http_message);

  // Encode HttpMessage
  OCTETSTRING data;
  _codec->encode(p_http_message, data);
  send_data(data, _params);
}

void ims_http_monitor_layer::send_data(OCTETSTRING &data, params &params) {
  loggers::get_instance().log_msg(">>> ims_http_monitor_layer::send_data: ", data);

  if (_device_mode) { // Need to build an HTTP packet
    loggers::get_instance().log("ims_http_monitor_layer::send_data: Build http layer");
    TTCN_Buffer buffer;
    buffer.put_cs(_params[params::method].c_str());
    buffer.put_c(' ');
    buffer.put_cs(_params[params::uri].c_str());
    buffer.put_cs(" HTTP/1.1\r\n");
    buffer.put_cs("Host: ");
    buffer.put_cs(_params[params::host].c_str());
    buffer.put_cs("\r\n");
    buffer.put_cs("Content-type: ");
    buffer.put_cs(_params[params::content_type].c_str());
    buffer.put_cs("\r\n");
    buffer.put_cs("Content-length: ");
    buffer.put_cs(static_cast<const char *>(int2str(data.lengthof() + 2 /*Stand for the last CRLF*/)));
    buffer.put_cs("\r\n\r\n");
    buffer.put_os(data);
    buffer.put_cs("\r\n");
    data = OCTETSTRING(buffer.get_len(), buffer.get_data());
  }

  loggers::get_instance().log_msg("ims_http_monitor_layer::send_data: ", data);
  send_to_all_layers(data, params);
}

void ims_http_monitor_layer::receive_data(OCTETSTRING &data, params &params) {
  loggers::get_instance().log_msg(">>> ims_http_monitor_layer::receive_data: ", data);

  // Decode HTTP message
  LibHttp__TypesAndValues::HttpMessage http_message;
  int ret_code = _codec->decode(data, http_message, &params);
  if (ret_code == -1) {
    loggers::get_instance().warning("ims_http_monitor_layer::receive_data: Failed to decode data");
    return;
  } else if (ret_code == -2) { // Need to wait for next data
    loggers::get_instance().log("ims_http_monitor_layer::receive_data: Set Buffurizing to 1");
    params.insert(std::make_pair<std::string, std::string>("Buffurizing", "1"));
    return;
  }
  if (_device_mode) {
    OCTETSTRING os;
    if (http_message.ischosen(LibHttp__TypesAndValues::HttpMessage::ALT_response)) {
      if (http_message.response().body().ispresent()) {
        LibHttp__MessageBodyTypes::HttpMessageBody &body =
          static_cast<LibHttp__MessageBodyTypes::HttpMessageBody &>(*http_message.response().body().get_opt_value());
        if (body.ischosen(LibHttp__MessageBodyTypes::HttpMessageBody::ALT_binary__body)) {
          LibHttp__BinaryMessageBodyTypes::BinaryBody &binary = body.binary__body();
          if (binary.ischosen(LibHttp__BinaryMessageBodyTypes::BinaryBody::ALT_raw)) {
            os = binary.raw();
          } else {
            loggers::get_instance().warning("ims_http_monitor_layer::receive_data: A raw binary payload is expected");
          }
        } else if (body.ischosen(LibHttp__MessageBodyTypes::HttpMessageBody::ALT_html__body)) {
          // TODO To be done
          loggers::get_instance().warning("ims_http_monitor_layer::receive_data: Not implemented yet");
        } else if (body.ischosen(LibHttp__MessageBodyTypes::HttpMessageBody::ALT_xml__body)) {
          // TODO To be done
          loggers::get_instance().warning("ims_http_monitor_layer::receive_data: Not implemented yet");
        } else if (body.ischosen(LibHttp__MessageBodyTypes::HttpMessageBody::ALT_text__body)) {
          // TODO To be done
          loggers::get_instance().warning("ims_http_monitor_layer::receive_data: Not implemented yet");
        }
        receive_to_all_layers(os, params);
      } else {
        loggers::get_instance().warning("ims_http_monitor_layer::receive_data: No body present");
      }
    } else {
      loggers::get_instance().warning("ims_http_monitor_layer::receive_data: An HTTP response is expected");
    }
  } else {
    // Pass it to the ports
    to_all_upper_ports(http_message, params);
  }
}

ims_http_monitor_layer_factory ims_http_monitor_layer_factory::_f;
+91 −0
Original line number Diff line number Diff line
/*!
 * \file      ims_http_monitor_layer.hh
 * \brief     Header file for ITS HTTP protocol layer.
 * \author    ETSI STF549
 * \copyright ETSI Copyright Notification
 *            No part may be reproduced except as authorized by written permission.
 *            The copyright and the foregoing restriction extend to reproduction in all media.
 *            All rights reserved.
 * \version   0.1
 */
#pragma once

#include <memory>

#include "t_layer.hh"

#include "http_codec.hh"

namespace AtsIms5gIot__TestSystem {
  class ImsMonitorHttpPort;
}

namespace LibHttp__TypesAndValues {
  class HttpMessage; //! Forward declaration of TITAN class
}

class OCTETSTRING; //! Forward declaration of TITAN class

/*!
 * \class ims_http_monitor_layer
 * \brief  This class provides a factory class to create an tcp_layer class instance
 */
class ims_http_monitor_layer : public t_layer<AtsIms5gIot__TestSystem::ImsMonitorHttpPort> {
  params _params;
  http_codec *_codec;
  bool _device_mode;

public: //! \publicsection
  /*!
   * \brief Specialised constructor
   *        Create a new instance of the ims_http_monitor_layer class
   * \param[in] p_type \todo
   * \param[in] p_param \todo
   */
  ims_http_monitor_layer() : t_layer(), _params(), _device_mode{false} { };
  /*!
   * \brief Specialised constructor
   *        Create a new instance of the ims_http_monitor_layer class
   * \param[in] p_type \todo
   * \param[in] p_param \todo
   */
  ims_http_monitor_layer(const std::string& p_type, const std::string& p_param);
  /*!
   * \brief Default destructor
   */
  virtual ~ims_http_monitor_layer() { if (_codec != nullptr) { delete _codec;} };

  /*!
   * \fn bool set_codec(http_codec *p_codec);
   * \brief Set the specialized HTTP codec to use
   * \param[in] p_codec Pointer to the specialized codec
   * \return true on success, false if the pointer is NULL
   */
  bool set_codec(http_codec *p_codec);

  /*!
   * \fn void sendMsg(const LibHttp__TypesAndValues::HttpMessage& p_http_message, params& p_param);
   * \brief Send HTTP message to the lower layers
   * \param[in] p_http_message The GeoNetworking message to be sent
   * \param[in] p_params Some parameters to overwrite default value of the lower layers parameters
   */
  void sendMsg(const LibHttp__TypesAndValues::HttpMessage& p_http_message, params& p_param);
  
  /*!
   * \virtual
   * \fn void send_data(OCTETSTRING& data, params& params);
   * \brief Send bytes formated data to the lower layers
   * \param[in] p_data The data to be sent
   * \param[in] p_params Some parameters to overwrite default value of the lower layers parameters
   */
  virtual void send_data(OCTETSTRING& data, params& params);
  /*!
   * \virtual
   * \fn void receive_data(OCTETSTRING& data, params& params);
   * \brief Receive bytes formated data from the lower layers
   * \param[in] p_data The bytes formated data received
   * \param[in] p_params Some lower layers parameters values when data was received
   */
  virtual void receive_data(OCTETSTRING& data, params& info);
}; // End of class ims_http_monitor_layer
+42 −0
Original line number Diff line number Diff line
/*!
 * \file      ims_http_monitor_layer_factory.hh
 * \brief     Header file for ITS Http protocol layer factory.
 * \author    ETSI STF525
 * \copyright ETSI Copyright Notification
 *            No part may be reproduced except as authorized by written permission.
 *            The copyright and the foregoing restriction extend to reproduction in all media.
 *            All rights reserved.
 * \version   0.1
 */
#pragma once

#include "layer_stack_builder.hh"

#include "ims_http_monitor_layer.hh"

/*!
 * \class ims_http_monitor_layer_factory
 * \brief  This class provides a factory class to create an ims_http_monitor_layer class instance
 */
class ims_http_monitor_layer_factory : public layer_factory {
  static ims_http_monitor_layer_factory _f; //! Reference to the unique instance of this class
public:                         //! \publicsection
  /*!
   * \brief Default constructor
   *        Create a new instance of the ims_http_monitor_layer_factory class
   * \remark The HTTP layer identifier is HTTP
   */
  ims_http_monitor_layer_factory() {
    // Register factory
    layer_stack_builder::register_layer_factory("IMS_HTTP_MONITOR", this);
  };
  /*!
   * \fn layer* create_layer(const std::string&  type, const std::string&  param);
   * \brief  Create the layers stack based on the provided layers stack description
   * \param[in] p_type The provided layers stack description
   * \param[in] p_params Optional parameters
   * \return 0 on success, -1 otherwise
   * \inline
   */
  inline virtual layer *create_layer(const std::string& p_type, const std::string& p_param) { return new ims_http_monitor_layer(p_type, p_param); };
}; // End of class ims_http_monitor_layer_factory
Loading