yate/modules/libypri.h

269 lines
6.6 KiB
C
Raw Normal View History

/**
* libypri.h
* This file is part of the YATE Project http://YATE.null.ro
*
* Common C++ base classes for PRI cards telephony drivers
*
* Yet Another Telephony Engine - a fully featured software PBX and IVR
* Copyright (C) 2004 Null Team
*
* This program 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.
*
* This program 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <yatephone.h>
namespace TelEngine {
#define bitswap(v) bitswap_table[v]
static unsigned char bitswap_table[256];
static void bitswap_init()
{
for (unsigned int c = 0; c <= 255; c++) {
unsigned char v = 0;
for (int b = 0; b <= 7; b++)
if (c & (1 << b))
v |= (0x80 >> b);
bitswap_table[c] = v;
}
}
class Fifo
{
public:
Fifo(int buflen = 0);
~Fifo();
void clear();
void put(unsigned char value);
unsigned char get();
private:
int m_buflen;
int m_head;
int m_tail;
unsigned char* m_buffer;
};
class PriChan;
class PriSpan : public GenObject, public Thread
{
friend class WpData;
public:
static PriSpan *create(int span, int chan1, int nChans, int dChan, int netType,
int switchType, int dialPlan, int presentation,
int overlapDial, int nsf = YATE_NSF_DEFAULT);
virtual ~PriSpan();
virtual void run();
inline struct pri *pri()
{ return m_pri; }
inline int span() const
{ return m_span; }
inline bool belongs(int chan) const
{ return (chan >= m_offs) && (chan < m_offs+m_nchans); }
inline int chan1() const
{ return m_offs; }
inline int chans() const
{ return m_nchans; }
inline int bchans() const
{ return m_bchans; }
inline int dplan() const
{ return m_dplan; }
inline int pres() const
{ return m_pres; }
inline unsigned int overlapped() const
{ return m_overlapped; }
inline bool outOfOrder() const
{ return !m_ok; }
int findEmptyChan(int first = 0, int last = 65535) const;
WpChan *getChan(int chan) const;
void idle();
static u_int64_t restartPeriod;
static bool dumpEvents;
private:
PriSpan(struct pri *_pri, int span, int first, int chans, int dchan, int fd, int dplan, int pres, int overlapDial);
static struct pri *makePri(int fd, int dchan, int nettype, int swtype, int overlapDial, int nsf);
void handleEvent(pri_event &ev);
bool validChan(int chan) const;
void restartChan(int chan, bool outgoing, bool force = false);
void ringChan(int chan, pri_event_ring &ev);
void infoChan(int chan, pri_event_ring &ev);
void hangupChan(int chan,pri_event_hangup &ev);
void ackChan(int chan);
void answerChan(int chan);
void proceedingChan(int chan);
int m_span;
int m_offs;
int m_nchans;
int m_bchans;
int m_fd;
int m_dplan;
int m_pres;
unsigned int m_overlapped;
struct pri *m_pri;
u_int64_t m_restart;
WpChan **m_chans;
WpData *m_data;
bool m_ok;
};
class WpSource : public DataSource
{
public:
WpSource(WpChan *owner,unsigned int bufsize,const char* format);
~WpSource();
void put(unsigned char val);
private:
WpChan *m_owner;
unsigned int m_bufpos;
DataBlock m_buf;
};
class WpConsumer : public DataConsumer, public Fifo
{
public:
WpConsumer(WpChan *owner,unsigned int bufsize,const char* format);
~WpConsumer();
virtual void Consume(const DataBlock &data, unsigned long timeDelta);
private:
WpChan *m_owner;
DataBlock m_buffer;
};
class PriChan : public DataEndpoint
{
friend class WpSource;
friend class WpConsumer;
friend class WpData;
public:
WpChan(PriSpan *parent, int chan, unsigned int bufsize);
virtual ~WpChan();
virtual void disconnected(bool final, const char *reason);
virtual bool nativeConnect(DataEndpoint *peer);
inline PriSpan *span() const
{ return m_span; }
inline int chan() const
{ return m_chan; }
inline int absChan() const
{ return m_abschan; }
inline bool inUse() const
{ return (m_ring || m_call); }
void ring(q931_call *call = 0);
void hangup(int cause = PRI_CAUSE_INVALID_MSG_UNSPECIFIED);
void sendDigit(char digit);
void gotDigits(const char *digits);
bool call(Message &msg, const char *called = 0);
bool answer();
void answered();
void idle();
void restart(bool outgoing = false);
bool openData(const char* format);
void closeData();
inline void setTimeout(u_int64_t tout)
{ m_timeout = tout ? Time::now()+tout : 0; }
const char *status() const;
const String& id() const
{ return m_id; }
bool isISDN() const
{ return m_isdn; }
inline void setTarget(const char *target = 0)
{ m_targetid = target; }
inline const String& getTarget() const
{ return m_targetid; }
private:
PriSpan *m_span;
int m_chan;
bool m_ring;
u_int64_t m_timeout;
q931_call *m_call;
unsigned int m_bufsize;
int m_abschan;
bool m_isdn;
String m_id;
String m_targetid;
WpSource* m_wp_s;
WpConsumer* m_wp_c;
};
class WpData : public Thread
{
public:
WpData(PriSpan* span);
~WpData();
virtual void run();
private:
PriSpan* m_span;
int m_fd;
unsigned char* m_buffer;
WpChan **m_chans;
};
class WpHandler : public MessageHandler
{
public:
WpHandler() : MessageHandler("call.execute") { }
virtual bool received(Message &msg);
};
class WpDropper : public MessageHandler
{
public:
WpDropper() : MessageHandler("call.drop") { }
virtual bool received(Message &msg);
};
class StatusHandler : public MessageHandler
{
public:
StatusHandler() : MessageHandler("engine.status") { }
virtual bool received(Message &msg);
};
class WpChanHandler : public MessageReceiver
{
public:
enum {
Ringing,
Answered,
DTMF,
};
virtual bool received(Message &msg, int id);
};
class WanpipePlugin : public Plugin
{
friend class PriSpan;
friend class WpHandler;
public:
WanpipePlugin();
virtual ~WanpipePlugin();
virtual void initialize();
virtual bool isBusy() const;
PriSpan *findSpan(int chan);
WpChan *findChan(const char *id);
WpChan *findChan(int first = -1, int last = -1);
ObjList m_spans;
Mutex mutex;
};
}
/* vi: set ts=8 sw=4 sts=4 noet: */