Commit 6166742d authored by Yann Garcia's avatar Yann Garcia
Browse files

Merging oneM2M changes

parent cc592966
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -60,7 +60,11 @@ public: //! \publicsection

  static const std::string& codecs;             //! List of codecs to use for HTTP application layers
  static const std::string& serialization;      //! Message serialization format

  static const std::string& protocol_binding;   //! oneM2M protocol binding
  static const std::string& type;               //! oneM2M message type (request/response)
  static const std::string& statuscode;         //! oneM2M status code in response
  static const std::string& responseStatusCode; //! oneM2M response status code (HTTP)
  static const std::string& statustext;         //! oneM2M status text if any (HTTP)
  /*!
   * \brief Default constructor
   *        Create a new instance of the params class
+36 −31
Original line number Diff line number Diff line
@@ -54,6 +54,11 @@ const std::string& params::headers = std::string("headers");

const std::string& params::codecs             = std::string("codecs");
const std::string& params::serialization      = std::string("serialization");
const std::string& params::protocol_binding   = std::string("protocol_binding");
const std::string& params::type               = std::string("type");
const std::string& params::statuscode         = std::string("statuscode");
const std::string& params::responseStatusCode = std::string("responseStatusCode");
const std::string& params::statustext         = std::string("statustext");

void params::convert(params &p_param, const std::string p_parameters) {
  // Sanity checks
+34 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ int http_codec::encode(const LibHttp__TypesAndValues::HttpMessage &msg, OCTETSTR
  loggers::get_instance().log(">>> http_codec::encode: %p", this);

  TTCN_EncDec::clear_error();
  TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_DEFAULT);
  TTCN_Buffer encoding_buffer;

  _ec.reset();
@@ -42,8 +43,10 @@ int http_codec::decode(const OCTETSTRING &data, LibHttp__TypesAndValues::HttpMes
  loggers::get_instance().log_msg(">>> http_codec::decode: data=", data);

  TTCN_EncDec::clear_error();
  TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_DEFAULT);
  TTCN_Buffer decoding_buffer;

  loggers::get_instance().log("http_codec::decode: _initial_content_length=%d", _initial_content_length);
  if (_initial_content_length != 0) { // Check if the data is a new fragment of the response 
    loggers::get_instance().warning("http_codec::decode: Need to bufferize and wait for all fragments received");
    _bufferized_buffers.push_back(data);
@@ -103,7 +106,7 @@ int http_codec::decode(const OCTETSTRING &data, LibHttp__TypesAndValues::HttpMes
      std::smatch                          m = *begin;
      loggers::get_instance().log("http_codec::decode: Process response: %d", m.size());
      if (m.size() != 5) {
        loggers::get_instance().warning("http_codec::decode: Unsupported tag");
        loggers::get_instance().error("http_codec::decode: Unsupported response tag");
        return -1;
      }
      response.version__major() = std::stoi(m[1].str().c_str());
@@ -115,6 +118,7 @@ int http_codec::decode(const OCTETSTRING &data, LibHttp__TypesAndValues::HttpMes
      decode_headers(decoding_buffer, headers, content_type);
      loggers::get_instance().log("http_codec::decode: _dc.length=%d", _dc.length);
      loggers::get_instance().log("http_codec::decode: decoding_buffer.get_len()=%d", decoding_buffer.get_len());
      loggers::get_instance().log("http_codec::decode: decoding_buffer.get_pos()=%d", decoding_buffer.get_pos());
      if (_dc.length > decoding_buffer.get_len()) { // HTTP response is fragmented
        // Need to bufferize the first packet and wait for the other fragments tp be received
        loggers::get_instance().warning("http_codec::decode: Need to bufferize the first packet and wait for the other fragments to be received");
@@ -126,6 +130,17 @@ int http_codec::decode(const OCTETSTRING &data, LibHttp__TypesAndValues::HttpMes
        _current_content_length += data.lengthof();
        loggers::get_instance().log("http_codec::decode: _bufferized_buffers size: %d - _current_content_length: %d", _bufferized_buffers.size(), _current_content_length);
        return -2;
      } else if ((decoding_buffer.get_pos() == decoding_buffer.get_len()) && (_dc.length > 0)/*no more byte in to decode in decoding_buffer and Coontent-Length > 0*/) { // Missing body
        // Need to bufferize the first packet and wait for the other fragments tp be received
        loggers::get_instance().warning("http_codec::decode: Body not recieved");
        // Set counters
        loggers::get_instance().log("http_codec::decode: Set bufferization counters");
        _initial_content_length = _dc.length;
        _current_content_length = 0;
        _bufferized_buffers.push_back(data);
        _current_content_length += data.lengthof();
        loggers::get_instance().log("http_codec::decode: _bufferized_buffers size: %d - _current_content_length: %d, current decoding pos: %d", _bufferized_buffers.size(), _current_content_length, decoding_buffer.get_pos());
        return -2;
      } else {
        // Force reset counters
        loggers::get_instance().log("http_codec::decode: Force reset bufferization counters");
@@ -167,8 +182,13 @@ int http_codec::decode(const OCTETSTRING &data, LibHttp__TypesAndValues::HttpMes
      std::sregex_iterator                begin(str.cbegin(), str.cend(), rgx);
      std::smatch                         m = *begin;
      if (m.size() != 5) {
        loggers::get_instance().error("http_codec::decode: Unsupported tag");
        loggers::get_instance().error("http_codec::decode: Unsupported request tag");
        return -1;
        // loggers::get_instance().warning("http_codec::decode: Unsupported tag");
        // LibHttp__MessageBodyTypes::HttpMessageBody body;
        // body.binary__body().raw() = data;
        // response.body() = OPTIONAL<LibHttp__MessageBodyTypes::HttpMessageBody>(body);
        // return 0;
      }
      request.method()         = CHARSTRING(m[1].str().c_str());
      request.uri()            = CHARSTRING(m[2].str().c_str());
@@ -179,6 +199,7 @@ int http_codec::decode(const OCTETSTRING &data, LibHttp__TypesAndValues::HttpMes
      decode_headers(decoding_buffer, headers, content_type);
      loggers::get_instance().log("http_codec::decode (request): _dc.length=%d", _dc.length);
      loggers::get_instance().log("http_codec::decode (request): decoding_buffer.get_len()=%d", decoding_buffer.get_len());
      loggers::get_instance().log("http_codec::decode (request): decoding_buffer.get_pos()=%d", decoding_buffer.get_pos());
      if (_dc.length > decoding_buffer.get_len()) { // HTTP response is fragmented
        // Need to bufferize the first packet and wait for the other fragments tp be received
        loggers::get_instance().warning("http_codec::decode (request): Need to bufferize the first packet and wait for the other fragments to be received");
@@ -190,6 +211,17 @@ int http_codec::decode(const OCTETSTRING &data, LibHttp__TypesAndValues::HttpMes
        _current_content_length += data.lengthof();
        loggers::get_instance().log("http_codec::decode (request): _bufferized_buffers size: %d - _current_content_length: %d", _bufferized_buffers.size(), _current_content_length);
        return -2;
      } else if ((decoding_buffer.get_pos() == decoding_buffer.get_len()) && (_dc.length > 0)/*no more byte in to decode in decoding_buffer and Coontent-Length > 0*/) { // Missing body
        // Need to bufferize the first packet and wait for the other fragments tp be received
        loggers::get_instance().warning("http_codec::decode (request): Body not recieved");
        // Set counters
        loggers::get_instance().log("http_codec::decode (request): Set bufferization counters");
        _initial_content_length = _dc.length;
        _current_content_length = 0;
        _bufferized_buffers.push_back(data);
        _current_content_length += data.lengthof();
        loggers::get_instance().log("http_codec::decode (request): _bufferized_buffers size: %d - _current_content_length: %d, current decoding pos: %d", _bufferized_buffers.size(), _current_content_length, decoding_buffer.get_pos());
        return -2;
      } else {
        // Force reset counters
        loggers::get_instance().log("http_codec::decode (request): Force reset bufferization counters");
+116 −14
Original line number Diff line number Diff line
@@ -33,6 +33,17 @@ http_layer::http_layer(const std::string& p_type, const std::string& param)
  if (it == _params.cend()) {
    _params[params::content_type] = "application/text";
  }
  it = _params.find(params::headers);
  if (it != _params.cend()) {
    // Change ';' into '\r\n'
    const std::string from(";");
    const std::string to("\r\n");
    _params[params::headers].assign(converter::get_instance().replace(it->second, from, to));
  }
  it = _params.find(params::device_mode);
  if (it != _params.cend()) {
    _device_mode = (1 == converter::get_instance().string_to_int(it->second));
  }
}

bool http_layer::set_codec(http_codec *p_codec) { 
@@ -65,23 +76,71 @@ void http_layer::sendMsg(const LibHttp__TypesAndValues::HttpMessage &p_http_mess
void http_layer::send_data(OCTETSTRING &data, params &params) {
  loggers::get_instance().log_msg(">>> http_layer::send_data: ", data);

  loggers::get_instance().log("http_layer::send_data: _params: ");
  _params.log();
  loggers::get_instance().log("http_layer::send_data: params: ");
  params.log();

  if (_device_mode) { // Need to build an HTTP packet
    loggers::get_instance().log("http_layer::send_data: Build http layer");
    TTCN_Buffer buffer;

    params::const_iterator it = params.find(params::method);
    if (it != params.cend()) {
      buffer.put_cs(params[params::method].c_str());
    } else {
      buffer.put_cs(_params[params::method].c_str());
    }
    buffer.put_c(' ');
    if ((it = params.find(params::uri)) != params.cend()) {
      buffer.put_cs(params[params::uri].c_str());
    } else {
      buffer.put_cs(_params[params::uri].c_str());
    }
    buffer.put_cs(" HTTP/1.1\r\n");
    buffer.put_cs("Host: ");
    if ((it = params.find(params::host)) != params.cend()) {
      buffer.put_cs(params[params::host].c_str());
    } else {
      buffer.put_cs(_params[params::host].c_str());
    }
    buffer.put_cs("\r\n");
    buffer.put_cs("Content-type: ");
    if ((it = params.find(params::content_type)) != params.cend()) {
      buffer.put_cs(params[params::content_type].c_str());
    } else {
      buffer.put_cs(_params[params::content_type].c_str());
    }
    buffer.put_cs("\r\n");
    if ((it = params.find(params::headers)) != _params.cend()) {
      buffer.put_cs(params[params::headers].c_str());
    } else if ((it = _params.find(params::headers)) != _params.cend()) {
      buffer.put_cs(_params[params::headers].c_str());
    }
    buffer.put_cs("\r\n");
    buffer.put_cs("Connection: keep-alive");
    buffer.put_cs("\r\n");    
    buffer.put_cs("Cache-Control: no-cache"); // FIXME FSCOM Use params parameter.
    buffer.put_cs("\r\n");
    buffer.put_cs("Server: Titan-Test-System-Framework/1.0"); // FIXME FSCOM Use params parameter.
    buffer.put_cs("\r\n");    
    buffer.put_cs("User-Agent: Titan-Test-System-Framework/1.0");
    buffer.put_cs("\r\n");    
    std::time_t time = std::time({});
    char timeString[std::size("yyyy-mm-ddThh:mm:ssZ")];
    std::strftime(std::data(timeString), std::size(timeString), "%FT%TZ", std::gmtime(&time));
    buffer.put_cs("Date: ");
    buffer.put_cs(timeString);
    buffer.put_cs("\r\n");
    if (data.lengthof() != 0) {
      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);
    } else {
      // Omit Content-length header for empty body
      buffer.put_cs("\r\n");
    }
    buffer.put_cs("\r\n");
    data = OCTETSTRING(buffer.get_len(), buffer.get_data());
  }
@@ -95,6 +154,9 @@ void http_layer::receive_data(OCTETSTRING &data, params &params) {

  // Decode HTTP message
  LibHttp__TypesAndValues::HttpMessage http_message;
  if (_codec == nullptr) {
    loggers::get_instance().error("http_layer::receive_data: Create codec");
  }
  int ret_code = _codec->decode(data, http_message, &params);
  if (ret_code == -1) {
    loggers::get_instance().warning("http_layer::receive_data: Failed to decode data");
@@ -104,7 +166,9 @@ void http_layer::receive_data(OCTETSTRING &data, params &params) {
    params.insert(std::make_pair<std::string, std::string>("Buffurizing", "1"));
    return;
  }

  if (_device_mode) {
    loggers::get_instance().log("http_layer::receive_data: Device mode set");
    OCTETSTRING os;
    if (http_message.ischosen(LibHttp__TypesAndValues::HttpMessage::ALT_response)) {
      if (http_message.response().body().ispresent()) {
@@ -114,19 +178,57 @@ void http_layer::receive_data(OCTETSTRING &data, params &params) {
          LibHttp__BinaryMessageBodyTypes::BinaryBody &binary = body.binary__body();
          if (binary.ischosen(LibHttp__BinaryMessageBodyTypes::BinaryBody::ALT_raw)) {
            os = binary.raw();
            params.insert(std::pair<std::string, std::string>("serialization", "binary"));
          } else {
            loggers::get_instance().warning("http_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("http_layer::receive_data: Not implemented yet");
          os = char2oct(body.html__body());
          params.insert(std::pair<std::string, std::string>("serialization", "html"));
        } else if (body.ischosen(LibHttp__MessageBodyTypes::HttpMessageBody::ALT_json__body)) {
          LibHttp__JsonMessageBodyTypes::JsonBody &json = body.json__body();
          if (json.ischosen(LibHttp__JsonMessageBodyTypes::JsonBody::ALT_raw)) {
            os = unichar2oct(json.raw());
            params.insert(std::pair<std::string, std::string>("serialization", "json"));
          } else {
            loggers::get_instance().warning("http_layer::receive_data: A raw JSON payload is expected");
          }
        } else if (body.ischosen(LibHttp__MessageBodyTypes::HttpMessageBody::ALT_xml__body)) {
          // TODO To be done
          loggers::get_instance().warning("http_layer::receive_data: Not implemented yet");
          LibHttp__XmlMessageBodyTypes::XmlBodyMsg &xml = body.xml__body().msg();
          if (xml.ischosen(LibHttp__XmlMessageBodyTypes::XmlBodyMsg::ALT_raw)) {
            os = unichar2oct(xml.raw());
            params.insert(std::pair<std::string, std::string>("serialization", "xml"));
          } else {
            loggers::get_instance().warning("http_layer::receive_data: A raw XML payload is expected");
          }
        } else if (body.ischosen(LibHttp__MessageBodyTypes::HttpMessageBody::ALT_text__body)) {
          // TODO To be done
          loggers::get_instance().warning("http_layer::receive_data: Not implemented yet");
          os = char2oct(body.text__body());
          params.insert(std::pair<std::string, std::string>("serialization", "txt"));
        }
        // Add additional message information
        params.insert(std::pair<std::string, std::string>(params::type, "response"));
        params.insert(std::pair<std::string, std::string>(params::protocol_binding, "HTTP"));
        params.insert(std::pair<std::string, std::string>(params::statuscode, std::to_string(http_message.response().statuscode())));
        params.insert(std::pair<std::string, std::string>(params::statustext, http_message.response().statustext()));
        for (int i = 0; i < http_message.response().header().lengthof(); i++) {
          const OPTIONAL<LibHttp__TypesAndValues::charstring__list> &o = http_message.response().header()[i].header__value();
          if (o.ispresent()) {
            const LibHttp__TypesAndValues::charstring__list &v = dynamic_cast<const OPTIONAL<LibHttp__TypesAndValues::charstring__list> &>(o);
            if (v.lengthof() == 0) {
              params.insert(std::pair<std::string, std::string>(static_cast<const char*>(http_message.response().header()[i].header__name()), ""));
            } else if (v.lengthof() == 1) {
              params.insert(std::pair<std::string, std::string>(static_cast<const char*>(http_message.response().header()[i].header__name()), v[0]));
            } else {
              std::ostringstream oss;
              int j = 0;
              for ( ; j < v.lengthof() - 1; j++) {
                oss << static_cast<const char*>(v[j]) << ";";
              } // End of 'for' statement
              oss << static_cast<const char*>(v[j]) << ";";
              params.insert(std::pair<std::string, std::string>(static_cast<const char*>(http_message.response().header()[i].header__name()), oss.str()));
            }
          }
        } // End of 'for' statement
        receive_to_all_layers(os, params);
      } else {
        loggers::get_instance().warning("http_layer::receive_data: No body present");
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ class OCTETSTRING; //! Forward declaration of TITAN class
 * \brief  This class provides a factory class to create an tcp_layer class instance
 */
class http_layer : public t_layer<LibHttp__TestSystem::HttpPort> {
protected: //! \protectedsection
  params _params;
  http_codec *_codec;
  bool _device_mode;
Loading