yate/modules/libypri.h

249 lines
6.9 KiB
C++

/**
* 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-2006 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <yatephone.h>
extern "C" {
#include <libpri.h>
}
namespace TelEngine {
class Fifo
{
public:
Fifo(int buflen = 0);
~Fifo();
void clear();
bool put(unsigned char value);
unsigned int put(const unsigned char* buf, unsigned int length);
unsigned char get();
private:
int m_buflen;
int m_head;
int m_tail;
unsigned char* m_buffer;
};
class DataErrors
{
public:
inline DataErrors()
: m_events(0), m_bytes(0)
{ }
inline void update(unsigned int nbytes)
{ m_events++; m_bytes += nbytes; }
inline void clear()
{ m_events = 0; m_bytes = 0; }
inline unsigned int events() const
{ return m_events; }
inline unsigned long bytes() const
{ return m_bytes; }
private:
unsigned int m_events;
unsigned long m_bytes;
};
class PriChan;
class PriDriver;
class PriSpan : public GenObject, public Mutex
{
public:
virtual ~PriSpan();
inline struct pri *pri()
{ return m_pri; }
inline PriDriver* driver() const
{ return m_driver; }
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 inband() const
{ return m_inband; }
inline bool outOfOrder() const
{ return !m_ok; }
inline int buflen() const
{ return m_buflen; }
inline int layer1() const
{ return m_layer1; }
int findEmptyChan(int first = 0, int last = 65535) const;
PriChan *getChan(int chan) const;
void idle();
protected:
PriSpan(struct pri *_pri, PriDriver* driver, int span, int first, int chans, int dchan, Configuration& cfg, const String& sect);
void runEvent(bool idleRun);
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 digitsChan(int chan, const char* digits);
void hangupChan(int chan,pri_event_hangup &ev);
void ackChan(int chan);
void answerChan(int chan);
void proceedingChan(int chan);
void ringingChan(int chan);
PriDriver* m_driver;
int m_span;
int m_offs;
int m_nchans;
int m_bchans;
int m_dplan;
int m_pres;
int m_buflen;
int m_layer1;
bool m_inband;
unsigned int m_overlapped;
String m_callednumber;
struct pri *m_pri;
u_int64_t m_restart;
u_int64_t m_restartPeriod;
bool m_dumpEvents;
PriChan **m_chans;
bool m_ok;
};
class PriSource : public DataSource
{
public:
PriSource(PriChan *owner, const char* format, unsigned int bufsize);
virtual ~PriSource();
protected:
PriChan *m_owner;
DataBlock m_buffer;
};
class PriConsumer : public DataConsumer
{
public:
PriConsumer(PriChan *owner, const char* format, unsigned int bufsize);
virtual ~PriConsumer();
protected:
PriChan *m_owner;
DataBlock m_buffer;
};
class PriChan : public Channel
{
friend class PriSource;
friend class PriConsumer;
public:
virtual ~PriChan();
virtual void disconnected(bool final, const char *reason);
virtual bool nativeConnect(DataEndpoint *peer);
virtual bool msgRinging(Message& msg);
virtual bool msgAnswered(Message& msg);
virtual bool msgTone(Message& msg, const char* tone);
virtual bool msgText(Message& msg, const char* text);
virtual bool msgDrop(Message& msg, const char* reason);
virtual void callAccept(Message& msg);
virtual void callRejected(const char* error, const char* reason = 0, const Message* msg = 0);
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); }
inline bool inband() const
{ return m_inband; }
void ring(pri_event_ring &ev);
void hangup(int cause = 0);
void sendDigit(char digit);
void gotDigits(const char *digits, bool overlapped = false);
bool call(Message &msg, const char *called = 0);
bool answer();
void answered();
void idle();
void restart(bool outgoing = false);
virtual bool openData(const char* format, int echoTaps = 0) = 0;
virtual void closeData();
virtual void goneUp();
inline void setTimeout(u_int64_t tout)
{ m_timeout = tout ? Time::now()+tout : 0; }
const char *chanStatus() const;
bool isISDN() const
{ return m_isdn; }
protected:
PriChan(const PriSpan *parent, int chan, unsigned int bufsize);
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;
bool m_inband;
};
class PriDriver : public Driver
{
friend class PriSpan;
public:
virtual ~PriDriver();
virtual bool isBusy() const;
virtual void dropAll();
virtual bool msgExecute(Message& msg, String& dest);
virtual void init(const char* configName);
virtual PriSpan* createSpan(PriDriver* driver, int span, int first, int chans, Configuration& cfg, const String& sect) = 0;
virtual PriChan* createChan(const PriSpan* span, int chan, unsigned int bufsize) = 0;
static void netParams(Configuration& cfg, const String& sect, int chans, int* netType, int* swType, int* dChan);
PriSpan* findSpan(int chan);
PriChan* findFree(int first = -1, int last = -1);
PriChan* findFree(const String& group);
static inline u_int8_t bitswap(u_int8_t v)
{ return s_bitswap[v]; }
protected:
PriDriver(const char* name);
void statusModule(String& str);
void statusParams(String& str);
ObjList m_spans;
ObjList m_groups;
private:
static u_int8_t s_bitswap[256];
static bool s_init;
};
}
/* vi: set ts=8 sw=4 sts=4 noet: */