📄 callbacklog.cpp
字号:
/*=============================================================
Function:
This class stores calls that could not be routed, yet.
Author: Leon Wang <wlywly@sina.com giga2@tom.com>
==============================================================*/
// CallBacklog.cpp: implementation of the CCallBacklog class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CallBacklog.h"
#include "Acdconfig.h"
#include "acdx.h"
#include "socket/Lock.h"
extern Lock g_lock_pend; // use global lock parameter
//Lock g_lock_pend("pendlist");
#pragma warning(disable: 4786)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
class ACDConfig;
class ACDX;
class Agent;
//##ModelId=424BB6460279
CCallBacklog::CCallBacklog()
{
//pendingList.reserve(10);
}
//##ModelId=424BB646027A
CCallBacklog::CCallBacklog(GkClient* _gkclient)
{
gkclient = _gkclient;
config = ACDConfig::getInstance();
//pendingList.reserve(10);
}
//##ModelId=424BB6460288
CCallBacklog::~CCallBacklog()
{
}
/**
* Sore a new pending request if there is still rome in the queue, otherwise reject it.
* @param queue called queue
* @param callerEndId caller endpoint ID
* @param callRef callRef
* @param callerAlias caller H.323 alias
* @param callerIp caller IP
* @param status PendingRequest.RINGING / TALKING
*/
//synchronized
//##ModelId=424BB646028A
void CCallBacklog::store(CString queue,
CString callerEndId,
CString callRef,
CString callerAlias,
CString callerIp,
int status)
{
if (!g_lock_pend.lock()) {
return;
}
int maxSize = config->getMaxSize(queue);// this is queue size it in ini queuename_size=x
if ((maxSize <= 0) || (pendingList.size() < maxSize)) {
int priority = config->getPriority(queue);
//SYSTEMTIME systime;
//GetSystemTime(&systime);
//long timeout = systime.wMilliseconds;
long timeout = GetTickCount();
if (status == PendingRequest::TALKING)
timeout += (config->getTalkTimeout(queue) * 1000);
else
timeout += (config->getRingTimeout(queue) * 1000);
PendingRequest* request = new PendingRequest(priority, queue, callerEndId, callRef, callerAlias, callerIp, timeout, status);
Logger::log("Call from " + callerAlias + " to " + queue + " queued.");
pendingList.reserve(10);
pendingList.push_back(*request); // add this pendrequest in list
} else {
Logger::log("Queue for " + queue + " is full - rejecting call.");
gkclient->routeReject(callerEndId, callRef);
}
g_lock_pend.unlock();
}
/**
* Check if requests have expired and delete + reject them.
*/
//synchronized
//##ModelId=424BB64602A7
void CCallBacklog::expire()
{
if (!g_lock_pend.lock()) {
return;
}
//SYSTEMTIME systime;
//GetSystemTime(&systime);
//long now = systime.wMilliseconds;
long now = GetTickCount();
std::vector<PendingRequest>::iterator pendElement;
for(pendElement=pendingList.begin();pendElement!=pendingList.end();++pendElement)
{
if(pendingList.empty()) break;
PendingRequest r = (PendingRequest) *pendElement;
if (r.timeout<now) {
CString wqName;
if (r.status == PendingRequest::TALKING) {
Logger::log("Pending call from " + r.callerAlias + " to " + r.queue + " expired in talking queue.");
if(!pendingList.empty())
{
pendElement = pendingList.erase(pendElement); // remove iterator
gkclient->disconnectAlias(r.callerAlias);
}
}else if ( (config->getQueueingMode(r.queue) == ACDConfig::QUEUEING_MODE_RINGANDTALK) && // transfer if: queue mode is talk after ring
(r.status == PendingRequest::RINGING) &&
( ((wqName = ACDX::getInstance()->getWaitQueue(r.queue)) != "") ) )
{ // AND we have a talinmg queue available
Logger::debug("*---callback expire-waiting queue name "+wqName);//test wqueue name
Logger::log("Pending call from " + r.callerAlias + " to " + r.queue + " routed to WQ " + wqName + " after ring timeout.");
gkclient->routeToAlias(wqName, r.callerEndId, r.callRef);
r.status = PendingRequest::TALKING;
//SYSTEMTIME systime2;
//GetSystemTime(&systime2);
//r.timeout = systime2.wMilliseconds + (config->getTalkTimeout(r.queue) * 1000);
r.timeout = GetTickCount() + (config->getTalkTimeout(r.queue) * 1000);
}else
{
Logger::log("Pending call from " + r.callerAlias + " to " + r.queue + " expired.");
if(!pendingList.empty())
{
pendElement = pendingList.erase(pendElement); // remove iterator;
gkclient->routeReject(r.callerEndId, r.callRef);
}
}
}
}
g_lock_pend.unlock();
}
/**
* Check if we have a pending call this agent could handle.
* @param agent available Agent
*/
//synchronized
//##ModelId=424BB64602A8
void CCallBacklog::checkPending(Agent* agent,aList & _aliasList)
{
if (!g_lock_pend.lock()) {
return;
}
std::vector<PendingRequest>::iterator pendElement;
PendingRequest r;
for(pendElement=pendingList.begin();pendElement!=pendingList.end();++pendElement)
{
if (pendingList.empty()) {
break;
}
r = (PendingRequest) *pendElement;
if (agent->isAvailable(r.queue)) {
CString alias = agent->getAlias();//((Alias*)agent)->getAlias();
Logger::log("Pending call from " + r.callerAlias + " to " + r.queue + " routed to " + alias);
if (!pendingList.empty())
{
pendElement = pendingList.erase(pendElement); // remove iterator;
// need set aliaslist -- add code
std::list<Agent>::iterator aliasElement;
Agent _agent;
for(aliasElement = _aliasList.begin();aliasElement != _aliasList.end();aliasElement++ )
{
_agent = *aliasElement;
if (_agent.getAlias()==alias) {
aliasElement->setState(Alias::TALKING);
aliasElement->setLastCall();
}//if
}//for
if (r.status == PendingRequest::RINGING)
gkclient->routeToAlias(alias, r.callerEndId, r.callRef);// routecall in gk
else
gkclient->transferCall(r.callerAlias, alias);// transfercall in gk
return;
}
}
}
g_lock_pend.unlock();
}
/**
* Remove all pending requests for this endpoint ID.
* @param epid endpoint ID
*/
// public synchronized
//##ModelId=424BB64602AB
void CCallBacklog::removeAllRequests(CString epid)
{
if (!g_lock_pend.lock()) {
return;
}
std::vector<PendingRequest>::iterator pendElement;
for(pendElement=pendingList.begin();pendElement!=pendingList.end();pendElement++)
{
if (pendingList.empty()) {
break;
}
PendingRequest r = (PendingRequest) *pendElement;
if (epid==r.callerEndId)
{
pendElement = pendingList.erase(pendElement); // remove iterator;
}
if (pendingList.empty()) {
break;
}
}
g_lock_pend.unlock();
}
/**
* Dump the list of all pending requests for debug.
* @return formatted list
*/
// synchronized
//##ModelId=424BB64602B8
CString CCallBacklog::dumpPendingList()
{
if (!g_lock_pend.lock()) {
return "";
}
//pendingList.
if (pendingList.empty()) {
return "no caller in pending list!";
}
int pendlistNumber = pendingList.size();
char ch[4];
itoa(pendlistNumber,ch,10);
CString result = "Pending list (" + CString(ch) + " entries)\n";
std::vector<PendingRequest>::iterator pendElement;
for(pendElement=pendingList.begin();pendElement!=pendingList.end();++pendElement)
{
PendingRequest r = (PendingRequest) *pendElement;
char pri_ch[4];
itoa(r.priority,pri_ch,10); // pri int number
result = result + r.queue + " (priority level: " + CString(pri_ch) + ") " + r.callerAlias + " (" + r.callerEndId + "/" +r.callRef + ")\n";
}
return result;
g_lock_pend.unlock();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -