*** empty log message ***

git-svn-id: http://voip.null.ro/svn/yate@296 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
paulc 2005-04-19 00:45:40 +00:00
parent 46b3998256
commit 5457ef325b
10 changed files with 245 additions and 125 deletions

View File

@ -141,14 +141,47 @@ AC_SUBST(HAVE_PGSQL)
AC_SUBST(PGSQL_INC)
HAVE_PRI=no
HAVE_PRI_CB=no
AC_ARG_WITH(libpri,AC_HELP_STRING([--with-libpri],[use ISDN PRI if available (default)]),[ac_cv_use_libpri=$withval],[ac_cv_use_libpri=yes])
if [[ "x$ac_cv_use_libpri" != "xno" ]]; then
AC_CHECK_HEADER(libpri.h, , [ac_cv_use_libpri=no])
fi
if [[ "x$ac_cv_use_libpri" != "xno" ]]; then
AC_CHECK_LIB([pri], [pri_new], [HAVE_PRI=yes])
if [[ "x$HAVE_PRI" = "xyes" ]]; then
AC_CHECK_LIB([pri], [pri_new_cb], [HAVE_PRI_CB=yes])
fi
fi
AC_SUBST(HAVE_PRI)
AC_SUBST(HAVE_PRI_CB)
HAVE_ZAP=no
AC_MSG_CHECKING([for Zaptel linux headers])
AC_TRY_COMPILE([
#include <linux/zaptel.h>
],[],
HAVE_ZAP="yes"
)
AC_MSG_RESULT([$HAVE_ZAP])
AC_SUBST(HAVE_ZAP)
HAVE_WANPIPE=no
AC_MSG_CHECKING([for Wanpipe linux headers])
AC_TRY_COMPILE([
#define __LINUX__
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/if_wanpipe.h>
#include <linux/if.h>
#include <linux/wanpipe.h>
#include <linux/sdla_bitstrm.h>
],[],
HAVE_WANPIPE="yes"
)
AC_MSG_RESULT([$HAVE_WANPIPE])
AC_SUBST(HAVE_WANPIPE)
HAVE_GSM=no
GSM_INC=""

View File

@ -285,7 +285,7 @@ DataEndpoint* Channel::setEndpoint(const char* type)
void Channel::setSource(DataSource* source, const char* type)
{
DataEndpoint* dat = setEndpoint(type);
DataEndpoint* dat = source ? setEndpoint(type) : getEndpoint(type);
if (dat)
dat->setSource(source);
}
@ -298,7 +298,7 @@ DataSource* Channel::getSource(const char* type) const
void Channel::setConsumer(DataConsumer* consumer, const char* type)
{
DataEndpoint* dat = setEndpoint(type);
DataEndpoint* dat = consumer ? setEndpoint(type) : getEndpoint(type);
if (dat)
dat->setConsumer(consumer);
}
@ -316,6 +316,7 @@ TokenDict Module::s_messages[] = {
{ "module.debug", Module::Level },
{ "engine.command", Module::Command },
{ "engine.help", Module::Help },
{ "engine.halt", Module::Halt },
{ "call.execute", Module::Execute },
{ "call.drop", Module::Drop },
{ "call.ringing", Module::Ringing },

View File

@ -108,4 +108,23 @@ const char* NamedList::getValue(const String& name, const char* defvalue) const
return s ? s->c_str() : defvalue;
}
int NamedList::getIntValue(const String& name, int defvalue) const
{
const NamedString *s = getParam(name);
return s ? s->toInteger(defvalue) : defvalue;
}
int NamedList::getIntValue(const String& name, const TokenDict* tokens, int defvalue) const
{
const NamedString *s = getParam(name);
return s ? s->toInteger(tokens,defvalue) : defvalue;
}
bool NamedList::getBoolValue(const String& name, bool defvalue) const
{
const NamedString *s = getParam(name);
return s ? s->toBoolean(defvalue) : defvalue;
}
/* vi: set ts=8 sw=4 sts=4 noet: */

View File

