From 05ef31e6b734239a3e2fc45a9bd7820c6c5fa490 Mon Sep 17 00:00:00 2001 From: paulc Date: Tue, 18 Aug 2009 14:55:25 +0000 Subject: [PATCH] Added parameter "queuetime" for the CDR builder to know how long a call waited in a queue. All calls in a queue can be dropped by specifying queuename/* as id. A call to a "single" type queue is dropped when its operator call fails. git-svn-id: http://yate.null.ro/svn/yate/trunk@2795 acf43c95-373e-0410-b603-e72c3f656dc1 --- conf.d/queues.conf.sample | 2 +- modules/server/queues.cpp | 52 +++++++++++++++++++++++++++++---------- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/conf.d/queues.conf.sample b/conf.d/queues.conf.sample index c1e02c5d..340fe4a1 100644 --- a/conf.d/queues.conf.sample +++ b/conf.d/queues.conf.sample @@ -5,7 +5,7 @@ ;account= ; priority: int: Default priority of message handlers, 0 to disable them -;priority=50 +;priority=45 ; rescan: int: Period of polling for available operators, in seconds ;rescan=5 diff --git a/modules/server/queues.cpp b/modules/server/queues.cpp index f6073ac2..07a371e6 100644 --- a/modules/server/queues.cpp +++ b/modules/server/queues.cpp @@ -65,10 +65,12 @@ public: { return m_calls.count(); } inline QueuedCall* findCall(const String& id) const { return static_cast(m_calls[id]); } + inline QueuedCall* findCall(unsigned int index) const + { return static_cast(m_calls[index]); } bool addCall(Message& msg); - inline bool removeCall(const String& id, const char* reason) + inline int removeCall(const String& id, const char* reason) { return removeCall(findCall(id),reason); } - bool removeCall(QueuedCall* call, const char* reason); + int removeCall(QueuedCall* call, const char* reason); QueuedCall* markCall(const char* mark); bool unmarkCall(const String& id); void countCalls(unsigned int& marked, unsigned int& unmarked) const; @@ -113,7 +115,7 @@ protected: void onHangup(Message& msg, String id); void onQueued(Message& msg, String qname); void onPickup(Message& msg, String qname); - void onDrop(Message& msg, String qname); + bool onDrop(Message& msg, String qname); private: bool m_init; }; @@ -298,10 +300,11 @@ bool CallsQueue::addCall(Message& msg) } // Remove and destroy call from the queue, destroy the queue if it becomes empty -bool CallsQueue::removeCall(QueuedCall* call, const char* reason) +int CallsQueue::removeCall(QueuedCall* call, const char* reason) { if (!call) - return false; + return -1; + int waited = (call->waitingTime() + 500000) / 1000000; notify(reason,call); int pos = m_detail ? position(call) : -1; m_calls.remove(call); @@ -315,7 +318,7 @@ bool CallsQueue::removeCall(QueuedCall* call, const char* reason) notify("position",c); } } - return true; + return waited; } // Mark a call as being routed to an operator @@ -340,6 +343,10 @@ bool CallsQueue::unmarkCall(const String& id) return false; if (m_single) { removeCall(call,"noanswer"); + Message* m = new Message("call.drop"); + m->addParam("id",id); + m->addParam("reason","noanswer"); + Engine::enqueue(m); return false; } call->setMarked(); @@ -568,7 +575,7 @@ void QueuesModule::onPickup(Message& msg, String qname) if (call) { id = *call; String pid = msg.getValue("id"); - queue->removeCall(call,"pickup"); + String waited(queue->removeCall(call,"pickup")); // convert message and let it connect to the queued call msg = "chan.connect"; msg.setParam("targetid",id); @@ -581,6 +588,7 @@ void QueuesModule::onPickup(Message& msg, String qname) m = new Message("call.answered"); m->setParam("id",id); m->setParam("targetid",pid); + m->setParam("queuetime",waited); Engine::enqueue(m); return; } @@ -608,7 +616,11 @@ void QueuesModule::onAnswered(Message& msg, String targetid, String reason) return; Debug(this,DebugCall,"Answered call '%s' in queue '%s'", targetid.c_str(),queue->c_str()); - queue->removeCall(targetid,"answered"); + String waited(queue->removeCall(targetid,"answered")); + Message* m = new Message("call.update"); + m->addParam("id",targetid); + m->addParam("queuetime",waited); + Engine::enqueue(m); } // Handle hangups on either caller or operator @@ -637,10 +649,10 @@ void QueuesModule::onHangup(Message& msg, String id) } // Drop the call from the head of a queue or a call specified by ID -void QueuesModule::onDrop(Message& msg, String qname) +bool QueuesModule::onDrop(Message& msg, String qname) { if (qname.null()) - return; + return false; String id; int sep = qname.find('/'); if (sep >= 0) { @@ -649,6 +661,20 @@ void QueuesModule::onDrop(Message& msg, String qname) } CallsQueue* queue = findQueue(qname); if (queue) { + if (id == "*") { + const char* reason = msg.getValue("reason"); + for (unsigned int i = 0; ; i++) { + QueuedCall* call = queue->findCall(i); + if (!call) + break; + Message* m = new Message("call.drop"); + m->addParam("id",*call); + if (reason) + m->addParam("reason",reason); + Engine::enqueue(m); + } + return true; + } QueuedCall* call = id ? queue->findCall(id) : queue->topCall(); if (call) { id = *call; @@ -657,6 +683,7 @@ void QueuesModule::onDrop(Message& msg, String qname) msg.setParam("id",id); } } + return false; } // Command line execute handler @@ -696,8 +723,7 @@ bool QueuesModule::received(Message& msg, int id) onHangup(msg,msg.getValue("id")); break; case Drop: - onDrop(msg,msg.getValue("id")); - break; + return onDrop(msg,msg.getValue("id")); default: lock.drop(); return Module::received(msg,id); @@ -752,7 +778,7 @@ void QueuesModule::initialize() return; m_init = true; setup(); - int priority = s_cfg.getIntValue("general","priority",50); + int priority = s_cfg.getIntValue("general","priority",45); installRelay(Execute,s_cfg.getIntValue("priorities","call.execute",priority)); installRelay(Answered,s_cfg.getIntValue("priorities","call.answered",priority)); installRelay(Private,"chan.hangup",s_cfg.getIntValue("priorities","chan.hangup",priority));