mirror of https://github.com/sipwise/sems.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
310 lines
7.2 KiB
310 lines
7.2 KiB
/*
|
|
* Copyright (C) 2006-2007 iptego GmbH
|
|
*
|
|
* This file is part of SEMS, a free SIP media server.
|
|
*
|
|
* SEMS is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* For a license to use the sems software under conditions
|
|
* other than those described here, or to purchase support for this
|
|
* software, please contact iptel.org by e-mail at the following addresses:
|
|
* info@iptel.org
|
|
*
|
|
* SEMS is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
#ifndef _AM_B2ABSession_H
|
|
#define _AM_B2ABSession_H
|
|
|
|
#include "AmSession.h"
|
|
#include "AmSipDialog.h"
|
|
#include "AmAdvancedAudio.h"
|
|
#include "SampleArray.h"
|
|
#include <string>
|
|
using std::string;
|
|
|
|
#include <map>
|
|
|
|
class AmSessionAudioConnector;
|
|
|
|
enum { B2ABTerminateLeg,
|
|
B2ABConnectLeg,
|
|
B2ABConnectEarlyAudio,
|
|
B2ABConnectAudio,
|
|
B2ABConnectOtherLegFailed,
|
|
B2ABConnectOtherLegException,
|
|
B2ABOtherLegRinging
|
|
};
|
|
|
|
/** \brief base class for event in B2AB session */
|
|
struct B2ABEvent: public AmEvent
|
|
{
|
|
B2ABEvent(int ev_id)
|
|
: AmEvent(ev_id)
|
|
{}
|
|
};
|
|
|
|
struct B2ABOtherLegRingingEvent: public B2ABEvent
|
|
{
|
|
B2ABOtherLegRingingEvent()
|
|
: B2ABEvent(B2ABOtherLegRinging)
|
|
{}
|
|
};
|
|
|
|
/** \brief trigger connecting the audio in B2AB session */
|
|
struct B2ABConnectAudioEvent: public B2ABEvent
|
|
{
|
|
B2ABConnectAudioEvent()
|
|
: B2ABEvent(B2ABConnectAudio)
|
|
{}
|
|
};
|
|
|
|
/** \brief trigger connecting the audio in B2AB session */
|
|
struct B2ABConnectEarlyAudioEvent: public B2ABEvent
|
|
{
|
|
B2ABConnectEarlyAudioEvent()
|
|
: B2ABEvent(B2ABConnectEarlyAudio)
|
|
{}
|
|
};
|
|
|
|
/** \brief trigger connecting the callee leg in B2AB session */
|
|
struct B2ABConnectLegEvent: public B2ABEvent
|
|
{
|
|
string remote_party;
|
|
string remote_uri;
|
|
string local_party;
|
|
string local_uri;
|
|
string callgroup;
|
|
string headers;
|
|
|
|
B2ABConnectLegEvent(const string& remote_party,
|
|
const string& remote_uri,
|
|
const string& local_party,
|
|
const string& local_uri,
|
|
const string& callgroup,
|
|
const string& headers = "")
|
|
: B2ABEvent(B2ABConnectLeg),
|
|
remote_party(remote_party),
|
|
remote_uri(remote_uri),
|
|
local_party(local_party),
|
|
local_uri(local_uri),
|
|
callgroup(callgroup),
|
|
headers(headers)
|
|
{}
|
|
};
|
|
|
|
/** \brief event fired if an exception occured while creating B leg */
|
|
struct B2ABConnectOtherLegExceptionEvent: public B2ABEvent {
|
|
|
|
unsigned int code;
|
|
string reason;
|
|
|
|
B2ABConnectOtherLegExceptionEvent(unsigned int code,
|
|
const string& reason)
|
|
: B2ABEvent(B2ABConnectOtherLegException),
|
|
code(code), reason(reason)
|
|
{}
|
|
};
|
|
|
|
/** \brief event fired if the B leg could not be connected (e.g. busy) */
|
|
struct B2ABConnectOtherLegFailedEvent: public B2ABEvent {
|
|
|
|
unsigned int code;
|
|
string reason;
|
|
|
|
B2ABConnectOtherLegFailedEvent(unsigned int code,
|
|
const string& reason)
|
|
: B2ABEvent(B2ABConnectOtherLegFailed),
|
|
code(code), reason(reason)
|
|
{}
|
|
};
|
|
|
|
/**
|
|
* \brief Base class for Sessions in B2ABUA mode.
|
|
*
|
|
* It has two legs: Callee- and caller-leg.
|
|
*/
|
|
class AmB2ABSession: public AmSession
|
|
{
|
|
|
|
protected:
|
|
|
|
/** local tag of the other leg */
|
|
string other_id;
|
|
|
|
/** reference to the audio connector - caution: not owned by callee dialog! */
|
|
AmSessionAudioConnector* connector;
|
|
|
|
/** Requests received for relaying */
|
|
std::map<int,AmSipRequest> recvd_req;
|
|
|
|
void clear_other();
|
|
|
|
/** Relay one event to the other side. */
|
|
virtual void relayEvent(AmEvent* ev);
|
|
|
|
/** Terminate our leg and forget the other. */
|
|
virtual void terminateLeg();
|
|
|
|
/** Terminate the other leg and forget it.*/
|
|
virtual void terminateOtherLeg();
|
|
|
|
|
|
/** B2ABEvent handler */
|
|
virtual void onB2ABEvent(B2ABEvent* ev);
|
|
|
|
/* // Other leg received a BYE */
|
|
/* virtual void onOtherBye(const AmSipRequest& req); */
|
|
|
|
/* /\** INVITE from other leg has been replied *\/ */
|
|
/* virtual void onOtherReply(const AmSipReply& reply); */
|
|
|
|
/** @see AmEventQueue */
|
|
void process(AmEvent* event);
|
|
|
|
public:
|
|
|
|
AmB2ABSession();
|
|
AmB2ABSession(const string& other_local_tag);
|
|
virtual ~AmB2ABSession();
|
|
|
|
void onBye(const AmSipRequest& req);
|
|
|
|
/** connect audio stream to the other session */
|
|
virtual void connectSession();
|
|
|
|
/** reverse operation of connectSession */
|
|
void disconnectSession();
|
|
|
|
};
|
|
|
|
class AmB2ABCalleeSession;
|
|
|
|
/** \brief Caller leg of a B2AB session */
|
|
class AmB2ABCallerSession: public AmB2ABSession
|
|
{
|
|
public:
|
|
enum CalleeStatus {
|
|
None=0,
|
|
NoReply,
|
|
Early,
|
|
Ringing,
|
|
Connected
|
|
};
|
|
|
|
private:
|
|
// Callee Status
|
|
CalleeStatus callee_status;
|
|
|
|
virtual void setupCalleeSession(AmB2ABCalleeSession* callee_session,
|
|
B2ABConnectLegEvent* ev);
|
|
|
|
protected:
|
|
|
|
virtual AmB2ABCalleeSession* createCalleeSession();
|
|
void relayEvent(AmEvent* ev);
|
|
|
|
public:
|
|
AmB2ABCallerSession();
|
|
~AmB2ABCallerSession();
|
|
|
|
CalleeStatus getCalleeStatus() { return callee_status; }
|
|
|
|
void connectCallee(const string& remote_party,
|
|
const string& remote_uri,
|
|
const string& local_party,
|
|
const string& local_uri,
|
|
const string& headers = "");
|
|
|
|
// @see AmB2ABSession
|
|
void terminateOtherLeg();
|
|
|
|
protected:
|
|
void onB2ABEvent(B2ABEvent* ev);
|
|
void onBeforeDestroy();
|
|
};
|
|
|
|
/** \brief Callee leg of a B2AB session */
|
|
class AmB2ABCalleeSession: public AmB2ABSession
|
|
{
|
|
bool is_connected;
|
|
|
|
public:
|
|
AmB2ABCalleeSession(const string& other_local_tag,
|
|
AmSessionAudioConnector* callers_connector);
|
|
~AmB2ABCalleeSession();
|
|
|
|
void onEarlySessionStart();
|
|
void onSessionStart();
|
|
void onSipReply(const AmSipRequest& req, const AmSipReply& rep,
|
|
AmSipDialog::Status old_dlg_status);
|
|
|
|
protected:
|
|
void onB2ABEvent(B2ABEvent* ev);
|
|
void onBeforeDestroy();
|
|
AmCondition<bool>* released;
|
|
};
|
|
|
|
/** BRIDGE_DELAY is needed because of possible different packet sizes */
|
|
#define BRIDGE_DELAY (30.0/1000.0) // 30ms
|
|
|
|
/**
|
|
* \brief connects the audio of two sessions together
|
|
*/
|
|
class AmSessionAudioConnector {
|
|
|
|
private:
|
|
AmAudioDelay audio_connectors[2];
|
|
string tag_sess[2];
|
|
bool connected[2];
|
|
AmMutex tag_mut;
|
|
|
|
AmCondition<bool> released;
|
|
|
|
public:
|
|
/** create a connector, connect audio to sess */
|
|
AmSessionAudioConnector()
|
|
: released(true)
|
|
{
|
|
connected[0] = false;
|
|
connected[1] = false;
|
|
audio_connectors[0].setDelay(BRIDGE_DELAY);
|
|
audio_connectors[1].setDelay(BRIDGE_DELAY);
|
|
}
|
|
|
|
~AmSessionAudioConnector() {}
|
|
|
|
/** connect audio to sess */
|
|
void connectSession(AmSession* sess);
|
|
|
|
/** disconnect session
|
|
* @return whether connector is still connected after disconnect
|
|
*/
|
|
bool disconnectSession(AmSession* sess);
|
|
|
|
/** mark as in use by entity not owning it */
|
|
void block();
|
|
|
|
/** mark as released by entity not owning it */
|
|
void release();
|
|
|
|
/** wait until released by everyone */
|
|
void waitReleased();
|
|
};
|
|
|
|
#endif
|
|
|
|
// Local Variables:
|
|
// mode:C++
|
|
// End:
|
|
|