mirror of
				https://github.com/RangeNetworks/openbts.git
				synced 2025-11-03 21:33:15 +00:00 
			
		
		
		
	git-svn-id: http://wush.net/svn/range/software/public/openbts/trunk@6168 19bc5d8c-e614-43d4-8b26-e1612bc8e597
		
			
				
	
	
		
			1152 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1152 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
* Copyright 2008 Free Software Foundation, Inc.
 | 
						|
*
 | 
						|
* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribuion.
 | 
						|
*
 | 
						|
* This use of this software may be subject to additional restrictions.
 | 
						|
* See the LEGAL file in the main directory for details.
 | 
						|
 | 
						|
    This program 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.
 | 
						|
 | 
						|
*/
 | 
						|
 | 
						|
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <signal.h>
 | 
						|
 | 
						|
#include <ortp/ortp.h>
 | 
						|
#include <osipparser2/sdp_message.h>
 | 
						|
#include <osipparser2/osip_md5.h>
 | 
						|
 | 
						|
#include "SIPInterface.h"
 | 
						|
#include "SIPUtility.h"
 | 
						|
#include "SIPMessage.h"
 | 
						|
 | 
						|
using namespace std;
 | 
						|
using namespace SIP;
 | 
						|
 | 
						|
 | 
						|
#define DEBUG 1
 | 
						|
#define MAX_VIA 10
 | 
						|
 | 
						|
void openbts_message_init(osip_message_t ** msg){
 | 
						|
	osip_message_init(msg);
 | 
						|
	//I think it's like 40 characters
 | 
						|
	static const char* userAgent = "OpenBTS " VERSION " Build Date " __DATE__;
 | 
						|
	const char *tag = userAgent;
 | 
						|
	osip_message_set_user_agent(*msg, strdup(tag));
 | 
						|
}
 | 
						|
 | 
						|
#define MSG_NO_ERROR		(0)
 | 
						|
#define MSG_INVALID_PARAM	(-1)
 | 
						|
#define MSG_EMPTY_HDR		(-2)
 | 
						|
#define MSG_STR_MEM			(-3)
 | 
						|
 | 
						|
int openbts_message_set_sdp(osip_message_t *request, sdp_message_t *sdp)
 | 
						|
{
 | 
						|
	char * sdp_str = NULL;
 | 
						|
	
 | 
						|
	if (!request || !sdp)
 | 
						|
		return MSG_INVALID_PARAM;
 | 
						|
	
 | 
						|
	sdp_message_to_str(sdp, &sdp_str);
 | 
						|
	if (sdp_str) {
 | 
						|
		osip_message_set_body(request, sdp_str, strlen(sdp_str));
 | 
						|
		osip_free(sdp_str);
 | 
						|
	} else {
 | 
						|
		return MSG_STR_MEM;
 | 
						|
	}
 | 
						|
	osip_message_set_content_type(request, strdup("application/sdp"));
 | 
						|
	return MSG_NO_ERROR;
 | 
						|
}
 | 
						|
 | 
						|
