*** empty log message ***
git-svn-id: http://voip.null.ro/svn/yate@308 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
bd8b5c8d28
commit
885f3646ac
|
@ -273,7 +273,7 @@ bool MessageDispatcher::dispatch(Message& msg)
|
|||
Debugger debug("MessageDispatcher::dispatch","(%p) (\"%s\")",&msg,msg.c_str());
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
unsigned long long t = Time::now();
|
||||
u_int64_t t = Time::now();
|
||||
#endif
|
||||
bool retv = false;
|
||||
ObjList *l = &m_handlers;
|
||||
|
@ -287,13 +287,13 @@ bool MessageDispatcher::dispatch(Message& msg)
|
|||
unsigned int p = h->priority();
|
||||
m_mutex.unlock();
|
||||
#ifdef DEBUG
|
||||
unsigned long long tm = Time::now();
|
||||
u_int64_t tm = Time::now();
|
||||
#endif
|
||||
retv = h->received(msg);
|
||||
#ifdef DEBUG
|
||||
tm = Time::now() - tm;
|
||||
if (tm > 100000)
|
||||
Debug(DebugInfo,"Message '%s' [%p] passed trough %p in %llu usec",
|
||||
Debug(DebugInfo,"Message '%s' [%p] passed trough %p in " FMT64 " usec",
|
||||
msg.c_str(),&msg,h,tm);
|
||||
#endif
|
||||
if (retv)
|
||||
|
@ -339,7 +339,7 @@ bool MessageDispatcher::dispatch(Message& msg)
|
|||
if (s)
|
||||
p << "\n ['" << s->name() << "']='" << *s << "'";
|
||||
}
|
||||
Debug("Performance",DebugMild,"Message %p '%s' retval '%s' returned %s in %llu usec%s",
|
||||
Debug("Performance",DebugMild,"Message %p '%s' retval '%s' returned %s in " FMT64 " usec%s",
|
||||
&msg,msg.c_str(),msg.retValue().c_str(),retv ? "true" : "false",t,p.safe());
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -38,7 +38,7 @@ static int s_debug = DebugWarn;
|
|||
static int s_indent = 0;
|
||||
static bool s_debugging = true;
|
||||
static bool s_abort = false;
|
||||
static unsigned long long s_timestamp = 0;
|
||||
static u_int64_t s_timestamp = 0;
|
||||
|
||||
static void dbg_stderr_func(const char* buf)
|
||||
{
|
||||
|
@ -75,7 +75,7 @@ static void dbg_output(const char* prefix, const char* format, va_list ap)
|
|||
char buf[OUT_BUFFER_SIZE];
|
||||
unsigned int n = 0;
|
||||
if (s_timestamp) {
|
||||
unsigned long long t = Time::now() - s_timestamp;
|
||||
u_int64_t t = Time::now() - s_timestamp;
|
||||
unsigned int s = t / 1000000;
|
||||
unsigned int u = t % 1000000;
|
||||
::sprintf(buf,"%07u.%06u ",s,u);
|
||||
|
|
|
@ -47,23 +47,23 @@ public:
|
|||
~GsmPlugin();
|
||||
virtual void initialize() { }
|
||||
virtual bool isBusy() const;
|
||||
virtual DataTranslator *create(const String &sFormat, const String &dFormat);
|
||||
virtual const TranslatorCaps *getCapabilities() const;
|
||||
virtual DataTranslator* create(const DataFormat& sFormat, const DataFormat& dFormat);
|
||||
virtual const TranslatorCaps* getCapabilities() const;
|
||||
};
|
||||
|
||||
class GsmCodec : public DataTranslator
|
||||
{
|
||||
public:
|
||||
GsmCodec(const char *sFormat, const char *dFormat, bool encoding);
|
||||
GsmCodec(const char* sFormat, const char* dFormat, bool encoding);
|
||||
~GsmCodec();
|
||||
virtual void Consume(const DataBlock &data, unsigned long timeDelta);
|
||||
virtual void Consume(const DataBlock& data, unsigned long timeDelta);
|
||||
private:
|
||||
bool m_encoding;
|
||||
gsm m_gsm;
|
||||
DataBlock m_data;
|
||||
};
|
||||
|
||||
GsmCodec::GsmCodec(const char *sFormat, const char *dFormat, bool encoding)
|
||||
GsmCodec::GsmCodec(const char* sFormat, const char* dFormat, bool encoding)
|
||||
: DataTranslator(sFormat,dFormat), m_encoding(encoding), m_gsm(0)
|
||||
{
|
||||
Debug(DebugAll,"GsmCodec::GsmCodec(\"%s\",\"%s\",%scoding) [%p]",
|
||||
|
@ -83,7 +83,7 @@ GsmCodec::~GsmCodec()
|
|||
}
|
||||
}
|
||||
|
||||
void GsmCodec::Consume(const DataBlock &data, unsigned long timeDelta)
|
||||
void GsmCodec::Consume(const DataBlock& data, unsigned long timeDelta)
|
||||
{
|
||||
if (!(m_gsm && getTransSource()))
|
||||
return;
|
||||
|
@ -129,7 +129,6 @@ GsmPlugin::GsmPlugin()
|
|||
Output("Loaded module GSM - based on libgsm-%d.%d.%d",GSM_MAJOR,GSM_MINOR,GSM_PATCHLEVEL);
|
||||
const FormatInfo* f = FormatRepository::addFormat("gsm",1650,33);
|
||||
caps[0].src = caps[1].dest = f;
|
||||
// caps[0].src = caps[1].dest = FormatRepository::getFormat("gsm");
|
||||
caps[0].dest = caps[1].src = FormatRepository::getFormat("slin");
|
||||
}
|
||||
|
||||
|
@ -143,7 +142,7 @@ bool GsmPlugin::isBusy() const
|
|||
return (count != 0);
|
||||
}
|
||||
|
||||
DataTranslator *GsmPlugin::create(const String &sFormat, const String &dFormat)
|
||||
DataTranslator* GsmPlugin::create(const DataFormat& sFormat, const DataFormat& dFormat)
|
||||
{
|
||||
if (sFormat == "slin" && dFormat == "gsm")
|
||||
return new GsmCodec(sFormat,dFormat,true);
|
||||
|
@ -152,7 +151,7 @@ DataTranslator *GsmPlugin::create(const String &sFormat, const String &dFormat)
|
|||
else return 0;
|
||||
}
|
||||
|
||||
const TranslatorCaps *GsmPlugin::getCapabilities() const
|
||||
const TranslatorCaps* GsmPlugin::getCapabilities() const
|
||||
{
|
||||
return caps;
|
||||
}
|
||||
|
|
|
@ -147,18 +147,18 @@ private:
|
|||
};
|
||||
|
||||
|
||||
class IAXPlugin : public Driver
|
||||
class IAXDriver : public Driver
|
||||
{
|
||||
public:
|
||||
IAXPlugin();
|
||||
virtual ~IAXPlugin();
|
||||
IAXDriver();
|
||||
virtual ~IAXDriver();
|
||||
virtual void initialize();
|
||||
virtual bool msgExecute(Message& msg, String& dest);
|
||||
IAXConnection *find(iax_session *session);
|
||||
IAXEndPoint *m_endpoint;
|
||||
};
|
||||
|
||||
static IAXPlugin iplugin;
|
||||
static IAXDriver iplugin;
|
||||
|
||||
static void iax_err_cb(const char *s)
|
||||
{
|
||||
|
@ -418,8 +418,7 @@ void IAXEndPoint::answer(iax_event *e)
|
|||
String addr(::inet_ntoa(e->session->peeraddr.sin_addr));
|
||||
addr << ":" << ntohs(e->session->peeraddr.sin_port);
|
||||
IAXConnection *conn = new IAXConnection(&iplugin,addr,e->session);
|
||||
if (!conn->startRouting(e))
|
||||
conn->callReject("failure","Internal server error");
|
||||
conn->startRouting(e);
|
||||
}
|
||||
|
||||
void IAXEndPoint::reg(iax_event *e)
|
||||
|
@ -655,7 +654,6 @@ void IAXConnection::callAccept(Message& msg)
|
|||
Debug(DebugAll,"IAXConnection::callAccept() [%p]",this);
|
||||
startAudio(m_format,m_capab);
|
||||
Channel::callAccept(msg);
|
||||
deref();
|
||||
}
|
||||
|
||||
void IAXConnection::callReject(const char* error, const char* reason)
|
||||
|
@ -855,7 +853,7 @@ bool IAXConnection::msgDrop(Message& msg, const char* reason)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool IAXPlugin::msgExecute(Message& msg, String& dest)
|
||||
bool IAXDriver::msgExecute(Message& msg, String& dest)
|
||||
{
|
||||
if (!msg.userData()) {
|
||||
Debug(DebugWarn,"IAX call found but no data channel!");
|
||||
|
@ -879,7 +877,7 @@ bool IAXPlugin::msgExecute(Message& msg, String& dest)
|
|||
return true;
|
||||
};
|
||||
|
||||
IAXConnection* IAXPlugin::find(iax_session *session)
|
||||
IAXConnection* IAXDriver::find(iax_session *session)
|
||||
{
|
||||
ObjList *p = channels().skipNull();
|
||||
for (; p; p=p->skipNext()) {
|
||||
|
@ -890,13 +888,13 @@ IAXConnection* IAXPlugin::find(iax_session *session)
|
|||
return 0;
|
||||
}
|
||||
|
||||
IAXPlugin::IAXPlugin()
|
||||
IAXDriver::IAXDriver()
|
||||
: Driver("iax","varchans"), m_endpoint(0)
|
||||
{
|
||||
Output("Loaded module IAX");
|
||||
}
|
||||
|
||||
IAXPlugin::~IAXPlugin()
|
||||
IAXDriver::~IAXDriver()
|
||||
{
|
||||
Output("Unloading module IAX");
|
||||
if (m_endpoint) {
|
||||
|
@ -905,7 +903,7 @@ IAXPlugin::~IAXPlugin()
|
|||
}
|
||||
}
|
||||
|
||||
void IAXPlugin::initialize()
|
||||
void IAXDriver::initialize()
|
||||
{
|
||||
Output("Initializing module IAX");
|
||||
lock();
|
||||
|
|
|
@ -949,9 +949,9 @@ bool PriDriver::isBusy() const
|
|||
return false;
|
||||
}
|
||||
|
||||
void PriDriver::statusParams(String& str)
|
||||
void PriDriver::statusModule(String& str)
|
||||
{
|
||||
Driver::statusParams(str);
|
||||
Driver::statusModule(str);
|
||||
String sp;
|
||||
const ObjList *l = &m_spans;
|
||||
for (; l; l=l->next()) {
|
||||
|
@ -959,6 +959,7 @@ void PriDriver::statusParams(String& str)
|
|||
if (s)
|
||||
sp.append(String(s->chans()),"|");
|
||||
}
|
||||
str.append("spans=",",") << m_spans.count();
|
||||
if (sp)
|
||||
str.append("spanlen=",",") << sp;
|
||||
}
|
||||
|
|
|
@ -205,7 +205,7 @@ public:
|
|||
{ return s_bitswap[v]; }
|
||||
protected:
|
||||
PriDriver(const char* name);
|
||||
void statusParams(String& str);
|
||||
void statusModule(String& str);
|
||||
private:
|
||||
ObjList m_spans;
|
||||
static u_int8_t s_bitswap[256];
|
||||
|
|
|
@ -24,16 +24,12 @@
|
|||
|
||||
#include <yatengine.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace TelEngine;
|
||||
|
||||
Mutex lmutex;
|
||||
|
||||
static Configuration s_cfg(Engine::configFile("regfile"));
|
||||
|
||||
ObjList registered;
|
||||
|
||||
class AuthHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
|
@ -41,6 +37,7 @@ public:
|
|||
: MessageHandler(name,prio) { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
class RegistHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
|
@ -49,7 +46,6 @@ public:
|
|||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
|
||||
class UnRegistHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
|
@ -69,7 +65,7 @@ public:
|
|||
class StatusHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
StatusHandler(const char *name, unsigned prio = 1)
|
||||
StatusHandler(const char *name, unsigned prio = 100)
|
||||
: MessageHandler(name,prio) { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
@ -82,10 +78,6 @@ public:
|
|||
virtual void initialize();
|
||||
private:
|
||||
AuthHandler *m_authhandler;
|
||||
RegistHandler *m_registhandler;
|
||||
UnRegistHandler *m_unregisthandler;
|
||||
RouteHandler *m_routehandler;
|
||||
StatusHandler *m_statushandler;
|
||||
};
|
||||
|
||||
bool AuthHandler::received(Message &msg)
|
||||
|
@ -98,48 +90,56 @@ bool AuthHandler::received(Message &msg)
|
|||
|
||||
bool RegistHandler::received(Message &msg)
|
||||
{
|
||||
const char *username = c_safe(msg.getValue("username"));
|
||||
const char *techno = c_safe(msg.getValue("techno"));
|
||||
const char *data = c_safe(msg.getValue("data"));
|
||||
|
||||
|
||||
Lock lock(lmutex);
|
||||
if (s_cfg.getSection(username)){
|
||||
s_cfg.setValue(username,"register",true);
|
||||
s_cfg.setValue(username,"techno",techno);
|
||||
s_cfg.setValue(username,"data",data);
|
||||
} else
|
||||
const char *username = msg.getValue("username");
|
||||
const char *driver = msg.getValue("driver");
|
||||
const char *data = msg.getValue("data");
|
||||
if (!(username && data))
|
||||
return false;
|
||||
return true;
|
||||
|
||||
|
||||
Lock lock(lmutex);
|
||||
if (s_cfg.getSection(username)) {
|
||||
Debug("RegFile",DebugInfo,"Registered '%s' via '%s'",username,data);
|
||||
s_cfg.setValue(username,"driver",driver);
|
||||
s_cfg.setValue(username,"data",data);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
bool UnRegistHandler::received(Message &msg)
|
||||
{
|
||||
const char *username = c_safe(msg.getValue("username"));
|
||||
const char *username = msg.getValue("username");
|
||||
if (!username)
|
||||
return false;
|
||||
|
||||
Lock lock(lmutex);
|
||||
if (s_cfg.getSection(username))
|
||||
s_cfg.setValue(username,"register",false);
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
if (s_cfg.getSection(username)) {
|
||||
Debug("RegFile",DebugInfo,"Unregistered '%s'",username);
|
||||
s_cfg.clearKey(username,"data");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
bool RouteHandler::received(Message &msg)
|
||||
{
|
||||
const char *username = c_safe(msg.getValue("username"));
|
||||
const char* username = msg.getValue("called");
|
||||
if (!username)
|
||||
return false;
|
||||
|
||||
Lock lock(lmutex);
|
||||
if (s_cfg.getSection(username))
|
||||
msg.retValue() = s_cfg.getValue(username,"data");
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
const char* data = s_cfg.getValue(username,"data");
|
||||
if (data) {
|
||||
Debug("RegFile",DebugInfo,"Routed '%s' via '%s'",username,data);
|
||||
msg.retValue() = data;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
bool StatusHandler::received(Message &msg)
|
||||
{
|
||||
Lock lock(lmutex);
|
||||
unsigned int n = s_cfg.sections();
|
||||
if (!s_cfg.getSection(0))
|
||||
--n;
|
||||
|
@ -149,18 +149,19 @@ bool StatusHandler::received(Message &msg)
|
|||
NamedList *user = s_cfg.getSection(i);
|
||||
if (!user)
|
||||
continue;
|
||||
const char* data = s_cfg.getValue(*user,"data");
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
msg.retValue() << ",";
|
||||
msg.retValue() << *user << "=" << s_cfg.getBoolValue(*user,"register");
|
||||
msg.retValue() << *user << "=" << (data != 0);
|
||||
}
|
||||
msg.retValue() <<"\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
RegfilePlugin::RegfilePlugin()
|
||||
: m_authhandler(0),m_registhandler(0),m_routehandler(0),m_statushandler(0)
|
||||
: m_authhandler(0)
|
||||
{
|
||||
Output("Loaded module Registration from file");
|
||||
}
|
||||
|
@ -170,24 +171,12 @@ void RegfilePlugin::initialize()
|
|||
Output("Initializing module Register for file");
|
||||
if (!m_authhandler) {
|
||||
s_cfg.load();
|
||||
Output("Installing Authentification handler");
|
||||
Engine::install(m_authhandler = new AuthHandler("user.auth",s_cfg.getIntValue("general","auth",10)));
|
||||
}
|
||||
if (!m_registhandler) {
|
||||
Output("Installing Registering handler");
|
||||
Engine::install(m_registhandler = new RegistHandler("user.register"));
|
||||
}
|
||||
if (!m_unregisthandler) {
|
||||
Output("Installing UnRegistering handler");
|
||||
Engine::install(m_unregisthandler = new UnRegistHandler("user.unregister"));
|
||||
}
|
||||
if (!m_routehandler) {
|
||||
Output("Installing Route handler");
|
||||
Engine::install(m_routehandler = new RouteHandler("call.route",s_cfg.getIntValue("general","route",100)));
|
||||
}
|
||||
if (!m_statushandler) {
|
||||
Output("Installing Status handler");
|
||||
Engine::install(m_statushandler = new StatusHandler("engine.status"));
|
||||
Output("Installing handlers");
|
||||
Engine::install(m_authhandler = new AuthHandler("user.auth",s_cfg.getIntValue("general","auth",100)));
|
||||
Engine::install(new RegistHandler("user.register"));
|
||||
Engine::install(new UnRegistHandler("user.unregister"));
|
||||
Engine::install(new RouteHandler("call.route",s_cfg.getIntValue("general","route",100)));
|
||||
Engine::install(new StatusHandler("engine.status"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#include <yatephone.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
using namespace TelEngine;
|
||||
|
@ -69,11 +68,11 @@ public:
|
|||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
class ToneGenPlugin : public Driver
|
||||
class ToneGenDriver : public Driver
|
||||
{
|
||||
public:
|
||||
ToneGenPlugin();
|
||||
~ToneGenPlugin();
|
||||
ToneGenDriver();
|
||||
~ToneGenDriver();
|
||||
virtual void initialize();
|
||||
virtual bool msgExecute(Message& msg, String& dest);
|
||||
protected:
|
||||
|
@ -83,7 +82,7 @@ private:
|
|||
AttachHandler* m_handler;
|
||||
};
|
||||
|
||||
INIT_PLUGIN(ToneGenPlugin);
|
||||
INIT_PLUGIN(ToneGenDriver);
|
||||
|
||||
// 421.052Hz (19 samples @ 8kHz) sine wave, pretty close to standard 425Hz
|
||||
static const short tone421hz[] = {
|
||||
|
@ -239,7 +238,7 @@ ToneChan::~ToneChan()
|
|||
Debug(DebugAll,"ToneChan::~ToneChan() %s [%p]",id().c_str(),this);
|
||||
}
|
||||
|
||||
bool ToneGenPlugin::msgExecute(Message& msg, String& dest)
|
||||
bool ToneGenDriver::msgExecute(Message& msg, String& dest)
|
||||
{
|
||||
Channel *dd = static_cast<Channel*>(msg.userData());
|
||||
if (dd) {
|
||||
|
@ -308,23 +307,23 @@ bool AttachHandler::received(Message &msg)
|
|||
return false;
|
||||
}
|
||||
|
||||
void ToneGenPlugin::statusModule(String& str)
|
||||
void ToneGenDriver::statusModule(String& str)
|
||||
{
|
||||
Module::statusModule(str);
|
||||
}
|
||||
|
||||
void ToneGenPlugin::statusParams(String& str)
|
||||
void ToneGenDriver::statusParams(String& str)
|
||||
{
|
||||
str << "tones=" << tones.count() << ",chans=" << channels().count();
|
||||
}
|
||||
|
||||
ToneGenPlugin::ToneGenPlugin()
|
||||
ToneGenDriver::ToneGenDriver()
|
||||
: Driver("tone","misc"), m_handler(0)
|
||||
{
|
||||
Output("Loaded module ToneGen");
|
||||
}
|
||||
|
||||
ToneGenPlugin::~ToneGenPlugin()
|
||||
ToneGenDriver::~ToneGenDriver()
|
||||
{
|
||||
Output("Unloading module ToneGen");
|
||||
ObjList *l = &channels();
|
||||
|
@ -339,7 +338,7 @@ ToneGenPlugin::~ToneGenPlugin()
|
|||
tones.clear();
|
||||
}
|
||||
|
||||
void ToneGenPlugin::initialize()
|
||||
void ToneGenDriver::initialize()
|
||||
{
|
||||
Output("Initializing module ToneGen");
|
||||
setup(0,true); // no need to install notifications
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
@ -36,7 +35,7 @@ using namespace TelEngine;
|
|||
class WaveSource : public ThreadedSource
|
||||
{
|
||||
public:
|
||||
WaveSource(const String& file, DataEndpoint *chan, bool autoclose = true);
|
||||
WaveSource(const String& file, Channel* chan, bool autoclose = true);
|
||||
~WaveSource();
|
||||
virtual void run();
|
||||
virtual void cleanup();
|
||||
|
@ -45,7 +44,7 @@ public:
|
|||
private:
|
||||
void detectAuFormat();
|
||||
void detectWavFormat();
|
||||
DataEndpoint *m_chan;
|
||||
Channel* m_chan;
|
||||
DataBlock m_data;
|
||||
int m_fd;
|
||||
bool m_swap;
|
||||
|
@ -59,13 +58,13 @@ private:
|
|||
class WaveConsumer : public DataConsumer
|
||||
{
|
||||
public:
|
||||
WaveConsumer(const String& file, DataEndpoint *chan = 0, unsigned maxlen = 0);
|
||||
WaveConsumer(const String& file, Channel* chan = 0, unsigned maxlen = 0);
|
||||
~WaveConsumer();
|
||||
virtual void Consume(const DataBlock &data, unsigned long timeDelta);
|
||||
virtual void Consume(const DataBlock& data, unsigned long timeDelta);
|
||||
inline void setNotify(const String& id)
|
||||
{ m_id = id; }
|
||||
private:
|
||||
DataEndpoint *m_chan;
|
||||
Channel* m_chan;
|
||||
int m_fd;
|
||||
unsigned m_total;
|
||||
unsigned m_maxlen;
|
||||
|
@ -73,37 +72,24 @@ private:
|
|||
String m_id;
|
||||
};
|
||||
|
||||
class WaveChan : public DataEndpoint
|
||||
class WaveChan : public Channel
|
||||
{
|
||||
public:
|
||||
WaveChan(const String& file, bool record, unsigned maxlen = 0);
|
||||
~WaveChan();
|
||||
virtual void disconnected(bool final, const char *reason);
|
||||
inline const String &id() const
|
||||
{ return m_id; }
|
||||
private:
|
||||
String m_id;
|
||||
static int s_nextid;
|
||||
};
|
||||
|
||||
class ConsDisconnector : public Thread
|
||||
{
|
||||
public:
|
||||
ConsDisconnector(DataEndpoint *chan, const String& id)
|
||||
ConsDisconnector(Channel* chan, const String& id)
|
||||
: m_chan(chan), m_id(id) { }
|
||||
virtual void run();
|
||||
private:
|
||||
DataEndpoint *m_chan;
|
||||
Channel* m_chan;
|
||||
String m_id;
|
||||
};
|
||||
|
||||
class WaveHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
WaveHandler() : MessageHandler("call.execute") { }
|
||||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
class AttachHandler : public MessageHandler
|
||||
{
|
||||
public:
|
||||
|
@ -111,16 +97,19 @@ public:
|
|||
virtual bool received(Message &msg);
|
||||
};
|
||||
|
||||
class WaveFilePlugin : public Plugin
|
||||
class WaveFileDriver : public Driver
|
||||
{
|
||||
public:
|
||||
WaveFilePlugin();
|
||||
WaveFileDriver();
|
||||
virtual void initialize();
|
||||
virtual bool msgExecute(Message& msg, String& dest);
|
||||
private:
|
||||
WaveHandler *m_handler;
|
||||
AttachHandler* m_handler;
|
||||
};
|
||||
|
||||
WaveSource::WaveSource(const String& file, DataEndpoint *chan, bool autoclose)
|
||||
INIT_PLUGIN(WaveFileDriver);
|
||||
|
||||
WaveSource::WaveSource(const String& file, Channel* chan, bool autoclose)
|
||||
: m_chan(chan), m_fd(-1), m_swap(false), m_brate(16000),
|
||||
m_total(0), m_time(0), m_autoclose(autoclose)
|
||||
{
|
||||
|
@ -133,19 +122,19 @@ WaveSource::WaveSource(const String& file, DataEndpoint *chan, bool autoclose)
|
|||
if (m_fd < 0) {
|
||||
Debug(DebugGoOn,"Opening '%s': error %d: %s",
|
||||
file.c_str(), errno, ::strerror(errno));
|
||||
m_format = 0;
|
||||
m_format.clear();
|
||||
return;
|
||||
}
|
||||
if (file.endsWith(".gsm")) {
|
||||
setFormatInternal("gsm");
|
||||
m_format = "gsm";
|
||||
m_brate = 1650;
|
||||
}
|
||||
else if (file.endsWith(".alaw") || file.endsWith(".A")) {
|
||||
setFormatInternal("alaw");
|
||||
m_format = "alaw";
|
||||
m_brate = 8000;
|
||||
}
|
||||
else if (file.endsWith(".mulaw") || file.endsWith(".u")) {
|
||||
setFormatInternal("mulaw");
|
||||
m_format = "mulaw";
|
||||
m_brate = 8000;
|
||||
}
|
||||
else if (file.endsWith(".au"))
|
||||
|
@ -195,10 +184,10 @@ void WaveSource::detectAuFormat()
|
|||
m_brate = samp;
|
||||
switch (ntohl(header.form)) {
|
||||
case 1:
|
||||
setFormatInternal("mulaw");
|
||||
m_format = "mulaw";
|
||||
break;
|
||||
case 27:
|
||||
setFormatInternal("alaw");
|
||||
m_format = "alaw";
|
||||
break;
|
||||
case 3:
|
||||
m_brate *= 2;
|
||||
|
@ -246,7 +235,7 @@ void WaveSource::run()
|
|||
}
|
||||
int64_t dly = tpos - Time::now();
|
||||
if (dly > 0) {
|
||||
XDebug("WaveSource",DebugAll,"Sleeping for %lld usec",dly);
|
||||
XDebug("WaveSource",DebugAll,"Sleeping for " FMT64 " usec",dly);
|
||||
Thread::usleep((unsigned long)dly);
|
||||
}
|
||||
Forward(m_data,m_data.length()*8000/m_brate);
|
||||
|
@ -270,7 +259,7 @@ void WaveSource::cleanup()
|
|||
m_chan->disconnect("eof");
|
||||
}
|
||||
|
||||
WaveConsumer::WaveConsumer(const String& file, DataEndpoint *chan, unsigned maxlen)
|
||||
WaveConsumer::WaveConsumer(const String& file, Channel* chan, unsigned maxlen)
|
||||
: m_chan(chan), m_fd(-1), m_total(0), m_maxlen(maxlen), m_time(0)
|
||||
{
|
||||
Debug(DebugAll,"WaveConsumer::WaveConsumer(\"%s\",%p,%u) [%p]",
|
||||
|
@ -278,11 +267,11 @@ WaveConsumer::WaveConsumer(const String& file, DataEndpoint *chan, unsigned maxl
|
|||
if (file == "-")
|
||||
return;
|
||||
else if (file.endsWith(".gsm"))
|
||||
setFormatInternal("gsm");
|
||||
m_format = "gsm";
|
||||
else if (file.endsWith(".alaw") || file.endsWith(".A"))
|
||||
setFormatInternal("alaw");
|
||||
m_format = "alaw";
|
||||
else if (file.endsWith(".mulaw") || file.endsWith(".u"))
|
||||
setFormatInternal("mulaw");
|
||||
m_format = "mulaw";
|
||||
m_fd = ::creat(file.safe(),S_IRUSR|S_IWUSR);
|
||||
if (m_fd < 0)
|
||||
Debug(DebugGoOn,"Creating '%s': error %d: %s",
|
||||
|
@ -305,7 +294,7 @@ WaveConsumer::~WaveConsumer()
|
|||
}
|
||||
}
|
||||
|
||||
void WaveConsumer::Consume(const DataBlock &data, unsigned long timeDelta)
|
||||
void WaveConsumer::Consume(const DataBlock& data, unsigned long timeDelta)
|
||||
{
|
||||
if (!data.null()) {
|
||||
if (!m_time)
|
||||
|
@ -349,15 +338,11 @@ void ConsDisconnector::run()
|
|||
}
|
||||
|
||||
Mutex mutex;
|
||||
int WaveChan::s_nextid = 1;
|
||||
|
||||
WaveChan::WaveChan(const String& file, bool record, unsigned maxlen)
|
||||
: DataEndpoint("wavefile")
|
||||
: Channel(__plugin)
|
||||
{
|
||||
Debug(DebugAll,"WaveChan::WaveChan(%s) [%p]",(record ? "record" : "play"),this);
|
||||
mutex.lock();
|
||||
m_id << "wave/" << s_nextid++;
|
||||
mutex.unlock();
|
||||
if (record) {
|
||||
setConsumer(new WaveConsumer(file,this,maxlen));
|
||||
getConsumer()->deref();
|
||||
|
@ -370,76 +355,7 @@ WaveChan::WaveChan(const String& file, bool record, unsigned maxlen)
|
|||
|
||||
WaveChan::~WaveChan()
|
||||
{
|
||||
Debug(DebugAll,"WaveChan::~WaveChan() %s [%p]",m_id.c_str(),this);
|
||||
}
|
||||
|
||||
void WaveChan::disconnected(bool final, const char *reason)
|
||||
{
|
||||
Debugger debug("WaveChan::disconnected()"," '%s' [%p]",reason,this);
|
||||
}
|
||||
|
||||
bool WaveHandler::received(Message &msg)
|
||||
{
|
||||
String dest(msg.getValue("callto"));
|
||||
if (dest.null())
|
||||
return false;
|
||||
Regexp r("^wave/\\([^/]*\\)/\\(.*\\)$");
|
||||
if (!dest.matches(r))
|
||||
return false;
|
||||
|
||||
bool meth = false;
|
||||
if (dest.matchString(1) == "record")
|
||||
meth = true;
|
||||
else if (dest.matchString(1) != "play") {
|
||||
Debug(DebugWarn,"Invalid wavefile method '%s', use 'record' or 'play'",
|
||||
dest.matchString(1).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
String ml(msg.getValue("maxlen"));
|
||||
unsigned maxlen = ml.toInteger(0);
|
||||
DataEndpoint *dd = static_cast<DataEndpoint *>(msg.userData());
|
||||
if (dd) {
|
||||
Debug(DebugInfo,"%s wave file '%s'", (meth ? "Record to" : "Play from"),
|
||||
dest.matchString(2).c_str());
|
||||
WaveChan *c = new WaveChan(dest.matchString(2),meth,maxlen);
|
||||
if (dd->connect(c)) {
|
||||
c->deref();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
c->destruct();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const char *targ = msg.getValue("target");
|
||||
if (!targ) {
|
||||
Debug(DebugWarn,"Wave outgoing call with no target!");
|
||||
return false;
|
||||
}
|
||||
Message m("call.route");
|
||||
m.addParam("driver","wave");
|
||||
m.addParam("id",dest);
|
||||
m.addParam("caller",dest);
|
||||
m.addParam("called",targ);
|
||||
if (Engine::dispatch(m)) {
|
||||
m = "call.execute";
|
||||
m.addParam("callto",m.retValue());
|
||||
m.retValue() = 0;
|
||||
WaveChan *c = new WaveChan(dest.matchString(2),meth,maxlen);
|
||||
m.setParam("id",c->id());
|
||||
m.userData(c);
|
||||
if (Engine::dispatch(m)) {
|
||||
c->deref();
|
||||
return true;
|
||||
}
|
||||
Debug(DebugWarn,"Wave outgoing call not accepted!");
|
||||
c->destruct();
|
||||
}
|
||||
else
|
||||
Debug(DebugWarn,"Wave outgoing call but no route!");
|
||||
return false;
|
||||
Debug(DebugAll,"WaveChan::~WaveChan() %s [%p]",id().c_str(),this);
|
||||
}
|
||||
|
||||
bool AttachHandler::received(Message &msg)
|
||||
|
@ -489,8 +405,8 @@ bool AttachHandler::received(Message &msg)
|
|||
|
||||
String ml(msg.getValue("maxlen"));
|
||||
unsigned maxlen = ml.toInteger(0);
|
||||
DataEndpoint *dd = static_cast<DataEndpoint *>(msg.userData());
|
||||
if (!dd) {
|
||||
Channel *ch = static_cast<Channel*>(msg.userData());
|
||||
if (!ch) {
|
||||
if (!src.null())
|
||||
Debug(DebugWarn,"Wave source '%s' attach request with no data channel!",src.c_str());
|
||||
if (!cons.null())
|
||||
|
@ -499,16 +415,16 @@ bool AttachHandler::received(Message &msg)
|
|||
}
|
||||
|
||||
if (!src.null()) {
|
||||
WaveSource* s = new WaveSource(src,dd,false);
|
||||
WaveSource* s = new WaveSource(src,ch,false);
|
||||
s->setNotify(msg.getValue("notify"));
|
||||
dd->setSource(s);
|
||||
ch->setSource(s);
|
||||
s->deref();
|
||||
}
|
||||
|
||||
if (!cons.null()) {
|
||||
WaveConsumer* c = new WaveConsumer(cons,dd,maxlen);
|
||||
WaveConsumer* c = new WaveConsumer(cons,ch,maxlen);
|
||||
c->setNotify(msg.getValue("notify"));
|
||||
dd->setConsumer(c);
|
||||
ch->setConsumer(c);
|
||||
c->deref();
|
||||
}
|
||||
|
||||
|
@ -516,22 +432,81 @@ bool AttachHandler::received(Message &msg)
|
|||
return !more;
|
||||
}
|
||||
|
||||
WaveFilePlugin::WaveFilePlugin()
|
||||
: m_handler(0)
|
||||
bool WaveFileDriver::msgExecute(Message& msg, String& dest)
|
||||
{
|
||||
Regexp r("^\\([^/]*\\)/\\(.*\\)$");
|
||||
if (!dest.matches(r))
|
||||
return false;
|
||||
|
||||
bool meth = false;
|
||||
if (dest.matchString(1) == "record")
|
||||
meth = true;
|
||||
else if (dest.matchString(1) != "play") {
|
||||
Debug(DebugWarn,"Invalid wavefile method '%s', use 'record' or 'play'",
|
||||
dest.matchString(1).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
String ml(msg.getValue("maxlen"));
|
||||
unsigned maxlen = ml.toInteger(0);
|
||||
Channel* ch = static_cast<Channel*>(msg.userData());
|
||||
if (ch) {
|
||||
Debug(DebugInfo,"%s wave file '%s'", (meth ? "Record to" : "Play from"),
|
||||
dest.matchString(2).c_str());
|
||||
WaveChan *c = new WaveChan(dest.matchString(2),meth,maxlen);
|
||||
if (ch->connect(c)) {
|
||||
c->deref();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
c->destruct();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const char *targ = msg.getValue("target");
|
||||
if (!targ) {
|
||||
Debug(DebugWarn,"Wave outgoing call with no target!");
|
||||
return false;
|
||||
}
|
||||
Message m("call.route");
|
||||
m.addParam("driver","wave");
|
||||
m.addParam("id",dest);
|
||||
m.addParam("caller",dest);
|
||||
m.addParam("called",targ);
|
||||
if (Engine::dispatch(m)) {
|
||||
m = "call.execute";
|
||||
m.addParam("callto",m.retValue());
|
||||
m.retValue() = 0;
|
||||
WaveChan *c = new WaveChan(dest.matchString(2),meth,maxlen);
|
||||
m.setParam("id",c->id());
|
||||
m.userData(c);
|
||||
if (Engine::dispatch(m)) {
|
||||
c->deref();
|
||||
return true;
|
||||
}
|
||||
Debug(DebugWarn,"Wave outgoing call not accepted!");
|
||||
c->destruct();
|
||||
}
|
||||
else
|
||||
Debug(DebugWarn,"Wave outgoing call but no route!");
|
||||
return false;
|
||||
}
|
||||
|
||||
WaveFileDriver::WaveFileDriver()
|
||||
: Driver("wave","misc"), m_handler(0)
|
||||
{
|
||||
Output("Loaded module WaveFile");
|
||||
}
|
||||
|
||||
void WaveFilePlugin::initialize()
|
||||
void WaveFileDriver::initialize()
|
||||
{
|
||||
Output("Initializing module WaveFile");
|
||||
setup();
|
||||
if (!m_handler) {
|
||||
m_handler = new WaveHandler;
|
||||
m_handler = new AttachHandler;
|
||||
Engine::install(m_handler);
|
||||
Engine::install(new AttachHandler);
|
||||
}
|
||||
}
|
||||
|
||||
INIT_PLUGIN(WaveFilePlugin);
|
||||
|
||||
/* vi: set ts=8 sw=4 sts=4 noet: */
|
||||
|
|
Loading…
Reference in New Issue