#pragma once
#include "sip_codec_request.hh"
class Base_Type;
class TTCN_Typedescriptor_t;
class TTCN_Buffer;
namespace LibSip__SIPTypesAndValues {
class INVITE__Request;
}
class sip_codec_invite_request: public codec_gen <
LibSip__SIPTypesAndValues::INVITE__Request,
LibSip__SIPTypesAndValues::INVITE__Request>
{
sip_codec_request _codec;
public:
explicit sip_codec_invite_request() : codec_gen<LibSip__SIPTypesAndValues::INVITE__Request, LibSip__SIPTypesAndValues::INVITE__Request>(), _codec() { };
virtual ~sip_codec_invite_request() { };
virtual int encode (const LibSip__SIPTypesAndValues::INVITE__Request& msg, OCTETSTRING& data);
virtual int decode (const OCTETSTRING& data, LibSip__SIPTypesAndValues::INVITE__Request& msg, params* p_params = NULL);
}; // End of class sip_codec_invite_request
#include "LibSip_SIPTypesAndValues.hh"
#include "LibSip_Common.hh"
#include "sip_codec_message_body.hh"
#include "loggers.hh"
#include "converter.hh"
#include "urn_ietf_params_xml_ns_pidf.hh"
#ifdef WIN32
#undef osip_malloc
#undef osip_free
#define osip_malloc(S) malloc(S)
#define osip_free(P) { if (P!=NULL) { free(P);} }
#endif
int sip_codec_message_body::encode (const LibSip__MessageBodyTypes::MessageBody& msg, OCTETSTRING& data)
{
loggers::get_instance().log_msg(">>> sip_codec_message_body::encode: ", msg);
TRACE_INITIALIZE(TRACE_LEVEL7, NULL);
OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, ">>> sip_codec_request::encode\n"));
if (msg.ischosen(LibSip__MessageBodyTypes::MessageBody::ALT_sdpMessageBody)) {
const LibSip__SDPTypes::SDP__Message& sdp = msg.sdpMessageBody();
sdp_message_t* sdp_body = nullptr;
if (encode_sdp(sdp, &sdp_body) == -1) {
loggers::get_instance().warning("sip_codec_message_body::encode: Failed to encode SDP message");
return -1;
}
char* buff = nullptr;
::sdp_message_to_str(sdp_body, &buff);
if (buff != nullptr) {
data = char2oct(CHARSTRING(buff));
osip_free(buff);
sdp_message_free(sdp_body);
}
} else if (msg.ischosen(LibSip__MessageBodyTypes::MessageBody::ALT_textplain)) {
data = char2oct(msg.textplain());
} else {
loggers::get_instance().warning("sip_codec_message_body::encode: Unsupported variant");
return -1;
}
loggers::get_instance().log_msg("<<< sip_codec_message_body::encode: ", data);
return 0;
}
int sip_codec_message_body::decode (const OCTETSTRING& data, LibSip__MessageBodyTypes::MessageBody& msg, params* p_params)
{
loggers::get_instance().log(">>> sip_codec_message_body::decode");
TRACE_INITIALIZE(TRACE_LEVEL7, NULL);
OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, ">>> sip_codec_request::decode\n"));
loggers::get_instance().error("sip_codec_message_body::decode: Not implemented yet");
return -1;
}
int sip_codec_message_body::encode_message_body(const LibSip__MessageBodyTypes::MessageBody& p_message_body, osip_message_t* p_sip_message)
{ // TODO Rename into encode_message
loggers::get_instance().log_msg(">>> sip_codec_message_body::encode_message_body: ", p_message_body);
osip_content_length* content_length = ::osip_message_get_content_length(p_sip_message);
loggers::get_instance().log("sip_codec_message_body::encode_message_body: content_length= %s", content_length->value);
if (p_message_body.ischosen(LibSip__MessageBodyTypes::MessageBody::ALT_sdpMessageBody)) {
const LibSip__SDPTypes::SDP__Message& sdp = p_message_body.sdpMessageBody();
sdp_message_t* sdp_body = nullptr;
if (encode_sdp(sdp, &sdp_body) == -1) {
loggers::get_instance().warning("sip_codec_message_body::encode_message_body: Failed to decode SDP message");
return -1;
}
char* buff = nullptr;
::sdp_message_to_str(sdp_body, &buff);
if (buff != nullptr) {
::osip_message_set_body(p_sip_message, buff, strlen(buff));
osip_free(buff);
sdp_message_free(sdp_body);
}
} else if (p_message_body.ischosen(LibSip__MessageBodyTypes::MessageBody::ALT_textplain)) {
const CHARSTRING& text = p_message_body.textplain();
::osip_message_set_body(p_sip_message, static_cast<const char*>(text), text.lengthof());
} else if (p_message_body.ischosen(LibSip__MessageBodyTypes::MessageBody::ALT_mimeMessageBody)) {
::osip_message_set_mime_version(p_sip_message, "2.0");
const LibSip__MessageBodyTypes::MIME__Message& mime = p_message_body.mimeMessageBody();
const LibSip__MessageBodyTypes::MimeEncapsulatedList& l = mime.mimeEncapsulatedList();
int pos = 0;
while (pos < l.lengthof()) {
const LibSip__MessageBodyTypes::MIME__Encapsulated__Part& p = l[pos];
loggers::get_instance().log_msg("sip_codec_message_body::encode_message_body: p: ", p);
const LibSip__MessageBodyTypes::MIME__Encapsulated__Parts& ps = p.mime__encapsulated__part();
if (ps.ischosen(LibSip__MessageBodyTypes::MIME__Encapsulated__Parts::ALT_sdpMessageBody)) {
const LibSip__SDPTypes::SDP__Message& sdp = ps.sdpMessageBody();
sdp_message_t* sdp_body = nullptr;
if (encode_sdp(sdp, &sdp_body) == -1) {
loggers::get_instance().warning("sip_codec_message_body::encode_message_body: Failed to encode SDP message");
return -1;
}
char* buff = nullptr;
::sdp_message_to_str(sdp_body, &buff);
if (buff != nullptr) {
loggers::get_instance().log("sip_codec_message_body::encode_message_body: sdp encoded value: %s", buff);
loggers::get_instance().log("sip_codec_message_body::encode_message_body: body list size: %d", ::osip_list_size(&p_sip_message->bodies));
if (::osip_message_set_body(p_sip_message, buff, strlen(buff)) != 0) {
loggers::get_instance().warning("sip_codec_message_body::encode_message_body: Failed to encode SDP message");
osip_free(buff);
sdp_message_free(sdp_body);
return -1;
}
loggers::get_instance().log("sip_codec_message_body::encode_message_body: new body list size: %d", ::osip_list_size(&p_sip_message->bodies));
osip_free(buff);
sdp_message_free(sdp_body);
// Retrive the new created body and add content type
osip_body_t* body = nullptr;
if (::osip_message_get_body(p_sip_message, ::osip_list_size(&p_sip_message->bodies) - 1, &body) != ::osip_list_size(&p_sip_message->bodies) - 1) {
loggers::get_instance().warning("sip_codec_message_body::encode_message_body: Failed to set XML body content-type");
return -1;
}
const char* ct = static_cast<const char*>(p.content__type());
loggers::get_instance().log("sip_codec_message_body::encode_message_body: content-type: %s", ct);
if (ct != nullptr) {
::osip_body_set_contenttype(body, ct);
} else { // Use a default value
::osip_body_set_contenttype(body, "application/sdp");
}
}
} else if (ps.ischosen(LibSip__MessageBodyTypes::MIME__Encapsulated__Parts::ALT_xmlBody)) {
const LibSip__XMLTypes::XmlBody& xml = ps.xmlBody();
osip_body_t* body;
if (encode_xml(xml, &body) == -1) {
loggers::get_instance().warning("sip_codec_message_body::encode_message_body: Failed to encode XML message");
return -1;
}
loggers::get_instance().log("sip_codec_message_body::encode_message_body: xml encoded value: %s", body->body);
loggers::get_instance().log("sip_codec_message_body::encode_message_body: body list size: %d", ::osip_list_size(&p_sip_message->bodies));
if (::osip_message_set_body(p_sip_message, body->body, body->length) != 0) {
loggers::get_instance().warning("sip_codec_message_body::encode_message_body: Failed to encode XML message");
osip_body_free(body);
return -1;
}
loggers::get_instance().log("sip_codec_message_body::encode_message_body: new body list size: %d", ::osip_list_size(&p_sip_message->bodies));
osip_body_free(body);
// Retrive the new created body and add content type
body = nullptr;
loggers::get_instance().log("sip_codec_message_body::encode_message_body: get item #%d", ::osip_list_size(&p_sip_message->bodies) - 1);
if (::osip_message_get_body(p_sip_message, ::osip_list_size(&p_sip_message->bodies) - 1, &body) != ::osip_list_size(&p_sip_message->bodies) - 1) {
loggers::get_instance().warning("sip_codec_message_body::encode_message_body: Failed to set content-type");
return -1;
}
const char* ct = static_cast<const char*>(p.content__type());
loggers::get_instance().log("sip_codec_message_body::encode_message_body: content-type: %s", ct);
if (ct != nullptr) {
::osip_body_set_contenttype(body, ct);
} else { // Use a default value
::osip_body_set_contenttype(body, "application/resource-lists+xml");
}
} else if (ps.ischosen(LibSip__MessageBodyTypes::MIME__Encapsulated__Parts::ALT_msdBody)) {
loggers::get_instance().warning("sip_codec_message_body::encode_message_body: Unsupported decoding of ALT_msdBody");
} else {
loggers::get_instance().warning("sip_codec_message_body::encode_message_body: Unsupported decoding of encapulated parts");
}
pos += 1;
} // End of 'while' statement
} else {
loggers::get_instance().warning("sip_codec_message_body::encode_message_body: Unsupported variant");
return -1;
}
return 0;
} // End of method encode_message_body
int sip_codec_message_body::encode_sdp(const LibSip__SDPTypes::SDP__Message& p_sdp_message, sdp_message_t** p_sdp_body) {
loggers::get_instance().log_msg(">>> sip_codec_message_body::encode_sdp: ", p_sdp_message);
::sdp_message_init(p_sdp_body);
// Encode mandatory fields
// Version
INTEGER version = p_sdp_message.protocol__version();
::sdp_message_v_version_set(*p_sdp_body, (char*)::strdup(std::to_string(static_cast<const int>(version)).c_str()));
LibSip__SDPTypes::SDP__Origin origin = p_sdp_message.origin();
// Origin
loggers::get_instance().log_msg("sip_codec_message_body::encode_sdp: origin: ", origin);
::sdp_message_o_origin_set(
*p_sdp_body,
(char*)::strdup(static_cast<const char*>(origin.user__name())),
(char*)::strdup(static_cast<const char*>(origin.session__id())),
(char*)::strdup(static_cast<const char*>(origin.session__version())),
(char*)::strdup(static_cast<const char*>(origin.net__type())),
(char*)::strdup(static_cast<const char*>(origin.addr__type())),
(char*)::strdup(static_cast<const char*>(origin.addr()))
);
// Session name
::sdp_message_s_name_set(*p_sdp_body, (char*)::strdup(static_cast<const char*>(p_sdp_message.session__name())));
// Time, t
::sdp_message_s_name_set(*p_sdp_body, (char*)::strdup(static_cast<const char*>(p_sdp_message.session__name())));
loggers::get_instance().log_msg("sip_codec_message_body::encode_sdp: times: ", p_sdp_message.times());
for (int i = 0; i < p_sdp_message.times().lengthof(); i++) {
const LibSip__SDPTypes::SDP__time& time = p_sdp_message.times()[i];
loggers::get_instance().log_msg("sip_codec_message_body::encode_sdp: time: ", time);
::sdp_message_t_time_descr_add(*p_sdp_body, (char*)::strdup(static_cast<const char*>(time.time__field().start__time())), (char*)::strdup(static_cast<const char*>(time.time__field().stop__time())));
if (time.time__repeat().is_present()) {
const LibSip__SDPTypes::SDP__repeat__list& l = static_cast<const OPTIONAL<LibSip__SDPTypes::SDP__repeat__list>&>(*time.time__repeat().get_opt_value());
loggers::get_instance().log_msg("sip_codec_message_body::encode_sdp: l: ", l);
for (int j = 0; j < l.lengthof(); j++) {
const LibSip__SDPTypes::SDP__repeat& r = l[j];
// TODO r.repeat__interval();
// TODO r.active();
for (int k = 0; k < r.offsets().lengthof(); k++) {
const LibSip__SDPTypes::SDP__typed__time& s = r.offsets()[k];
// TODO ::sdp_message_r_repeat_add(p_sdp_body, k, char *value);
} // End of 'for' statement
// TODO ::sdp_message_r_repeat_add(p_sdp_body, int pos_time_descr, char *value)
} // End of 'for' statement
}
} // End of 'for' statement
// Encode optional fields
// email, e
loggers::get_instance().log_msg("sip_codec_message_body::encode_sdp: emails: ", p_sdp_message.emails());
if (p_sdp_message.emails().is_present()) {
const LibSip__SDPTypes::SDP__email__list& l = static_cast<const LibSip__SDPTypes::SDP__email__list&>(*p_sdp_message.emails().get_opt_value());
for (int j = 0; j < l.lengthof(); j++) {
const LibSip__SDPTypes::SDP__contact& e = l[j];
std::string str;
if (e.disp__name().is_present()) {
str = static_cast<const char*>(static_cast<const CHARSTRING&>(*e.disp__name().get_opt_value()));
str += " ";
}
str += static_cast<const char*>(e.addr__or__phone());
::sdp_message_e_email_add(*p_sdp_body, ::strdup(str.c_str()));
} // End of 'for' statement
}
// Information, i
loggers::get_instance().log_msg("sip_codec_message_body::encode_sdp: information: ", p_sdp_message.information());
if (p_sdp_message.information().is_present()) {
::sdp_message_i_info_set(*p_sdp_body, 0, ::strdup(static_cast<const CHARSTRING&>(*p_sdp_message.information().get_opt_value())));
}
// Media list, m
loggers::get_instance().log_msg("sip_codec_message_body::encode_sdp: medias: ", p_sdp_message.media__list());
if (p_sdp_message.media__list().is_present()) {
const LibSip__SDPTypes::SDP__media__desc__list& l = static_cast<const LibSip__SDPTypes::SDP__media__desc__list&>(*p_sdp_message.media__list().get_opt_value());
int i = 0;
for ( ; i < l.lengthof(); i++) {
const LibSip__SDPTypes::SDP__media__desc m = l[i];
loggers::get_instance().log_msg("sip_codec_message_body::encode_sdp: media: ", m);
// Media field
if (m.media__field().ports().num__of__ports().is_present()) {
int p = static_cast<const INTEGER&>(*m.media__field().ports().num__of__ports().get_opt_value());
::sdp_message_m_media_add(*p_sdp_body, (char*)::strdup(static_cast<const char*>(m.media__field().media())), (char*)::strdup(std::to_string(m.media__field().ports().port__number()).c_str()), (char*)::strdup(std::to_string(p).c_str()), (char*)::strdup(static_cast<const char*>(m.media__field().transport())));
} else {
::sdp_message_m_media_add(*p_sdp_body, (char*)::strdup(static_cast<const char*>(m.media__field().media())), (char*)::strdup(std::to_string(m.media__field().ports().port__number()).c_str()), NULL, (char*)::strdup(static_cast<const char*>(m.media__field().transport())));
}
// Format list
const LibSip__SDPTypes::SDP__fmt__list& fmts = m.media__field().fmts();
std::string str;
for (int j = 0; j < fmts.lengthof() - 1; j++) {
str += static_cast<const char*>(fmts[j]);
str += " ";
} // End of 'for' statement
str += static_cast<const char*>(fmts[fmts.lengthof() - 1]);
// information
if (m.information().is_present()) {
str += " ";
str += static_cast<const char*>(static_cast<const CHARSTRING&>(*m.information().get_opt_value()));
}
if (str.length() != 0) {
::sdp_message_m_payload_add(*p_sdp_body, i, (char*)::strdup(str.c_str()));
}
// Attribute list, a
loggers::get_instance().log_msg("sip_codec_message_body::encode_sdp: attributes: ", m.attributes());
if (m.attributes().is_present()) {
const LibSip__SDPTypes::SDP__attribute__list& al = static_cast<const LibSip__SDPTypes::SDP__attribute__list&>(*m.attributes().get_opt_value());
for (int k = 0; k < al.lengthof(); k++) {
const LibSip__SDPTypes::SDP__attribute a = al[k];
loggers::get_instance().log_msg("sip_codec_message_body::encode_sdp: attribute: ", a);
if (a.ischosen(LibSip__SDPTypes::SDP__attribute::ALT_rtpmap)) {
std::string str(static_cast<const char*>(a.rtpmap().payload__type()));
str += " ";
str += static_cast<const char*>(a.rtpmap().codec().encoding());
str += "/";
str += a.rtpmap().codec().clockrate();
if (a.rtpmap().codec().parameters().is_present()) {
str += "/";
str += static_cast<const char*>(static_cast<const CHARSTRING&>(*a.rtpmap().codec().parameters().get_opt_value()));
}
loggers::get_instance().log("sip_codec_message_body::encode_sdp: attribute: media #%d: encode rtpmap:%s", i, str.c_str());
::sdp_message_a_attribute_add(*p_sdp_body, i, (char*)::strdup("rtpmap"), (char*)::strdup(str.c_str()));
} else if (a.ischosen(LibSip__SDPTypes::SDP__attribute::ALT_fmtp)) {
std::string str(static_cast<const char*>(a.fmtp().format()));
str += " ";
if (a.fmtp().params().ischosen(LibSip__SDPTypes::SDP__attribute__fmtp__format__specific__params::ALT_paramList)) {
const LibSip__Common::SemicolonParam__List& sl = a.fmtp().params().paramList();
for (int k = 0; k < sl.lengthof(); k++) {
str += static_cast<const char*>(sl[k].id());
if (sl[k].paramValue().is_present()) {
const LibSip__Common::GenValue& v = static_cast<const LibSip__Common::GenValue&>(*sl[k].paramValue().get_opt_value());
loggers::get_instance().log_msg("sip_codec_message_body::encode_sdp: attribute: fmtp: v: ", v);
str += "=";
if (v.ischosen(LibSip__Common::GenValue::ALT_tokenOrHost)) {
str += static_cast<const char*>(v.tokenOrHost());
} else {
str += static_cast<const char*>(v.quotedString());
}
} // else, nothing to do
str += ";";
} // End of 'for' statement
} else {
str += static_cast<const char*>(a.fmtp().params().unstructured());
}
::sdp_message_a_attribute_add(*p_sdp_body, i, (char*)::strdup("fmtp"), (char*)::strdup(str.c_str()));
} else if (a.ischosen(LibSip__SDPTypes::SDP__attribute::ALT_curr)) {
std::string str(static_cast<const char*>(a.curr().preconditionType()));
str += " ";
str += static_cast<const char*>(a.curr().statusType());
str += " ";
str += static_cast<const char*>(a.curr().direction());
::sdp_message_a_attribute_add(*p_sdp_body, i, (char*)::strdup("curr"), (char*)::strdup(str.c_str()));
} else if (a.ischosen(LibSip__SDPTypes::SDP__attribute::ALT_des)) {
std::string str(static_cast<const char*>(a.des().preconditionType()));
str += " ";
str += static_cast<const char*>(a.des().strength());
str += " ";
str += static_cast<const char*>(a.des().statusType());
str += " ";
str += static_cast<const char*>(a.des().direction());
::sdp_message_a_attribute_add(*p_sdp_body, i, (char*)::strdup("des"), (char*)::strdup(str.c_str()));
} else if (a.ischosen(LibSip__SDPTypes::SDP__attribute::ALT_maxptime)) {
::sdp_message_a_attribute_add(*p_sdp_body, i, (char*)::strdup("maxptime"), (char*)::strdup(static_cast<const char*>(a.maxptime().attr__value())));
} else if (a.ischosen(LibSip__SDPTypes::SDP__attribute::ALT_sendrecv)) {
::sdp_message_a_attribute_add(*p_sdp_body, i, (char*)::strdup("sendrecv"), nullptr);
} else {
loggers::get_instance().warning("sip_codec_message_body::encode_sdp: attribute not processed");
}
} // End of 'for' statement
}
} // End of 'for' statement
::sdp_message_endof_media(*p_sdp_body, i);
}
// Attribute list, a
loggers::get_instance().log_msg("sip_codec_message_body::encode_sdp: attributes: ", p_sdp_message.attributes());
if (p_sdp_message.attributes().is_present()) {
const LibSip__SDPTypes::SDP__attribute__list& l = static_cast<const LibSip__SDPTypes::SDP__attribute__list&>(*p_sdp_message.attributes().get_opt_value());
int i = 0;
for ( ; i < l.lengthof(); i++) {
const LibSip__SDPTypes::SDP__attribute a = l[i];
loggers::get_instance().log_msg("sip_codec_message_body::encode_sdp: attribute: ", a);
if (a.ischosen(LibSip__SDPTypes::SDP__attribute::ALT_rtpmap)) {
std::string str(static_cast<const char*>(a.rtpmap().payload__type()));
str += " ";
str += static_cast<const char*>(a.rtpmap().codec().encoding());
str += " ";
str += a.rtpmap().codec().clockrate();
if (a.rtpmap().codec().parameters().is_present()) {
str += "/";
str += static_cast<const char*>(static_cast<const CHARSTRING&>(*a.rtpmap().codec().parameters().get_opt_value()));
}
loggers::get_instance().log("sip_codec_message_body::encode_sdp: attribute: media #%d: encode rtpmap:%s", i, str.c_str());
::sdp_message_a_attribute_add(*p_sdp_body, 0, (char*)::strdup("rtpmap"), (char*)::strdup(str.c_str()));
} else if (a.ischosen(LibSip__SDPTypes::SDP__attribute::ALT_fmtp)) {
std::string str(static_cast<const char*>(a.fmtp().format()));
str += " ";
if (a.fmtp().params().ischosen(LibSip__SDPTypes::SDP__attribute__fmtp__format__specific__params::ALT_paramList)) {
const LibSip__Common::SemicolonParam__List& sl = a.fmtp().params().paramList();
for (int k = 0; k < sl.lengthof(); k++) {
str += static_cast<const char*>(sl[k].id());
if (sl[k].paramValue().is_present()) {
const LibSip__Common::GenValue& v = static_cast<const LibSip__Common::GenValue&>(*sl[k].paramValue().get_opt_value());
loggers::get_instance().log_msg("sip_codec_message_body::encode_sdp: attribute: fmtp: v: ", v);
str += "=";
if (v.ischosen(LibSip__Common::GenValue::ALT_tokenOrHost)) {
str += static_cast<const char*>(v.tokenOrHost());
} else {
str += static_cast<const char*>(v.quotedString());
}
} // else, nothing to do
str += ";";
} // End of 'for' statement
} else {
str += static_cast<const char*>(a.fmtp().params().unstructured());
}
::sdp_message_a_attribute_add(*p_sdp_body, 0, (char*)::strdup("fmtp"), (char*)::strdup(str.c_str()));
} else if (a.ischosen(LibSip__SDPTypes::SDP__attribute::ALT_curr)) {
std::string str(static_cast<const char*>(a.curr().preconditionType()));
str += " ";
str += static_cast<const char*>(a.curr().statusType());
str += " ";
str += static_cast<const char*>(a.curr().direction());
::sdp_message_a_attribute_add(*p_sdp_body, 0, (char*)::strdup("curr"), (char*)::strdup(str.c_str()));
} else if (a.ischosen(LibSip__SDPTypes::SDP__attribute::ALT_des)) {
std::string str(static_cast<const char*>(a.des().preconditionType()));
str += " ";
str += static_cast<const char*>(a.des().strength());
str += " ";
str += static_cast<const char*>(a.des().statusType());
str += " ";
str += static_cast<const char*>(a.des().direction());
::sdp_message_a_attribute_add(*p_sdp_body, 0, (char*)::strdup("des"), (char*)::strdup(str.c_str()));
} else if (a.ischosen(LibSip__SDPTypes::SDP__attribute::ALT_maxptime)) {
::sdp_message_a_attribute_add(*p_sdp_body, 0, (char*)::strdup("maxptime"), (char*)::strdup(static_cast<const char*>(a.maxptime().attr__value())));
} else if (a.ischosen(LibSip__SDPTypes::SDP__attribute::ALT_sendrecv)) {
::sdp_message_a_attribute_add(*p_sdp_body, 0, (char*)::strdup("sendrecv"), nullptr);
} else {
loggers::get_instance().warning("sip_codec_message_body::encode_sdp: attribute not processed");
}
} // End of 'for' statement
}
// Bandwith, b
loggers::get_instance().log_msg("sip_codec_message_body::encode_sdp: Bandwidth: ", p_sdp_message.bandwidth());
if (p_sdp_message.bandwidth().is_present()) {
const LibSip__SDPTypes::SDP__bandwidth__list& l = static_cast<const LibSip__SDPTypes::SDP__bandwidth__list&>(*p_sdp_message.bandwidth().get_opt_value());
int i = 0;
for ( ; i < l.lengthof(); i++) {
const LibSip__SDPTypes::SDP__bandwidth b = l[i];
loggers::get_instance().log_msg("sip_codec_message_body::encode_sdp: bandwidth: ", b);
::sdp_message_b_bandwidth_add(*p_sdp_body, i, (char*)::strdup(static_cast<const char*>(b.modifier())), (char*)::strdup(std::to_string(b.bandwidth()).c_str()));
} // End of 'for' statement
}
// Connection, c
loggers::get_instance().log_msg("sip_codec_message_body::encode_sdp: Connection: ", p_sdp_message.connection());
if (p_sdp_message.connection().is_present()) {
const LibSip__SDPTypes::SDP__connection& c = static_cast<const LibSip__SDPTypes::SDP__connection&>(*p_sdp_message.connection().get_opt_value());
::sdp_message_c_connection_add(*p_sdp_body, 0, ::strdup(static_cast<const char*>(c.net__type())), ::strdup(static_cast<const char*>(c.addr__type())), ::strdup(static_cast<const char*>(c.conn__addr().addr())), nullptr, nullptr);
}
// TODO To be continued
loggers::get_instance().log("<<< sip_codec_message_body::encode_sdp");
return 0;
}
void sip_codec_message_body::decode_message_body(const osip_message_t* p_sip_message, OPTIONAL<LibSip__MessageBodyTypes::MessageBody>& p_message_body)
{ // TODO Rename into decode_message
loggers::get_instance().log(">>> sip_codec_message_body::decode_message_body");
osip_content_length* content_length = ::osip_message_get_content_length(p_sip_message);
loggers::get_instance().log("sip_codec_message_body::decode_message_body: content_length= %s", content_length->value);
if (strcmp((const char*)content_length->value, "0") == 0) {
p_message_body.set_to_omit();
return;
}
// TODO Align the body the content_length
osip_content_type_t* content_type = ::osip_message_get_content_type(p_sip_message);
osip_body_t* body;
int result = ::osip_message_get_body(p_sip_message, 0, &body);
if (result != 0) {
loggers::get_instance().warning("sip_codec_message_body::decode_message_body: Failed to retrieve body");
p_message_body.set_to_omit();
return;
}
loggers::get_instance().log("sip_codec_message_body::decode_message_body: Body size: %d", body->length);
loggers::get_instance().log("sip_codec_message_body::decode_message_body: Body content: %s", body->body);
if (body->headers != nullptr) {
loggers::get_instance().log("sip_codec_message_body::decode_message_body: Body headers size: %d", osip_list_size(body->headers));
}
if (body->content_type != nullptr) {
loggers::get_instance().log("sip_codec_message_body::decode_message_body: Body content-type: '%s'/'%s'/%p", body->content_type->type, body->content_type->subtype, body->content_type->gen_params.node);
}
if (::osip_list_size(body->headers) != 0) {
loggers::get_instance().log("sip_codec_message_body::decode_message_body: Body header is present");
// TODO Process Content-ID and other headers
}
LibSip__MessageBodyTypes::MessageBody msg_body;
if (content_type != nullptr) {
loggers::get_instance().log("sip_codec_message_body::decode_message_body: content-type.type: '%s'/'%s'/%p", content_type->type, content_type->subtype, content_type->gen_params.node);
if (std::string(content_type->type).compare("multipart") == 0) {
const osip_list_t* p = &(p_sip_message->bodies);
size_t size = osip_list_size(p);
loggers::get_instance().log("sip_codec_message_body::decode_message_body: Multipart body size: %d\n", size);
if (size == 0) {
loggers::get_instance().warning("sip_codec_message_body::decode_message_body: Empty multipart content, fallback to textplain");
msg_body.textplain() = CHARSTRING(body->body);
} else {
LibSip__MessageBodyTypes::MIME__Message mime;
if (content_type->gen_params.node != nullptr) {
mime.boundary() = CHARSTRING("boundary1"/*(const char*)content_type->gen_params.node->element*/); // TODO How to get the boundary name?
} else {
mime.boundary() = CHARSTRING("boundary1");
}
loggers::get_instance().log_msg("sip_codec_message_body::decode_message_body: Boundary: ", mime.boundary());
LibSip__MessageBodyTypes::MimeEncapsulatedList& l = mime.mimeEncapsulatedList();
size_t pos = 0;
while (pos < size) {
const osip_header_t* header = (const osip_header_t*)osip_list_get(p, pos);
loggers::get_instance().log("sip_codec_message_body::decode_message_body: body content=%s", header->hname);
if ((*header->hname == 'v') && (*(header->hname + 1) == '=') && (*(header->hname + 2) == '0')) { // SDP
loggers::get_instance().log("sip_codec_message_body::decode_message_body: Decode SDP");
LibSip__MessageBodyTypes::MIME__Encapsulated__Part p;
p.content__type() = CHARSTRING("application/sdp");
p.content__disposition().set_to_omit();
p.content__id().set_to_omit();
LibSip__SDPTypes::SDP__Message sdp_body;
osip_body_t* body;
::osip_body_init(&body);
body->body = ::strdup(header->hname); // TODO Check if strdup is needed
body->length = strlen(header->hname);
LibSip__MessageBodyTypes::MIME__Encapsulated__Parts& parts = p.mime__encapsulated__part();
if (decode_sdp(body, sdp_body) == 0) {
parts.sdpMessageBody() = sdp_body;
} else {
parts.msdBody() = char2oct(CHARSTRING(header->hname));
}
l[pos] = p;
} else if ((*header->hname == '<') && (*(header->hname + 1) == '?') && (*(header->hname + 2) == 'x')) { // <?xml
loggers::get_instance().log("sip_codec_message_body::decode_message_body: Decode XML");
LibSip__MessageBodyTypes::MIME__Encapsulated__Part p;
p.content__type() = CHARSTRING("application/resource-lists+xml");
p.content__disposition().set_to_omit();
p.content__id().set_to_omit();
LibSip__XMLTypes::XmlBody xml_body;
osip_body_t* body;
::osip_body_init(&body);
body->body = header->hname;
body->length = strlen(header->hname);
LibSip__MessageBodyTypes::MIME__Encapsulated__Parts& parts = p.mime__encapsulated__part();
if (decode_xml(body, xml_body) == 0) {
parts.xmlBody() = xml_body;
} else {
parts.msdBody() = char2oct(CHARSTRING(header->hname));
}
l[pos] = p;
} else {
// TODO
loggers::get_instance().error("sip_codec_message_body::decode_message_body: Not implemented yet");
}
pos += 1;
} // End of 'while' statement
msg_body.mimeMessageBody() = mime;
}
} else if ((std::string(content_type->type).compare("application") == 0) && (std::string(content_type->subtype).compare("sdp") == 0)) {
LibSip__SDPTypes::SDP__Message sdp_body;
if (decode_sdp(body, sdp_body) == 0) {
// Set message body
msg_body.sdpMessageBody() = sdp_body;
} else {
loggers::get_instance().warning("sip_codec_message_body::decode_message_body: sdp_message_parse failed, fallback to textplain");
msg_body.textplain() = CHARSTRING(body->body);
}
} else {
loggers::get_instance().warning("sip_codec_message_body::decode_message_body: Unsuported content-type, fallback to textplain");
msg_body.textplain() = CHARSTRING(body->body);
}
p_message_body = OPTIONAL<LibSip__MessageBodyTypes::MessageBody>(msg_body);
} else if ((body != nullptr) && (body->body != nullptr)) {
msg_body.textplain() = CHARSTRING(body->body);
p_message_body = OPTIONAL<LibSip__MessageBodyTypes::MessageBody>(msg_body);
} else {
p_message_body.set_to_omit();
}
loggers::get_instance().log_msg("<<< sip_codec_message_body::decode_message_body: ", p_message_body);
} // End of method decode_message_body
int sip_codec_message_body::decode_sdp(const osip_body_t* p_body, LibSip__SDPTypes::SDP__Message& p_sdp_header) {
loggers::get_instance().log(">>> sip_codec_message_body::decode_sdp: %s", p_body->body);
sdp_message_t* sdp = nullptr;
::sdp_message_init(&sdp);
std::string s(p_body->body);
s += "\r\n\r\n";
if (::sdp_message_parse(sdp, s.c_str()/*p_body->body*/) == 0) {
// Mandatroy fields
// Version, v
char *hvalue = ::sdp_message_v_version_get(sdp);
if (hvalue != nullptr) {
p_sdp_header.protocol__version() = std::stoi(hvalue);
}
// Origin, o
p_sdp_header.origin() = LibSip__SDPTypes::SDP__Origin(
::sdp_message_o_username_get(sdp),
::sdp_message_o_sess_version_get(sdp),
::sdp_message_o_sess_version_get(sdp),
::sdp_message_o_nettype_get(sdp),
::sdp_message_o_addrtype_get(sdp),
::sdp_message_o_addr_get(sdp)
);
// Session name, s
if ((hvalue = ::sdp_message_s_name_get(sdp)) != nullptr) {
p_sdp_header.session__name() = CHARSTRING(hvalue);
}
// Time, t
int i = 0;
if ((hvalue = ::sdp_message_t_start_time_get(sdp, i)) != nullptr) {
LibSip__SDPTypes::SDP__time__list l;
do {
LibSip__SDPTypes::SDP__time t;
LibSip__SDPTypes::SDP__time__field tf;
tf.start__time() = CHARSTRING(hvalue);
tf.stop__time() = CHARSTRING(sdp_message_t_stop_time_get(sdp, i));
t.time__field() = tf;
t.time__repeat().set_to_omit(); // TODO
l[i] = t;
i += 1;
} while ((hvalue = ::sdp_message_t_start_time_get(sdp, i)) != nullptr);
p_sdp_header.times() = l;
} else {
loggers::get_instance().warning("sip_codec_message_body::decode_sdp: No start time in sdp");
}
// Optional fields
// Emails, e
i = 0;
if ((hvalue = ::sdp_message_e_email_get(sdp, i)) != nullptr) {
LibSip__SDPTypes::SDP__email__list l;
do {
LibSip__SDPTypes::SDP__contact e;
e.addr__or__phone() = CHARSTRING(hvalue);
e.disp__name().set_to_omit(); // TODO To be refined
l[i] = e;
i += 1;
} while ((hvalue = ::sdp_message_e_email_get(sdp, i)) != nullptr);
p_sdp_header.emails() = OPTIONAL<LibSip__SDPTypes::SDP__email__list>(l);
} else {
loggers::get_instance().warning("sip_codec_message_body::decode_sdp: No emails in sdp");
p_sdp_header.emails().set_to_omit();
}
// Information, i
i = 0;
if ((hvalue = ::sdp_message_i_info_get(sdp, i)) != nullptr) {
p_sdp_header.information() = OPTIONAL<CHARSTRING>(CHARSTRING(hvalue));
} else {
loggers::get_instance().warning("sip_codec_message_body::decode_sdp: No information in sdp");
p_sdp_header.information().set_to_omit();
}
// Media, m
i = 0;
if ((hvalue = ::sdp_message_m_media_get(sdp, i)) != nullptr) {
LibSip__SDPTypes::SDP__media__desc__list l;
do {
loggers::get_instance().log("sip_codec_message_body::decode_sdp: Media='%s'", hvalue);
// Media description
LibSip__SDPTypes::SDP__media__field f;
f.media() = CHARSTRING(hvalue);
LibSip__SDPTypes::SDP__media__port p;
hvalue = ::sdp_message_m_port_get(sdp, i);
p.port__number() = std::stoi(hvalue);
if ((hvalue = ::sdp_message_m_number_of_port_get(sdp, i)) == nullptr) {
p.num__of__ports().set_to_omit();
} else {
p.num__of__ports() = OPTIONAL<INTEGER>(std::stoi(hvalue));
}
f.ports() = p;
f.transport() = CHARSTRING(::sdp_message_m_proto_get(sdp, i));
LibSip__SDPTypes::SDP__fmt__list fl;
int j = 0;
while ((hvalue = ::sdp_message_m_payload_get(sdp, i, j)) != nullptr) {
fl[j++] = CHARSTRING(hvalue);
} // End of 'for' statement
f.fmts() = fl;
LibSip__SDPTypes::SDP__media__desc m;
m.media__field() = f;
loggers::get_instance().log_msg("sip_codec_message_body::decode_sdp: m=", m);
// TODO
// Media attributes
m.attributes().set_to_omit();
m.bandwidth().set_to_omit();
m.information().set_to_omit();
m.connections().set_to_omit();
m.key().set_to_omit();
l[i] = m;
i += 1;
} while ((hvalue = ::sdp_message_m_media_get(sdp, i)) != nullptr);
p_sdp_header.media__list() = OPTIONAL<LibSip__SDPTypes::SDP__media__desc__list>(l);
} else {
loggers::get_instance().warning("sip_codec_message_body::decode_sdp: No media in sdp");
p_sdp_header.media__list().set_to_omit();
}
// Attributes, a
i = 0;
sdp_attribute_t* a;
if ((a = ::sdp_message_attribute_get(sdp, 0, i)) != nullptr) {
LibSip__SDPTypes::SDP__attribute__list l;
int j = 0;
do {
loggers::get_instance().log("sip_codec_message_body::decode_sdp: Attributes#%d: '%s'='%s'", i, a->a_att_field, (a->a_att_value == nullptr) ? "(null)" : a->a_att_value);
// Attribute description
LibSip__SDPTypes::SDP__attribute f;
if (strcmp(a->a_att_field, "rtpmap") == 0) {
std::vector<std::string> output = converter::get_instance().split(a->a_att_value, " ");
LibSip__SDPTypes::SDP__attribute__rtpmap__codec c;
std::vector<std::string> o = converter::get_instance().split(output[1], "/");
c.encoding() = CHARSTRING(o[0].c_str());
c.clockrate() = CHARSTRING(o[1].c_str());
if (o.size() == 3) {
c.parameters() = OPTIONAL<CHARSTRING>(CHARSTRING(o[2].c_str()));
} else {
c.parameters().set_to_omit();
}
f.rtpmap() = LibSip__SDPTypes::SDP__attribute__rtpmap(CHARSTRING(output[0].c_str()), c);
} else if (strcmp(a->a_att_field, "fmtp") == 0) {
// fmtp'='114 mode-change-capability=2;max-red=0'
std::vector<std::string> o = converter::get_instance().split(a->a_att_value, " ");
LibSip__SDPTypes::SDP__attribute__fmtp fmtp;
fmtp.format() = CHARSTRING(o[0].c_str());
LibSip__SDPTypes::SDP__attribute__fmtp__format__specific__params c;
if (o[1].find(";") != std::string::npos) {
loggers::get_instance().log("sip_codec_message_body::decode_sdp: Attributes#%d: param list='%s'", i, o[1].c_str());
o = converter::get_instance().split(o[1], ";");
LibSip__Common::SemicolonParam__List& sl = c.paramList();
for (unsigned int k = 0; k < o.size(); k++) {
loggers::get_instance().log("sip_codec_headers::decode_semi_colon_params: Process param: %s", o[k].c_str());
size_t eq_pos = o[k].find("=");
if (eq_pos == std::string::npos) {
sl[k] = LibSip__Common::GenericParam(CHARSTRING(o[k].c_str()), OPTIONAL<LibSip__Common::GenValue>(OMIT_VALUE));
} else {
loggers::get_instance().log("sip_codec_headers::decode_semi_colon_params: substrs: %s - %s", o[k].substr(0, eq_pos).c_str(), o[k].substr(eq_pos + 1).c_str());
LibSip__Common::GenValue g;
g.tokenOrHost() = CHARSTRING(o[k].substr(eq_pos + 1).c_str());
sl[k] = LibSip__Common::GenericParam(CHARSTRING(o[k].substr(0, eq_pos).c_str()), g);
}
} // End of 'for'statement
} else {
c.unstructured() = CHARSTRING(o[1].c_str());
}
fmtp.params() = c;
f.fmtp() = fmtp;
} else if (strcmp(a->a_att_field, "curr") == 0) {
std::vector<std::string> o = converter::get_instance().split(a->a_att_value, " ");
if (o.size() == 3) {
LibSip__SDPTypes::SDP__attribute__curr c;
c.preconditionType() = CHARSTRING(o[0].c_str());
c.statusType() = CHARSTRING(o[1].c_str());
c.direction() = CHARSTRING(o[2].c_str());
f.curr() = c;
} else {
loggers::get_instance().warning("sip_codec_message_body::decode_sdp: Wrong formatted curr SDP");
f.curr().set_to_omit();
}
} else if (strcmp(a->a_att_field, "des") == 0) {
std::vector<std::string> o = converter::get_instance().split(a->a_att_value, " ");
if (o.size() == 4) {
LibSip__SDPTypes::SDP__attribute__des c;
c.preconditionType() = CHARSTRING(o[0].c_str());
c.strength() = CHARSTRING(o[1].c_str());
c.statusType() = CHARSTRING(o[2].c_str());
c.direction() = CHARSTRING(o[3].c_str());
f.des() = c;
} else {
loggers::get_instance().warning("sip_codec_message_body::decode_sdp: Wrong formatted des SDP");
f.des().set_to_omit();
}
} else if (strcmp(a->a_att_field, "sendrecv") == 0) {
f.sendrecv() = LibSip__SDPTypes::SDP__attribute__sendrecv(NULL_VALUE);
} else if (strcmp(a->a_att_field, "maxptime") == 0) {
LibSip__SDPTypes::SDP__attribute__maxptime m;
f.maxptime() = LibSip__SDPTypes::SDP__attribute__maxptime(CHARSTRING((const char*)a->a_att_value));
} else {
loggers::get_instance().warning("sip_codec_message_body::decode_sdp: Unprocessed attributes#%d: '%s'='%s'", i, a->a_att_field, a->a_att_value);
}
loggers::get_instance().log_msg("sip_codec_message_body::decode_sdp: f: ", f);
if (f.is_bound()) {
l[j++] = f;
}
i += 1;
} while ((a = ::sdp_message_attribute_get(sdp, 0, i)) != nullptr);
loggers::get_instance().log_msg("sip_codec_message_body::decode_sdp: After Attribute loop: ", l);
if (j == 0) { // Empty list
p_sdp_header.attributes().set_to_omit();
} else {
p_sdp_header.attributes() = OPTIONAL<LibSip__SDPTypes::SDP__attribute__list>(l);
}
} else {
loggers::get_instance().warning("sip_codec_message_body::decode_sdp: No attributes in sdp");
p_sdp_header.attributes().set_to_omit();
}
// Bandwith, b
i = 0;
sdp_bandwidth_t* b;
if ((b = ::sdp_message_bandwidth_get(sdp, 0, i)) != nullptr) {
LibSip__SDPTypes::SDP__bandwidth__list l;
do {
loggers::get_instance().log("sip_codec_message_body::decode_sdp: Bandwidths#%d: '%s'='%s'", i, b->b_bwtype, b->b_bandwidth);
LibSip__SDPTypes::SDP__bandwidth a(b->b_bwtype, INTEGER(std::stoi(b->b_bandwidth)));
loggers::get_instance().log_msg("sip_codec_message_body::decode_sdp_sdp: Bandwith: ", a);
l[i] = a;
i += 1;
} while((b = ::sdp_message_bandwidth_get(sdp, 0, i)) != nullptr);
p_sdp_header.bandwidth() = OPTIONAL<LibSip__SDPTypes::SDP__bandwidth__list>(l);
} else {
p_sdp_header.bandwidth().set_to_omit();
}
// Connection, c
char* net__type;
if ((net__type = ::sdp_message_c_nettype_get(sdp, 0, 0)) != nullptr) {
loggers::get_instance().log("sip_codec_message_body::decode_sdp: Connections#%d: '%s'", 0, a);
LibSip__SDPTypes::SDP__connection c;
c.net__type() = CHARSTRING(net__type);
c.addr__type() = CHARSTRING(::sdp_message_c_addrtype_get(sdp, 0, 0));
LibSip__SDPTypes::SDP__conn__addr a;
a.addr() = CHARSTRING(::sdp_message_c_addr_get(sdp, 0, 0));
if (::sdp_message_c_addr_multicast_ttl_get(sdp, 0, 0) != nullptr) {
a.ttl() = OPTIONAL<INTEGER>(::stoi(::sdp_message_c_addr_multicast_ttl_get(sdp, 0, 0)));
} else {
a.ttl().set_to_omit();
}
if (::sdp_message_c_addr_multicast_int_get(sdp, 0, 0) != nullptr) {
a.num__of__addr() = OPTIONAL<INTEGER>(::stoi(::sdp_message_c_addr_multicast_int_get(sdp, 0, 0)));
} else {
a.num__of__addr().set_to_omit();
}
c.conn__addr() = a;
loggers::get_instance().log_msg("sip_codec_message_body::decode_sdp_sdp: connection: ", c);
p_sdp_header.connection() = OPTIONAL<LibSip__SDPTypes::SDP__connection>(c);
} else {
p_sdp_header.connection().set_to_omit();
}
i = 0;
// TODO
p_sdp_header.uri().set_to_omit();
p_sdp_header.phone__numbers().set_to_omit();
p_sdp_header.timezone__adjustments().set_to_omit();
p_sdp_header.key().set_to_omit();
} else {
loggers::get_instance().warning("sip_codec_message_body::decode_sdp: Failed to parse SDP");
return -1;
}
loggers::get_instance().log_msg("<<< sip_codec_message_body::decode_sdp: sdp: ", p_sdp_header);
return 0;
}
int sip_codec_message_body::encode_xml(const LibSip__XMLTypes::XmlBody& p_message_body, osip_body_t** p_body) {
loggers::get_instance().log_msg(">>> sip_codec_message_body::encode_xml: ", p_message_body);
::osip_body_init(p_body);
TTCN_EncDec::clear_error();
TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_DEFAULT);
TTCN_Buffer encoding_buffer;
CHARSTRING h("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n");
encoding_buffer.put_s(h.lengthof(), (const unsigned char*)static_cast<const char*>(h));
if (p_message_body.ischosen(LibSip__XMLTypes::XmlBody::ALT_presence)) { // Held codec
const urn__ietf__params__xml__ns__pidf::Presence& presence = p_message_body.presence();
loggers::get_instance().log_msg("sip_codec_message_body::encode_xml: Process Presence", (const Base_Type&)presence);
presence.encode(urn__ietf__params__xml__ns__pidf::Presence_descr_, encoding_buffer, TTCN_EncDec::CT_XER, XER_EXTENDED);
} else {
loggers::get_instance().warning("sip_codec_message_body::encode_xml: Unsupported variant");
return -1;
}
OCTETSTRING data = OCTETSTRING(encoding_buffer.get_len(), encoding_buffer.get_data());
if (p_message_body.ischosen(LibSip__XMLTypes::XmlBody::ALT_presence)) { // NG112-2021 Workaround for TITAN/XSD issue
// TODO TITAN work-around, replace tq0003 namespace???
std::string s(static_cast<const unsigned char*>(data), data.lengthof() + static_cast<const unsigned char*>(data));
/*size_t idx = 0;
std::string f("tq0000:");
std::string t("");
while ((idx = s.find(f)) != std::string::npos) {
s.replace(idx, f.length(), t);
idx += t.length();
} // End of 'while' statement
f.assign(":tq0000");
while ((idx = s.find(f)) != std::string::npos) {
s.replace(idx, f.length(), t);
idx += t.length();
} // End of 'while' statement
f.assign("tq0001:");
while ((idx = s.find(f)) != std::string::npos) {
s.replace(idx, f.length(), t);
idx += t.length();
} // End of 'while' statement
f.assign(":tq0001");
while ((idx = s.find(f)) != std::string::npos) {
s.replace(idx, f.length(), t);
idx += t.length();
} // End of 'while' statement
f.assign("tq0002:");
while ((idx = s.find(f)) != std::string::npos) {
s.replace(idx, f.length(), t);
idx += t.length();
} // End of 'while' statement
f.assign(":tq0002");
while ((idx = s.find(f)) != std::string::npos) {
s.replace(idx, f.length(), t);
idx += t.length();
} // End of 'while' statement
f.assign("tq0003:");
while ((idx = s.find(f)) != std::string::npos) {
s.replace(idx, f.length(), t);
idx += t.length();
} // End of 'while' statement
f.assign(":tq0003");
while ((idx = s.find(f)) != std::string::npos) {
s.replace(idx, f.length(), t);
idx += t.length();
} // End of 'while' statement
f.assign("tq0004:");
while ((idx = s.find(f)) != std::string::npos) {
s.replace(idx, f.length(), t);
idx += t.length();
} // End of 'while' statement
f.assign(":tq0004");
while ((idx = s.find(f)) != std::string::npos) {
s.replace(idx, f.length(), t);
idx += t.length();
} // End of 'while' statement
*/
data = OCTETSTRING(s.length(), (const unsigned char*)s.c_str());
}
(*p_body)->body = ::strdup(static_cast<const char*>(oct2char(data)));
(*p_body)->length = strlen((*p_body)->body);
loggers::get_instance().log("<<< sip_codec_message_body::encode_xml: %s", (*p_body)->body);
return 0;
}
int sip_codec_message_body::decode_xml(const osip_body_t* p_body, LibSip__XMLTypes::XmlBody& p_xml_header) {
loggers::get_instance().log(">>> sip_codec_message_body::decode_xml: %s", p_body->body);
// TODO Unify held_codec for bothHttp & Sip: instead of LibHttp__XmlMessageBodyTypes::XmlBody, use a generic XmlBody common to LibItsHttp & LibSip
TTCN_EncDec::clear_error();
TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_DEFAULT);
OCTETSTRING data(p_body->length, (const unsigned char*)p_body->body);
TTCN_Buffer decoding_buffer(data);
loggers::get_instance().log_to_hexa("sip_codec_message_body::decode_xml: decoding_buffer: ", decoding_buffer);
if (strstr(p_body->body, "<presence") != nullptr) { // Held codec
urn__ietf__params__xml__ns__pidf::Presence presence;
presence.decode(urn__ietf__params__xml__ns__pidf::Presence_descr_, decoding_buffer, TTCN_EncDec::CT_XER, XER_EXTENDED);
p_xml_header.presence() = presence;
} else {
loggers::get_instance().warning("sip_codec_message_body::decode_xml: Unsupported XML message, to be implemented");
}
loggers::get_instance().log_msg("<<< sip_codec_message_body::decode_xml: xml: ", p_xml_header);
return 0;
}
#pragma once
#include "codec_gen.hh"
#include "params.hh"
#include "osipparser2/osip_parser.h"
#include "osipparser2/sdp_message.h"
namespace LibSip__MessageBodyTypes {
class MessageBody;
}
namespace LibSip__SDPTypes {
class SDP__Messag;
}
namespace LibSip__XMLTypes {
class XmlBody;
}
class sip_codec_message_body: public codec_gen <
LibSip__MessageBodyTypes::MessageBody,
LibSip__MessageBodyTypes::MessageBody>
{
public:
explicit sip_codec_message_body() { };
virtual ~sip_codec_message_body() { };
virtual int encode (const LibSip__MessageBodyTypes::MessageBody& msg, OCTETSTRING& data);
virtual int decode (const OCTETSTRING& data, LibSip__MessageBodyTypes::MessageBody& msg, params* p_params = NULL);
virtual int encode_message_body(const LibSip__MessageBodyTypes::MessageBody& p_message_body, osip_message_t* p_sip_message);
virtual void decode_message_body(const osip_message_t* p_sip_message, OPTIONAL<LibSip__MessageBodyTypes::MessageBody>& p_message_body);
private:
int encode_sdp(const LibSip__SDPTypes::SDP__Message& p_message_body, sdp_message_t** p_sdp_body);
int decode_sdp(const osip_body_t* p_body, LibSip__SDPTypes::SDP__Message& p_sdp_header);
int encode_xml(const LibSip__XMLTypes::XmlBody& p_message_body, osip_body_t** p_body);
int decode_xml(const osip_body_t* p_body, LibSip__XMLTypes::XmlBody& p_xml_header);
}; // End of class sip_codec_message_body
#include "LibSip_SIPTypesAndValues.hh"
#include "sip_codec_message_request.hh"
#include "loggers.hh"
int sip_codec_message_request::encode (const LibSip__SIPTypesAndValues::MESSAGE__Request& msg, OCTETSTRING& data)
{
loggers::get_instance().log_msg(">>> sip_codec_message_request::encode: ", (const Base_Type&)msg);
if (_codec.encode((LibSip__SIPTypesAndValues::Request&)msg, data) == -1) {
loggers::get_instance().warning("sip_codec_message_request::encode: Failed to encode message");
return -1;
}
loggers::get_instance().log_msg("<<< sip_codec_message_request::encode: data=", data);
return 0;
}
int sip_codec_message_request::decode (const OCTETSTRING& data, LibSip__SIPTypesAndValues::MESSAGE__Request& msg, params* p_params)
{
loggers::get_instance().log_msg(">>> sip_codec_message_request::decode: data=", data);
// Sanity checks
if (data.lengthof() == 0) {
loggers::get_instance().warning("sip_codec_message_request::decode: Wrong parameters");
return -1;
}
// LibSip__SIPTypesAndValues::Request request;
if (_codec.decode(data, (LibSip__SIPTypesAndValues::Request&)msg) == -1) {
// if (_codec.decode(data, request) == -1) {
loggers::get_instance().warning("sip_codec_message_request::decode: Failed to decode message");
return -1;
}
// msg.requestLine() = request.requestLine();
// msg.msgHeader() = request.msgHeader();
// msg.messageBody() = request.messageBody();
// msg.payload() = request.payload();
if (msg.requestLine().method() != LibSip__SIPTypesAndValues::Method::MESSAGE__E) {
loggers::get_instance().warning("sip_codec_message_request::decode: Wrong SIP Method, expected MESSAGE");
return -1;
}
return 0;
}
#pragma once
#include "sip_codec_request.hh"
class Base_Type;
class TTCN_Typedescriptor_t;
class TTCN_Buffer;
namespace LibSip__SIPTypesAndValues {
class MESSAGE__Request;
}
class sip_codec_message_request: public codec_gen <
LibSip__SIPTypesAndValues::MESSAGE__Request,
LibSip__SIPTypesAndValues::MESSAGE__Request>
{
sip_codec_request _codec;
public:
explicit sip_codec_message_request() : codec_gen<LibSip__SIPTypesAndValues::MESSAGE__Request, LibSip__SIPTypesAndValues::MESSAGE__Request>(), _codec() { };
virtual ~sip_codec_message_request() { };
virtual int encode (const LibSip__SIPTypesAndValues::MESSAGE__Request& msg, OCTETSTRING& data);
virtual int decode (const OCTETSTRING& data, LibSip__SIPTypesAndValues::MESSAGE__Request& msg, params* p_params = NULL);
}; // End of class sip_codec_message_request
#include "LibSip_SIPTypesAndValues.hh"
#include "sip_codec_notify_request.hh"
#include "loggers.hh"
int sip_codec_notify_request::encode (const LibSip__SIPTypesAndValues::NOTIFY__Request& msg, OCTETSTRING& data)
{
loggers::get_instance().log_msg(">>> sip_codec_notify_request::encode: ", (const Base_Type&)msg);
if (_codec.encode((LibSip__SIPTypesAndValues::Request&)msg, data) == -1) {
loggers::get_instance().warning("sip_codec_notify_request::encode: Failed to encode message");
return -1;
}
loggers::get_instance().log_msg("<<< sip_codec_notify_request::encode: data=", data);
return 0;
}
int sip_codec_notify_request::decode (const OCTETSTRING& data, LibSip__SIPTypesAndValues::NOTIFY__Request& msg, params* p_params)
{
loggers::get_instance().log_msg(">>> sip_codec_notify_request::decode: data=", data);
// Sanity checks
if (data.lengthof() == 0) {
loggers::get_instance().warning("sip_codec_notify_request::decode: Wrong parameters");
return -1;
}
// LibSip__SIPTypesAndValues::Request request;
if (_codec.decode(data, (LibSip__SIPTypesAndValues::Request&)msg) == -1) {
// if (_codec.decode(data, request) == -1) {
loggers::get_instance().warning("sip_codec_notify_request::decode: Failed to decode message");
return -1;
}
// msg.requestLine() = request.requestLine();
// msg.msgHeader() = request.msgHeader();
// msg.messageBody() = request.messageBody();
// msg.payload() = request.payload();
if (msg.requestLine().method() != LibSip__SIPTypesAndValues::Method::NOTIFY__E) {
loggers::get_instance().warning("sip_codec_notify_request::decode: Wrong SIP Method, expected NOTIFY");
return -1;
}
return 0;
}
#pragma once
#include "sip_codec_request.hh"
class Base_Type;
class TTCN_Typedescriptor_t;
class TTCN_Buffer;
namespace LibSip__SIPTypesAndValues {
class NOTIFY__Request;
}
class sip_codec_notify_request: public codec_gen <
LibSip__SIPTypesAndValues::NOTIFY__Request,
LibSip__SIPTypesAndValues::NOTIFY__Request>
{
sip_codec_request _codec;
public:
explicit sip_codec_notify_request() : codec_gen<LibSip__SIPTypesAndValues::NOTIFY__Request, LibSip__SIPTypesAndValues::NOTIFY__Request>(), _codec() { };
virtual ~sip_codec_notify_request() { };
virtual int encode (const LibSip__SIPTypesAndValues::NOTIFY__Request& msg, OCTETSTRING& data);
virtual int decode (const OCTETSTRING& data, LibSip__SIPTypesAndValues::NOTIFY__Request& msg, params* p_params = NULL);
}; // End of class sip_codec_notify_request
#include "LibSip_SIPTypesAndValues.hh"
#include "sip_codec_options_request.hh"
#include "loggers.hh"
int sip_codec_options_request::encode (const LibSip__SIPTypesAndValues::OPTIONS__Request& msg, OCTETSTRING& data)
{
loggers::get_instance().log_msg(">>> sip_codec_options_request::encode: ", (const Base_Type&)msg);
if (_codec.encode((LibSip__SIPTypesAndValues::Request&)msg, data) == -1) {
loggers::get_instance().warning("sip_codec_options_request::encode: Failed to encode message");
return -1;
}
loggers::get_instance().log_msg("<<< sip_codec_options_request::encode: data=", data);
return 0;
}
int sip_codec_options_request::decode (const OCTETSTRING& data, LibSip__SIPTypesAndValues::OPTIONS__Request& msg, params* p_params)
{
loggers::get_instance().log_msg(">>> sip_codec_options_request::decode: data=", data);
// Sanity checks
if (data.lengthof() == 0) {
loggers::get_instance().warning("sip_codec_options_request::decode: Wrong parameters");
return -1;
}
// LibSip__SIPTypesAndValues::Request request;
if (_codec.decode(data, (LibSip__SIPTypesAndValues::Request&)msg) == -1) {
// if (_codec.decode(data, request) == -1) {
loggers::get_instance().warning("sip_codec_options_request::decode: Failed to decode message");
return -1;
}
// msg.requestLine() = request.requestLine();
// msg.msgHeader() = request.msgHeader();
// msg.messageBody() = request.messageBody();
// msg.payload() = request.payload();
if (msg.requestLine().method() != LibSip__SIPTypesAndValues::Method::OPTIONS__E) {
loggers::get_instance().warning("sip_codec_options_request::decode: Wrong SIP Method, expected OPTIONS");
return -1;
}
return 0;
}
#pragma once
#include "sip_codec_request.hh"
class Base_Type;
class TTCN_Typedescriptor_t;
class TTCN_Buffer;
namespace LibSip__SIPTypesAndValues {
class OPTIONS__Request;
}
class sip_codec_options_request: public codec_gen <
LibSip__SIPTypesAndValues::OPTIONS__Request,
LibSip__SIPTypesAndValues::OPTIONS__Request>
{
sip_codec_request _codec;
public:
explicit sip_codec_options_request() : codec_gen<LibSip__SIPTypesAndValues::OPTIONS__Request, LibSip__SIPTypesAndValues::OPTIONS__Request>(), _codec() { };
virtual ~sip_codec_options_request() { };
virtual int encode (const LibSip__SIPTypesAndValues::OPTIONS__Request& msg, OCTETSTRING& data);
virtual int decode (const OCTETSTRING& data, LibSip__SIPTypesAndValues::OPTIONS__Request& msg, params* p_params = NULL);
}; // End of class sip_codec_options_request
#include "LibSip_SIPTypesAndValues.hh"
#include "sip_codec_register_request.hh"
#include "loggers.hh"
int sip_codec_register_request::encode (const LibSip__SIPTypesAndValues::REGISTER__Request& msg, OCTETSTRING& data)
{
loggers::get_instance().log_msg(">>> sip_codec_register_request::encode: ", (const Base_Type&)msg);
if (_codec.encode((LibSip__SIPTypesAndValues::Request&)msg, data) == -1) {
loggers::get_instance().warning("sip_codec_register_request::encode: Failed to encode message");
return -1;
}
loggers::get_instance().log_msg("<<< sip_codec_register_request::encode: data=", data);
return 0;
}
int sip_codec_register_request::decode (const OCTETSTRING& data, LibSip__SIPTypesAndValues::REGISTER__Request& msg, params* p_params)
{
loggers::get_instance().log_msg(">>> sip_codec_register_request::decode: data=", data);
// Sanity checks
if (data.lengthof() == 0) {
loggers::get_instance().warning("sip_codec_register_request::decode: Wrong parameters");
return -1;
}
// LibSip__SIPTypesAndValues::Request request;
if (_codec.decode(data, (LibSip__SIPTypesAndValues::Request&)msg) == -1) {
// if (_codec.decode(data, request) == -1) {
loggers::get_instance().warning("sip_codec_register_request::decode: Failed to decode message");
return -1;
}
// msg.requestLine() = request.requestLine();
// msg.msgHeader() = request.msgHeader();
// msg.messageBody() = request.messageBody();
// msg.payload() = request.payload();
if (msg.requestLine().method() != LibSip__SIPTypesAndValues::Method::REGISTER__E) {
loggers::get_instance().warning("sip_codec_register_request::decode: Wrong SIP Method, expected REGISTER");
return -1;
}
return 0;
}
#pragma once
#include "sip_codec_request.hh"
class Base_Type;
class TTCN_Typedescriptor_t;
class TTCN_Buffer;
namespace LibSip__SIPTypesAndValues {
class REGISTER__Request;
}
class sip_codec_register_request: public codec_gen <
LibSip__SIPTypesAndValues::REGISTER__Request,
LibSip__SIPTypesAndValues::REGISTER__Request>
{
sip_codec_request _codec;
public:
explicit sip_codec_register_request() : codec_gen<LibSip__SIPTypesAndValues::REGISTER__Request, LibSip__SIPTypesAndValues::REGISTER__Request>(), _codec() { };
virtual ~sip_codec_register_request() { };
virtual int encode (const LibSip__SIPTypesAndValues::REGISTER__Request& msg, OCTETSTRING& data);
virtual int decode (const OCTETSTRING& data, LibSip__SIPTypesAndValues::REGISTER__Request& msg, params* p_params = NULL);
}; // End of class sip_codec_register_request
#include "LibSip_SIPTypesAndValues.hh"
#include "LibSip_Common.hh"
#include "sip_codec_request.hh"
#include "loggers.hh"
#include "converter.hh"
#ifdef WIN32
#undef osip_malloc
#undef osip_free
#define osip_malloc(S) malloc(S)
#define osip_free(P) { if (P!=NULL) { free(P);} }
#endif
int sip_codec_request::encode (const LibSip__SIPTypesAndValues::Request& msg, OCTETSTRING& data)
{
loggers::get_instance().log_msg(">>> sip_codec_request::encode: ", (const Base_Type&)msg);
TRACE_INITIALIZE(TRACE_LEVEL7, NULL);
OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, ">>> sip_codec_request::encode\n"));
osip_message_t* sip_message = nullptr; // TODO Use smart pointer
::parser_init();
int result = ::osip_message_init(&sip_message);
if (result != 0) {
loggers::get_instance().warning("sip_codec_request::encode: Failed to initialise internal data structures");
return -1;
}
if (encode_request(msg, sip_message) == -1) {
loggers::get_instance().warning("sip_codec_request::encode: Failed to encode Request");
::osip_message_free(sip_message);
sip_message = nullptr;
return -1;
}
char* buffer = nullptr;
size_t length = 0;
result = ::osip_message_to_str(sip_message, &buffer, &length);
if (result != 0) {
loggers::get_instance().warning("sip_codec_request::encode: Failed to encode data structures");
::osip_message_free(sip_message);
return -1;
}
loggers::get_instance().log("sip_codec_request::encode: Message:%s", buffer);
data = OCTETSTRING(length, (const unsigned char*)buffer);
osip_free(buffer);
::osip_message_free(sip_message);
loggers::get_instance().log_msg("<<< sip_codec_request::encode: data=", data);
return result;
}
int sip_codec_request::decode (const OCTETSTRING& data, LibSip__SIPTypesAndValues::Request& msg, params* p_params)
{
loggers::get_instance().log_msg(">>> sip_codec_request::decode: data=", data);
TRACE_INITIALIZE(TRACE_LEVEL7, NULL);
OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, ">>> sip_codec_request::decode\n"));
// Sanity checks
if (data.lengthof() == 0) {
loggers::get_instance().warning("sip_codec_request::decode: Wrong parameters");
return -1;
}
osip_message_t* sip_message;
::parser_init();
int result = ::osip_message_init(&sip_message);
if (result != 0) {
loggers::get_instance().warning("sip_codec_request::decode: Failed to initialise internal data structures");
return -1;
}
result = ::osip_message_parse(sip_message, (const char*)static_cast<const unsigned char*>(data), data.lengthof());
if (result != 0) {
loggers::get_instance().warning("sip_codec_request::decode: Failed to parse SIP message");
::osip_message_free(sip_message);
return -1;
}
// Fill RequestLine
decode_request_line(sip_message, msg);
// Fill Headers
decode_request_headers(sip_message, msg);
// Fill MessageBody
decode_message_body(sip_message, msg.messageBody());
// Fill Payload
decode_payload(sip_message, msg);
::osip_message_free(sip_message);
loggers::get_instance().log_msg("sip_codec_request::decode: ", msg);
return 0;
}
int sip_codec_request::encode_request(const LibSip__SIPTypesAndValues::Request& p_request, osip_message_t* p_sip_message)
{
loggers::get_instance().log(">>> sip_codec_request::encode_request");
encode_request_line(p_request.requestLine(), p_sip_message);
encode_request_headers(p_request.msgHeader(), p_sip_message);
if (p_request.messageBody().is_present()) {
const LibSip__MessageBodyTypes::MessageBody& m = static_cast<const LibSip__MessageBodyTypes::MessageBody&>(*p_request.messageBody().get_opt_value());
encode_message_body(m, p_sip_message);
}
if (p_request.payload().is_present()) {
const LibSip__SIPTypesAndValues::Payload& p = static_cast<const LibSip__SIPTypesAndValues::Payload&>(*p_request.payload().get_opt_value());
encode_request_payload(p, p_sip_message);
}
return 0;
} // End of method encode_request
int sip_codec_request::encode_request_line(const LibSip__SIPTypesAndValues::RequestLine& p_request_line, osip_message_t* p_sip_message)
{
loggers::get_instance().log_msg(">>> sip_codec_request::encode_request_line", p_request_line);
// Sip method
std::string str(LibSip__SIPTypesAndValues::Method::enum_to_str(p_request_line.method()));
char *p = (char*)osip_malloc(str.length() - 2 + 1); // Will be freed by osip_message_free
::strcpy(p, str.substr(0, str.length() - 2).c_str()); // Remove _E
::osip_message_set_method(p_sip_message, p);
// Sip uri
osip_uri_t *uri;
if (encode_sip_url(p_request_line.requestUri(), &uri) == -1) {
loggers::get_instance().warning("sip_codec_request::encode_request_line: Faile to encode SipUrl");
return -1;
}
::osip_message_set_uri(p_sip_message, uri);
// FIXME: Add parameter to support udp/tcp/tls transport
//::osip_uri_set_transport_tcp(uri);
::osip_uri_set_transport_tls(uri);
// SIP version
p = (char*)osip_malloc(p_request_line.sipVersion().lengthof() + 1); // Will be freed by osip_message_free
::strcpy(p, (char*)static_cast<const char*>(p_request_line.sipVersion()));
::osip_message_set_version(p_sip_message, p);
return 0;
} // End of method encode_request_line
int sip_codec_request::encode_request_headers(const LibSip__SIPTypesAndValues::MessageHeader& p_msg_header, osip_message_t* p_sip_message)
{ // TODO Rename to encode_headers and call sip_codec_headers::encode_headers
loggers::get_instance().log_msg(">>> sip_codec_request::encode_request_headers: ", p_msg_header);
if (encode_headers(p_msg_header, p_sip_message) == -1) {
loggers::get_instance().warning("sip_codec_request::encode_request_headers: Failed to encode headers");
return -1;
}
return 0;
} // End of method encode_request_headers
int sip_codec_request::encode_request_payload(const LibSip__SIPTypesAndValues::Payload& p_payload, osip_message_t* p_sip_message)
{
loggers::get_instance().log(">>> sip_codec_request::encode_request_payload");
return 0;
} // End of method encode_request_payload
void sip_codec_request::decode_request_headers(const osip_message_t* p_sip_message, LibSip__SIPTypesAndValues::Request& p_request)
{ // TODO rename into decode_headers and call sip_code_headers::decode_headers
loggers::get_instance().log(">>> sip_codec_request::decode_request_headers");
LibSip__SIPTypesAndValues::MessageHeader& headers = p_request.msgHeader();
decode_headers(p_sip_message, headers);
if (!headers.is_bound()) {
loggers::get_instance().warning("sip_codec_request::decode_request_headers: Failed to decode headers");
return;
}
loggers::get_instance().log_msg("<<< sip_codec_request::decode_request_headers: ", p_request);
} // End of method decode_request_headers
void sip_codec_request::decode_payload(const osip_message_t* p_sip_message, LibSip__SIPTypesAndValues::Request& p_request)
{
loggers::get_instance().log(">>> sip_codec_request::decode_payload");
p_request.payload().set_to_omit();
} // End of method decode_payload
void sip_codec_request::decode_request_line(const osip_message_t* p_sip_message, LibSip__SIPTypesAndValues::Request& p_request)
{
loggers::get_instance().log(">>> sip_codec_request::decode_request_line");
LibSip__SIPTypesAndValues::RequestLine request_line;
std::string str(::osip_message_get_method(p_sip_message));
str += "_E";
request_line.method() = LibSip__SIPTypesAndValues::Method(LibSip__SIPTypesAndValues::Method::str_to_enum(str.c_str()));
loggers::get_instance().log_msg("sip_codec_request::decode_request_line: Method: ", request_line.method());
LibSip__SIPTypesAndValues::SipUrl uri;
decode_uri(uri, ::osip_message_get_uri(p_sip_message));
loggers::get_instance().log_msg("sip_codec_request::decode_request_line: SipUrl: ", uri);
request_line.requestUri() = uri;
request_line.sipVersion() = CHARSTRING(::osip_message_get_version(p_sip_message));
p_request.requestLine() = request_line;
// FIXME To be continued
loggers::get_instance().log_msg("<<< sip_codec_request::decode_request_line: ", p_request);
}
#pragma once
#include "codec_gen.hh"
#include "params.hh"
#include "sip_codec_headers.hh"
#include "sip_codec_message_body.hh"
#include "osipparser2/osip_parser.h"
#include "osipparser2/sdp_message.h"
class Base_Type;
class TTCN_Typedescriptor_t;
class TTCN_Buffer;
namespace LibSip__SIPTypesAndValues {
class Request;
class RequestLine;
class MessageHeader;
class Payload;
}
class sip_codec_request: public codec_gen <
LibSip__SIPTypesAndValues::Request,
LibSip__SIPTypesAndValues::Request>,
sip_codec_headers, sip_codec_message_body
{
public:
explicit sip_codec_request() : codec_gen<LibSip__SIPTypesAndValues::Request, LibSip__SIPTypesAndValues::Request>() { };
virtual ~sip_codec_request() { };
virtual int encode (const LibSip__SIPTypesAndValues::Request& msg, OCTETSTRING& data);
virtual int decode (const OCTETSTRING& data, LibSip__SIPTypesAndValues::Request& msg, params* p_params = NULL);
private:
int encode_request(const LibSip__SIPTypesAndValues::Request& p_request, osip_message_t* p_sip_message);
int encode_request_line(const LibSip__SIPTypesAndValues::RequestLine& p_request_line, osip_message_t* p_sip_message);
int encode_request_headers(const LibSip__SIPTypesAndValues::MessageHeader& p_msg_header, osip_message_t* p_sip_message);
int encode_request_payload(const LibSip__SIPTypesAndValues::Payload& p_payload, osip_message_t* p_sip_message);
private:
void decode_payload(const osip_message_t* p_sip_message, LibSip__SIPTypesAndValues::Request& p_request);
void decode_request_line(const osip_message_t* p_sip_message, LibSip__SIPTypesAndValues::Request& msg);
void decode_request_headers(const osip_message_t* p_sip_message, LibSip__SIPTypesAndValues::Request& msg);
}; // End of class sip_codec_request
#include "LibSip_SIPTypesAndValues.hh"
#include "LibSip_Common.hh"
#include "sip_codec_response.hh"
#include "loggers.hh"
#include "converter.hh"
#ifdef WIN32
#undef osip_malloc
#undef osip_free
#define osip_malloc(S) malloc(S)
#define osip_free(P) { if (P!=NULL) { free(P);} }
#endif
int sip_codec_response::encode (const LibSip__SIPTypesAndValues::Response& msg, OCTETSTRING& data)
{
loggers::get_instance().log_msg(">>> sip_codec_response::encode: ", (const Base_Type&)msg);
osip_message_t* sip_message = nullptr; // TODO Use smart pointer
::parser_init();
int result = ::osip_message_init(&sip_message);
if (result != 0) {
loggers::get_instance().warning("sip_codec_response::encode: Failed to initialise internal data structures");
return -1;
}
if (encode_response(msg, sip_message) == -1) {
loggers::get_instance().warning("sip_codec_response::encode: Failed to encode Response");
::osip_message_free(sip_message);
sip_message = nullptr;
return -1;
}
char* buffer = nullptr;
size_t length = 0;
result = ::osip_message_to_str(sip_message, &buffer, &length);
if (result != 0) {
loggers::get_instance().warning("sip_codec_response::encode: Failed to encode data structures: return code=%d", result);
::osip_message_free(sip_message);
return -1;
}
loggers::get_instance().log("sip_codec_response::encode: Message:%s", buffer);
data = OCTETSTRING(length, (const unsigned char*)buffer);
osip_free(buffer);
::osip_message_free(sip_message);
loggers::get_instance().log_msg("<<< sip_codec_response::encode: data=", data);
return result;
}
int sip_codec_response::decode (const OCTETSTRING& data, LibSip__SIPTypesAndValues::Response& msg, params* p_params)
{
loggers::get_instance().log_msg(">>> sip_codec_response::decode: data=", data);
// Sanity checks
if (data.lengthof() == 0) {
loggers::get_instance().warning("sip_codec_response::decode: Wrong parameters");
return -1;
}
osip_message_t* sip_message;
::parser_init();
int result = ::osip_message_init(&sip_message);
if (result != 0) {
loggers::get_instance().warning("sip_codec_response::decode: Failed to initialise internal data structures");
return -1;
}
result = ::osip_message_parse(sip_message, (const char*)static_cast<const unsigned char*>(data), data.lengthof());
if (result != 0) {
loggers::get_instance().warning("sip_codec_response::decode: Failed to parse SIP message");
::osip_message_free(sip_message);
return -1;
}
// Fill StatusLine
decode_status_line(sip_message, msg);
// Fill Headers
decode_response_headers(sip_message, msg);
// Fill MessageBody
decode_message_body(sip_message, msg.messageBody());
// Fill Payload
decode_payload(sip_message, msg);
::osip_message_free(sip_message);
loggers::get_instance().log_msg("sip_codec_response::decode: ", msg);
return 0;
}
int sip_codec_response::encode_response(const LibSip__SIPTypesAndValues::Response& p_response, osip_message_t* p_sip_message)
{
loggers::get_instance().log(">>> sip_codec_response::encode_response");
encode_status_line(p_response.statusLine(), p_sip_message);
encode_response_headers(p_response.msgHeader(), p_sip_message);
if (p_response.messageBody().is_present()) {
const LibSip__MessageBodyTypes::MessageBody& m = static_cast<const LibSip__MessageBodyTypes::MessageBody&>(*p_response.messageBody().get_opt_value());
encode_message_body(m, p_sip_message);
}
if (p_response.payload().is_present()) {
const LibSip__SIPTypesAndValues::Payload& p = static_cast<const LibSip__SIPTypesAndValues::Payload&>(*p_response.payload().get_opt_value());
encode_response_payload(p, p_sip_message);
}
return 0;
} // End of method encode_response
int sip_codec_response::encode_status_line(const LibSip__SIPTypesAndValues::StatusLine& p_status_line, osip_message_t* p_sip_message)
{
loggers::get_instance().log(">>> sip_codec_response::encode_status_line");
// Sip version
char* p = (char*)osip_malloc(p_status_line.sipVersion().lengthof() + 1); // Will be freed by osip_message_free
::strcpy(p, (char*)static_cast<const char*>(p_status_line.sipVersion()));
::osip_message_set_version(p_sip_message, p);
// Status code
loggers::get_instance().log("sip_codec_response::encode_status_line: status code=%d", static_cast<const int>(p_status_line.statusCode()));
::osip_message_set_status_code(p_sip_message, static_cast<const int>(p_status_line.statusCode()));
// Reason phrase
p = (char*)osip_malloc(p_status_line.reasonPhrase().lengthof() + 1); // Will be freed by osip_message_free
::strcpy(p, (char*)static_cast<const char*>(p_status_line.reasonPhrase()));
::osip_message_set_reason_phrase(p_sip_message, p);
return 0;
} // End of method encode_status_line
int sip_codec_response::encode_response_headers(const LibSip__SIPTypesAndValues::MessageHeader& p_msg_header, osip_message_t* p_sip_message)
{ // TODO Rename to encode_headers and call sip_codec_headers::encode_headers
loggers::get_instance().log_msg(">>> sip_codec_response::encode_response_headers: ", p_msg_header);
if (encode_headers(p_msg_header, p_sip_message) == -1) {
loggers::get_instance().warning("sip_codec_response::encode_response_headers: Failed to encode headers");
return -1;
}
return 0;
} // End of method encode_response_headers
int sip_codec_response::encode_response_payload(const LibSip__SIPTypesAndValues::Payload& p_payload, osip_message_t* p_sip_message)
{
loggers::get_instance().log(">>> sip_codec_response::encode_response_payload");
return 0;
} // End of method encode_response_payload
void sip_codec_response::decode_status_line(const osip_message_t* p_sip_message, LibSip__SIPTypesAndValues::Response& p_response)
{
loggers::get_instance().log(">>> sip_codec_response::decode_status_line");
LibSip__SIPTypesAndValues::StatusLine status_line;
status_line.sipVersion() = CHARSTRING(::osip_message_get_version(p_sip_message));
loggers::get_instance().log_msg("sip_codec_response::decode_status_line: sipVersion: ", status_line.sipVersion());
status_line.statusCode() = INTEGER(osip_message_get_status_code(p_sip_message));
loggers::get_instance().log_msg("sip_codec_response::decode_status_line: statusCode: ", status_line.statusCode());
status_line.reasonPhrase() = CHARSTRING(::osip_message_get_reason_phrase(p_sip_message));
loggers::get_instance().log_msg("sip_codec_response::decode_status_line: reasonPhrase: ", status_line.reasonPhrase());
p_response.statusLine() = status_line;
loggers::get_instance().log_msg("<<< sip_codec_response::decode_status_line: ", p_response.statusLine());
} // End of method decode_status_line
void sip_codec_response::decode_response_headers(const osip_message_t* p_sip_message, LibSip__SIPTypesAndValues::Response& p_response)
{ // TODO rename into decode_headers and call sip_code_headers::decode_headers
loggers::get_instance().log(">>> sip_codec_response::decode_response_headers");
LibSip__SIPTypesAndValues::MessageHeader& headers = p_response.msgHeader();
decode_headers(p_sip_message, headers);
if (!headers.is_bound()) {
loggers::get_instance().warning("sip_codec_response::decode_response_headers: Failed to decode headers");
return;
}
loggers::get_instance().log_msg("<<< sip_codec_response::decode_response_headers: ", p_response);
} // End of method decode_response_headers
void sip_codec_response::decode_payload(const osip_message_t* p_sip_message, LibSip__SIPTypesAndValues::Response& p_response)
{
loggers::get_instance().log(">>> sip_codec_response::decode_payload");
p_response.payload().set_to_omit();
} // End of method decode_payload
#pragma once
#include "codec_gen.hh"
#include "params.hh"
#include "sip_codec_headers.hh"
#include "sip_codec_message_body.hh"
#include "osipparser2/osip_parser.h"
#include "osipparser2/sdp_message.h"
class Base_Type;
class TTCN_Typedescriptor_t;
class TTCN_Buffer;
namespace LibSip__SIPTypesAndValues {
class Response;
class StatusLine;
class MessageHeader;
class Payload;
}
class sip_codec_response: public codec_gen <
LibSip__SIPTypesAndValues::Response,
LibSip__SIPTypesAndValues::Response>,
sip_codec_headers, sip_codec_message_body
{
public:
explicit sip_codec_response() : codec_gen<LibSip__SIPTypesAndValues::Response, LibSip__SIPTypesAndValues::Response>() { };
virtual ~sip_codec_response() { };
virtual int encode (const LibSip__SIPTypesAndValues::Response& msg, OCTETSTRING& data);
virtual int decode (const OCTETSTRING& data, LibSip__SIPTypesAndValues::Response& msg, params* p_params = NULL);
private:
int encode_response(const LibSip__SIPTypesAndValues::Response& p_response, osip_message_t* p_sip_message);
int encode_status_line(const LibSip__SIPTypesAndValues::StatusLine& p_status_line, osip_message_t* p_sip_message);
int encode_response_headers(const LibSip__SIPTypesAndValues::MessageHeader& p_msg_header, osip_message_t* p_sip_message);
int encode_response_payload(const LibSip__SIPTypesAndValues::Payload& p_payload, osip_message_t* p_sip_message);
private:
void decode_status_line(const osip_message_t* p_sip_message, LibSip__SIPTypesAndValues::Response& msg);
void decode_response_headers(const osip_message_t* p_sip_message, LibSip__SIPTypesAndValues::Response& msg);
void decode_payload(const osip_message_t* p_sip_message, LibSip__SIPTypesAndValues::Response& p_response);
}; // End of class sip_codec_response
#include "LibSip_SIPTypesAndValues.hh"
#include "sip_codec_subscribe_request.hh"
#include "loggers.hh"
int sip_codec_subscribe_request::encode (const LibSip__SIPTypesAndValues::SUBSCRIBE__Request& msg, OCTETSTRING& data)
{
loggers::get_instance().log_msg(">>> sip_codec_subscribe_request::encode: ", (const Base_Type&)msg);
if (_codec.encode((LibSip__SIPTypesAndValues::Request&)msg, data) == -1) {
loggers::get_instance().warning("sip_codec_subscribe_request::encode: Failed to encode message");
return -1;
}
loggers::get_instance().log_msg("<<< sip_codec_subscribe_request::encode: data=", data);
return 0;
}
int sip_codec_subscribe_request::decode (const OCTETSTRING& data, LibSip__SIPTypesAndValues::SUBSCRIBE__Request& msg, params* p_params)
{
loggers::get_instance().log_msg(">>> sip_codec_subscribe_request::decode: data=", data);
// Sanity checks
if (data.lengthof() == 0) {
loggers::get_instance().warning("sip_codec_subscribe_request::decode: Wrong parameters");
return -1;
}
// LibSip__SIPTypesAndValues::Request request;
if (_codec.decode(data, (LibSip__SIPTypesAndValues::Request&)msg) == -1) {
// if (_codec.decode(data, request) == -1) {
loggers::get_instance().warning("sip_codec_subscribe_request::decode: Failed to decode message");
return -1;
}
// msg.requestLine() = request.requestLine();
// msg.msgHeader() = request.msgHeader();
// msg.messageBody() = request.messageBody();
// msg.payload() = request.payload();
if (msg.requestLine().method() != LibSip__SIPTypesAndValues::Method::SUBSCRIBE__E) {
loggers::get_instance().warning("sip_codec_subscribe_request::decode: Wrong SIP Method, expected SUBSCRIBE");
return -1;
}
return 0;
}
#pragma once
#include "sip_codec_request.hh"
class Base_Type;
class TTCN_Typedescriptor_t;
class TTCN_Buffer;
namespace LibSip__SIPTypesAndValues {
class SUBSCRIBE__Request;
}
class sip_codec_subscribe_request: public codec_gen <
LibSip__SIPTypesAndValues::SUBSCRIBE__Request,
LibSip__SIPTypesAndValues::SUBSCRIBE__Request>
{
sip_codec_request _codec;
public:
explicit sip_codec_subscribe_request() : codec_gen<LibSip__SIPTypesAndValues::SUBSCRIBE__Request, LibSip__SIPTypesAndValues::SUBSCRIBE__Request>(), _codec() { };
virtual ~sip_codec_subscribe_request() { };
virtual int encode (const LibSip__SIPTypesAndValues::SUBSCRIBE__Request& msg, OCTETSTRING& data);
virtual int decode (const OCTETSTRING& data, LibSip__SIPTypesAndValues::SUBSCRIBE__Request& msg, params* p_params = NULL);
}; // End of class sip_codec_subscribe_request
#include "LibSip_Interface.hh"
#include "LibSip_SIPTypesAndValues.hh"
#include "sip_layer_factory.hh"
#include "loggers.hh"
#include "converter.hh"
sip_layer::sip_layer(const std::string & p_type, const std::string & p_param) : t_layer<LibSip__Interface::SipPort>(p_type), _params(), _codec_request(), _codec_response(), _codec_register(), _codec_invite(), _codec_ack(), _codec_subscribe(), _codec_message(), _codec_options(), _codec_cancel(), _codec_notify(), _codec_info(), _codec_bye() {
loggers::get_instance().log(">>> sip_layer::sip_layer: %s, %s", to_string().c_str(), p_param.c_str());
// Setup parameters
params::convert(_params, p_param);
}
void sip_layer::sendMsg(const LibSip__SIPTypesAndValues::REGISTER__Request& p_sip_message, params& p_param) {
loggers::get_instance().log_msg(">>> sip_layer::sendMsg: ", p_sip_message);
// Encode SipMessage
OCTETSTRING data;
_codec_register.encode(p_sip_message, data);
send_data(data, _params);
}
void sip_layer::sendMsg(const LibSip__SIPTypesAndValues::INVITE__Request& p_sip_message, params& p_param) {
loggers::get_instance().log_msg(">>> sip_layer::sendMsg: ", p_sip_message);
// Encode SipMessage
OCTETSTRING data;
_codec_invite.encode(p_sip_message, data);
send_data(data, _params);
}
void sip_layer::sendMsg(const LibSip__SIPTypesAndValues::ACK__Request& p_sip_message, params& p_param) {
loggers::get_instance().log_msg(">>> sip_layer::sendMsg: ", p_sip_message);
// Encode SipMessage
OCTETSTRING data;
_codec_ack.encode(p_sip_message, data);
send_data(data, _params);
}
void sip_layer::sendMsg(const LibSip__SIPTypesAndValues::SUBSCRIBE__Request& p_sip_message, params& p_param) {
loggers::get_instance().log_msg(">>> sip_layer::sendMsg: ", p_sip_message);
// Encode SipMessage
OCTETSTRING data;
_codec_subscribe.encode(p_sip_message, data);
send_data(data, _params);
}
void sip_layer::sendMsg(const LibSip__SIPTypesAndValues::MESSAGE__Request& p_sip_message, params& p_param) {
loggers::get_instance().log_msg(">>> sip_layer::sendMsg: ", p_sip_message);
// Encode SipMessage
OCTETSTRING data;
_codec_message.encode(p_sip_message, data);
send_data(data, _params);
}
void sip_layer::sendMsg(const LibSip__SIPTypesAndValues::OPTIONS__Request& p_sip_message, params& p_param) {
loggers::get_instance().log_msg(">>> sip_layer::sendMsg: ", p_sip_message);
// Encode SipMessage
OCTETSTRING data;
_codec_options.encode(p_sip_message, data);
send_data(data, _params);
}
void sip_layer::sendMsg(const LibSip__SIPTypesAndValues::BYE__Request& p_sip_message, params& p_param) {
loggers::get_instance().log_msg(">>> sip_layer::sendMsg: ", p_sip_message);
// Encode SipMessage
OCTETSTRING data;
_codec_bye.encode(p_sip_message, data);
send_data(data, _params);
}
void sip_layer::sendMsg(const LibSip__SIPTypesAndValues::CANCEL__Request& p_sip_message, params& p_param) {
loggers::get_instance().log_msg(">>> sip_layer::sendMsg: ", p_sip_message);
// Encode SipMessage
OCTETSTRING data;
_codec_cancel.encode(p_sip_message, data);
send_data(data, _params);
}
void sip_layer::sendMsg(const LibSip__SIPTypesAndValues::NOTIFY__Request& p_sip_message, params& p_param) {
loggers::get_instance().log_msg(">>> sip_layer::sendMsg: ", p_sip_message);
// Encode SipMessage
OCTETSTRING data;
_codec_notify.encode(p_sip_message, data);
send_data(data, _params);
}
void sip_layer::sendMsg(const LibSip__SIPTypesAndValues::INFO__Request& p_sip_message, params& p_param) {
loggers::get_instance().log_msg(">>> sip_layer::sendMsg: ", p_sip_message);
// Encode SipMessage
OCTETSTRING data;
_codec_info.encode(p_sip_message, data);
send_data(data, _params);
}
void sip_layer::sendMsg(const LibSip__SIPTypesAndValues::Response& p_sip_message, params& p_param) {
loggers::get_instance().log_msg(">>> sip_layer::sendMsg: ", p_sip_message);
// Encode SipMessage
OCTETSTRING data;
_codec_response.encode(p_sip_message, data);
send_data(data, _params);
}
void sip_layer::send_data(OCTETSTRING& data, params& p_params) {
loggers::get_instance().log_msg(">>> sip_layer::send_data: ", data);
send_to_all_layers(data, p_params);
}
void sip_layer::receive_data(OCTETSTRING& data, params& p_params)
{
loggers::get_instance().log_msg(">>> sip_layer::receive_data: ", data);
// Decode SIP message
if ((data[0].get_octet() == 'S') && (data[1].get_octet() == 'I') && (data[2].get_octet() == 'P')) { // SIP... Assume it is a responce
LibSip__SIPTypesAndValues::Response sip_response;
if (_codec_response.decode(data, sip_response) == -1) {
loggers::get_instance().warning("sip_layer::receive_data: Failed to decode response data");
return;
}
// Pass it to the ports
to_all_upper_ports(sip_response, p_params);
} else { // Assume it is a request
LibSip__SIPTypesAndValues::Request sip_request;
if (_codec_request.decode(data, sip_request) == -1) {
loggers::get_instance().warning("sip_layer::receive_data: Failed to decode request data");
return;
}
// Pass it to the ports
to_all_upper_ports(sip_request, p_params);
}
}
sip_layer_factory sip_layer_factory::_f;
/*!
* \file sip_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 "sip_codec_request.hh"
#include "sip_codec_response.hh"
#include "sip_codec_register_request.hh"
#include "sip_codec_invite_request.hh"
#include "sip_codec_ack_request.hh"
#include "sip_codec_subscribe_request.hh"
#include "sip_codec_message_request.hh"
#include "sip_codec_options_request.hh"
#include "sip_codec_notify_request.hh"
#include "sip_codec_cancel_request.hh"
#include "sip_codec_info_request.hh"
#include "sip_codec_bye_request.hh"
namespace LibSip__Interface {
class SipPort; //! Forward declaration of TITAN class
}
namespace LibSip__SIPTypesAndValues {
class REGISTER__Request; //! Forward declaration of TITAN class
class INVITE__Request; //! Forward declaration of TITAN class
class ACK__Request; //! Forward declaration of TITAN class
class SUSCRIBE__Request; //! Forward declaration of TITAN class
class MESSAGE__Request; //! Forward declaration of TITAN class
class OPTIONS__Request; //! Forward declaration of TITAN class
class CANCEL__Request; //! Forward declaration of TITAN class
class NOTIFY__Request; //! Forward declaration of TITAN class
class INFO__Request; //! Forward declaration of TITAN class
class BYE__Request; //! Forward declaration of TITAN class
class Resquest; //! Forward declaration of TITAN class
class Response; //! Forward declaration of TITAN class
}
class OCTETSTRING; //! Forward declaration of TITAN class
/*!
* \class sip_layer
* \brief This class provides a factory class to create an sip_layer class instance
*/
class sip_layer : public t_layer<LibSip__Interface::SipPort> {
params _params;
sip_codec_request _codec_request;
sip_codec_response _codec_response;
sip_codec_register_request _codec_register;
sip_codec_invite_request _codec_invite;
sip_codec_ack_request _codec_ack;
sip_codec_subscribe_request _codec_subscribe;
sip_codec_message_request _codec_message;
sip_codec_options_request _codec_options;
sip_codec_cancel_request _codec_cancel;
sip_codec_notify_request _codec_notify;
sip_codec_info_request _codec_info;
sip_codec_bye_request _codec_bye;
public: //! \publicsection
/*!
* \brief Specialised constructor
* Create a new instance of the sip_layer class
* \param[in] p_type \todo
* \param[in] p_param \todo
*/
sip_layer() : t_layer<LibSip__Interface::SipPort>(), _params(), _codec_request(), _codec_response(), _codec_register(), _codec_invite(), _codec_ack(), _codec_subscribe(), _codec_message(), _codec_options(), _codec_cancel(), _codec_notify(), _codec_info(), _codec_bye() {};
/*!
* \brief Specialised constructor
* Create a new instance of the sip_layer class
* \param[in] p_type \todo
* \param[in] p_param \todo
*/
sip_layer(const std::string& p_type, const std::string& p_param);
/*!
* \brief Default destructor
*/
virtual ~sip_layer() { };
void sendMsg(const LibSip__SIPTypesAndValues::REGISTER__Request& p_sip_message, params& p_param);
void sendMsg(const LibSip__SIPTypesAndValues::INVITE__Request& p_sip_message, params& p_param);
void sendMsg(const LibSip__SIPTypesAndValues::ACK__Request& p_sip_message, params& p_param);
void sendMsg(const LibSip__SIPTypesAndValues::SUBSCRIBE__Request& p_sip_message, params& p_param);
void sendMsg(const LibSip__SIPTypesAndValues::MESSAGE__Request& p_sip_message, params& p_param);
void sendMsg(const LibSip__SIPTypesAndValues::OPTIONS__Request& p_sip_message, params& p_param);
void sendMsg(const LibSip__SIPTypesAndValues::BYE__Request& p_sip_message, params& p_param);
void sendMsg(const LibSip__SIPTypesAndValues::CANCEL__Request& p_sip_message, params& p_param);
void sendMsg(const LibSip__SIPTypesAndValues::NOTIFY__Request& p_sip_message, params& p_param);
void sendMsg(const LibSip__SIPTypesAndValues::INFO__Request& p_sip_message, params& p_param);
void sendMsg(const LibSip__SIPTypesAndValues::Response& p_sip_message, params& p_param);
/*!
* \virtual
* \fn void send_data(OCTETSTRING& data, params& p_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& p_params);
/*!
* \virtual
* \fn void receive_data(OCTETSTRING& data, params& p_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 sip_layer
/*!
* \file sip_layer_factory.hh
* \brief Header file for ITS Sip 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 "sip_layer.hh"
/*!
* \class sip_layer_factory
* \brief This class provides a factory class to create an sip_layer class instance
*/
class sip_layer_factory : public layer_factory {
static sip_layer_factory _f; //! Reference to the unique instance of this class
public: //! \publicsection
/*!
* \brief Default constructor
* Create a new instance of the udp_layer_factory class
* \remark The HTTP layer identifier is HTTP
*/
sip_layer_factory() {
// Register factory
layer_stack_builder::register_layer_factory("SIP", 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 sip_layer(p_type, p_param);
};
}; // End of class sip_layer_factory