int openbts_message_set_via(osip_message_t *response, osip_message_t *orig)
 | 
						|
{
 | 
						|
	osip_via_t * via = NULL;
 | 
						|
	
 | 
						|
	if (!orig || !response)
 | 
						|
		return MSG_INVALID_PARAM;
 | 
						|
	
 | 
						|
	osip_message_get_via(orig, 0, &via);
 | 
						|
	if (via) {
 | 
						|
		char * via_str = NULL;
 | 
						|
		osip_via_to_str(via, &via_str);
 | 
						|
		if (via_str) {
 | 
						|
			osip_message_set_via(response, via_str);
 | 
						|
			osip_free(via_str);
 | 
						|
		} else {
 | 
						|
			return MSG_STR_MEM;
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		return MSG_EMPTY_HDR;
 | 
						|
	}
 | 
						|
	
 | 
						|
	return MSG_NO_ERROR;
 | 
						|
}
 | 
						|
 | 
						|
int openbts_message_set_contact(osip_message_t *response, osip_message_t *orig)
 | 
						|
{
 | 
						|
	osip_contact_t * cont = NULL;
 | 
						|
 | 
						|
	if (!orig || !response)
 | 
						|
		return MSG_INVALID_PARAM;
 | 
						|
 | 
						|
	osip_message_get_contact(orig, 0, &cont);
 | 
						|
	if (cont) {
 | 
						|
		char * cont_str = NULL;
 | 
						|
		osip_contact_to_str(cont, &cont_str);
 | 
						|
		if (cont_str) {
 | 
						|
			osip_message_set_contact(response, cont_str);
 | 
						|
			osip_free(cont_str);
 | 
						|
		} else {
 | 
						|
			return MSG_STR_MEM;
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		return MSG_EMPTY_HDR;
 | 
						|
	}
 | 
						|
	
 | 
						|
	return MSG_NO_ERROR;
 | 
						|
}
 | 
						|
 | 
						|
int openbts_message_set_cseq(osip_message_t *response, osip_message_t *orig)
 | 
						|
{
 | 
						|
	osip_cseq_t * cseq = NULL;
 | 
						|
 | 
						|
	if (!orig || !response)
 | 
						|
		return MSG_INVALID_PARAM;
 | 
						|
 | 
						|
	cseq = osip_message_get_cseq(orig);
 | 
						|
	if (cseq) {
 | 
						|
		char * cseq_str = NULL;
 | 
						|
		osip_cseq_to_str(cseq ,&cseq_str);
 | 
						|
		if (cseq_str) {
 | 
						|
			osip_message_set_cseq(response, cseq_str);	
 | 
						|
			osip_free(cseq_str);
 | 
						|
		} else {
 | 
						|
			return MSG_STR_MEM;
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		return MSG_EMPTY_HDR;
 | 
						|
	}
 | 
						|
	
 | 
						|
	return MSG_NO_ERROR;
 | 
						|
}
 | 
						|
 | 
						|
int openbts_message_set_rr(osip_message_t *response, osip_message_t *orig)
 | 
						|
{
 | 
						|
	osip_record_route_t * rr = NULL;
 | 
						|
 | 
						|
	if (!orig || !response)
 | 
						|
		return MSG_INVALID_PARAM;
 | 
						|
 | 
						|
	osip_message_get_record_route(orig, 0, &rr);
 | 
						|
	if (rr) {
 | 
						|
		char * rr_str = NULL;
 | 
						|
		osip_record_route_to_str(rr, &rr_str);
 | 
						|
		if (rr_str) {
 | 
						|
			osip_message_set_record_route(response, rr_str);
 | 
						|
			osip_free(rr_str);
 | 
						|
		} else {
 | 
						|
			return MSG_STR_MEM;
 | 
						|
		}
 | 
						|
	} else {
 | 
						|
		return MSG_EMPTY_HDR;
 | 
						|
	}
 | 
						|
 | 
						|
	return MSG_NO_ERROR;
 | 
						|
}
 | 
						|
 | 
						|
osip_message_t * SIP::sip_register( const char * sip_username, short timeout, short wlocal_port, const char * local_ip, const char * proxy_ip, const char * from_tag, const char * via_branch, const char * call_id, int cseq, string *RAND, const char *IMSI, const char *SRES) {
 | 
						|
 | 
						|
 	char local_port[10];
 | 
						|
	sprintf(local_port,"%i",wlocal_port);	
 | 
						|
	
 | 
						|
	// Message URI
 | 
						|
	osip_message_t * request;
 | 
						|
	openbts_message_init(&request);
 | 
						|
	// FIXME -- Should use the "force_update" function.
 | 
						|
	request->message_property = 2; // buffer is not synchronized with object
 | 
						|
	request->sip_method = strdup("REGISTER");
 | 
						|
	osip_message_set_version(request, strdup("SIP/2.0"));	
 | 
						|
	osip_uri_init(&request->req_uri);
 | 
						|
	osip_uri_set_host(request->req_uri, strdup(proxy_ip));
 | 
						|
 | 
						|
	
 | 
						|
	// VIA
 | 
						|
	osip_via_t * via;
 | 
						|
	osip_via_init(&via);
 | 
						|
	via_set_version(via, strdup("2.0"));
 | 
						|
	via_set_protocol(via, strdup("UDP"));
 | 
						|
	via_set_host(via, strdup(local_ip));
 | 
						|
	via_set_port(via, strdup(local_port));
 | 
						|
 | 
						|
	// VIA BRANCH
 | 
						|
	osip_via_set_branch(via, strdup(via_branch));
 | 
						|
 | 
						|
	// MAX FORWARDS
 | 
						|
	osip_message_set_max_forwards(request, strdup(gConfig.getStr("SIP.MaxForwards").c_str()));
 | 
						|
 | 
						|
	char  * via_str;
 | 
						|
	osip_via_to_str(via, &via_str);
 | 
						|
	osip_message_set_via(request, via_str);
 | 
						|
 | 
						|
 | 
						|
	// FROM
 | 
						|
	osip_from_init(&request->from);
 | 
						|
	osip_from_set_displayname(request->from, strdup(sip_username));
 | 
						|
 | 
						|
	// FROM TAG
 | 
						|
	osip_from_set_tag(request->from, strdup(from_tag));
 | 
						|
	osip_uri_init(&request->from->url);
 | 
						|
	osip_uri_set_host(request->from->url, strdup(proxy_ip));
 | 
						|
	osip_uri_set_username(request->from->url, strdup(sip_username));
 | 
						|
 | 
						|
	// TO
 | 
						|
	osip_to_init(&request->to);
 | 
						|
	osip_to_set_displayname(request->to, strdup(sip_username));
 | 
						|
	osip_uri_init(&request->to->url);
 | 
						|
	osip_uri_set_host(request->to->url, strdup(proxy_ip));
 | 
						|
	osip_uri_set_username(request->to->url, strdup(sip_username));
 | 
						|
	
 | 
						|
	// CALL ID
 | 
						|
	osip_call_id_init(&request->call_id);
 | 
						|
	osip_call_id_set_host(request->call_id, strdup(local_ip));
 | 
						|
	osip_call_id_set_number(request->call_id, strdup(call_id));
 | 
						|
 | 
						|
	// CSEQ
 | 
						|
	osip_cseq_init(&request->cseq);
 | 
						|
	osip_cseq_set_method(request->cseq, strdup("REGISTER"));
 | 
						|
	char temp_buf[14];
 | 
						|
	sprintf(temp_buf,"%i",cseq);
 | 
						|
	osip_cseq_set_number(request->cseq, strdup(temp_buf));	
 | 
						|
 | 
						|
	// CONTACT
 | 
						|
	osip_contact_t * con;
 | 
						|
	osip_to_init(&con);
 | 
						|
 | 
						|
	// CONTACT URI
 | 
						|
	osip_uri_init(&con->url);
 | 
						|
	osip_uri_set_host(con->url, strdup(local_ip));
 | 
						|
	osip_uri_set_port(con->url, strdup(local_port));
 | 
						|
	osip_uri_set_username(con->url, strdup(sip_username));
 | 
						|
	char numbuf[10];
 | 
						|
	sprintf(numbuf,"%d",timeout);
 | 
						|
	osip_contact_param_add(con, strdup("expires"), strdup(numbuf) );
 | 
						|
 | 
						|
	// add contact
 | 
						|
	osip_list_add(&request->contacts, con, -1);
 | 
						|
 | 
						|
	if (SRES) {
 | 
						|
		// add authentication
 | 
						|
		osip_authorization_t *auth;
 | 
						|
		osip_authorization_init(&auth);
 | 
						|
		osip_authorization_set_auth_type(auth, osip_strdup("Digest"));
 | 
						|
		osip_authorization_set_nonce(auth, osip_strdup(RAND->c_str()));
 | 
						|
		osip_authorization_set_uri(auth, osip_strdup(IMSI));
 | 
						|
		osip_authorization_set_response(auth, osip_strdup(SRES));
 | 
						|
		osip_list_add(&request->authorizations, auth, -1);
 | 
						|
	}
 | 
						|
 | 
						|
	return request;	
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
osip_message_t * SIP::sip_message( const char * dialed_number, const char * sip_username, short wlocal_port, const char * local_ip, const char * proxy_ip, const char * from_tag, const char * via_branch, const char * call_id, int cseq, const char* message, const char* content_type) {
 | 
						|
 | 
						|
	char local_port[10];
 | 
						|
	sprintf(local_port, "%i", wlocal_port);
 | 
						|
 | 
						|
	osip_message_t * request;
 | 
						|
	openbts_message_init(&request);
 | 
						|
	// FIXME -- Should use the "force_update" function.
 | 
						|
	request->message_property = 2;
 | 
						|
 | 
						|
	// METHOD
 | 
						|
	request->sip_method = strdup("MESSAGE");
 | 
						|
	osip_message_set_version(request, strdup("SIP/2.0"));	
 | 
						|
 | 
						|
	// REQ.URI
 | 
						|
	osip_uri_init(&request->req_uri);
 | 
						|
	osip_uri_set_host(request->req_uri, strdup(proxy_ip));
 | 
						|
	osip_uri_set_username(request->req_uri, strdup(dialed_number));
 | 
						|
	
 | 
						|
	// VIA
 | 
						|
	osip_via_t * via;
 | 
						|
	osip_via_init(&via);
 | 
						|
	via_set_version(via, strdup("2.0"));
 | 
						|
	via_set_protocol(via, strdup("UDP"));
 | 
						|
	via_set_host(via, strdup(local_ip));
 | 
						|
	via_set_port(via, strdup(local_port));
 | 
						|
	osip_via_set_branch(via, strdup(via_branch));
 | 
						|
 | 
						|
	// MAX FORWARDS
 | 
						|
	osip_message_set_max_forwards(request, strdup(gConfig.getStr("SIP.MaxForwards").c_str()));
 | 
						|
 | 
						|
	// add via
 | 
						|
	osip_list_add(&request->vias, via, -1);
 | 
						|
 | 
						|
	// FROM
 | 
						|
	osip_from_init(&request->from);
 | 
						|
	osip_from_set_displayname(request->from, strdup(sip_username));
 | 
						|
	osip_uri_init(&request->from->url);
 | 
						|
	osip_uri_set_host(request->from->url, strdup(proxy_ip));
 | 
						|
	osip_uri_set_username(request->from->url, strdup(sip_username));
 | 
						|
	// FROM TAG
 | 
						|
	osip_from_set_tag(request->from, strdup(from_tag));
 | 
						|
 | 
						|
	// TO
 | 
						|
	osip_to_init(&request->to);
 | 
						|
	osip_to_set_displayname(request->to, strdup(dialed_number));
 | 
						|
	osip_uri_init(&request->to->url);
 | 
						|
	osip_uri_set_host(request->to->url, strdup(proxy_ip));
 | 
						|
	osip_uri_set_username(request->to->url, strdup(dialed_number));
 | 
						|
 | 
						|
	// CALL ID
 | 
						|
	osip_call_id_init(&request->call_id);
 | 
						|
	osip_call_id_set_host(request->call_id, strdup(local_ip));
 | 
						|
	osip_call_id_set_number(request->call_id, strdup(call_id));
 | 
						|
 | 
						|
	// CSEQ
 | 
						|
	osip_cseq_init(&request->cseq);
 | 
						|
	osip_cseq_set_method(request->cseq, strdup("MESSAGE"));
 | 
						|
	char temp_buf[21];
 | 
						|
	sprintf(temp_buf,"%i",cseq);
 | 
						|
	osip_cseq_set_number(request->cseq, strdup(temp_buf));	
 | 
						|
 | 
						|
	// Content-Type
 | 
						|
	if (content_type)
 | 
						|
	{
 | 
						|
		// Explicit value provided
 | 
						|
		osip_message_set_content_type(request, strdup(content_type));
 | 
						|
	} else {
 | 
						|
		// Default to text/plain
 | 
						|
		osip_message_set_content_type(request, strdup("text/plain"));
 | 
						|
	}
 | 
						|
 | 
						|
	// Content-Length
 | 
						|
	sprintf(temp_buf,"%u",strlen(message));
 | 
						|
	osip_message_set_content_length(request, strdup(temp_buf));
 | 
						|
 | 
						|
	// Payload.
 | 
						|
	osip_message_set_body(request,message,strlen(message));
 | 
						|
 | 
						|
	return request;	
 | 
						|
}
 | 
						|
 | 
						|
osip_message_t * SIP::sip_invite( const char * dialed_number, short rtp_port, const char * sip_username, short wlocal_port, const char * local_ip, const char * proxy_ip, const char * from_tag, const char * via_branch, const char * call_id, int cseq, unsigned codec) {
 | 
						|
 | 
						|
	char local_port[10];
 | 
						|
	sprintf(local_port, "%i", wlocal_port);
 | 
						|
 | 
						|
	osip_message_t * request;
 | 
						|
	openbts_message_init(&request);
 | 
						|
	// FIXME -- Should use the "force_update" function.
 | 
						|
	request->message_property = 2;
 | 
						|
	request->sip_method = strdup("INVITE");
 | 
						|
	osip_message_set_version(request, strdup("SIP/2.0"));	
 | 
						|
	osip_uri_init(&request->req_uri);
 | 
						|
	osip_uri_set_host(request->req_uri, strdup(proxy_ip));
 | 
						|
	osip_uri_set_username(request->req_uri, strdup(dialed_number));
 | 
						|
	
 | 
						|
	// VIA
 | 
						|
	osip_via_t * via;
 | 
						|
	osip_via_init(&via);
 | 
						|
	via_set_version(via, strdup("2.0"));
 | 
						|
	via_set_protocol(via, strdup("UDP"));
 | 
						|
	via_set_host(via, strdup(local_ip));
 | 
						|
	via_set_port(via, strdup(local_port));
 | 
						|
 | 
						|
	// VIA BRANCH
 | 
						|
	osip_via_set_branch(via, strdup(via_branch));
 | 
						|
 | 
						|
	// MAX FORWARDS
 | 
						|
	osip_message_set_max_forwards(request, strdup(gConfig.getStr("SIP.MaxForwards").c_str()));
 | 
						|
 | 
						|
	// add via
 | 
						|
	osip_list_add(&request->vias, via, -1);
 | 
						|
 | 
						|
	// FROM
 | 
						|
	osip_from_init(&request->from);
 | 
						|
	osip_from_set_displayname(request->from, strdup(sip_username));
 | 
						|
 | 
						|
	// FROM TAG
 | 
						|
	osip_from_set_tag(request->from, strdup(from_tag));
 | 
						|
 | 
						|
	osip_uri_init(&request->from->url);
 | 
						|
	osip_uri_set_host(request->from->url, strdup(proxy_ip));
 | 
						|
	osip_uri_set_username(request->from->url, strdup(sip_username));
 | 
						|
 | 
						|
	// TO
 | 
						|
	osip_to_init(&request->to);
 | 
						|
	osip_to_set_displayname(request->to, strdup(""));
 | 
						|
	osip_uri_init(&request->to->url);
 | 
						|
	osip_uri_set_host(request->to->url, strdup(proxy_ip));
 | 
						|
	osip_uri_set_username(request->to->url, strdup(dialed_number));
 | 
						|
 | 
						|
	// If response, we need a to tag.
 | 
						|
	//osip_uri_param_t * to_tag_param;
 | 
						|
	//osip_from_get_tag(rsp->to, &to_tag_param);
 | 
						|
 | 
						|
	// CALL ID
 | 
						|
	osip_call_id_init(&request->call_id);
 | 
						|
	osip_call_id_set_host(request->call_id, strdup(local_ip));
 | 
						|
	osip_call_id_set_number(request->call_id, strdup(call_id));
 | 
						|
 | 
						|
	// CSEQ
 | 
						|
	osip_cseq_init(&request->cseq);
 | 
						|
	osip_cseq_set_method(request->cseq, strdup("INVITE"));
 | 
						|
	char temp_buf[14];
 | 
						|
	sprintf(temp_buf,"%i",cseq);
 | 
						|
	osip_cseq_set_number(request->cseq, strdup(temp_buf));	
 | 
						|
 | 
						|
	// CONTACT
 | 
						|
	osip_contact_t * con;
 | 
						|
	osip_to_init(&con);
 | 
						|
 | 
						|
	// CONTACT URI
 | 
						|
	osip_uri_init(&con->url);
 | 
						|
	osip_uri_set_host(con->url, strdup(local_ip));
 | 
						|
	osip_uri_set_port(con->url, strdup(local_port));
 | 
						|
	osip_uri_set_username(con->url, strdup(sip_username));
 | 
						|
	osip_contact_param_add(con, strdup("expires"), strdup("3600") );
 | 
						|
 | 
						|
	// add contact
 | 
						|
	osip_list_add(&request->contacts, con, -1);
 | 
						|
 | 
						|
	sdp_message_t * sdp;
 | 
						|
	sdp_message_init(&sdp);
 | 
						|
	sdp_message_v_version_set(sdp, strdup("0"));
 | 
						|
	sdp_message_o_origin_set(sdp, strdup(sip_username), strdup("0"),
 | 
						|
        strdup("0"), strdup("IN"), strdup("IP4"), strdup(local_ip));
 | 
						|
 | 
						|
	sdp_message_s_name_set(sdp, strdup("Talk Time"));
 | 
						|
	sdp_message_t_time_descr_add(sdp, strdup("0"), strdup("0") );
 | 
						|
 | 
						|
	sprintf(temp_buf,"%i",rtp_port);
 | 
						|
	sdp_message_m_media_add(sdp, strdup("audio"), 
 | 
						|
		strdup(temp_buf), NULL, strdup("RTP/AVP"));
 | 
						|
	sdp_message_c_connection_add
 | 
						|
        (sdp, 0, strdup("IN"), strdup("IP4"), strdup(local_ip),NULL, NULL);
 | 
						|
 | 
						|
	// FIXME -- This should also be inside the switch?
 | 
						|
	sdp_message_m_payload_add(sdp,0,strdup("3"));
 | 
						|
	switch (codec) {
 | 
						|
		case RTPuLaw:
 | 
						|
			sdp_message_a_attribute_add(sdp,0,strdup("rtpmap"),strdup("0 PCMU/8000"));
 | 
						|
			break;
 | 
						|
		case RTPGSM610:
 | 
						|
			sdp_message_a_attribute_add(sdp,0,strdup("rtpmap"),strdup("3 GSM/8000"));
 | 
						|
			break;
 | 
						|
		default: assert(0);
 | 
						|
	};
 | 
						|
 | 
						|
	/*
 | 
						|
	 * We construct a sdp_message_t, turn it into a string, and then treat it
 | 
						|
	 * like an osip_body_t.  This works, and perhaps is how it is supposed to
 | 
						|
	 * be done, but in any case we're going to have to do the extra processing
 | 
						|
	 * to turn it into a string first.
 | 
						|
	 */
 | 
						|
	openbts_message_set_sdp(request, sdp);
 | 
						|
	// TODO: In the unlikely event that sdp_str is null, we should probably do some nice cleanup.
 | 
						|
 | 
						|
	return request;	
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
osip_message_t * SIP::sip_reinvite(
 | 
						|
		const char* RemoteUsername,
 | 
						|
		const char* RemoteIP,
 | 
						|
 | 
						|
		const char* SIPDisplayname,
 | 
						|
		const char* SIPUsername,
 | 
						|
 | 
						|
		const char* fromTag,
 | 
						|
		const char* fromUsername,
 | 
						|
		const char* fromIP,
 | 
						|
 | 
						|
		const char* toTag,
 | 
						|
		const char* toUsername,
 | 
						|
		const char* toIP,
 | 
						|
 | 
						|
		const char* viaBranch,
 | 
						|
		const char* callID,
 | 
						|
		const char* callIP,
 | 
						|
 | 
						|
		int cseq,
 | 
						|
		unsigned codec,
 | 
						|
		short wRTPPort,
 | 
						|
 | 
						|
		const char* SessionID,
 | 
						|
		const char* SessionVersion)
 | 
						|
{
 | 
						|
 | 
						|
	char RTPPort[10];
 | 
						|
	sprintf(RTPPort, "%i", wRTPPort);
 | 
						|
 | 
						|
	const char * BS2port = gConfig.getStr("SIP.Local.Port").c_str();
 | 
						|
	const char * BS2IP = gConfig.getStr("SIP.Local.IP").c_str();
 | 
						|
 | 
						|
	osip_message_t * request;
 | 
						|
	osip_message_init(&request);
 | 
						|
	request->message_property = 2;
 | 
						|
	request->sip_method = strdup("INVITE");
 | 
						|
	osip_message_set_version(request, strdup("SIP/2.0"));	
 | 
						|
	osip_uri_init(&request->req_uri);
 | 
						|
	osip_uri_set_host(request->req_uri, strdup(RemoteIP));
 | 
						|
	osip_uri_set_username(request->req_uri, strdup(RemoteUsername));
 | 
						|
	
 | 
						|
	// VIA
 | 
						|
	osip_via_t * via;
 | 
						|
	osip_via_init(&via);
 | 
						|
	via_set_version(via, strdup("2.0"));
 | 
						|
	via_set_protocol(via, strdup("UDP"));
 | 
						|
	via_set_host(via, strdup(BS2IP));
 | 
						|
	via_set_port(via, strdup(BS2port));
 | 
						|
 | 
						|
	// VIA BRANCH
 | 
						|
	osip_via_set_branch(via, strdup(viaBranch));
 | 
						|
 | 
						|
	// MAX FORWARDS
 | 
						|
	osip_message_set_max_forwards(request, strdup(gConfig.getStr("SIP.MaxForwards").c_str()));
 | 
						|
 | 
						|
	// add via
 | 
						|
	osip_list_add(&request->vias, via, -1);
 | 
						|
 | 
						|
	// FROM
 | 
						|
	osip_from_init(&request->from);
 | 
						|
	// osip_from_set_displayname(request->from, strdup(fromDisplayname));
 | 
						|
	osip_from_set_tag(request->from, strdup(fromTag));
 | 
						|
	osip_uri_init(&request->from->url);
 | 
						|
	osip_uri_set_host(request->from->url, strdup(fromIP));
 | 
						|
	osip_uri_set_username(request->from->url, strdup(fromUsername));
 | 
						|
 | 
						|
	// TO
 | 
						|
	osip_to_init(&request->to);
 | 
						|
	// osip_to_set_displayname(request->to, strdup(toDisplayname));
 | 
						|
	osip_to_set_tag(request->to, strdup(toTag));
 | 
						|
	osip_uri_init(&request->to->url);
 | 
						|
	osip_uri_set_host(request->to->url, strdup(toIP));
 | 
						|
	osip_uri_set_username(request->to->url, strdup(toUsername));
 | 
						|
 | 
						|
	// CALL ID
 | 
						|
	osip_call_id_init(&request->call_id);
 | 
						|
	if (*callIP) osip_call_id_set_host(request->call_id, strdup(callIP));
 | 
						|
	osip_call_id_set_number(request->call_id, strdup(callID));
 | 
						|
 | 
						|
	// CSEQ
 | 
						|
	osip_cseq_init(&request->cseq);
 | 
						|
	osip_cseq_set_method(request->cseq, strdup("INVITE"));
 | 
						|
	char temp_buf[14];
 | 
						|
	sprintf(temp_buf,"%i",cseq);
 | 
						|
	osip_cseq_set_number(request->cseq, strdup(temp_buf));	
 | 
						|
 | 
						|
	// CONTACT
 | 
						|
	osip_contact_t * con;
 | 
						|
	osip_to_init(&con);
 | 
						|
 | 
						|
	// CONTACT URI
 | 
						|
	osip_uri_init(&con->url);
 | 
						|
	osip_uri_set_host(con->url, strdup(BS2IP));
 | 
						|
	osip_uri_set_port(con->url, strdup(BS2port));
 | 
						|
	osip_uri_set_username(con->url, strdup(SIPUsername));
 | 
						|
	osip_contact_param_add(con, strdup("expires"), strdup("3600") );
 | 
						|
 | 
						|
	// add contact
 | 
						|
	osip_list_add(&request->contacts, con, -1);
 | 
						|
 | 
						|
	sdp_message_t * sdp;
 | 
						|
	sdp_message_init(&sdp);
 | 
						|
	sdp_message_v_version_set(sdp, strdup("0"));
 | 
						|
	sdp_message_o_origin_set(sdp, strdup(SIPDisplayname), strdup(SessionID),
 | 
						|
        strdup(SessionVersion), strdup("IN"), strdup("IP4"), strdup(BS2IP));
 | 
						|
 | 
						|
	sdp_message_s_name_set(sdp, strdup("Talk Time"));
 | 
						|
	sdp_message_t_time_descr_add(sdp, strdup("0"), strdup("0") );
 | 
						|
 | 
						|
	sdp_message_m_media_add(sdp, strdup("audio"), 
 | 
						|
		strdup(RTPPort), NULL, strdup("RTP/AVP"));
 | 
						|
	sdp_message_c_connection_add
 | 
						|
        (sdp, 0, strdup("IN"), strdup("IP4"), strdup(BS2IP),NULL, NULL);
 | 
						|
 | 
						|
	// FIXME -- This should also be inside the switch?
 | 
						|
	sdp_message_m_payload_add(sdp,0,strdup("3"));
 | 
						|
	switch (codec) {
 | 
						|
		case RTPuLaw:
 | 
						|
			sdp_message_a_attribute_add(sdp,0,strdup("rtpmap"),strdup("0 PCMU/8000"));
 | 
						|
			break;
 | 
						|
		case RTPGSM610:
 | 
						|
			sdp_message_a_attribute_add(sdp,0,strdup("rtpmap"),strdup("3 GSM/8000"));
 | 
						|
			break;
 | 
						|
		default: assert(0);
 | 
						|
	};
 | 
						|
 | 
						|
	/*
 | 
						|
	 * We construct a sdp_message_t, turn it into a string, and then treat it
 | 
						|
	 * like an osip_body_t.  This works, and perhaps is how it is supposed to
 | 
						|
	 * be done, but in any case we're going to have to do the extra processing
 | 
						|
	 * to turn it into a string first.
 | 
						|
	 */
 | 
						|
	openbts_message_set_sdp(request, sdp);
 | 
						|
	// TODO: In the unlikely event that sdp_str is null, we should probably do some nice cleanup.
 | 
						|
 | 
						|
	return request;	
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Take the authorization produced by an earlier invite message.
 | 
						|
 | 
						|
osip_message_t * SIP::sip_ack(const char * req_uri, const char * dialed_number, const char * sip_username, short wlocal_port, const char * local_ip, const char * proxy_ip, const osip_from_t *from_header, const osip_to_t* to_header, const char * via_branch, const osip_call_id_t* call_id_header, int cseq) {
 | 
						|
 | 
						|
	char local_port[20];
 | 
						|
	sprintf(local_port, "%i", wlocal_port);
 | 
						|
 | 
						|
	osip_message_t * ack;
 | 
						|
	openbts_message_init(&ack);
 | 
						|
	// FIXME -- Should use the "force_update" function.
 | 
						|
	ack->message_property = 2;
 | 
						|
	ack->sip_method = strdup("ACK");
 | 
						|
	osip_message_set_version(ack, strdup("SIP/2.0"));	
 | 
						|
 | 
						|
	osip_uri_init(&ack->req_uri);
 | 
						|
 | 
						|
	// If we are Acking a BYE message then need to 
 | 
						|
	// set the req_uri to the owner address thats taken from the 200 Okay.
 | 
						|
	if( req_uri == NULL ) {
 | 
						|
		osip_uri_set_host(ack->req_uri, strdup(proxy_ip));
 | 
						|
	} else {
 | 
						|
		osip_uri_set_host(ack->req_uri, strdup(req_uri));
 | 
						|
	}
 | 
						|
 | 
						|
	osip_uri_set_username(ack->req_uri, strdup(dialed_number));
 | 
						|
 | 
						|
	// Via
 | 
						|
	osip_via_t *via;
 | 
						|
	osip_via_init(&via);
 | 
						|
	via_set_version(via, strdup("2.0"));
 | 
						|
	via_set_protocol(via, strdup("UDP"));
 | 
						|
	via_set_host(via, strdup(local_ip));
 | 
						|
	via_set_port(via, strdup(local_port));
 | 
						|
 | 
						|
	// VIA BRANCH
 | 
						|
	osip_via_set_branch(via, strdup(via_branch));
 | 
						|
 | 
						|
	// MAX FORWARDS
 | 
						|
	osip_message_set_max_forwards(ack, strdup(gConfig.getStr("SIP.MaxForwards").c_str()));
 | 
						|
 | 
						|
	// add via
 | 
						|
	osip_list_add(&ack->vias, via, -1);
 | 
						|
 | 
						|
	osip_from_init(&ack->from);
 | 
						|
	osip_from_set_displayname(ack->from, strdup(sip_username));
 | 
						|
	osip_uri_init(&ack->from->url);
 | 
						|
	osip_uri_set_host(ack->from->url, strdup(proxy_ip));
 | 
						|
	osip_uri_set_username(ack->from->url, strdup(sip_username));
 | 
						|
 | 
						|
	// from/to headers
 | 
						|
	osip_from_clone(from_header, &ack->from);
 | 
						|
	osip_to_clone(to_header, &ack->to);
 | 
						|
 | 
						|
	// call id
 | 
						|
	osip_call_id_clone(call_id_header, &ack->call_id);
 | 
						|
 | 
						|
	osip_cseq_init(&ack->cseq);
 | 
						|
	osip_cseq_set_method(ack->cseq, strdup("ACK"));
 | 
						|
	char temp_buf[14];
 | 
						|
	sprintf(temp_buf, "%i", cseq);
 | 
						|
	osip_cseq_set_number(ack->cseq, strdup(temp_buf));	
 | 
						|
 | 
						|
	return ack;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
osip_message_t * SIP::sip_bye(const char * req_uri, const char * dialed_number, const char * sip_username, short wlocal_port, const char * local_ip, const char * proxy_ip, short wproxy_port, const osip_from_t* from_header, const osip_to_t* to_header, const char * via_branch, const osip_call_id_t* call_id_header, int cseq) {
 | 
						|
 | 
						|
	// FIXME -- We really need some NULL-value error checking in here.
 | 
						|
 | 
						|
	char local_port[10];
 | 
						|
	sprintf(local_port,"%i",wlocal_port);
 | 
						|
 | 
						|
	char proxy_port[10];
 | 
						|
	sprintf(proxy_port,"%i",wproxy_port);
 | 
						|
 | 
						|
	osip_message_t * bye;
 | 
						|
	openbts_message_init(&bye);
 | 
						|
	// FIXME -- Should use the "force_update" function.
 | 
						|
	bye->message_property = 2;
 | 
						|
	bye->sip_method = strdup("BYE");
 | 
						|
	osip_message_set_version(bye, strdup("SIP/2.0"));	
 | 
						|
 | 
						|
	//char o_addr[30];
 | 
						|
	//get_owner_ip(okay, o_addr);
 | 
						|
 | 
						|
	osip_uri_init(&bye->req_uri);
 | 
						|
	osip_uri_set_host(bye->req_uri, strdup(req_uri));
 | 
						|
	osip_uri_set_username(bye->req_uri, strdup(dialed_number));
 | 
						|
 | 
						|
	osip_via_t * via;
 | 
						|
	osip_via_init(&via);
 | 
						|
	via_set_version(via, strdup("2.0"));
 | 
						|
	via_set_protocol(via, strdup("UDP"));
 | 
						|
	via_set_host(via, strdup(local_ip));
 | 
						|
	via_set_port(via, strdup(local_port));
 | 
						|
 | 
						|
	// via branch + max forwards
 | 
						|
	osip_via_set_branch(via, strdup(via_branch));
 | 
						|
	osip_message_set_max_forwards(bye, strdup(gConfig.getStr("SIP.MaxForwards").c_str()));
 | 
						|
 | 
						|
	// add via
 | 
						|
	osip_list_add(&bye->vias, via, -1);
 | 
						|
 | 
						|
	// from/to header
 | 
						|
	osip_from_clone(from_header, &bye->from);
 | 
						|
	osip_to_clone(to_header, &bye->to);
 | 
						|
 | 
						|
	// Call Id Header	
 | 
						|
	osip_call_id_clone(call_id_header, &bye->call_id);
 | 
						|
 | 
						|
	// Cseq Number
 | 
						|
	osip_cseq_init(&bye->cseq);
 | 
						|
	osip_cseq_set_method(bye->cseq, strdup("BYE"));
 | 
						|
	char temp_buf[12];
 | 
						|
	sprintf(temp_buf,"%i",cseq);
 | 
						|
	osip_cseq_set_number(bye->cseq, strdup(temp_buf));	
 | 
						|
 | 
						|
	// Contact
 | 
						|
	osip_contact_t * contact;
 | 
						|
	osip_contact_init(&contact);
 | 
						|
	osip_contact_set_displayname(contact, strdup(sip_username) );	
 | 
						|
	osip_uri_init(&contact->url);
 | 
						|
	osip_uri_set_host(contact->url, strdup(local_ip));
 | 
						|
	osip_uri_set_username(contact->url, strdup(sip_username));
 | 
						|
	osip_uri_set_port(contact->url, strdup(local_port));
 | 
						|
 | 
						|
	// add contact
 | 
						|
	osip_list_add(&bye->contacts, contact, -1);
 | 
						|
 | 
						|
	return bye;
 | 
						|
}
 | 
						|
 | 
						|
osip_message_t * SIP::sip_error(osip_message_t * invite,  const char * host, const char * username, short port, short code, const char* reason)
 | 
						|
{
 | 
						|
 | 
						|
	if(invite==NULL){ return NULL;}
 | 
						|
 | 
						|
	osip_message_t * unavail;
 | 
						|
	openbts_message_init(&unavail);
 | 
						|
	//clone doesn't work -kurtis
 | 
						|
	// FIXME -- Should use the "force_update" function.
 | 
						|
	unavail->message_property = 2;
 | 
						|
	//header stuff first
 | 
						|
	unavail->status_code = code;
 | 
						|
	unavail->reason_phrase = strdup(reason);
 | 
						|
	osip_message_set_version(unavail, strdup("SIP/2.0"));
 | 
						|
 | 
						|
	char local_port[10];
 | 
						|
	sprintf(local_port, "%i", port);
 | 
						|
	
 | 
						|
	//uri
 | 
						|
	osip_uri_init(&unavail->req_uri);
 | 
						|
	osip_uri_set_host(unavail->req_uri, strdup(host));
 | 
						|
	osip_uri_set_username(unavail->req_uri, strdup(username));
 | 
						|
	osip_uri_set_port(unavail->req_uri, strdup(local_port));
 | 
						|
 | 
						|
	//via
 | 
						|
	openbts_message_set_via(unavail, invite);
 | 
						|
 | 
						|
	// MAX FORWARDS
 | 
						|
	osip_message_set_max_forwards(unavail, strdup(gConfig.getStr("SIP.MaxForwards").c_str()));
 | 
						|
 | 
						|
	// from/to header
 | 
						|
	osip_from_clone(invite->from, &unavail->from);
 | 
						|
	osip_to_clone(invite->to, &unavail->to);
 | 
						|
 | 
						|
	//contact
 | 
						|
	openbts_message_set_contact(unavail, invite);
 | 
						|
 | 
						|
	// Get Call-ID.
 | 
						|
	osip_call_id_clone(invite->call_id, &unavail->call_id);
 | 
						|
 | 
						|
	// Get Cseq.
 | 
						|
	openbts_message_set_cseq(unavail, invite);
 | 
						|
 | 
						|
	return unavail;
 | 
						|
}
 | 
						|
 | 
						|
/* Cancel a previous invite */
 | 
						|
osip_message_t * SIP::sip_cancel( osip_message_t * invite,  const char * host, const char * username, short  port)
 | 
						|
{
 | 
						|
 | 
						|
	if(invite==NULL){ return NULL;}
 | 
						|
 | 
						|
	osip_message_t * cancel;
 | 
						|
	openbts_message_init(&cancel);
 | 
						|
	//clone doesn't work -kurtis
 | 
						|
	//osip_message_clone(invite, &cancel)
 | 
						|
	// FIXME -- Should use the "force_update" function.
 | 
						|
	cancel->message_property = 2;
 | 
						|
	//header stuff first
 | 
						|
	cancel->sip_method = strdup("CANCEL");
 | 
						|
	osip_message_set_version(cancel, strdup("SIP/2.0"));
 | 
						|
 | 
						|
	char local_port[10];
 | 
						|
	sprintf(local_port, "%i", port);
 | 
						|
	
 | 
						|
	//uri
 | 
						|
	osip_uri_init(&cancel->req_uri);
 | 
						|
	osip_uri_set_host(cancel->req_uri, strdup(host));
 | 
						|
	osip_uri_set_username(cancel->req_uri, strdup(username));
 | 
						|
	osip_uri_set_port(cancel->req_uri, strdup(local_port));
 | 
						|
 | 
						|
	//via
 | 
						|
	openbts_message_set_via(cancel, invite);
 | 
						|
 | 
						|
	// from/to header
 | 
						|
	osip_from_clone(invite->from, &cancel->from);
 | 
						|
	osip_to_clone(invite->to, &cancel->to);
 | 
						|
 | 
						|
	//contact
 | 
						|
	openbts_message_set_contact(cancel, invite);
 | 
						|
 | 
						|
	// Get Call-ID.
 | 
						|
	osip_call_id_clone(invite->call_id, &cancel->call_id);
 | 
						|
 | 
						|
	  // Get Cseq.
 | 
						|
	openbts_message_set_cseq(cancel, invite);
 | 
						|
 | 
						|
	//update message type
 | 
						|
	osip_cseq_set_method(cancel->cseq, strdup("CANCEL"));
 | 
						|
 | 
						|
	return cancel;
 | 
						|
}
 | 
						|
 | 
						|
osip_message_t * SIP::sip_okay_sdp( osip_message_t * inv, const char * sip_username, const char * local_ip, short wlocal_port, short rtp_port, unsigned audio_codec)
 | 
						|
{
 | 
						|
 | 
						|
	// Check for consistency.
 | 
						|
	if(inv==NULL){ return NULL;}
 | 
						|
 | 
						|
	char local_port[10];
 | 
						|
	sprintf(local_port, "%i", wlocal_port);
 | 
						|
	// k used for error conditions on various osip operations.
 | 
						|
	
 | 
						|
	osip_message_t * okay;
 | 
						|
	openbts_message_init(&okay);
 | 
						|
	// FIXME -- Should use the "force_update" function.
 | 
						|
	okay->message_property = 2;
 | 
						|
 | 
						|
	// Set Header stuff.
 | 
						|
	okay->status_code = 200;	
 | 
						|
	okay->reason_phrase = strdup("OK");
 | 
						|
	osip_message_set_version(okay, strdup("SIP/2.0"));
 | 
						|
	osip_uri_init(&okay->req_uri);
 | 
						|
 | 
						|
	// Get Record Route.
 | 
						|
	// FIXME -- Should use _clone() routines.
 | 
						|
	openbts_message_set_rr(okay, inv);
 | 
						|
 | 
						|
	// SIP Okay needs to repeat the Via tags from the INVITE Message.
 | 
						|
	openbts_message_set_via(okay, inv);
 | 
						|
 | 
						|
	// from/to header
 | 
						|
	osip_from_clone(inv->from, &okay->from);
 | 
						|
	osip_to_clone(inv->to, &okay->to);
 | 
						|
 | 
						|
	// CONTACT URI
 | 
						|
	osip_contact_t * con;
 | 
						|
	osip_to_init(&con);
 | 
						|
	osip_uri_init(&con->url);
 | 
						|
	osip_uri_set_host(con->url, strdup(local_ip));
 | 
						|
	osip_uri_set_port(con->url, strdup(local_port));
 | 
						|
	osip_uri_set_username(con->url, strdup(sip_username));
 | 
						|
	osip_contact_param_add(con, strdup("expires"), strdup("3600") );
 | 
						|
 | 
						|
	// add contact
 | 
						|
	osip_list_add(&okay->contacts, con, -1);
 | 
						|
 | 
						|
	// Get Call-ID.
 | 
						|
	osip_call_id_clone(inv->call_id, &okay->call_id);
 | 
						|
 | 
						|
	// Get Cseq.
 | 
						|
	openbts_message_set_cseq(okay, inv);
 | 
						|
 | 
						|
	// Session Description Protocol.	
 | 
						|
	sdp_message_t * sdp;
 | 
						|
	sdp_message_init(&sdp);
 | 
						|
	sdp_message_v_version_set(sdp, strdup("0"));
 | 
						|
	sdp_message_o_origin_set(sdp, strdup(sip_username), strdup("0"),
 | 
						|
        strdup("0"), strdup("IN"), strdup("IP4"), strdup(local_ip));
 | 
						|
 | 
						|
	sdp_message_s_name_set(sdp, strdup("Talk Time"));
 | 
						|
	sdp_message_t_time_descr_add(sdp, strdup("0"), strdup("0") );
 | 
						|
	char temp_buf[10];
 | 
						|
	sprintf(temp_buf,"%i", rtp_port);
 | 
						|
	sdp_message_m_media_add(sdp, strdup("audio"), 
 | 
						|
		strdup(temp_buf), NULL, strdup("RTP/AVP"));
 | 
						|
	sdp_message_c_connection_add
 | 
						|
        (sdp, 0, strdup("IN"), strdup("IP4"), strdup(local_ip),NULL, NULL);
 | 
						|
 | 
						|
	// FIXME -- This should also be inside the switch?
 | 
						|
	sdp_message_m_payload_add(sdp,0,strdup("3"));
 | 
						|
	switch (audio_codec) {
 | 
						|
		case RTPuLaw:
 | 
						|
			sdp_message_a_attribute_add(sdp,0,strdup("rtpmap"),strdup("0 PCMU/8000"));
 | 
						|
			break;
 | 
						|
		case RTPGSM610:
 | 
						|
			sdp_message_a_attribute_add(sdp,0,strdup("rtpmap"),strdup("3 GSM/8000"));
 | 
						|
			break;
 | 
						|
		default: assert(0);
 | 
						|
	};
 | 
						|
 | 
						|
	openbts_message_set_sdp(okay, sdp);
 | 
						|
 | 
						|
	return okay;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
osip_message_t * SIP::sip_b_okay( osip_message_t * bye  )
 | 
						|
{
 | 
						|
	// Check for consistency.
 | 
						|
	if(bye==NULL){ return NULL;}
 | 
						|
 | 
						|
	// k used for error conditions on various osip operations.
 | 
						|
	
 | 
						|
	osip_message_t * okay;
 | 
						|
	openbts_message_init(&okay);
 | 
						|
	// FIXME -- Should use the "force_update" function.
 | 
						|
	okay->message_property = 2;
 | 
						|
 | 
						|
	// Set Header stuff.
 | 
						|
	okay->status_code = 200;	
 | 
						|
	okay->reason_phrase = strdup("OK");
 | 
						|
	osip_message_set_version(okay, strdup("SIP/2.0"));
 | 
						|
	osip_uri_init(&okay->req_uri);
 | 
						|
 | 
						|
	// SIP Okay needs to repeat the Via tags from the BYE Message.
 | 
						|
	openbts_message_set_via(okay, bye);
 | 
						|
 | 
						|
	// from/to header
 | 
						|
	osip_from_clone(bye->from, &okay->from);
 | 
						|
	osip_to_clone(bye->to, &okay->to);
 | 
						|
 | 
						|
	// Get Call-ID.
 | 
						|
	osip_call_id_clone(bye->call_id, &okay->call_id);
 | 
						|
 | 
						|
	// Get Cseq.
 | 
						|
	openbts_message_set_cseq(okay, bye);
 | 
						|
 | 
						|
	return okay;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
osip_message_t * SIP::sip_trying( osip_message_t * invite, const char * sip_username, const char * local_ip )
 | 
						|
{
 | 
						|
	osip_message_t * trying;
 | 
						|
	openbts_message_init(&trying);
 | 
						|
	// FIXME -- Should use the "force_update" function.
 | 
						|
	trying->message_property = 2;
 | 
						|
 | 
						|
	// Set Header stuff.
 | 
						|
	trying->status_code = 100;	
 | 
						|
	trying->reason_phrase = strdup("Trying");
 | 
						|
	osip_message_set_version(trying, strdup("SIP/2.0"));
 | 
						|
	osip_uri_init(&invite->req_uri);	// FIXME? -- Invite rather than trying?
 | 
						|
 | 
						|
	// Get Via
 | 
						|
	openbts_message_set_via(trying, invite);
 | 
						|
	
 | 
						|
	// from/to header
 | 
						|
	osip_from_clone(invite->from, &trying->from);
 | 
						|
	osip_to_clone(invite->to, &trying->to);
 | 
						|
 | 
						|
	// Get Call-ID.
 | 
						|
	osip_call_id_clone(invite->call_id, &trying->call_id);
 | 
						|
 | 
						|
	// Get Cseq.
 | 
						|
	openbts_message_set_cseq(trying, invite);
 | 
						|
 | 
						|
	// CONTACT URI
 | 
						|
	osip_contact_t * con;
 | 
						|
	osip_to_init(&con);
 | 
						|
	osip_uri_init(&con->url);
 | 
						|
	osip_uri_set_host(con->url, strdup(local_ip));
 | 
						|
	//osip_uri_set_port(con->url, strdup(local_port));	// FIXME ??
 | 
						|
	osip_uri_set_username(con->url, strdup(sip_username));
 | 
						|
 | 
						|
	// add contact
 | 
						|
	osip_list_add(&trying->contacts, con, -1);
 | 
						|
 | 
						|
	return trying;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
osip_message_t * SIP::sip_ringing( osip_message_t * invite, const char * sip_username, const char *local_ip)
 | 
						|
{
 | 
						|
	osip_message_t * ringing;
 | 
						|
	openbts_message_init(&ringing);
 | 
						|
	// FIXME -- Should use the "force_update" function.
 | 
						|
	ringing->message_property = 2;
 | 
						|
 | 
						|
	// Set Header stuff.
 | 
						|
	ringing->status_code = 180;	
 | 
						|
	ringing->reason_phrase = strdup("Ringing");
 | 
						|
	osip_message_set_version(ringing, strdup("SIP/2.0"));
 | 
						|
	//osip_uri_init(&invite->req_uri);
 | 
						|
 | 
						|
	// Get Via.
 | 
						|
	openbts_message_set_via(ringing, invite);
 | 
						|
	
 | 
						|
	// from/to header
 | 
						|
	osip_from_clone(invite->from, &ringing->from);
 | 
						|
	osip_to_clone(invite->to, &ringing->to);
 | 
						|
 | 
						|
	// Get Call-ID.
 | 
						|
	osip_call_id_clone(invite->call_id, &ringing->call_id);
 | 
						|
 | 
						|
	// Get Cseq.
 | 
						|
	openbts_message_set_cseq(ringing, invite);
 | 
						|
 | 
						|
	// CONTACT URI
 | 
						|
	osip_contact_t * con;
 | 
						|
	osip_to_init(&con);
 | 
						|
	osip_uri_init(&con->url);
 | 
						|
	osip_uri_set_host(con->url, strdup(local_ip));
 | 
						|
	osip_uri_set_username(con->url, strdup(sip_username));
 | 
						|
 | 
						|
	// add contact
 | 
						|
	osip_list_add(&ringing->contacts, con, -1);
 | 
						|
 | 
						|
	return ringing;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
osip_message_t * SIP::sip_okay( osip_message_t * inv, const char * sip_username, const char * local_ip, short wlocal_port)
 | 
						|
{
 | 
						|
 | 
						|
	// Check for consistency.
 | 
						|
	if(inv==NULL){ return NULL;}
 | 
						|
 | 
						|
	char local_port[20];
 | 
						|
	sprintf(local_port, "%i", wlocal_port);
 | 
						|
 | 
						|
	osip_message_t * okay;
 | 
						|
	openbts_message_init(&okay);
 | 
						|
	// FIXME -- Should use the "force_update" function.
 | 
						|
	okay->message_property = 2;
 | 
						|
 | 
						|
	// FIXME -- Do we really need all of this string conversion?
 | 
						|
 | 
						|
	// Set Header stuff.
 | 
						|
	okay->status_code = 200;	
 | 
						|
	okay->reason_phrase = strdup("OK");
 | 
						|
	osip_message_set_version(okay, strdup("SIP/2.0"));
 | 
						|
	osip_uri_init(&okay->req_uri);
 | 
						|
 | 
						|
	// Get Record Route.
 | 
						|
	openbts_message_set_rr(okay, inv);
 | 
						|
 | 
						|
	// SIP Okay needs to repeat the Via tags from the INVITE Message.
 | 
						|
//	osip_via_clone(inv->via, &okay->via);
 | 
						|
	openbts_message_set_via(okay, inv);
 | 
						|
 | 
						|
	// from/to header
 | 
						|
	osip_from_clone(inv->from, &okay->from);
 | 
						|
	osip_to_clone(inv->to, &okay->to);
 | 
						|
 | 
						|
	// Get Call-ID.
 | 
						|
	osip_call_id_clone(inv->call_id, &okay->call_id);
 | 
						|
 | 
						|
	// Get Cseq.
 | 
						|
	openbts_message_set_cseq(okay, inv);
 | 
						|
 | 
						|
	return okay;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
osip_message_t * SIP::sip_info(unsigned info, const char *dialed_number, short rtp_port, const char * sip_username, short wlocal_port, const char * local_ip, const char * proxy_ip, const char * from_tag, const char * via_branch, const osip_call_id_t *call_id_header, int cseq) {
 | 
						|
 | 
						|
	char local_port[10];
 | 
						|
	sprintf(local_port, "%i", wlocal_port);
 | 
						|
 | 
						|
	osip_message_t * request;
 | 
						|
	openbts_message_init(&request);
 | 
						|
	// FIXME -- Should use the "force_update" function.
 | 
						|
	request->message_property = 2;
 | 
						|
	request->sip_method = strdup("INFO");
 | 
						|
	osip_message_set_version(request, strdup("SIP/2.0"));	
 | 
						|
	osip_uri_init(&request->req_uri);
 | 
						|
	osip_uri_set_host(request->req_uri, strdup(proxy_ip));
 | 
						|
	osip_uri_set_username(request->req_uri, strdup(dialed_number));
 | 
						|
	
 | 
						|
	// VIA
 | 
						|
	osip_via_t * via;
 | 
						|
	osip_via_init(&via);
 | 
						|
	via_set_version(via, strdup("2.0"));
 | 
						|
	via_set_protocol(via, strdup("UDP"));
 | 
						|
	via_set_host(via, strdup(local_ip));
 | 
						|
	via_set_port(via, strdup(local_port));
 | 
						|
 | 
						|
	// VIA BRANCH
 | 
						|
	osip_via_set_branch(via, strdup(via_branch));
 | 
						|
 | 
						|
	// add via
 | 
						|
	osip_list_add(&request->vias, via, -1);
 | 
						|
 | 
						|
	// FROM
 | 
						|
	osip_from_init(&request->from);
 | 
						|
	osip_from_set_displayname(request->from, strdup(sip_username));
 | 
						|
 | 
						|
	// FROM TAG
 | 
						|
	osip_from_set_tag(request->from, strdup(from_tag));
 | 
						|
 | 
						|
	osip_uri_init(&request->from->url);
 | 
						|
	osip_uri_set_host(request->from->url, strdup(proxy_ip));
 | 
						|
	osip_uri_set_username(request->from->url, strdup(sip_username));
 | 
						|
 | 
						|
	// TO
 | 
						|
	osip_to_init(&request->to);
 | 
						|
	osip_to_set_displayname(request->to, strdup(""));
 | 
						|
	osip_uri_init(&request->to->url);
 | 
						|
	osip_uri_set_host(request->to->url, strdup(proxy_ip));
 | 
						|
	osip_uri_set_username(request->to->url, strdup(dialed_number));
 | 
						|
 | 
						|
	// CALL ID
 | 
						|
	osip_call_id_clone(call_id_header, &request->call_id);
 | 
						|
 | 
						|
	// CSEQ
 | 
						|
	osip_cseq_init(&request->cseq);
 | 
						|
	osip_cseq_set_method(request->cseq, strdup("INFO"));
 | 
						|
	char temp_buf[21];
 | 
						|
	sprintf(temp_buf,"%i",cseq);
 | 
						|
	osip_cseq_set_number(request->cseq, strdup(temp_buf));	
 | 
						|
 | 
						|
	osip_message_set_content_type(request, strdup("application/dtmf-relay"));
 | 
						|
	char message[31];
 | 
						|
	// FIXME -- This duration should probably come from a config file.
 | 
						|
	switch (info) {
 | 
						|
		case 11:
 | 
						|
			snprintf(message,sizeof(message),"Signal=*\nDuration=200");
 | 
						|
			break;
 | 
						|
		case 12:
 | 
						|
			snprintf(message,sizeof(message),"Signal=#\nDuration=200");
 | 
						|
			break;
 | 
						|
		default:
 | 
						|
			snprintf(message,sizeof(message),"Signal=%i\nDuration=200",info);
 | 
						|
	}
 | 
						|
	sprintf(temp_buf,"%lu",strlen(message));
 | 
						|
	osip_message_set_content_length(request, strdup(temp_buf));
 | 
						|
 | 
						|
	// Payload.
 | 
						|
	osip_message_set_body(request,message,strlen(message));
 | 
						|
 | 
						|
	return request;	
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
// vim: ts=4 sw=4
 |