261 lines
7.3 KiB
C++
261 lines
7.3 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 detect() const
|
|
{ return m_detect; }
|
|
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;
|
|
bool m_detect;
|
|
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 msgProgress(Message& msg);
|
|
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; }
|
|
inline bool detect() const
|
|
{ return m_detect; }
|
|
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();
|
|
bool progress();
|
|
bool ringing();
|
|
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; }
|
|
inline void extTimeout(u_int64_t tout)
|
|
{ if (m_timeout) setTimeout(tout); }
|
|
const char *chanStatus() const;
|
|
bool isISDN() const
|
|
{ return m_isdn; }
|
|
protected:
|
|
PriChan(const PriSpan *parent, int chan, unsigned int bufsize);
|
|
virtual void dataChanged();
|
|
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;
|
|
bool m_detect;
|
|
};
|
|
|
|
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: */
|