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.
364 lines
9.0 KiB
364 lines
9.0 KiB
/*
|
|
* $Id: AmSession.h,v 1.20.2.5 2005/08/31 13:54:29 rco Exp $
|
|
*
|
|
* Copyright (C) 2002-2003 Fhg Fokus
|
|
*
|
|
* 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 ser 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 _AmSession_h_
|
|
#define _AmSession_h_
|
|
|
|
#include "AmRtpStream.h"
|
|
#include "AmThread.h"
|
|
//#include "AmRequest.h"
|
|
#include "AmEventQueue.h"
|
|
#include "AmRtpAudio.h"
|
|
#include "AmDtmfDetector.h"
|
|
#include "AmSipRequest.h"
|
|
#include "AmSipDialog.h"
|
|
#include "AmSipEvent.h"
|
|
#include "AmApi.h"
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <queue>
|
|
#include <map>
|
|
using std::string;
|
|
using std::vector;
|
|
using std::queue;
|
|
using std::map;
|
|
using std::pair;
|
|
|
|
class AmSessionFactory;
|
|
class AmDtmfEvent;
|
|
|
|
/**
|
|
* \brief Interface for SIP events signaling plugins implement
|
|
*
|
|
* Signaling plugins must inherite from this class.
|
|
*/
|
|
class AmSessionEventHandler
|
|
{
|
|
public:
|
|
AmSession* s;
|
|
bool destroy;
|
|
|
|
AmSessionEventHandler(AmSession* s)
|
|
: destroy(true),s(s) {}
|
|
|
|
virtual ~AmSessionEventHandler() {}
|
|
/*
|
|
* All the methods return true if event processing
|
|
* should stopped after calling them.
|
|
*/
|
|
virtual bool process(AmEvent*);
|
|
virtual bool onSipEvent(AmSipEvent*);
|
|
virtual bool onSipRequest(const AmSipRequest&);
|
|
virtual bool onSipReply(const AmSipReply&);
|
|
|
|
virtual bool onSendRequest(const string& method,
|
|
const string& content_type,
|
|
const string& body,
|
|
string& hdrs);
|
|
|
|
virtual bool onSendReply(const AmSipRequest& req,
|
|
unsigned int code,
|
|
const string& reason,
|
|
const string& content_type,
|
|
const string& body,
|
|
string& hdrs);
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
* \brief Implements the behavior of one session
|
|
*
|
|
* The session is identified by Call-ID, From-Tag and To-Tag.
|
|
*/
|
|
class AmSession : public AmThread,
|
|
public AmEventQueue,
|
|
public AmEventHandler,
|
|
public AmSipDialogEventHandler
|
|
{
|
|
AmMutex audio_mut;
|
|
AmAudio* input;
|
|
AmAudio* output;
|
|
|
|
SdpPayload payload;
|
|
bool negotiate_onreply;
|
|
|
|
AmDtmfDetector m_dtmfDetector;
|
|
AmDtmfEventQueue m_dtmfEventQueue;
|
|
bool m_dtmfDetectionEnabled;
|
|
|
|
vector<AmSessionEventHandler*> ev_handlers;
|
|
|
|
/** @see AmThread::run() */
|
|
void run();
|
|
|
|
/** @see AmThread::on_stop() */
|
|
void on_stop();
|
|
|
|
AmCondition<bool> sess_stopped;
|
|
AmCondition<bool> detached;
|
|
|
|
friend class AmMediaProcessor;
|
|
friend class AmMediaProcessorThread;
|
|
friend class AmSessionContainer;
|
|
friend class AmSessionFactory;
|
|
|
|
// this is the call group - by default local tag
|
|
string callgroup;
|
|
|
|
protected:
|
|
AmSdp sdp;
|
|
AmRtpAudio rtp_str;
|
|
|
|
public:
|
|
AmSipDialog dlg;
|
|
|
|
/**
|
|
* \brief Exception occured in a Session
|
|
*
|
|
* Session (creation) should be aborted and replied with code/reason.
|
|
*/
|
|
struct Exception {
|
|
int code;
|
|
string reason;
|
|
Exception(int c, string r) : code(c), reason(r) {}
|
|
};
|
|
|
|
/**
|
|
* Session constructor.
|
|
*/
|
|
AmSession();
|
|
|
|
virtual ~AmSession();
|
|
|
|
/**
|
|
* @see AmEventHandler
|
|
*/
|
|
void process(AmEvent*);
|
|
|
|
void addHandler(AmSessionEventHandler*);
|
|
|
|
/**
|
|
* Set the call group for this call.
|
|
*
|
|
* Note: this must be set before inserting
|
|
* the session to the scheduler!
|
|
*/
|
|
void setCallgroup(const string& cg);
|
|
string getCallgroup() { return callgroup; }
|
|
|
|
/**
|
|
* Accept the SDP proposal
|
|
* thus setting up audio stream
|
|
*/
|
|
int acceptAudio(const string& body,
|
|
const string& hdrs = "",
|
|
string* sdp_reply=0);
|
|
|
|
/**
|
|
* Lock and unlock audio input & output
|
|
* (inclusive RTP stream)
|
|
*/
|
|
void lockAudio();
|
|
void unlockAudio();
|
|
|
|
/**
|
|
* Audio input & output get methods.
|
|
* Note: audio must be locked.
|
|
*/
|
|
AmAudio* getInput() { return input; }
|
|
AmAudio* getOutput(){ return output;}
|
|
|
|
/**
|
|
* Audio input & output set methods.
|
|
* Note: audio will be locked by the methods.
|
|
*/
|
|
void setInput(AmAudio* in);
|
|
void setOutput(AmAudio* out);
|
|
void setInOut(AmAudio* in, AmAudio* out);
|
|
|
|
/**
|
|
* Clears input & ouput (no need to lock)
|
|
*/
|
|
void clearAudio();
|
|
|
|
/** setter for rtp_str->mute */
|
|
void setMute(bool mute) { rtp_str.mute = mute; }
|
|
|
|
/** Gets the Session's call ID */
|
|
const string& getCallID() const;
|
|
|
|
/** Gets the Session's remote tag */
|
|
const string& getRemoteTag()const ;
|
|
|
|
/** Gets the Session's local tag */
|
|
const string& getLocalTag() const;
|
|
void setLocalTag(const string& tag);
|
|
|
|
// AmSipDialog& getDialog() { return dlg; }
|
|
|
|
/** Gets the current RTP payload */
|
|
const SdpPayload* getPayload();
|
|
|
|
/** Gets the port number of the remote part of the session */
|
|
int getRPort();
|
|
|
|
|
|
/** Set whether on positive reply session should be negotiated */
|
|
void setNegotiateOnReply(bool n) { negotiate_onreply = n; }
|
|
|
|
/** handle SDP negotiation: only for INVITEs & re-INVITEs */
|
|
virtual void negotiate(const string& sdp_body,
|
|
bool force_symmetric_rtp,
|
|
string* sdp_reply);
|
|
|
|
void sendUpdate();
|
|
void sendReinvite();
|
|
void sendInvite();
|
|
|
|
/**
|
|
* Destroy the session.
|
|
* It causes the session to be erased from the active session list
|
|
* and added to the dead session list.
|
|
* @see AmSessionContainer
|
|
*/
|
|
void destroy();
|
|
|
|
/**
|
|
* Signals the session it should stop.
|
|
* This will cause the session to be able
|
|
* to exit the main loop.
|
|
*/
|
|
void setStopped() { sess_stopped.set(true); }
|
|
|
|
/**
|
|
* Has the session already been stopped ?
|
|
*/
|
|
bool getStopped() { return sess_stopped.get(); }
|
|
|
|
bool getDetached() { return detached.get(); }
|
|
|
|
/**
|
|
* Creates a new Id which can be used within sessions.
|
|
*/
|
|
static string getNewId();
|
|
|
|
/**
|
|
* Entry point for DTMF events
|
|
*/
|
|
void postDtmfEvent(AmDtmfEvent *);
|
|
|
|
void processDtmfEvents();
|
|
bool isDtmfDetectionEnabled() { return m_dtmfDetectionEnabled; }
|
|
void setDtmfDetectionEnabled(bool e) { m_dtmfDetectionEnabled = e; }
|
|
void putDtmfAudio(const unsigned char *buf, int size, int user_ts);
|
|
/** event handler for apps to use*/
|
|
virtual void onDtmf(int event, int duration);
|
|
|
|
/**
|
|
* onStart will be called before everything else.
|
|
*/
|
|
virtual void onStart(){}
|
|
|
|
/**
|
|
* onInvite will be called if an INVITE or re-INVITE
|
|
* has been received for the session.
|
|
*/
|
|
virtual void onInvite(const AmSipRequest& req);
|
|
|
|
/**
|
|
* onCancel will be called if a CANCEL for a running
|
|
* dialog has been received. At this point, the CANCEL
|
|
* transaction has been replied with 200.
|
|
*
|
|
* A normal plug-in does not have to do anything special,
|
|
* as normal dialogs are immediatly replied with 200
|
|
* or error code.
|
|
*
|
|
* Note: You are still responsible for responding the
|
|
* initial transaction.
|
|
*/
|
|
virtual void onCancel(){}
|
|
|
|
/**
|
|
* onSessionStart will be called after call setup.
|
|
*
|
|
* Throw AmSession::Exception if you want to
|
|
* signal any error.
|
|
*
|
|
* Warning:
|
|
* Sems will NOT send any BYE on his own.
|
|
*/
|
|
virtual void onSessionStart(const AmSipRequest& req){}
|
|
|
|
/**
|
|
* onSessionStart method for calls originating
|
|
* from SEMS.
|
|
*
|
|
* Throw AmSession::Exception if you want to
|
|
* signal any error.
|
|
*
|
|
* Warning:
|
|
* Sems will NOT send any BYE on his own.
|
|
*/
|
|
virtual void onSessionStart(const AmSipReply& reply){}
|
|
|
|
/**
|
|
* @see AmDialogState
|
|
*/
|
|
virtual void onBye(const AmSipRequest& req);
|
|
|
|
/**
|
|
* Entry point for SIP events
|
|
*/
|
|
virtual void onSipEvent(AmSipEvent* sip_ev);
|
|
virtual void onSipRequest(const AmSipRequest& req);
|
|
virtual void onSipReply(const AmSipReply& reply);
|
|
|
|
/* only called by AmSipDialog */
|
|
virtual void onSendRequest(const string& method,
|
|
const string& content_type,
|
|
const string& body,
|
|
string& hdrs);
|
|
|
|
virtual void onSendReply(const AmSipRequest& req,
|
|
unsigned int code,
|
|
const string& reason,
|
|
const string& content_type,
|
|
const string& body,
|
|
string& hdrs);
|
|
};
|
|
|
|
|
|
#endif
|
|
|
|
// Local Variables:
|
|
// mode:C++
|
|
// End:
|
|
|