Skip to content
Snippets Groups Projects
Commit 3a3b996c authored by yanmorin's avatar yanmorin
Browse files

Implementing registration and outgoing call

parent 9f7579f1
No related branches found
No related tags found
No related merge requests found
......@@ -26,11 +26,42 @@
#define IAX_SUCCESS 0
#define IAX_FAILURE -1
#define RANDOM_IAX_PORT rand() % 64000 + 1024
// from IAXC : iaxclient.h
/* payload formats : WARNING: must match libiax values!!! */
/* Data formats for capabilities and frames alike */
#define IAX__FORMAT_G723_1 (1 << 0) /* G.723.1 compression */
#define IAX__FORMAT_GSM (1 << 1) /* GSM compression */
#define IAX__FORMAT_ULAW (1 << 2) /* Raw mu-law data (G.711) */
#define IAX__FORMAT_ALAW (1 << 3) /* Raw A-law data (G.711) */
#define IAX__FORMAT_G726 (1 << 4) /* ADPCM, 32kbps */
#define IAX__FORMAT_ADPCM (1 << 5) /* ADPCM IMA */
#define IAX__FORMAT_SLINEAR (1 << 6) /* Raw 16-bit Signed Linear (8000 Hz) PCM */
#define IAX__FORMAT_LPC10 (1 << 7) /* LPC10, 180 samples/frame */
#define IAX__FORMAT_G729A (1 << 8) /* G.729a Audio */
#define IAX__FORMAT_SPEEX (1 << 9) /* Speex Audio */
#define IAX__FORMAT_ILBC (1 << 10) /* iLBC Audio */
#define IAX__FORMAT_MAX_AUDIO (1 << 15) /* Maximum audio format */
#define IAX__FORMAT_JPEG (1 << 16) /* JPEG Images */
#define IAX__FORMAT_PNG (1 << 17) /* PNG Images */
#define IAX__FORMAT_H261 (1 << 18) /* H.261 Video */
#define IAX__FORMAT_H263 (1 << 19) /* H.263 Video */
#define IAX__FORMAT_H263_PLUS (1 << 20) /* H.263+ Video */
#define IAX__FORMAT_MPEG4 (1 << 21) /* MPEG4 Video */
#define IAX__FORMAT_H264 (1 << 23) /* H264 Video */
#define IAX__FORMAT_THEORA (1 << 24) /* Theora Video */
IAXVoIPLink::IAXVoIPLink(const AccountID& accountID)
: VoIPLink(accountID)
{
_evThread = new EventThread(this);
_regSession = 0;
// to get random number for RANDOM_PORT
srand (time(NULL));
}
......@@ -48,17 +79,31 @@ IAXVoIPLink::init()
//_localAddress = "127.0.0.1";
// port 0 is default
// iax_enable_debug(); have to enable debug when compiling iax...
int port = iax_init(IAX_DEFAULT_PORTNO);
if (port == IAX_FAILURE) {
_debug("IAX Failure: Error when initializing\n");
} else if ( port == 0 ) {
_debug("IAX Warning: already initialize\n");
} else {
_debug("IAX Info: listening on port %d\n", port);
_localPort = port;
returnValue = true;
_evThread->start();
int port = IAX_DEFAULT_PORTNO;
int last_port = 0;
int nbTry = 3;
while (port != IAX_FAILURE && nbTry) {
last_port = port;
port = iax_init(port);
if ( port < 0 ) {
_debug("IAX Warning: already initialize on port %d\n", last_port);
port = RANDOM_IAX_PORT;
} else if (port == IAX_FAILURE) {
_debug("IAX Fail to start on port %d", last_port);
port = RANDOM_IAX_PORT;
} else {
_debug("IAX Info: listening on port %d\n", last_port);
_localPort = last_port;
returnValue = true;
_evThread->start();
break;
}
nbTry--;
}
if (port == IAX_FAILURE || nbTry==0) {
_debug("Fail to initialize iax\n");
}
return returnValue;
}
......@@ -75,42 +120,44 @@ void
IAXVoIPLink::getEvent()
{
// mutex here
_mutexIAX.enterMutex();
iax_event* event = 0;
IAXCall* call = 0;
while ( (event = iax_get_event(0)) != 0 ) {
_debug ("Receive IAX Event: %d\n", event->etype);
call = iaxFindCallBySession(event->session);
if (call!=0) {
iaxHandleCallEvent(event, call);
iaxHandleCallEvent(event, call);
} else if (event->session != 0 && event->session == _regSession) {
// in iaxclient, there is many session handling, here, only one
iaxHandleRegReply(event);
// in iaxclient, there is many session handling, here, only one
iaxHandleRegReply(event);
} else {
switch(event->etype) {
case IAX_EVENT_REGACK:
case IAX_EVENT_REGREJ:
_debug("Unknown IAX Registration Event\n");
break;
case IAX_EVENT_REGREQ:
_debug("Registration by a peer, don't allow it\n");
break;
case IAX_EVENT_CONNECT: // new call
// New incoming call!
break;
case IAX_EVENT_TIMEOUT: // timeout for an unknown session
break;
default:
_debug("Unknown event type: %d\n", event->etype);
}
switch(event->etype) {
case IAX_EVENT_REGACK:
case IAX_EVENT_REGREJ:
_debug("Unknown IAX Registration Event\n");
break;
case IAX_EVENT_REGREQ:
_debug("Registration by a peer, don't allow it\n");
break;
case IAX_EVENT_CONNECT: // new call
// New incoming call!
break;
case IAX_EVENT_TIMEOUT: // timeout for an unknown session
break;
default:
_debug("Unknown event type: %d\n", event->etype);
}
}
iax_event_free(event);
}
// unlock mutex here
_mutexIAX.leaveMutex();
//iaxRefreshRegistrations();
// thread wait 5 millisecond
......@@ -130,8 +177,9 @@ IAXVoIPLink::setRegister()
Manager::instance().displayConfigError("Fill user field for IAX Account");
return false;
}
// lock
// lock
_mutexIAX.enterMutex();
_regSession = iax_session_new();
if (!_regSession) {
......@@ -147,12 +195,13 @@ IAXVoIPLink::setRegister()
strcpy(pass, _pass.c_str());
//iax_register don't use const char*
_debug("Sending registration to %s with user %s\n", host, user);
iax_register(_regSession, host, user, pass, 300);
_debug("IAX Sending registration to %s with user %s\n", host, user);
int val = iax_register(_regSession, host, user, pass, 300);
_debug ("Return value: %d\n", val);
result = true;
}
// unlock
_mutexIAX.leaveMutex();
}
return result;
}
......@@ -160,9 +209,69 @@ IAXVoIPLink::setRegister()
bool
IAXVoIPLink::setUnregister()
{
if (_regSession==0) {
// lock here
_mutexIAX.enterMutex();
iax_destroy(_regSession);
_regSession = 0;
// unlock here
_mutexIAX.leaveMutex();
return false;
}
return false;
}
Call*
IAXVoIPLink::newOutgoingCall(const CallID& id, const std::string& toUrl)
{
IAXCall* call = new IAXCall(id, Call::Outgoing);
if (call) {
call->setPeerNumber(toUrl);
// we have to add the codec before using it in SIPOutgoingInvite...
//call->setCodecMap(Manager::instance().getCodecDescriptorMap());
if ( iaxOutgoingInvite(call) ) {
call->setConnectionState(Call::Progressing);
call->setState(Call::Active);
addCall(call);
} else {
delete call; call = 0;
}
}
return call;
}
bool
IAXVoIPLink::iaxOutgoingInvite(IAXCall* call)
{
struct iax_session *newsession;
// lock here
_mutexIAX.enterMutex();
newsession = iax_session_new();
if (!newsession) {
_debug("IAX Error: Can't make new session for a new call\n");
// unlock here
_mutexIAX.leaveMutex();
return false;
}
call->setSession(newsession);
/* reset activity and ping "timers" */
// iaxc_note_activity(callNo);
char num[call->getPeerNumber().length()+1];
strcpy(num, call->getPeerNumber().c_str());
char* lang = NULL;
int wait = 0;
int audio_format_preferred = IAX__FORMAT_SPEEX;
int audio_format_capability = IAX__FORMAT_ULAW | IAX__FORMAT_ALAW | IAX__FORMAT_GSM | IAX__FORMAT_SPEEX;
iax_call(newsession, num, num, num, lang, wait, audio_format_preferred, audio_format_capability);
// unlock here
_mutexIAX.leaveMutex();
return true;
}
IAXCall*
IAXVoIPLink::iaxFindCallBySession(struct iax_session* session)
{
......@@ -196,7 +305,7 @@ IAXVoIPLink::iaxHandleCallEvent(iax_event* event, IAXCall* call)
case IAX_EVENT_ACCEPT:
break;
case IAX_EVENT_ANSWER:
break;
......@@ -233,8 +342,17 @@ IAXVoIPLink::iaxHandleCallEvent(iax_event* event, IAXCall* call)
}
}
void
IAXVoIPLink::iaxHandleRegReply(iax_event* event)
{
// use _regSession here, should be equal to event->session;
//unregister
if (event->etype == IAX_EVENT_REGREJ) {
iax_destroy(_regSession);
_regSession = 0;
Manager::instance().registrationFailed(getAccountID());
} else if (event->etype == IAX_EVENT_REGACK) {
Manager::instance().registrationSucceed(getAccountID());
}
}
......@@ -45,7 +45,7 @@ public:
bool setRegister (void);
bool setUnregister (void);
Call* newOutgoingCall(const CallID& id, const std::string& toUrl) {return 0; }
Call* newOutgoingCall(const CallID& id, const std::string& toUrl);
bool answer(const CallID& id) {return false;}
bool hangup(const CallID& id) { return false; }
......@@ -83,6 +83,11 @@ private:
*/
void iaxHandleRegReply(iax_event* event);
/**
* Send an outgoing call invite to iax
*/
bool iaxOutgoingInvite(IAXCall* Call);
EventThread* _evThread;
/** registration session : 0 if not register */
struct iax_session* _regSession;
......@@ -93,7 +98,8 @@ private:
std::string _user;
/** IAX Password */
std::string _pass;
ost::Mutex _mutexIAX;
};
#endif
......@@ -421,12 +421,11 @@ ManagerImpl::initRegisterVoIPLink()
if ( iter->second) {
iter->second->loadConfig();
if ( iter->second->shouldInitOnStart() ) {
iter->second->init();
if (iter->second->shouldRegisterOnStart()) {
iter->second->registerAccount();
if ( iter->second->init() && iter->second->shouldRegisterOnStart()) {
iter->second->registerAccount();
}
// init only the first account
break;
// init only the first account
break;
}
}
iter++;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment