www.pudn.com > acdx.rar > CallBacklog.cpp
/*============================================================= Function: This class stores calls that could not be routed, yet. Author: Leon Wang==============================================================*/ // 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 ::iterator pendElement; for(pendElement=pendingList.begin();pendElement!=pendingList.end();++pendElement) { if(pendingList.empty()) break; PendingRequest r = (PendingRequest) *pendElement; if (r.timeout 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 ::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 ::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 ::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 ::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(); }