c732d49e |
#if HAVE_CRT
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif //HAVE_CRT
/*
* Copyright (C) 2017, University of the Basque Country (UPV/EHU)
* Contact for licensing options: <licensing-mcpttclient(at)mcopenplatform(dot)com>
*
* The original file was part of Open Source Doubango Framework
* Copyright (C) 2010-2011 Mamadou Diop.
* Copyright (C) 2012 Doubango Telecom <http://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.
*
*/
/**@file tsip_api_message.c
* @brief Public short messaging (MESSAGE) functions.
*
* @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
*
*/ |
175b478c |
#include <tinysip/tsip_ssession.h> |
c732d49e |
#include "tinysip/api/tsip_api_message.h"
#include "tinysip/dialogs/tsip_dialog_layer.h"
#include "tinysip/dialogs/tsip_dialog_message.h"
#include "tinymedia/content/tmedia_content_multipart.h"
#include "tinysip/headers/tsip_header_Dummy.h"
#include "tinysip/tsip_message.h"
#include "tsip.h"
#include "tsk_memory.h"
#include "tsk_runnable.h"
#include "tsk_debug.h"
#define TSIP_MESSAGE_EVENT_CREATE( type) (tsip_message_event_t*)tsk_object_new(tsip_message_event_def_t, type)
#define VALUE_CONTENT_TYPE_MESSAGE_LOCATION "application/vnd.3gpp.mcptt-location-info+xml" |
175b478c |
|
c732d49e |
#define VALUE_CONTENT_TYPE_MESSAGE_AFFILIATION "application/vnd.3gpp.mcptt-affiliation-command+xml"
#define VALUE_CONTENT_TYPE_MESSAGE_MBMS "application/vnd.3gpp.mcptt-mbms-usage-info+xml"
#define VALUE_P_ASSERTED_SERVICE_MESSAGE_AFFILIATION "urn:urn-7:3gpp-service.ims.icsi.mcptt"
#define VALUE_P_ASSERTED_SERVICE_MESSAGE_MBMS "urn:urn-7:3gpp-service.ims.icsi.mcptt"
#define VALUE_CONTENT_TYPE_MULTIPART "multipart/mixed"
extern tsip_action_t* _tsip_action_create(tsip_action_type_t type, va_list* app);
|
175b478c |
#if HAVE_LIBXML2
static int register_xml_namespaces(xmlXPathContextPtr xpathCtx, const xmlChar* nsList)
{
xmlChar* nsListDup;
xmlChar* prefix;
xmlChar* href;
xmlChar* next;
nsListDup = xmlStrdup(nsList);
if(nsListDup == NULL)
{
return(-1);
}
next = nsListDup;
while(next != NULL)
{
/* skip spaces */
while((*next) == ' ') next++;
if((*next) == '\0') break;
/* find prefix */
prefix = next;
next = (xmlChar*)xmlStrchr(next, '=');
if(next == NULL)
{
xmlFree(nsListDup);
return(-1);
}
*(next++) = '\0';
/* find href */
href = next;
next = (xmlChar*)xmlStrchr(next, ' ');
if(next != NULL)
{
*(next++) = '\0';
}
if(href[0] == '\"' || href[0] == '\'')
{
href = href + 1;
if(href[strlen(href) - 1] == '\"' || href[strlen(href) - 1] == '\'')
href[strlen(href) - 1] = '\0';
}
/* do register namespace */
if(xmlXPathRegisterNs(xpathCtx, prefix, href) != 0)
{
xmlFree(nsListDup);
return(-1);
}
}
xmlFree(nsListDup);
return(0);
}
#endif
|
c732d49e |
int tsip_message_event_signal(tsip_message_event_type_t type, tsip_ssession_handle_t* ss, short status_code, const char *phrase, const tsip_message_t* sipmessage)
{
tsip_message_event_t* sipevent = TSIP_MESSAGE_EVENT_CREATE(type);
tmedia_content_multipart_t* mp_content = tsk_null;
tmedia_content_multipart_t* mp_content_sdp = tsk_null;
tmedia_multipart_body_t* mp_body = tsk_null;
char* boundary = tsk_null;
const tsip_header_t* header =tsk_null;
char* hdr_value=tsk_null;
uint32_t local_ssrc = 0;
char* psi_mbms_value=tsk_null;
//tmedia_session_t* audio_session;
//tsdp_message_t* sdp_ro = tsk_null;
int con=0;
char* sdp=tsk_null;
tsip_message_t* sipmessage2=tsk_null; |
175b478c |
|
c732d49e |
//if the messager is send
if((((tsip_ssession_t*)ss)->media.type & tmedia_mcptt_location) == tmedia_mcptt_location){
tsip_event_init(TSIP_EVENT(sipevent), ss, status_code, phrase, sipmessage, tsip_event_message_location);
}else
if(tsk_strcmp(TSIP_MESSAGE_CONTENT_TYPE(sipmessage),VALUE_CONTENT_TYPE_MESSAGE_LOCATION)==0){//it receive message
tsip_event_init(TSIP_EVENT(sipevent), ss, status_code, phrase, sipmessage, tsip_event_message_location);
}else
if(
tsk_strcmp(TSIP_MESSAGE_CONTENT_TYPE(sipmessage),VALUE_CONTENT_TYPE_MESSAGE_AFFILIATION)==0){//it receive message
for(con=0; (header = tsip_message_get_headerAt(sipmessage, tsip_htype_Dummy, con)); con++)
{
const tsip_header_Dummy_t* dummy_hdr = (const tsip_header_Dummy_t*)header;
if(tsk_strcmp(dummy_hdr->name, "P-Asserted-Service") == 0)
{
#if HAVE_CRT //Debug memory
hdr_value = (char *)malloc(tsk_strlen(dummy_hdr->value) * sizeof(char));
#else
hdr_value = (char *)tsk_malloc(tsk_strlen(dummy_hdr->value) * sizeof(char));
#endif //HAVE_CRT
hdr_value=strdup(dummy_hdr->value);
break;
}
/* else if(tsk_strcmp(dummy_hdr->name, "User-Agent") == 0)
{
len = tsk_strlen(dummy_hdr->value) + 19;
hdr_value = (char *)malloc(len * sizeof(char));
tsk_sprintf(&hdr_value, "PoC-client/OMA_PCPS_1.0 %s", dummy_hdr->value);
tsk_object_delete(dummy_hdr->value);
}*/
}
if((hdr_value)!=tsk_null &&
tsk_strcmp(hdr_value,VALUE_P_ASSERTED_SERVICE_MESSAGE_AFFILIATION)==0 ){
tsip_event_init(TSIP_EVENT(sipevent), ss, status_code, phrase, sipmessage, tsip_event_message_affiliation);
}
TSK_FREE(hdr_value);
}else if(tsk_striequals(VALUE_CONTENT_TYPE_MULTIPART, TSIP_MESSAGE_CONTENT_TYPE(sipmessage))){
//multipart/mixed
boundary = tsip_header_get_param_value((tsip_header_t*)sipmessage->Content_Type, "boundary");
if(boundary != tsk_null)
{
mp_body = tmedia_content_multipart_body_parse(TSIP_MESSAGE_CONTENT_DATA(sipmessage), TSIP_MESSAGE_CONTENT_DATA_LENGTH(sipmessage), VALUE_CONTENT_TYPE_MULTIPART, boundary);
if(mp_body != tsk_null)
{
mp_content = tmedia_content_multipart_body_get_content(mp_body,VALUE_CONTENT_TYPE_MESSAGE_LOCATION);
if(mp_content != tsk_null)//Location
{
//change de content for format location |
175b478c |
TSK_FREE(sipmessage->Content->data);
if ((sipmessage->Content->data = (char*)tsk_calloc((mp_content->data_size) + 1, sizeof(uint8_t)))) {
memcpy(sipmessage->Content->data, mp_content->data, mp_content->data_size);
((char *)sipmessage->Content->data)[mp_content->data_size]='\0';
} |
c732d49e |
sipmessage->Content->size=mp_content->data_size;
tsip_event_init(TSIP_EVENT(sipevent), ss, status_code, phrase, sipmessage, tsip_event_message_location); |
175b478c |
}else
if(1){
|
c732d49e |
mp_content = tmedia_content_multipart_body_get_content(mp_body,VALUE_CONTENT_TYPE_MESSAGE_AFFILIATION);
if(mp_content != tsk_null )//Affiliation
{
for(con=0; (header = tsip_message_get_headerAt(sipmessage, tsip_htype_Dummy, con)); con++)
{
const tsip_header_Dummy_t* dummy_hdr = (const tsip_header_Dummy_t*)header;
if(tsk_strcmp(dummy_hdr->name, "P-Asserted-Service") == 0)
{
#if HAVE_CRT //Debug memory
hdr_value = (char *)malloc(tsk_strlen(dummy_hdr->value) * sizeof(char));
#else
hdr_value = (char *)tsk_malloc(tsk_strlen(dummy_hdr->value) * sizeof(char));
#endif //HAVE_CRT
hdr_value=strdup(dummy_hdr->value);
break;
}
}
if((hdr_value)!=tsk_null &&
tsk_strcmp(hdr_value,VALUE_P_ASSERTED_SERVICE_MESSAGE_AFFILIATION)==0 ){
//change de content for format affiliation
//tsk_realloc(sipmessage->Content->data,mp_content->data_size);
TSK_FREE(sipmessage->Content->data)
sipmessage->Content->data=tsk_strndup(mp_content->data,mp_content->data_size);
sipmessage->Content->size=mp_content->data_size;
tsip_event_init(TSIP_EVENT(sipevent), ss, status_code, phrase, sipmessage, tsip_event_message_affiliation);
}
}
else{
tmedia_multipart_body_t* body = tsk_null;
char* content_type_hdr = tsk_null;
char* body_string = tsk_null;
//mp_content is xml of MBMS
mp_content = tmedia_content_multipart_body_get_content(mp_body,VALUE_CONTENT_TYPE_MESSAGE_MBMS);
//mp_content_sdp is the data in char* of SDP
mp_content_sdp = tmedia_content_multipart_body_get_content(mp_body, "application/sdp");
if(mp_content != tsk_null && mp_content_sdp!=tsk_null)//MBMS service
{
for(con=0; (header = tsip_message_get_headerAt(sipmessage, tsip_htype_Dummy, con)); con++)
{
const tsip_header_Dummy_t* dummy_hdr = (const tsip_header_Dummy_t*)header;
if(tsk_strcmp(dummy_hdr->name, "P-Asserted-Service") == 0)
{
#if HAVE_CRT //Debug memory
hdr_value = (char *)malloc(tsk_strlen(dummy_hdr->value) * sizeof(char));
#else
hdr_value = (char *)tsk_malloc(tsk_strlen(dummy_hdr->value) * sizeof(char));
#endif //HAVE_CRT
hdr_value=strdup(dummy_hdr->value);
break;
}
}
//SDP of MBMS message
if(mp_content_sdp == tsk_null){
TSK_DEBUG_ERROR("content-type is not supportted");
return -3;
}
if((hdr_value)!=tsk_null &&
tsk_strcmp(hdr_value,VALUE_P_ASSERTED_SERVICE_MESSAGE_MBMS)==0 ){
body = tmedia_content_multipart_body_create("multipart/mixed", tsk_null);
if(body)
{
tmedia_content_multipart_body_add_content(body, mp_content_sdp);
tmedia_content_multipart_body_add_content(body, mp_content);
body_string =tmedia_content_multipart_body_tostring(body);
content_type_hdr = tmedia_content_multipart_body_get_header(body);
sipmessage2=tsip_message_create();
tsip_message_add_content(sipmessage2, content_type_hdr, body_string, tsk_strlen(body_string));
}
/*
//change de content for format MBMS
tsk_realloc(sipmessage->Content->data,mp_content->data_size);
strcpy(sipmessage->Content->data, mp_content->data);
sipmessage->Content->size=mp_content->data_size;
*/
tsip_event_init(TSIP_EVENT(sipevent), ss, status_code, phrase, sipmessage, tsip_event_message_mbms);
}
}else{
TSK_DEBUG_ERROR("The new message isn't valid.");
tsip_event_init(TSIP_EVENT(sipevent), ss, status_code, phrase, sipmessage, tsip_event_message);
}
}
}
}
}else{
tsip_event_init(TSIP_EVENT(sipevent), ss, status_code, phrase, sipmessage, tsip_event_message);
}
}else
tsip_event_init(TSIP_EVENT(sipevent), ss, status_code, phrase, sipmessage, tsip_event_message);
if(hdr_value)
TSK_FREE(hdr_value);
TSK_RUNNABLE_ENQUEUE_OBJECT(TSK_RUNNABLE(TSIP_SSESSION(ss)->stack), sipevent);
return 0;
}
int tsip_api_message_send_message(const tsip_ssession_handle_t *ss, ...)
{
const tsip_ssession_t* _ss;
va_list ap;
tsip_action_t* action;
tsip_dialog_t* dialog;
int ret = -1;
if(!(_ss = ss) || !_ss->stack){
TSK_DEBUG_ERROR("Invalid parameter.");
return ret;
}
/* Checks if the stack has been started */
if(!TSK_RUNNABLE(_ss->stack)->started){
TSK_DEBUG_ERROR("Stack not started.");
return -2;
}
/* action */
va_start(ap, ss);
if((action = _tsip_action_create(tsip_atype_message_send, &ap))){
if(!(dialog = tsip_dialog_layer_find_by_ss(_ss->stack->layer_dialog, ss))){
dialog = tsip_dialog_layer_new(_ss->stack->layer_dialog, tsip_dialog_MESSAGE, ss);
}
ret = tsip_dialog_fsm_act(dialog, action->type, tsk_null, action);
tsk_object_unref(dialog);
TSK_OBJECT_SAFE_FREE(action);
}
va_end(ap);
return ret;
} |
175b478c |
//Location |
c732d49e |
int tsip_api_message_send_message_location(const tsip_ssession_handle_t *ss, ...)
{
const tsip_ssession_t* _ss;
va_list ap;
tsip_action_t* action;
tsip_dialog_t* dialog;
int ret = -1;
if(!(_ss = ss) || !_ss->stack){
TSK_DEBUG_ERROR("Invalid parameter.");
return ret;
}
/* Checks if the stack has been started */
if(!TSK_RUNNABLE(_ss->stack)->started){
TSK_DEBUG_ERROR("Stack not started.");
return -2;
}
//This session is type MCPTT location
((tsip_ssession_t*)ss)->media.type=tmedia_mcptt_location;
/* action */
va_start(ap, ss);
if((action = _tsip_action_create(tsip_atype_message_send, &ap))){
if(!(dialog = tsip_dialog_layer_find_by_ss(_ss->stack->layer_dialog, ss))){
dialog = tsip_dialog_layer_new(_ss->stack->layer_dialog, tsip_dialog_MESSAGE, ss);
}
ret = tsip_dialog_fsm_act(dialog, action->type, tsk_null, action);
tsk_object_unref(dialog);
TSK_OBJECT_SAFE_FREE(action);
}
va_end(ap);
return ret;
} |
175b478c |
//MBMS |
c732d49e |
int tsip_api_message_send_message_mbms(const tsip_ssession_handle_t *ss, ...)
{
const tsip_ssession_t* _ss;
va_list ap;
tsip_action_t* action;
tsip_dialog_t* dialog;
int ret = -1;
if(!(_ss = ss) || !_ss->stack){
TSK_DEBUG_ERROR("Invalid parameter.");
return ret;
}
/* Checks if the stack has been started */
if(!TSK_RUNNABLE(_ss->stack)->started){
TSK_DEBUG_ERROR("Stack not started.");
return -2;
}
//This session is type MCPTT MBMS
((tsip_ssession_t*)ss)->media.type=tmedia_mcptt_mbms;
/* action */
va_start(ap, ss);
if((action = _tsip_action_create(tsip_atype_message_send, &ap))){
if(!(dialog = tsip_dialog_layer_find_by_ss(_ss->stack->layer_dialog, ss))){
dialog = tsip_dialog_layer_new(_ss->stack->layer_dialog, tsip_dialog_MESSAGE, ss);
}
ret = tsip_dialog_fsm_act(dialog, action->type, tsk_null, action);
tsk_object_unref(dialog);
TSK_OBJECT_SAFE_FREE(action);
}
va_end(ap);
return ret;
}
//========================================================
// SIP MESSAGE event object definition
//
static tsk_object_t* tsip_message_event_ctor(tsk_object_t * self, va_list * app)
{
tsip_message_event_t *sipevent = self;
if(sipevent){
sipevent->type = va_arg(*app, tsip_message_event_type_t);
}
return self;
}
static tsk_object_t* tsip_message_event_dtor(tsk_object_t * self)
{
tsip_message_event_t *sipevent = self;
if(sipevent){
tsip_event_deinit(TSIP_EVENT(sipevent));
}
return self;
}
static int tsip_message_event_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2)
{
return -1;
}
static const tsk_object_def_t tsip_message_event_def_s =
{
sizeof(tsip_message_event_t),
tsip_message_event_ctor,
tsip_message_event_dtor,
tsip_message_event_cmp,
};
const tsk_object_def_t *tsip_message_event_def_t = &tsip_message_event_def_s; |