diff options
Diffstat (limited to 'bindings/_common/SipMessage.cxx')
-rw-r--r-- | bindings/_common/SipMessage.cxx | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/bindings/_common/SipMessage.cxx b/bindings/_common/SipMessage.cxx new file mode 100644 index 0000000..a4f09fd --- /dev/null +++ b/bindings/_common/SipMessage.cxx @@ -0,0 +1,289 @@ +/* +* Copyright (C) 2010-2011 Mamadou Diop. +* +* Contact: Mamadou Diop <diopmamadou(at)doubango.org> +* +* This file is part of Open Source Doubango Framework. +* +* DOUBANGO is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* DOUBANGO is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with DOUBANGO. +* +*/ +#include "SipMessage.h" + + +SdpMessage::SdpMessage() +:m_pSdpMessage(tsk_null) +{ +} + +SdpMessage::SdpMessage(tsdp_message_t *_sdpmessage) +{ + m_pSdpMessage = (tsdp_message_t *)tsk_object_ref(_sdpmessage); +} + +SdpMessage::~SdpMessage() +{ + TSK_OBJECT_SAFE_FREE(m_pSdpMessage); +} + +char* SdpMessage::getSdpHeaderValue(const char* media, char name, unsigned index /*= 0*/) +{ + const tsdp_header_M_t* M; + + if((M = (const tsdp_header_M_t*)tsdp_message_get_header(m_pSdpMessage, tsdp_htype_M))){ + tsdp_header_type_t type = tsdp_htype_Dummy; + const tsdp_header_t* header; + switch(name){ + case 'a': type = tsdp_htype_A; break; + case 'b': type = tsdp_htype_B; break; + case 'c': type = tsdp_htype_C; break; + case 'e': type = tsdp_htype_E; break; + case 'i': type = tsdp_htype_I; break; + case 'k': type = tsdp_htype_K; break; + case 'm': type = tsdp_htype_M; break; + case 'o': type = tsdp_htype_O; break; + + + case 'p': type = tsdp_htype_P; break; + case 'r': type = tsdp_htype_R; break; + case 's': type = tsdp_htype_S; break; + case 't': type = tsdp_htype_T; break; + case 'u': type = tsdp_htype_U; break; + case 'v': type = tsdp_htype_V; break; + case 'z': type = tsdp_htype_Z; break; + } + + if((header = tsdp_message_get_headerAt(m_pSdpMessage, type, index))){ + return tsdp_header_tostring(header); + } + } + + return tsk_null; +} + +char* SdpMessage::getSdpHeaderAValue(const char* media, const char* attributeName) +{ + const tsdp_header_M_t* M; + tsk_size_t i; + + for(i = 0; (M = (const tsdp_header_M_t*)tsdp_message_get_headerAt(m_pSdpMessage, tsdp_htype_M, i)); i++){ + if(tsk_striequals(M->media, media)){ + const tsdp_header_A_t* A; + if((A = tsdp_header_M_findA(M, attributeName))){ + return tsk_strdup(A->value); + } + } + } + + return tsk_null; +} + + +SipMessage::SipMessage() +:m_pSipMessage(tsk_null), m_pSdpMessage(tsk_null) +{ +} + +SipMessage::SipMessage(tsip_message_t *_sipmessage) +: m_pSdpMessage(tsk_null) +{ + m_pSipMessage = (tsip_message_t *)tsk_object_ref(_sipmessage); +} + +SipMessage::~SipMessage() +{ + TSK_OBJECT_SAFE_FREE(m_pSipMessage); + if(m_pSdpMessage){ + delete m_pSdpMessage; + } +} + +bool SipMessage::isResponse() +{ + return TSIP_MESSAGE_IS_RESPONSE(m_pSipMessage); +} + +tsip_request_type_t SipMessage::getRequestType() +{ + if(TSIP_MESSAGE_IS_REQUEST(m_pSipMessage)){ + return (m_pSipMessage)->line.request.request_type; + } + return tsip_NONE; +} + +short SipMessage::getResponseCode() +{ + return TSIP_RESPONSE_CODE(m_pSipMessage); +} + +const char* SipMessage::getResponsePhrase() +{ + return TSIP_RESPONSE_PHRASE(m_pSipMessage); +} + +const tsip_header_t* SipMessage::getSipHeader(const char* name, unsigned index /* =0 */) +{ + /* Do not worry about calling tsk_striequals() several times because the function + * is fully optimized. + */ + /* Code below comes from tsip_message_get_headerAt() */ + tsk_size_t pos = 0; + const tsk_list_item_t *item; + const tsip_header_t* hdr = tsk_null; + if(!m_pSipMessage || !name){ + return tsk_null; + } + + if(tsk_striequals(name, "v") || tsk_striequals(name, "via")){ + if(index == 0){ + hdr = (const tsip_header_t*)m_pSipMessage->firstVia; + goto bail; + }else pos++; } + if(tsk_striequals(name, "f") || tsk_striequals(name, "from")){ + if(index == 0){ + hdr = (const tsip_header_t*)m_pSipMessage->From; + goto bail; + }else pos++; } + if(tsk_striequals(name, "t") || tsk_striequals(name, "to")){ + if(index == 0){ + hdr = (const tsip_header_t*)m_pSipMessage->To; + goto bail; + }else pos++; } + if(tsk_striequals(name, "m") || tsk_striequals(name, "contact")){ + if(index == 0){ + hdr = (const tsip_header_t*)m_pSipMessage->Contact; + goto bail; + }else pos++; } + if(tsk_striequals(name, "i") || tsk_striequals(name, "call-id")){ + if(index == 0){ + hdr = (const tsip_header_t*)m_pSipMessage->Call_ID; + goto bail; + }else pos++; } + if(tsk_striequals(name, "cseq")){ + if(index == 0){ + hdr = (const tsip_header_t*)m_pSipMessage->CSeq; + goto bail; + }else pos++; } + if(tsk_striequals(name, "expires")){ + if(index == 0){ + hdr = (const tsip_header_t*)m_pSipMessage->Expires; + goto bail; + }else pos++; } + if(tsk_striequals(name, "c") || tsk_striequals(name, "content-type")){ + if(index == 0){ + hdr = (const tsip_header_t*)m_pSipMessage->Content_Type; + goto bail; + }else pos++; } + if(tsk_striequals(name, "l") || tsk_striequals(name, "content-length")){ + if(index == 0){ + hdr = (const tsip_header_t*)m_pSipMessage->Content_Length; + goto bail; + }else pos++; } + + + tsk_list_foreach(item, m_pSipMessage->headers){ + if(tsk_striequals(tsip_header_get_name_2(TSIP_HEADER(item->data)), name)){ + if(pos++ >= index){ + hdr = (const tsip_header_t*)item->data; + break; + } + } + } + + +bail: + return hdr; +} + +// e.g. getHeaderParamValue("content-type"); +char* SipMessage::getSipHeaderValue(const char* name, unsigned index /* = 0*/) +{ + const tsip_header_t* header; + if((header = this->getSipHeader(name, index))){ + + switch(header->type){ + case tsip_htype_From: + return tsip_uri_tostring(((const tsip_header_From_t*)header)->uri, tsk_false, tsk_false); + case tsip_htype_To: + return tsip_uri_tostring(((const tsip_header_To_t*)header)->uri, tsk_false, tsk_false); + break; + case tsip_htype_P_Asserted_Identity: + return tsip_uri_tostring(((const tsip_header_P_Asserted_Identity_t*)header)->uri, tsk_false, tsk_false); + break; + + default: + return tsip_header_value_tostring(header); + } + } + // SWIG: %newobject getHeaderValueAt; + return tsk_null; +} + +// e.g. getHeaderParamValue("content-type", "charset"); +char* SipMessage::getSipHeaderParamValue(const char* name, const char* param, unsigned index /*=0*/) +{ + const tsip_header_t* header; + + if((header = this->getSipHeader(name, index))){ + return tsip_header_get_param_value(header, param); + } + + // SWIG: %newobject getSipHeaderParamValue; + return tsk_null; +} + +/** Returns the content length. +*/ +unsigned SipMessage::getSipContentLength() +{ + return TSIP_MESSAGE_CONTENT_DATA_LENGTH(m_pSipMessage); +} + +/** Gets the message content +* @param output A pointer to the output buffer where to copy the data. MUST +* be allocated by the caller. +* @param maxsize The maximum number of octets to copy. Should be less than the size of the +* @a output buffer. You can use @a getSipContentLength() to get the right value to use. +* @retval The number of octet copied in the @a output buffer. +*/ +unsigned SipMessage::getSipContent(void* output, unsigned maxsize) +{ + unsigned retsize = 0; + if(output && maxsize && TSIP_MESSAGE_HAS_CONTENT(m_pSipMessage)){ + retsize = (m_pSipMessage->Content->size > maxsize) ? maxsize : m_pSipMessage->Content->size; + memcpy(output, m_pSipMessage->Content->data, retsize); + } + return retsize; +} + +const void* SipMessage::getSipContentPtr() +{ + if(m_pSipMessage && m_pSipMessage->Content){ + return m_pSipMessage->Content->data; + } + return tsk_null; +} + +const SdpMessage* SipMessage::getSdpMessage() +{ + if(!m_pSdpMessage && TSIP_MESSAGE_HAS_CONTENT(m_pSipMessage)){ + tsdp_message_t* sdp = tsdp_message_parse(m_pSipMessage->Content->data, m_pSipMessage->Content->size); + if(sdp){ + m_pSdpMessage = new SdpMessage(sdp); + TSK_OBJECT_SAFE_FREE(sdp); + } + } + + return m_pSdpMessage; +} |