diff --git a/engine/Channel.cpp b/engine/Channel.cpp index b0fcc29e..02d84568 100644 --- a/engine/Channel.cpp +++ b/engine/Channel.cpp @@ -178,7 +178,7 @@ Message* Channel::message(const char* name, bool minimal) const return msg; } -bool Channel::startRouter(Message* msg) const +bool Channel::startRouter(Message* msg) { if (!msg) return false; @@ -190,6 +190,10 @@ bool Channel::startRouter(Message* msg) const } else delete msg; + callReject("failure","Internal server error"); + // dereference and die if the channel is dynamic + if (m_driver && m_driver->varchan()) + deref(); return false; } @@ -278,7 +282,6 @@ DataEndpoint* Channel::setEndpoint(const char* type) dat = new DataEndpoint(this,type); if (m_peer) dat->connect(m_peer->getEndpoint(type)); -// dat->ref(); } return dat; } @@ -329,7 +332,7 @@ TokenDict Module::s_messages[] = { { 0, 0 } }; -unsigned int Module::s_delay = 2; +unsigned int Module::s_delay = 5; const char* Module::messageName(int id) { @@ -382,6 +385,7 @@ void Module::initialize() void Module::setup() { + Debug(DebugAll,"Module::setup()"); if (m_init) return; m_init = true; @@ -492,7 +496,9 @@ bool Module::setDebug(Message& msg, const String& target) Driver::Driver(const char* name, const char* type) - : Module(name,type), m_init(false), m_routing(0), m_routed(0), m_nextid(0) + : Module(name,type), + m_init(false), m_varchan(true), + m_routing(0), m_routed(0), m_nextid(0) { m_prefix << name << "/"; } @@ -511,6 +517,7 @@ void Driver::initialize() void Driver::setup(const char* prefix, bool minimal) { + Debug(DebugAll,"Driver::setup('%s',%d)",prefix,minimal); Module::setup(); if (m_init) return; @@ -712,7 +719,8 @@ bool Router::route() m_driver->lock(); Channel* chan = m_driver->find(m_id); if (chan) { - // this will keep it referenced + // this will keep it referenced even if message user data is changed + chan->ref(); m_msg->userData(chan); chan->status("routed"); } @@ -728,16 +736,18 @@ bool Router::route() m_msg->setParam("callto",m_msg->retValue()); m_msg->retValue().clear(); ok = Engine::dispatch(m_msg); - if (ok) { + if (ok) chan->callAccept(*m_msg); - chan->deref(); - } else chan->callReject("noconn","Could not connected to target"); } else chan->callReject("noroute","No route to call target"); + chan->deref(); + // dereference again if the channel is dynamic + if (m_driver->varchan()) + chan->deref(); return ok; } diff --git a/modules/iaxchan.cpp b/modules/iaxchan.cpp index 51788ed0..1b775f5b 100644 --- a/modules/iaxchan.cpp +++ b/modules/iaxchan.cpp @@ -655,6 +655,7 @@ 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) diff --git a/modules/libypri.cpp b/modules/libypri.cpp index c863155b..987ef9c6 100644 --- a/modules/libypri.cpp +++ b/modules/libypri.cpp @@ -877,6 +877,7 @@ bool PriDriver::s_init = true; PriDriver::PriDriver(const char* name) : Driver(name,"fixchans") { + varchan(false); if (s_init) { s_init = false; for (unsigned int c = 0; c <= 255; c++) { @@ -948,6 +949,20 @@ bool PriDriver::isBusy() const return false; } +void PriDriver::statusParams(String& str) +{ + Driver::statusParams(str); + String sp; + const ObjList *l = &m_spans; + for (; l; l=l->next()) { + PriSpan *s = static_cast(l->get()); + if (s) + sp.append(String(s->chans()),"|"); + } + if (sp) + str.append("spanlen=",",") << sp; +} + void PriDriver::netParams(Configuration& cfg, const String& sect, int chans, int* netType, int* swType, int* dChan) { if (netType) diff --git a/modules/libypri.h b/modules/libypri.h index 28f6dafc..c505879c 100644 --- a/modules/libypri.h +++ b/modules/libypri.h @@ -205,6 +205,7 @@ public: { return s_bitswap[v]; } protected: PriDriver(const char* name); + void statusParams(String& str); private: ObjList m_spans; static u_int8_t s_bitswap[256]; diff --git a/yatephone.h b/yatephone.h index f5609eb4..033962f0 100644 --- a/yatephone.h +++ b/yatephone.h @@ -1082,12 +1082,12 @@ public: { disconnect(false,reason); } /** - * Start a routing thread for this channel + * Start a routing thread for this channel, dereference dynamic channels * @param msg Pointer to message to route, typically a "call.route", will be * destroyed after routing fails or completes * @return True if routing thread started successfully, false if failed */ - bool startRouter(Message* msg) const; + bool startRouter(Message* msg); /** * Get a data endpoint of this object @@ -1191,6 +1191,7 @@ class YATE_API Driver : public Module private: bool m_init; + bool m_varchan; String m_prefix; ObjList m_chans; int m_routing; @@ -1212,6 +1213,13 @@ public: inline const String& prefix() const { return m_prefix; } + /** + * Check if this driver is for dynamic (variable number) channels + * @return True if the channels are dynamic, false for fixed + */ + inline bool varchan() const + { return m_varchan; } + /** * Get the list of channels of this driver * @return A reference to the channel list @@ -1323,6 +1331,13 @@ protected: */ virtual bool setDebug(Message& msg, const String& target); + /** + * Set if this driver is for dynamic (variable number) channels + * @param variable True if the channels are dynamic, false for fixed + */ + inline void varchan(bool variable) + { m_varchan = variable; } + private: Driver(); // no default constructor please };