[Pkg-voip-commits] [SCM] reSIProcate branch, master, updated. upstream/1.8.0_pre1-42-g87a864a
Daniel Pocock
daniel at pocock.com.au
Tue May 22 13:39:41 UTC 2012
The following commit has been merged in the master branch:
commit 80eaf627b550ba61b1c824f796ab0c0a31a4b2f1
Author: Daniel Pocock <daniel at pocock.com.au>
Date: Tue May 22 13:34:49 2012 +0000
Imported Upstream version 1.8.0~pre5
diff --git a/Makefile.am b/Makefile.am
index 6f42621..6da5081 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -6,6 +6,9 @@ ACLOCAL_AMFLAGS = -I m4
SUBDIRS = rutil
SUBDIRS += resip
SUBDIRS += repro
+if BUILD_B2BUA
+SUBDIRS += b2bua
+endif
if BUILD_TFM
SUBDIRS += tfm
endif
diff --git a/Makefile.in b/Makefile.in
index 3a40fd1..995e2c0 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -33,14 +33,15 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
- at BUILD_TFM_TRUE@am__append_1 = tfm
- at BUILD_APPS_TRUE@am__append_2 = apps
+ at BUILD_B2BUA_TRUE@am__append_1 = b2bua
+ at BUILD_TFM_TRUE@am__append_2 = tfm
+ at BUILD_APPS_TRUE@am__append_3 = apps
# The Makefiles for these don't separate SSL stuff yet...
- at USE_SSL_TRUE@am__append_3 = reTurn reTurn/client
- at BUILD_RECON_TRUE@@USE_SSL_TRUE at am__append_4 = reflow resip/recon
- at USE_SSL_TRUE@am__append_5 = presSvr
- at BUILD_P2P_TRUE@@USE_SSL_TRUE at am__append_6 = p2p/s2c/s2c p2p
+ at USE_SSL_TRUE@am__append_4 = reTurn reTurn/client
+ at BUILD_RECON_TRUE@@USE_SSL_TRUE at am__append_5 = reflow resip/recon
+ at USE_SSL_TRUE@am__append_6 = presSvr
+ at BUILD_P2P_TRUE@@USE_SSL_TRUE at am__append_7 = p2p/s2c/s2c p2p
subdir = .
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/config.h.in \
@@ -78,8 +79,8 @@ AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
distdir dist dist-all distcheck
ETAGS = etags
CTAGS = ctags
-DIST_SUBDIRS = rutil resip repro tfm apps reTurn reTurn/client reflow \
- resip/recon presSvr p2p/s2c/s2c p2p
+DIST_SUBDIRS = rutil resip repro b2bua tfm apps reTurn reTurn/client \
+ reflow resip/recon presSvr p2p/s2c/s2c p2p
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
@@ -246,7 +247,7 @@ AUTOMAKE_OPTIONS = foreign dist-tarZ
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = rutil resip repro $(am__append_1) $(am__append_2) \
$(am__append_3) $(am__append_4) $(am__append_5) \
- $(am__append_6)
+ $(am__append_6) $(am__append_7)
#EXTRA_DIST = build-contrib.sh
#EXTRA_DIST += reSIProcate_7_1.sln
diff --git a/apps/sipdial/sipdialer.1 b/apps/sipdial/sipdialer.1
index dacd973..712210c 100644
--- a/apps/sipdial/sipdialer.1
+++ b/apps/sipdial/sipdialer.1
@@ -15,4 +15,4 @@ Daniel Pocock <daniel at pocock.com.au>
.SH "REPORTING BUGS"
See http://www.resiprocate.org
.SH COPYRIGHT
-Copyright (C) 2007 Daniel Pocock - licenced under the terms of GPL v3
+Copyright (C) 2007 Daniel Pocock - licenced under BSD terms
diff --git a/b2bua/AccountingManager.hxx b/b2bua/AccountingManager.hxx
new file mode 100644
index 0000000..f0bac7b
--- /dev/null
+++ b/b2bua/AccountingManager.hxx
@@ -0,0 +1,68 @@
+
+#ifndef __AccountingManager_h
+#define __AccountingManager_h
+
+
+#include "rutil/Data.h"
+
+namespace b2bua
+{
+
+class AccountingManager {
+
+public:
+ // Call has entered system
+ virtual void onCallStart() = 0;
+ // Call has been authorised
+ virtual void onCallAuthorise() = 0;
+ // Call has connected
+ virtual void onCallConnect() = 0;
+ // A route has failed
+ virtual void onCallRouteFail() = 0;
+ // All routes have been tried and failed, or the call was not authorised
+ virtual void onCallFail() = 0;
+ // The call connected and completed successfully
+ virtual void onCallFinish() = 0;
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/AuthenticationManager.cxx b/b2bua/AuthenticationManager.cxx
new file mode 100644
index 0000000..22484bf
--- /dev/null
+++ b/b2bua/AuthenticationManager.cxx
@@ -0,0 +1,45 @@
+
+#include "AuthenticationManager.hxx"
+
+using namespace b2bua;
+
+AuthenticationManager::SecretListener::~SecretListener() {
+}
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/AuthenticationManager.hxx b/b2bua/AuthenticationManager.hxx
new file mode 100644
index 0000000..76d40a2
--- /dev/null
+++ b/b2bua/AuthenticationManager.hxx
@@ -0,0 +1,79 @@
+
+#ifndef __AuthenticationManager_h
+#define __AuthenticationManager_h
+
+#include "rutil/Data.hxx"
+
+namespace b2bua
+{
+
+class AuthenticationManager {
+
+// const resip::Data& realm;
+// const resip::Data& user;
+
+public:
+
+ /**
+ * The application should implement SecretListener to receive callbacks
+ * when authentication is complete.
+ */
+ class SecretListener {
+ public:
+ virtual ~SecretListener();
+ // Called when the secret is found successfully
+ virtual void onSuccess(const resip::Data& realm, const resip::Data& user, const resip::Data& secret) = 0;
+ // Called when the user ID is not recognised
+ virtual void onUserUnknown(const resip::Data& realm, const resip::Data& user) = 0;
+ // Called when an internal failure or timeout occurs
+ virtual void onFailure(const resip::Data& realm, const resip::Data& user) = 0;
+ };
+
+ virtual ~AuthenticationManager() {};
+
+ virtual void getSecret(const resip::Data& realm, const resip::Data& user, AuthenticationManager::SecretListener *secretListener) = 0;
+
+};
+
+}
+
+#endif
+
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/AuthorizationManager.hxx b/b2bua/AuthorizationManager.hxx
new file mode 100644
index 0000000..d50817e
--- /dev/null
+++ b/b2bua/AuthorizationManager.hxx
@@ -0,0 +1,92 @@
+
+#ifndef __AuthorizationManager_h
+#define __AuthorizationManager_h
+
+#include "rutil/Data.hxx"
+
+#include "CallHandle.hxx"
+
+namespace b2bua
+{
+
+class AuthorizationManager {
+
+public:
+
+ typedef enum DenialReason {
+ AuthenticationRequired, // A username is required
+ PeerUnknown, // IP or username unrecognised by
+ // the AuthorizationManager
+ InsufficientFunds, // Deposit more funds
+ Unspecified, // Request denied for an unspecified
+ // reason (e.g. account suspended),
+ // but not due to error
+ DestinationIncomplete, // Number is too short
+ DestinationInvalid, // Unrecognised destination prefix
+ // or name
+ InvalidRequest, // Some other aspect of the request
+ // is invalid
+ NetworkError, // An error occurred communicating
+ // with a remote auth server
+ Timeout, // A timeout occurred
+ GeneralError // An error while processing
+ };
+
+ class AuthorizationListener {
+ public:
+ virtual ~AuthorizationListener() {};
+ // Call is authorized
+ virtual void onSuccess() = 0;
+ // Call is denied
+ virtual void onDeny(AuthorizationManager::DenialReason reason) = 0;
+ };
+
+ //virtual void getAuthorization();
+
+ virtual ~AuthorizationManager() {};
+
+ virtual CallHandle *authorizeCall(const resip::NameAddr& sourceAddr, const resip::Uri& destinationAddr, const resip::Data& authRealm, const resip::Data& authUser, const resip::Data& authPass, const resip::Data& srcIp, const resip::Data& contextId, const resip::Data& accountId, const resip::Data& baseIp, const resip::Data& controlId, time_t startTime) = 0;
+
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/B2BCall.cxx b/b2bua/B2BCall.cxx
new file mode 100644
index 0000000..424d197
--- /dev/null
+++ b/b2bua/B2BCall.cxx
@@ -0,0 +1,1321 @@
+
+#include <sstream>
+
+#include "resip/dum/ServerInviteSession.hxx"
+
+#include "B2BCall.hxx"
+#include "CallHandle.hxx"
+#include "Logging.hxx"
+#include "MyAppDialog.hxx"
+
+using namespace b2bua;
+using namespace resip;
+using namespace std;
+
+// DialogUsageManager *B2BCall::dum = NULL;
+// CallController *B2BCall::callController = NULL;
+// list<B2BCall *> B2BCall::calls;
+
+Data B2BCall::callStateNames[] = {
+ Data("NewCall"),
+ Data("CallerCancel"),
+ Data("AuthorizationPending"),
+ Data("AuthorizationSuccess"),
+ Data("AuthorizationFail"),
+ Data("MediaProxySuccess"),
+ Data("MediaProxyFail"),
+ Data("ReadyToDial"),
+ Data("DialInProgress"),
+ Data("DialFailed"),
+ Data("DialRejected"),
+ Data("SelectAlternateRoute"),
+ Data("DialAborted"),
+ Data("DialReceived180"),
+ Data("DialReceivedEarlyAnswer"),
+ Data("DialEarlyMediaProxySuccess"),
+ Data("DialEarlyMediaProxyFail"),
+ Data("CallAccepted"),
+ Data("CallAcceptedMediaProxySuccess"),
+ Data("CallAcceptedMediaProxyFail"),
+ Data("CallActive"),
+ Data("CallerHangup"),
+ Data("CalleeHangup"),
+ Data("LocalHangup"),
+ Data("CallStop"),
+ Data("CallStopMediaProxySuccess"),
+ Data("CallStopMediaProxyFail"),
+ Data("CallStopFinal")
+};
+
+const char *B2BCall::basicClearingReasonName[] = {
+ "NO ANSWER",
+ "BUSY",
+ "CONGESTION",
+ "ERROR",
+ "ANSWERED"
+};
+
+/* void B2BCall::setDum(DialogUsageManager *dum) {
+ B2BCall::dum = dum;
+} */
+
+/* void B2BCall::setCallController(CallController *callController) {
+ B2BCall::callController = callController;
+} */
+
+B2BCall::B2BCall(CDRHandler& cdrHandler, DialogUsageManager& dum, AuthorizationManager& authorizationManager, MyAppDialog *aLegAppDialog, const resip::NameAddr& sourceAddr, const resip::Uri& destinationAddr, const resip::Data& authRealm, const resip::Data& authUser, const resip::Data& authPassword, const resip::Data& srcIp, const resip::Data& contextId, const resip::Data& accountId, const resip::Data& baseIp, const resip::Data& controlId) : cdrHandler(cdrHandler), dum(dum), authorizationManager(authorizationManager), sourceAddr(sourceAddr), destinationAddr(destinationAddr), authRealm(authRealm), authUser(authUser), authPassword(authPassword), srcIp(srcIp), contextId(contextId), accountId(accountId), baseIp(baseIp), controlId(controlId) {
+ callHandle = NULL;
+ fullClearingReason = Unset;
+ rejectOtherCode = 0;
+ failureStatusCode = -1;
+ this->aLegAppDialog = aLegAppDialog;
+ aLegAppDialog->setB2BCall(this);
+ bLegAppDialogSet = NULL;
+ bLegAppDialog = NULL;
+ //callState = CALL_NEW;
+ callState = NewCall;
+ time(&startTime);
+ connectTime = 0;
+ finishTime = 0;
+ //aLegSdp = NULL;
+ //bLegSdp = NULL;
+ try {
+ mediaManager = new MediaManager(*this, aLegAppDialog->getDialogId().getCallId(), aLegAppDialog->getDialogId().getLocalTag(), Data(""));
+ } catch (...) {
+ B2BUA_LOG_ERR("failed to instantiate MediaManager");
+ throw new exception;
+ }
+ earlyAnswerSent = false;
+ failureReason = NULL;
+// calls.push_back(this);
+}
+
+B2BCall::~B2BCall() {
+ if(callHandle != NULL)
+ delete callHandle;
+ if(mediaManager != NULL)
+ delete mediaManager;
+ if(failureReason != NULL)
+ delete failureReason;
+ if(aLegAppDialog != NULL)
+ aLegAppDialog->setB2BCall(NULL);
+ if(bLegAppDialogSet != NULL)
+ bLegAppDialogSet->setB2BCall(NULL);
+ if(bLegAppDialog != NULL)
+ bLegAppDialog->setB2BCall(NULL);
+}
+
+
+bool B2BCall::setCallState(B2BCall::B2BCallState newCallState) {
+ B2BUA_LOG_DEBUG("CallState change: " << callState << ":" << getCallStateName(callState) << " -> " << newCallState << ":" << getCallStateName(newCallState) << ": ");
+ if(!isCallStatePermitted(newCallState)) {
+ B2BUA_LOG_ERR("Denied call state change: %d: %s -> %d: %s", callState, getCallStateName(callState).c_str(), newCallState, getCallStateName(newCallState).c_str());
+ return false;
+ }
+ B2BUA_LOG_DEBUG("permitted.");
+ callState = newCallState;
+ return true;
+}
+
+bool B2BCall::isCallStatePermitted(B2BCall::B2BCallState newCallState) {
+ switch(callState) {
+
+ case NewCall:
+ switch(newCallState) {
+ case CallerCancel:
+ case AuthorizationPending:
+ case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case CallerCancel:
+ switch(newCallState) {
+ case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case AuthorizationPending:
+ switch(newCallState) {
+ case AuthorizationSuccess:
+ case AuthorizationFail:
+ case CallerCancel:
+ //case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case AuthorizationSuccess:
+ switch(newCallState) {
+ case CallerCancel:
+ case MediaProxySuccess:
+ case MediaProxyFail:
+ case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case AuthorizationFail:
+ switch(newCallState) {
+ case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case MediaProxySuccess:
+ switch(newCallState) {
+ case CallerCancel:
+ case ReadyToDial:
+ //case DialInProgress:
+ case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case MediaProxyFail:
+ switch(newCallState) {
+ case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case ReadyToDial:
+ switch(newCallState) {
+ case CallerCancel:
+ case DialInProgress:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ }
+
+ case DialInProgress:
+ switch(newCallState) {
+ case CallerCancel:
+ case DialFailed:
+ case DialRejected:
+ case DialInProgress: // FIXME - should we change to same state?
+ //case DialReceived100:
+ case DialReceived180:
+ case DialReceivedEarlyAnswer:
+ case CallAccepted:
+ //case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case DialFailed:
+ switch(newCallState) {
+ case CallerCancel:
+ //case MediaProxySuccess:
+ //case ReadyToDial:
+ case SelectAlternateRoute:
+ //case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case DialRejected:
+ switch(newCallState) {
+ case CallerCancel:
+ //case MediaProxySuccess:
+ //case ReadyToDial:
+ case SelectAlternateRoute:
+ case DialAborted:
+ //case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case SelectAlternateRoute:
+ switch(newCallState) {
+ case CallerCancel:
+ case ReadyToDial:
+ case DialAborted:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case DialAborted:
+ switch(newCallState) {
+ case CallStop:
+ return true;
+ default:
+ return false;
+ };
+
+ /* case DialReceived100:
+ switch(newCallState) {
+ case CallerCancel:
+ case DialInProgress:
+ case DialReceived180:
+ case DialReceivedEarlyAnswer:
+ case DialFailed:
+ case DialRejected:
+ case CallAccepted:
+ case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ }; */
+
+ case DialReceived180:
+ switch(newCallState) {
+ case CallerCancel:
+ case DialInProgress:
+ case DialFailed:
+ case DialRejected:
+ case DialReceivedEarlyAnswer:
+ case CallAccepted:
+ //case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case DialReceivedEarlyAnswer:
+ switch(newCallState) {
+ case CallerCancel:
+ case DialInProgress:
+ case DialFailed:
+ case DialRejected:
+ case DialEarlyMediaProxySuccess:
+ case DialEarlyMediaProxyFail:
+ case CallAccepted:
+ //case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+/* case DialEarlyMediaProxyRequested:
+ switch(newCallState) {
+ case :
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ }; */
+
+ case DialEarlyMediaProxySuccess:
+ switch(newCallState) {
+ case CallerCancel:
+ case DialInProgress:
+ case DialFailed:
+ case DialRejected:
+ case CallAccepted:
+ //case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case DialEarlyMediaProxyFail:
+ switch(newCallState) {
+ case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case CallAccepted:
+ switch(newCallState) {
+ case CallerCancel:
+ case CallAcceptedMediaProxySuccess:
+ case CallAcceptedMediaProxyFail:
+ case CallActive:
+ case CallerHangup:
+ case CalleeHangup:
+ case LocalHangup:
+ //case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+/* case CallAcceptedMediaProxyRequested:
+ switch(newCallState) {
+ case :
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ }; */
+
+ case CallAcceptedMediaProxySuccess:
+ switch(newCallState) {
+ case CallerCancel:
+ case CallActive:
+ case CallerHangup:
+ case CalleeHangup:
+ case LocalHangup:
+ //case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case CallAcceptedMediaProxyFail:
+ switch(newCallState) {
+ case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case CallActive:
+ switch(newCallState) {
+ case CallerCancel:
+ case CallerHangup:
+ case CalleeHangup:
+ case LocalHangup:
+ //case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case CallerHangup:
+ switch(newCallState) {
+ case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case CalleeHangup:
+ switch(newCallState) {
+ case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case LocalHangup:
+ switch(newCallState) {
+ case CallStop:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case CallStop:
+ switch(newCallState) {
+ case CallStopMediaProxySuccess:
+ case CallStopMediaProxyFail:
+ case CallStopFinal:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+/* case CallStopMediaProxyNotified:
+ switch(newCallState) {
+ case :
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ }; */
+
+ case CallStopMediaProxySuccess:
+ switch(newCallState) {
+ case CallStopFinal:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case CallStopMediaProxyFail:
+ switch(newCallState) {
+ case CallStopFinal:
+ callState = newCallState;
+ return true;
+ default:
+ return false;
+ };
+
+ case CallStopFinal:
+ return false; // no state changes permitted
+
+ default:
+ B2BUA_LOG_ERR("B2BCall in unknown call state %d", callState);
+ return false;
+ };
+};
+
+const Data& B2BCall::getCallStateName(B2BCallState s) {
+ return callStateNames[s];
+};
+
+void B2BCall::setALegSdp(const SdpContents& sdp, const in_addr_t& msgSourceAddress) {
+ // try {
+ mediaManager->setALegSdp(sdp, msgSourceAddress);
+ //} catch (...) {
+ // FIXME - call state
+ // B2BUA_LOG_WARNING, "failed to accept SDP from A leg");
+ //callState = CALL_STOP;
+ //}
+}
+
+void B2BCall::setBLegSdp(const SdpContents& sdp, const in_addr_t& msgSourceAddress) {
+ //try {
+ mediaManager->setBLegSdp(sdp, msgSourceAddress);
+ //} catch (...) {
+ // B2BUA_LOG_WARNING, "failed to accept SDP from B leg");
+ //callState = CALL_STOP;
+ //}
+}
+
+void B2BCall::setBLegAppDialog(MyAppDialog *myAppDialog) {
+ bLegAppDialog = myAppDialog;
+ //mediaManager->setToTag(bLegAppDialog->getDialogId().getLocalTag());
+}
+
+void B2BCall::releaseAppDialog(MyAppDialog *myAppDialog) {
+ if(myAppDialog == aLegAppDialog) {
+ aLegAppDialog = NULL;
+ } else if(myAppDialog == bLegAppDialog) {
+ bLegAppDialog = NULL;
+ } else {
+ B2BUA_LOG_ERR("releaseAppDialog for unknown AppDialog");
+ }
+}
+
+void B2BCall::releaseAppDialogSet(MyAppDialogSet *myAppDialogSet) {
+ if(myAppDialogSet == bLegAppDialogSet) {
+ bLegAppDialogSet = NULL;
+ } else {
+ B2BUA_LOG_ERR("releaseAppDialogSet for unknown AppDialogSet");
+ }
+}
+
+/* This method is called regularly.
+ Instead, the callbacks or setCallState should send a message to
+ B2BUA to say that the call needs attention. */
+void B2BCall::checkProgress(time_t now, bool stopping) {
+ switch(callState) {
+ case NewCall:
+ doNewCall();
+ break;
+ case CallerCancel:
+ doCallerCancel();
+ break;
+ case AuthorizationPending:
+ doAuthorizationPending();
+ break;
+ case AuthorizationSuccess:
+ doAuthorizationSuccess();
+ break;
+ case AuthorizationFail:
+ doAuthorizationFail();
+ break;
+ case MediaProxySuccess:
+ doMediaProxySuccess();
+ break;
+ case MediaProxyFail:
+ doMediaProxyFail();
+ break;
+ case ReadyToDial:
+ doReadyToDial();
+ break;
+ case DialInProgress:
+ // FIXME - route timeout?
+ break;
+ case DialFailed:
+ doDialFailed();
+ break;
+ case DialRejected:
+ doDialRejected();
+ break;
+ case SelectAlternateRoute:
+ doSelectAlternateRoute();
+ break;
+ case DialAborted:
+ doDialAborted();
+ break;
+ /* case DialReceived100:
+ doDialReceived100();
+ break; */
+ case DialReceived180:
+ doDialReceived180();
+ break;
+ /* case CALL_DIAL_183:
+ doCallDial183();
+ break; */
+ case DialReceivedEarlyAnswer:
+ doDialReceivedEarlyAnswer();
+ break;
+ case DialEarlyMediaProxySuccess:
+ doDialEarlyMediaProxySuccess();
+ break;
+ case DialEarlyMediaProxyFail:
+ doDialEarlyMediaProxyFail();
+ break;
+ //case CALL_DIAL_PROGRESS:
+ //doCallDialProgress();
+ //break;
+ case CallAccepted:
+ doCallAccepted();
+ break;
+ case CallAcceptedMediaProxySuccess:
+ doCallAcceptedMediaProxySuccess();
+ break;
+ case CallAcceptedMediaProxyFail:
+ doCallAcceptedMediaProxyFail();
+ break;
+ case CallActive:
+ doCallActive();
+ break;
+ case CallerHangup:
+ case CalleeHangup:
+ case LocalHangup:
+ doHangup();
+ case CallStop:
+ doCallStop();
+ break;
+ case CallStopMediaProxySuccess:
+ doCallStopMediaProxySuccess();
+ break;
+ case CallStopMediaProxyFail:
+ doCallStopMediaProxyFail();
+ break;
+ case CallStopFinal:
+ doCallStopFinal();
+ break;
+ default:
+ B2BUA_LOG_ERR("unknown call state %d", callState);
+ assert(0);
+ break;
+ }
+}
+
+bool B2BCall::isComplete() {
+ return (callState == CallStopFinal);
+}
+
+B2BCall::CallStatus B2BCall::getStatus() {
+ switch(callState) {
+ case NewCall:
+ return PreDial;
+ case CallerCancel:
+ return Finishing;
+ case AuthorizationPending:
+ case AuthorizationSuccess:
+ case AuthorizationFail:
+ case MediaProxySuccess:
+ case MediaProxyFail:
+ return PreDial;
+ case ReadyToDial:
+ case DialInProgress:
+ case DialFailed:
+ case DialRejected:
+ case SelectAlternateRoute:
+ case DialAborted:
+ //case DialReceived100:
+ case DialReceived180:
+ case DialReceivedEarlyAnswer:
+ case DialEarlyMediaProxySuccess:
+ case DialEarlyMediaProxyFail:
+ return Dialing;
+ case CallAccepted:
+ case CallAcceptedMediaProxySuccess:
+ case CallAcceptedMediaProxyFail:
+ case CallActive:
+ return Connected;
+ case CallerHangup:
+ case CalleeHangup:
+ case LocalHangup:
+ case CallStop:
+ case CallStopMediaProxySuccess:
+ case CallStopMediaProxyFail:
+ case CallStopFinal:
+ return Finishing;
+ default:
+ return Unknown;
+ }
+}
+
+void B2BCall::doNewCall() {
+ // Indicate trying
+ ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get());
+ sis->provisional(100);
+ callHandle = authorizationManager.authorizeCall(sourceAddr, destinationAddr, authRealm, authUser, authPassword, srcIp, contextId, accountId, baseIp, controlId, startTime);
+ if(callHandle == NULL) {
+ B2BUA_LOG_WARNING("failed to get callHandle");
+ setCallState(CallStop);
+ } else {
+ setCallState(AuthorizationPending);
+ }
+}
+
+void B2BCall::doCallerCancel() {
+ setClearingReason(NoAnswerCancel, -1);
+ // If B leg dialing, send a CANCEL
+ if(bLegAppDialogSet != NULL) {
+ bLegAppDialogSet->end();
+ }
+ setCallState(CallStop);
+}
+
+void B2BCall::doAuthorizationPending() {
+ switch(callHandle->getAuthResult()) {
+ case CC_PENDING:
+ return;
+ case CC_PERMITTED:
+ setCallState(AuthorizationSuccess);
+ break;
+ default:
+ setCallState(AuthorizationFail);
+ }
+ return;
+}
+
+void B2BCall::doAuthorizationSuccess() {
+ // point to the first route
+ callRoute = callHandle->getRoutes().begin();
+ if(callRoute == callHandle->getRoutes().end()) {
+ appRef1 = Data("");
+ appRef2 = Data("");
+ setClearingReason(InvalidDestination, -1);
+ B2BUA_LOG_NOTICE("no routes returned");
+ ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get());
+ sis->reject(500); // Server internal error
+ setCallState(CallStop);
+ return;
+ }
+ appRef1 = (*callRoute)->getAppRef1();
+ appRef2 = (*callRoute)->getAppRef2();
+ setCallState(MediaProxySuccess);
+ doMediaProxySuccess();
+}
+
+void B2BCall::doAuthorizationFail() {
+ setClearingReason(AuthError, -1);
+ if(aLegAppDialog != NULL) {
+ ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get());
+ switch(callHandle->getAuthResult()) {
+ case CC_AUTH_REQUIRED:
+ sis->reject(401); // Unauthorized/credentials required
+ break;
+ case CC_PAYMENT_REQUIRED:
+ sis->reject(402); // Payment required
+ break;
+ case CC_REQUEST_DENIED:
+ case CC_IP_DENIED:
+ sis->reject(403); // Permission denied/forbidden
+ break;
+ case CC_ERROR:
+ sis->reject(500); // Server internal error
+ break;
+ case CC_INVALID:
+ sis->reject(403); // Forbidden
+ break;
+ case CC_DESTINATION_INCOMPLETE:
+ sis->reject(484); // Incomplete
+ break;
+ case CC_DESTINATION_INVALID:
+ sis->reject(404); // User doesn't exist
+ break;
+ case CC_TIMEOUT:
+ sis->reject(500); // Server internal error
+ break;
+ default:
+ sis->reject(500); // Server internal error
+ }
+ }
+ setCallState(CallStop);
+}
+
+void B2BCall::doMediaProxySuccess() {
+ setCallState(ReadyToDial);
+ doReadyToDial();
+}
+
+void B2BCall::doMediaProxyFail() {
+ setClearingReason(AuthError, -1);
+ B2BUA_LOG_ERR("failed to prepare media proxy");
+ setCallState(CallStop);
+}
+
+void B2BCall::doReadyToDial() {
+ // Media Proxy is ready, now we can create the B-leg and send an INVITE
+ try {
+ //SharedPtr<UserProfile> outboundUserProfile(new UserProfile);
+ SharedPtr<UserProfile> outboundUserProfile(dum.getMasterUserProfile());
+ outboundUserProfile->setDefaultFrom((*callRoute)->getSourceAddr());
+ outboundUserProfile->setDigestCredential((*callRoute)->getAuthRealm(), (*callRoute)->getAuthUser(), (*callRoute)->getAuthPass());
+ if((*callRoute)->getOutboundProxy() != Uri())
+ outboundUserProfile->setOutboundProxy((*callRoute)->getOutboundProxy());
+ bLegAppDialogSet = new MyAppDialogSet(dum, this, outboundUserProfile);
+
+ SharedPtr<SipMessage> msgB;
+ SdpContents *initialOffer = (SdpContents *)mediaManager->getALegSdp().clone();
+ msgB = dum.makeInviteSession((*callRoute)->getDestinationAddr(), outboundUserProfile, initialOffer, bLegAppDialogSet);
+ delete initialOffer;
+ dum.send(msgB);
+
+ setCallState(DialInProgress);
+ } catch (...) {
+ B2BUA_LOG_WARNING("failed to create new InviteSession");
+ setClearingReason(AuthError, -1);
+ setCallState(DialFailed);
+ return;
+ }
+}
+
+// A route failed (timeout, ICMP, invalid domain, etc), try the next route
+void B2BCall::doDialFailed() {
+ if(bLegAppDialogSet != NULL) {
+ bLegAppDialogSet->end();
+ bLegAppDialogSet->setB2BCall(NULL);
+ }
+ bLegAppDialogSet = NULL;
+ bLegAppDialog = NULL;
+ failureStatusCode = -1;
+ //setClearingReason(AuthError, -1);
+ setCallState(SelectAlternateRoute);
+ doSelectAlternateRoute();
+}
+
+// A route rejected the call, try the next route
+void B2BCall::doDialRejected() {
+ switch(failureStatusCode) {
+ case -1:
+ //setClearingReason(AuthError, -1);
+ setCallState(SelectAlternateRoute);
+ doSelectAlternateRoute();
+ break;
+ //case 480: // Temporarily not available
+ case 486: // Busy
+ //case 600: // Busy everywhere
+ //case 603: // Decline
+ // We will consider all of the above to be `BUSY'
+ setClearingReason(RejectBusy, failureStatusCode);
+ setCallState(DialAborted);
+ doDialAborted();
+ break;
+ default:
+ //setClearingReason(RejectOther, failureStatusCode);
+ if(bLegAppDialogSet != NULL) {
+ bLegAppDialogSet->end();
+ bLegAppDialogSet->setB2BCall(NULL);
+ }
+ bLegAppDialogSet = NULL;
+ bLegAppDialog = NULL;
+ setCallState(SelectAlternateRoute);
+ doSelectAlternateRoute();
+ break;
+ }
+}
+
+void B2BCall::doSelectAlternateRoute() {
+ callRoute++;
+ if(callRoute == callHandle->getRoutes().end()) {
+ B2BUA_LOG_DEBUG("no routes remaining, aborting attempt");
+ setCallState(DialAborted);
+ doDialAborted();
+ return;
+ }
+ appRef1 = (*callRoute)->getAppRef1();
+ appRef2 = (*callRoute)->getAppRef2();
+ setCallState(ReadyToDial);
+ doReadyToDial();
+}
+
+void B2BCall::doDialAborted() {
+ ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get());
+ if(failureStatusCode == -1) {
+ setClearingReason(AuthError, failureStatusCode); // FIXME
+ sis->reject(503);
+ } else {
+ setClearingReason(RejectOther, failureStatusCode);
+ sis->reject(failureStatusCode);
+ }
+ setCallState(CallStop);
+ doCallStop();
+}
+
+
+/* void B2BCall::doDialReceived100() {
+ setCallState(DialInProgress);
+} */
+
+void B2BCall::doDialReceived180() {
+ if(setCallState(DialInProgress)) {
+ ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get());
+ sis->provisional(180);
+ }
+}
+
+/* void B2BCall::doCallDial183() {
+ // FIXME - do nothing for now, unless there is an offer
+ setCallState(DialInProgress);
+} */
+
+void B2BCall::doDialReceivedEarlyAnswer() {
+ if(earlyAnswerSent == true) {
+ setCallState(DialInProgress);
+ return;
+ }
+ ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get());
+ //sis->provideAnswer(*bLegSdp);
+ try {
+ sis->provideAnswer(mediaManager->getBLegSdp());
+ } catch (...) {
+ B2BUA_LOG_WARNING("failed to get B Leg SDP");
+ setClearingReason(AuthError, -1);
+ setCallState(DialEarlyMediaProxyFail);
+ return;
+ }
+ //sis->provisional(183);
+ //earlyAnswerSent = true;
+ setCallState(DialEarlyMediaProxySuccess);
+ doDialEarlyMediaProxySuccess();
+}
+
+void B2BCall::doDialEarlyMediaProxySuccess() {
+ ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get());
+ sis->provisional(183);
+ earlyAnswerSent = true;
+ setCallState(DialInProgress);
+}
+
+void B2BCall::doDialEarlyMediaProxyFail() {
+ setClearingReason(AuthError, -1);
+ ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get());
+ sis->reject(500); // FIXME - error code
+ setCallState(CallStop);
+}
+
+void B2BCall::doCallAccepted() {
+ ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get());
+ if(!earlyAnswerSent) {
+ try {
+ SdpContents& sdp = mediaManager->getBLegSdp();
+ sis->provideAnswer(sdp); // FIXME - for re-INVITE
+ } catch(...) {
+ //setClearingReason(Error, -1);
+ setClearingReason(AnsweredError, -1);
+ setCallState(CallAcceptedMediaProxyFail);
+ return;
+ }
+ }
+ setCallState(CallAcceptedMediaProxySuccess);
+ doCallAcceptedMediaProxySuccess();
+}
+
+void B2BCall::doCallAcceptedMediaProxySuccess() {
+ ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get());
+ sis->accept();
+ time(&connectTime);
+ callHandle->connect(&connectTime);
+ setCallState(CallActive);
+}
+
+void B2BCall::doCallAcceptedMediaProxyFail() {
+ setClearingReason(AnsweredError, -1);
+ ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get());
+ sis->reject(500); // FIXME - error codes
+ setCallState(CallStop);
+}
+
+void B2BCall::doCallActive() {
+ if(callHandle->mustHangup()) {
+ B2BUA_LOG_DEBUG("ending a call due to mustHangup()");
+ setClearingReason(AnsweredLimit, -1);
+ setCallState(LocalHangup);
+ }
+}
+
+void B2BCall::doHangup() {
+ setCallState(CallStop);
+}
+
+void B2BCall::doCallStop() {
+// setClearingReason(AnsweredUnknown, -1);
+ time(&finishTime);
+ if(callHandle != NULL) {
+ if(connectTime != 0)
+ callHandle->finish(&finishTime);
+ else
+ callHandle->fail(&finishTime);
+ }
+ if(aLegAppDialog != NULL) {
+ ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get());
+ sis->end();
+ }
+ if(bLegAppDialogSet != NULL) {
+ bLegAppDialogSet->end();
+ }
+ writeCDR();
+ setCallState(CallStopFinal);
+}
+
+void B2BCall::doCallStopMediaProxySuccess() {
+ setCallState(CallStopFinal);
+}
+
+void B2BCall::doCallStopMediaProxyFail() {
+ setCallState(CallStopFinal);
+}
+
+void B2BCall::doCallStopFinal() {
+ // do nothing, the call should be deleted shortly
+ if(callHandle != NULL) {
+ delete callHandle;
+ callHandle = NULL;
+ }
+}
+
+void B2BCall::setClearingReason(FullClearingReason reason, int code) {
+ // has a reason already been specified? If so, leave it alone
+ if(fullClearingReason != Unset)
+ return;
+
+ fullClearingReason = reason;
+ if(fullClearingReason == RejectOther)
+ rejectOtherCode = code;
+ switch(fullClearingReason) {
+ case InvalidDestination:
+ case AuthError:
+ basicClearingReason = Error;
+ break;
+ case NoAnswerCancel:
+ case NoAnswerTimeout:
+ basicClearingReason = NoAnswer;
+ break;
+ case NoAnswerError:
+ basicClearingReason = Error;
+ break;
+ case RejectBusy:
+ basicClearingReason = Busy;
+ break;
+ case RejectOther:
+ switch(rejectOtherCode) {
+ /* case 503: // ambiguous, could also indicate out of funds with a carrier
+ basicClearingReason = Congestion;
+ break; */
+ default:
+ basicClearingReason = Error;
+ break;
+ };
+ break;
+ case AnsweredALegHangup:
+ case AnsweredBLegHangup:
+ case AnsweredLimit:
+ case AnsweredShutdown:
+ case AnsweredError:
+ case AnsweredUnknown:
+ basicClearingReason = Answered;
+ break;
+ default:
+ basicClearingReason = Error;
+ break;
+ };
+}
+
+void B2BCall::setClearingReasonMediaFail() {
+ if(connectTime == 0)
+ setClearingReason(NoAnswerError, -1);
+ else
+ setClearingReason(AnsweredError, -1);
+}
+
+void B2BCall::writeCDR() {
+ std::ostringstream cdrStream;
+ cdrStream << sourceAddr << ",";
+ cdrStream << destinationAddr << ",";
+ cdrStream << contextId << ",";
+ cdrStream << '"' << basicClearingReasonName[basicClearingReason] << '"' << ",";
+ cdrStream << fullClearingReason << ",";
+ cdrStream << rejectOtherCode << ",";
+ cdrStream << startTime << ",";
+ if(connectTime == 0)
+ cdrStream << ",";
+ else
+ cdrStream << connectTime << ",";
+ cdrStream << finishTime << ",";
+ cdrStream << finishTime - startTime << ",";
+ if(connectTime != 0)
+ cdrStream << finishTime - connectTime;
+ cdrStream << ",";
+ cdrStream << appRef1 << "," << appRef2 << ",";
+ cdrHandler.handleRecord(cdrStream.str());
+}
+
+/* void B2BCall::onTrying() {
+ setCallState(DialReceived100);
+} */
+
+void B2BCall::onRinging() {
+ //callState = CALL_DIAL_180;
+ setCallState(DialReceived180);
+}
+
+//void B2BCall::onSessionProgress() {
+ //callState = CALL_DIAL_183;
+ //setCallState(DialReceived183);
+//}
+
+void B2BCall::onEarlyMedia(const SdpContents& sdp, const in_addr_t& msgSourceAddress) {
+ setCallState(DialReceivedEarlyAnswer);
+ try {
+ setBLegSdp(sdp, msgSourceAddress);
+ } catch (...) {
+ // FIXME
+ setCallState(DialEarlyMediaProxyFail);
+ B2BUA_LOG_WARNING("onEarlyMedia: exception while calling setBLegSdp");
+ setClearingReason(NoAnswerError, -1);
+ //setCallState(CallStop);
+ return;
+ }
+ //ServerInviteSession *sis = (ServerInviteSession *)(aLegAppDialog->getInviteSession().get());
+ //sis->provideOffer(sdp);
+ //sis->provisional(183);
+}
+
+void B2BCall::onCancel() {
+ //callState = CALL_CANCEL;
+ setCallState(CallerCancel);
+}
+
+// Dial Failure due to ICMP, Timeout, protocol error or other reason
+void B2BCall::onFailure(MyAppDialog *myAppDialog) {
+
+ // If we are about to try another route, bLegAppDialogSet will be NULL
+ if(bLegAppDialogSet == NULL)
+ return;
+
+ // No need to do anything if it's already been rejected
+ if(callState == DialRejected)
+ return;
+
+ if(setCallState(DialFailed)) {
+ }
+}
+
+// Dial failure due to rejection by remote party
+void B2BCall::onRejected(int statusCode, const Data& reason) {
+ if(setCallState(DialRejected)) {
+ failureStatusCode = statusCode;
+ failureReason = new Data(reason);
+ }
+}
+
+
+void B2BCall::onOffer(MyAppDialog *myAppDialog, const SdpContents& sdp, const in_addr_t& msgSourceAddress) {
+ InviteSession *otherInviteSession = NULL; // used to relay SDP to
+ // other party
+ SdpContents *otherSdp = NULL;
+ if(myAppDialog == aLegAppDialog) {
+ B2BUA_LOG_DEBUG("received SDP offer from A leg");
+ try {
+ setALegSdp(sdp, msgSourceAddress);
+ } catch (...) {
+ // FIXME -
+ setClearingReasonMediaFail();
+ B2BUA_LOG_WARNING("onOffer: exception while calling setALegSdp");
+ setCallState(CallStop);
+ return;
+ }
+ if(bLegAppDialog != NULL) {
+ otherInviteSession = (InviteSession *)(bLegAppDialog->getInviteSession().get());
+ otherSdp = (SdpContents *)mediaManager->getALegSdp().clone();
+ }
+ } else if(myAppDialog == bLegAppDialog) {
+ B2BUA_LOG_DEBUG("received SDP offer from B leg");
+ try {
+ setBLegSdp(sdp, msgSourceAddress);
+ } catch (...) {
+ // FIXME
+ setClearingReasonMediaFail();
+ B2BUA_LOG_WARNING("onOffer: exception while calling setBLegSdp");
+ setCallState(CallStop);
+ return;
+ }
+ if(aLegAppDialog != NULL) {
+ otherInviteSession = (InviteSession *)(aLegAppDialog->getInviteSession().get());
+ otherSdp = (SdpContents *)mediaManager->getBLegSdp().clone();
+ }
+ } else {
+ B2BUA_LOG_ERR("onOffer: unrecognised myAppDialog");
+ throw new exception;
+ }
+ if(callState == CallActive) {
+ // Must be a re-INVITE, relay to other party
+ // FIXME - change state
+ B2BUA_LOG_DEBUG("processing a re-INVITE");
+ if(otherInviteSession != NULL)
+ otherInviteSession->provideOffer(*otherSdp);
+ else {
+ B2BUA_LOG_ERR("onOffer: otherInviteSession == NULL");
+ throw new exception; // FIXME
+ }
+ }
+ if(otherSdp != NULL)
+ delete otherSdp;
+}
+
+void B2BCall::onAnswer(MyAppDialog *myAppDialog, const SdpContents& sdp, const in_addr_t& msgSourceAddress) {
+ mediaManager->setToTag(bLegAppDialog->getDialogId().getLocalTag());
+ if(callState != CallActive) {
+ B2BUA_LOG_DEBUG("received answer");
+ // Answer to original INVITE
+ //callState = CALL_ANSWERED;
+ setCallState(CallAccepted);
+ time(&connectTime);
+ try {
+ setBLegSdp(sdp, msgSourceAddress);
+ } catch (...) {
+ // FIXME - stop the call
+ setClearingReasonMediaFail();
+ B2BUA_LOG_WARNING("onAnswer: exception while processing SDP");
+ setCallState(CallStop);
+ return;
+ }
+ } else {
+ // Answer to re-INVITE
+ InviteSession *inviteSession = NULL;
+ SdpContents *otherSdp = NULL;
+ if(myAppDialog == aLegAppDialog) {
+ B2BUA_LOG_DEBUG("answer received from A leg");
+ setALegSdp(sdp, msgSourceAddress);
+ inviteSession = (InviteSession *)(bLegAppDialog->getInviteSession().get());
+ otherSdp = (SdpContents *)mediaManager->getALegSdp().clone();
+ } else {
+ B2BUA_LOG_DEBUG("answer received from B leg");
+ setBLegSdp(sdp, msgSourceAddress);
+ inviteSession = (InviteSession *)(aLegAppDialog->getInviteSession().get());
+ otherSdp = (SdpContents *)mediaManager->getBLegSdp().clone();
+ }
+ inviteSession->provideAnswer(*otherSdp);
+ if(otherSdp != NULL)
+ delete otherSdp;
+ }
+}
+
+void B2BCall::onMediaTimeout() {
+ B2BUA_LOG_NOTICE("call hangup due to media timeout");
+ if(connectTime == 0)
+ setClearingReason(AnsweredNoMedia, -1);
+ else
+ setClearingReason(NoAnswerError, -1);
+ time(&finishTime);
+ setCallState(CallStop);
+}
+
+void B2BCall::onHangup(MyAppDialog *myAppDialog) {
+ if(myAppDialog == aLegAppDialog) {
+ B2BUA_LOG_DEBUG("call hung up by a leg");
+ setClearingReason(AnsweredALegHangup, -1);
+ setCallState(CallerHangup);
+ time(&finishTime);
+ } else if(myAppDialog == bLegAppDialog) {
+ B2BUA_LOG_DEBUG("call hung up by b leg");
+ setClearingReason(AnsweredBLegHangup, -1);
+ setCallState(CalleeHangup);
+ time(&finishTime);
+ } else {
+ // possible termination of B leg after route fail
+ B2BUA_LOG_WARNING("B2BCall::onHangup(): unrecognised MyAppDialog");
+ }
+ //time(&finishTime);
+ //setCallState(CallStop);
+}
+
+void B2BCall::onStopping() {
+ // FIXME - should any states be handled differently?
+ switch(callState) {
+ case CallerCancel:
+ case AuthorizationFail:
+ case MediaProxyFail:
+ case DialEarlyMediaProxyFail:
+ case CallAcceptedMediaProxyFail:
+ case CallerHangup:
+ case CalleeHangup:
+ case LocalHangup:
+ case CallStop:
+ case CallStopMediaProxySuccess:
+ case CallStopMediaProxyFail:
+ case CallStopFinal:
+ return;
+ default:
+ onHangup(NULL);
+ }
+}
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/B2BCall.hxx b/b2bua/B2BCall.hxx
new file mode 100644
index 0000000..f941285
--- /dev/null
+++ b/b2bua/B2BCall.hxx
@@ -0,0 +1,308 @@
+
+#ifndef __B2BCall_h
+#define __B2BCall_h
+
+/* B2BCall models a bridged call between a caller and a callee
+*/
+
+#include "rutil/Data.hxx"
+#include "resip/dum/DialogUsageManager.hxx"
+
+namespace b2bua
+{
+
+class B2BCall;
+class MyDialogSetHandler;
+
+}
+
+#include "AuthorizationManager.hxx"
+#include "CallHandle.hxx"
+#include "CDRHandler.hxx"
+#include "MediaManager.hxx"
+#include "MyAppDialog.hxx"
+
+
+namespace b2bua
+{
+
+class B2BCall {
+
+protected:
+
+ typedef enum B2BCallState {
+ NewCall = 0, // just started
+ CallerCancel, // CANCEL received from A leg
+ AuthorizationPending,
+ AuthorizationSuccess,
+ AuthorizationFail,
+// RoutesPending, // routes requested
+// RoutesSuccess,
+// RoutesFail,
+// MediaProxyPending, // Media Proxy requested
+ MediaProxySuccess,
+ MediaProxyFail,
+ ReadyToDial, // Route ready
+ DialInProgress, // INVITE sent
+ DialFailed, // Network error, e.g. ICMP
+ DialRejected, // SIP error received
+ // error code in data member
+ // failureStatusCode
+ SelectAlternateRoute, // Need to select another
+ // route
+ DialAborted, // No other carriers
+ // available, or a failure
+ // that doesn't require us
+ // to try another carrier
+ // e.g. Busy
+// DialReceived100, // 100 response received
+ DialReceived180, // 180 response received
+// DialReceived183, // 183 response received
+ DialReceivedEarlyAnswer, // early answer (SDP) received
+// DialEarlyMediaProxyRequested, // Media proxy requested for
+ // early media
+ DialEarlyMediaProxySuccess, // Media Proxy ready
+ DialEarlyMediaProxyFail, // Media Proxy failed
+ CallAccepted, // 200 received
+// CallAcceptedMediaProxyRequested, // Media proxy requested for
+ // media
+ CallAcceptedMediaProxySuccess, // Media Proxy ready
+ CallAcceptedMediaProxyFail, // Media proxy failed
+ CallActive, // Call in progress
+ CallerHangup, // Caller has hungup
+ CalleeHangup, // Callee has hungup
+ LocalHangup, // B2BUA initiated hangup
+ CallStop, // Call is stopped
+// CallStopMediaProxyNotified, // Media proxy informed
+ CallStopMediaProxySuccess, // Media proxy acknowledged
+ CallStopMediaProxyFail, // Media proxy failed to ack
+ CallStopFinal // Call can be purged from
+ // the system
+ };
+
+ static resip::Data callStateNames[];
+
+ typedef enum BasicClearingReason {
+ NoAnswer = 0, // caller gave up/timeout
+ Busy, // callee indicated busy
+ Congestion, // callee indicated congestion
+ Error, // callee indicated error
+ Answered // call was answered
+ };
+
+ static const char *basicClearingReasonName[];
+
+ typedef enum FullClearingReason {
+ Unset,
+
+ // No attempted
+ InvalidDestination,
+ AuthError,
+
+ // not answered
+ NoAnswerCancel,
+ NoAnswerTimeout,
+ NoAnswerError, // media negotiation failed
+
+ // Rejected
+ RejectBusy,
+ RejectOther, // rejectOtherCode = SIP error code
+
+ // Answered
+ AnsweredALegHangup, // A leg hangup first
+ AnsweredBLegHangup, // B leg hangup first
+ AnsweredLimit, // reached limit
+ AnsweredShutdown, // Answered, B2BUA shutdown
+ AnsweredError, // An error occured, e.g. during a re-INVITE
+ AnsweredNoMedia, // Media stopped
+ AnsweredUnknown // Answered, hangup for unknown reason
+ };
+
+ CDRHandler& cdrHandler;
+ resip::DialogUsageManager& dum;
+ //CallController *callController;
+ AuthorizationManager& authorizationManager;
+
+ //static std::list<B2BCall *> calls;
+
+ // Attributes of the call, from the original INVITE
+ resip::NameAddr sourceAddr;
+ resip::Uri destinationAddr;
+ resip::Data authRealm;
+ resip::Data authUser;
+ resip::Data authPassword;
+ resip::Data srcIp;
+ resip::Data contextId;
+ resip::Data accountId;
+ resip::Data baseIp;
+ resip::Data controlId;
+
+ //int callState;
+
+ B2BCallState callState;
+
+ BasicClearingReason basicClearingReason;
+ FullClearingReason fullClearingReason;
+ int rejectOtherCode;
+
+ // Call time information
+ time_t startTime;
+ time_t connectTime;
+ time_t finishTime;
+
+ // CallHandle from CallController
+ CallHandle *callHandle;
+ std::list<CallRoute *>::iterator callRoute;
+ resip::Data appRef1;
+ resip::Data appRef2;
+
+ // If we are waiting for something, this is the timeout
+ time_t timeout;
+
+ MyAppDialog *aLegAppDialog;
+ MyAppDialog *bLegAppDialog;
+ MyAppDialogSet *bLegAppDialogSet;
+ //resip::SdpContents *aLegSdp; // most recent offer from A leg
+ //resip::SdpContents *bLegSdp; // most recent offer from B leg
+ bool earlyAnswerSent;
+ MediaManager *mediaManager;
+ // resip::SharedPtr<resip::UserProfile> outboundUserProfile;
+
+ int failureStatusCode;
+ resip::Data *failureReason;
+
+ // Returns true if successful, false if new state is not
+ // permitted
+ bool setCallState(B2BCallState newCallState);
+ bool isCallStatePermitted(B2BCallState newCallState);
+ const resip::Data& getCallStateName(B2BCallState s);
+
+ void setALegSdp(const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress);
+ void setBLegSdp(const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress);
+
+ void doNewCall();
+ void doCallerCancel();
+ void doAuthorizationPending();
+ void doAuthorizationSuccess();
+ void doAuthorizationFail();
+ void doMediaProxySuccess();
+ void doMediaProxyFail();
+ void doReadyToDial();
+ void doDialFailed();
+ void doDialRejected();
+ void doSelectAlternateRoute();
+ void doDialAborted();
+ //void doDialReceived100();
+ void doDialReceived180();
+ //void doCallDial183();
+ void doDialReceivedEarlyAnswer();
+ void doDialEarlyMediaProxySuccess();
+ void doDialEarlyMediaProxyFail();
+ void doCallAccepted();
+ void doCallAcceptedMediaProxySuccess();
+ void doCallAcceptedMediaProxyFail();
+ void doCallActive();
+ void doHangup();
+ void doCallStop();
+ void doCallStopMediaProxySuccess();
+ void doCallStopMediaProxyFail();
+ void doCallStopFinal();
+
+ // sets the clearing reason codes if necessary
+ void setClearingReason(FullClearingReason reason, int code);
+ void setClearingReasonMediaFail();
+
+ void writeCDR();
+
+public:
+
+ // More basic then B2BCallState, used for reporting
+ typedef enum CallStatus {
+ PreDial, // the call hasn't started dialing
+ Dialing, // the call is dialing
+ Connected, // the call has connected
+ Finishing, // the call has been hung up
+ Unknown // unknown
+ };
+
+ void checkProgress(time_t now, bool stopping);
+ bool isComplete();
+
+ CallStatus getStatus();
+
+ //static void setDum(resip::DialogUsageManager *dum);
+ //static void setCallController(CallController *callController);
+
+ // B2BCall(MyAppDialog *aLegDialog);
+ B2BCall(CDRHandler& cdrHandler, resip::DialogUsageManager& dum, AuthorizationManager& authorizationManager, MyAppDialog *aLegDialog, const resip::NameAddr& sourceAddr, const resip::Uri& destinationAddr, const resip::Data& authRealm, const resip::Data& authUser, const resip::Data& authPassword, const resip::Data& srcIp, const resip::Data& contextId, const resip::Data& accountId, const resip::Data& baseIp, const resip::Data& controlId);
+ virtual ~B2BCall();
+
+ void setBLegAppDialog(MyAppDialog *myAppDialog);
+
+ // called every time we go through the main program loop
+ //static void checkCalls();
+
+ // For InviteSessionHandler
+ //void onTrying();
+ void onRinging();
+ //void onSessionProgress();
+ void onEarlyMedia(const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress);
+ void onCancel();
+ void onFailure(MyAppDialog *myAppDialog);
+ void onRejected(int statusCode, const resip::Data& reason);
+ void onOffer(MyAppDialog *myAppDialog, const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress);
+ void onAnswer(MyAppDialog *myAppDialog, const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress);
+ void onMediaTimeout();
+ void onHangup(MyAppDialog *myAppDialog);
+
+ // For B2BCallManager
+ void onStopping();
+
+ void releaseAppDialog(MyAppDialog *myAppDialog);
+ void releaseAppDialogSet(MyAppDialogSet *myAppDialogSet);
+
+ friend class MyDialogSetHandler;
+
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/B2BCallManager.cxx b/b2bua/B2BCallManager.cxx
new file mode 100644
index 0000000..c66db5d
--- /dev/null
+++ b/b2bua/B2BCallManager.cxx
@@ -0,0 +1,135 @@
+
+
+#include <syslog.h>
+
+#include "B2BCallManager.hxx"
+#include "Logging.hxx"
+
+using namespace b2bua;
+using namespace resip;
+using namespace std;
+
+B2BCallManager::B2BCallManager(resip::DialogUsageManager& dum, AuthorizationManager *authorizationManager, CDRHandler& cdrHandler) : dum(dum), authorizationManager(authorizationManager), cdrHandler(cdrHandler) {
+ stopping = false;
+ mustStopCalls = false;
+}
+
+B2BCallManager::~B2BCallManager() {
+}
+
+void B2BCallManager::setAuthorizationManager(AuthorizationManager *authorizationManager) {
+ this->authorizationManager = authorizationManager;
+}
+
+TaskManager::TaskResult B2BCallManager::doTaskProcessing() {
+ time_t now;
+
+ if(mustStopCalls) {
+ B2BUA_LOG_NOTICE("notifying calls to stop");
+ list<B2BCall *>::iterator call = calls.begin();
+ while(call != calls.end()) {
+ (*call)->onStopping();
+ call++;
+ }
+ mustStopCalls = false;
+ }
+
+ time(&now);
+ list<B2BCall *>::iterator i = calls.begin();
+ while(i != calls.end()) {
+ (*i)->checkProgress(now, stopping);
+ if((*i)->isComplete()) {
+ B2BCall *call = *i;
+ i++;
+ calls.remove(call);
+ delete call;
+ } else
+ i++;
+ }
+ if(stopping && calls.begin() == calls.end()) {
+ B2BUA_LOG_NOTICE("no (more) calls in progress");
+ return TaskManager::TaskComplete;
+ }
+ return TaskManager::TaskNotComplete;
+}
+
+void B2BCallManager::stop() {
+ stopping = true;
+ mustStopCalls = true;
+}
+
+bool B2BCallManager::isStopping() {
+ return stopping;
+}
+
+void B2BCallManager::onNewCall(MyAppDialog *aLegDialog, const resip::NameAddr& sourceAddr, const resip::Uri& destinationAddr, const resip::Data& authRealm, const resip::Data& authUser, const resip::Data& authPassword, const resip::Data& srcIp, const resip::Data& contextId, const resip::Data& accountId, const resip::Data& baseIp, const resip::Data& controlId) {
+
+ B2BCall *call = new B2BCall(cdrHandler, dum, *authorizationManager, aLegDialog, sourceAddr, destinationAddr, authRealm, authUser, authPassword, srcIp, contextId, accountId, baseIp, controlId);
+
+ calls.push_back(call);
+
+}
+
+void B2BCallManager::logStats() {
+ int preDial = 0, dialing = 0, connected = 0, finishing = 0, unknown = 0;
+ list<B2BCall *>::iterator call = calls.begin();
+ while(call != calls.end()) {
+ switch((*call)->getStatus()) {
+ case B2BCall::PreDial:
+ preDial++;
+ break;
+ case B2BCall::Dialing:
+ dialing++;
+ break;
+ case B2BCall::Connected:
+ connected++;
+ break;
+ case B2BCall::Finishing:
+ finishing++;
+ break;
+ default:
+ unknown++;
+ break;
+ }
+ call++;
+ }
+ B2BUA_LOG_NOTICE("call info: preDial = %d, dialing = %d, connected = %d, finishing = %d, unknown = %d, total = %d", preDial, dialing, connected, finishing, unknown, (preDial + dialing + connected + finishing + unknown));
+}
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/B2BCallManager.hxx b/b2bua/B2BCallManager.hxx
new file mode 100644
index 0000000..b9f7cf7
--- /dev/null
+++ b/b2bua/B2BCallManager.hxx
@@ -0,0 +1,94 @@
+
+#ifndef __B2BCallManager_h
+#define __B2BCallManager_h
+
+#include <fstream>
+#include <list>
+
+
+#include "resip/dum/DialogUsageManager.hxx"
+
+#include "AuthorizationManager.hxx"
+#include "B2BCall.hxx"
+#include "CDRHandler.hxx"
+#include "TaskManager.hxx"
+
+namespace b2bua
+{
+
+class B2BCallManager : public TaskManager::RecurringTask {
+
+protected:
+ resip::DialogUsageManager& dum;
+ AuthorizationManager *authorizationManager;
+
+ std::list<B2BCall *> calls;
+
+ bool stopping;
+ bool mustStopCalls;
+
+ CDRHandler& cdrHandler;
+
+public:
+ B2BCallManager(resip::DialogUsageManager& dum, AuthorizationManager *authorizationManager, CDRHandler& cdrHandler);
+ virtual ~B2BCallManager();
+
+ void setAuthorizationManager(AuthorizationManager *authorizationManager);
+
+ TaskManager::TaskResult doTaskProcessing();
+
+ /**
+ * Stop accepting new calls
+ * Shutdown existing calls
+ * Blocks until all existing calls stopped
+ */
+ void stop();
+ bool isStopping();
+
+ void onNewCall(MyAppDialog *aLegDialog, const resip::NameAddr& sourceAddr, const resip::Uri& destinationAddr, const resip::Data& authRealm, const resip::Data& authUser, const resip::Data& authPassword, const resip::Data& srcIp, const resip::Data& contextId, const resip::Data& accountId, const resip::Data& baseIp, const resip::Data& controlId);
+
+ void logStats();
+
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/B2BUA.cxx b/b2bua/B2BUA.cxx
new file mode 100644
index 0000000..0988b29
--- /dev/null
+++ b/b2bua/B2BUA.cxx
@@ -0,0 +1,111 @@
+
+
+#include "resip/stack/SipMessage.hxx"
+#include "resip/dum/ClientAuthManager.hxx"
+#include "resip/dum/DialogUsageManager.hxx"
+#include "resip/dum/MasterProfile.hxx"
+#include "resip/dum/ServerAuthManager.hxx"
+
+#include "B2BUA.hxx"
+#include "DefaultAuthorizationManager.hxx"
+#include "DialogUsageManagerRecurringTask.hxx"
+#include "Logging.hxx"
+#include "MyAppDialog.hxx"
+#include "MyDialogSetHandler.hxx"
+#include "MyInviteSessionHandler.hxx"
+
+using namespace b2bua;
+using namespace resip;
+using namespace std;
+
+B2BUA::B2BUA(AuthorizationManager *authorizationManager, CDRHandler& cdrHandler) {
+
+ if(authorizationManager == NULL) {
+ authorizationManager = new DefaultAuthorizationManager();
+ }
+
+ taskManager = new TaskManager();
+
+ sipStack = new SipStack();
+ dialogUsageManager = new DialogUsageManager(*sipStack);
+ uasMasterProfile = SharedPtr<MasterProfile>(new MasterProfile);
+ dialogUsageManager->setMasterProfile(uasMasterProfile);
+ auto_ptr<AppDialogSetFactory> myAppDialogSetFactory(new MyAppDialogSetFactory);
+ dialogUsageManager->setAppDialogSetFactory(myAppDialogSetFactory);
+
+ // Set up authentication when we act as UAC
+ auto_ptr<ClientAuthManager> clientAuth(new ClientAuthManager);
+ dialogUsageManager->setClientAuthManager(clientAuth);
+
+ dialogUsageManager->setDialogSetHandler(new MyDialogSetHandler());
+
+ DialogUsageManagerRecurringTask *dialogUsageManagerTask = new DialogUsageManagerRecurringTask(*sipStack, *dialogUsageManager);
+ taskManager->addRecurringTask(dialogUsageManagerTask);
+ callManager = new B2BCallManager(*dialogUsageManager, authorizationManager, cdrHandler);
+ taskManager->addRecurringTask(callManager);
+
+ MyInviteSessionHandler *uas = new MyInviteSessionHandler(*dialogUsageManager, *callManager);
+ dialogUsageManager->setInviteSessionHandler(uas);
+
+}
+
+B2BUA::~B2BUA() {
+}
+
+void B2BUA::setAuthorizationManager(AuthorizationManager *authorizationManager) {
+ this->authorizationManager = authorizationManager;
+ callManager->setAuthorizationManager(authorizationManager);
+}
+
+void B2BUA::run() {
+ taskManager->start();
+}
+
+void B2BUA::logStats() {
+ callManager->logStats();
+}
+
+void B2BUA::stop() {
+ //B2BUA_LOG_CRIT("B2BUA::stop not implemented!");
+ //assert(0);
+ B2BUA_LOG_NOTICE("B2BUA beginning shutdown process");
+ taskManager->stop();
+}
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/B2BUA.hxx b/b2bua/B2BUA.hxx
new file mode 100644
index 0000000..18bb02a
--- /dev/null
+++ b/b2bua/B2BUA.hxx
@@ -0,0 +1,102 @@
+
+#ifndef __B2BUA_h
+#define __B2BUA_h
+
+#include "resip/stack/SipStack.hxx"
+#include "resip/dum/DialogUsageManager.hxx"
+
+#include "B2BCallManager.hxx"
+#include "CDRHandler.hxx"
+#include "DefaultAuthorizationManager.hxx"
+#include "TaskManager.hxx"
+
+namespace b2bua
+{
+
+/**
+ * Provides the framework for a B2BUA and implements the core activities
+ *
+ * Derived classes might extend the way some activities are performed, and
+ * must define ways to initialise the managers required by the application
+ */
+class B2BUA {
+
+protected:
+
+ TaskManager *taskManager;
+
+ B2BCallManager *callManager;
+
+ AuthorizationManager *authorizationManager;
+// AuthorizationManager *authorizationManager;
+// AccountingManager *accountingManager;
+
+// std::list<B2BUACall *> calls;
+
+// MediaManager *mediaManager;
+
+// resip::ServerAuthManager *serverAuthManager;
+// resip::InviteSessionHandler *inviteSessionHandler;
+ resip::SharedPtr<resip::MasterProfile> uasMasterProfile;
+ resip::DialogUsageManager *dialogUsageManager;
+ resip::SipStack *sipStack;
+
+ B2BUA(AuthorizationManager *authorizationManager, CDRHandler& cdrHandler);
+ virtual ~B2BUA();
+ void setAuthorizationManager(AuthorizationManager *authorizationManager);
+
+public:
+ // Run the B2BUA
+ // only returns when B2BUA stops
+ virtual void run();
+
+ // Send some stats about the system to syslog
+ virtual void logStats();
+
+ // Indicate to the B2BUA that it should shutdown cleanly
+ // (stop all calls, wait for all managers to stop)
+ virtual void stop();
+
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/CDRHandler.hxx b/b2bua/CDRHandler.hxx
new file mode 100644
index 0000000..a151404
--- /dev/null
+++ b/b2bua/CDRHandler.hxx
@@ -0,0 +1,81 @@
+
+#ifndef __CDRHandler_h
+#define __CDRHandler_h
+
+#include <fstream>
+#include <iostream>
+#include <time.h>
+
+namespace b2bua
+{
+
+class CDRHandler {
+
+public:
+
+
+ virtual ~CDRHandler() {};
+
+ virtual void handleRecord(const std::string& record) = 0;
+
+};
+
+class DailyCDRHandler : public CDRHandler {
+
+protected:
+ std::string mBasename;
+ int last_write;
+ std::ofstream cdrStream;
+
+ int day_number(struct tm* tm);
+ void updateTime();
+ void initFile(struct tm* tm);
+
+public:
+ DailyCDRHandler(const char* basename);
+ ~DailyCDRHandler();
+ void handleRecord(const std::string& record);
+
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/CallHandle.cxx b/b2bua/CallHandle.cxx
new file mode 100644
index 0000000..ec49cb1
--- /dev/null
+++ b/b2bua/CallHandle.cxx
@@ -0,0 +1,48 @@
+
+#include "CallHandle.hxx"
+
+using namespace b2bua;
+
+CallRoute::~CallRoute() {
+}
+
+CallHandle::~CallHandle() {
+}
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/CallHandle.hxx b/b2bua/CallHandle.hxx
new file mode 100644
index 0000000..d14031e
--- /dev/null
+++ b/b2bua/CallHandle.hxx
@@ -0,0 +1,101 @@
+
+#ifndef __CallHandle_h
+#define __CallHandle_h
+
+#include <iostream>
+#include <list>
+
+#include "resip/stack/NameAddr.hxx"
+#include "resip/stack/Uri.hxx"
+#include "rutil/Data.hxx"
+#include "rutil/SharedPtr.hxx"
+
+namespace b2bua
+{
+
+#define CC_PERMITTED 0 // Call is permitted
+#define CC_AUTH_REQUIRED 1 // Auth is required
+#define CC_PAYMENT_REQUIRED 2 // Payment is required
+#define CC_IP_DENIED 3 // IP is blocked/unrecognised
+#define CC_ERROR 4 // Server error
+#define CC_INVALID 5 // Request is invalid
+#define CC_PENDING 6 // Waiting for server
+#define CC_DESTINATION_INCOMPLETE 7 // Destination number too short
+#define CC_DESTINATION_INVALID 8 // Destination invalid
+#define CC_TIMEOUT 9 // Timeout waiting for server
+#define CC_USER_UNKNOWN 10 // User unknown
+#define CC_REALM_UNKNOWN 11 // Realm unknown
+#define CC_REQUEST_DENIED 12 // Request denied for
+ // administrative reason
+
+class CallRoute {
+public:
+ virtual ~CallRoute();
+ virtual const resip::Data& getAppRef1() = 0;
+ virtual const resip::Data& getAppRef2() = 0;
+ virtual const resip::Data& getAuthRealm() = 0;
+ virtual const resip::Data& getAuthUser() = 0;
+ virtual const resip::Data& getAuthPass() = 0;
+ virtual const resip::NameAddr& getSourceAddr() = 0;
+ virtual const resip::NameAddr& getDestinationAddr() = 0;
+ virtual const resip::Uri& getOutboundProxy() = 0;
+ virtual const bool isSrvQuery() = 0;
+};
+
+class CallHandle {
+public:
+ virtual ~CallHandle();
+ virtual int getAuthResult() = 0;
+ virtual const resip::Data& getRealm() = 0; // Realm for client auth,
+ // if we require further auth
+ virtual time_t getHangupTime() = 0; // The time to hangup,
+ // 0 for no limit
+ virtual bool mustHangup() = 0;
+ virtual void connect(time_t *connectTime) = 0; // The call connected
+ virtual void fail(time_t *finishTime) = 0; // The attempt failed, or
+ // the caller gave up
+ virtual void finish(time_t *finishTime) = 0; // The call hungup
+ virtual std::list<CallRoute *>& getRoutes() = 0;
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/DailyCDRHandler.cxx b/b2bua/DailyCDRHandler.cxx
new file mode 100644
index 0000000..f0ffaf9
--- /dev/null
+++ b/b2bua/DailyCDRHandler.cxx
@@ -0,0 +1,93 @@
+
+#include "CDRHandler.hxx"
+#include "Logging.hxx"
+
+using namespace b2bua;
+
+DailyCDRHandler::DailyCDRHandler(const char* basename) :
+ mBasename(basename),
+ last_write(0) {
+
+}
+
+DailyCDRHandler::~DailyCDRHandler() {
+ if(cdrStream.is_open())
+ cdrStream.close();
+}
+
+void DailyCDRHandler::handleRecord(const std::string& record) {
+
+ // First check the time
+ updateTime();
+
+ // Now write to file
+ cdrStream << record << std::endl;
+ cdrStream.flush();
+}
+
+int DailyCDRHandler::day_number(struct tm* tm) {
+ return (tm->tm_year + 1900) * 10000 + ((tm->tm_mon + 1) * 100) + tm->tm_mday;
+}
+
+void DailyCDRHandler::updateTime() {
+ time_t now;
+ time(&now);
+ struct tm* tm = gmtime(&now);
+ int x = day_number(tm);
+ if(x > last_write) {
+ last_write = x;
+ initFile(tm);
+ }
+}
+
+void DailyCDRHandler::initFile(struct tm* tm) {
+ if(cdrStream.is_open()) {
+ cdrStream.close();
+ }
+ char buf[200];
+ sprintf(buf, "%s-%04d-%02d-%02d.csv", mBasename.c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
+ cdrStream.open(buf, std::ios::out | std::ios::app);
+ if(!cdrStream.is_open()) {
+ B2BUA_LOG_ERR("Failed to open CDR file");
+ throw;
+ }
+}
+
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/DefaultAuthorizationManager.cxx b/b2bua/DefaultAuthorizationManager.cxx
new file mode 100644
index 0000000..b0ba6b0
--- /dev/null
+++ b/b2bua/DefaultAuthorizationManager.cxx
@@ -0,0 +1,60 @@
+
+
+
+#include "DefaultAuthorizationManager.hxx"
+#include "Logging.hxx"
+
+using namespace b2bua;
+
+DefaultAuthorizationManager::DefaultAuthorizationManager() {
+}
+
+
+void DefaultAuthorizationManager::getAuthorization() {
+ B2BUA_LOG_CRIT("DefaultAuthorizationManager::getAuthorization not implemented");
+ assert(0);
+}
+
+CallHandle *DefaultAuthorizationManager::authorizeCall(const resip::NameAddr& sourceAddr, const resip::Uri& destinationAddr, const resip::Data& authRealm, const resip::Data& authUser, const resip::Data& authPass, const resip::Data& srcIp, const resip::Data& contextId, const resip::Data& accountId, const resip::Data& baseIp, const resip::Data& controlId, time_t startTime) {
+ B2BUA_LOG_CRIT("DefaultAuthorizationManager::authorizeCall not implemented");
+ assert(0);
+ return NULL;
+}
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/DefaultAuthorizationManager.hxx b/b2bua/DefaultAuthorizationManager.hxx
new file mode 100644
index 0000000..9f8f657
--- /dev/null
+++ b/b2bua/DefaultAuthorizationManager.hxx
@@ -0,0 +1,60 @@
+
+#ifndef __DefaultAuthorizationManager_h
+#define __DefaultAuthorizationManager_h
+
+
+#include "AuthorizationManager.hxx"
+#include "CallHandle.hxx"
+
+namespace b2bua
+{
+
+class DefaultAuthorizationManager : public AuthorizationManager {
+
+public:
+ DefaultAuthorizationManager();
+ void getAuthorization();
+ CallHandle *authorizeCall(const resip::NameAddr& sourceAddr, const resip::Uri& destinationAddr, const resip::Data& authRealm, const resip::Data& authUser, const resip::Data& authPass, const resip::Data& srcIp, const resip::Data& contextId, const resip::Data& accountId, const resip::Data& baseIp, const resip::Data& controlId, time_t startTime);
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/DialogUsageManagerRecurringTask.cxx b/b2bua/DialogUsageManagerRecurringTask.cxx
new file mode 100644
index 0000000..4068e17
--- /dev/null
+++ b/b2bua/DialogUsageManagerRecurringTask.cxx
@@ -0,0 +1,91 @@
+
+
+#include "resip/dum/DialogUsageManager.hxx"
+
+#include "DialogUsageManagerRecurringTask.hxx"
+#include "Logging.hxx"
+#include "TaskManager.hxx"
+
+using namespace b2bua;
+using namespace resip;
+using namespace std;
+
+DialogUsageManagerRecurringTask::DialogUsageManagerRecurringTask(resip::SipStack& sipStack, resip::DialogUsageManager& dum) : sipStack(sipStack), dum(dum) {
+ stopping = false;
+}
+
+TaskManager::TaskResult DialogUsageManagerRecurringTask::doTaskProcessing() {
+ FdSet fdset;
+ sipStack.buildFdSet(fdset);
+ // FIXME - allow time for other tasks
+ int err = fdset.selectMilliSeconds(resipMin((int)sipStack.getTimeTillNextProcessMS(), 50));
+ if(err == -1) {
+ if(errno != EINTR) {
+ B2BUA_LOG_ERR("fdset.select returned error code %d", err);
+ assert(0); // FIXME
+ }
+ }
+ // Process all SIP stack activity
+ sipStack.process(fdset);
+ // Process all DUM activity
+ //try {
+ while(dum.process());
+ //} catch(...) {
+ // B2BUA_LOG_ERR("Exception in dum.process(), continuing anyway");
+ //}
+
+ // FIXME If sipStack and dum are finished, then we should return TaskDone
+ if(!stopping)
+ return TaskManager::TaskNotComplete;
+
+ time_t t;
+ time(&t);
+ if(t > stopTime)
+ return TaskManager::TaskIndefinite;
+ else
+ return TaskManager::TaskNotComplete;
+}
+
+void DialogUsageManagerRecurringTask::stop() {
+ stopping = true;
+ time(&stopTime);
+ stopTime += STOP_TIMEOUT;
+}
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/DialogUsageManagerRecurringTask.hxx b/b2bua/DialogUsageManagerRecurringTask.hxx
new file mode 100644
index 0000000..821d175
--- /dev/null
+++ b/b2bua/DialogUsageManagerRecurringTask.hxx
@@ -0,0 +1,72 @@
+
+#ifndef __DialogUsageManagerRecurringTask_h
+#define __DialogUsageManagerRecurringTask_h
+
+#include "resip/stack/SipStack.hxx"
+#include "resip/dum/DialogUsageManager.hxx"
+
+#include "TaskManager.hxx"
+
+namespace b2bua
+{
+
+#define STOP_TIMEOUT 3 // how many seconds to wait before shutdown
+
+class DialogUsageManagerRecurringTask : public TaskManager::RecurringTask {
+
+protected:
+ resip::SipStack& sipStack;
+ resip::DialogUsageManager& dum;
+ bool stopping;
+ time_t stopTime;
+
+public:
+ DialogUsageManagerRecurringTask(resip::SipStack& sipStack, resip::DialogUsageManager& dum);
+ TaskManager::TaskResult doTaskProcessing();
+
+ // let's the task know the application would like to stop soon
+ void stop();
+
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/DummyRegistrationPersistenceManager.cxx b/b2bua/DummyRegistrationPersistenceManager.cxx
new file mode 100644
index 0000000..bf54561
--- /dev/null
+++ b/b2bua/DummyRegistrationPersistenceManager.cxx
@@ -0,0 +1,75 @@
+
+
+#include "DummyRegistrationPersistenceManager.hxx"
+
+using namespace b2bua;
+
+void DummyRegistrationPersistenceManager::addAor(const resip::Uri& aor, const resip::ContactList contacts = resip::ContactList()) {
+}
+
+void DummyRegistrationPersistenceManager::removeAor(const resip::Uri& aor) {
+}
+
+bool DummyRegistrationPersistenceManager::aorIsRegistered(const resip::Uri& aor) {
+ return false;
+}
+
+void DummyRegistrationPersistenceManager::lockRecord(const resip::Uri& aor) {
+}
+
+void DummyRegistrationPersistenceManager::unlockRecord(const resip::Uri& aor) {
+}
+
+resip::RegistrationPersistenceManager::UriList DummyRegistrationPersistenceManager::getAors() {
+ return resip::RegistrationPersistenceManager::UriList();
+}
+
+resip::RegistrationPersistenceManager::update_status_t DummyRegistrationPersistenceManager::updateContact(const resip::Uri& aor, const resip::Uri& contact, time_t expires, float q) {
+ return CONTACT_CREATED;
+}
+
+void DummyRegistrationPersistenceManager::removeContact(const resip::Uri& aor, const resip::Uri& contact) {
+}
+
+resip::ContactList DummyRegistrationPersistenceManager::getContacts(const resip::Uri& aor) {
+ return resip::ContactList();
+}
+
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/DummyRegistrationPersistenceManager.hxx b/b2bua/DummyRegistrationPersistenceManager.hxx
new file mode 100644
index 0000000..1e9caa7
--- /dev/null
+++ b/b2bua/DummyRegistrationPersistenceManager.hxx
@@ -0,0 +1,67 @@
+
+#ifndef __DummyRegistrationPersistenceManager_h
+#define __DummyRegistrationPersistenceManager_h
+
+#include "resip/dum/ContactInstanceRecord.hxx"
+#include "resip/dum/RegistrationPersistenceManager.hxx"
+
+namespace b2bua
+{
+
+class DummyRegistrationPersistenceManager : public resip::RegistrationPersistenceManager {
+public:
+
+ void addAor(const resip::Uri& aor, const resip::ContactList contacts);
+ void removeAor(const resip::Uri& aor);
+ bool aorIsRegistered(const resip::Uri& aor);
+ void lockRecord(const resip::Uri& aor);
+ void unlockRecord(const resip::Uri& aor);
+ UriList getAors();
+ update_status_t updateContact(const resip::Uri& aor, const resip::Uri& contact, time_t expires, float q = -1);
+ void removeContact(const resip::Uri& aor, const resip::Uri& contact);
+ resip::ContactList getContacts(const resip::Uri& aor);
+
+
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/DummyServerRegistrationHandler.cxx b/b2bua/DummyServerRegistrationHandler.cxx
new file mode 100644
index 0000000..eabe5d7
--- /dev/null
+++ b/b2bua/DummyServerRegistrationHandler.cxx
@@ -0,0 +1,34 @@
+
+
+#include "resip/stack/SipMessage.hxx"
+
+#include "resip/dum/ServerRegistration.hxx"
+
+#include "DummyServerRegistrationHandler.hxx"
+#include "Logging.hxx"
+
+using namespace b2bua;
+using namespace resip;
+using namespace std;
+
+void DummyServerRegistrationHandler::onRefresh(ServerRegistrationHandle sr, const SipMessage& reg) {
+ sr->accept(200);
+}
+
+void DummyServerRegistrationHandler::onRemove(ServerRegistrationHandle sr, const SipMessage& reg) {
+ sr->accept(200);
+}
+
+void DummyServerRegistrationHandler::onRemoveAll(ServerRegistrationHandle sr, const SipMessage& reg) {
+ sr->accept(200);
+}
+
+void DummyServerRegistrationHandler::onAdd(ServerRegistrationHandle sr, const SipMessage& reg) {
+ B2BUA_LOG_INFO("client trying to register, username=%s", reg.header(h_From).uri().user().c_str());
+ sr->accept(200);
+}
+
+void DummyServerRegistrationHandler::onQuery(ServerRegistrationHandle sr, const SipMessage& reg) {
+ sr->accept(200);
+}
+
diff --git a/b2bua/DummyServerRegistrationHandler.hxx b/b2bua/DummyServerRegistrationHandler.hxx
new file mode 100644
index 0000000..511db9e
--- /dev/null
+++ b/b2bua/DummyServerRegistrationHandler.hxx
@@ -0,0 +1,62 @@
+
+#ifndef __DummyServerRegistrationHandler_h
+#define __DummyServerRegistrationHandler_h
+
+#include "resip/dum/RegistrationHandler.hxx"
+
+namespace b2bua
+{
+
+class DummyServerRegistrationHandler : public resip::ServerRegistrationHandler {
+
+public:
+// virtual ~ServerRegistrationHandler();
+ void onRefresh(resip::ServerRegistrationHandle, const resip::SipMessage& reg);
+ void onRemove(resip::ServerRegistrationHandle, const resip::SipMessage& reg);
+ void onRemoveAll(resip::ServerRegistrationHandle, const resip::SipMessage& reg);
+ void onAdd(resip::ServerRegistrationHandle, const resip::SipMessage& reg);
+ void onQuery(resip::ServerRegistrationHandle, const resip::SipMessage& reg);
+
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/Logging.hxx b/b2bua/Logging.hxx
new file mode 100644
index 0000000..f0b91aa
--- /dev/null
+++ b/b2bua/Logging.hxx
@@ -0,0 +1,71 @@
+
+/*
+
+ Logging.h provides definitions for logging.
+
+ Possible implementations of these definitions are:
+ - no logging - empty definitions for production use
+ - syslog - pass all messages to syslog
+ - file or stream - log all messages to a file or stream
+ - resip - log all messages to the underlying resiprocate logging method
+ - Log4C - pass all logging to Log4c
+*/
+
+#ifndef __Logging_h
+#define __Logging_h
+
+
+// syslog implementation
+
+#include <syslog.h>
+
+#define B2BUA_LOG_INIT(n) openlog(n, LOG_ODELAY | LOG_PID, LOG_LOCAL0)
+
+#define B2BUA_LOG_DEBUG(fmt, ...) syslog(LOG_DEBUG, "b2bua:%s:%d: " #fmt, __FILE__, __LINE__, ## __VA_ARGS__)
+#define B2BUA_LOG_INFO(fmt, ...) syslog(LOG_INFO, "b2bua:%s:%d: " #fmt, __FILE__, __LINE__, ## __VA_ARGS__)
+#define B2BUA_LOG_NOTICE(fmt, ...) syslog(LOG_NOTICE, "b2bua:%s:%d: " #fmt, __FILE__, __LINE__, ## __VA_ARGS__)
+#define B2BUA_LOG_WARNING(fmt, ...) syslog(LOG_WARNING, "b2bua:%s:%d: " #fmt, __FILE__, __LINE__, ## __VA_ARGS__)
+#define B2BUA_LOG_ERR(fmt, ...) syslog(LOG_ERR, "b2bua:%s:%d: " #fmt, __FILE__, __LINE__, ## __VA_ARGS__)
+#define B2BUA_LOG_CRIT(fmt, ...) syslog(LOG_CRIT, "b2bua:%s:%d: " #fmt, __FILE__, __LINE__, ## __VA_ARGS__)
+
+
+#endif
+
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/Makefile.am b/b2bua/Makefile.am
new file mode 100644
index 0000000..582c719
--- /dev/null
+++ b/b2bua/Makefile.am
@@ -0,0 +1,92 @@
+# $Id$
+
+EXTRA_DIST = README.txt
+
+SUBDIRS = .
+
+#AM_CXXFLAGS = -DUSE_ARES
+
+lib_LTLIBRARIES = libb2bua.la
+
+libb2bua_la_LDFLAGS = @LIBTOOL_VERSION_RELEASE@ -export-dynamic
+libb2bua_la_LIBADD = ../resip/dum/libdum.la
+libb2bua_la_LIBADD += ../resip/stack/libresip.la ../rutil/librutil.la
+libb2bua_la_LIBADD += @LIBSSL_LIBADD@ -lpthread
+
+libb2bua_la_SOURCES = \
+ AuthenticationManager.cxx \
+ B2BCall.cxx \
+ B2BCallManager.cxx \
+ B2BUA.cxx \
+ CallHandle.cxx \
+ DailyCDRHandler.cxx \
+ DefaultAuthorizationManager.cxx \
+ DialogUsageManagerRecurringTask.cxx \
+ DummyRegistrationPersistenceManager.cxx \
+ DummyServerRegistrationHandler.cxx \
+ MediaManager.cxx \
+ MediaProxy.cxx \
+ MyAppDialog.cxx \
+ MyDialogSetHandler.cxx \
+ MyInviteSessionHandler.cxx \
+ RtpProxyRecurringTask.cxx \
+ RtpProxyUtil.cxx \
+ TaskManager.cxx
+
+b2buaincludedir = $(includedir)/b2bua
+nobase_b2buainclude_HEADERS = \
+ AccountingManager.hxx \
+ AuthenticationManager.hxx \
+ AuthorizationManager.hxx \
+ B2BCall.hxx \
+ B2BCallManager.hxx \
+ B2BUA.hxx \
+ CallHandle.hxx \
+ CDRHandler.hxx \
+ DefaultAuthorizationManager.hxx \
+ DialogUsageManagerRecurringTask.hxx \
+ DummyRegistrationPersistenceManager.hxx \
+ DummyServerRegistrationHandler.hxx \
+ Logging.hxx \
+ MediaManager.hxx \
+ MediaProxy.hxx \
+ MyAppDialog.hxx \
+ MyDialogSetHandler.hxx \
+ MyInviteSessionHandler.hxx \
+ RtpProxyRecurringTask.hxx \
+ RtpProxyUtil.hxx \
+ TaskManager.hxx
+
+##############################################################################
+#
+# Copyright (c) 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+#
+##############################################################################
diff --git a/b2bua/Makefile.in b/b2bua/Makefile.in
new file mode 100644
index 0000000..50ad7d5
--- /dev/null
+++ b/b2bua/Makefile.in
@@ -0,0 +1,826 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+# $Id$
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = b2bua
+DIST_COMMON = $(nobase_b2buainclude_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_have_epoll.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(b2buaincludedir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+libb2bua_la_DEPENDENCIES = ../resip/dum/libdum.la \
+ ../resip/stack/libresip.la ../rutil/librutil.la
+am_libb2bua_la_OBJECTS = AuthenticationManager.lo B2BCall.lo \
+ B2BCallManager.lo B2BUA.lo CallHandle.lo DailyCDRHandler.lo \
+ DefaultAuthorizationManager.lo \
+ DialogUsageManagerRecurringTask.lo \
+ DummyRegistrationPersistenceManager.lo \
+ DummyServerRegistrationHandler.lo MediaManager.lo \
+ MediaProxy.lo MyAppDialog.lo MyDialogSetHandler.lo \
+ MyInviteSessionHandler.lo RtpProxyRecurringTask.lo \
+ RtpProxyUtil.lo TaskManager.lo
+libb2bua_la_OBJECTS = $(am_libb2bua_la_OBJECTS)
+libb2bua_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(libb2bua_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libb2bua_la_SOURCES)
+DIST_SOURCES = $(libb2bua_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+HEADERS = $(nobase_b2buainclude_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GPERF = @GPERF@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBARES_LIBADD = @LIBARES_LIBADD@
+LIBGEOIP_LIBADD = @LIBGEOIP_LIBADD@
+LIBMYSQL_LIBADD = @LIBMYSQL_LIBADD@
+LIBOBJS = @LIBOBJS@
+LIBPOPT_LIBADD = @LIBPOPT_LIBADD@
+LIBRADIUS_LIBADD = @LIBRADIUS_LIBADD@
+LIBS = @LIBS@
+LIBSSL_LIBADD = @LIBSSL_LIBADD@
+LIBTOOL = @LIBTOOL@
+LIBTOOL_VERSION_RELEASE = @LIBTOOL_VERSION_RELEASE@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SO_RELEASE = @SO_RELEASE@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = README.txt
+SUBDIRS = .
+
+#AM_CXXFLAGS = -DUSE_ARES
+lib_LTLIBRARIES = libb2bua.la
+libb2bua_la_LDFLAGS = @LIBTOOL_VERSION_RELEASE@ -export-dynamic
+libb2bua_la_LIBADD = ../resip/dum/libdum.la ../resip/stack/libresip.la \
+ ../rutil/librutil.la @LIBSSL_LIBADD@ -lpthread
+libb2bua_la_SOURCES = \
+ AuthenticationManager.cxx \
+ B2BCall.cxx \
+ B2BCallManager.cxx \
+ B2BUA.cxx \
+ CallHandle.cxx \
+ DailyCDRHandler.cxx \
+ DefaultAuthorizationManager.cxx \
+ DialogUsageManagerRecurringTask.cxx \
+ DummyRegistrationPersistenceManager.cxx \
+ DummyServerRegistrationHandler.cxx \
+ MediaManager.cxx \
+ MediaProxy.cxx \
+ MyAppDialog.cxx \
+ MyDialogSetHandler.cxx \
+ MyInviteSessionHandler.cxx \
+ RtpProxyRecurringTask.cxx \
+ RtpProxyUtil.cxx \
+ TaskManager.cxx
+
+b2buaincludedir = $(includedir)/b2bua
+nobase_b2buainclude_HEADERS = \
+ AccountingManager.hxx \
+ AuthenticationManager.hxx \
+ AuthorizationManager.hxx \
+ B2BCall.hxx \
+ B2BCallManager.hxx \
+ B2BUA.hxx \
+ CallHandle.hxx \
+ CDRHandler.hxx \
+ DefaultAuthorizationManager.hxx \
+ DialogUsageManagerRecurringTask.hxx \
+ DummyRegistrationPersistenceManager.hxx \
+ DummyServerRegistrationHandler.hxx \
+ Logging.hxx \
+ MediaManager.hxx \
+ MediaProxy.hxx \
+ MyAppDialog.hxx \
+ MyDialogSetHandler.hxx \
+ MyInviteSessionHandler.hxx \
+ RtpProxyRecurringTask.hxx \
+ RtpProxyUtil.hxx \
+ TaskManager.hxx
+
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .cxx .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu b2bua/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu b2bua/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libb2bua.la: $(libb2bua_la_OBJECTS) $(libb2bua_la_DEPENDENCIES)
+ $(libb2bua_la_LINK) -rpath $(libdir) $(libb2bua_la_OBJECTS) $(libb2bua_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/AuthenticationManager.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/B2BCall.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/B2BCallManager.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/B2BUA.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/CallHandle.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DailyCDRHandler.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DefaultAuthorizationManager.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DialogUsageManagerRecurringTask.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DummyRegistrationPersistenceManager.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DummyServerRegistrationHandler.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/MediaManager.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/MediaProxy.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/MyAppDialog.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/MyDialogSetHandler.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/MyInviteSessionHandler.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/RtpProxyRecurringTask.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/RtpProxyUtil.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TaskManager.Plo at am__quote@
+
+.cxx.o:
+ at am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cxx.obj:
+ at am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cxx.lo:
+ at am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-nobase_b2buaincludeHEADERS: $(nobase_b2buainclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(b2buaincludedir)" || $(MKDIR_P) "$(DESTDIR)$(b2buaincludedir)"
+ @list='$(nobase_b2buainclude_HEADERS)'; test -n "$(b2buaincludedir)" || list=; \
+ $(am__nobase_list) | while read dir files; do \
+ xfiles=; for file in $$files; do \
+ if test -f "$$file"; then xfiles="$$xfiles $$file"; \
+ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
+ test -z "$$xfiles" || { \
+ test "x$$dir" = x. || { \
+ echo "$(MKDIR_P) '$(DESTDIR)$(b2buaincludedir)/$$dir'"; \
+ $(MKDIR_P) "$(DESTDIR)$(b2buaincludedir)/$$dir"; }; \
+ echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(b2buaincludedir)/$$dir'"; \
+ $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(b2buaincludedir)/$$dir" || exit $$?; }; \
+ done
+
+uninstall-nobase_b2buaincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(nobase_b2buainclude_HEADERS)'; test -n "$(b2buaincludedir)" || list=; \
+ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(b2buaincludedir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(b2buaincludedir)" && rm -f $$files
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(b2buaincludedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-nobase_b2buaincludeHEADERS
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-libLTLIBRARIES \
+ uninstall-nobase_b2buaincludeHEADERS
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
+ install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool ctags ctags-recursive \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-libLTLIBRARIES install-man \
+ install-nobase_b2buaincludeHEADERS install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-recursive uninstall uninstall-am \
+ uninstall-libLTLIBRARIES uninstall-nobase_b2buaincludeHEADERS
+
+
+##############################################################################
+#
+# Copyright (c) 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+#
+##############################################################################
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/b2bua/MediaManager.cxx b/b2bua/MediaManager.cxx
new file mode 100644
index 0000000..633e6cf
--- /dev/null
+++ b/b2bua/MediaManager.cxx
@@ -0,0 +1,112 @@
+
+#include "rutil/Data.hxx"
+
+#include "MediaManager.hxx"
+
+using namespace b2bua;
+using namespace resip;
+using namespace std;
+
+Data MediaManager::proxyAddress;
+
+void MediaManager::setProxyAddress(const Data& proxyAddress) {
+ MediaManager::proxyAddress = proxyAddress;
+};
+
+MediaManager::MediaManager(B2BCall& b2BCall) : b2BCall(b2BCall) {
+ aLegProxy = NULL;
+ bLegProxy = NULL;
+ rtpProxyUtil = NULL;
+};
+
+MediaManager::MediaManager(B2BCall& b2BCall, const Data& callId, const Data& fromTag, const Data& toTag) : b2BCall(b2BCall), callId(callId), fromTag(fromTag), toTag(toTag) {
+ aLegProxy = NULL;
+ bLegProxy = NULL;
+ rtpProxyUtil = NULL;
+};
+
+MediaManager::~MediaManager() {
+ if(aLegProxy != NULL)
+ delete aLegProxy;
+ if(bLegProxy != NULL)
+ delete bLegProxy;
+ if(rtpProxyUtil != NULL)
+ delete rtpProxyUtil;
+};
+
+void MediaManager::setFromTag(const Data& fromTag) {
+ this->fromTag = fromTag;
+};
+
+void MediaManager::setToTag(const Data& toTag) {
+ this->toTag = toTag;
+};
+
+int MediaManager::setALegSdp(const SdpContents& sdp, const in_addr_t& msgSourceAddress) {
+ aLegSdp = sdp;
+ if(aLegProxy == NULL)
+ aLegProxy = new MediaProxy(*this);
+ return aLegProxy->updateSdp(aLegSdp, msgSourceAddress);
+};
+
+SdpContents& MediaManager::getALegSdp() {
+ if(aLegProxy == NULL) {
+ throw new exception;
+ }
+ return aLegProxy->getSdp();
+};
+
+int MediaManager::setBLegSdp(const SdpContents& sdp, const in_addr_t& msgSourceAddress) {
+ bLegSdp = sdp;
+ if(bLegProxy == NULL)
+ bLegProxy = new MediaProxy(*this);
+ return bLegProxy->updateSdp(bLegSdp, msgSourceAddress);
+};
+
+SdpContents& MediaManager::getBLegSdp() {
+ if(bLegProxy == NULL)
+ throw new exception;
+ return bLegProxy->getSdp();
+};
+
+void MediaManager::onMediaTimeout() {
+ b2BCall.onMediaTimeout();
+};
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/MediaManager.hxx b/b2bua/MediaManager.hxx
new file mode 100644
index 0000000..01b99e3
--- /dev/null
+++ b/b2bua/MediaManager.hxx
@@ -0,0 +1,130 @@
+
+#ifndef __MediaManager_h
+#define __MediaManager_h
+
+#include "resip/stack/SdpContents.hxx"
+#include "rutil/Data.hxx"
+
+namespace b2bua
+{
+
+class MediaManager;
+
+}
+
+#include "B2BCall.hxx"
+#include "MediaProxy.hxx"
+#include "RtpProxyUtil.hxx"
+
+namespace b2bua
+{
+
+/*
+ Each B2BCall requires a MediaManager to handle the SDP and media
+ (typically RTP/AVP).
+
+ MediaManager is responsible for:
+ - validating the content of the SDP (IP4 only, UDP only, etc)
+ - creating and destroying pairs of MediaProxy instances as needed
+ - rewriting the SDP connection addresses and port numbers
+ - hiding information about the remote party (e.g. phone, web, fax)
+*/
+
+// FIXME - use enum types
+#define MM_SDP_OK 0 // The SDP was acceptable
+#define MM_SDP_BAD 1 // The SDP was not acceptable
+
+class B2BCall;
+
+class MediaManager : public RtpProxyUtil::TimeoutListener {
+
+private:
+
+ static resip::Data proxyAddress;
+
+ B2BCall& b2BCall;
+
+ resip::Data callId; // from A Leg
+ resip::Data fromTag; // `from' tag for A leg party
+ resip::Data toTag; // `to' tag for B leg party
+ resip::SdpContents aLegSdp;
+ resip::SdpContents newALegSdp;
+ resip::SdpContents bLegSdp;
+ resip::SdpContents newBLegSdp;
+
+ RtpProxyUtil *rtpProxyUtil; // Access to rtpproxy
+
+ MediaProxy *aLegProxy; // Proxies on behalf of A leg
+ MediaProxy *bLegProxy; // Proxies on behalf of B leg
+
+public:
+ friend class MediaProxy;
+
+ // Set the proxyAddress
+ static void setProxyAddress(const resip::Data& proxyAddress);
+
+ // Instantiate a MediaManager
+ MediaManager(B2BCall& b2BCall);
+ MediaManager(B2BCall& b2BCall, const resip::Data& callId, const resip::Data& fromTag, const resip::Data& toTag);
+ virtual ~MediaManager();
+
+ // Set the From tag
+ void setFromTag(const resip::Data& fromTag);
+ // Set the To tag
+ void setToTag(const resip::Data& toTag);
+
+ // inspect and save an offer (A leg)
+ int setALegSdp(const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress);
+ // generate an offer (to send to B leg)
+ resip::SdpContents& getALegSdp();
+
+ // inspect and save an answer (B leg)
+ int setBLegSdp(const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress);
+ // generate an answer (to send to A leg)
+ resip::SdpContents& getBLegSdp();
+
+ void onMediaTimeout();
+
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/MediaProxy.cxx b/b2bua/MediaProxy.cxx
new file mode 100644
index 0000000..0d46a06
--- /dev/null
+++ b/b2bua/MediaProxy.cxx
@@ -0,0 +1,218 @@
+
+#include <exception>
+#include <iostream>
+
+#include "Logging.hxx"
+#include "MediaProxy.hxx"
+
+using namespace b2bua;
+using namespace resip;
+using namespace std;
+
+bool MediaProxy::mNatHelper = false;
+
+void MediaProxy::setNatHelper(bool natHelper) {
+ mNatHelper = natHelper;
+}
+
+MediaProxy::MediaProxy(MediaManager& mediaManager) : mediaManager(mediaManager) {
+ originalSdp = NULL;
+ newSdp = NULL;
+}
+
+MediaProxy::~MediaProxy() {
+ if(originalSdp != NULL)
+ delete originalSdp;
+ if(newSdp != NULL)
+ delete newSdp;
+}
+
+int MediaProxy::updateSdp(const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress) {
+ bool callerAsymmetric = true;
+ bool calleeAsymmetric = true;
+ if(originalSdp != NULL)
+ delete originalSdp;
+ originalSdp = (SdpContents *)sdp.clone();
+ if(newSdp != NULL)
+ delete newSdp;
+ newSdp = (SdpContents *)sdp.clone();
+
+ // Process the Origin
+ if(originalSdp->session().origin().getAddressType() != SdpContents::IP4) {
+ // FIXME - implement IPv6
+ B2BUA_LOG_WARNING("processing SDP origin, only IP4 is supported");
+ return MM_SDP_BAD;
+ }
+ // FIXME - set username also
+ newSdp->session().origin().setAddress(MediaManager::proxyAddress);
+
+ // Process the default connection
+ if(originalSdp->session().connection().getAddressType() != SdpContents::IP4) {
+ // FIXME - implement IPv6
+ B2BUA_LOG_WARNING("processing SDP connection, only IP4 is supported");
+ return MM_SDP_BAD;
+ }
+ newSdp->session().connection().setAddress(MediaManager::proxyAddress);
+
+ newSdp->session().clearMedium();
+ list<SdpContents::Session::Medium>::iterator i = originalSdp->session().media().begin();
+ while(i != originalSdp->session().media().end()) {
+ if(allowProtocol((*i).protocol())) {
+ if(newSdp->session().media().size() > 0) {
+ // FIXME
+ B2BUA_LOG_WARNING("only one medium definition supported");
+ return MM_SDP_BAD;
+ }
+ struct MediaProxy::EndPoint endpoint;
+ endpoint.address = originalSdp->session().connection().getAddress();
+ // Should we adjust the address because of NAT?
+ if(mNatHelper) {
+ in_addr_t sdpConnectionAddr = inet_addr(originalSdp->session().connection().getAddress().c_str());
+ // Is the endpoint a private address?
+ bool addressIsPrivate = isAddressPrivate(sdpConnectionAddr);
+ if(addressIsPrivate)
+ B2BUA_LOG_WARNING("IP address in SDP is private: %s", originalSdp->session().connection().getAddress().c_str());
+
+ // Does the endpoint address not match the msg source address?
+ bool matchesMsgSource = false;
+ if(sdpConnectionAddr == msgSourceAddress)
+ matchesMsgSource = true;
+
+ if(addressIsPrivate && !matchesMsgSource) {
+ // use the msg source address instead of the address in the SDP
+ struct in_addr sa;
+ sa.s_addr = msgSourceAddress;
+ endpoint.address = Data(inet_ntoa(sa));
+ callerAsymmetric = false;
+ B2BUA_LOG_WARNING("rewriting NAT address, was %s, using %s", originalSdp->session().connection().getAddress().c_str(), endpoint.address.c_str());
+ }
+ }
+ // Check for a connection spec
+ if((*i).getMediumConnections().size() > 1) {
+ // FIXME - connection for each medium
+ B2BUA_LOG_WARNING("multiple medium specific connections not supported");
+ return MM_SDP_BAD;
+ }
+ if((*i).getMediumConnections().size() == 1) {
+ const SdpContents::Session::Connection& mc = (*i).getMediumConnections().front();
+ // FIXME - check address type, etc, or implement operator==
+ if(!(mc.getAddress() == originalSdp->session().connection().getAddress())) {
+ B2BUA_LOG_WARNING("medium specific connection doesn't match global connection");
+ return MM_SDP_BAD;
+ }
+
+ }
+ // Get the old port, insert new port
+ endpoint.originalPort = (*i).port();
+ SdpContents::Session::Medium m(*i);
+ // FIXME - only needed until more detailed handling of medium specific
+ // connections is implemented:
+ //m.getMediumConnections().clear();
+ m.setConnection(newSdp->session().connection());
+ if(mediaManager.aLegProxy == this) {
+ // this must be A leg
+ if(mediaManager.rtpProxyUtil == NULL) {
+ mediaManager.rtpProxyUtil = new RtpProxyUtil();
+ mediaManager.rtpProxyUtil->setTimeoutListener(&mediaManager);
+ }
+ endpoint.proxyPort = mediaManager.rtpProxyUtil->setupCaller(mediaManager.callId.c_str(), endpoint.address.c_str(), endpoint.originalPort, mediaManager.fromTag.c_str(), callerAsymmetric);
+ if(endpoint.proxyPort == 0)
+ throw new exception;
+ } else {
+ // this must be B leg
+ endpoint.proxyPort = mediaManager.rtpProxyUtil->setupCallee(endpoint.address.c_str(), endpoint.originalPort, mediaManager.toTag.c_str(), calleeAsymmetric);
+ if(endpoint.proxyPort == 0)
+ throw new exception;
+ }
+ m.setPort(endpoint.proxyPort);
+ //newMedia.push_back(m);
+ newSdp->session().addMedium(m);
+ endpoints.push_back(endpoint);
+ } else {
+ B2BUA_LOG_WARNING("media protocol %s not recognised, removed from SDP", (*i).protocol().c_str());
+ }
+ i++;
+ }
+ if(endpoints.size() == 0) {
+ B2BUA_LOG_WARNING("no acceptable media protocol found, try RTP/AVP or UDP");
+ return MM_SDP_BAD;
+ }
+
+ return MM_SDP_OK;
+
+}
+
+resip::SdpContents& MediaProxy::getSdp() {
+ return *newSdp;
+}
+
+bool MediaProxy::allowProtocol(const resip::Data& protocol) {
+ if(protocol == Data("RTP/AVP") || protocol == Data("UDP") || protocol == Data("udp") || protocol == Data("udptl")) {
+ return true;
+ }
+ return false;
+}
+
+// 10.0.0.0/8 - 10.255.255.255
+// 172.16.0.0/12 - 172.31.255.255
+// 192.168.0.0/16 - 192.168.255.255
+bool MediaProxy::isAddressPrivate(const in_addr_t& subj_addr) {
+ //in_addr_t subj_addr = inet_addr(address.c_str());
+ if(subj_addr == INADDR_NONE) {
+ B2BUA_LOG_WARNING("subject address is invalid: INADDR_NONE");
+ return false;
+ }
+
+ uint32_t subj_addr1 = ntohl(subj_addr);
+ uint32_t priv1 = (10 << 24);
+ uint32_t nm1 = 0xff000000;
+ uint32_t priv2 = (172 << 24) + (16 << 16);
+ uint32_t nm2 = 0xfff00000;
+ uint32_t priv3 = (192 << 24) + (168 << 16);
+ uint32_t nm3 = 0xffff0000;
+
+ if(((subj_addr1 & nm1) == priv1) ||
+ ((subj_addr1 & nm2) == priv2) ||
+ ((subj_addr1 & nm3) == priv3))
+ return true;
+
+ return false;
+}
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/MediaProxy.hxx b/b2bua/MediaProxy.hxx
new file mode 100644
index 0000000..577f058
--- /dev/null
+++ b/b2bua/MediaProxy.hxx
@@ -0,0 +1,111 @@
+
+#ifndef __MediaProxy_h
+#define __MediaProxy_h
+
+#include "resip/stack/SdpContents.hxx"
+
+namespace b2bua
+{
+
+class MediaProxy;
+
+}
+
+#include "MediaManager.hxx"
+
+namespace b2bua
+{
+
+/*
+ A generic MediaProxy is based on the SDP from a single endpoint.
+
+ Two MediaProxys must work together to provide a symmetric RTP service
+ that will get through NAT. The two MediaProxy instances are
+ synchronised by the MediaManager.
+
+ For an implementation based on rtpproxy, we must also use SIP callID,
+ from-tag and to-tag, as these are the values rtpproxy expects to use
+ for uniquely identifying each call.
+
+ Alternatively, we could use our own unique identifier system.
+*/
+
+class MediaProxy {
+
+protected:
+ struct EndPoint {
+ resip::Data address; // the address we should forward to
+ unsigned int originalPort; // the port on the dest address
+ unsigned int proxyPort; // the port we listen with
+ };
+
+ static bool mNatHelper;
+
+private:
+ MediaManager& mediaManager; // the MediaManager who controls us
+ std::list<EndPoint> endpoints; // the endpoints for each media
+ // offer in the SDP
+ resip::SdpContents *originalSdp; // the original SDP
+ resip::SdpContents *newSdp; // the modified SDP
+
+public:
+ static void setNatHelper(bool natHelper);
+ MediaProxy(MediaManager& mediaManager);
+ virtual ~MediaProxy();
+ int updateSdp(const resip::SdpContents& sdp, const in_addr_t& msgSourceAddress); // update the SDP,
+ // as a result of a
+ // new offer
+ resip::SdpContents& getSdp(); // get the SDP
+ // that should be sent
+ // to the other party
+ // we correspond with
+ bool allowProtocol(const resip::Data& protocol); // discover if protocol
+ // is permitted/handled
+ // by this proxy
+ // implementation
+
+ bool isAddressPrivate(const in_addr_t& subj_addr);
+
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/MyAppDialog.cxx b/b2bua/MyAppDialog.cxx
new file mode 100644
index 0000000..92403d3
--- /dev/null
+++ b/b2bua/MyAppDialog.cxx
@@ -0,0 +1,100 @@
+
+#include "MyAppDialog.hxx"
+
+using namespace b2bua;
+using namespace resip;
+using namespace std;
+
+MyAppDialog::MyAppDialog(HandleManager& ham) : AppDialog(ham) {
+ setB2BCall(NULL);
+}
+
+MyAppDialog::MyAppDialog(HandleManager& ham, B2BCall *b2BCall) : AppDialog(ham) {
+ setB2BCall(b2BCall);
+ // FIXME - is this the B Leg?
+ if(b2BCall != NULL)
+ b2BCall->setBLegAppDialog(this);
+}
+
+MyAppDialog::~MyAppDialog() {
+ if(b2BCall != NULL)
+ b2BCall->releaseAppDialog(this);
+}
+
+B2BCall *MyAppDialog::getB2BCall() {
+ return b2BCall;
+}
+
+void MyAppDialog::setB2BCall(B2BCall *b2BCall) {
+ this->b2BCall = b2BCall;
+}
+
+MyAppDialogSet::MyAppDialogSet(DialogUsageManager& dum) : AppDialogSet(dum) {
+ this->b2BCall = NULL;
+ //userProfile = NULL;
+}
+
+MyAppDialogSet::MyAppDialogSet(DialogUsageManager& dum, B2BCall *b2BCall, SharedPtr<UserProfile>& userProfile) : AppDialogSet(dum) {
+ this->b2BCall = b2BCall;
+ this->userProfile = userProfile;
+}
+
+MyAppDialogSet::~MyAppDialogSet() {
+ if(b2BCall != NULL)
+ b2BCall->releaseAppDialogSet(this);
+}
+
+AppDialog* MyAppDialogSet::createAppDialog(const SipMessage& msg) {
+ return new MyAppDialog(mDum, b2BCall);
+}
+
+/* SharedPtr<UserProfile> MyAppDialogSet::getUserProfile() {
+ return userProfile;
+} */
+
+SharedPtr<UserProfile> MyAppDialogSet::selectUASUserProfile(const SipMessage& msg) {
+ //return getUserProfile();
+ return mDum.getMasterUserProfile();
+}
+
+AppDialogSet* MyAppDialogSetFactory::createAppDialogSet(DialogUsageManager& dum, const SipMessage& msg) {
+ return new MyAppDialogSet(dum);
+}
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/MyAppDialog.hxx b/b2bua/MyAppDialog.hxx
new file mode 100644
index 0000000..bc1ad98
--- /dev/null
+++ b/b2bua/MyAppDialog.hxx
@@ -0,0 +1,107 @@
+
+#ifndef __MyAppDialog_h
+#define __MyAppDialog_h
+
+#include "resip/stack/SipMessage.hxx"
+
+#include "resip/dum/AppDialog.hxx"
+#include "resip/dum/AppDialogSet.hxx"
+#include "resip/dum/AppDialogSetFactory.hxx"
+#include "resip/dum/DialogUsageManager.hxx"
+
+namespace b2bua
+{
+
+class MyAppDialog;
+class MyAppDialogSet;
+class MyDialogSetHandler;
+
+}
+
+#include "B2BCall.hxx"
+
+namespace b2bua
+{
+
+class MyAppDialog : public resip::AppDialog {
+
+protected:
+ B2BCall *b2BCall;
+
+public:
+
+ MyAppDialog(resip::HandleManager& ham);
+ MyAppDialog(resip::HandleManager& ham, B2BCall *b2BCall);
+ virtual ~MyAppDialog();
+ B2BCall *getB2BCall();
+ void setB2BCall(B2BCall *b2BCall);
+
+};
+
+class MyAppDialogSet : public resip::AppDialogSet {
+
+protected:
+ B2BCall *b2BCall;
+ resip::SharedPtr<resip::UserProfile> userProfile;
+
+public:
+ MyAppDialogSet(resip::DialogUsageManager& dum);
+ MyAppDialogSet(resip::DialogUsageManager& dum, B2BCall *b2BCall, resip::SharedPtr<resip::UserProfile>& userProfile);
+ virtual ~MyAppDialogSet();
+ virtual resip::AppDialog* createAppDialog(const resip::SipMessage& msg);
+ // virtual resip::SharedPtr<resip::UserProfile> getUserProfile();
+ virtual resip::SharedPtr<resip::UserProfile> selectUASUserProfile(const resip::SipMessage& msg);
+ void setB2BCall(B2BCall *b2BCall)
+ { this->b2BCall = b2BCall; };
+
+ friend class MyDialogSetHandler;
+};
+
+class MyAppDialogSetFactory : public resip::AppDialogSetFactory {
+
+public:
+ virtual resip::AppDialogSet* createAppDialogSet(resip::DialogUsageManager& dum, const resip::SipMessage& msg);
+
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/MyDialogSetHandler.cxx b/b2bua/MyDialogSetHandler.cxx
new file mode 100644
index 0000000..1ee005e
--- /dev/null
+++ b/b2bua/MyDialogSetHandler.cxx
@@ -0,0 +1,64 @@
+
+
+#include "B2BCall.hxx"
+#include "Logging.hxx"
+#include "MyAppDialog.hxx"
+#include "MyDialogSetHandler.hxx"
+
+using namespace b2bua;
+using namespace resip;
+using namespace std;
+
+MyDialogSetHandler::~MyDialogSetHandler() {
+}
+
+void MyDialogSetHandler::onTrying(resip::AppDialogSetHandle ah, const resip::SipMessage& msg) {
+}
+
+void MyDialogSetHandler::onNonDialogCreatingProvisional(resip::AppDialogSetHandle ah, const resip::SipMessage& msg) {
+ B2BUA_LOG_DEBUG("received 180 without contact header");
+ MyAppDialogSet *ads = dynamic_cast<MyAppDialogSet *>(ah.get());
+ if(ads) {
+ B2BUA_LOG_DEBUG("dialog found");
+ if(ads->b2BCall)
+ ads->b2BCall->doDialReceived180();
+ }
+}
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/MyDialogSetHandler.hxx b/b2bua/MyDialogSetHandler.hxx
new file mode 100644
index 0000000..b692f7d
--- /dev/null
+++ b/b2bua/MyDialogSetHandler.hxx
@@ -0,0 +1,61 @@
+
+#ifndef __MyDialogSetHandler_h
+#define __MyDialogSetHandler_h
+
+#include "resip/dum/DialogSetHandler.hxx"
+
+namespace b2bua
+{
+
+class MyDialogSetHandler : public resip::DialogSetHandler {
+
+public:
+ ~MyDialogSetHandler();
+
+ virtual void onTrying(resip::AppDialogSetHandle ah, const resip::SipMessage& msg);
+
+ virtual void onNonDialogCreatingProvisional(resip::AppDialogSetHandle ah, const resip::SipMessage& msg);
+
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/MyInviteSessionHandler.cxx b/b2bua/MyInviteSessionHandler.cxx
new file mode 100644
index 0000000..816f451
--- /dev/null
+++ b/b2bua/MyInviteSessionHandler.cxx
@@ -0,0 +1,334 @@
+
+
+
+#include "resip/stack/ExtensionHeader.hxx"
+#include "resip/stack/SipMessage.hxx"
+#include "resip/stack/Tuple.hxx"
+#include "rutil/Data.hxx"
+
+#include "B2BCall.hxx"
+#include "B2BCallManager.hxx"
+#include "Logging.hxx"
+#include "MyInviteSessionHandler.hxx"
+
+using namespace b2bua;
+using namespace resip;
+using namespace std;
+
+MyInviteSessionHandler::MyInviteSessionHandler(DialogUsageManager& dum, B2BCallManager& callManager) : dum(dum), callManager(callManager) {
+}
+
+void MyInviteSessionHandler::onSuccess(ClientRegistrationHandle h, const SipMessage& response) {
+}
+
+void MyInviteSessionHandler::onFailure(ClientRegistrationHandle, const SipMessage& msg) {
+}
+
+void MyInviteSessionHandler::onMessage(resip::Handle<resip::InviteSession>, const resip::SipMessage& msg) {
+}
+
+void MyInviteSessionHandler::onMessageSuccess(resip::Handle<resip::InviteSession>, const resip::SipMessage&) {
+}
+
+void MyInviteSessionHandler::onMessageFailure(resip::Handle<resip::InviteSession>, const resip::SipMessage&) {
+}
+
+void MyInviteSessionHandler::onFailure(ClientInviteSessionHandle cis, const SipMessage& msg) {
+ B2BUA_LOG_DEBUG("onFailure: %d, %s", msg.header(h_StatusLine).statusCode(), msg.header(h_StatusLine).reason().c_str());
+ B2BCall *call = getB2BCall(cis.get());
+ if(call == NULL) {
+ B2BUA_LOG_WARNING("onFailure: unrecognised dialog");
+ return;
+ }
+ call->onRejected(msg.header(h_StatusLine).statusCode(), msg.header(h_StatusLine).reason());
+}
+
+void MyInviteSessionHandler::onForkDestroyed(ClientInviteSessionHandle) {
+}
+
+void MyInviteSessionHandler::onInfoSuccess(InviteSessionHandle, const SipMessage& msg) {
+}
+
+void MyInviteSessionHandler::onInfoFailure(InviteSessionHandle, const SipMessage& msg) {
+}
+
+void MyInviteSessionHandler::onProvisional(ClientInviteSessionHandle cis, const SipMessage& msg) {
+ B2BCall *call = getB2BCall(cis.get());
+ if(call == NULL) {
+ B2BUA_LOG_WARNING("onProvisional: unrecognised dialog");
+ return;
+ }
+ int code = msg.header(h_StatusLine).statusCode();
+ switch(code) {
+ case 100:
+ //call->onTrying();
+ break;
+ case 180:
+ call->onRinging();
+ break;
+ case 183:
+ //call->onSessionProgress();
+ break;
+ default:
+ B2BUA_LOG_DEBUG("onProvisional: unknown provisional code (%d)", code);
+ }
+}
+
+void MyInviteSessionHandler::onConnected(ClientInviteSessionHandle, const SipMessage& msg) {
+ // FIXME - start charging here instead of waiting for onAnswer
+}
+
+void MyInviteSessionHandler::onStaleCallTimeout(ClientInviteSessionHandle) {
+}
+
+void MyInviteSessionHandler::onConnected(InviteSessionHandle, const SipMessage& msg) {
+ // FIXME
+}
+
+void MyInviteSessionHandler::onRedirected(ClientInviteSessionHandle, const SipMessage& msg) {
+}
+
+void MyInviteSessionHandler::onAnswer(InviteSessionHandle is, const SipMessage& msg, const SdpContents& sdp) {
+ MyAppDialog *myAppDialog = (MyAppDialog *)is->getAppDialog().get();
+ B2BCall *call = getB2BCall(is.get());
+ if(call == NULL) {
+ B2BUA_LOG_WARNING("onAnswer: unrecognised dialog");
+ return;
+ }
+ Tuple sourceTuple = msg.getSource();
+ in_addr_t msgSourceAddress = sourceTuple.toGenericIPAddress().v4Address.sin_addr.s_addr;
+ call->onAnswer(myAppDialog, sdp, msgSourceAddress);
+}
+
+void MyInviteSessionHandler::onEarlyMedia(ClientInviteSessionHandle cis, const SipMessage& msg, const SdpContents& sdp) {
+ B2BCall *call = getB2BCall(cis.get());
+ if(call == NULL) {
+ B2BUA_LOG_WARNING("onEarlyMedia: unrecognised dialog");
+ return;
+ }
+ Tuple sourceTuple = msg.getSource();
+ in_addr_t msgSourceAddress = sourceTuple.toGenericIPAddress().v4Address.sin_addr.s_addr;
+ call->onEarlyMedia(sdp, msgSourceAddress);
+}
+
+void MyInviteSessionHandler::onOfferRequired(InviteSessionHandle, const SipMessage& msg) {
+ // FIXME
+}
+
+void MyInviteSessionHandler::onOfferRejected(Handle<InviteSession>, const SipMessage *msg) {
+ // FIXME
+ B2BUA_LOG_DEBUG("onOfferRejected: %d, %s", msg->header(h_StatusLine).statusCode(), msg->header(h_StatusLine).reason().c_str());
+}
+
+void MyInviteSessionHandler::onInfo(InviteSessionHandle, const SipMessage& msg) {
+}
+
+void MyInviteSessionHandler::onRefer(InviteSessionHandle, ServerSubscriptionHandle, const SipMessage& msg) {
+}
+
+void MyInviteSessionHandler::onReferAccepted(InviteSessionHandle, ClientSubscriptionHandle, const SipMessage& msg) {
+}
+
+void MyInviteSessionHandler::onReferRejected(InviteSessionHandle, const SipMessage& msg) {
+}
+
+void MyInviteSessionHandler::onReferNoSub(resip::Handle<resip::InviteSession> is, const resip::SipMessage& msg) {
+}
+
+void MyInviteSessionHandler::onRemoved(ClientRegistrationHandle) {
+}
+
+int MyInviteSessionHandler::onRequestRetry(ClientRegistrationHandle, int retrySeconds, const SipMessage& response) {
+// cerr << "onRequestRetry not implemented" << endl;
+ //FIXME
+ B2BUA_LOG_DEBUG("onRequestRetry not implemented");
+ return -1;
+}
+
+// New inbound connection
+// We must create a B2BCall and insert the B2BCall into the linked list
+void MyInviteSessionHandler::onNewSession(ServerInviteSessionHandle sis, InviteSession::OfferAnswerType oat, const SipMessage& msg) {
+ //cerr << "onNewSession sis" << endl;
+
+ // Are we shutting down? If so, reject the call with SIP code 503
+ if(callManager.isStopping()) {
+ B2BUA_LOG_DEBUG("rejecting inbound call as we are stopping");
+ sis->reject(503);
+ return;
+ }
+
+ // Check the headers
+ if(!msg.exists(h_From)) {
+ B2BUA_LOG_WARNING("inbound connection missing from header, rejecting dialog");
+ sis->reject(603);
+ return;
+ }
+ // FIXME - do above for all headers
+ if(msg.getReceivedTransport() == 0) {
+ // msg not received from the wire
+ // FIXME
+ B2BUA_LOG_WARNING("request not received from the wire");
+ sis->reject(603);
+ }
+ Tuple sourceTuple = msg.getSource();
+ Data sourceIp = Data(inet_ntoa(sourceTuple.toGenericIPAddress().v4Address.sin_addr));
+ Data contextId;
+ Data accountId;
+ Data baseIp;
+ Data controlId;
+ ExtensionHeader xContextId("X-MyB2BUA-Context-ID");
+ if(msg.exists(xContextId)) {
+ const StringCategories& contextIds = msg.header(xContextId);
+ contextId = Data((contextIds.begin())->value());
+ }
+ ExtensionHeader xAccountId("X-MyB2BUA-Account-ID");
+ if(msg.exists(xAccountId)) {
+ const StringCategories& accountIds = msg.header(xAccountId);
+ accountId = Data((accountIds.begin())->value());
+ }
+ ExtensionHeader xBaseIp("X-MyB2BUA-Base-IP");
+ if(msg.exists(xBaseIp)) {
+ const StringCategories& baseIps = msg.header(xBaseIp);
+ baseIp = Data((baseIps.begin())->value());
+ }
+ ExtensionHeader xControlId("X-MyB2BUA-Control-ID");
+ if(msg.exists(xControlId)) {
+ const StringCategories& controlIds = msg.header(xControlId);
+ controlId = Data((controlIds.begin())->value());
+ }
+ // Now inspect the authentication info
+ Data authRealm("");
+ Data authUser("");
+ Data authPassword("");
+ if(msg.exists(h_ProxyAuthorizations)) {
+ for(Auths::const_iterator it = msg.header(h_ProxyAuthorizations).begin(); it != msg.header(h_ProxyAuthorizations).end(); it++) {
+ if(dum.isMyDomain(it->param(p_realm))) {
+ authRealm = it->param(p_realm);
+ authUser = it->param(p_username);
+ }
+ }
+ }
+ try {
+ callManager.onNewCall((MyAppDialog *)sis->getAppDialog().get(), msg.header(h_From), msg.header(h_RequestLine).uri(), authRealm, authUser, Data(""), sourceIp, contextId, accountId, baseIp, controlId);
+ } catch (...) {
+ B2BUA_LOG_ERR("failed to instantiate B2BCall");
+ sis->reject(500); // Indicate temporary error condition
+ }
+}
+
+void MyInviteSessionHandler::onNewSession(ClientInviteSessionHandle cis, InviteSession::OfferAnswerType oat, const SipMessage& msg) {
+}
+
+void MyInviteSessionHandler::onTerminated(InviteSessionHandle is, InviteSessionHandler::TerminatedReason reason, const SipMessage* msg) {
+ B2BUA_LOG_DEBUG("onTerminated, reason = %d", reason);
+ B2BCall *call = getB2BCall(is.get());
+ if(call == NULL) {
+ B2BUA_LOG_WARNING("onTerminated: unrecognised dialog");
+ return;
+ }
+ MyAppDialog *myAppDialog = (MyAppDialog *)is->getAppDialog().get();
+ switch(reason) {
+
+ // received a BYE or CANCEL from peer
+ case RemoteCancel:
+ B2BUA_LOG_DEBUG("onTerminated: RemoteCancel");
+ call->onCancel();
+ break;
+
+ case RemoteBye:
+ B2BUA_LOG_DEBUG("onTerminated: RemoteBye");
+ // MyAppDialog *myAppDialog = (MyAppDialog *)is->getAppDialog().get();
+ call->onHangup(myAppDialog);
+ break;
+
+ // ended by the application
+ case LocalBye:
+ B2BUA_LOG_DEBUG("onTerminated: LocalBye");
+ //call->onFailure(myAppDialog);
+ break;
+
+ case Referred:
+ B2BUA_LOG_DEBUG("onTerminated: Referred");
+ //call->onFailure(myAppDialog);
+ break;
+
+ // ended due to a failure
+ case Error:
+ B2BUA_LOG_DEBUG("onTerminated: Error");
+ call->onFailure(myAppDialog);
+ break;
+
+ case Timeout:
+ B2BUA_LOG_DEBUG("onTerminated: Timeout");
+ call->onFailure(myAppDialog);
+ break;
+
+ case LocalCancel: // ended by the application via Cancel
+ B2BUA_LOG_DEBUG("onTerminated: LocalCancel");
+ // no need to do anything, because we have initiated this cancel
+ break;
+
+ default:
+ B2BUA_LOG_WARNING("onTerminated: unhandled case %d", reason);
+ break;
+ }
+}
+
+void MyInviteSessionHandler::onOffer(InviteSessionHandle is, const SipMessage& msg, const SdpContents& sdp) {
+ B2BCall *call = getB2BCall(is.get());
+ if(call == NULL) {
+ B2BUA_LOG_WARNING("onOffer: unrecognised dialog");
+ return;
+ }
+ B2BUA_LOG_DEBUG("onOffer received");
+ MyAppDialog *myAppDialog = (MyAppDialog *)is->getAppDialog().get();
+ Tuple sourceTuple = msg.getSource();
+ in_addr_t msgSourceAddress = sourceTuple.toGenericIPAddress().v4Address.sin_addr.s_addr;
+ call->onOffer(myAppDialog, sdp, msgSourceAddress);
+}
+
+/**
+ * Handy utility functions
+ */
+B2BCall *MyInviteSessionHandler::getB2BCall(InviteSession *is) {
+ MyAppDialog *myAppDialog = (MyAppDialog *)is->getAppDialog().get();
+ return (B2BCall *)myAppDialog->getB2BCall();
+}
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/MyInviteSessionHandler.hxx b/b2bua/MyInviteSessionHandler.hxx
new file mode 100644
index 0000000..c1de9e2
--- /dev/null
+++ b/b2bua/MyInviteSessionHandler.hxx
@@ -0,0 +1,97 @@
+
+
+#ifndef __MyInviteSessionHandler_h
+#define __MyInviteSessionHandler_h
+
+#include "resip/stack/SipMessage.hxx"
+#include "resip/dum/ClientInviteSession.hxx"
+#include "resip/dum/InviteSessionHandler.hxx"
+#include "resip/dum/ServerInviteSession.hxx"
+
+namespace b2bua
+{
+
+class MyInviteSessionHandler : public resip::InviteSessionHandler {
+
+protected:
+ resip::DialogUsageManager& dum;
+ B2BCallManager& callManager;
+
+public:
+ MyInviteSessionHandler(resip::DialogUsageManager& dum, B2BCallManager& callManager);
+ virtual void onSuccess(resip::ClientRegistrationHandle h, const resip::SipMessage& response);
+ virtual void onFailure(resip::ClientRegistrationHandle, const resip::SipMessage& msg);
+ virtual void onMessage(resip::Handle<resip::InviteSession>, const resip::SipMessage& msg);
+ virtual void onMessageSuccess(resip::Handle<resip::InviteSession>, const resip::SipMessage&);
+ virtual void onMessageFailure(resip::Handle<resip::InviteSession>, const resip::SipMessage&);
+ virtual void onFailure(resip::ClientInviteSessionHandle cis, const resip::SipMessage& msg);
+ virtual void onForkDestroyed(resip::ClientInviteSessionHandle);
+ virtual void onInfoSuccess(resip::InviteSessionHandle, const resip::SipMessage& msg);
+ virtual void onInfoFailure(resip::InviteSessionHandle, const resip::SipMessage& msg);
+ virtual void onProvisional(resip::ClientInviteSessionHandle cis, const resip::SipMessage& msg);
+ virtual void onConnected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg);
+ virtual void onConnected(resip::InviteSessionHandle, const resip::SipMessage& msg);
+ virtual void onStaleCallTimeout(resip::ClientInviteSessionHandle);
+ virtual void onRedirected(resip::ClientInviteSessionHandle, const resip::SipMessage& msg);
+ virtual void onAnswer(resip::InviteSessionHandle is, const resip::SipMessage& msg, const resip::SdpContents& sdp);
+ virtual void onEarlyMedia(resip::ClientInviteSessionHandle, const resip::SipMessage& msg, const resip::SdpContents& sdp);
+ virtual void onOfferRequired(resip::InviteSessionHandle, const resip::SipMessage& msg);
+ virtual void onOfferRejected(resip::Handle<resip::InviteSession>, const resip::SipMessage *msg);
+ virtual void onInfo(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::Handle<resip::InviteSession>, const resip::SipMessage&);
+ virtual void onRemoved(resip::ClientRegistrationHandle);
+ virtual int onRequestRetry(resip::ClientRegistrationHandle, int retrySeconds, const resip::SipMessage& response);
+ virtual void onNewSession(resip::ServerInviteSessionHandle sis, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg);
+ virtual void onNewSession(resip::ClientInviteSessionHandle cis, resip::InviteSession::OfferAnswerType oat, const resip::SipMessage& msg);
+ virtual void onTerminated(resip::InviteSessionHandle is, resip::InviteSessionHandler::TerminatedReason reason, const resip::SipMessage* msg);
+ virtual void onOffer(resip::InviteSessionHandle is, const resip::SipMessage& msg, const resip::SdpContents& sdp);
+
+ // Utility functions
+ B2BCall *getB2BCall(resip::InviteSession *is);
+
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/README.txt b/b2bua/README.txt
new file mode 100644
index 0000000..c522153
--- /dev/null
+++ b/b2bua/README.txt
@@ -0,0 +1,94 @@
+
+Introduction
+============
+
+This is a reSIProcate based B2BUA library.
+
+The library is libb2bua.so
+
+It is built on top of reSIProcate's dialog usage manager (DUM)
+
+Building
+========
+
+In the main reSIProcate directory:
+
+./configure
+make b2bua
+
+NOTE: the command `make' or `make all' will NOT build the B2BUA
+ by default. I have left it out of the default build until
+ it has been tested more extensively by the reSIProcate community.
+
+Background and technical notes
+==============================
+
+The code has been adapted from a previous project. Consequently,
+the initial import to the reSIProcate repository doesn't fully adhere to
+reSIProcate coding standards. Nonetheless, it is working code,
+so a decision was taken to commit the code as-is, without
+modification, and then gradually overhaul it in subsequent commits.
+
+Some key points about this code:
+
+- It produces a shared object - to produce an executable,
+ the B2BUA class must be instantiated and put to work.
+ Such an example will be added shortly. A typical
+ implementation of a B2BUA must implement the following
+ classes:
+ - b2bua::CallRoute
+ - b2bua::CallHandle
+ - b2bua::AuthorizationManager
+ - b2bua::B2BUA
+
+- It relies on rtpproxy from http://www.rtpproxy.org to relay
+ the media streams. I have created various patches for
+ rtpproxy 0.2:
+ - rtpproxy sends notification to the B2BUA on media timeout
+ - fix a file descriptor bug
+ - timeout on either direction
+ The rtpproxy patches are being posted on the rtpproxy mailing
+ list shortly.
+
+Daniel Pocock
+daniel at readytechnology.co.uk
+
+
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/RtpProxyRecurringTask.cxx b/b2bua/RtpProxyRecurringTask.cxx
new file mode 100644
index 0000000..9faae5e
--- /dev/null
+++ b/b2bua/RtpProxyRecurringTask.cxx
@@ -0,0 +1,54 @@
+
+#include "RtpProxyRecurringTask.hxx"
+#include "RtpProxyUtil.hxx"
+
+using namespace b2bua;
+
+RtpProxyRecurringTask::RtpProxyRecurringTask() {
+}
+
+TaskManager::TaskResult RtpProxyRecurringTask::doTaskProcessing() {
+ RtpProxyUtil::do_timeouts();
+ return TaskManager::TaskIndefinite;
+}
+
+void RtpProxyRecurringTask::stop() {
+}
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/RtpProxyRecurringTask.hxx b/b2bua/RtpProxyRecurringTask.hxx
new file mode 100644
index 0000000..ab8f5d2
--- /dev/null
+++ b/b2bua/RtpProxyRecurringTask.hxx
@@ -0,0 +1,68 @@
+
+#ifndef __RtpProxyRecurringTask_h
+#define __RtpProxyRecurringTask_h
+
+
+#include "TaskManager.hxx"
+
+namespace b2bua
+{
+
+#define STOP_TIMEOUT 3 // how many seconds to wait before shutdown
+
+class RtpProxyRecurringTask : public TaskManager::RecurringTask {
+
+protected:
+ bool stopping;
+ time_t stopTime;
+
+public:
+ RtpProxyRecurringTask();
+ TaskManager::TaskResult doTaskProcessing();
+
+ // let's the task know the application would like to stop soon
+ void stop();
+
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/RtpProxyUtil.cxx b/b2bua/RtpProxyUtil.cxx
new file mode 100644
index 0000000..e989a0c
--- /dev/null
+++ b/b2bua/RtpProxyUtil.cxx
@@ -0,0 +1,488 @@
+
+/* Todo:
+ - handle re-INVITE
+ - share a socket?
+ - test socket when app starts
+ - release ports when object destroyed
+*/
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <sys/uio.h>
+#include <sys/un.h>
+#include <ctype.h>
+#include <errno.h>
+#include <netdb.h>
+#include <poll.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <exception>
+#include <iostream>
+
+#include "Logging.hxx"
+#include "RtpProxyUtil.hxx"
+
+#define STR2IOVEC(sx, ix) {(ix).iov_base = (sx); (ix).iov_len = strlen((sx));}
+
+#define RTPPROXY_RETRY_COUNT 3
+
+using namespace b2bua;
+using namespace std;
+
+int RtpProxyUtil::umode = 0;
+char *RtpProxyUtil::rtpproxy_sock = (char *)DEFAULT_RTPPROXY_SOCK;
+int RtpProxyUtil::controlfd = 0;
+char *RtpProxyUtil::timeout_sock = (char *)DEFAULT_RTPPROXY_TIMEOUT_SOCK;
+int RtpProxyUtil::timeoutfd = 0;
+int RtpProxyUtil::timeout_clientfd = -1;
+int RtpProxyUtil::rtpproxy_retr = DEFAULT_RTPPROXY_RETR;
+int RtpProxyUtil::rtpproxy_tout = DEFAULT_RTPPROXY_TOUT;
+
+map<int, RtpProxyUtil *> RtpProxyUtil::proxies;
+
+void RtpProxyUtil::setSocket(const char *socket) {
+ if((rtpproxy_sock = (char *)malloc(strlen(socket) + 1)) == NULL) {
+ B2BUA_LOG_ERR("setSocket: malloc failed");
+ throw;
+ }
+ strcpy(rtpproxy_sock, socket);
+}
+
+void RtpProxyUtil::setTimeoutSocket(const char *socket) {
+ if((timeout_sock = (char *)malloc(strlen(socket) + 1)) == NULL) {
+ B2BUA_LOG_ERR("setSocket: malloc failed");
+ throw;
+ }
+ strcpy(timeout_sock, socket);
+}
+
+void RtpProxyUtil::init() {
+ umode = 0;
+// rtpproxy_sock = DEFAULT_RTPPROXY_SOCK;
+// timeout_sock = DEFAULT_RTPPROXY_TIMEOUT_SOCK;
+ rtpproxy_retr = DEFAULT_RTPPROXY_RETR;
+ rtpproxy_tout = DEFAULT_RTPPROXY_TOUT;
+
+ int len;
+ struct sockaddr_un local;
+
+ int flags;
+
+ if ((timeoutfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ B2BUA_LOG_ERR("socket: %m");
+ exit(1); // FIXME
+ }
+
+ local.sun_family = AF_UNIX;
+ strcpy(local.sun_path, timeout_sock);
+ unlink(local.sun_path);
+ len = strlen(local.sun_path) + sizeof(local.sun_family);
+ if (bind(timeoutfd, (struct sockaddr *)&local, len) == -1) {
+ B2BUA_LOG_ERR("bind: %m");
+ exit(1); // FIXME
+ }
+
+ if (listen(timeoutfd, 5) == -1) {
+ B2BUA_LOG_ERR("listen: %m");
+ exit(1); // FIXME
+ }
+
+ flags = fcntl(timeoutfd, F_GETFL);
+ flags |= O_NONBLOCK;
+ fcntl(timeoutfd, F_SETFL, flags);
+
+ timeout_clientfd = -1;
+
+ B2BUA_LOG_NOTICE("telling rtpproxy to flush calls");
+ // Check the version
+ struct iovec v[2] = {{NULL, 0}, {(char *)"x", 1}};
+ char *cp = sendCommandRetry(RTPPROXY_RETRY_COUNT, v, 2, "");
+ if(cp == NULL)
+ throw new exception;
+}
+
+void RtpProxyUtil::do_timeouts() {
+ // check for new connections with accept
+ // read any data with read
+ socklen_t t;
+ struct sockaddr_un remote;
+ int flags;
+ int n;
+ char buf[100];
+ int p1, p2;
+
+ if(timeout_clientfd == -1) {
+ t = sizeof(remote);
+ if((timeout_clientfd = accept(timeoutfd, (struct sockaddr *)&remote, &t)) == -1) {
+ if(errno == EAGAIN) {
+ // no connections coming in from rtpproxy
+ return;
+ }
+ B2BUA_LOG_ERR("accept: %m");
+ exit(1);
+ }
+ B2BUA_LOG_DEBUG("accepted a new connection from rtpproxy");
+ flags = fcntl(timeout_clientfd, F_GETFL);
+ flags |= O_NONBLOCK;
+ fcntl(timeout_clientfd, F_SETFL, flags);
+ }
+
+ n = recv(timeout_clientfd, buf, 100, 0);
+ if (n == -1) {
+ if (errno != EAGAIN) {
+ // FIXME
+ B2BUA_LOG_ERR("recv: %m");
+ close(timeout_clientfd);
+ timeout_clientfd = -1;
+ }
+ return;
+ }
+ if(n== 0) {
+ // n = 0 means that socket closed remotely
+ timeout_clientfd = -1;
+ return;
+ }
+
+ buf[n] = 0;
+ if((n = sscanf(buf, "%d %d\n", &p1, &p2)) != 2) {
+ B2BUA_LOG_WARNING("invalid number of arguments from rtpproxy_timeout client [%s]", buf);
+ } else {
+ B2BUA_LOG_DEBUG("timeout on ports %d %d", p1, p2);
+ if(proxies.count(p1) == 1) {
+ RtpProxyUtil *proxy = proxies.find(p1)->second;
+ proxy->mediaTimeout();
+ }
+ }
+}
+
+
+RtpProxyUtil::RtpProxyUtil() {
+ timeoutListener = NULL;
+ valid = true;
+ mypid = getpid();
+ myseqn = 0;
+ callID = NULL;
+ callerAddr = NULL;
+ callerPort = 0;
+ calleeAddr = NULL;
+ calleePort = 0;
+ fromTag = NULL;
+ toTag = NULL;
+
+ callerProxyPort = 0;
+ calleeProxyPort = 0;
+
+ // Check the version
+ struct iovec v[2] = {{NULL, 0}, {(char *)"V", 1}};
+ char *cp = sendCommandRetry(RTPPROXY_RETRY_COUNT, v, 2, gencookie());
+ if(cp == NULL)
+ throw new exception;
+
+}
+
+RtpProxyUtil::~RtpProxyUtil() {
+
+ if(callerProxyPort != 0)
+ proxies.erase(callerProxyPort);
+ if(calleeProxyPort != 0)
+ proxies.erase(calleeProxyPort);
+
+ struct iovec v[1 + 4 + 3] = {{NULL, 0}, {(char *)"D", 1}, {(char *)" ", 1}, {NULL, 0}, {(char *)" ", 1}, {NULL, 0}, {(char *)" ", 1}, {NULL, 0}};
+ STR2IOVEC(callID, v[3]);
+ STR2IOVEC(fromTag, v[5]);
+ if(toTag != NULL)
+ STR2IOVEC(toTag, v[7]);
+ // ignore return value
+ sendCommandRetry(RTPPROXY_RETRY_COUNT, v, (toTag != NULL) ? 8 : 6, gencookie());
+
+ if(callID != NULL)
+ free(callID);
+ if(callerAddr != NULL)
+ free(callerAddr);
+ if(calleeAddr != NULL)
+ free(calleeAddr);
+ if(fromTag != NULL)
+ free(fromTag);
+ if(toTag != NULL)
+ free(toTag);
+
+}
+
+void RtpProxyUtil::setTimeoutListener(TimeoutListener *timeoutListener) {
+ this->timeoutListener = timeoutListener;
+}
+
+void RtpProxyUtil::mediaTimeout() {
+ valid = false;
+ if(timeoutListener != NULL)
+ timeoutListener->onMediaTimeout();
+}
+
+unsigned int RtpProxyUtil::setupCaller(const char *callID, const char *callerAddr, int callerPort, const char *fromTag, bool callerAsymmetric) {
+ if(this->callID != NULL)
+ free(this->callID);
+ if((this->callID=(char *)malloc(strlen(callID) + 1))==NULL) {
+ return 0;
+ }
+ if(this->callerAddr != NULL)
+ free(this->callerAddr);
+ if((this->callerAddr=(char *)malloc(strlen(callerAddr) + 1))==NULL) {
+ return 0;
+ }
+ if(this->fromTag != NULL)
+ free(this->fromTag);
+ if((this->fromTag=(char *)malloc(strlen(fromTag) + 1))==NULL) {
+ return 0;
+ }
+ strcpy(this->callID, callID);
+ strcpy(this->callerAddr, callerAddr);
+ this->callerPort = callerPort;
+ strcpy(this->fromTag, fromTag);
+
+ char buf[BUF_SIZE];
+ struct iovec v[1 + 6 + 5] = {{NULL, 0}, {NULL, 0}, {(char *)" ", 1}, {NULL, 0},
+ {(char *)" ", 1}, {NULL, 7}, {(char *)" ", 1}, {NULL, 1}, {(char *)" ", 1}, {NULL, 0},
+ {(char *)" ", 1}, {NULL, 0}};
+ if(callerAsymmetric == true)
+ v[1].iov_base = (char *)"Ua";
+ else
+ v[1].iov_base = (char *)"Us";
+ v[1].iov_len = 2;
+ STR2IOVEC((char *)callID, v[3]);
+ STR2IOVEC((char *)callerAddr, v[5]);
+ sprintf(buf, "%d", callerPort);
+ STR2IOVEC(buf, v[7]);
+ STR2IOVEC((char *)fromTag, v[9]);
+ // STR2IOVEC(toTag, v[11]);
+ char *cp = sendCommandRetry(RTPPROXY_RETRY_COUNT, v, 10, gencookie());
+ if(cp == NULL)
+ throw new exception;
+ callerProxyPort = atoi(cp);
+ proxies[callerProxyPort] = this;
+ return callerProxyPort;
+}
+
+void RtpProxyUtil::ammendCaller(const char *callerAddr, int callerPort) {
+}
+
+unsigned int RtpProxyUtil::setupCallee(const char *calleeAddr, int calleePort, const char *toTag, bool calleeAsymmetric) {
+ if(this->calleeAddr != NULL)
+ free(this->calleeAddr);
+ if((this->calleeAddr=(char *)malloc(strlen(calleeAddr) + 1))==NULL) {
+ return 0;
+ }
+ if(this->toTag != NULL)
+ free(this->toTag);
+ if((this->toTag=(char *)malloc(strlen(toTag) + 1))==NULL) {
+ return 0;
+ }
+ strcpy(this->calleeAddr, calleeAddr);
+ this->calleePort = calleePort;
+ strcpy(this->toTag, toTag);
+
+ char buf[BUF_SIZE];
+ struct iovec v[1 + 6 + 5] = {{NULL, 0}, {NULL, 0}, {(char *)" ", 1}, {NULL, 0},
+ {(char *)" ", 1}, {NULL, 7}, {(char *)" ", 1}, {NULL, 1}, {(char *)" ", 1},
+{NULL, 0},
+ {(char *)" ", 1}, {NULL, 0}};
+ if(calleeAsymmetric == true)
+ v[1].iov_base = (char *)"La";
+ else
+ v[1].iov_base = (char *)"Ls";
+ v[1].iov_len = 2;
+ STR2IOVEC(callID, v[3]);
+ STR2IOVEC((char *)calleeAddr, v[5]);
+ sprintf(buf, "%d", calleePort);
+ STR2IOVEC(buf, v[7]);
+ STR2IOVEC(fromTag, v[9]);
+ STR2IOVEC((char *)toTag, v[11]);
+ char *cp = sendCommandRetry(RTPPROXY_RETRY_COUNT, v, 12, gencookie());
+ if(cp == NULL)
+ throw new exception;
+ calleeProxyPort = atoi(cp);
+ proxies[calleeProxyPort] = this;
+ return calleeProxyPort;
+}
+
+void RtpProxyUtil::ammendCallee(const char *calleeAddr, int calleePort) {
+}
+
+unsigned int RtpProxyUtil::getCallerProxyPort() {
+ return callerProxyPort;
+}
+
+unsigned int RtpProxyUtil::getCalleeProxyPort() {
+ return calleeProxyPort;
+}
+
+char *RtpProxyUtil::sendCommandRetry(int retries, struct iovec *v, int vcnt, char *my_cookie) {
+ int c = 0;
+ char *result;
+ while(c++ < retries) {
+ result = sendCommand(v, vcnt, my_cookie);
+ if(result != NULL)
+ return result;
+ }
+ return NULL;
+}
+
+char *RtpProxyUtil::sendCommand(struct iovec *v, int vcnt, char *my_cookie) {
+
+ struct sockaddr_un addr;
+ int fd, i, len;
+ char *cp;
+ static char buf[256];
+ struct pollfd fds[1];
+
+ len = 0;
+ cp = buf;
+ if (umode == 0) {
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_LOCAL;
+ strncpy(addr.sun_path, rtpproxy_sock,
+ sizeof(addr.sun_path) - 1);
+#ifdef HAVE_SOCKADDR_SA_LEN
+ addr.sun_len = strlen(addr.sun_path);
+#endif
+
+ fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+ if (fd < 0) {
+ B2BUA_LOG_ERR("send_rtpp_command: can't create socket");
+ return NULL;
+ }
+ if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ close(fd);
+ B2BUA_LOG_ERR("ERROR: send_rtpp_command: can't connect to RTP proxy: %s", addr.sun_path);
+ //perror("RtpProxyUtil");
+ return NULL;
+ }
+
+ do {
+ len = writev(fd, v + 1, vcnt - 1);
+ } while (len == -1 && errno == EINTR);
+ if (len <= 0) {
+ close(fd);
+ B2BUA_LOG_ERR("ERROR: send_rtpp_command: can't send command to a RTP proxy");
+ return NULL;
+ }
+ do {
+ len = read(fd, buf, sizeof(buf) - 1);
+ } while (len == -1 && errno == EINTR);
+ close(fd);
+ if (len <= 0) {
+ B2BUA_LOG_ERR("ERROR: send_rtpp_command: can't read reply from the RTP proxy, errno = %d", errno);
+ return NULL;
+ }
+ } else {
+ fds[0].fd = controlfd;
+ fds[0].events = POLLIN;
+ fds[0].revents = 0;
+ /* Drain input buffer */
+ while ((poll(fds, 1, 0) == 1) &&
+ ((fds[0].revents & POLLIN) != 0)) {
+ recv(controlfd, buf, sizeof(buf) - 1, 0);
+ fds[0].revents = 0;
+ }
+ v[0].iov_base = my_cookie;
+ v[0].iov_len = strlen((const char *)v[0].iov_base);
+ for (i = 0; i < rtpproxy_retr; i++) {
+ do {
+ len = writev(controlfd, v, vcnt);
+ } while (len == -1 && (errno == EINTR || errno == ENOBUFS));
+ if (len <= 0) {
+ /* LOG(L_ERR, "ERROR: send_rtpp_command: "
+ "can't send command to a RTP proxy\n"); */
+ B2BUA_LOG_ERR("ERROR: send_rtpp_command: can't send command to a RTP proxy");
+ return NULL;
+ }
+ while ((poll(fds, 1, rtpproxy_tout * 1000) == 1) &&
+ (fds[0].revents & POLLIN) != 0) {
+ do {
+ len = recv(controlfd, buf, sizeof(buf) - 1, 0);
+ } while (len == -1 && errno == EINTR);
+ if (len <= 0) {
+ /* LOG(L_ERR, "ERROR: send_rtpp_command: "
+ "can't read reply from a RTP proxy\n"); */
+ B2BUA_LOG_ERR("ERROR: send_rtpp_command:can't read reply from a RTP proxy");
+ return NULL;
+ }
+ if (len >= (v[0].iov_len - 1) &&
+ memcmp(buf, v[0].iov_base, (v[0].iov_len - 1)) == 0) {
+ len -= (v[0].iov_len - 1);
+ cp += (v[0].iov_len - 1);
+ if (len != 0) {
+ len--;
+ cp++;
+ }
+ goto out;
+ }
+ fds[0].revents = 0;
+ }
+ }
+ if (i == rtpproxy_retr) {
+ /* LOG(L_ERR, "ERROR: send_rtpp_command: "
+ "timeout waiting reply from a RTP proxy\n"); */
+ B2BUA_LOG_ERR("ERROR: send_rtpp_command: timeout waiting reply from a RTP proxy");
+ return NULL;
+ }
+ }
+
+out:
+ cp[len] = '\0';
+ return cp;
+
+}
+
+
+char *RtpProxyUtil::gencookie() {
+ static char cook[34];
+
+ sprintf(cook, "%d_%u ", (int)mypid, myseqn);
+ myseqn++;
+ return cook;
+}
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/RtpProxyUtil.hxx b/b2bua/RtpProxyUtil.hxx
new file mode 100644
index 0000000..bf602f7
--- /dev/null
+++ b/b2bua/RtpProxyUtil.hxx
@@ -0,0 +1,137 @@
+
+#ifndef __RtpProxyUtil_h
+#define __RtpProxyUtil_h
+
+#include <map>
+
+namespace b2bua
+{
+
+#define DEFAULT_RTPPROXY_SOCK "/var/run/rtpproxy.sock"
+#define DEFAULT_RTPPROXY_TIMEOUT_SOCK "/var/run/rtpproxy.timeout.sock"
+#define DEFAULT_RTPPROXY_RETR 5
+#define DEFAULT_RTPPROXY_TOUT 1
+
+#define BUF_SIZE 250
+
+class RtpProxyUtil {
+
+public:
+
+ class TimeoutListener {
+ public:
+ virtual ~TimeoutListener() {};
+ virtual void onMediaTimeout() = 0;
+ };
+
+
+private:
+
+
+ // Static variables for system wide settings
+ static int umode;
+ static char *rtpproxy_sock;
+ static int controlfd;
+ static char *timeout_sock;
+ static int timeoutfd;
+ static int timeout_clientfd;
+ static int rtpproxy_retr;
+ static int rtpproxy_tout;
+ static std::map<int, RtpProxyUtil *> proxies;
+
+ // Instance variables for per-instance data
+ pid_t mypid;
+ int myseqn;
+
+
+ TimeoutListener *timeoutListener;
+
+ bool valid;
+
+ char *callID;
+ char *callerAddr;
+ unsigned int callerPort;
+ char *calleeAddr;
+ unsigned int calleePort;
+ char *fromTag;
+ char *toTag;
+
+ unsigned int callerProxyPort;
+ unsigned int calleeProxyPort;
+
+protected:
+ static char *sendCommandRetry(int retries, struct iovec *v, int vcnt, char *my_cookie);
+ static char *sendCommand(struct iovec *v, int vcnt, char *my_cookie);
+ char *gencookie();
+
+ // called when a media timeout occurs
+ void mediaTimeout();
+
+public:
+
+ static void setSocket(const char *socket);
+ static void setTimeoutSocket(const char *socket);
+ static void init();
+ // check for timeout data from socket
+ static void do_timeouts();
+
+ RtpProxyUtil();
+ ~RtpProxyUtil();
+
+ void setTimeoutListener(TimeoutListener *timeoutListener);
+
+ // Inform rtpproxy of the caller's details
+ unsigned int setupCaller(const char *callID, const char *callerAddr, int callerPort, const char *fromTag, bool callerAsymmetric);
+ // ammend the caller's details (after the caller sends re-INVITE)
+ void ammendCaller(const char *callerAddr, int callerPort);
+ // Inform rtpproxy of the callee's details
+ unsigned int setupCallee(const char *calleeAddr, int calleePort, const char *toTag, bool calleeAsymmetric);
+ // ammend the callee's details
+ void ammendCallee(const char *calleeAddr, int calleePort);
+
+ unsigned int getCallerProxyPort();
+ unsigned int getCalleeProxyPort();
+
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/TaskManager.cxx b/b2bua/TaskManager.cxx
new file mode 100644
index 0000000..48493b3
--- /dev/null
+++ b/b2bua/TaskManager.cxx
@@ -0,0 +1,99 @@
+
+#include <cassert>
+#include <list>
+
+#include "Logging.hxx"
+#include "TaskManager.hxx"
+
+using namespace b2bua;
+using namespace std;
+
+TaskManager::TaskManager() {
+}
+
+void TaskManager::start() {
+ while(true) {
+ int incompleteCount = 0;
+ list<RecurringTask *>::iterator iterator = recurringTasks.begin();
+ while(iterator != recurringTasks.end()) {
+ // FIXME - read return value, remove completed tasks
+ RecurringTask *t = *iterator;
+ iterator++;
+ TaskResult r = t->doTaskProcessing();
+ switch(r) {
+ case TaskComplete:
+ recurringTasks.remove(t);
+ break;
+ case TaskNotComplete:
+ incompleteCount++;
+ break;
+ default:
+ // ignore any other return value
+ break;
+ }
+ }
+ if(incompleteCount == 0) {
+ // All tasks are done
+ B2BUA_LOG_NOTICE("all tasks complete");
+ return;
+ }
+ // FIXME - do scheduled tasks (not yet implemented)
+ }
+}
+
+void TaskManager::addRecurringTask(RecurringTask *t) {
+ recurringTasks.push_back(t);
+}
+
+void TaskManager::scheduleTask(ScheduledTask *t, time_t& executionTime) {
+ // FIXME - not yet implemented
+ B2BUA_LOG_CRIT("scheduleTask not implemented");
+ assert(0);
+}
+
+void TaskManager::stop() {
+ list<RecurringTask *>::iterator iterator = recurringTasks.begin();
+ while(iterator != recurringTasks.end()) {
+ RecurringTask *t = *iterator;
+ iterator++;
+ t->stop();
+ }
+}
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/b2bua/TaskManager.hxx b/b2bua/TaskManager.hxx
new file mode 100644
index 0000000..41cbbb6
--- /dev/null
+++ b/b2bua/TaskManager.hxx
@@ -0,0 +1,102 @@
+
+#ifndef __TaskManager_h
+#define __TaskManager_h
+
+#include <ctime>
+#include <list>
+
+namespace b2bua
+{
+
+/**
+ * The TaskManager keeps a record of all recurring tasks, and
+ * also tasks scheduled to take place at a specified time.
+ * It provides an efficient way of giving CPU time to each task.
+ * TaskManager is expected to be used with tasks that do not block
+ * or run for extended periods of time.
+ * TaskManager runs all tasks in a single thread.
+ */
+
+class TaskManager {
+
+public:
+
+ typedef enum TaskResult {
+ TaskComplete, // the task doesn't need to run again
+ TaskNotComplete, // the task would like to run again shortly
+ TaskIndefinite // the task can be run again, but doesn't
+ // object if the TaskManager stops
+ };
+
+ class RecurringTask {
+ public:
+ virtual ~RecurringTask() {};
+ virtual TaskResult doTaskProcessing() = 0;
+ virtual void stop() = 0;
+ };
+
+ class ScheduledTask {
+ public:
+ virtual ~ScheduledTask() {};
+ virtual void doTaskSchedule() = 0;
+ };
+
+ TaskManager();
+
+ /**
+ * Start the task manager - blocks until complete.
+ * Exits when all recurring tasks exit and no scheduled tasks remain.
+ */
+ void start();
+ void addRecurringTask(RecurringTask *t);
+ void scheduleTask(ScheduledTask *t, time_t& executionTime);
+
+ void stop();
+
+protected:
+ std::list<RecurringTask *> recurringTasks;
+ std::list<ScheduledTask *> scheduleTasks;
+
+};
+
+}
+
+#endif
+
+/* ====================================================================
+ *
+ * Copyright 2012 Daniel Pocock. 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 the author(s) nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) 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 AUTHOR(S) 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.
+ *
+ * ====================================================================
+ *
+ *
+ */
+
diff --git a/config.h.in b/config.h.in
index 73672f9..efa2f18 100644
--- a/config.h.in
+++ b/config.h.in
@@ -3,6 +3,9 @@
/* BUILD_APPS */
#undef BUILD_APPS
+/* BUILD_B2BUA */
+#undef BUILD_B2BUA
+
/* BUILD_ICHAT_GW */
#undef BUILD_ICHAT_GW
diff --git a/configure b/configure
index 714fd44..94e3ba8 100755
--- a/configure
+++ b/configure
@@ -757,6 +757,8 @@ BUILD_APPS_FALSE
BUILD_APPS_TRUE
BUILD_TFM_FALSE
BUILD_TFM_TRUE
+BUILD_B2BUA_FALSE
+BUILD_B2BUA_TRUE
LIBRADIUS_LIBADD
USE_RADIUS_CLIENT_FALSE
USE_RADIUS_CLIENT_TRUE
@@ -911,6 +913,7 @@ enable_dtls
with_mysql
with_geoip
with_radius
+with_b2bua
with_tfm
with_apps
with_ichat_gw
@@ -1576,6 +1579,7 @@ Optional Packages:
--with-mysql Link against MySQL client libraries
--with-geoip Link against MaxMind GeoIP libraries
--with-radius Link against RADIUS client libraries
+ --with-b2bua Build B2BUA lib, no extra dependencies
--with-tfm Build TFM, links against Netxx and cppunit
--with-apps Build apps, links against various things
--with-ichat-gw Build iChat gateway, links against gloox
@@ -5122,13 +5126,13 @@ if test "${lt_cv_nm_interface+set}" = set; then :
else
lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
- (eval echo "\"\$as_me:5125: $ac_compile\"" >&5)
+ (eval echo "\"\$as_me:5129: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5
- (eval echo "\"\$as_me:5128: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval echo "\"\$as_me:5132: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5
- (eval echo "\"\$as_me:5131: output\"" >&5)
+ (eval echo "\"\$as_me:5135: output\"" >&5)
cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -6334,7 +6338,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 6337 "configure"' > conftest.$ac_ext
+ echo '#line 6341 "configure"' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -8390,11 +8394,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8393: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8397: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:8397: \$? = $ac_status" >&5
+ echo "$as_me:8401: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -8729,11 +8733,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8732: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8736: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:8736: \$? = $ac_status" >&5
+ echo "$as_me:8740: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -8834,11 +8838,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8837: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8841: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:8841: \$? = $ac_status" >&5
+ echo "$as_me:8845: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -8889,11 +8893,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8892: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8896: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:8896: \$? = $ac_status" >&5
+ echo "$as_me:8900: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -11273,7 +11277,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11276 "configure"
+#line 11280 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11369,7 +11373,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11372 "configure"
+#line 11376 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -13325,11 +13329,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:13328: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13332: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:13332: \$? = $ac_status" >&5
+ echo "$as_me:13336: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -13424,11 +13428,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:13427: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13431: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:13431: \$? = $ac_status" >&5
+ echo "$as_me:13435: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -13476,11 +13480,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:13479: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13483: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:13483: \$? = $ac_status" >&5
+ echo "$as_me:13487: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -15080,6 +15084,33 @@ fi
if false; then
+ BUILD_B2BUA_TRUE=
+ BUILD_B2BUA_FALSE='#'
+else
+ BUILD_B2BUA_TRUE='#'
+ BUILD_B2BUA_FALSE=
+fi
+
+
+# Check whether --with-b2bua was given.
+if test "${with_b2bua+set}" = set; then :
+ withval=$with_b2bua;
+cat >>confdefs.h <<_ACEOF
+#define BUILD_B2BUA /**/
+_ACEOF
+
+ if true; then
+ BUILD_B2BUA_TRUE=
+ BUILD_B2BUA_FALSE='#'
+else
+ BUILD_B2BUA_TRUE='#'
+ BUILD_B2BUA_FALSE=
+fi
+
+fi
+
+
+ if false; then
BUILD_TFM_TRUE=
BUILD_TFM_FALSE='#'
else
@@ -15671,7 +15702,7 @@ fi
-ac_config_files="$ac_config_files Makefile rutil/dns/ares/Makefile rutil/Makefile rutil/test/Makefile resip/Makefile resip/stack/Makefile resip/stack/test/Makefile resip/dum/Makefile resip/dum/test/Makefile resip/certs/Makefile repro/Makefile repro/reprocmd/Makefile repro/test/Makefile tfm/Makefile tfm/repro/Makefile tfm/tfdum/Makefile apps/Makefile apps/clicktocall/Makefile apps/ichat-gw/Makefile apps/ichat-gw/jabberconnector/Makefile apps/sipdial/Makefile resip.spec reTurn/Makefile reTurn/test/Makefile reTurn/client/Makefile reflow/Makefile resip/recon/Makefile presSvr/Makefile p2p/s2c/s2c/Makefile p2p/Makefile"
+ac_config_files="$ac_config_files Makefile rutil/dns/ares/Makefile rutil/Makefile rutil/test/Makefile resip/Makefile resip/stack/Makefile resip/stack/test/Makefile resip/dum/Makefile resip/dum/test/Makefile resip/certs/Makefile repro/Makefile repro/reprocmd/Makefile repro/test/Makefile b2bua/Makefile tfm/Makefile tfm/repro/Makefile tfm/tfdum/Makefile apps/Makefile apps/clicktocall/Makefile apps/ichat-gw/Makefile apps/ichat-gw/jabberconnector/Makefile apps/sipdial/Makefile resip.spec reTurn/Makefile reTurn/test/Makefile reTurn/client/Makefile reflow/Makefile resip/recon/Makefile presSvr/Makefile p2p/s2c/s2c/Makefile p2p/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -15851,6 +15882,14 @@ if test -z "${USE_RADIUS_CLIENT_TRUE}" && test -z "${USE_RADIUS_CLIENT_FALSE}";
as_fn_error $? "conditional \"USE_RADIUS_CLIENT\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${BUILD_B2BUA_TRUE}" && test -z "${BUILD_B2BUA_FALSE}"; then
+ as_fn_error $? "conditional \"BUILD_B2BUA\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${BUILD_B2BUA_TRUE}" && test -z "${BUILD_B2BUA_FALSE}"; then
+ as_fn_error $? "conditional \"BUILD_B2BUA\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
if test -z "${BUILD_TFM_TRUE}" && test -z "${BUILD_TFM_FALSE}"; then
as_fn_error $? "conditional \"BUILD_TFM\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -16865,6 +16904,7 @@ do
"repro/Makefile") CONFIG_FILES="$CONFIG_FILES repro/Makefile" ;;
"repro/reprocmd/Makefile") CONFIG_FILES="$CONFIG_FILES repro/reprocmd/Makefile" ;;
"repro/test/Makefile") CONFIG_FILES="$CONFIG_FILES repro/test/Makefile" ;;
+ "b2bua/Makefile") CONFIG_FILES="$CONFIG_FILES b2bua/Makefile" ;;
"tfm/Makefile") CONFIG_FILES="$CONFIG_FILES tfm/Makefile" ;;
"tfm/repro/Makefile") CONFIG_FILES="$CONFIG_FILES tfm/repro/Makefile" ;;
"tfm/tfdum/Makefile") CONFIG_FILES="$CONFIG_FILES tfm/tfdum/Makefile" ;;
diff --git a/configure.ac b/configure.ac
index 9316da0..3ddebe4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -200,6 +200,12 @@ AC_ARG_WITH(radius,
AM_CONDITIONAL(USE_RADIUS_CLIENT, true)],
[ AC_SUBST(LIBRADIUS_LIBADD, "")])
+AM_CONDITIONAL(BUILD_B2BUA, false)
+AC_ARG_WITH(b2bua,
+[ --with-b2bua Build B2BUA lib, no extra dependencies],
+ [AC_DEFINE_UNQUOTED(BUILD_B2BUA, , BUILD_B2BUA)
+ AM_CONDITIONAL(BUILD_B2BUA, true)], )
+
AM_CONDITIONAL(BUILD_TFM, false)
AC_ARG_WITH(tfm,
[ --with-tfm Build TFM, links against Netxx and cppunit],
@@ -254,6 +260,7 @@ AC_OUTPUT(Makefile \
repro/Makefile \
repro/reprocmd/Makefile \
repro/test/Makefile \
+ b2bua/Makefile \
tfm/Makefile \
tfm/repro/Makefile \
tfm/tfdum/Makefile \
--
reSIProcate
More information about the Pkg-voip-commits
mailing list