- switch to latest resiprocate
This commit is contained in:
9
src/libs/resiprocate/apps/ichat-gw/.gitignore
vendored
Normal file
9
src/libs/resiprocate/apps/ichat-gw/.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
/Makefile.in
|
||||
/Makefile
|
||||
/.deps
|
||||
/.libs
|
||||
/.dirstamp
|
||||
|
||||
/ichat-gw
|
||||
|
||||
216
src/libs/resiprocate/apps/ichat-gw/AddressTranslator.cxx
Normal file
216
src/libs/resiprocate/apps/ichat-gw/AddressTranslator.cxx
Normal file
@@ -0,0 +1,216 @@
|
||||
|
||||
#include "rutil/Logger.hxx"
|
||||
#include "rutil/ParseBuffer.hxx"
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "AddressTranslator.hxx"
|
||||
#include "rutil/WinLeakCheck.hxx"
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::GATEWAY
|
||||
|
||||
using namespace gateway;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
AddressTranslator::AddressTranslator()
|
||||
{
|
||||
}
|
||||
|
||||
AddressTranslator::~AddressTranslator()
|
||||
{
|
||||
// Destroy all of the filters
|
||||
for(FilterOpList::iterator it = mFilterOperators.begin(); it != mFilterOperators.end(); it++)
|
||||
{
|
||||
if ( it->preq )
|
||||
{
|
||||
regfree ( it->preq );
|
||||
delete it->preq;
|
||||
it->preq = 0;
|
||||
}
|
||||
}
|
||||
mFilterOperators.clear();
|
||||
}
|
||||
|
||||
void
|
||||
AddressTranslator::addTranslation(const resip::Data& matchingPattern,
|
||||
const resip::Data& rewriteExpression)
|
||||
{
|
||||
InfoLog( << "Add translation " << matchingPattern << " -> " << rewriteExpression);
|
||||
|
||||
FilterOp filter;
|
||||
filter.mMatchingPattern = matchingPattern;
|
||||
filter.mRewriteExpression = rewriteExpression;
|
||||
|
||||
if( !filter.mMatchingPattern.empty() )
|
||||
{
|
||||
int flags = REG_EXTENDED;
|
||||
if( filter.mRewriteExpression.find("$") == Data::npos )
|
||||
{
|
||||
flags |= REG_NOSUB;
|
||||
}
|
||||
filter.preq = new regex_t;
|
||||
int ret = regcomp( filter.preq, filter.mMatchingPattern.c_str(), flags );
|
||||
if( ret != 0 )
|
||||
{
|
||||
delete filter.preq;
|
||||
ErrLog( << "Translation has invalid match expression: "
|
||||
<< filter.mMatchingPattern );
|
||||
filter.preq = 0;
|
||||
}
|
||||
}
|
||||
mFilterOperators.push_back( filter );
|
||||
}
|
||||
|
||||
void
|
||||
AddressTranslator::removeTranslation(const resip::Data& matchingPattern )
|
||||
{
|
||||
FilterOpList::iterator it = mFilterOperators.begin();
|
||||
while ( it != mFilterOperators.end() )
|
||||
{
|
||||
if ( it->mMatchingPattern == matchingPattern )
|
||||
{
|
||||
FilterOpList::iterator i = it;
|
||||
it++;
|
||||
if ( i->preq )
|
||||
{
|
||||
regfree ( i->preq );
|
||||
delete i->preq;
|
||||
i->preq = 0;
|
||||
}
|
||||
mFilterOperators.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AddressTranslator::translate(const resip::Data& address, resip::Data& translation, bool failIfNoRule)
|
||||
{
|
||||
bool rc=false;
|
||||
DebugLog( << "Translating "<< address);
|
||||
|
||||
for (FilterOpList::iterator it = mFilterOperators.begin();
|
||||
it != mFilterOperators.end(); it++)
|
||||
{
|
||||
Data rewrite = it->mRewriteExpression;
|
||||
Data& match = it->mMatchingPattern;
|
||||
if ( it->preq )
|
||||
{
|
||||
int ret;
|
||||
|
||||
const int nmatch=10;
|
||||
regmatch_t pmatch[nmatch];
|
||||
|
||||
ret = regexec(it->preq, address.c_str(), nmatch, pmatch, 0/*eflags*/);
|
||||
if ( ret != 0 )
|
||||
{
|
||||
// did not match
|
||||
DebugLog( << " Skipped translation "<< address << " did not match " << match );
|
||||
continue;
|
||||
}
|
||||
|
||||
DebugLog( << " Matched translation "<< address << " matched " << match );
|
||||
translation = rewrite;
|
||||
rc=true;
|
||||
if ( rewrite.find("$") != Data::npos )
|
||||
{
|
||||
for ( int i=1; i<nmatch; i++)
|
||||
{
|
||||
if ( pmatch[i].rm_so != -1 )
|
||||
{
|
||||
Data subExp(address.substr(pmatch[i].rm_so,
|
||||
pmatch[i].rm_eo-pmatch[i].rm_so));
|
||||
DebugLog( << " subExpression[" <<i <<"]="<< subExp );
|
||||
|
||||
Data result;
|
||||
{
|
||||
DataStream s(result);
|
||||
|
||||
ParseBuffer pb(translation);
|
||||
|
||||
while (true)
|
||||
{
|
||||
const char* a = pb.position();
|
||||
pb.skipToChars( Data("$") + char('0'+i) );
|
||||
if ( pb.eof() )
|
||||
{
|
||||
s << pb.data(a);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
s << pb.data(a);
|
||||
pb.skipN(2);
|
||||
s << subExp;
|
||||
}
|
||||
}
|
||||
s.flush();
|
||||
}
|
||||
translation = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
translation = rewrite;
|
||||
rc = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't find a translation and we are not suppossed to fail, then just return address
|
||||
if(!rc && !failIfNoRule)
|
||||
{
|
||||
rc = true;
|
||||
translation = address;
|
||||
}
|
||||
|
||||
InfoLog( << "Translated "<< address << " to " << translation);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
79
src/libs/resiprocate/apps/ichat-gw/AddressTranslator.hxx
Normal file
79
src/libs/resiprocate/apps/ichat-gw/AddressTranslator.hxx
Normal file
@@ -0,0 +1,79 @@
|
||||
#if !defined(AddressTranslator_hxx)
|
||||
#define AddressTranslator_hxx
|
||||
|
||||
#include <list>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <pcreposix.h>
|
||||
#else
|
||||
#include <regex.h>
|
||||
#endif
|
||||
#include "rutil/Data.hxx"
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class AddressTranslator
|
||||
{
|
||||
public:
|
||||
AddressTranslator();
|
||||
~AddressTranslator();
|
||||
|
||||
void addTranslation(const resip::Data& matchingPattern,
|
||||
const resip::Data& rewriteExpression);
|
||||
|
||||
void removeTranslation(const resip::Data& matchingPattern);
|
||||
|
||||
bool translate(const resip::Data& address, resip::Data& translation, bool failIfNoRule=false);
|
||||
|
||||
private:
|
||||
class FilterOp
|
||||
{
|
||||
public:
|
||||
resip::Data mMatchingPattern;
|
||||
resip::Data mRewriteExpression;
|
||||
regex_t *preq;
|
||||
};
|
||||
|
||||
typedef std::list<FilterOp> FilterOpList;
|
||||
FilterOpList mFilterOperators;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
38
src/libs/resiprocate/apps/ichat-gw/AppSubsystem.cxx
Normal file
38
src/libs/resiprocate/apps/ichat-gw/AppSubsystem.cxx
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "AppSubsystem.hxx"
|
||||
|
||||
AppSubsystem AppSubsystem::GATEWAY("GATEWAY");
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
61
src/libs/resiprocate/apps/ichat-gw/AppSubsystem.hxx
Normal file
61
src/libs/resiprocate/apps/ichat-gw/AppSubsystem.hxx
Normal file
@@ -0,0 +1,61 @@
|
||||
#if !defined(AppSubsystem_hxx)
|
||||
#define AppSubsystem_hxx
|
||||
|
||||
#include <iostream>
|
||||
#include <rutil/Subsystem.hxx>
|
||||
|
||||
/**
|
||||
This class is used in the logging subsystem to identify
|
||||
logging messages generated from the iChat Gateway.
|
||||
|
||||
Author: Scott Godin (sgodin AT SipSpectrum DOT com)
|
||||
*/
|
||||
|
||||
class AppSubsystem : public resip::Subsystem
|
||||
{
|
||||
public:
|
||||
// Add new systems below
|
||||
static AppSubsystem GATEWAY;
|
||||
|
||||
private:
|
||||
explicit AppSubsystem(const char* rhs) : resip::Subsystem(rhs) {};
|
||||
explicit AppSubsystem(const resip::Data& rhs);
|
||||
AppSubsystem& operator=(const resip::Data& rhs);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
1699
src/libs/resiprocate/apps/ichat-gw/B2BSession.cxx
Normal file
1699
src/libs/resiprocate/apps/ichat-gw/B2BSession.cxx
Normal file
File diff suppressed because it is too large
Load Diff
175
src/libs/resiprocate/apps/ichat-gw/B2BSession.hxx
Normal file
175
src/libs/resiprocate/apps/ichat-gw/B2BSession.hxx
Normal file
@@ -0,0 +1,175 @@
|
||||
#if !defined(B2BSession_hxx)
|
||||
#define B2BSession_hxx
|
||||
|
||||
#include <rutil/Log.hxx>
|
||||
#include <rutil/SharedPtr.hxx>
|
||||
#include <resip/dum/DialogUsageManager.hxx>
|
||||
#include <resip/dum/InviteSessionHandler.hxx>
|
||||
#include <resip/dum/DialogSetHandler.hxx>
|
||||
#include <resip/dum/AppDialogSet.hxx>
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class Server;
|
||||
class IChatIPPortData;
|
||||
|
||||
typedef unsigned int B2BSessionHandle;
|
||||
|
||||
class B2BSession : public resip::AppDialogSet
|
||||
{
|
||||
public:
|
||||
B2BSession(Server& server, bool hasDialogSet=true);
|
||||
virtual ~B2BSession();
|
||||
|
||||
virtual void end();
|
||||
|
||||
void setPeer(B2BSession* peer);
|
||||
B2BSession* getPeer();
|
||||
void stealPeer(B2BSession* victimSession);
|
||||
|
||||
B2BSessionHandle getB2BSessionHandle() const { return mHandle; }
|
||||
|
||||
void initiateIChatCallRequest(const std::string& to, const std::string& from);
|
||||
bool createNewPeer(const resip::Uri& destinationUri, const resip::NameAddr& from, const resip::SdpContents *sdp);
|
||||
void startIChatCall(const resip::Uri& destinationUri, const resip::NameAddr& from, const resip::SdpContents *sdp);
|
||||
void startSIPCall(const resip::Uri& destinationUri, const resip::NameAddr& from, const resip::SdpContents *sdp);
|
||||
bool checkIChatCallMatch(const resip::SipMessage& msg);
|
||||
|
||||
// iChat call notifications from Jabber Component
|
||||
void notifyIChatCallCancelled();
|
||||
void notifyIChatCallProceeding(const std::string& to);
|
||||
void notifyIChatCallFailed(unsigned int statusCode);
|
||||
void continueIChatCall(const std::string& remoteIPPortListBlob);
|
||||
void timeoutIChatCall();
|
||||
|
||||
// IPC messages for Jabber Component
|
||||
void initiateIChatCall();
|
||||
void cancelIChatCall();
|
||||
void proceedingIChatCall();
|
||||
void acceptIChatCall();
|
||||
void rejectIChatCall();
|
||||
|
||||
protected:
|
||||
friend class Server;
|
||||
|
||||
virtual resip::SharedPtr<resip::UserProfile> selectUASUserProfile(const resip::SipMessage& msg);
|
||||
|
||||
// Invite Session Handler /////////////////////////////////////////////////////
|
||||
virtual void onNewSession(resip::ClientInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg);
|
||||
virtual void onNewSession(resip::ServerInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg);
|
||||
virtual void onFailure(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg);
|
||||
virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage&, const resip::SdpContents&);
|
||||
virtual void onProvisional(resip::ClientInviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onConnected(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg);
|
||||
virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onStaleCallTimeout(resip::ClientInviteSessionHandle);
|
||||
virtual void onTerminated(resip::InviteSessionHandle h, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* msg);
|
||||
virtual void onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onAnswer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&);
|
||||
virtual void onOffer(resip::InviteSessionHandle handle, const resip::SipMessage& msg, const resip::SdpContents& offer);
|
||||
virtual void onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onOfferRejected(resip::InviteSessionHandle, const resip::SipMessage* msg);
|
||||
virtual void onOfferRequestRejected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onRemoteSdpChanged(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents& sdp);
|
||||
virtual void onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual bool doReferNoSub(const resip::SipMessage& msg);
|
||||
virtual void onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessage(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessageSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessageFailure(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onForkDestroyed(resip::ClientInviteSessionHandle);
|
||||
|
||||
// DialogSetHandler //////////////////////////////////////////////
|
||||
virtual void onTrying(resip::AppDialogSetHandle, const resip::SipMessage& msg);
|
||||
virtual void onNonDialogCreatingProvisional(resip::AppDialogSetHandle, const resip::SipMessage& msg);
|
||||
|
||||
// ClientSubscriptionHandler ///////////////////////////////////////////////////
|
||||
virtual void onUpdatePending(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onUpdateActive(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onUpdateExtension(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onTerminated(resip::ClientSubscriptionHandle h, const resip::SipMessage* notify);
|
||||
virtual void onNewSubscription(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify);
|
||||
virtual int onRequestRetry(resip::ClientSubscriptionHandle h, int retryMinimum, const resip::SipMessage& notify);
|
||||
|
||||
private:
|
||||
bool buildLocalOffer(resip::SdpContents& sdp);
|
||||
bool buildLocalAnswer(resip::SdpContents& sdp);
|
||||
bool provideLocalAnswer(void);
|
||||
void endPeer();
|
||||
bool isUACConnected();
|
||||
bool isStaleFork(const resip::DialogId& dialogId);
|
||||
void fixupSdp(const resip::SdpContents& origSdp, resip::SdpContents& fixedSdp);
|
||||
unsigned int mapRejectionCodeForIChat(unsigned int statusCode);
|
||||
|
||||
Server& mServer;
|
||||
bool mHasDialogSet;
|
||||
resip::DialogUsageManager& mDum;
|
||||
B2BSession* mPeer;
|
||||
resip::InviteSessionHandle mInviteSessionHandle;
|
||||
B2BSessionHandle mHandle;
|
||||
resip::AppDialogSetHandle mReferringAppDialogSet;
|
||||
|
||||
// State information
|
||||
resip::DialogId mUACConnectedDialogId;
|
||||
bool mWaitingOfferFromPeer;
|
||||
bool mWaitingAnswerFromPeer;
|
||||
bool mWaitingNitAnswerFromPeer;
|
||||
bool mAnchorMedia;
|
||||
unsigned short mMediaRelayPort;
|
||||
|
||||
// IChat specific endpoint info
|
||||
bool mIChatEndpoint;
|
||||
bool mIChatWaitingToAccept;
|
||||
bool mIChatWaitingToProceed;
|
||||
bool mIChatWaitingToContinue;
|
||||
resip::Uri mIChatDestination;
|
||||
resip::NameAddr mIChatFrom;
|
||||
resip::SdpContents* mIChatSdp;
|
||||
std::string mIChatCallToJID;
|
||||
std::string mIChatCallFromJID;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
443
src/libs/resiprocate/apps/ichat-gw/ConfigParser.cxx
Executable file
443
src/libs/resiprocate/apps/ichat-gw/ConfigParser.cxx
Executable file
@@ -0,0 +1,443 @@
|
||||
#include "ConfigParser.hxx"
|
||||
#include "Server.hxx"
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
|
||||
#include <rutil/DnsUtil.hxx>
|
||||
#include <rutil/Log.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <rutil/WinLeakCheck.hxx>
|
||||
|
||||
using namespace gateway;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::GATEWAY
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
ConfigParser::ConfigParser(int argc, char** argv) :
|
||||
// Defaults
|
||||
mSipPort(5070),
|
||||
mTlsPort(5071),
|
||||
mTlsDomain(DnsUtil::getLocalHostName()),
|
||||
mRegistrationTime(3600),
|
||||
mRegistrationRetryTime(120),
|
||||
mKeepAlives(true),
|
||||
mLogLevel("INFO"),
|
||||
mLogFilename("ichat-gw.log"),
|
||||
mLogFileMaxLines(50000), // 50000 is about 5M size
|
||||
mGatewayIPCPort(2078),
|
||||
mJabberConnectorIPCPort(2079),
|
||||
mHttpPort(5090),
|
||||
mHttpAuth(false),
|
||||
mHttpAuthPwd("admin"),
|
||||
mIChatProceedingTimeout(5000),
|
||||
mAlwaysRelayIChatMedia(true),
|
||||
mPreferIPv6(false),
|
||||
mSkipFirstIChatAddress(false),
|
||||
mMediaRelayPortRangeMin(8000),
|
||||
mMediaRelayPortRangeMax(9999),
|
||||
mJabberComponentPort(5275),
|
||||
mJabberServerPingDuration(60) // 1 min
|
||||
{
|
||||
// Parse config file first
|
||||
parseConfigFile("ichat-gw.config");
|
||||
|
||||
// Parse command line options
|
||||
// Note: command line overrides config file setting
|
||||
parseCommandLine(argc, argv);
|
||||
}
|
||||
|
||||
ConfigParser::~ConfigParser()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ConfigParser::parseCommandLine(int argc, char** argv)
|
||||
{
|
||||
// Loop through command line arguments and process them
|
||||
for(int i = 1; i < argc; i++)
|
||||
{
|
||||
Data commandName(argv[i]);
|
||||
|
||||
// Process all commandNames that don't take values
|
||||
if(isEqualNoCase(commandName, "-?") ||
|
||||
isEqualNoCase(commandName, "--?") ||
|
||||
isEqualNoCase(commandName, "--help") ||
|
||||
isEqualNoCase(commandName, "/?"))
|
||||
{
|
||||
cout << "Command line options are:" << endl;
|
||||
cout << " -a <IP Address> - bind SIP transports to this IP address" << endl;
|
||||
cout << " -d <DNS servers> - comma seperated list of DNS servers, overrides OS detected list" << endl;
|
||||
cout << " -gi <Gateway identity> - used in From header of click-to-call requests to initiator" << endl;
|
||||
cout << " -sp <port num> - local port number to use for SIP messaging (UDP/TCP)" << endl;
|
||||
cout << " -tp <port num> - local port number to use for TLS SIP messaging" << endl;
|
||||
cout << " -td <domain name> - domain name to use for TLS server connections" << endl;
|
||||
cout << " -nk - no keepalives, set this to disable sending of keepalives" << endl;
|
||||
cout << " -op <SIP URI> - URI of a proxy server to use a SIP outbound proxy" << endl;
|
||||
cout << " -l <NONE|CRIT|ERR|WARNING|INFO|DEBUG|STACK> - logging level" << endl;
|
||||
cout << endl;
|
||||
cout << "Sample Command line:" << endl;
|
||||
cout << "ichat-gw -a 192.168.1.100 -l DEBUG" << endl;
|
||||
exit(0);
|
||||
}
|
||||
else if(isEqualNoCase(commandName, "-nk"))
|
||||
{
|
||||
mKeepAlives = false;
|
||||
}
|
||||
else if(commandName.at(0) == '-')
|
||||
{
|
||||
commandName = commandName.substr(1); // Remove -
|
||||
|
||||
// Process commands that have values
|
||||
Data commandValue(i+1 < argc ? argv[i+1] : Data::Empty);
|
||||
if(commandValue.empty() || commandValue.at(0) == '-')
|
||||
{
|
||||
cerr << "Invalid command line parameters!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
i++; // increment argument
|
||||
|
||||
//cout << "Command Line Name='" << commandName << "' value='" << commandValue << "'" << endl;
|
||||
if(!processOption(commandName.lowercase(), commandValue))
|
||||
{
|
||||
cerr << "Invalid command line parameters!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Invalid command line parameters!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConfigParser::parseConfigFile(const Data& filename)
|
||||
{
|
||||
ifstream configFile(filename.c_str());
|
||||
|
||||
string sline;
|
||||
while(getline(configFile, sline))
|
||||
{
|
||||
Data line(sline);
|
||||
Data name;
|
||||
Data value;
|
||||
ParseBuffer pb(line);
|
||||
|
||||
pb.skipWhitespace();
|
||||
const char * anchor = pb.position();
|
||||
if(pb.eof() || *anchor == '#') continue; // if line is a comment or blank then skip it
|
||||
// Look for =
|
||||
pb.skipToOneOf("= \t");
|
||||
if(!pb.eof())
|
||||
{
|
||||
pb.data(name,anchor);
|
||||
if(*pb.position()!='=')
|
||||
{
|
||||
pb.skipToChar('=');
|
||||
}
|
||||
pb.skipChar('=');
|
||||
pb.skipWhitespace();
|
||||
anchor = pb.position();
|
||||
if(!pb.eof())
|
||||
{
|
||||
pb.skipToEnd();
|
||||
pb.data(value, anchor);
|
||||
}
|
||||
//cout << "Config file Name='" << name << "' value='" << value << "'" << endl;
|
||||
processOption(name.lowercase(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ConfigParser::assignOnOffSetting(const Data& value, bool& setting)
|
||||
{
|
||||
if(value == "1" || value == "true" || value == "on" || value == "enable")
|
||||
{
|
||||
setting = true;
|
||||
return true;
|
||||
}
|
||||
else if(value == "0" || value == "false" || value == "off" || value == "disable")
|
||||
{
|
||||
setting = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ConfigParser::processOption(const Data& name, const Data& value)
|
||||
{
|
||||
bool result = true;
|
||||
if(name == "a" || name == "ipaddress")
|
||||
{
|
||||
mAddress = value;
|
||||
}
|
||||
else if(name == "d" || name == "dnsservers")
|
||||
{
|
||||
if(!value.empty()) mDnsServers.clear(); // allow command line to override config file, since list is added to
|
||||
|
||||
// DNS Servers
|
||||
ParseBuffer pb(value);
|
||||
Data dnsServer;
|
||||
while(!value.empty() && !pb.eof())
|
||||
{
|
||||
pb.skipWhitespace();
|
||||
const char *start = pb.position();
|
||||
pb.skipToOneOf(ParseBuffer::Whitespace, ";,"); // allow white space
|
||||
pb.data(dnsServer, start);
|
||||
if(DnsUtil::isIpV4Address(dnsServer))
|
||||
{
|
||||
mDnsServers.push_back(Tuple(dnsServer, 0, UNKNOWN_TRANSPORT).toGenericIPAddress());
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Tried to add dns server, but invalid format: " << value << endl;
|
||||
result = false;
|
||||
}
|
||||
if(!pb.eof())
|
||||
{
|
||||
pb.skipChar();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(name == "gi" || name == "sipgatewayidentity")
|
||||
{
|
||||
result = assignNameAddr("sip gateway identity", value, mGatewayIdentity);
|
||||
}
|
||||
else if(name == "sp" || name == "udptcpport")
|
||||
{
|
||||
mSipPort = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "tp" || name == "tlsport")
|
||||
{
|
||||
mTlsPort = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "td" || name == "tlsdomain")
|
||||
{
|
||||
mTlsDomain = value;
|
||||
}
|
||||
else if(name == "keepalives")
|
||||
{
|
||||
assignOnOffSetting(value, mKeepAlives);
|
||||
}
|
||||
else if(name == "op" || name == "outboundproxy")
|
||||
{
|
||||
result = assignNameAddr("outbound proxy", value, mOutboundProxy);
|
||||
}
|
||||
else if(name == "registrationtime")
|
||||
{
|
||||
mRegistrationTime = value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "registrationretrytime")
|
||||
{
|
||||
mRegistrationRetryTime = value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "l" || name == "loglevel")
|
||||
{
|
||||
mLogLevel = value;
|
||||
}
|
||||
else if(name == "logfilename")
|
||||
{
|
||||
mLogFilename = value;
|
||||
}
|
||||
else if(name == "logfilemaxlines")
|
||||
{
|
||||
mLogFileMaxLines = value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "gatewayipcport")
|
||||
{
|
||||
mGatewayIPCPort = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "jabberconnectoripcport")
|
||||
{
|
||||
mJabberConnectorIPCPort = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "httpport")
|
||||
{
|
||||
mHttpPort = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "httpauth")
|
||||
{
|
||||
assignOnOffSetting(value, mHttpAuth);
|
||||
}
|
||||
else if(name == "httpauthpwd")
|
||||
{
|
||||
mHttpAuthPwd = value;
|
||||
}
|
||||
else if(name == "ichatproceedingtimeout")
|
||||
{
|
||||
mIChatProceedingTimeout = value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "alwaysrelayichatmedia")
|
||||
{
|
||||
assignOnOffSetting(value, mAlwaysRelayIChatMedia);
|
||||
}
|
||||
else if(name == "preferipv6")
|
||||
{
|
||||
assignOnOffSetting(value, mPreferIPv6);
|
||||
}
|
||||
else if(name == "skipfirstichataddress")
|
||||
{
|
||||
assignOnOffSetting(value, mSkipFirstIChatAddress);
|
||||
}
|
||||
else if(name == "codecidfilterlist")
|
||||
{
|
||||
ParseBuffer pb(value);
|
||||
Data codecId;
|
||||
while(!value.empty() && !pb.eof())
|
||||
{
|
||||
pb.skipWhitespace();
|
||||
const char *start = pb.position();
|
||||
pb.skipToOneOf(ParseBuffer::Whitespace, ";,"); // allow white space
|
||||
pb.data(codecId, start);
|
||||
mCodecIdFilterList.insert((unsigned short)codecId.convertUnsignedLong());
|
||||
if(!pb.eof())
|
||||
{
|
||||
pb.skipChar();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(name == "mediarelayportrangemin")
|
||||
{
|
||||
mMediaRelayPortRangeMin = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "mediarelayportrangemax")
|
||||
{
|
||||
mMediaRelayPortRangeMax = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "translationpattern")
|
||||
{
|
||||
mAddressTranslations.push_back(std::make_pair(value, Data::Empty));
|
||||
}
|
||||
else if(name == "translationoutput")
|
||||
{
|
||||
if(!mAddressTranslations.empty())
|
||||
{
|
||||
mAddressTranslations.back().second = value;
|
||||
}
|
||||
}
|
||||
else if(name == "jabberserver")
|
||||
{
|
||||
mJabberServer = value;
|
||||
}
|
||||
else if(name == "jabbercomponentname")
|
||||
{
|
||||
mJabberComponentName = value;
|
||||
}
|
||||
else if(name == "jabbercomponentpassword")
|
||||
{
|
||||
mJabberComponentPassword = value;
|
||||
}
|
||||
else if(name == "jabbercomponentport")
|
||||
{
|
||||
mJabberComponentPort = (unsigned short)value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "jabberserverpingduration")
|
||||
{
|
||||
mJabberServerPingDuration = value.convertUnsignedLong();
|
||||
}
|
||||
else if(name == "jabbercontrolusername")
|
||||
{
|
||||
mJabberControlUsername = value;
|
||||
}
|
||||
else if(name == "tlsdhparamsfilename")
|
||||
{
|
||||
mTLSDHParamsFilename = value;
|
||||
}
|
||||
else if(name == "tlscertificate")
|
||||
{
|
||||
mTLSCertificate = value;
|
||||
}
|
||||
else if(name == "tlsprivateKey")
|
||||
{
|
||||
mTLSPrivateKey = value;
|
||||
}
|
||||
else if(name == "tlsprivatekeypassphrase")
|
||||
{
|
||||
mTLSPrivateKeyPassPhrase = value;
|
||||
}
|
||||
else if(name == "ichatjabberconnectorpath")
|
||||
{
|
||||
mIchatJabberConnectorPath = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
ConfigParser::assignNameAddr(const Data& settingName, const Data& settingValue, NameAddr& nameAddr)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(!settingValue.empty())
|
||||
{
|
||||
NameAddr tempNameAddr(settingValue);
|
||||
nameAddr = tempNameAddr;
|
||||
}
|
||||
}
|
||||
catch(resip::BaseException& e)
|
||||
{
|
||||
// Try adding sip: to address to see if it will be valid
|
||||
try
|
||||
{
|
||||
NameAddr tempNameAddr(Data("sip:" + settingValue));
|
||||
nameAddr = tempNameAddr;
|
||||
}
|
||||
catch(resip::BaseException&)
|
||||
{
|
||||
cerr << "Invalid " << settingName << " NameAddr format=" << settingValue << ": " << e << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
111
src/libs/resiprocate/apps/ichat-gw/ConfigParser.hxx
Executable file
111
src/libs/resiprocate/apps/ichat-gw/ConfigParser.hxx
Executable file
@@ -0,0 +1,111 @@
|
||||
#if !defined(ConfigParser_hxx)
|
||||
#define ConfigParser_hxx
|
||||
|
||||
#include <list>
|
||||
#include <resip/dum/MasterProfile.hxx>
|
||||
#include <rutil/dns/DnsStub.hxx>
|
||||
#include <rutil/Log.hxx>
|
||||
#include <rutil/SharedPtr.hxx>
|
||||
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class ConfigParser
|
||||
{
|
||||
public:
|
||||
ConfigParser(int argc, char** argv);
|
||||
virtual ~ConfigParser();
|
||||
|
||||
resip::Data mAddress;
|
||||
resip::DnsStub::NameserverList mDnsServers;
|
||||
resip::NameAddr mGatewayIdentity;
|
||||
unsigned short mSipPort;
|
||||
unsigned short mTlsPort;
|
||||
resip::Data mTlsDomain;
|
||||
resip::NameAddr mOutboundProxy;
|
||||
unsigned int mRegistrationTime;
|
||||
unsigned int mRegistrationRetryTime;
|
||||
bool mKeepAlives;
|
||||
resip::Data mLogLevel;
|
||||
resip::Data mLogFilename;
|
||||
unsigned int mLogFileMaxLines;
|
||||
unsigned short mGatewayIPCPort;
|
||||
unsigned short mJabberConnectorIPCPort;
|
||||
unsigned short mHttpPort;
|
||||
bool mHttpAuth;
|
||||
resip::Data mHttpAuthPwd;
|
||||
unsigned int mIChatProceedingTimeout;
|
||||
bool mAlwaysRelayIChatMedia;
|
||||
bool mPreferIPv6;
|
||||
bool mSkipFirstIChatAddress; // (for testing): skipping the first IPV4 NAT mapped address (on systems with one interface) causes the local address to be used
|
||||
typedef std::set<unsigned short> CodecIdList;
|
||||
CodecIdList mCodecIdFilterList;
|
||||
unsigned short mMediaRelayPortRangeMin;
|
||||
unsigned short mMediaRelayPortRangeMax;
|
||||
typedef std::list<std::pair<resip::Data,resip::Data> > TranslationList;
|
||||
TranslationList mAddressTranslations;
|
||||
|
||||
// Jabber specific settings
|
||||
resip::Data mJabberServer;
|
||||
resip::Data mJabberComponentName;
|
||||
resip::Data mJabberComponentPassword;
|
||||
unsigned short mJabberComponentPort;
|
||||
unsigned int mJabberServerPingDuration;
|
||||
resip::Data mJabberControlUsername;
|
||||
|
||||
// TLS specific settings
|
||||
resip::Data mTLSDHParamsFilename;
|
||||
resip::Data mTLSCertificate;
|
||||
resip::Data mTLSPrivateKey;
|
||||
resip::Data mTLSPrivateKeyPassPhrase;
|
||||
|
||||
// iChat Jabber Connector file path
|
||||
resip::Data mIchatJabberConnectorPath;
|
||||
|
||||
private:
|
||||
void parseCommandLine(int argc, char** argv);
|
||||
void parseConfigFile(const resip::Data& filename);
|
||||
bool processOption(const resip::Data& name, const resip::Data& value);
|
||||
bool assignNameAddr(const resip::Data& settingName, const resip::Data& settingValue, resip::NameAddr& nameAddr);
|
||||
bool assignOnOffSetting(const resip::Data& value, bool& setting);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
182
src/libs/resiprocate/apps/ichat-gw/IChatGatewayCmds.hxx
Normal file
182
src/libs/resiprocate/apps/ichat-gw/IChatGatewayCmds.hxx
Normal file
@@ -0,0 +1,182 @@
|
||||
#if !defined(IChatGatewayCmds_hxx)
|
||||
#define IChatGatewayCmds_hxx
|
||||
|
||||
#include <resip/dum/DumCommand.hxx>
|
||||
|
||||
#include "Server.hxx"
|
||||
#include "B2BSession.hxx"
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::GATEWAY
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
/**
|
||||
The classes defined here are used to pass commands from the
|
||||
application thread to the DUM thread (process loop).
|
||||
This ensures thread safety of the external Server methods.
|
||||
|
||||
Author: Scott Godin (sgodin AT SipSpectrum DOT com)
|
||||
*/
|
||||
|
||||
class NotifyIChatCallRequestCmd : public resip::DumCommand
|
||||
{
|
||||
public:
|
||||
NotifyIChatCallRequestCmd(Server& server, const std::string& to, const std::string& from)
|
||||
: mServer(server), mTo(to), mFrom(from) {}
|
||||
virtual void executeCommand()
|
||||
{
|
||||
mServer.notifyIChatCallRequestImpl(mTo, mFrom);
|
||||
}
|
||||
resip::Message* clone() const { resip_assert(0); return 0; }
|
||||
EncodeStream& encode(EncodeStream& strm) const { strm << " NotifyIChatCallRequestCmd: "; return strm; }
|
||||
EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); }
|
||||
private:
|
||||
Server& mServer;
|
||||
std::string mTo;
|
||||
std::string mFrom;
|
||||
};
|
||||
|
||||
class NotifyIChatCallCancelledCmd : public resip::DumCommand
|
||||
{
|
||||
public:
|
||||
NotifyIChatCallCancelledCmd(Server& server, const B2BSessionHandle& handle)
|
||||
: mServer(server), mHandle(handle) {}
|
||||
virtual void executeCommand()
|
||||
{
|
||||
mServer.notifyIChatCallCancelledImpl(mHandle);
|
||||
}
|
||||
resip::Message* clone() const { resip_assert(0); return 0; }
|
||||
EncodeStream& encode(EncodeStream& strm) const { strm << " NotifyIChatCallCancelledCmd: "; return strm; }
|
||||
EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); }
|
||||
private:
|
||||
Server& mServer;
|
||||
B2BSessionHandle mHandle;
|
||||
};
|
||||
|
||||
class NotifyIChatCallProceedingCmd : public resip::DumCommand
|
||||
{
|
||||
public:
|
||||
NotifyIChatCallProceedingCmd(Server& server, const B2BSessionHandle& handle, const std::string& to)
|
||||
: mServer(server), mHandle(handle), mTo(to) {}
|
||||
virtual void executeCommand()
|
||||
{
|
||||
mServer.notifyIChatCallProceedingImpl(mHandle, mTo);
|
||||
}
|
||||
resip::Message* clone() const { resip_assert(0); return 0; }
|
||||
EncodeStream& encode(EncodeStream& strm) const { strm << " NotifyIChatCallProceedingCmd: "; return strm; }
|
||||
EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); }
|
||||
private:
|
||||
Server& mServer;
|
||||
B2BSessionHandle mHandle;
|
||||
std::string mTo;
|
||||
};
|
||||
|
||||
class NotifyIChatCallFailedCmd : public resip::DumCommand
|
||||
{
|
||||
public:
|
||||
NotifyIChatCallFailedCmd(Server& server, const B2BSessionHandle& handle, unsigned int statusCode)
|
||||
: mServer(server), mHandle(handle), mStatusCode(statusCode) {}
|
||||
virtual void executeCommand()
|
||||
{
|
||||
mServer.notifyIChatCallFailedImpl(mHandle, mStatusCode);
|
||||
}
|
||||
resip::Message* clone() const { resip_assert(0); return 0; }
|
||||
EncodeStream& encode(EncodeStream& strm) const { strm << " NotifyIChatCallFailedCmd: "; return strm; }
|
||||
EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); }
|
||||
private:
|
||||
Server& mServer;
|
||||
B2BSessionHandle mHandle;
|
||||
unsigned int mStatusCode;
|
||||
};
|
||||
|
||||
class ContinueIChatCallCmd : public resip::DumCommand
|
||||
{
|
||||
public:
|
||||
ContinueIChatCallCmd(Server& server, const B2BSessionHandle& handle, const std::string& remoteIPPortListBlob)
|
||||
: mServer(server), mHandle(handle), mRemoteIPPortListBlob(remoteIPPortListBlob) {}
|
||||
virtual void executeCommand()
|
||||
{
|
||||
mServer.continueIChatCallImpl(mHandle, mRemoteIPPortListBlob);
|
||||
}
|
||||
resip::Message* clone() const { resip_assert(0); return 0; }
|
||||
EncodeStream& encode(EncodeStream& strm) const { strm << " ContinueIChatCallCmd: "; return strm; }
|
||||
EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); }
|
||||
private:
|
||||
Server& mServer;
|
||||
B2BSessionHandle mHandle;
|
||||
std::string mRemoteIPPortListBlob;
|
||||
};
|
||||
|
||||
class SipRegisterJabberUserCmd : public resip::DumCommand
|
||||
{
|
||||
public:
|
||||
SipRegisterJabberUserCmd(Server& server, const std::string& jidToRegister)
|
||||
: mServer(server), mJidToRegister(jidToRegister) {}
|
||||
virtual void executeCommand()
|
||||
{
|
||||
mServer.sipRegisterJabberUserImpl(mJidToRegister);
|
||||
}
|
||||
resip::Message* clone() const { resip_assert(0); return 0; }
|
||||
EncodeStream& encode(EncodeStream& strm) const { strm << " SipRegisterJabberUserCmd: "; return strm; }
|
||||
EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); }
|
||||
private:
|
||||
Server& mServer;
|
||||
std::string mJidToRegister;
|
||||
};
|
||||
|
||||
class SipUnregisterJabberUserCmd : public resip::DumCommand
|
||||
{
|
||||
public:
|
||||
SipUnregisterJabberUserCmd(Server& server, const std::string& jidToUnregister)
|
||||
: mServer(server), mJidToUnregister(jidToUnregister) {}
|
||||
virtual void executeCommand()
|
||||
{
|
||||
mServer.sipUnregisterJabberUserImpl(mJidToUnregister);
|
||||
}
|
||||
resip::Message* clone() const { resip_assert(0); return 0; }
|
||||
EncodeStream& encode(EncodeStream& strm) const { strm << " SipUnregisterJabberUserCmd: "; return strm; }
|
||||
EncodeStream& encodeBrief(EncodeStream& strm) const { return encode(strm); }
|
||||
private:
|
||||
Server& mServer;
|
||||
std::string mJidToUnregister;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
169
src/libs/resiprocate/apps/ichat-gw/IChatIPPortData.cxx
Normal file
169
src/libs/resiprocate/apps/ichat-gw/IChatIPPortData.cxx
Normal file
@@ -0,0 +1,169 @@
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <resip/stack/Helper.hxx>
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "IChatIPPortData.hxx"
|
||||
#include <rutil/WinLeakCheck.hxx>
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::GATEWAY
|
||||
|
||||
using namespace gateway;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short initialPad;
|
||||
unsigned short family;
|
||||
char interfaceName[16];
|
||||
char ipAddress[16];
|
||||
unsigned short port;
|
||||
unsigned short finalPad;
|
||||
} IPPortDataBlob;
|
||||
|
||||
IChatIPPortData::IChatIPPortData()
|
||||
{
|
||||
}
|
||||
|
||||
IChatIPPortData::IChatIPPortData(const std::string& hexblob) : mHexBlob(hexblob)
|
||||
{
|
||||
unsigned int pad = 0;
|
||||
// Note: gloox passes us an initial line feed, so be tollerant of this
|
||||
if(hexblob.at(0) == 0xa)
|
||||
{
|
||||
pad = 1;
|
||||
}
|
||||
|
||||
// Convert hexblob to binary blob
|
||||
if(((hexblob.size()-pad) % 40) != 0)
|
||||
{
|
||||
ErrLog(<< "Data size provided for IChatIPPortData is not correct, size=" << hexblob.size());
|
||||
return;
|
||||
}
|
||||
Data blob((unsigned int)hexblob.size()-1 / 2, Data::Preallocate);
|
||||
for(unsigned int i = pad; i < hexblob.size(); i=i+8)
|
||||
{
|
||||
unsigned int block = ntohl(Helper::hex2integer(&hexblob.at(i)));
|
||||
blob.append((const char*)&block, 4);
|
||||
}
|
||||
|
||||
for(unsigned int j = 0; j < blob.size(); j=j+40)
|
||||
{
|
||||
IPPortDataBlob* ipPortDataBlob = (IPPortDataBlob*)(blob.data()+j);
|
||||
|
||||
if(ipPortDataBlob->family == V4)
|
||||
{
|
||||
in_addr addr;
|
||||
memcpy(&addr, ipPortDataBlob->ipAddress, 4);
|
||||
addIPPortData(Data(ipPortDataBlob->interfaceName), Tuple(addr,ntohs(ipPortDataBlob->port),UDP));
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef USE_IPV6
|
||||
in6_addr addr;
|
||||
memcpy(&addr, ipPortDataBlob->ipAddress, 16);
|
||||
addIPPortData(Data(ipPortDataBlob->interfaceName), Tuple(addr,ntohs(ipPortDataBlob->port),UDP));
|
||||
#else
|
||||
ErrLog(<< "IPv6 support not enabled at compile time.");
|
||||
resip_assert(0);
|
||||
#endif
|
||||
}
|
||||
InfoLog(<< "IChatIPPortData: name=" << mIPPortDataList.back().first << " addr=" << mIPPortDataList.back().second);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IChatIPPortData::addIPPortData(const Data& name, const Tuple& ipPortData)
|
||||
{
|
||||
mIPPortDataList.push_back(std::make_pair(name, ipPortData));
|
||||
mHexBlob.clear(); // clear any existing blob string - it will now need to be re-generated if requested
|
||||
}
|
||||
|
||||
std::string&
|
||||
IChatIPPortData::hexBlob()
|
||||
{
|
||||
if(mHexBlob.empty())
|
||||
{
|
||||
Data dataBlob((int)mIPPortDataList.size() * sizeof(IPPortDataBlob), Data::Preallocate);
|
||||
IPPortDataList::const_iterator it;
|
||||
for(it = mIPPortDataList.begin(); it != mIPPortDataList.end(); it++)
|
||||
{
|
||||
IPPortDataBlob ipPortDataBlob;
|
||||
memset(&ipPortDataBlob, 0, sizeof(ipPortDataBlob));
|
||||
memcpy(ipPortDataBlob.interfaceName, it->first.data(), it->first.size() < 16 ? it->first.size() : 16);
|
||||
ipPortDataBlob.port = htons(it->second.getPort());
|
||||
if(it->second.ipVersion() == V4)
|
||||
{
|
||||
ipPortDataBlob.family = V4;
|
||||
memcpy(ipPortDataBlob.ipAddress, &reinterpret_cast<const sockaddr_in&>(it->second.getSockaddr()).sin_addr, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
ipPortDataBlob.family = V6;
|
||||
memcpy(ipPortDataBlob.ipAddress, &reinterpret_cast<const sockaddr_in6&>(it->second.getSockaddr()).sin6_addr, 16);
|
||||
}
|
||||
dataBlob.append((const char*)&ipPortDataBlob, sizeof(ipPortDataBlob));
|
||||
}
|
||||
|
||||
// Hexify
|
||||
for(unsigned int i = 0; i < dataBlob.size(); i=i+4)
|
||||
{
|
||||
unsigned int block;
|
||||
memcpy(&block, dataBlob.data()+i, 4);
|
||||
char hexBlock[8];
|
||||
Helper::integer2hex(hexBlock, htonl(block));
|
||||
mHexBlob.append(hexBlock, 8);
|
||||
}
|
||||
}
|
||||
return mHexBlob;
|
||||
}
|
||||
|
||||
const IChatIPPortData::IPPortDataList&
|
||||
IChatIPPortData::getIPPortDataList() const
|
||||
{
|
||||
return mIPPortDataList;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
66
src/libs/resiprocate/apps/ichat-gw/IChatIPPortData.hxx
Normal file
66
src/libs/resiprocate/apps/ichat-gw/IChatIPPortData.hxx
Normal file
@@ -0,0 +1,66 @@
|
||||
#if !defined(IChatIPPortData_hxx)
|
||||
#define IChatIPPortData_hxx
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include "rutil/Data.hxx"
|
||||
#include "resip/stack/Tuple.hxx"
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class IChatIPPortData
|
||||
{
|
||||
public:
|
||||
typedef std::list<std::pair<resip::Data,resip::Tuple> > IPPortDataList;
|
||||
|
||||
IChatIPPortData();
|
||||
IChatIPPortData(const std::string& hexblob);
|
||||
|
||||
void addIPPortData(const resip::Data& name, const resip::Tuple& ipPortData);
|
||||
std::string& hexBlob();
|
||||
const IPPortDataList& getIPPortDataList() const;
|
||||
|
||||
private:
|
||||
IPPortDataList mIPPortDataList;
|
||||
std::string mHexBlob;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
281
src/libs/resiprocate/apps/ichat-gw/IPCThread.cxx
Normal file
281
src/libs/resiprocate/apps/ichat-gw/IPCThread.cxx
Normal file
@@ -0,0 +1,281 @@
|
||||
#include "rutil/ResipAssert.h"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <WS2tcpip.h>
|
||||
#else
|
||||
#include <sys/fcntl.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "IPCThread.hxx"
|
||||
|
||||
using namespace gateway;
|
||||
using namespace std;
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#define EADDRINUSE WSAEADDRINUSE
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#define sleepMs(t) Sleep(t)
|
||||
#else
|
||||
#define sleepMs(t) usleep(t*1000)
|
||||
#endif
|
||||
|
||||
|
||||
IPCThread::IPCThread(unsigned short localPort, unsigned short remotePort, IPCHandler* handler, IPCMutex* mutex) :
|
||||
mLocalPort(localPort),
|
||||
mRemotePort(remotePort),
|
||||
mHandler(handler),
|
||||
mMutex(mutex)
|
||||
{
|
||||
resip_assert(handler!=0);
|
||||
mSocket = createIPCSocket("127.0.0.1",mLocalPort);
|
||||
if(mSocket == INVALID_SOCKET)
|
||||
{
|
||||
cerr << "IPCThread::IPCThread - could not create IPC udp socket on port=" << mLocalPort << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set RemoteSockaddr to be same as local but with remote port
|
||||
memcpy(&mRemoteSockaddr, &mLocalSockaddr, sizeof(mRemoteSockaddr));
|
||||
sockaddr_in* anonv4 = (sockaddr_in*)&mRemoteSockaddr;
|
||||
anonv4->sin_port = htons(remotePort);
|
||||
|
||||
cout << "IPCThread::IPCThread: local port=" << mLocalPort << ", remote port=" << remotePort << endl;
|
||||
}
|
||||
}
|
||||
|
||||
IPCThread::~IPCThread()
|
||||
{
|
||||
#if defined(WIN32)
|
||||
closesocket(mSocket);
|
||||
#else
|
||||
close(mSocket);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
IPCThread::sendIPCMsg(IPCMsg& msg)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
msg.encode(oss);
|
||||
mMutex->lock();
|
||||
mDataToSend.push(oss.str());
|
||||
mMutex->unlock();
|
||||
}
|
||||
|
||||
Socket
|
||||
IPCThread::createIPCSocket(const std::string& printableAddr, unsigned int port)
|
||||
{
|
||||
Socket fd;
|
||||
sockaddr_in* anonv4 = (sockaddr_in*)&mLocalSockaddr;
|
||||
|
||||
fd = ::socket(PF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
if ( fd == INVALID_SOCKET )
|
||||
{
|
||||
int e = getErrno();
|
||||
cerr << "IPCThread::createIPCSocket - Failed to create socket: error=" << e << endl;
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
memset(anonv4, 0, sizeof(anonv4));
|
||||
anonv4->sin_family = AF_INET;
|
||||
anonv4->sin_port = htons(port);
|
||||
if (printableAddr.empty())
|
||||
{
|
||||
anonv4->sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
}
|
||||
else
|
||||
{
|
||||
anonv4->sin_addr.s_addr = inet_addr(printableAddr.c_str());
|
||||
}
|
||||
|
||||
//cout << "IPCThread::createIPCSocket - Creating fd=" << (int)fd
|
||||
// << ", Binding to " << printableAddr << ":" << port << endl;
|
||||
|
||||
if ( ::bind( fd, &mLocalSockaddr, sizeof(mLocalSockaddr)) == SOCKET_ERROR )
|
||||
{
|
||||
int e = getErrno();
|
||||
if ( e == EADDRINUSE )
|
||||
{
|
||||
cerr << "IPCThread::createIPCSocket - " << printableAddr << ":" << port << " already in use" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "IPCThread::createIPCSocket - Could not bind to " << printableAddr << ":" << port << ", error=" << e << endl;
|
||||
}
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
if(port == 0)
|
||||
{
|
||||
// If we used port 0, then query what port the OS allocated for us
|
||||
socklen_t len = sizeof(mLocalSockaddr);
|
||||
if(::getsockname(fd, &mLocalSockaddr, &len) == SOCKET_ERROR)
|
||||
{
|
||||
int e = getErrno();
|
||||
cerr <<"IPCThread::createIPCSocket - getsockname failed, error=" << e << endl;
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
unsigned long noBlock = 1;
|
||||
int errNoBlock = ioctlsocket( fd, FIONBIO , &noBlock );
|
||||
if ( errNoBlock != 0 )
|
||||
{
|
||||
cerr << "IPCThread::createIPCSocket - Could not make socket non-blocking" << endl;
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
#else
|
||||
int flags = fcntl( fd, F_GETFL, 0);
|
||||
int errNoBlock = fcntl(fd, F_SETFL, flags | O_NONBLOCK );
|
||||
if ( errNoBlock != 0 )
|
||||
{
|
||||
cerr << "IPCThread::createIPCSocket - Could not make socket non-blocking" << endl;
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
#endif
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
void
|
||||
IPCThread::thread()
|
||||
{
|
||||
fd_set read;
|
||||
fd_set write;
|
||||
fd_set except;
|
||||
struct timeval tv;
|
||||
|
||||
if(mSocket == INVALID_SOCKET) return;
|
||||
|
||||
while (!isShutdown())
|
||||
{
|
||||
tv.tv_sec = 1; // Note: calling select on linux based systems can cause the contents of the passed in timeval struct to be modified, so we need to reset the time on each loop iteration
|
||||
tv.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&read);
|
||||
FD_ZERO(&write);
|
||||
FD_ZERO(&except);
|
||||
|
||||
FD_SET(mSocket, &read);
|
||||
FD_SET(mSocket, &except);
|
||||
|
||||
if(!mDataToSend.empty())
|
||||
{
|
||||
FD_SET(mSocket, &write);
|
||||
}
|
||||
|
||||
int ret = ::select(mSocket+1, &read, &write, &except, &tv);
|
||||
if (ret > 0)
|
||||
{
|
||||
process(read, write);
|
||||
}
|
||||
}
|
||||
cout << "IPCThread::thread - IPCThread shutdown." << endl;
|
||||
}
|
||||
|
||||
void
|
||||
IPCThread::process(fd_set& read_fdset, fd_set& write_fdset)
|
||||
{
|
||||
// If data to send and write has signalled
|
||||
if(!mDataToSend.empty() && (FD_ISSET(mSocket, &write_fdset) != 0))
|
||||
{
|
||||
int count;
|
||||
mMutex->lock();
|
||||
std::string& dataToSend = mDataToSend.front();
|
||||
count = sendto(mSocket,
|
||||
dataToSend.data(),
|
||||
dataToSend.size(),
|
||||
0, // flags
|
||||
&mRemoteSockaddr, sizeof(mRemoteSockaddr));
|
||||
mDataToSend.pop();
|
||||
mMutex->unlock();
|
||||
if ( count == SOCKET_ERROR )
|
||||
{
|
||||
int e = getErrno();
|
||||
cerr << "IPCThread::process - Failed (" << e << ") sending." << endl;
|
||||
}
|
||||
}
|
||||
if((FD_ISSET(mSocket, &read_fdset) != 0))
|
||||
{
|
||||
sockaddr readAddr;
|
||||
bool success = true;
|
||||
|
||||
socklen_t slen = sizeof(readAddr);
|
||||
int len = recvfrom(mSocket,
|
||||
mReadBuffer,
|
||||
UDP_IPC_BUFFER_SIZE,
|
||||
0 /*flags */,
|
||||
&readAddr,
|
||||
&slen);
|
||||
if ( len == SOCKET_ERROR )
|
||||
{
|
||||
int err = getErrno();
|
||||
if ( err != EWOULDBLOCK )
|
||||
{
|
||||
cerr << "IPCThread::process - Error calling recvfrom: " << err << endl;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (len == 0 || len == SOCKET_ERROR)
|
||||
{
|
||||
cerr << "IPCThread::process - No data calling recvfrom: len=" << len << endl;
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (len+1 >= UDP_IPC_BUFFER_SIZE)
|
||||
{
|
||||
cerr << "IPCThread::process - Datagram exceeded max length "<<UDP_IPC_BUFFER_SIZE << endl;
|
||||
success = false;
|
||||
}
|
||||
|
||||
if(success)
|
||||
{
|
||||
//cout << "IPCThread::process - Received a datagram of size=" << len << endl;
|
||||
IPCMsg msg(std::string(mReadBuffer, len));
|
||||
mHandler->onNewIPCMsg(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
156
src/libs/resiprocate/apps/ichat-gw/IPCThread.hxx
Normal file
156
src/libs/resiprocate/apps/ichat-gw/IPCThread.hxx
Normal file
@@ -0,0 +1,156 @@
|
||||
#if !defined(IPCThread_hxx)
|
||||
#define IPCThread_hxx
|
||||
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef WIN32
|
||||
# include <sys/socket.h>
|
||||
# include <sys/select.h>
|
||||
# include <netinet/in.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "Thread.hxx"
|
||||
|
||||
#define UDP_IPC_BUFFER_SIZE 4192
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
#ifndef WIN32
|
||||
typedef int Socket;
|
||||
#define INVALID_SOCKET (-1)
|
||||
#define SOCKET_ERROR (-1)
|
||||
inline int getErrno() { return errno; }
|
||||
#else
|
||||
typedef SOCKET Socket;
|
||||
inline int getErrno() { return WSAGetLastError(); }
|
||||
#endif
|
||||
|
||||
class IPCMutex
|
||||
{
|
||||
public:
|
||||
IPCMutex() {}
|
||||
virtual ~IPCMutex() {}
|
||||
virtual void lock() = 0;
|
||||
virtual void unlock() = 0;
|
||||
};
|
||||
|
||||
class IPCMsg
|
||||
{
|
||||
public:
|
||||
IPCMsg() {};
|
||||
IPCMsg(const std::string& msg)
|
||||
{
|
||||
unsigned int start = 0;
|
||||
for(unsigned int i = 0; i < msg.size(); i++)
|
||||
{
|
||||
if(msg.at(i) == '\r')
|
||||
{
|
||||
mArgs.push_back(msg.substr(start,i-start));
|
||||
start = i+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
void addArg(const std::string& arg) { mArgs.push_back(arg); }
|
||||
void addArg(unsigned int arg)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << arg;
|
||||
mArgs.push_back(oss.str());
|
||||
}
|
||||
std::ostream& encode(std::ostream& strm) const
|
||||
{
|
||||
std::vector<std::string>::const_iterator it = mArgs.begin();
|
||||
for(;it != mArgs.end();it++)
|
||||
{
|
||||
strm << *it << "\r"; // Note: using /r since there is a /n character at the start of the iChat call blob
|
||||
}
|
||||
strm.flush();
|
||||
return strm;
|
||||
}
|
||||
const std::vector<std::string>& getArgs() const { return mArgs; }
|
||||
private:
|
||||
std::vector<std::string> mArgs;
|
||||
};
|
||||
|
||||
class IPCHandler
|
||||
{
|
||||
public:
|
||||
virtual ~IPCHandler() {}
|
||||
virtual void onNewIPCMsg(const IPCMsg& msg) = 0;
|
||||
};
|
||||
|
||||
class IPCThread : public Thread
|
||||
{
|
||||
public:
|
||||
IPCThread(unsigned short localPort, unsigned short remotePort, IPCHandler* handler, IPCMutex* mutex);
|
||||
virtual ~IPCThread();
|
||||
|
||||
void sendIPCMsg(IPCMsg& msg);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
virtual void thread();
|
||||
|
||||
void process(fd_set& read_fdset, fd_set& write_fdset);
|
||||
|
||||
Socket createIPCSocket(const std::string& printableAddr, unsigned int port);
|
||||
char mReadBuffer[UDP_IPC_BUFFER_SIZE+1];
|
||||
|
||||
sockaddr mLocalSockaddr;
|
||||
sockaddr mRemoteSockaddr;
|
||||
Socket mSocket;
|
||||
unsigned short mLocalPort;
|
||||
unsigned short mRemotePort;
|
||||
//resip::Mutex mIPCMutex;
|
||||
std::queue<std::string> mDataToSend;
|
||||
|
||||
IPCHandler* mHandler;
|
||||
IPCMutex* mMutex;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
99
src/libs/resiprocate/apps/ichat-gw/Makefile.am
Normal file
99
src/libs/resiprocate/apps/ichat-gw/Makefile.am
Normal file
@@ -0,0 +1,99 @@
|
||||
# $Id$
|
||||
|
||||
EXTRA_DIST = ichat-gw.config
|
||||
EXTRA_DIST += doc
|
||||
EXTRA_DIST += *.sln
|
||||
EXTRA_DIST += *.vcproj
|
||||
|
||||
SUBDIRS = .
|
||||
# this has more external dependencies, it has been adapted
|
||||
# for autotools and can be enabled manually if the deps
|
||||
# are available
|
||||
SUBDIRS += jabberconnector
|
||||
|
||||
#AM_CXXFLAGS = -DUSE_ARES
|
||||
|
||||
sbin_PROGRAMS = ichat-gw
|
||||
ichat_gw_LDADD = ../../resip/dum/libdum.la
|
||||
ichat_gw_LDADD += ../../resip/stack/libresip.la ../../rutil/librutil.la
|
||||
ichat_gw_LDADD += @LIBSSL_LIBADD@ -lpcre @LIBPTHREAD_LIBADD@
|
||||
|
||||
ichat_gw_SOURCES = \
|
||||
AddressTranslator.cxx \
|
||||
AppSubsystem.cxx \
|
||||
B2BSession.cxx \
|
||||
ConfigParser.cxx \
|
||||
ichat-gw.cxx \
|
||||
IChatIPPortData.cxx \
|
||||
IPCThread.cxx \
|
||||
MediaRelay.cxx \
|
||||
MediaRelayPort.cxx \
|
||||
Server.cxx \
|
||||
SipRegistration.cxx \
|
||||
Thread.cxx
|
||||
|
||||
ichat_gwincludedir = $(includedir)/ichat-gw
|
||||
nobase_ichat_gwinclude_HEADERS = AddressTranslator.hxx \
|
||||
AppSubsystem.hxx \
|
||||
B2BSession.hxx \
|
||||
ConfigParser.hxx \
|
||||
IChatGatewayCmds.hxx \
|
||||
IChatIPPortData.hxx \
|
||||
IPCThread.hxx \
|
||||
MediaRelay.hxx \
|
||||
MediaRelayPort.hxx \
|
||||
Server.hxx \
|
||||
SipRegistration.hxx \
|
||||
Thread.hxx \
|
||||
Version.hxx
|
||||
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# The Vovida Software License, Version 1.0
|
||||
# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
#
|
||||
# 3. The names "VOCAL", "Vovida Open Communication Application Library",
|
||||
# and "Vovida Open Communication Application Library (VOCAL)" must
|
||||
# not be used to endorse or promote products derived from this
|
||||
# software without prior written permission. For written
|
||||
# permission, please contact vocal@vovida.org.
|
||||
#
|
||||
# 4. Products derived from this software may not be called "VOCAL", nor
|
||||
# may "VOCAL" appear in their name, without prior written
|
||||
# permission of Vovida Networks, Inc.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
|
||||
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
|
||||
# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
|
||||
# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
|
||||
# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
# DAMAGE.
|
||||
#
|
||||
# ====================================================================
|
||||
#
|
||||
# This software consists of voluntary contributions made by Vovida
|
||||
# Networks, Inc. and many individuals on behalf of Vovida Networks,
|
||||
# Inc. For more information on Vovida Networks, Inc., please see
|
||||
# <http://www.vovida.org/>.
|
||||
#
|
||||
##############################################################################
|
||||
651
src/libs/resiprocate/apps/ichat-gw/MediaRelay.cxx
Normal file
651
src/libs/resiprocate/apps/ichat-gw/MediaRelay.cxx
Normal file
@@ -0,0 +1,651 @@
|
||||
#include "rutil/ResipAssert.h"
|
||||
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <rutil/Timer.hxx>
|
||||
#include <resip/stack/Symbols.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
#include <rutil/Random.hxx>
|
||||
#include <rutil/DnsUtil.hxx>
|
||||
#include <rutil/ParseBuffer.hxx>
|
||||
#include <resip/stack/Transport.hxx>
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "MediaRelay.hxx"
|
||||
#include <rutil/WinLeakCheck.hxx>
|
||||
|
||||
using namespace gateway;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::GATEWAY
|
||||
|
||||
#ifdef WIN32
|
||||
#define sleepMs(t) Sleep(t)
|
||||
#else
|
||||
#define sleepMs(t) usleep(t*1000)
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short versionExtPayloadTypeAndMarker;
|
||||
unsigned short sequenceNumber;
|
||||
unsigned int timestamp;
|
||||
unsigned int ssrc;
|
||||
} RtpHeader;
|
||||
|
||||
|
||||
MediaRelay::MediaRelay(bool isV6Avail, unsigned short portRangeMin, unsigned short portRangeMax) :
|
||||
mIsV6Avail(isV6Avail)
|
||||
{
|
||||
if(portRangeMax < portRangeMin) portRangeMax = portRangeMin; // saftey check
|
||||
for(unsigned int i = portRangeMin; i <= portRangeMax; i++)
|
||||
{
|
||||
mFreeRelayPortList.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
MediaRelay::~MediaRelay()
|
||||
{
|
||||
Lock lock(mRelaysMutex);
|
||||
RelayPortList::iterator it = mRelays.begin();
|
||||
for(;it != mRelays.end(); it++)
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
|
||||
#define NUM_CREATE_TRIES 10 // Number of times to try to allocate a port, since port may be in use by another application
|
||||
bool
|
||||
MediaRelay::createRelay(unsigned short& port)
|
||||
{
|
||||
for(unsigned int i = 0; i < NUM_CREATE_TRIES; i++)
|
||||
{
|
||||
if(createRelayImpl(port)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
MediaRelay::createRelayImpl(unsigned short& port)
|
||||
{
|
||||
Lock lock(mRelaysMutex);
|
||||
|
||||
if(mFreeRelayPortList.empty()) return false;
|
||||
|
||||
unsigned short trialPort = mFreeRelayPortList.front();
|
||||
mFreeRelayPortList.pop_front();
|
||||
|
||||
Tuple v4tuple(Data::Empty,trialPort,V4,UDP,Data::Empty);
|
||||
resip::Socket v4fd = createRelaySocket(v4tuple);
|
||||
|
||||
if(v4fd == INVALID_SOCKET)
|
||||
{
|
||||
mFreeRelayPortList.push_back(trialPort);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(mIsV6Avail)
|
||||
{
|
||||
Tuple v6tuple(Data::Empty,trialPort,V6,UDP,Data::Empty);
|
||||
resip::Socket v6fd = createRelaySocket(v6tuple);
|
||||
|
||||
if(v6fd != INVALID_SOCKET)
|
||||
{
|
||||
port = trialPort;
|
||||
|
||||
mRelays[port] = new MediaRelayPort(v4fd, v4tuple, v6fd, v6tuple);
|
||||
InfoLog(<< "MediaRelay::createRelayImpl - Media relay started for port " << port);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
closesocket(v4fd);
|
||||
#else
|
||||
close(v4fd);
|
||||
#endif
|
||||
|
||||
mFreeRelayPortList.push_back(trialPort);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Only V4 is available
|
||||
port = trialPort;
|
||||
|
||||
mRelays[port] = new MediaRelayPort(v4fd, v4tuple);
|
||||
InfoLog(<< "MediaRelay::createRelayImpl - Media relay started for port " << port);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaRelay::destroyRelay(unsigned short port)
|
||||
{
|
||||
Lock lock(mRelaysMutex);
|
||||
RelayPortList::iterator it = mRelays.find(port);
|
||||
if(it != mRelays.end())
|
||||
{
|
||||
InfoLog(<< "MediaRelay::destroyRelay - port=" << port);
|
||||
delete it->second;
|
||||
mRelays.erase(it);
|
||||
mFreeRelayPortList.push_back(port);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaRelay::primeNextEndpoint(unsigned short& port, resip::Tuple& destinationIPPort)
|
||||
{
|
||||
Lock lock(mRelaysMutex);
|
||||
RelayPortList::iterator it = mRelays.find(port);
|
||||
if(it != mRelays.end())
|
||||
{
|
||||
if(it->second->mFirstEndpoint.mTuple.getPort() == 0)
|
||||
{
|
||||
InfoLog(<< "MediaRelay::primeNextEndpoint - sender=first, port=" << port << ", addr=" << destinationIPPort);
|
||||
it->second->mFirstEndpoint.mTuple = destinationIPPort;
|
||||
}
|
||||
else
|
||||
{
|
||||
InfoLog(<< "MediaRelay::primeNextEndpoint - sender=second, port=" << port << ", addr=" << destinationIPPort);
|
||||
it->second->mSecondEndpoint.mTuple = destinationIPPort;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resip::Socket
|
||||
MediaRelay::createRelaySocket(resip::Tuple& tuple)
|
||||
{
|
||||
resip::Socket fd;
|
||||
|
||||
#ifdef USE_IPV6
|
||||
fd = ::socket(tuple.ipVersion() == V4 ? PF_INET : PF_INET6, SOCK_DGRAM, 0);
|
||||
#else
|
||||
fd = ::socket(PF_INET, SOCK_DGRAM, 0);
|
||||
#endif
|
||||
|
||||
if ( fd == INVALID_SOCKET )
|
||||
{
|
||||
int e = getErrno();
|
||||
ErrLog (<< "MediaRelay::createRelaySocket - Failed to create socket: " << strerror(e));
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
DebugLog (<< "MediaRelay::createRelaySocket - Creating fd=" << (int)fd
|
||||
<< (tuple.ipVersion() == V4 ? " V4" : " V6")
|
||||
<< ", Binding to " << Tuple::inet_ntop(tuple));
|
||||
|
||||
if ( ::bind( fd, &tuple.getSockaddr(), tuple.length()) == SOCKET_ERROR )
|
||||
{
|
||||
int e = getErrno();
|
||||
if ( e == EADDRINUSE )
|
||||
{
|
||||
ErrLog (<< "MediaRelay::createRelaySocket - " << tuple << " already in use ");
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrLog (<< "MediaRelay::createRelaySocket - Could not bind to " << tuple << ", error=" << e);
|
||||
}
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
if(tuple.getPort() == 0)
|
||||
{
|
||||
// If we used port 0, then query what port the OS allocated for us
|
||||
socklen_t len = tuple.length();
|
||||
if(::getsockname(fd, &tuple.getMutableSockaddr(), &len) == SOCKET_ERROR)
|
||||
{
|
||||
int e = getErrno();
|
||||
ErrLog (<<"MediaRelay::createRelaySocket - getsockname failed, error=" << e);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
bool ok = makeSocketNonBlocking(fd);
|
||||
if ( !ok )
|
||||
{
|
||||
ErrLog (<< "MediaRelay::createRelaySocket - Could not make socket non-blocking");
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
void
|
||||
MediaRelay::thread()
|
||||
{
|
||||
while (!isShutdown())
|
||||
{
|
||||
try
|
||||
{
|
||||
if(mRelays.size() == 0)
|
||||
{
|
||||
// No relays yet - just wait
|
||||
sleepMs(50);
|
||||
}
|
||||
else
|
||||
{
|
||||
resip::FdSet fdset;
|
||||
buildFdSet(fdset);
|
||||
int ret = fdset.selectMilliSeconds(50);
|
||||
if (ret > 0)
|
||||
{
|
||||
process(fdset);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (BaseException& e)
|
||||
{
|
||||
ErrLog (<< "MediaRelay::thread - Unhandled exception: " << e);
|
||||
}
|
||||
}
|
||||
WarningLog (<< "MediaRelay::thread - shutdown");
|
||||
}
|
||||
|
||||
void
|
||||
MediaRelay::buildFdSet(FdSet& fdset)
|
||||
{
|
||||
Lock lock(mRelaysMutex);
|
||||
|
||||
RelayPortList::iterator it = mRelays.begin();
|
||||
for(;it != mRelays.end(); it++)
|
||||
{
|
||||
// Add read fd's
|
||||
fdset.setRead(it->second->mV4Fd);
|
||||
if(mIsV6Avail) fdset.setRead(it->second->mV6Fd);
|
||||
fdset.setExcept(it->second->mV4Fd);
|
||||
if(mIsV6Avail) fdset.setExcept(it->second->mV6Fd);
|
||||
|
||||
checkKeepalives(it->second);
|
||||
|
||||
// Add write fd's if there is data to write
|
||||
if((it->second->mFirstEndpoint.mRelayDatagram.get() != 0 && it->second->mFirstEndpoint.mTuple.ipVersion() == V4) ||
|
||||
(it->second->mSecondEndpoint.mRelayDatagram.get() != 0 && it->second->mSecondEndpoint.mTuple.ipVersion() == V4))
|
||||
{
|
||||
fdset.setWrite(it->second->mV4Fd);
|
||||
}
|
||||
if(mIsV6Avail &&
|
||||
((it->second->mFirstEndpoint.mRelayDatagram.get() != 0 && it->second->mFirstEndpoint.mTuple.ipVersion() == V6) ||
|
||||
(it->second->mSecondEndpoint.mRelayDatagram.get() != 0 && it->second->mSecondEndpoint.mTuple.ipVersion() == V6)))
|
||||
{
|
||||
fdset.setWrite(it->second->mV6Fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define KEEPALIVETIMEOUTMS 1000
|
||||
#define KEEPALIVEMS 20
|
||||
#define STALEENDPOINTTIMEOUTMS 2000
|
||||
void
|
||||
MediaRelay::checkKeepalives(MediaRelayPort* relayPort)
|
||||
{
|
||||
UInt64 now = Timer::getTimeMs();
|
||||
|
||||
// See if First Endpoint is stale (ie. hasn't received data in STALEENDPOINTTIMEOUTMS ms)
|
||||
if(relayPort->mFirstEndpoint.mTuple.getPort() != 0 &&
|
||||
(now - relayPort->mFirstEndpoint.mRecvTimeMs) > STALEENDPOINTTIMEOUTMS)
|
||||
{
|
||||
relayPort->mFirstEndpoint.reset();
|
||||
InfoLog(<< "MediaRelay::checkKeepalives: port=" << relayPort->mLocalV4Tuple.getPort() << ", haven't recevied data from first endpoint in " << STALEENDPOINTTIMEOUTMS << "ms - reseting endpoint.");
|
||||
}
|
||||
|
||||
// See if Second Endpoint is stale (ie. hasn't received data in STALEENDPOINTTIMEOUTMS ms)
|
||||
if(relayPort->mSecondEndpoint.mTuple.getPort() != 0 &&
|
||||
(now - relayPort->mSecondEndpoint.mRecvTimeMs) > STALEENDPOINTTIMEOUTMS)
|
||||
{
|
||||
relayPort->mSecondEndpoint.reset();
|
||||
InfoLog(<< "MediaRelay::checkKeepalives: port=" << relayPort->mLocalV4Tuple.getPort() << ", haven't recevied data from second endpoint in " << STALEENDPOINTTIMEOUTMS << "ms - reseting endpoint.");
|
||||
}
|
||||
|
||||
//if(relayPort->mFirstEndpoint.mTuple.getPort() != 0)
|
||||
//{
|
||||
//InfoLog(<< "MediaRelay::checkKeepalives - port=" << relayPort->mFirstEndpoint.mTuple.getPort() << ", dataToSend=" <<
|
||||
// (relayPort->mFirstEndpoint.mRelayDatagram.get() == 0 ? "no" : "yes") << ", time since last send=" <<
|
||||
// (now - relayPort->mFirstEndpoint.mSendTimeMs));
|
||||
//}
|
||||
|
||||
// See if keepalive needs to be sent to First Endpoint
|
||||
if(relayPort->mFirstEndpoint.mTuple.getPort() != 0 &&
|
||||
relayPort->mFirstEndpoint.mRelayDatagram.get() == 0 &&
|
||||
((!relayPort->mFirstEndpoint.mKeepaliveMode && (now - relayPort->mFirstEndpoint.mSendTimeMs) > KEEPALIVETIMEOUTMS) ||
|
||||
(relayPort->mFirstEndpoint.mKeepaliveMode && (now - relayPort->mFirstEndpoint.mSendTimeMs) > KEEPALIVEMS)))
|
||||
{
|
||||
RtpHeader keepalive; // Create an empty G711 packet to keep iChat happy
|
||||
keepalive.versionExtPayloadTypeAndMarker = htons(0x8000);
|
||||
keepalive.sequenceNumber = 0;
|
||||
keepalive.timestamp = 0;
|
||||
keepalive.ssrc = relayPort->mFirstEndpoint.mSsrc;
|
||||
|
||||
if(!relayPort->mFirstEndpoint.mKeepaliveMode)
|
||||
{
|
||||
InfoLog(<< "MediaRelay::checkKeepalives: port=" << relayPort->mLocalV4Tuple.getPort() << ", dispatching initial RTP keepalive to first sender!");
|
||||
relayPort->mFirstEndpoint.mKeepaliveMode = true;
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// InfoLog(<< "MediaRelay::checkKeepalives: port=" << relayPort->mLocalV4Tuple.getPort() << ", dispatching subsequent RTP keepalive to first sender!");
|
||||
//}
|
||||
|
||||
// Add message to buffer
|
||||
std::auto_ptr<char> buffer(new char[sizeof(RtpHeader)]);
|
||||
memcpy(buffer.get(), &keepalive, sizeof(RtpHeader));
|
||||
|
||||
relayPort->mFirstEndpoint.mRelayDatagram = buffer;
|
||||
relayPort->mFirstEndpoint.mRelayDatagramLen = sizeof(RtpHeader);
|
||||
}
|
||||
|
||||
// See if keepalive needs to be sent to Second Endpoint
|
||||
if(relayPort->mSecondEndpoint.mTuple.getPort() != 0 &&
|
||||
relayPort->mSecondEndpoint.mRelayDatagram.get() == 0 &&
|
||||
((!relayPort->mSecondEndpoint.mKeepaliveMode && (now - relayPort->mSecondEndpoint.mSendTimeMs) > KEEPALIVETIMEOUTMS) ||
|
||||
(relayPort->mSecondEndpoint.mKeepaliveMode && (now - relayPort->mSecondEndpoint.mSendTimeMs) > KEEPALIVEMS)))
|
||||
{
|
||||
RtpHeader keepalive; // Create an empty G711 packet to keep iChat happy
|
||||
keepalive.versionExtPayloadTypeAndMarker = htons(0x8000);
|
||||
keepalive.sequenceNumber = 0;
|
||||
keepalive.timestamp = 0;
|
||||
keepalive.ssrc = relayPort->mSecondEndpoint.mSsrc;
|
||||
|
||||
if(!relayPort->mSecondEndpoint.mKeepaliveMode)
|
||||
{
|
||||
InfoLog(<< "MediaRelay::checkKeepalives: port=" << relayPort->mLocalV4Tuple.getPort() << ", dispatching initial RTP keepalive to second sender!");
|
||||
relayPort->mSecondEndpoint.mKeepaliveMode = true;
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// InfoLog(<< "MediaRelay::checkKeepalives: port=" << relayPort->mLocalV4Tuple.getPort() << ", dispatching subsequent RTP keepalive to second sender!");
|
||||
//}
|
||||
|
||||
// Add message to buffer
|
||||
std::auto_ptr<char> buffer(new char[sizeof(RtpHeader)]);
|
||||
memcpy(buffer.get(), &keepalive, sizeof(RtpHeader));
|
||||
|
||||
relayPort->mSecondEndpoint.mRelayDatagram = buffer;
|
||||
relayPort->mSecondEndpoint.mRelayDatagramLen = sizeof(RtpHeader);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaRelay::process(FdSet& fdset)
|
||||
{
|
||||
Lock lock(mRelaysMutex);
|
||||
|
||||
RelayPortList::iterator it = mRelays.begin();
|
||||
for(;it != mRelays.end(); it++)
|
||||
{
|
||||
if(processWrites(fdset, it->second))
|
||||
{
|
||||
// If all writes have been processed, process reads
|
||||
processReads(fdset, it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
MediaRelay::processWrites(FdSet& fdset, MediaRelayPort* relayPort)
|
||||
{
|
||||
resip::Socket fd = INVALID_SOCKET;
|
||||
Tuple tuple;
|
||||
std::auto_ptr<char> buffer;
|
||||
int len;
|
||||
|
||||
// If we have data to write to first sender then check if readyToWrite
|
||||
if(relayPort->mFirstEndpoint.mRelayDatagram.get() != 0)
|
||||
{
|
||||
if(relayPort->mFirstEndpoint.mTuple.ipVersion() == V4 &&
|
||||
fdset.readyToWrite(relayPort->mV4Fd))
|
||||
{
|
||||
fd = relayPort->mV4Fd;
|
||||
tuple = relayPort->mFirstEndpoint.mTuple;
|
||||
buffer = relayPort->mFirstEndpoint.mRelayDatagram;
|
||||
len = relayPort->mFirstEndpoint.mRelayDatagramLen;
|
||||
}
|
||||
else if(mIsV6Avail &&
|
||||
relayPort->mFirstEndpoint.mTuple.ipVersion() == V6 &&
|
||||
fdset.readyToWrite(relayPort->mV6Fd))
|
||||
{
|
||||
fd = relayPort->mV6Fd;
|
||||
tuple = relayPort->mFirstEndpoint.mTuple;
|
||||
buffer = relayPort->mFirstEndpoint.mRelayDatagram;
|
||||
len = relayPort->mFirstEndpoint.mRelayDatagramLen;
|
||||
}
|
||||
}
|
||||
|
||||
// If anything to send to first sender then do it
|
||||
if (fd != INVALID_SOCKET)
|
||||
{
|
||||
int count;
|
||||
count = sendto(fd,
|
||||
buffer.get(),
|
||||
len,
|
||||
0, // flags
|
||||
&tuple.getMutableSockaddr(), tuple.length());
|
||||
if ( count == SOCKET_ERROR )
|
||||
{
|
||||
int e = getErrno();
|
||||
InfoLog (<< "MediaRelay::processWrites: port=" << relayPort->mLocalV4Tuple.getPort() << ", Failed (" << e << ") sending to " << tuple);
|
||||
}
|
||||
else
|
||||
{
|
||||
// InfoLog(<< len << " bytes of data sent to " << tuple);
|
||||
relayPort->mFirstEndpoint.mSendTimeMs = Timer::getTimeMs();
|
||||
}
|
||||
}
|
||||
|
||||
// check if we have data to write to second sender then check if readyToWrite
|
||||
fd = INVALID_SOCKET; // reset
|
||||
if(relayPort->mSecondEndpoint.mRelayDatagram.get() != 0)
|
||||
{
|
||||
if(relayPort->mSecondEndpoint.mTuple.ipVersion() == V4 &&
|
||||
fdset.readyToWrite(relayPort->mV4Fd))
|
||||
{
|
||||
fd = relayPort->mV4Fd;
|
||||
tuple = relayPort->mSecondEndpoint.mTuple;
|
||||
buffer = relayPort->mSecondEndpoint.mRelayDatagram;
|
||||
len = relayPort->mSecondEndpoint.mRelayDatagramLen;
|
||||
}
|
||||
else if(mIsV6Avail &&
|
||||
relayPort->mSecondEndpoint.mTuple.ipVersion() == V6 &&
|
||||
fdset.readyToWrite(relayPort->mV6Fd))
|
||||
{
|
||||
fd = relayPort->mV6Fd;
|
||||
tuple = relayPort->mSecondEndpoint.mTuple;
|
||||
buffer = relayPort->mSecondEndpoint.mRelayDatagram;
|
||||
len = relayPort->mSecondEndpoint.mRelayDatagramLen;
|
||||
}
|
||||
}
|
||||
|
||||
// If anything to send to sender sender then do it
|
||||
if (fd != INVALID_SOCKET)
|
||||
{
|
||||
int count;
|
||||
count = sendto(fd,
|
||||
buffer.get(),
|
||||
len,
|
||||
0, // flags
|
||||
&tuple.getMutableSockaddr(), tuple.length());
|
||||
if ( count == SOCKET_ERROR )
|
||||
{
|
||||
int e = getErrno();
|
||||
InfoLog (<< "MediaRelay::processWrites: port=" << relayPort->mLocalV4Tuple.getPort() << ", Failed (" << e << ") sending to " << tuple);
|
||||
}
|
||||
else
|
||||
{
|
||||
//InfoLog(<< len << " bytes of data sent to " << tuple);
|
||||
relayPort->mSecondEndpoint.mSendTimeMs = Timer::getTimeMs();
|
||||
}
|
||||
}
|
||||
|
||||
return relayPort->mFirstEndpoint.mRelayDatagram.get() == 0 &&
|
||||
relayPort->mSecondEndpoint.mRelayDatagram.get() == 0;
|
||||
}
|
||||
|
||||
#define UDP_BUFFER_SIZE 1000
|
||||
void
|
||||
MediaRelay::processReads(FdSet& fdset, MediaRelayPort* relayPort)
|
||||
{
|
||||
resip::Socket fd = INVALID_SOCKET;
|
||||
Tuple tuple;
|
||||
|
||||
if(fdset.readyToRead(relayPort->mV4Fd))
|
||||
{
|
||||
//InfoLog(<<"V4 socket is ready to read.");
|
||||
fd = relayPort->mV4Fd;
|
||||
tuple = relayPort->mLocalV4Tuple;
|
||||
}
|
||||
else if(mIsV6Avail && fdset.readyToRead(relayPort->mV6Fd))
|
||||
{
|
||||
//InfoLog(<<"V6 socket is ready to read.");
|
||||
fd = relayPort->mV6Fd;
|
||||
tuple = relayPort->mLocalV6Tuple;
|
||||
}
|
||||
if (fd != INVALID_SOCKET)
|
||||
{
|
||||
std::auto_ptr<char> buffer(new char[UDP_BUFFER_SIZE+1]);
|
||||
|
||||
socklen_t slen = tuple.length();
|
||||
int len = recvfrom( fd,
|
||||
buffer.get(),
|
||||
UDP_BUFFER_SIZE,
|
||||
0 /*flags */,
|
||||
&tuple.getMutableSockaddr(),
|
||||
&slen);
|
||||
if ( len == SOCKET_ERROR )
|
||||
{
|
||||
int err = getErrno();
|
||||
if ( err != EWOULDBLOCK )
|
||||
{
|
||||
ErrLog (<< "MediaRelay::processReads: port=" << relayPort->mLocalV4Tuple.getPort() << ", Error calling recvfrom: " << err);
|
||||
}
|
||||
buffer.reset();
|
||||
}
|
||||
|
||||
if (len == 0)
|
||||
{
|
||||
ErrLog (<< "MediaRelay::processReads: port=" << relayPort->mLocalV4Tuple.getPort() << ", No data calling recvfrom: len=" << len);
|
||||
buffer.reset();
|
||||
}
|
||||
|
||||
if (len+1 >= UDP_BUFFER_SIZE)
|
||||
{
|
||||
InfoLog(<<"MediaRelay::processReads: port=" << relayPort->mLocalV4Tuple.getPort() << ", Datagram exceeded max length "<<UDP_BUFFER_SIZE);
|
||||
buffer.reset();
|
||||
}
|
||||
|
||||
if(buffer.get() != 0)
|
||||
{
|
||||
UInt64 now = Timer::getTimeMs();
|
||||
RtpHeader* rtpHeader = (RtpHeader*)buffer.get();
|
||||
//InfoLog(<< "Received a datagram of size=" << len << " from=" << tuple);
|
||||
MediaEndpoint* pReceivingEndpoint = 0;
|
||||
MediaEndpoint* pSendingEndpoint = 0;
|
||||
|
||||
// First check if packet is from first endpoint
|
||||
if(tuple == relayPort->mFirstEndpoint.mTuple)
|
||||
{
|
||||
pReceivingEndpoint = &relayPort->mFirstEndpoint;
|
||||
pSendingEndpoint = &relayPort->mSecondEndpoint;
|
||||
}
|
||||
// Next check if packet is from second endpoint
|
||||
else if(tuple == relayPort->mSecondEndpoint.mTuple)
|
||||
{
|
||||
pReceivingEndpoint = &relayPort->mSecondEndpoint;
|
||||
pSendingEndpoint = &relayPort->mFirstEndpoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
// See if we can store this new sender in First Endpoint
|
||||
if(relayPort->mFirstEndpoint.mTuple.getPort() == 0)
|
||||
{
|
||||
InfoLog(<< "MediaRelay::processReads: port=" << relayPort->mLocalV4Tuple.getPort() << ", First packet received from First Endpoint " << tuple);
|
||||
pReceivingEndpoint = &relayPort->mFirstEndpoint;
|
||||
pSendingEndpoint = &relayPort->mSecondEndpoint;
|
||||
}
|
||||
else if(relayPort->mSecondEndpoint.mTuple.getPort() == 0)
|
||||
{
|
||||
InfoLog(<< "MediaRelay::processReads: port=" << relayPort->mLocalV4Tuple.getPort() << ", First packet received from Second Endpoint " << tuple);
|
||||
pReceivingEndpoint = &relayPort->mSecondEndpoint;
|
||||
pSendingEndpoint = &relayPort->mFirstEndpoint;
|
||||
}
|
||||
else // We already have 2 endpoints - this would be a third
|
||||
{
|
||||
// We have a third sender - for now drop, if one of the other senders stops sending data for 2 seconds then we will start picking up this sender
|
||||
WarningLog(<< "MediaRelay::processReads: port=" << relayPort->mLocalV4Tuple.getPort() << ", MediaRelay on " << relayPort->mLocalV4Tuple.getPort() << " has seen a third sender " << tuple << " - not implemented yet - ignoring packet");
|
||||
}
|
||||
if(pReceivingEndpoint)
|
||||
{
|
||||
pReceivingEndpoint->mTuple = tuple;
|
||||
pReceivingEndpoint->mSendTimeMs = now;
|
||||
pReceivingEndpoint->mRecvTimeMs = now;
|
||||
}
|
||||
}
|
||||
|
||||
if(pReceivingEndpoint)
|
||||
{
|
||||
pReceivingEndpoint->mRecvTimeMs = now;
|
||||
if(pSendingEndpoint && pSendingEndpoint->mTuple.getPort() != 0)
|
||||
{
|
||||
if(ntohs(rtpHeader->versionExtPayloadTypeAndMarker) & 0x8000) // RTP Version 2
|
||||
{
|
||||
// Adjust ssrc
|
||||
rtpHeader->ssrc = pSendingEndpoint->mSsrc;
|
||||
|
||||
// relay packet to second sender
|
||||
resip_assert(pSendingEndpoint->mRelayDatagram.get() == 0);
|
||||
pSendingEndpoint->mRelayDatagram = buffer;
|
||||
pSendingEndpoint->mRelayDatagramLen = len;
|
||||
if(pSendingEndpoint->mKeepaliveMode)
|
||||
{
|
||||
InfoLog(<< "MediaRelay::processReads: port=" << relayPort->mLocalV4Tuple.getPort() << ", received packet to forward, turning off keepalive mode for " << pSendingEndpoint->mTuple);
|
||||
pSendingEndpoint->mKeepaliveMode = false;
|
||||
}
|
||||
|
||||
//InfoLog(<< "Relaying packet from=" << tuple << " to " << pSendingEndpoint->mTuple);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// InfoLog(<< "MediaRelay::processReads: port=" << relayPort->mLocalV4Tuple.getPort() << ", discarding received packet with unknown RTP version from " << tuple);
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
87
src/libs/resiprocate/apps/ichat-gw/MediaRelay.hxx
Normal file
87
src/libs/resiprocate/apps/ichat-gw/MediaRelay.hxx
Normal file
@@ -0,0 +1,87 @@
|
||||
#if !defined(MediaRelay_hxx)
|
||||
#define MediaRelay_hxx
|
||||
|
||||
#include <map>
|
||||
#include <deque>
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <rutil/ThreadIf.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
|
||||
#include "MediaRelayPort.hxx"
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class MediaRelay : public resip::ThreadIf
|
||||
{
|
||||
public:
|
||||
MediaRelay(bool isV6Avail, unsigned short portRangeMin, unsigned short portRangeMax);
|
||||
virtual ~MediaRelay();
|
||||
|
||||
bool createRelay(unsigned short& port);
|
||||
void destroyRelay(unsigned short port);
|
||||
|
||||
void primeNextEndpoint(unsigned short& port, resip::Tuple& destinationIPPort);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
virtual void thread();
|
||||
|
||||
void buildFdSet(resip::FdSet& fdset);
|
||||
void checkKeepalives(MediaRelayPort* relayPort);
|
||||
void process(resip::FdSet& fdset);
|
||||
bool processWrites(resip::FdSet& fdset, MediaRelayPort* relayPort); // return true if all writes are complete
|
||||
void processReads(resip::FdSet& fdset, MediaRelayPort* relayPort);
|
||||
|
||||
bool createRelayImpl(unsigned short& port);
|
||||
resip::Socket createRelaySocket(resip::Tuple& tuple);
|
||||
|
||||
typedef std::map<unsigned short, MediaRelayPort*> RelayPortList;
|
||||
RelayPortList mRelays;
|
||||
resip::Mutex mRelaysMutex;
|
||||
bool mIsV6Avail;
|
||||
|
||||
std::deque<unsigned int> mFreeRelayPortList;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
84
src/libs/resiprocate/apps/ichat-gw/MediaRelayPort.cxx
Normal file
84
src/libs/resiprocate/apps/ichat-gw/MediaRelayPort.cxx
Normal file
@@ -0,0 +1,84 @@
|
||||
#include "rutil/ResipAssert.h"
|
||||
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <resip/stack/Symbols.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
//#include <rutil/DnsUtil.hxx>
|
||||
//#include <rutil/ParseBuffer.hxx>
|
||||
#include <resip/stack/Transport.hxx>
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "MediaRelayPort.hxx"
|
||||
#include <rutil/WinLeakCheck.hxx>
|
||||
|
||||
using namespace gateway;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::GATEWAY
|
||||
|
||||
MediaRelayPort::MediaRelayPort() : mV4Fd(INVALID_SOCKET), mV6Fd(INVALID_SOCKET)
|
||||
{
|
||||
}
|
||||
|
||||
MediaRelayPort::MediaRelayPort(resip::Socket& v4fd, resip::Tuple& v4tuple, resip::Socket& v6fd, resip::Tuple& v6tuple) :
|
||||
mV4Fd(v4fd), mLocalV4Tuple(v4tuple),
|
||||
mV6Fd(v6fd), mLocalV6Tuple(v6tuple)
|
||||
{
|
||||
}
|
||||
|
||||
MediaRelayPort::MediaRelayPort(resip::Socket& v4fd, resip::Tuple& v4tuple) :
|
||||
mV4Fd(v4fd), mLocalV4Tuple(v4tuple),
|
||||
mV6Fd(INVALID_SOCKET)
|
||||
{
|
||||
}
|
||||
|
||||
MediaRelayPort::~MediaRelayPort()
|
||||
{
|
||||
#if defined(WIN32)
|
||||
if(mV4Fd != INVALID_SOCKET) closesocket(mV4Fd);
|
||||
if(mV6Fd != INVALID_SOCKET) closesocket(mV6Fd);
|
||||
#else
|
||||
if(mV4Fd != INVALID_SOCKET) close(mV4Fd);
|
||||
if(mV6Fd != INVALID_SOCKET) close(mV6Fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
94
src/libs/resiprocate/apps/ichat-gw/MediaRelayPort.hxx
Normal file
94
src/libs/resiprocate/apps/ichat-gw/MediaRelayPort.hxx
Normal file
@@ -0,0 +1,94 @@
|
||||
#if !defined(MediaRelayPort_hxx)
|
||||
#define MediaRelayPort_hxx
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <rutil/Data.hxx>
|
||||
#include <rutil/Random.hxx>
|
||||
#include <rutil/Socket.hxx>
|
||||
#include <rutil/TransportType.hxx>
|
||||
#include <resip/stack/Tuple.hxx>
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class MediaEndpoint
|
||||
{
|
||||
public:
|
||||
MediaEndpoint() : mSsrc(resip::Random::getRandom()), mRelayDatagramLen(0), mSendTimeMs(0), mRecvTimeMs(0), mKeepaliveMode(false) {}
|
||||
|
||||
resip::Tuple mTuple;
|
||||
unsigned int mSsrc;
|
||||
std::auto_ptr<char> mRelayDatagram;
|
||||
int mRelayDatagramLen;
|
||||
UInt64 mSendTimeMs;
|
||||
UInt64 mRecvTimeMs;
|
||||
bool mKeepaliveMode;
|
||||
|
||||
void reset()
|
||||
{
|
||||
mTuple = resip::Tuple();
|
||||
mRelayDatagram.release();
|
||||
mRelayDatagramLen = 0;
|
||||
mKeepaliveMode = false;
|
||||
}
|
||||
};
|
||||
|
||||
class MediaRelayPort
|
||||
{
|
||||
public:
|
||||
MediaRelayPort();
|
||||
MediaRelayPort(resip::Socket& v4fd, resip::Tuple& v4tuple, resip::Socket& v6fd, resip::Tuple& v6tuple);
|
||||
MediaRelayPort(resip::Socket& v4fd, resip::Tuple& v4tuple);
|
||||
~MediaRelayPort();
|
||||
|
||||
// V4 and V6 fd's and tuples
|
||||
resip::Socket mV4Fd;
|
||||
resip::Tuple mLocalV4Tuple;
|
||||
|
||||
resip::Socket mV6Fd;
|
||||
resip::Tuple mLocalV6Tuple;
|
||||
|
||||
// Sender data
|
||||
MediaEndpoint mFirstEndpoint;
|
||||
MediaEndpoint mSecondEndpoint;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
1507
src/libs/resiprocate/apps/ichat-gw/Server.cxx
Normal file
1507
src/libs/resiprocate/apps/ichat-gw/Server.cxx
Normal file
File diff suppressed because it is too large
Load Diff
360
src/libs/resiprocate/apps/ichat-gw/Server.hxx
Normal file
360
src/libs/resiprocate/apps/ichat-gw/Server.hxx
Normal file
@@ -0,0 +1,360 @@
|
||||
#if !defined(Server_hxx)
|
||||
#define Server_hxx
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <resip/stack/TransactionUser.hxx>
|
||||
#include <resip/stack/InterruptableStackThread.hxx>
|
||||
#include <rutil/SelectInterruptor.hxx>
|
||||
#include <resip/stack/UdpTransport.hxx>
|
||||
#include <resip/dum/MasterProfile.hxx>
|
||||
#include <resip/dum/DumShutdownHandler.hxx>
|
||||
#include <resip/dum/DialogUsageManager.hxx>
|
||||
#include <resip/dum/InviteSessionHandler.hxx>
|
||||
#include <resip/dum/DialogSetHandler.hxx>
|
||||
#include <resip/dum/OutOfDialogHandler.hxx>
|
||||
#include <resip/dum/RedirectHandler.hxx>
|
||||
#include <resip/dum/SubscriptionHandler.hxx>
|
||||
#include <resip/dum/RegistrationHandler.hxx>
|
||||
#include <rutil/Log.hxx>
|
||||
#include <rutil/SharedPtr.hxx>
|
||||
#include <rutil/Mutex.hxx>
|
||||
|
||||
#include "ConfigParser.hxx"
|
||||
#include "B2BSession.hxx"
|
||||
#include "SipRegistration.hxx"
|
||||
#include "AddressTranslator.hxx"
|
||||
#include "MediaRelay.hxx"
|
||||
#include "IChatIPPortData.hxx"
|
||||
#include "IPCThread.hxx"
|
||||
|
||||
#ifdef WIN32
|
||||
#define sleepMs(t) Sleep(t)
|
||||
#else
|
||||
#define sleepMs(t) usleep(t*1000)
|
||||
#endif
|
||||
|
||||
#define SDP_ICHATGW_ORIGIN_USER "iChat-gw"
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class ShutdownCmd;
|
||||
class B2BSession;
|
||||
|
||||
class Server : public ConfigParser,
|
||||
public IPCHandler,
|
||||
public resip::DumShutdownHandler,
|
||||
public resip::InviteSessionHandler,
|
||||
public resip::DialogSetHandler,
|
||||
public resip::OutOfDialogHandler,
|
||||
public resip::RedirectHandler,
|
||||
public resip::ClientSubscriptionHandler,
|
||||
public resip::ServerSubscriptionHandler,
|
||||
public resip::ClientRegistrationHandler,
|
||||
public resip::ExternalUnknownDatagramHandler
|
||||
{
|
||||
public:
|
||||
Server(int argc, char** argv);
|
||||
virtual ~Server();
|
||||
|
||||
/**
|
||||
Starts the SIP stack thread.
|
||||
|
||||
@note This should be called before calling process() in a loop
|
||||
*/
|
||||
void startup();
|
||||
|
||||
/**
|
||||
This should be called in a loop to give process cycles to the server.
|
||||
|
||||
@param timeoutMs Will return after timeoutMs if nothing to do.
|
||||
Application can do some work, but should call
|
||||
process again ASAP.
|
||||
*/
|
||||
void process(int timeoutMs); // call this in a loop
|
||||
|
||||
/**
|
||||
Used to initiate a shutdown of the server. This function blocks
|
||||
until the shutdown is complete.
|
||||
|
||||
@note There should not be an active process request when this
|
||||
is called.
|
||||
*/
|
||||
void shutdown();
|
||||
|
||||
// Utility Methods ////////////////////////////////////////////////////////////
|
||||
typedef enum
|
||||
{
|
||||
SubsystemAll,
|
||||
SubsystemContents,
|
||||
SubsystemDns,
|
||||
SubsystemDum,
|
||||
SubsystemSdp,
|
||||
SubsystemSip,
|
||||
SubsystemTransaction,
|
||||
SubsystemTransport,
|
||||
SubsystemStats,
|
||||
SubsystemGateway
|
||||
} LoggingSubsystem;
|
||||
|
||||
/**
|
||||
Static method that sets the logging level for a particular subsystem,
|
||||
or all subsystems.
|
||||
|
||||
@param level Logging level to set
|
||||
@param subsystem Subsystem to set level on
|
||||
|
||||
@note: Use Server::SubsystemAll to set the logging level on all
|
||||
subsystems
|
||||
*/
|
||||
static void setLogLevel(resip::Log::Level level, LoggingSubsystem subsystem=SubsystemAll);
|
||||
|
||||
/**
|
||||
Called by Jabber side of gateway to notify SIP side of iChat call request.
|
||||
|
||||
@param to Bare JID of endpoint we are proceeding to ring
|
||||
@param from Full JID of endpoint requesting the call
|
||||
*/
|
||||
void notifyIChatCallRequest(const std::string& to, const std::string& from);
|
||||
|
||||
/**
|
||||
Called by Jabber side of gateway to notify SIP side of cancelled iChat call request.
|
||||
|
||||
@param handle Handle of the B2BSession object for the call
|
||||
*/
|
||||
void notifyIChatCallCancelled(const B2BSessionHandle& handle);
|
||||
|
||||
/**
|
||||
Called by Jabber side of gateway to notify B2BSession that iChat call is proceeding.
|
||||
This call will cause a timeout timer to be deactiviated.
|
||||
|
||||
@param handle Handle of the B2BSession object for the call
|
||||
@param to Full JID of endpoint we are proceeding to ring
|
||||
*/
|
||||
void notifyIChatCallProceeding(const B2BSessionHandle& handle, const std::string& to);
|
||||
|
||||
/**
|
||||
Called by Jabber side of gateway to notify B2BSession that iChat call has failed.
|
||||
|
||||
@param handle Handle of the B2BSession object for the call
|
||||
@param statusCode Code representing the reason for the failure
|
||||
*/
|
||||
void notifyIChatCallFailed(const B2BSessionHandle& handle, unsigned int statusCode);
|
||||
|
||||
/**
|
||||
Called by Jabber side of gateway to notify B2BSession that iChat call setup
|
||||
has completed on the Jabber side, and that it now needs to continue via SIP.
|
||||
|
||||
@param handle Handle of the B2BSession object for the call
|
||||
@param remoteIPPortListBlob List of transports received from the iChat client via
|
||||
Jabber messaging - in proprietary iChat blob format
|
||||
*/
|
||||
void continueIChatCall(const B2BSessionHandle& handle, const std::string& remoteIPPortListBlob);
|
||||
|
||||
/**
|
||||
Called by Jabber side of gateway to request that a jabber user be registered on the
|
||||
configured SIP server. Note: The jabber user's JID is first transformed into a
|
||||
SIP URI using the configured translation rules. Note: calling this multiple times
|
||||
with the same jidToRegister is safe and will result in a no op.
|
||||
|
||||
@param jidToRegister - Jabber user's JID to register on the SIP server.
|
||||
*/
|
||||
void sipRegisterJabberUser(const std::string& jidToRegister);
|
||||
|
||||
/**
|
||||
Called by Jabber side of gateway to request that a jabber user be unregistered from the
|
||||
configured SIP server. Note: The jabber user's JID is first transformed into a
|
||||
SIP URI using the configured translation rules.
|
||||
|
||||
@param jidToUnregister - Jabber user's JID to unregister from the SIP server.
|
||||
*/
|
||||
void sipUnregisterJabberUser(const std::string& jidToUnregister);
|
||||
|
||||
/**
|
||||
Called by Jabber side of gateway to check if the JID to be subscribed will pass the
|
||||
translation rules.
|
||||
|
||||
@param to - JID of address being subscribed to
|
||||
@param from - JID of subscriber
|
||||
*/
|
||||
void checkSubscription(const std::string& to, const std::string& from);
|
||||
|
||||
B2BSession* findMatchingIChatB2BSession(const resip::SipMessage& msg);
|
||||
|
||||
protected:
|
||||
resip::SharedPtr<resip::MasterProfile>& getMasterProfile() { return mProfile; }
|
||||
bool translateAddress(const resip::Data& address, resip::Data& translation, bool failIfNoRule=false);
|
||||
|
||||
// IPC Handler
|
||||
virtual void onNewIPCMsg(const IPCMsg& msg);
|
||||
|
||||
// External Unknown Packet Handler//////////////////////////////////////////////
|
||||
virtual void operator()(resip::UdpTransport* transport, const resip::Tuple& source, std::auto_ptr<resip::Data> unknownPacket);
|
||||
|
||||
// Shutdown Handler ////////////////////////////////////////////////////////////
|
||||
void onDumCanBeDeleted();
|
||||
|
||||
// Invite Session Handler /////////////////////////////////////////////////////
|
||||
virtual void onNewSession(resip::ClientInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg);
|
||||
virtual void onNewSession(resip::ServerInviteSessionHandle h, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg);
|
||||
virtual void onFailure(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg);
|
||||
virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage&, const resip::SdpContents&);
|
||||
virtual void onProvisional(resip::ClientInviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onConnected(resip::ClientInviteSessionHandle h, const resip::SipMessage& msg);
|
||||
virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onStaleCallTimeout(resip::ClientInviteSessionHandle);
|
||||
virtual void onTerminated(resip::InviteSessionHandle h, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* msg);
|
||||
virtual void onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onAnswer(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents&);
|
||||
virtual void onOffer(resip::InviteSessionHandle handle, const resip::SipMessage& msg, const resip::SdpContents& offer);
|
||||
virtual void onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onOfferRejected(resip::InviteSessionHandle, const resip::SipMessage* msg);
|
||||
virtual void onOfferRequestRejected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onRemoteSdpChanged(resip::InviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents& sdp);
|
||||
virtual void onInfo(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onRefer(resip::InviteSessionHandle, resip::ServerSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onReferAccepted(resip::InviteSessionHandle, resip::ClientSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onReferRejected(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onReferNoSub(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessage(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessageSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onMessageFailure(resip::InviteSessionHandle, const resip::SipMessage& msg);
|
||||
virtual void onForkDestroyed(resip::ClientInviteSessionHandle);
|
||||
|
||||
// DialogSetHandler //////////////////////////////////////////////
|
||||
virtual void onTrying(resip::AppDialogSetHandle, const resip::SipMessage& msg);
|
||||
virtual void onNonDialogCreatingProvisional(resip::AppDialogSetHandle, const resip::SipMessage& msg);
|
||||
|
||||
// ClientSubscriptionHandler ///////////////////////////////////////////////////
|
||||
virtual void onUpdatePending(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onUpdateActive(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onUpdateExtension(resip::ClientSubscriptionHandle, const resip::SipMessage& notify, bool outOfOrder);
|
||||
virtual void onTerminated(resip::ClientSubscriptionHandle h, const resip::SipMessage* notify);
|
||||
virtual void onNewSubscription(resip::ClientSubscriptionHandle h, const resip::SipMessage& notify);
|
||||
virtual int onRequestRetry(resip::ClientSubscriptionHandle h, int retryMinimum, const resip::SipMessage& notify);
|
||||
|
||||
// ServerSubscriptionHandler ///////////////////////////////////////////////////
|
||||
virtual void onNewSubscription(resip::ServerSubscriptionHandle, const resip::SipMessage& sub);
|
||||
virtual void onNewSubscriptionFromRefer(resip::ServerSubscriptionHandle, const resip::SipMessage& sub);
|
||||
virtual void onRefresh(resip::ServerSubscriptionHandle, const resip::SipMessage& sub);
|
||||
virtual void onTerminated(resip::ServerSubscriptionHandle);
|
||||
virtual void onReadyToSend(resip::ServerSubscriptionHandle, resip::SipMessage&);
|
||||
virtual void onNotifyRejected(resip::ServerSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onError(resip::ServerSubscriptionHandle, const resip::SipMessage& msg);
|
||||
virtual void onExpiredByClient(resip::ServerSubscriptionHandle, const resip::SipMessage& sub, resip::SipMessage& notify);
|
||||
virtual void onExpired(resip::ServerSubscriptionHandle, resip::SipMessage& notify);
|
||||
virtual bool hasDefaultExpires() const;
|
||||
virtual UInt32 getDefaultExpires() const;
|
||||
|
||||
// OutOfDialogHandler //////////////////////////////////////////////////////////
|
||||
virtual void onSuccess(resip::ClientOutOfDialogReqHandle, const resip::SipMessage& response);
|
||||
virtual void onFailure(resip::ClientOutOfDialogReqHandle, const resip::SipMessage& response);
|
||||
virtual void onReceivedRequest(resip::ServerOutOfDialogReqHandle, const resip::SipMessage& request);
|
||||
|
||||
// RedirectHandler /////////////////////////////////////////////////////////////
|
||||
virtual void onRedirectReceived(resip::AppDialogSetHandle, const resip::SipMessage& response);
|
||||
virtual bool onTryingNextTarget(resip::AppDialogSetHandle, const resip::SipMessage& request);
|
||||
|
||||
// Registration Handler ////////////////////////////////////////////////////////
|
||||
virtual void onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
virtual void onFailure(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
virtual void onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
virtual int onRequestRetry(resip::ClientRegistrationHandle h, int retryMinimum, const resip::SipMessage& msg);
|
||||
|
||||
private:
|
||||
friend class ShutdownCmd;
|
||||
friend class B2BSession;
|
||||
friend class IChatCallTimeout;
|
||||
|
||||
resip::DialogUsageManager& getDialogUsageManager();
|
||||
|
||||
void post(resip::ApplicationMessage& message, unsigned int ms=0);
|
||||
void shutdownImpl();
|
||||
|
||||
friend class NotifyIChatCallRequestCmd;
|
||||
void notifyIChatCallRequestImpl(const std::string& to, const std::string& from);
|
||||
friend class NotifyIChatCallCancelledCmd;
|
||||
void notifyIChatCallCancelledImpl(const B2BSessionHandle& handle);
|
||||
friend class NotifyIChatCallProceedingCmd;
|
||||
void notifyIChatCallProceedingImpl(const B2BSessionHandle& handle, const std::string& to);
|
||||
friend class NotifyIChatCallFailedCmd;
|
||||
void notifyIChatCallFailedImpl(const B2BSessionHandle& handle, unsigned int statusCode);
|
||||
friend class ContinueIChatCallCmd;
|
||||
void continueIChatCallImpl(const B2BSessionHandle& handle, const std::string& remoteIPPortListBlob);
|
||||
friend class SipRegisterJabberUserCmd;
|
||||
void sipRegisterJabberUserImpl(const std::string& jidToRegister);
|
||||
friend class SipUnregisterJabberUserCmd;
|
||||
void sipUnregisterJabberUserImpl(const std::string& jidToUnregister);
|
||||
|
||||
resip::SharedPtr<resip::MasterProfile> mProfile;
|
||||
resip::Security* mSecurity;
|
||||
resip::SelectInterruptor mSelectInterruptor;
|
||||
resip::SipStack mStack;
|
||||
resip::DialogUsageManager mDum;
|
||||
resip::InterruptableStackThread mStackThread;
|
||||
volatile bool mDumShutdown;
|
||||
|
||||
typedef std::map<B2BSessionHandle, B2BSession*> B2BSessionMap;
|
||||
B2BSessionMap mB2BSessions;
|
||||
B2BSessionHandle mCurrentB2BSessionHandle;
|
||||
B2BSession* getB2BSession(const B2BSessionHandle& handle) const;
|
||||
B2BSessionHandle registerB2BSession(B2BSession *);
|
||||
void unregisterB2BSession(const B2BSessionHandle& handle);
|
||||
|
||||
friend class SipRegistration;
|
||||
typedef std::map<resip::Uri, SipRegistration*> RegistrationMap;
|
||||
RegistrationMap mRegistrations;
|
||||
void registerRegistration(SipRegistration *);
|
||||
void unregisterRegistration(SipRegistration *);
|
||||
|
||||
bool mIsV6Avail;
|
||||
IChatIPPortData mLocalIPPortData;
|
||||
|
||||
MediaRelay* mMediaRelay;
|
||||
|
||||
IPCThread* mIPCThread;
|
||||
|
||||
AddressTranslator mAddressTranslator;
|
||||
std::map<resip::DialogSetId,B2BSession*> mActiveSessions;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
165
src/libs/resiprocate/apps/ichat-gw/SipRegistration.cxx
Normal file
165
src/libs/resiprocate/apps/ichat-gw/SipRegistration.cxx
Normal file
@@ -0,0 +1,165 @@
|
||||
#include "Server.hxx"
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "SipRegistration.hxx"
|
||||
|
||||
#include <rutil/Log.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <resip/dum/DialogUsageManager.hxx>
|
||||
#include <resip/dum/ClientRegistration.hxx>
|
||||
|
||||
using namespace gateway;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::GATEWAY
|
||||
|
||||
SipRegistration::SipRegistration(Server& server, DialogUsageManager& dum, Uri& aor)
|
||||
: AppDialogSet(dum),
|
||||
mServer(server),
|
||||
mDum(dum),
|
||||
mAor(aor),
|
||||
mEnded(false)
|
||||
{
|
||||
mServer.registerRegistration(this);
|
||||
}
|
||||
|
||||
SipRegistration::~SipRegistration()
|
||||
{
|
||||
mServer.unregisterRegistration(this);
|
||||
}
|
||||
|
||||
const resip::Uri&
|
||||
SipRegistration::getAor()
|
||||
{
|
||||
return mAor;
|
||||
}
|
||||
|
||||
void
|
||||
SipRegistration::end()
|
||||
{
|
||||
if(!mEnded)
|
||||
{
|
||||
mEnded = true;
|
||||
if(mRegistrationHandle.isValid())
|
||||
{
|
||||
try
|
||||
{
|
||||
// If ended - then just shutdown registration - likely due to shutdown
|
||||
mRegistrationHandle->end();
|
||||
}
|
||||
catch(BaseException&)
|
||||
{
|
||||
// If end() call is nested - it will throw - catch here so that processing continues normally
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const NameAddrs&
|
||||
SipRegistration::getContactAddresses()
|
||||
{
|
||||
static NameAddrs empty;
|
||||
if(mRegistrationHandle.isValid())
|
||||
{
|
||||
return mRegistrationHandle->allContacts(); // .slg. note: myContacts is not sufficient, since they do not contain the stack populated transport address
|
||||
}
|
||||
else
|
||||
{
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Registration Handler ////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void
|
||||
SipRegistration::onSuccess(ClientRegistrationHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(<< "onSuccess(ClientRegistrationHandle): aor=" << mAor << ", msg=" << msg.brief());
|
||||
if(!mEnded)
|
||||
{
|
||||
mRegistrationHandle = h;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
// If ended - then just shutdown registration - likely due to shutdown
|
||||
h->end();
|
||||
}
|
||||
catch(BaseException&)
|
||||
{
|
||||
// If end() call is nested - it will throw - catch here so that processing continues normally
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SipRegistration::onFailure(ClientRegistrationHandle h, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(<< "onFailure(ClientRegistrationHandle): aor=" << mAor << ", msg=" << msg.brief());
|
||||
if(!mEnded)
|
||||
{
|
||||
mRegistrationHandle = h;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
// If we don't have a handle - then just shutdown registration - likely due to shutdown
|
||||
h->end();
|
||||
}
|
||||
catch(BaseException&)
|
||||
{
|
||||
// If end() call is nested - it will throw - catch here so that processing continues normally
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SipRegistration::onRemoved(ClientRegistrationHandle h, const SipMessage&msg)
|
||||
{
|
||||
InfoLog(<< "onRemoved(ClientRegistrationHandle): aor=" << mAor << ", msg=" << msg.brief());
|
||||
}
|
||||
|
||||
int
|
||||
SipRegistration::onRequestRetry(ClientRegistrationHandle h, int retryMinimum, const SipMessage& msg)
|
||||
{
|
||||
InfoLog(<< "onRequestRetry(ClientRegistrationHandle): aor=" << mAor << ", msg=" << msg.brief());
|
||||
return -1; // Let Profile retry setting take effect
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
89
src/libs/resiprocate/apps/ichat-gw/SipRegistration.hxx
Normal file
89
src/libs/resiprocate/apps/ichat-gw/SipRegistration.hxx
Normal file
@@ -0,0 +1,89 @@
|
||||
#if !defined(SipRegistration_hxx)
|
||||
#define SipRegistration_hxx
|
||||
|
||||
#include <resip/dum/AppDialogSet.hxx>
|
||||
#include <resip/dum/InviteSessionHandler.hxx>
|
||||
#include <resip/dum/DialogSetHandler.hxx>
|
||||
#include <resip/dum/SubscriptionHandler.hxx>
|
||||
|
||||
#include "Server.hxx"
|
||||
|
||||
namespace resip
|
||||
{
|
||||
class DialogUsageManager;
|
||||
class SipMessage;
|
||||
}
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
class Server;
|
||||
|
||||
/**
|
||||
This class is used to manage active SIP registrations.
|
||||
|
||||
Author: Scott Godin (sgodin AT SipSpectrum DOT com)
|
||||
*/
|
||||
|
||||
class SipRegistration : public resip::AppDialogSet
|
||||
{
|
||||
public:
|
||||
SipRegistration(Server& server, resip::DialogUsageManager& dum, resip::Uri& aor);
|
||||
virtual ~SipRegistration();
|
||||
|
||||
virtual void end();
|
||||
|
||||
const resip::Uri& getAor();
|
||||
const resip::NameAddrs& getContactAddresses();
|
||||
|
||||
// Registration Handler ////////////////////////////////////////////////////////
|
||||
virtual void onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
virtual void onFailure(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
virtual void onRemoved(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
|
||||
virtual int onRequestRetry(resip::ClientRegistrationHandle h, int retryMinimum, const resip::SipMessage& msg);
|
||||
|
||||
private:
|
||||
Server &mServer;
|
||||
resip::DialogUsageManager &mDum;
|
||||
resip::Uri mAor;
|
||||
bool mEnded;
|
||||
resip::ClientRegistrationHandle mRegistrationHandle;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
176
src/libs/resiprocate/apps/ichat-gw/Thread.cxx
Normal file
176
src/libs/resiprocate/apps/ichat-gw/Thread.cxx
Normal file
@@ -0,0 +1,176 @@
|
||||
#include "rutil/ResipAssert.h"
|
||||
|
||||
#include "Thread.hxx"
|
||||
|
||||
using namespace gateway;
|
||||
using namespace std;
|
||||
|
||||
#if defined(WIN32)
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#include <time.h>
|
||||
#include <process.h> // for _beginthreadex()
|
||||
typedef unsigned(__stdcall *THREAD_START_ROUTINE)(void*);
|
||||
#endif
|
||||
|
||||
#include "rutil/ResipAssert.h"
|
||||
#include <iostream>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
static void*
|
||||
#ifdef WIN32
|
||||
__stdcall
|
||||
#endif
|
||||
threadWrapper( void* parm )
|
||||
{
|
||||
resip_assert( parm );
|
||||
Thread* t = static_cast < Thread* > ( parm );
|
||||
|
||||
resip_assert( t );
|
||||
t->thread();
|
||||
#ifdef WIN32
|
||||
_endthreadex(0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Thread::Thread() :
|
||||
#ifdef WIN32
|
||||
mThread(0),
|
||||
#endif
|
||||
mId(0), mShutdown(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Thread::~Thread()
|
||||
{
|
||||
shutdown();
|
||||
join();
|
||||
}
|
||||
|
||||
void
|
||||
Thread::run()
|
||||
{
|
||||
resip_assert(mId == 0);
|
||||
|
||||
#if defined(WIN32)
|
||||
mThread =
|
||||
(HANDLE)_beginthreadex
|
||||
(
|
||||
NULL, // LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to security attributes
|
||||
0, // DWORD dwStackSize, // initial thread stack size
|
||||
THREAD_START_ROUTINE
|
||||
(threadWrapper), // LPTHREAD_START_ROUTINE lpStartAddress, // pointer to thread function
|
||||
this, //LPVOID lpParameter, // argument for new thread
|
||||
0, //DWORD dwCreationFlags, // creation flags
|
||||
&mId// LPDWORD lpThreadId // pointer to receive thread ID
|
||||
);
|
||||
resip_assert( mThread != 0 );
|
||||
#else
|
||||
// spawn the thread
|
||||
if ( int retval = pthread_create( &mId, 0, threadWrapper, this) )
|
||||
{
|
||||
std::cerr << "Failed to spawn thread: " << retval << std::endl;
|
||||
resip_assert(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
Thread::join()
|
||||
{
|
||||
if (mId == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
DWORD exitCode;
|
||||
while (true)
|
||||
{
|
||||
if (GetExitCodeThread(mThread,&exitCode) != 0)
|
||||
{
|
||||
if (exitCode != STILL_ACTIVE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitForSingleObject(mThread,INFINITE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(mThread);
|
||||
mThread=0;
|
||||
#else
|
||||
void* stat;
|
||||
if (mId != pthread_self())
|
||||
{
|
||||
int r = pthread_join( mId , &stat );
|
||||
if ( r != 0 )
|
||||
{
|
||||
cerr << "Internal error: pthread_join() returned " << r << endl;
|
||||
resip_assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
mId = 0;
|
||||
}
|
||||
|
||||
void
|
||||
Thread::shutdown()
|
||||
{
|
||||
mShutdown = true;
|
||||
}
|
||||
|
||||
bool
|
||||
Thread::isShutdown() const
|
||||
{
|
||||
return mShutdown;
|
||||
}
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
85
src/libs/resiprocate/apps/ichat-gw/Thread.hxx
Normal file
85
src/libs/resiprocate/apps/ichat-gw/Thread.hxx
Normal file
@@ -0,0 +1,85 @@
|
||||
#if !defined(Thread_hxx)
|
||||
#define Thread_hxx
|
||||
|
||||
#ifdef WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
# include <winsock2.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#else
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class Thread
|
||||
{
|
||||
public:
|
||||
Thread();
|
||||
virtual ~Thread();
|
||||
|
||||
virtual void run();
|
||||
void join();
|
||||
virtual void shutdown();
|
||||
bool isShutdown() const;
|
||||
|
||||
#ifdef WIN32
|
||||
typedef unsigned int Id;
|
||||
#else
|
||||
typedef pthread_t Id;
|
||||
#endif
|
||||
|
||||
virtual void thread() = 0;
|
||||
|
||||
protected:
|
||||
#ifdef WIN32
|
||||
HANDLE mThread;
|
||||
#endif
|
||||
Id mId;
|
||||
volatile bool mShutdown;
|
||||
|
||||
private:
|
||||
// Suppress copying
|
||||
Thread(const Thread &);
|
||||
const Thread & operator=(const Thread &);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
36
src/libs/resiprocate/apps/ichat-gw/Version.hxx
Normal file
36
src/libs/resiprocate/apps/ichat-gw/Version.hxx
Normal file
@@ -0,0 +1,36 @@
|
||||
#define ICHATGW_VERSION_STRING "0.1"
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
Binary file not shown.
Binary file not shown.
154
src/libs/resiprocate/apps/ichat-gw/ichat-gw.config
Normal file
154
src/libs/resiprocate/apps/ichat-gw/ichat-gw.config
Normal file
@@ -0,0 +1,154 @@
|
||||
########################################################
|
||||
# ichat-gw configuration file
|
||||
########################################################
|
||||
|
||||
|
||||
########################################################
|
||||
# SIP settings
|
||||
########################################################
|
||||
|
||||
# Local IP Address to bind SIP transports to. If left blank
|
||||
# ichat-gw will bind to all adapters.
|
||||
#IPAddress = 192.168.1.106
|
||||
#IPAddress = 2001:5c0:1000:a::6d
|
||||
IPAddress =
|
||||
|
||||
# Comma separated list of DNS servers, overrides default OS detected list (leave blank for default)
|
||||
DNSServers =
|
||||
|
||||
# Used in From header of SIP calls, when caller is unknown. Value must be a valid formatted SIP
|
||||
# NameAddr. Ie. “{displayname}” <{SIP URI}>. Currently this setting is only used when
|
||||
# calling iChat endpoints and is never displayed to the end user.
|
||||
SIPGatewayIdentity = "iChat-gw" <sip:ichat-gw@blitzzgod.com>
|
||||
|
||||
# Local port to listen on for SIP messages over UDP or TCP
|
||||
UDPTCPPort = 5070
|
||||
|
||||
# Local port to listen on for SIP messages over TLS
|
||||
TLSPort = 5071
|
||||
|
||||
# TLS domain name for this server (note: domain cert for this domain must be present)
|
||||
TLSDomain =
|
||||
|
||||
# Enable/Disable TCP/UDP CRLFCRLF keepalive packets for SIP endpoints
|
||||
# 1|true|on|enable to enable, 0|false|off|disable to disable
|
||||
KeepAlives = enable
|
||||
|
||||
# URI of a proxy server to use a SIP outbound proxy. This setting should not be required if
|
||||
# proper DNS based SIP routing is operational.
|
||||
OutboundProxy =
|
||||
|
||||
# SIP Registration Time - the requested amount of seconds between SIP re-registration requests
|
||||
# Set to 0, to instruct the iChat gateway not to perform any registrations
|
||||
RegistrationTime = 3600
|
||||
|
||||
# SIP Registration Retry Time - the requested amount of seconds between retrying SIP registration
|
||||
# requests after a registration failure.
|
||||
RegistrationRetryTime = 120
|
||||
|
||||
|
||||
########################################################
|
||||
# General settings
|
||||
########################################################
|
||||
|
||||
# Logging level: NONE|CRIT|ERR|WARNING|INFO|DEBUG|STACK
|
||||
LogLevel = INFO
|
||||
|
||||
# Log Filename
|
||||
LogFilename = ichat-gw.log
|
||||
|
||||
# Log file Max Lines
|
||||
LogFileMaxLines = 50000
|
||||
|
||||
# Gateway IPC Port - for IPC UDP socket bound to 127.0.0.1
|
||||
GatewayIPCPort = 2078
|
||||
|
||||
# Jabber Connector IPC Port - for IPC UDP socket bound to 127.0.0.1
|
||||
JabberConnectorIPCPort = 2079
|
||||
|
||||
# Timeout for obtaining iChat Resources when an iChat user is called.
|
||||
IChatProceedingTimeout = 5000
|
||||
|
||||
# If enabled then any time an IChat endpoint is involved then the media relay will be used.
|
||||
# If disabled then the media relay is only used if iChat is originator of a Click-to-dial call.
|
||||
# Note: The media relay MUST be used to perform RTP IPV4<->IPV6 translation and to avoid
|
||||
# media stream timeout during a SIP phone hold.
|
||||
# 1|true|on|enable to enable, 0|false|off|disable to disable
|
||||
AlwaysRelayIChatMedia = true
|
||||
|
||||
# Prefer IPv6 over IPv4 - this setting controls which IP address we select when presented
|
||||
# with the list of IP addresses for an iChat endpoint
|
||||
PreferIPv6 = true
|
||||
|
||||
# Comma separated codec ID filter list - specifies non-interopable codecs that should
|
||||
# be filtered from Sdp Offers.
|
||||
# Note: Default is 3 (GSM), since it has proven non-interopable between iChat and SNOM phones
|
||||
CodecIdFilterList = 3
|
||||
|
||||
# Media relay port range min/max settings. These settings define the range of ports that will be used
|
||||
# by the media relay.
|
||||
MediaRelayPortRangeMin = 8000
|
||||
MediaRelayPortRangeMax = 9999
|
||||
|
||||
|
||||
########################################################
|
||||
# Jabber settings
|
||||
########################################################
|
||||
|
||||
# Hostname or IP address of the Jabber server to connect to
|
||||
JabberServer = jabber.blitzzgod.com
|
||||
|
||||
# Identity of this component - note: domain suffix should match Jabber server domain
|
||||
JabberComponentName = ichat-gw.jabber.blitzzgod.com
|
||||
|
||||
# Jabber Component Password required in order to connect to Jabber server as a component
|
||||
JabberComponentPassword = password
|
||||
|
||||
# Jabber Component Port - port on Jabber server that accepts component connections
|
||||
JabberComponentPort = 5275
|
||||
|
||||
# Duration between Jabber ping messages sent to the server, in order to keep the component connection alive
|
||||
JabberServerPingDuration = 60
|
||||
|
||||
# Username for the iChat Gateway control user - Note: iChat users of the Gateway must add this user to their roster
|
||||
JabberControlUsername = control
|
||||
|
||||
|
||||
########################################################
|
||||
# Address Translation Rules (must be listed in pairs)
|
||||
########################################################
|
||||
|
||||
# Rule for mapping any sip address to appropriate jabber JID/domain
|
||||
TranslationPattern=^sip:(.*)@(.*)$
|
||||
TranslationOutput=xmpp:$1@jabber.blitzzgod.com
|
||||
|
||||
#Rule for mapping any xmpp address to appropriate SIP URI/domain
|
||||
TranslationPattern=^xmpp:(.*)@(.*)$
|
||||
TranslationOutput=sip:$1@blitzzgod.com
|
||||
|
||||
|
||||
########################################################
|
||||
# TLS Configurations
|
||||
########################################################
|
||||
|
||||
#Local path to DH Parameters file
|
||||
TLSDHParamsFilename =
|
||||
|
||||
# Local path to TLS Certificate
|
||||
TLSCertificate =
|
||||
|
||||
# Local path to Private key file
|
||||
TLSPrivateKey =
|
||||
|
||||
# Pass phrase of private key file (can be left blank)
|
||||
TLSPrivateKeyPassPhrase =
|
||||
|
||||
########################################################
|
||||
# iChat Jabber Connector Settings
|
||||
########################################################
|
||||
|
||||
# Path to iChat jabber connector (ichat-gw-jc) executable
|
||||
IchatJabberConnectorPath = ichat-gw-jc
|
||||
|
||||
#For Windows
|
||||
#IchatJabberConnectorPath = ichat-gw-jc.exe
|
||||
115
src/libs/resiprocate/apps/ichat-gw/ichat-gw.cxx
Normal file
115
src/libs/resiprocate/apps/ichat-gw/ichat-gw.cxx
Normal file
@@ -0,0 +1,115 @@
|
||||
#include <signal.h>
|
||||
|
||||
#include "AppSubsystem.hxx"
|
||||
#include "Server.hxx"
|
||||
|
||||
#include <rutil/Log.hxx>
|
||||
#include <rutil/Logger.hxx>
|
||||
#include <rutil/DnsUtil.hxx>
|
||||
#include <rutil/BaseException.hxx>
|
||||
#include <resip/stack/NameAddr.hxx>
|
||||
#include <rutil/WinLeakCheck.hxx>
|
||||
|
||||
using namespace gateway;
|
||||
using namespace resip;
|
||||
using namespace std;
|
||||
|
||||
#define RESIPROCATE_SUBSYSTEM AppSubsystem::GATEWAY
|
||||
|
||||
static bool finished = false;
|
||||
|
||||
static void
|
||||
signalHandler(int signo)
|
||||
{
|
||||
//std::cerr << "Shutting down..." << endl;
|
||||
finished = true;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char** argv)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
if ( signal( SIGPIPE, SIG_IGN) == SIG_ERR)
|
||||
{
|
||||
cerr << "Couldn't install signal handler for SIGPIPE" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
#else
|
||||
#if defined(_DEBUG) && defined(LEAK_CHECK)
|
||||
resip::FindMemoryLeaks fml;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ( signal( SIGINT, signalHandler ) == SIG_ERR )
|
||||
{
|
||||
cerr << "Couldn't install signal handler for SIGINT" << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
if ( signal( SIGTERM, signalHandler ) == SIG_ERR )
|
||||
{
|
||||
cerr << "Couldn't install signal handler for SIGTERM" << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
initNetwork();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Create Server
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
{
|
||||
Server server(argc, argv);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Startup and run...
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
server.startup();
|
||||
|
||||
while(true)
|
||||
{
|
||||
server.process(50);
|
||||
if(finished) break;
|
||||
}
|
||||
|
||||
server.shutdown();
|
||||
}
|
||||
|
||||
InfoLog(<< "ichat-gw is shutdown.");
|
||||
sleepSeconds(2);
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
72
src/libs/resiprocate/apps/ichat-gw/ichat-gw_9_0.sln
Normal file
72
src/libs/resiprocate/apps/ichat-gw/ichat-gw_9_0.sln
Normal file
@@ -0,0 +1,72 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ichat-gw", "ichat-gw_9_0.vcproj", "{8BA87397-9B42-4820-BA53-62FF35C22CAD}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{A77DCD34-20CA-4602-B185-EE3EAD97713D} = {A77DCD34-20CA-4602-B185-EE3EAD97713D}
|
||||
{2A8BE839-6466-4001-B224-8F1C3168D04A} = {2A8BE839-6466-4001-B224-8F1C3168D04A}
|
||||
{12720B4D-F4FC-4502-8FA9-589BF5166216} = {12720B4D-F4FC-4502-8FA9-589BF5166216}
|
||||
{38594885-CF9C-4C5F-B3F0-E4969D7E3F58} = {38594885-CF9C-4C5F-B3F0-E4969D7E3F58}
|
||||
{96CD935E-1951-43B8-AF75-F1C06B3778C1} = {96CD935E-1951-43B8-AF75-F1C06B3778C1}
|
||||
{3D0E5CEB-93DC-4FDB-918B-D08FA369E106} = {3D0E5CEB-93DC-4FDB-918B-D08FA369E106}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rutil", "..\..\rutil\rutil_9_0.vcproj", "{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "resiprocate", "..\..\resip\stack\resiprocate_9_0.vcproj", "{2A8BE839-6466-4001-B224-8F1C3168D04A}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dum", "..\..\resip\dum\dum_9_0.vcproj", "{12720B4D-F4FC-4502-8FA9-589BF5166216}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ares", "..\..\rutil\dns\ares\ares_9_0.vcproj", "{96CD935E-1951-43B8-AF75-F1C06B3778C1}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcre", "..\..\contrib\pcre\pcre_9_0.vcproj", "{38594885-CF9C-4C5F-B3F0-E4969D7E3F58}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jabberconnector", "jabberconnector\jabberconnector_9_0.vcproj", "{A77DCD34-20CA-4602-B185-EE3EAD97713D}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{EEDA9797-BEAA-4377-96FC-C4B41E063290} = {EEDA9797-BEAA-4377-96FC-C4B41E063290}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gloox", "..\..\contrib\gloox\gloox.vcproj", "{EEDA9797-BEAA-4377-96FC-C4B41E063290}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{8BA87397-9B42-4820-BA53-62FF35C22CAD}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{8BA87397-9B42-4820-BA53-62FF35C22CAD}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{8BA87397-9B42-4820-BA53-62FF35C22CAD}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{8BA87397-9B42-4820-BA53-62FF35C22CAD}.Release|Win32.Build.0 = Release|Win32
|
||||
{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.ActiveCfg = SSL-Debug|Win32
|
||||
{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Debug|Win32.Build.0 = SSL-Debug|Win32
|
||||
{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.ActiveCfg = SSL-Release|Win32
|
||||
{3D0E5CEB-93DC-4FDB-918B-D08FA369E106}.Release|Win32.Build.0 = SSL-Release|Win32
|
||||
{2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug|Win32.ActiveCfg = SSL-Debug|Win32
|
||||
{2A8BE839-6466-4001-B224-8F1C3168D04A}.Debug|Win32.Build.0 = SSL-Debug|Win32
|
||||
{2A8BE839-6466-4001-B224-8F1C3168D04A}.Release|Win32.ActiveCfg = SSL-Release|Win32
|
||||
{2A8BE839-6466-4001-B224-8F1C3168D04A}.Release|Win32.Build.0 = SSL-Release|Win32
|
||||
{12720B4D-F4FC-4502-8FA9-589BF5166216}.Debug|Win32.ActiveCfg = SSL-Debug|Win32
|
||||
{12720B4D-F4FC-4502-8FA9-589BF5166216}.Debug|Win32.Build.0 = SSL-Debug|Win32
|
||||
{12720B4D-F4FC-4502-8FA9-589BF5166216}.Release|Win32.ActiveCfg = SSL-Release|Win32
|
||||
{12720B4D-F4FC-4502-8FA9-589BF5166216}.Release|Win32.Build.0 = SSL-Release|Win32
|
||||
{96CD935E-1951-43B8-AF75-F1C06B3778C1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{96CD935E-1951-43B8-AF75-F1C06B3778C1}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{96CD935E-1951-43B8-AF75-F1C06B3778C1}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{96CD935E-1951-43B8-AF75-F1C06B3778C1}.Release|Win32.Build.0 = Release|Win32
|
||||
{38594885-CF9C-4C5F-B3F0-E4969D7E3F58}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{38594885-CF9C-4C5F-B3F0-E4969D7E3F58}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{38594885-CF9C-4C5F-B3F0-E4969D7E3F58}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{38594885-CF9C-4C5F-B3F0-E4969D7E3F58}.Release|Win32.Build.0 = Release|Win32
|
||||
{A77DCD34-20CA-4602-B185-EE3EAD97713D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{A77DCD34-20CA-4602-B185-EE3EAD97713D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{A77DCD34-20CA-4602-B185-EE3EAD97713D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{A77DCD34-20CA-4602-B185-EE3EAD97713D}.Release|Win32.Build.0 = Release|Win32
|
||||
{EEDA9797-BEAA-4377-96FC-C4B41E063290}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{EEDA9797-BEAA-4377-96FC-C4B41E063290}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{EEDA9797-BEAA-4377-96FC-C4B41E063290}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{EEDA9797-BEAA-4377-96FC-C4B41E063290}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
300
src/libs/resiprocate/apps/ichat-gw/ichat-gw_9_0.vcproj
Normal file
300
src/libs/resiprocate/apps/ichat-gw/ichat-gw_9_0.vcproj
Normal file
@@ -0,0 +1,300 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="ichat-gw"
|
||||
ProjectGUID="{8BA87397-9B42-4820-BA53-62FF35C22CAD}"
|
||||
RootNamespace="ichatgw"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""$(ProjectDir)../../";"$(ProjectDir)../../contrib/openssl/include";"$(ProjectDir)../../contrib/openssl/inc32";"$(ProjectDir)../../contrib/pcre""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_SSL;USE_IPV6"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="Ws2_32.lib winmm.lib Dnsapi.lib Iphlpapi.lib crypt32.lib "$(ProjectDir)..\..\contrib\openssl\lib\vc\static\libeay32MDd.lib" "$(ProjectDir)..\..\contrib\openssl\lib\vc\static\ssleay32MDd.lib""
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""$(ProjectDir)../../";"$(ProjectDir)../../contrib/openssl/include";"$(ProjectDir)../../contrib/openssl/inc32";"$(ProjectDir)../../contrib/pcre""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;USE_SSL;USE_IPV6"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="Ws2_32.lib winmm.lib Dnsapi.lib Iphlpapi.lib crypt32.lib "$(ProjectDir)..\..\contrib\openssl\lib\vc\static\libeay32MD.lib" "$(ProjectDir)..\..\contrib\openssl\lib\vc\static\ssleay32MD.lib""
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\AddressTranslator.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\AppSubsystem.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\B2BSession.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ConfigParser.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ichat-gw.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\IChatIPPortData.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\IPCThread.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MediaRelay.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MediaRelayPort.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Server.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SipRegistration.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Thread.cxx"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\AddressTranslator.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\AppSubsystem.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\B2BSession.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ConfigParser.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\IChatGatewayCmds.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\IChatIPPortData.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\IPCThread.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MediaRelay.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MediaRelayPort.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Server.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\SipRegistration.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Thread.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Version.hxx"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\ichat-gw.config"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
8
src/libs/resiprocate/apps/ichat-gw/jabberconnector/.gitignore
vendored
Normal file
8
src/libs/resiprocate/apps/ichat-gw/jabberconnector/.gitignore
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
/Makefile.in
|
||||
/Makefile
|
||||
/.deps
|
||||
/.libs
|
||||
|
||||
/ichat-gw-jc
|
||||
|
||||
210
src/libs/resiprocate/apps/ichat-gw/jabberconnector/IChatUser.cxx
Normal file
210
src/libs/resiprocate/apps/ichat-gw/jabberconnector/IChatUser.cxx
Normal file
@@ -0,0 +1,210 @@
|
||||
#include "IChatUser.hxx"
|
||||
#include "JabberComponent.hxx"
|
||||
|
||||
using namespace gateway;
|
||||
using namespace std;
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
IChatUser::IChatUser(JabberComponent& component, const std::string& jid) :
|
||||
mJID(jid),
|
||||
mComponent(component)
|
||||
{
|
||||
}
|
||||
|
||||
IChatUser::~IChatUser()
|
||||
{
|
||||
ResourceMap::iterator it = mResources.begin();
|
||||
for(;it!=mResources.end();it++)
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IChatUser::updateResourceInfo(const std::string& resourceId, const gloox::Presence& presence, int priority, bool avAvail)
|
||||
{
|
||||
bool originalUnavailability = isUnavailable();
|
||||
if(resourceId.empty())
|
||||
{
|
||||
if(presence.presence() == gloox::Presence::Unavailable)
|
||||
{
|
||||
// All resources are unanavaiable
|
||||
ResourceMap::iterator it = mResources.begin();
|
||||
for(; it != mResources.end(); it++)
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
mResources.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// PresenceAvailable with no resource is meaningless
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ResourceMap::iterator it = mResources.find(resourceId);
|
||||
if(it != mResources.end())
|
||||
{
|
||||
if(presence.presence() == gloox::Presence::Unavailable)
|
||||
{
|
||||
delete it->second;
|
||||
mResources.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
it->second->mPresence = presence;
|
||||
it->second->mPriority = priority;
|
||||
it->second->mAvAvail = avAvail;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(presence.presence() != gloox::Presence::Unavailable)
|
||||
{
|
||||
mResources[resourceId] = new ResourceInfo(presence, mJID, priority, avAvail);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(originalUnavailability && !isUnavailable())
|
||||
{
|
||||
// User was originally unavailable and now they are available - register SIP endpoint
|
||||
mComponent.sipRegisterJabberUser(mJID);
|
||||
}
|
||||
else if(!originalUnavailability && isUnavailable())
|
||||
{
|
||||
// User was originally available and now they are unavailable - unregister SIP endpoint
|
||||
mComponent.sipUnregisterJabberUser(mJID);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
IChatUser::isUnavailable()
|
||||
{
|
||||
return mResources.empty();
|
||||
}
|
||||
|
||||
IChatUser::ResourceMap::iterator
|
||||
IChatUser::getMostAvailableResourceItr()
|
||||
{
|
||||
ResourceMap::iterator itBestResource = mResources.end();
|
||||
ResourceMap::iterator it = mResources.begin();
|
||||
for(;it!=mResources.end();it++)
|
||||
{
|
||||
if(it->second->mAvAvail)
|
||||
{
|
||||
if(itBestResource == mResources.end())
|
||||
{
|
||||
itBestResource=it;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(it->second->mPresence.presence() < itBestResource->second->mPresence.presence())
|
||||
{
|
||||
itBestResource=it;
|
||||
}
|
||||
else if(it->second->mPresence.presence() == itBestResource->second->mPresence.presence())
|
||||
{
|
||||
if(it->second->mPriority < itBestResource->second->mPriority)
|
||||
{
|
||||
itBestResource=it;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return itBestResource;
|
||||
}
|
||||
|
||||
const std::string&
|
||||
IChatUser::getMostAvailableResource()
|
||||
{
|
||||
static const std::string empty;
|
||||
ResourceMap::iterator itBestResource = getMostAvailableResourceItr();
|
||||
if(itBestResource != mResources.end())
|
||||
{
|
||||
return itBestResource->first;
|
||||
}
|
||||
return empty;
|
||||
}
|
||||
|
||||
bool
|
||||
IChatUser::getMostAvailableResourceList(std::list<std::string>& resourceList)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
// Pass one - go through list and see what highest mPresence availability is
|
||||
ResourceMap::iterator itBestResource = getMostAvailableResourceItr();
|
||||
|
||||
// Pass two - return all resources with matching mPresence and mPriority
|
||||
if(itBestResource != mResources.end())
|
||||
{
|
||||
ResourceMap::iterator it = mResources.begin();
|
||||
for(;it!=mResources.end();it++)
|
||||
{
|
||||
if(it->second->mAvAvail &&
|
||||
it->second->mPresence.presence() == itBestResource->second->mPresence.presence() &&
|
||||
it->second->mPriority == itBestResource->second->mPriority)
|
||||
{
|
||||
resourceList.push_back(it->first);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
IChatUser::addSubscribedGatewayUser(const std::string& jid)
|
||||
{
|
||||
mSubscribedGatewayUsers.insert(jid);
|
||||
}
|
||||
|
||||
void
|
||||
IChatUser::removeSubscribedGatewayUser(const std::string& jid)
|
||||
{
|
||||
SubscribedGatewayUserList::iterator it = mSubscribedGatewayUsers.find(jid);
|
||||
if(it!=mSubscribedGatewayUsers.end())
|
||||
{
|
||||
mSubscribedGatewayUsers.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
104
src/libs/resiprocate/apps/ichat-gw/jabberconnector/IChatUser.hxx
Normal file
104
src/libs/resiprocate/apps/ichat-gw/jabberconnector/IChatUser.hxx
Normal file
@@ -0,0 +1,104 @@
|
||||
#if !defined(IChatUser_hxx)
|
||||
#define IChatUser_hxx
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <list>
|
||||
|
||||
#ifdef WIN32
|
||||
#define RESIP_CONTRIB_GLOOX
|
||||
#endif
|
||||
|
||||
// Gloox includes
|
||||
#ifndef RESIP_CONTRIB_GLOOX
|
||||
#include <gloox/component.h>
|
||||
#include <gloox/presence.h>
|
||||
#else
|
||||
#include <src/component.h>
|
||||
#include <src/presence.h>
|
||||
#endif
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class JabberComponent;
|
||||
|
||||
class ResourceInfo
|
||||
{
|
||||
public:
|
||||
ResourceInfo(const gloox::Presence& presence, const std::string& jid, int priority, bool avAvail) :
|
||||
mPresence(presence.presence(), jid), mPriority(priority), mAvAvail(avAvail) {}
|
||||
~ResourceInfo() {}
|
||||
|
||||
gloox::Presence mPresence;
|
||||
int mPriority;
|
||||
bool mAvAvail;
|
||||
};
|
||||
|
||||
class IChatUser
|
||||
{
|
||||
public:
|
||||
IChatUser(JabberComponent& component, const std::string& jid);
|
||||
~IChatUser();
|
||||
|
||||
typedef std::set<std::string> SubscribedGatewayUserList;
|
||||
|
||||
void updateResourceInfo(const std::string& resourceId, const gloox::Presence& presence, int priority, bool avAvail);
|
||||
bool isUnavailable();
|
||||
const std::string& getMostAvailableResource();
|
||||
bool getMostAvailableResourceList(std::list<std::string>& resourceList);
|
||||
|
||||
void addSubscribedGatewayUser(const std::string& jid);
|
||||
void removeSubscribedGatewayUser(const std::string& jid);
|
||||
const SubscribedGatewayUserList& getSubscribedGatewayUserList() { return mSubscribedGatewayUsers; }
|
||||
|
||||
private:
|
||||
std::string mJID;
|
||||
|
||||
typedef std::map<std::string, ResourceInfo*> ResourceMap;
|
||||
ResourceMap mResources;
|
||||
|
||||
ResourceMap::iterator getMostAvailableResourceItr();
|
||||
|
||||
SubscribedGatewayUserList mSubscribedGatewayUsers;
|
||||
JabberComponent& mComponent;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,215 @@
|
||||
#if !defined(JabberComponent_hxx)
|
||||
#define JabberComponent_hxx
|
||||
|
||||
#include "JabberUserDb.hxx"
|
||||
#include "../IPCThread.hxx"
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <list>
|
||||
|
||||
#ifdef WIN32
|
||||
#define RESIP_CONTRIB_GLOOX
|
||||
#endif
|
||||
|
||||
// Gloox includes
|
||||
#ifndef RESIP_CONTRIB_GLOOX
|
||||
#include <gloox/component.h>
|
||||
#include <gloox/mutex.h>
|
||||
#include <gloox/messagehandler.h>
|
||||
#include <gloox/presencehandler.h>
|
||||
#include <gloox/loghandler.h>
|
||||
#include <gloox/rostermanager.h>
|
||||
#include <gloox/connectionlistener.h>
|
||||
#include <gloox/stanzaextension.h>
|
||||
#include <gloox/iqhandler.h>
|
||||
#include <gloox/disco.h>
|
||||
#include <gloox/disconodehandler.h>
|
||||
#include <gloox/subscriptionhandler.h>
|
||||
#else
|
||||
#include <src/component.h>
|
||||
#include <src/mutex.h>
|
||||
#include <src/messagehandler.h>
|
||||
#include <src/presencehandler.h>
|
||||
#include <src/loghandler.h>
|
||||
#include <src/rostermanager.h>
|
||||
#include <src/connectionlistener.h>
|
||||
#include <src/stanzaextension.h>
|
||||
#include <src/iqhandler.h>
|
||||
#include <src/disco.h>
|
||||
#include <src/disconodehandler.h>
|
||||
#include <src/subscriptionhandler.h>
|
||||
#endif
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class JabberComponent;
|
||||
class IChatUser;
|
||||
|
||||
class IChatCallRequest
|
||||
{
|
||||
public:
|
||||
IChatCallRequest() : mJabberComponent(0), mB2BSessionHandle(0), mCancelled(false) {}
|
||||
IChatCallRequest(JabberComponent* jabberComponent, const std::string& to, const std::string& from, unsigned int handle) :
|
||||
mJabberComponent(jabberComponent), mTo(to), mFrom(from), mB2BSessionHandle(handle), mCancelled(false) {}
|
||||
|
||||
// Client Methods
|
||||
void sendIChatVCRequest(const std::string& fullTo);
|
||||
void sendIChatVCCancelToAll();
|
||||
void receivedIChatVCResponse(const std::string& from);
|
||||
|
||||
// Server Methods
|
||||
void sendIChatVCResponse(bool accept);
|
||||
|
||||
JabberComponent* mJabberComponent;
|
||||
|
||||
std::string mTo;
|
||||
std::string mFrom;
|
||||
unsigned int mB2BSessionHandle;
|
||||
bool mCancelled;
|
||||
std::set<std::string> mPendingVCRequestSet;
|
||||
};
|
||||
|
||||
class JabberComponent : public Thread,
|
||||
IPCHandler,
|
||||
gloox::ConnectionListener,
|
||||
gloox::PresenceHandler,
|
||||
gloox::MessageHandler,
|
||||
gloox::LogHandler,
|
||||
gloox::DiscoNodeHandler,
|
||||
gloox::IqHandler,
|
||||
gloox::SubscriptionHandler
|
||||
{
|
||||
public:
|
||||
JabberComponent(unsigned short jabberConnectorIPCPort,
|
||||
unsigned short gatewayIPCPort,
|
||||
const std::string& server,
|
||||
const std::string& component,
|
||||
const std::string& password,
|
||||
int port,
|
||||
unsigned int serverPingDuration,
|
||||
const std::string& controlUser,
|
||||
const std::string& localIChatPortListBlob);
|
||||
~JabberComponent();
|
||||
|
||||
void stop();
|
||||
void disconnect();
|
||||
|
||||
// Client Methods
|
||||
void initiateIChatCall(const std::string& to, const std::string& from, unsigned int handle, bool alertOneOnly=true);
|
||||
void cancelIChatCall(const std::string& to, const std::string& from);
|
||||
|
||||
// Server Methods
|
||||
void proceedingIChatCall(const std::string& to, const std::string& from, unsigned int handle);
|
||||
void acceptIChatCall(const std::string& to, const std::string& from);
|
||||
void rejectIChatCall(const std::string& to, const std::string& from);
|
||||
|
||||
private:
|
||||
void probePresence(const std::string& to);
|
||||
void sendPresenceForRequest(const gloox::Presence& presence);
|
||||
void sendPresence(const std::string& to, const std::string& from, bool advertiseIChatSupport, bool available);
|
||||
void sendSubscriptionResponse(const std::string& to, const std::string& from, bool success);
|
||||
|
||||
// Interfaces to send IPC messages
|
||||
friend class IChatUser;
|
||||
void notifyIChatCallRequest(const std::string& to, const std::string& from);
|
||||
void notifyIChatCallCancelled(unsigned int handle);
|
||||
void notifyIChatCallProceeding(unsigned int handle, const std::string& to);
|
||||
void notifyIChatCallFailed(unsigned int handle, unsigned int statusCode);
|
||||
void continueIChatCall(unsigned int, const std::string& remoteIPPortListBlob);
|
||||
void sipRegisterJabberUser(const std::string& jidToRegister);
|
||||
void sipUnregisterJabberUser(const std::string& jidToUnregister);
|
||||
void checkSubscription(const std::string& to, const std::string& from);
|
||||
|
||||
// Handlers
|
||||
virtual void onNewIPCMsg(const IPCMsg& msg);
|
||||
virtual void handleLog(gloox::LogLevel level, gloox::LogArea area, const std::string& message);
|
||||
virtual void onConnect();
|
||||
virtual void onDisconnect(gloox::ConnectionError e);
|
||||
virtual bool onTLSConnect(const gloox::CertInfo& info);
|
||||
virtual void handleSubscription(const gloox::Subscription& subscription);
|
||||
virtual void handlePresence(const gloox::Presence& presence);
|
||||
virtual void handleMessage(const gloox::Message& msg, gloox::MessageSession* session = 0);
|
||||
virtual bool handleIq(const gloox::IQ& iq);
|
||||
virtual void handleIqID(const gloox::IQ& iq, int context);
|
||||
virtual gloox::StringList handleDiscoNodeFeatures(const gloox::JID& from, const std::string& node);
|
||||
virtual gloox::Disco::IdentityList handleDiscoNodeIdentities(const gloox::JID& from, const std::string& node);
|
||||
virtual gloox::Disco::ItemList handleDiscoNodeItems(const gloox::JID& from, const gloox::JID& to, const std::string& node);
|
||||
|
||||
virtual void thread();
|
||||
|
||||
gloox::Component* mComponent;
|
||||
bool mStopping;
|
||||
unsigned int mServerPingDuration;
|
||||
std::string mControlJID;
|
||||
std::string mLocalIChatPortListBlob;
|
||||
|
||||
// Outstanding IChat call request maps
|
||||
typedef std::map<std::string, IChatCallRequest> IChatCallRequestMap;
|
||||
friend class IChatCallRequest;
|
||||
std::string makeVCRequestKey(const std::string& bareTo, const std::string& bareFrom);
|
||||
|
||||
IChatCallRequestMap mOutstandingClientIChatCallRequests;
|
||||
gloox::util::Mutex mOutstandingClientIChatCallRequestsMutex;
|
||||
IChatCallRequestMap::iterator findOutstandingClientIChatCallRequest(const std::string& bareTo, const std::string& bareFrom);
|
||||
void failOutstandingClientIChatCallRequest(const std::string& bareTo, const std::string& bareFrom, unsigned int code);
|
||||
void failOutstandingClientIChatCallRequest(const std::string& bareTo, unsigned int code);
|
||||
|
||||
IChatCallRequestMap mOutstandingServerIChatCallRequests;
|
||||
gloox::util::Mutex mOutstandingServerIChatCallRequestsMutex;
|
||||
IChatCallRequestMap::iterator findOutstandingServerIChatCallRequest(const std::string& bareTo, const std::string& bareFrom);
|
||||
void cancelOutstandingServerIChatCallRequest(const std::string& bareTo, const std::string& bareFrom);
|
||||
|
||||
gloox::util::Mutex mIChatUserMutex;
|
||||
typedef std::map<std::string, IChatUser*> IChatUserMap;
|
||||
IChatUserMap mIChatUsers;
|
||||
void storeIChatSubscribedUser(const std::string& user, const std::string& subscribedJID);
|
||||
void removeIChatSubscribedUser(const std::string& user, const std::string& subscribedJID);
|
||||
void storeIChatPresence(const gloox::JID& jid, const gloox::Presence& presence, int priority, bool avAvail);
|
||||
bool getMostAvailableIChatUserFullJID(const gloox::JID& jid, std::string& fullJID);
|
||||
bool getMostAvailableIChatUserFullJIDList(const gloox::JID& jid, std::list<std::string>& fullJIDList);
|
||||
|
||||
JabberUserDb mUserDb;
|
||||
IPCThread mIPCThread;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
#include "JabberUserDb.hxx"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
|
||||
using namespace gateway;
|
||||
using namespace std;
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
JabberUserDb::JabberUserDb()
|
||||
: mDbFilename("ichat-gw.userdb")
|
||||
{
|
||||
parseDbFile(mDbFilename);
|
||||
}
|
||||
|
||||
JabberUserDb::~JabberUserDb()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
JabberUserDb::addSubscribedJID(const std::string& user, const std::string& subscribedJID)
|
||||
{
|
||||
mUsers[user].insert(subscribedJID);
|
||||
writeDbFile(mDbFilename);
|
||||
}
|
||||
|
||||
void
|
||||
JabberUserDb::removeSubscribedJID(const std::string& user, const std::string& subscribedJID)
|
||||
{
|
||||
bool found = false;
|
||||
UserMap::iterator it = mUsers.find(user);
|
||||
if(it!=mUsers.end())
|
||||
{
|
||||
SubscribeSet::iterator it2 = it->second.find(subscribedJID);
|
||||
if(it2!=it->second.end())
|
||||
{
|
||||
found = true;
|
||||
it->second.erase(it2);
|
||||
}
|
||||
// Remove user entirely if no subscriptions left
|
||||
if(it->second.size() == 0)
|
||||
{
|
||||
mUsers.erase(it);
|
||||
}
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
writeDbFile(mDbFilename);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
JabberUserDb::parseDbFile(const std::string& filename)
|
||||
{
|
||||
ifstream dbFile(filename.c_str());
|
||||
string lastUser;
|
||||
string sline;
|
||||
|
||||
// Get first line and ensure version is present
|
||||
if(getline(dbFile, sline))
|
||||
{
|
||||
if(sline != "v1") // For now we just read version 1 format
|
||||
{
|
||||
cerr << "JabberUserDb::parseDbFile: invalid first line in file, expecting version line!" << endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "JabberUserDb::parseDbFile: invalid first line in file, expecting version line!" << endl;
|
||||
return;
|
||||
}
|
||||
while(getline(dbFile, sline))
|
||||
{
|
||||
if(sline.size() > 1 &&
|
||||
sline.at(0) == '\t' &&
|
||||
!lastUser.empty())
|
||||
{
|
||||
// This should be a local subscription JID
|
||||
mUsers[lastUser].insert(sline.substr(1));
|
||||
//cout << "'" << lastUser << "': '" << sline.substr(1) << "'" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This should be a user
|
||||
lastUser = sline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
JabberUserDb::writeDbFile(const std::string& filename)
|
||||
{
|
||||
std::string tempfilename = filename + ".tmp";
|
||||
|
||||
// safewrite - write to a temp file, delete original, then move temp file
|
||||
ofstream dbFile(tempfilename.c_str(), std::ios_base::out | std::ios_base::trunc);
|
||||
if(dbFile.is_open())
|
||||
{
|
||||
dbFile << "v1\n";
|
||||
UserMap::iterator it = mUsers.begin();
|
||||
for(;it!=mUsers.end();it++)
|
||||
{
|
||||
dbFile << it->first << "\n";
|
||||
SubscribeSet::iterator it2 = it->second.begin();
|
||||
for(;it2!=it->second.end();it2++)
|
||||
{
|
||||
dbFile << "\t" << *it2 << "\n";
|
||||
}
|
||||
}
|
||||
dbFile.close();
|
||||
if(remove(filename.c_str()) != 0)
|
||||
{
|
||||
cerr << "JabberUserDb::writeDbFile - error removing " << filename << " to update with new data." << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(rename(tempfilename.c_str(), filename.c_str()) != 0)
|
||||
{
|
||||
cerr << "JabberUserDb::writeDbFile - error renaming " << tempfilename << " to " << filename << " to update with new data." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "JabberUserDb::writeDbFile - error opening " << tempfilename << " for writing." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
#if !defined(JabberUserDb_hxx)
|
||||
#define JabberUserDb_hxx
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace gateway
|
||||
{
|
||||
|
||||
class JabberUserDb
|
||||
{
|
||||
public:
|
||||
JabberUserDb();
|
||||
virtual ~JabberUserDb();
|
||||
|
||||
typedef std::set<std::string> SubscribeSet;
|
||||
typedef std::map<std::string, SubscribeSet> UserMap;
|
||||
|
||||
const UserMap& getUserSubscriptions() const { return mUsers; }
|
||||
|
||||
void addSubscribedJID(const std::string& user, const std::string& subscribedJID);
|
||||
void removeSubscribedJID(const std::string& user, const std::string& subscribedJID);
|
||||
|
||||
private:
|
||||
void parseDbFile(const std::string& filename);
|
||||
void writeDbFile(const std::string& filename);
|
||||
|
||||
std::string mDbFilename;
|
||||
UserMap mUsers;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
# $Id$
|
||||
|
||||
EXTRA_DIST = *.vcproj
|
||||
|
||||
SUBDIRS = .
|
||||
|
||||
#AM_CXXFLAGS = -DUSE_ARES
|
||||
|
||||
sbin_PROGRAMS = ichat-gw-jc
|
||||
ichat_gw_jc_LDADD = ../../../resip/dum/libdum.la
|
||||
ichat_gw_jc_LDADD += ../../../resip/stack/libresip.la
|
||||
ichat_gw_jc_LDADD += ../../../rutil/librutil.la
|
||||
ichat_gw_jc_LDADD += -lgloox
|
||||
ichat_gw_jc_LDADD += -lgnutls
|
||||
ichat_gw_jc_LDADD += -lidn
|
||||
ichat_gw_jc_LDADD += -lresolv
|
||||
ichat_gw_jc_LDADD += @LIBPTHREAD_LIBADD@
|
||||
|
||||
ichat_gw_jc_SOURCES = \
|
||||
ichat-gw-jc.cxx \
|
||||
IChatUser.cxx \
|
||||
../IPCThread.cxx \
|
||||
JabberComponent.cxx \
|
||||
JabberUserDb.cxx \
|
||||
../Thread.cxx
|
||||
|
||||
ichat_gw_jcincludedir = $(includedir)/ichat-gw-jc
|
||||
nobase_ichat_gw_jcinclude_HEADERS = IChatUser.hxx \
|
||||
JabberComponent.hxx \
|
||||
JabberUserDb.hxx
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# The Vovida Software License, Version 1.0
|
||||
# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
#
|
||||
# 3. The names "VOCAL", "Vovida Open Communication Application Library",
|
||||
# and "Vovida Open Communication Application Library (VOCAL)" must
|
||||
# not be used to endorse or promote products derived from this
|
||||
# software without prior written permission. For written
|
||||
# permission, please contact vocal@vovida.org.
|
||||
#
|
||||
# 4. Products derived from this software may not be called "VOCAL", nor
|
||||
# may "VOCAL" appear in their name, without prior written
|
||||
# permission of Vovida Networks, Inc.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
|
||||
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
|
||||
# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
|
||||
# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
|
||||
# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
# DAMAGE.
|
||||
#
|
||||
# ====================================================================
|
||||
#
|
||||
# This software consists of voluntary contributions made by Vovida
|
||||
# Networks, Inc. and many individuals on behalf of Vovida Networks,
|
||||
# Inc. For more information on Vovida Networks, Inc., please see
|
||||
# <http://www.vovida.org/>.
|
||||
#
|
||||
##############################################################################
|
||||
@@ -0,0 +1,129 @@
|
||||
#include <signal.h>
|
||||
#include <iostream>
|
||||
#include "rutil/ResipAssert.h"
|
||||
|
||||
#include "JabberComponent.hxx"
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace gateway;
|
||||
using namespace std;
|
||||
|
||||
void sleepSeconds(unsigned int seconds)
|
||||
{
|
||||
#ifdef WIN32
|
||||
Sleep(seconds*1000);
|
||||
#else
|
||||
sleep(seconds);
|
||||
#endif
|
||||
}
|
||||
|
||||
JabberComponent* g_component;
|
||||
|
||||
static void
|
||||
signalHandler(int signo)
|
||||
{
|
||||
//std::cerr << "Shutting down" << endl;
|
||||
g_component->stop();
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char** argv)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
if ( signal( SIGPIPE, SIG_IGN) == SIG_ERR)
|
||||
{
|
||||
cerr << "Couldn't install signal handler for SIGPIPE" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( signal( SIGINT, signalHandler ) == SIG_ERR )
|
||||
{
|
||||
cerr << "Couldn't install signal handler for SIGINT" << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
if ( signal( SIGTERM, signalHandler ) == SIG_ERR )
|
||||
{
|
||||
cerr << "Couldn't install signal handler for SIGTERM" << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
if(argc != 11 || std::string(argv[0]) != std::string("ichat-gw"))
|
||||
{
|
||||
cerr << "argc=" << argc << ", argv[0]=" << argv[0] << endl;
|
||||
cerr << "Jabber connector process must not be launched manually, it is launched automatically from the main ichat-gw program." << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
WORD wVersionRequested = MAKEWORD( 2, 2 );
|
||||
WSADATA wsaData;
|
||||
int err = WSAStartup( wVersionRequested, &wsaData );
|
||||
if ( err != 0 )
|
||||
{
|
||||
// could not find a usable WinSock DLL
|
||||
cerr << "Could not load winsock" << endl;
|
||||
resip_assert(0);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int jabberConnectorIPCPort = atoi(argv[1]);
|
||||
unsigned int gatewayIPCPort = atoi(argv[2]);
|
||||
|
||||
g_component = new JabberComponent(jabberConnectorIPCPort,
|
||||
gatewayIPCPort,
|
||||
argv[3], // Jabber server
|
||||
argv[4], // Jabber component name
|
||||
argv[5], // Jabber component password
|
||||
atoi(argv[6]), // Jabber component port
|
||||
atoi(argv[7]), // Jabber server ping duration
|
||||
argv[8], // Jabber control username
|
||||
argv[9]); // IPPort Data blob
|
||||
|
||||
|
||||
g_component->run();
|
||||
|
||||
g_component->join();
|
||||
delete g_component;
|
||||
|
||||
cout << "ichat-gw-jc is shutdown." << endl;
|
||||
sleepSeconds(2);
|
||||
}
|
||||
|
||||
|
||||
/* ====================================================================
|
||||
|
||||
Copyright (c) 2009, SIP Spectrum, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of SIP Spectrum nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
==================================================================== */
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="jabberconnector"
|
||||
ProjectGUID="{A77DCD34-20CA-4602-B185-EE3EAD97713D}"
|
||||
RootNamespace="jabberconnector"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""$(ProjectDir)../../../";"$(ProjectDir)../../../contrib/gloox""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;USE_SSL;USE_IPV6"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="Ws2_32.lib winmm.lib Dnsapi.lib Iphlpapi.lib crypt32.lib"
|
||||
OutputFile="$(OutDir)\ichat-gw-jc.exe"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="copy $(TargetPath) $(ProjectDir)..\"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""$(ProjectDir)../../../";"$(ProjectDir)../../../contrib/gloox""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;USE_SSL;USE_IPV6"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="Ws2_32.lib winmm.lib Dnsapi.lib Iphlpapi.lib crypt32.lib"
|
||||
OutputFile="$(OutDir)\ichat-gw-jc.exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
CommandLine="copy $(TargetPath) $(ProjectDir)..\"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\ichat-gw-jc.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\IChatUser.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\IPCThread.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\JabberComponent.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\JabberUserDb.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Thread.cxx"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\IChatUser.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\IPCThread.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\JabberComponent.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\JabberUserDb.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Thread.hxx"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
Reference in New Issue
Block a user