⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 callbacklog.cpp

📁 一个c++实现的acd的例子。 ----ACDCommandListener.cpp ---ACDCommandListenerThread.cpp ---ACDConfig.cpp ---a
💻 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 + -