@ -79,7 +79,7 @@ static pthread_once_t current_key_once = PTHREAD_ONCE_INIT;
#endif
ObjList threads;
Mutex tmutex;
Mutex tmutex(true);
ThreadPrivate* ThreadPrivate::create(Thread* t,const char* name)
{
@ -167,7 +167,6 @@ void ThreadPrivate::pubdestroy()
}
else {
cancel(false);
bool done = false;
// delay a little so thread has a chance to clean up
for (int i=0; i<20; i++) {
tmutex.lock();

View File

@ -29,10 +29,14 @@ ifneq (@HAVE_PGSQL@,no)
PROGS := $(PROGS) pgsqlroute.yate cdrpgsql.yate register.yate
endif
ifneq (@HAVE_PRI@,no)
ifeq (@HAVE_PRI@_@HAVE_ZAP@,yes_yes)
PROGS := $(PROGS) zapchan.yate
endif
ifeq (@HAVE_PRI_CB@_@HAVE_WANPIPE@,yes_yes)
PROGS := $(PROGS) wpchan.yate
endif
ifneq (@HAVE_H323@,no)
PROGS := $(PROGS) h323chan.yate
endif
@ -120,7 +124,11 @@ lib%.so: %.o
# Take special care of the modules that depend on optional libs
zapchan.yate: LOCALFLAGS = -lpri
zapchan.yate: libypri.o
zapchan.yate: LOCALFLAGS = libypri.o -lpri
wpchan.yate: libypri.o
wpchan.yate: LOCALFLAGS = libypri.o -lpri
h323chan.yate: LOCALFLAGS = -DPHAS_TEMPLATES -D_REENTRANT -DP_HAS_SEMAPHORES @H323_INC@ @H323_LIB@

View File

@ -226,44 +226,32 @@ unsigned char Fifo::get()
return tmp;
}
PriSpan::PriSpan(struct pri *_pri, PriDriver* driver, int span, int first, int chans, Configuration* cfg, const String& sect)
: m_span(span), m_offs(first), m_nchans(chans), m_bchans(0),
PriSpan::PriSpan(struct pri *_pri, PriDriver* driver, int span, int first, int chans, int dchan, Configuration& cfg, const String& sect)
: m_driver(driver), m_span(span), m_offs(first), m_nchans(chans), m_bchans(0),
m_pri(_pri), m_restart(0), m_chans(0), m_ok(false)
{
int dchan = -1;
// guess where we may have a D channel
switch (chans) {
case 3: // BRI ISDN
dchan = 3;
break;
case 24: // T1 with CCS
dchan = 24;
break;
case 31: // EuroISDN
dchan = 16;
break;
}
dchan = cfg->getIntValue(sect,"dchan", dchan),
Debug(DebugAll,"PriSpan::PriSpan() [%p]",this);
int buflength = cfg.getIntValue(sect,"buflen", s_buflen);
m_dplan = cfg->getIntValue(sect,"dialplan",dict_str2dplan,PRI_UNKNOWN);
m_pres = cfg->getIntValue(sect,"presentation",dict_str2pres,PRES_ALLOWED_USER_NUMBER_NOT_SCREENED);
m_restartPeriod = cfg->getIntValue(sect,"restart") * (u_int64_t)1000000;
m_dumpEvents = cfg->getBoolValue(sect,"dumpevents");
m_overlapped = cfg->getIntValue(sect,"overlapdial");
m_dplan = cfg.getIntValue(sect,"dialplan",dict_str2dplan,PRI_UNKNOWN);
m_pres = cfg.getIntValue(sect,"presentation",dict_str2pres,PRES_ALLOWED_USER_NUMBER_NOT_SCREENED);
m_restartPeriod = cfg.getIntValue(sect,"restart") * (u_int64_t)1000000;
m_dumpEvents = cfg.getBoolValue(sect,"dumpevents");
m_overlapped = cfg.getIntValue(sect,"overlapdial");
if (m_overlapped < 0)
m_overlapped = 0;
#ifdef PRI_SET_OVERLAPDIAL
::pri_set_overlapdial(m_pri, (m_overlapped > 0));
#endif
#ifdef PRI_NSF_NONE
::pri_set_nsf(m_pri,cfg->getIntValue(sect,"facilities",dict_str2nsf,YATE_NSF_DEFAULT));
::pri_set_nsf(m_pri,cfg.getIntValue(sect,"facilities",dict_str2nsf,YATE_NSF_DEFAULT));
#endif
::pri_set_userdata(m_pri, this);
PriChan **ch = new PriChan* [chans];
for (int i = 1; i <= chans; i++) {
if (i != dchan) {
ch[i-1] = create(i);
ch[i-1] = m_driver->createChan(this,i,buflength);
m_bchans++;
}
else
@ -535,11 +523,12 @@ PriConsumer::~PriConsumer()
Debug(DebugAll,"PriConsumer::~PriConsumer() [%p]",this);
}
PriChan::PriChan(PriSpan *parent, int chan, unsigned int bufsize)
: Channel(parent->driver()), m_span(parent), m_chan(chan), m_ring(false),
PriChan::PriChan(const PriSpan *parent, int chan, unsigned int bufsize)
: Channel(parent->driver()),
m_span(const_cast<PriSpan*>(parent)), m_chan(chan), m_ring(false),
m_timeout(0), m_call(0), m_bufsize(bufsize)
{
Debug(DebugAll,"PriChan::PriChan(%p,%d) [%p]",parent,chan,this);
Debug(DebugAll,"PriChan::PriChan(%p,%d,%u) [%p]",parent,chan,bufsize,this);
// I hate counting from one...
m_abschan = m_chan+m_span->chan1()-1;
m_isdn = true;
@ -702,12 +691,12 @@ bool PriChan::call(Message &msg, const char *called)
called = msg.getValue("called");
Debug("PriChan",DebugInfo,"Calling '%s' on channel %d span %d",
called, m_chan,m_span->span());
int layer1 = lookup(msg.getValue("format"),dict_str2law,-1);
int layer1 = msg.getIntValue("format",dict_str2law,-1);
hangup(PRI_CAUSE_PRE_EMPTED);
setOutgoing(true);
Channel *ch = static_cast<Channel *>(msg.userData());
if (ch) {
openData(lookup(layer1,dict_str2law));
openData(lookup(layer1,dict_str2law),msg.getBoolValue("cancelecho"));
connect(ch);
m_targetid = msg.getValue("id");
msg.addParam("targetid",id());
@ -716,10 +705,10 @@ bool PriChan::call(Message &msg, const char *called)
msg.userData(this);
Output("Calling '%s' on %s (%d/%d)",called,id().c_str(),m_span->span(),m_chan);
char *caller = (char *)msg.getValue("caller");
int callerplan = lookup(msg.getValue("callerplan"),dict_str2dplan,m_span->dplan());
int callerplan = msg.getIntValue("callerplan",dict_str2dplan,m_span->dplan());
char *callername = (char *)msg.getValue("callername");
int callerpres = lookup(msg.getValue("callerpres"),dict_str2pres,m_span->pres());
int calledplan = lookup(msg.getValue("calledplan"),dict_str2dplan,m_span->dplan());
int callerpres = msg.getIntValue("callerpres",dict_str2pres,m_span->pres());
int calledplan = msg.getIntValue("calledplan",dict_str2dplan,m_span->dplan());
Debug(DebugAll,"Caller='%s' name='%s' plan=%s pres=%s, Called plan=%s",
caller,callername,lookup(callerplan,dict_str2dplan),
lookup(callerpres,dict_str2pres),lookup(calledplan,dict_str2dplan));
@ -943,10 +932,33 @@ bool PriDriver::isBusy() const
return false;
}
void PriDriver::netParams(Configuration& cfg, const String& sect, int chans, int* netType, int* swType, int* dChan)
{
if (netType)
*netType = cfg.getIntValue(sect,"type",dict_str2type,PRI_NETWORK);
if (swType)
*swType = cfg.getIntValue(sect,"swtype",dict_str2switch,PRI_SWITCH_UNKNOWN);
if (dChan) {
int dchan = -1;
// guess where we may have a D channel
switch (chans) {
case 3: // BRI ISDN
dchan = 3;
break;
case 24: // T1 with CCS
dchan = 24;
break;
case 31: // EuroISDN
dchan = 16;
break;
}
*dChan = cfg.getIntValue(sect,"dchan", dchan);
}
}
void PriDriver::init(const char* configName)
{
Output("Initializing module Wanpipe");
Configuration cfg(Engine::configFile("configName"));
Configuration cfg(Engine::configFile(configName));
s_buflen = cfg.getIntValue("general","buflen",480);
if (!m_spans.count()) {
int chan1 = 1;
@ -958,7 +970,7 @@ void PriDriver::init(const char* configName)
break;
if (num) {
chan1 = cfg.getIntValue(sect,"first",chan1);
create(this,span,chan1,num,&cfg,sect);
createSpan(this,span,chan1,num,cfg,sect);
chan1 += num;
}
}

View File

@ -81,8 +81,7 @@ public:
void idle();
protected:
PriSpan(struct pri *_pri, PriDriver* driver, int span, int first, int chans, Configuration* cfg, const String& sect);
virtual PriChan* create(int chan) = 0;
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;
@ -161,7 +160,7 @@ public:
void answered();
void idle();
void restart(bool outgoing = false);
virtual bool openData(const char* format) = 0;
virtual bool openData(const char* format, bool cancelEcho = false) = 0;
void closeData();
inline void setTimeout(u_int64_t tout)
{ m_timeout = tout ? Time::now()+tout : 0; }
@ -169,7 +168,7 @@ public:
bool isISDN() const
{ return m_isdn; }
protected:
PriChan(PriSpan *parent, int chan, unsigned int bufsize);
PriChan(const PriSpan *parent, int chan, unsigned int bufsize);
PriSpan *m_span;
int m_chan;
bool m_ring;
@ -189,7 +188,9 @@ public:
virtual void dropAll();
virtual bool msgExecute(Message& msg, String& dest);
virtual void init(const char* configName);
virtual bool create(PriDriver* driver, int span, int first, int chans, Configuration* cfg, const String& sect) = 0;
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 *find(int first = -1, int last = -1);
static inline u_int8_t bitswap(u_int8_t v)

View File

@ -51,26 +51,18 @@ extern "C" {
using namespace TelEngine;
/* Layer 1 formats */
static TokenDict dict_str2law[] = {
{ "mulaw", PRI_LAYER_1_ULAW },
{ "alaw", PRI_LAYER_1_ALAW },
{ "g721", PRI_LAYER_1_G721 },
{ 0, -1 }
};
class WpChan;
class WpSpan : public PriSpan, public Thread
{
friend class WpData;
friend class WpDriver;
public:
virtual ~WpSpan();
virtual void run();
private:
WpSpan(struct pri *_pri, PriDriver* driver, int span, int first, int chans, Configuration* cfg, const String& sect, int fd);
static struct pri *makePri(int fd, int dchan, int nettype, int swtype, int overlapDial, int nsf);
WpSpan(struct pri *_pri, PriDriver* driver, int span, int first, int chans, int dchan, Configuration& cfg, const String& sect, int fd);
int m_fd;
WpData *m_data;
};
@ -101,11 +93,9 @@ class WpChan : public PriChan
friend class WpConsumer;
friend class WpData;
public:
WpChan(PriSpan *parent, int chan, unsigned int bufsize);
WpChan(const PriSpan *parent, int chan, unsigned int bufsize);
virtual ~WpChan();
virtual void disconnected(bool final, const char *reason);
virtual bool nativeConnect(DataEndpoint *peer);
bool openData(const char* format);
bool openData(const char* format, bool cancelEcho);
private:
WpSource* m_wp_s;
@ -115,7 +105,7 @@ private:
class WpData : public Thread
{
public:
WpData(WpSpan* span);
WpData(WpSpan* span, const char* card, const char* device);
~WpData();
virtual void run();
private:
@ -133,11 +123,10 @@ public:
WpDriver();
virtual ~WpDriver();
virtual void initialize();
virtual bool create(PriDriver* driver, int span, int first, int chans, Configuration* cfg, const String& sect);
virtual PriSpan* createSpan(PriDriver* driver, int span, int first, int chans, Configuration& cfg, const String& sect);
virtual PriChan* createChan(const PriSpan* span, int chan, unsigned int bufsize);
};
WpDriver wdriver;
#define WP_HEADER 16
static int wp_read(struct pri *pri, void *buf, int buflen)
@ -176,62 +165,41 @@ static int wp_write(struct pri *pri, void *buf, int buflen)
return w;
}
bool WpDriver::create(PriDriver* driver, int span, int first, int chans, Configuration* cfg, const String& sect)
static struct pri* wp_create(const char* card, const char* device, int nettype, int swtype)
{
}
virtual PriChan* WpSpan::create(int chan)
{
return new WpChan(this,chan,m_bufsize)
}
PriSpan *PriSpan::create(int span, int chan1, int nChans, int dChan, int netType,
int switchType, int dialPlan, int presentation,
int overlapDial, int nsf)
{
int fd = ::socket(AF_WANPIPE, SOCK_RAW, 0);
if (fd < 0)
DDebug(DebugAll,"wp_create('%s','%s',%d,%d)",card,device,nettype,swtype);
if (null(card) || null(device))
return 0;
struct pri *p = makePri(fd,
(dChan >= 0) ? dChan+chan1-1 : -1,
netType,
switchType, overlapDial, nsf);
if (!p) {
int fd = ::socket(AF_WANPIPE, SOCK_RAW, 0);
if (fd < 0) {
Debug(DebugGoOn,"Wanpipe failed to create socket: error %d: %s",
errno,::strerror(errno));
return 0;
}
// Set up the D channel
struct wan_sockaddr_ll sa;
memset(&sa,0,sizeof(struct wan_sockaddr_ll));
::strncpy((char*)sa.sll_device,device,sizeof(sa.sll_device));
::strncpy((char*)sa.sll_card,card,sizeof(sa.sll_card));
sa.sll_protocol = htons(PVC_PROT);
sa.sll_family=AF_WANPIPE;
if (::bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
Debug(DebugGoOn,"Wanpipe failed to bind %d: error %d: %s",
fd,errno,::strerror(errno));
::close(fd);
return 0;
}
WpSpan *ps = new WpSpan(p,span,chan1,nChans,dChan,fd);
ps->startup();
return ps;
struct pri* p = ::pri_new_cb(fd, nettype, swtype, wp_read, wp_write, 0);
if (!p)
::close(fd);
return p;
}
struct pri *PriSpan::makePri(int fd, int dchan, int nettype, int swtype)
{
if (dchan >= 0) {
// Set up the D channel if we have one
struct wan_sockaddr_ll sa;
memset(&sa,0,sizeof(struct wan_sockaddr_ll));
::strcpy( (char*)sa.sll_device, "w1g2");
::strcpy( (char*)sa.sll_card, "wanpipe1");
sa.sll_protocol = htons(PVC_PROT);
sa.sll_family=AF_WANPIPE;
if (::bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
Debug("PriSpan",DebugGoOn,"Failed to bind %d: error %d: %s",
fd,errno,::strerror(errno));
return 0;
}
}
return ::pri_new_cb(fd, nettype, swtype, wp_read, wp_write, 0);
}
WpSpan::WpSpan(struct pri *_pri, PriDriver* driver, int span, int first, int chans, Configuration* cfg, const String& sect, int fd)
: PriSpan(_pri,driver,span,first,chans,cfg,sect), Thread("WpSpan"),
WpSpan::WpSpan(struct pri *_pri, PriDriver* driver, int span, int first, int chans, int dchan, Configuration& cfg, const String& sect, int fd)
: PriSpan(_pri,driver,span,first,chans,dchan,cfg,sect), Thread("WpSpan"),
m_fd(fd), m_data(0)
{
Debug(DebugAll,"PriSpan::PriSpan() [%p]",this);
WpData* dat = new WpData(this);
dat->startup();
Debug(DebugAll,"WpSpan::WpSpan() [%p]",this);
}
WpSpan::~WpSpan()
@ -245,7 +213,7 @@ WpSpan::~WpSpan()
void WpSpan::run()
{
Debug(DebugAll,"PriSpan::run() [%p]",this);
Debug(DebugAll,"WpSpan::run() [%p]",this);
fd_set rdfds;
fd_set errfds;
for (;;) {
@ -257,7 +225,7 @@ void WpSpan::run()
tv.tv_sec = 0;
tv.tv_usec = 100;
int sel = ::select(m_fd+1, &rdfds, NULL, &errfds, &tv);
pri_event *ev = 0;
Thread::check();
if (!sel)
runEvent(true);
else if (sel > 0)
@ -311,7 +279,7 @@ void WpConsumer::Consume(const DataBlock &data, unsigned long timeDelta)
put(buf[i]);
}
WpData::WpData(WpSpan* span)
WpData::WpData(WpSpan* span, const char* card, const char* device)
: Thread("WpData"), m_span(span), m_fd(-1), m_buffer(0), m_chans(0)
{
Debug(DebugAll,"WpData::WpData(%p) [%p]",span,this);
@ -320,12 +288,12 @@ WpData::WpData(WpSpan* span)
// Set up the B channel group
struct wan_sockaddr_ll sa;
memset(&sa,0,sizeof(struct wan_sockaddr_ll));
::strcpy( (char*)sa.sll_device, "w1g1");
::strcpy( (char*)sa.sll_card, "wanpipe1");
::strncpy((char*)sa.sll_device,device,sizeof(sa.sll_device));
::strncpy((char*)sa.sll_card,card,sizeof(sa.sll_card));
sa.sll_protocol = htons(PVC_PROT);
sa.sll_family=AF_WANPIPE;
if (::bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
Debug("PriSpan",DebugGoOn,"Failed to bind %d: error %d: %s",
Debug("WpData",DebugGoOn,"Failed to bind %d: error %d: %s",
fd,errno,::strerror(errno));
::close(fd);
}
@ -362,16 +330,20 @@ void WpData::run()
for (int n = 0; n < bchans; n++) {
while (!m_span->m_chans[b])
b++;
m_chans[n] = m_span->m_chans[b++];
m_chans[n] = static_cast<WpChan*>(m_span->m_chans[b++]);
DDebug("wpdata_chans",DebugInfo,"ch[%d]=%d (%p)",n,m_chans[n]->chan(),m_chans[n]);
}
fd_set rdfds,oobfds;
while (m_span && (m_fd >= 0)) {
Thread::check();
FD_ZERO(&rdfds);
FD_ZERO(&oobfds);
FD_SET(m_fd, &rdfds);
FD_SET(m_fd, &oobfds);
if (::select(m_fd+1, &rdfds, NULL, &oobfds, NULL) <= 0)
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 100;
if (::select(m_fd+1, &rdfds, NULL, &oobfds, &tv) <= 0)
continue;
if (FD_ISSET(m_fd, &oobfds)) {
@ -389,7 +361,7 @@ void WpData::run()
if ((r > 0) && ((r % bchans) == 0)) {
r /= bchans;
const unsigned char* dat = m_buffer + WP_HEADER;
wplugin.mutex.lock();
m_span->driver()->lock();
for (int n = r; n > 0; n--)
for (b = 0; b < bchans; b++) {
WpSource *s = m_chans[b]->m_wp_s;
@ -397,19 +369,19 @@ void WpData::run()
s->put(PriDriver::bitswap(*dat));
dat++;
}
wplugin.mutex.unlock();
m_span->driver()->unlock();
}
int w = samp;
::memset(m_buffer,0,WP_HEADER);
unsigned char* dat = m_buffer + WP_HEADER;
wplugin.mutex.lock();
m_span->driver()->lock();
for (int n = w; n > 0; n--) {
for (b = 0; b < bchans; b++) {
WpConsumer *c = m_chans[b]->m_wp_c;
*dat++ = PriDriver::bitswap(c ? c->get() : 0xff);
}
}
wplugin.mutex.unlock();
m_span->driver()->unlock();
w = (w * bchans) + WP_HEADER;
XDebug("wpdata_send",DebugAll,"pre buf=%p len=%d sz=%d",m_buffer,w,sz);
w = ::send(m_fd,m_buffer,w,MSG_DONTWAIT);
@ -418,8 +390,20 @@ void WpData::run()
}
}
bool WpChan::openData(const char* format)
WpChan::WpChan(const PriSpan *parent, int chan, unsigned int bufsize)
: PriChan(parent,chan,bufsize), m_wp_s(0), m_wp_c(0)
{
}
WpChan::~WpChan()
{
closeData();
}
bool WpChan::openData(const char* format, bool cancelEcho)
{
if (cancelEcho)
Debug(DebugWarn,"Echo cancellation requested but not available in wanpipe");
setSource(new WpSource(this,m_bufsize,format));
getSource()->deref();
setConsumer(new WpConsumer(this,m_bufsize,format));
@ -427,6 +411,41 @@ bool WpChan::openData(const char* format)
return true;
}
PriSpan* WpDriver::createSpan(PriDriver* driver, int span, int first, int chans, Configuration& cfg, const String& sect)
{
Debug(DebugAll,"WpDriver::createSpan(%p,%d,%d,%d) [%p]",driver,span,first,chans,this);
int netType = -1;
int swType = -1;
int dchan = -1;
netParams(cfg,sect,chans,&netType,&swType,&dchan);
String card;
card << "wanpipe" << span;
card = cfg.getValue(sect,"card",card);
String dev;
dev << "w" << span << "g2";
pri* p = wp_create(card,cfg.getValue(sect,"dgroup",dev),netType,swType);
if (!p)
return 0;
Debug(DebugAll,"WpDriver::createSpan #1");
WpSpan *ps = new WpSpan(p,driver,span,first,chans,dchan,cfg,sect,::pri_fd(p));
Debug(DebugAll,"WpDriver::createSpan #2");
ps->startup();
dev.clear();
dev << "w" << span << "g1";
Debug(DebugAll,"WpDriver::createSpan #3");
WpData* dat = new WpData(ps,card,cfg.getValue(sect,"bgroup",dev));
Debug(DebugAll,"WpDriver::createSpan #4");
dat->startup();
Debug(DebugAll,"WpDriver::createSpan #5");
return ps;
}
PriChan* WpDriver::createChan(const PriSpan* span, int chan, unsigned int bufsize)
{
Debug(DebugAll,"WpDriver::createChan(%p,%d,%u) [%p]",span,chan,bufsize,this);
return new WpChan(span,chan,bufsize);
}
WpDriver::WpDriver()
: PriDriver("wp")
{
@ -444,4 +463,6 @@ void WpDriver::initialize()
init("wpchan");
}
INIT_PLUGIN(WpDriver);
/* vi: set ts=8 sw=4 sts=4 noet: */

View File

@ -1935,6 +1935,31 @@ public:
*/
const char* getValue(const String& name, const char* defvalue = 0) const;
/**
* Retrive the numeric value of a parameter.
* @param name Name of parameter to locate
* @param defvalue Default value to return if not found
* @return The number contained in the named parameter or the default
*/
int getIntValue(const String& name, int defvalue = 0) const;
/**
* Retrive the numeric value of a parameter trying first a table lookup.
* @param name Name of parameter to locate
* @param tokens A pointer to an array of tokens to try to lookup
* @param defvalue Default value to return if not found
* @return The number contained in the named parameter or the default
*/
int getIntValue(const String& name, const TokenDict* tokens, int defvalue = 0) const;
/**
* Retrive the boolean value of a parameter.
* @param name Name of parameter to locate
* @param defvalue Default value to return if not found
* @return The boolean value contained in the named parameter or the default
*/
bool getBoolValue(const String& name, bool defvalue = false) const;
private:
NamedList(); // no default constructor please
NamedList(const NamedList& value); // no copy constructor

View File

@ -765,9 +765,10 @@ protected:
Level = 0x0004,
Command = 0x0008,
Help = 0x0010,
Halt = 0x0020,
// Driver messages
Execute = 0x0020,
Drop = 0x0040,
Execute = 0x0040,
Drop = 0x0080,
// Channel messages
Ringing = 0x0100,
Answered = 0x0200,