exosip针对UA是对osip进行扩展,oSIP不提供不论什么高速产生请求消息和响应消息的方法,全部请求消息和响应消息的形成必须调用一组sip message api来手动组装完毕,所以作者在osip上基础上开发了exosip,用exosip开发软电话非常方便,仅需几个API就能够完毕.exosip中附带一个样例:josua,只是josua相对复杂了点,以下给出一个最简单的样例供大家參考,由于样例实在太简单所以没有给出凝视,用到exosip的API的參数请參看exosip源码,看懂这个样例再研究josua就非常easy了.我使用的是osip 2.0.9+exosip 0.77.
#include "assert.h"
#include <conio.h>
#include <iostream>
#include <osip2/osip_mt.h>
#include <eXosip/eXosip.h>
#include <eXosip/eXosip_cfg.h>
using namespace std;
class jcall;
class jcall {
public:
int cid;
int did;
char reason_phrase[50];
int status_code;
char textinfo[256];
char req_uri[256];
char local_uri[256];
char remote_uri[256];
char subject[256];
char remote_sdp_audio_ip[50];
int remote_sdp_audio_port;
int payload;
char payload_name[50];
int state;
jcall() {}
int build(eXosip_event_t *je)
{
jcall *ca = this;
ca->cid = je->cid;
ca->did = je->did;
if (ca->did<1 && ca->cid<1)
{
assert(0);
return -1; /* not enough information for this event?? */
}
osip_strncpy(ca->textinfo, je->textinfo, 255);
osip_strncpy(ca->req_uri, je->req_uri, 255);
osip_strncpy(ca->local_uri, je->local_uri, 255);
osip_strncpy(ca->remote_uri, je->remote_uri, 255);
osip_strncpy(ca->subject, je->subject, 255);
if (ca->remote_sdp_audio_ip[0]==‘/0‘)
{
osip_strncpy(ca->remote_sdp_audio_ip, je->remote_sdp_audio_ip, 49);
ca->remote_sdp_audio_port = je->remote_sdp_audio_port;
ca->payload = je->payload;
osip_strncpy(ca->payload_name, je->payload_name, 49);
}
if (je->reason_phrase[0]!=‘/0‘)
{
osip_strncpy(ca->reason_phrase, je->reason_phrase, 49);
ca->status_code = je->status_code;
}
ca->state = je->type;
return 0;
}
};
jcall call;
void __exit( int r )
{
char line[256];
gets( line );
exit( r );
}
void josua_printf(char* buf)
{
printf( "/n" );
}
int josua_event_get()
{
int counter =0;
/* use events to print some info */
eXosip_event_t *je;
for (;;)
{
char buf[100];
je = eXosip_event_wait(0,50);
if (je==NULL)
break;
counter++;
if (je->type==EXOSIP_CALL_NEW)
{
printf( "<- (%i %i) INVITE from: %s",
je->cid, je->did,
je->remote_uri);
josua_printf(buf);
call.build(je);
}
else if (je->type==EXOSIP_CALL_ANSWERED)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_CALL_PROCEEDING)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_CALL_RINGING)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_CALL_REDIRECTED)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_CALL_REQUESTFAILURE)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_CALL_SERVERFAILURE)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_CALL_GLOBALFAILURE)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_CALL_CLOSED)
{
printf( "<- (%i %i) BYE from: %s",
je->cid, je->did, je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_CALL_HOLD)
{
printf( "<- (%i %i) INVITE (On Hold) from: %s",
je->cid, je->did, je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_CALL_OFFHOLD)
{
printf( "<- (%i %i) INVITE (Off Hold) from: %s",
je->cid, je->did, je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_REGISTRATION_SUCCESS)
{
printf( "<- (%i) [%i %s] %s for REGISTER %s",
je->rid,
je->status_code,
je->reason_phrase,
je->remote_uri,
je->req_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_REGISTRATION_FAILURE)
{
printf( "<- (%i) [%i %s] %s for REGISTER %s",
je->rid,
je->status_code,
je->reason_phrase,
je->remote_uri,
je->req_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_OPTIONS_NEW)
{
printf( "<- (%i %i) OPTIONS from: %s",
je->cid, je->did,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_OPTIONS_ANSWERED)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_OPTIONS_PROCEEDING)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_OPTIONS_REDIRECTED)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_OPTIONS_REQUESTFAILURE)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_OPTIONS_SERVERFAILURE)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_OPTIONS_GLOBALFAILURE)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_INFO_NEW)
{
printf( "<- (%i %i) INFO from: %s",
je->cid, je->did,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_INFO_ANSWERED)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_INFO_PROCEEDING)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_INFO_REDIRECTED)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_INFO_REQUESTFAILURE)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_INFO_SERVERFAILURE)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_INFO_GLOBALFAILURE)
{
printf( "<- (%i %i) [%i %s] %s",
je->cid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_SUBSCRIPTION_ANSWERED)
{
printf( "<- (%i %i) [%i %s] %s for SUBSCRIBE",
je->sid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
printf( "<- (%i %i) online=%i [status: %i reason:%i]",
je->sid, je->did,
je->online_status,
je->ss_status,
je->ss_reason);
josua_printf(buf);
}
else if (je->type==EXOSIP_SUBSCRIPTION_PROCEEDING)
{
printf( "<- (%i %i) [%i %s] %s for SUBSCRIBE",
je->sid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_SUBSCRIPTION_REDIRECTED)
{
printf( "<- (%i %i) [%i %s] %s for SUBSCRIBE",
je->sid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_SUBSCRIPTION_REQUESTFAILURE)
{
printf( "<- (%i %i) [%i %s] %s for SUBSCRIBE",
je->sid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_SUBSCRIPTION_SERVERFAILURE)
{
printf( "<- (%i %i) [%i %s] %s for SUBSCRIBE",
je->sid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_SUBSCRIPTION_GLOBALFAILURE)
{
printf( "<- (%i %i) [%i %s] %s for SUBSCRIBE",
je->sid, je->did,
je->status_code,
je->reason_phrase,
je->remote_uri);
josua_printf(buf);
}
else if (je->type==EXOSIP_SUBSCRIPTION_NOTIFY)
{
printf( "<- (%i %i) NOTIFY from: %s",
je->sid, je->did,
je->remote_uri);
josua_printf(buf);
printf( "<- (%i %i) online=%i [status: %i reason:%i]",
je->sid, je->did,
je->online_status,
je->ss_status,
je->ss_reason);
josua_printf(buf);
}
else if (je->type==EXOSIP_IN_SUBSCRIPTION_NEW)
{
printf( "<- (%i %i) SUBSCRIBE from: %s",
je->nid, je->did,
je->remote_uri);
josua_printf(buf);
/* search for the user to see if he has been
previously accepted or not! */
eXosip_notify(je->did, EXOSIP_SUBCRSTATE_PENDING, EXOSIP_NOTIFY_AWAY);
}
else if (je->textinfo[0]!=‘/0‘)
{
printf( "(%i %i %i %i) %s", je->cid, je->sid, je->nid, je->did, je->textinfo);
josua_printf(buf);
}
eXosip_event_free(je);
}
if (counter>0)
return 0;
return -1;
}
int main(int argc, char* argv[])
{
int i;
memset( &call, 0, sizeof(call) );
cout << "Usage:"<< endl;
cout << "a - answering call"<< endl;
cout << "h - hangup"<< endl;
cout << "r - ringing"<< endl;
cout << "c - call"<< endl;
cout << "q - quit"<< endl;
FILE* logfile = fopen( "logfile.txt", "w");
// osip_trace_initialize( (_trace_level)0, logfile );
// osip_trace_initialize( (_trace_level)8, stdout );
i = eXosip_init(stdin, stdout, 5060);
if (i!=0)
{
fprintf (stderr, "test: could not initialize eXosip/n");
__exit(0);
}
eXosip_sdp_negotiation_remove_audio_payloads();
eXosip_sdp_negotiation_add_codec(osip_strdup("0"),
NULL,
osip_strdup("RTP/AVP"),
NULL, NULL, NULL,
NULL,NULL,
osip_strdup("0 PCMU/8000"));
eXosip_sdp_negotiation_add_codec(osip_strdup("8"),
NULL,
osip_strdup("RTP/AVP"),
NULL, NULL, NULL,
NULL,NULL,
osip_strdup("8 PCMA/8000"));
/* register callbacks? */
eXosip_set_mode(EVENT_MODE);
osip_message_t *invite;
i = eXosip_build_initial_invite(&invite,
"sip:192.168.197.5:5060", //被叫对IP
"sip:192.168.197.254:5060", //自己IP
NULL,
"oSIP phone");
if (i!=0)
{
fprintf (stderr, "eXosip_build_initial_invite failed/n");
__exit(0);
}
cout << "oSIP>";
bool run = true;
while( run )
{
josua_event_get();
if ( _kbhit() )
{
switch ( _getch() )
{
case ‘a‘:
cout << "answer"<< endl;
eXosip_lock();
eXosip_answer_call(call.did, 200, 0);
eXosip_unlock();
break;
case ‘h‘:
cout << "hangup"<< endl;
eXosip_lock();
eXosip_terminate_call( call.cid, call.did );
eXosip_unlock();
break;
case ‘r‘:
cout << "ringing"<< endl;
eXosip_lock();
eXosip_answer_call(call.did, 180, 0);
eXosip_unlock();
break;
case ‘c‘:
cout << "call"<< endl;
eXosip_lock();
eXosip_initiate_call(invite, NULL, NULL, "10500");
eXosip_unlock();
break;
case ‘q‘:
cout << "quit"<< endl;
run = false;
break;
default :
cout << "/noSIP>";
}
}
}
return 0;
}