Ejemplo n.º 1
0
bool ACDQueue_Linear::buildTargetAgentList(UtlSList& rTargetAgentList, ACDCall* pCallRef)
{
   ACDAgent* pAgent;
   ACDAgent* pLastAttemptedAgent;

   // Always rebuild the list to get the agents added on the fly
   buildACDAgentList();

   UtlSListIterator listIterator(mAcdAgentList);
   int numAgents = mAcdAgentList.entries();

   // Iterate through the ACDAgent list, starting after the agent that
   // The ACDCall was last using.  If the end of the list is
   // reached, wrap around to the beginning.  If this LastAttemptedAgent
   // is NULL, start from the head of the list
   pLastAttemptedAgent = pCallRef->getLastAgent();
   if (pLastAttemptedAgent != NULL) {
      // walk the iterator to point after pLastAttemptedAgent
      if (listIterator.findNext(pLastAttemptedAgent) == NULL) {
         // Didn't find pLastAttemptedAgent, start again from the top.
         listIterator.reset();
         pCallRef->setLastAgent(NULL);
      }
   }

   for(int i=0; i<numAgents; i++) {
      // Check the next agent
      pAgent = dynamic_cast<ACDAgent*>(listIterator());
      if (pAgent == NULL) {
         // We've hit the end of the list start back from the head of the list
         listIterator.reset();
         pAgent = dynamic_cast<ACDAgent*>(listIterator());
         if (pAgent == NULL) {
            // All out of agents to try
            return false;
         }
      }

      if (pAgent->isAvailable(true)) {
         rTargetAgentList.append(pAgent);
         // Remember the agent chosen
         pCallRef->setLastAgent(pAgent);
         OsSysLog::add(FAC_ACD, gACD_DEBUG, "%s::buildTargetAgentList - agent(%s) is added to the target list",
                       mAcdSchemeString, pAgent->getUriString()->data());
         return true;
      }
   }

   // The whole list was tried, yet no appropriate agents were found.
   return false;
}
Ejemplo n.º 2
0
bool ACDCallManager::validateTransferToLine(SIPX_CALLSTATE_INFO* pCallInfo)
{
   SIPX_CALL hAssociatedCallHandle;
   int       callEvent;
   int       callCause;
   const char*     remUri;
   char      userUri[512];

   mLock.acquire();


   // Extract the call handle and state info
   hAssociatedCallHandle = pCallInfo->hAssociatedCall;
   callEvent   = pCallInfo->event;
   callCause   = pCallInfo->cause;
   remUri      = pCallInfo->remoteAddress;

   UtlString userId, hostAddress;
   Url remoteUrl(remUri);
   remoteUrl.getUserId(userId);
   remoteUrl.getHostAddress(hostAddress);

   if (remUri) {
      // Now find out if there is an agent for this remUri
      sprintf(userUri,"sip:%s@%s",userId.data(),hostAddress.data()); 
      UtlString agentUri(userUri);
      ACDAgent* pAgentRef =
         mpAcdServer->getAcdAgentManager()->getAcdAgentReference(agentUri);
      if ((pAgentRef) && (FALSE == pAgentRef->isFree())) {
         mLock.release();
         return TRUE;
      }
   }

   mLock.release();
   return FALSE;
}
Ejemplo n.º 3
0
bool ACDQueue_LongestIdle::buildTargetAgentList(UtlSList& rTargetAgentList, ACDCall* pCallRef)
{
    // Always rebuild the list to get the agents added on the fly
    buildACDAgentList();

    // Iterate through the ACDAgent list, starting at the head of the list
    // and find the agent that has been idle the longest.
    for(;;) {
        ACDAgent* pAgent;
        ACDAgent* pLongestIdleAgent = NULL;
        unsigned long maxIdleTime = 0;
        UtlSListIterator listIterator(mAcdAgentList);

        // Find the available agent with the longest idle time
        while ((pAgent = dynamic_cast<ACDAgent*>(listIterator())) != NULL) {
            if (pAgent->isAvailable(false)) {
                if (pAgent->getIdleTime() >= maxIdleTime) {
                    maxIdleTime = pAgent->getIdleTime();
                    pLongestIdleAgent = pAgent;
                }
            }
        }

        if (pLongestIdleAgent == NULL) {
            // None available
            break ;
        }

        // If he is still available, use him.  Otherwise start again.
        if (pLongestIdleAgent->isAvailable(true)) {
            rTargetAgentList.append(pLongestIdleAgent);
            OsSysLog::add(FAC_ACD, gACD_DEBUG, "%s::buildTargetAgentList - agent(%s) is added to the target list.  Idle time was %lu seconds",
                          mAcdSchemeString, pLongestIdleAgent->getUriString()->data(),
                          maxIdleTime);
            return true ;
        }
    }

    // The whole list was tried, yet no appropriate agents were found.
    return false;
}
Ejemplo n.º 4
0
void ACDCallManager::updateTransferCallState(SIPX_CALLSTATE_INFO* pCallInfo)
{
   SIPX_CALL hCallHandle = SIPX_CALL_NULL;
   SIPX_CALL hAssociatedCallHandle;
   int       callEvent;
   int       callCause;
   const char*     remUri;
   char      userUri[512];
   ACDCall*  pCallRef;

   mLock.acquire();


   // Extract the call handle and state info
   hAssociatedCallHandle = pCallInfo->hAssociatedCall;
   callEvent   = pCallInfo->event;
   callCause   = pCallInfo->cause;
   remUri      = pCallInfo->remoteAddress;

   /**
    * For the NEWCALL_TRANSFER event - find the ACDCall object instance
    * on the basis of the Associated call handle (from the older leg).
    */
   if (pCallInfo->cause == CALLSTATE_NEW_CALL_TRANSFER)
   {
      if (TRUE == validateTransferToLine(pCallInfo))
      {
         // Don't allow agents to transfer calls INTO the acd.  It screws
         // things up.  The correct behavior would be to move the call
         // the agent is currently handling into a new queue, but due to
         // the inability to remove calls from a conference, this just doesn't
         // work.  Hangup on the transfer attempt.  Ths should leave
         // caller and agent connected.
         OsSysLog::add(FAC_ACD, PRI_WARNING,
                       "ACDCallManager::updateTransferCallState - "
                       "CALLSTATE_OFFERING::%d to the ACD Line REJECTED",
                       pCallInfo->cause);
         sipxCallReject(pCallInfo->hCall, SIP_BAD_REQUEST_CODE, "Agent Transfer Loop Rejected");
         return ;
      }

      // not an agent transferring into the acd
      hCallHandle = hAssociatedCallHandle;
      UtlInt callKey(hCallHandle);
      pCallRef = dynamic_cast<ACDCall*>(mAgentCallHandleMap.findValue(&callKey));
   }
   else     // not new call transfer
   {
      UtlInt searchKey(pCallInfo->hCall);
      pCallRef = dynamic_cast<ACDCall*>(mTransferCallHandleMap.findValue(&searchKey));
   }

   if (pCallRef != NULL)
   {
      if (callCause == CALLSTATE_NEW_CALL_TRANSFER)
      {
         addMapTransferAgentCallHandleToCall(pCallInfo->hCall, pCallRef);
         pCallRef->mFlagTransfer = TRUE;    // only set TRUE here.
      }

      if (   (callCause == CALLSTATE_REMOTE_OFFERING_NORMAL)
          && (pCallRef->mFlagTransfer == TRUE))
      {
         UtlString userId, hostAddress;
         Url remoteUrl(remUri);
         remoteUrl.getUserId(userId);
         remoteUrl.getHostAddress(hostAddress);

         if (remUri)
         {
            // Now find the agent for this remUri
            sprintf(userUri,"sip:%s@%s",userId.data(),hostAddress.data());
            UtlString agentUri(userUri);
            ACDAgent* pAgentRef =
                     mpAcdServer->getAcdAgentManager()->getAcdAgentReference(agentUri);
            if (!pAgentRef)
            {
               OsSysLog::add(FAC_ACD, gACD_DEBUG,
                             "ACDCallManager::updateTransferCallState - "
                             "Failed to find Agent. This is probably an agent that is not signed in: "
                             "call(%d), TransferAgentCall(%d), agentUri(%s)",
                             pCallRef->getCallHandle(), pCallInfo->hCall, agentUri.data());
               // A non registered agent is not yet supported - so do not try !
               pAgentRef = mpAcdServer->getAcdAgentManager()->createACDAgent(userUri,
                                                                             "dummy", "",
                                                                             FALSE, FALSE, NULL, TRUE);

               if (!pAgentRef)
               {
                   assert(0);
               }
            }

            //set the mhCallHandle of the Agent object
            pAgentRef->setCallHandle(pCallInfo->hCall);
            // set the transfer agent object in the call object
            pCallRef->mpTransferAgent = pAgentRef;
            OsSysLog::add(FAC_ACD, gACD_DEBUG,
                          "ACDCallManager::updateTransferCallState - "
                          "success in finding Agent: call(%d), TransferAgentCall(%d) AgentUri(%s)",
                          pCallRef->getCallHandle(), pCallInfo->hCall, pAgentRef->getUriString()->data());
         }
      }

      if (   (callCause == CALLSTATE_REMOTE_OFFERING_NORMAL)
          && (pCallRef->mFlagTransfer == FALSE))
      {
           ; // do nothing
      }
      else
      {
           pCallRef->updateState(hCallHandle, callEvent, callCause);
      }
   }

   mLock.release();
   return;
}