Пример #1
0
bool cAlarmServer::loadAlarmStrings(const UtlString& stringsFile)
{
   // load file in English for fallback
   bool loadResult = loadAlarmStringsFile(stringsFile);

   // load localized version if available
   if (!mLanguage.isNull() && mLanguage.compareTo("en"))
   {
      UtlString localStringsFile = stringsFile;
      ssize_t pos = localStringsFile.index(".xml");
      if (pos != UTL_NOT_FOUND)
      {
         // append language to string file name
         UtlString langSuffix = mLanguage;
         langSuffix.insert(0, "_");
         localStringsFile = localStringsFile.insert(pos, langSuffix);
         loadResult = loadAlarmStringsFile(localStringsFile);
      }
      else
      {
         OsSysLog::add(FAC_ALARM, PRI_NOTICE,
               "stringsFile %s is not .xml, not loading local language", stringsFile.data());
         loadResult = false;
      }
   }

   return loadResult;
}
RedirectPlugin::LookUpStatus
SipRedirectorPresenceRouting::doLookUp(
   const Url& toUrl,
   ContactList& contactList)
{
   // check if we have unified presence info for this user
   const UnifiedPresence* pUp;
   UtlString to;
   UtlString username;
   toUrl.getIdentity( to );
   toUrl.getUserId( username );
   OsSysLog::add(FAC_SIP, PRI_INFO, "%s::LookUpStatus is looking up '%s'",
                                    mLogName.data(),to.data() );
   pUp = UnifiedPresenceContainer::getInstance()->lookup( &to );

   if( pUp )
   {
      // unified presence data is available for the called party.
      // Use it to make call routing decisions.
       OsSysLog::add(FAC_SIP, PRI_INFO, "%s::LookUpStatus "
                                        "Presence information for '%s':\r\n"
                                        "    Telephony presence: '%s'"
                                        "    XMPP presence: '%s'"
                                        "    Custom presence message: '%s'",
                                        mLogName.data(),
                                        to.data(), pUp->getSipState().data(),
                                        pUp->getXmppPresence().data(),
                                        pUp->getXmppStatusMessage().data() );

       // look for tel uri in the custom presence message

       RegEx telUri( TelUri );
       telUri.Search( pUp->getXmppStatusMessage().data() );
       UtlString targetUri;
       if( telUri.MatchString( &targetUri, 1 ) )
       {
         // prepend 'sip:' and add target as contact
         targetUri.insert( 0, "sip:" );
         contactList.add( targetUri, *this );
      }
      else
      {
         // If user is busy then call goes directly to voicemail.
         if( ( pUp->getSipState().compareTo("BUSY", UtlString::ignoreCase ) == 0 && mbForwardToVmOnBusy ) ||
             ( pUp->getXmppPresence().compareTo("BUSY", UtlString::ignoreCase ) == 0 && mUserPrefs.forwardToVoicemailOnDnd( username ) ) )
         {
            // prune all non-voicemail contacts from the list
            removeNonVoicemailContacts( contactList );
         }
      }
   }
   return RedirectPlugin::SUCCESS;
}
Пример #3
0
// Construct a tuple id from a presence resource name.
void SipPresenceMonitor::makeId(UtlString& id,             ///< output: tuple id
                                const UtlString& resource  ///< resource URI
   )
{
   // Construct the id by hashing the resource URI.  But we must prepend
   // a letter, because tuple id's can't start with digits.
   // (Tuple id's are defined in RFC 3863 section 4.4 to be type 'ID' from
   // http://www.w3.org/2001/XMLSchema.
   // http://www.w3.org/TR/xmlschema-2/#ID tells that their grammar is
   // "NCName" from Namespaces in XML.
   // http://www.w3.org/TR/1999/REC-xml-names-19990114/#NT-NCName gives the
   // grammar.)
   NetMd5Codec::encode(resource.data(), id); // clears previous contents of 'id'.
   id.insert(0, 'I');
}
Пример #4
0
UtlBoolean SipUserAgentStateless::sendTo(SipMessage& message,
        const char* sendAddress,
        const char* sendProtocol,
        int sendPort)
{
    UtlBoolean sendOk = FALSE;

    if(sendAddress && *sendAddress && mpUdpServer)
    {
        if (!portIsValid(sendPort))
        {
            sendPort = SIP_PORT;
        }

        sendOk = mpUdpServer->sendTo(message, sendAddress, sendPort);
    }

    // Log the message
    if (isMessageLoggingEnabled())
    {
        UtlString messageStatus;
        char messageChars[200];
        if(sendOk)
            sprintf(messageChars, "Sent message %s port:%d:\n",
                    sendAddress, sendPort);
        else
            sprintf(messageChars, "Failed to send message %s port:%d:\n",
                    sendAddress, sendPort);
        messageStatus = messageChars;
        UtlString msgBytes;
        int msgLen;
        message.getBytes(&msgBytes, &msgLen);
        msgBytes.insert(0, messageStatus);
        msgBytes.append("--------------------END--------------------\n");
        logMessage(msgBytes.data(), msgBytes.length());
    }

    return(sendOk);
}
Пример #5
0
int SipUdpServer::run(void* runArg)
{
    int cseq = 1;
    if(mSipUserAgent)
    {
        UtlString contact;
        mSipUserAgent->getContactUri(&contact);

        // Add a tag to the contact and build the from field
        UtlString from(contact);
        int tagRand1 = rand();
        int tagRand2 = rand();
        char fromTag[80];
        sprintf(fromTag, ";tag=%d%d", tagRand1, tagRand2);
        from.append(fromTag);

        UtlString rawAddress;
        int port;
        Url pingUrl(mNatPingUrl);

        // Create a cannonized version of the ping URL in case
        // it does not specify "sip:", etc.
        UtlString cannonizedPingUrl = pingUrl.toString();

        // Get the address and port in the png URL so that
        // we can look up the DNS stuff if needed
        port = pingUrl.getHostPort();
        pingUrl.getHostAddress(rawAddress);

        // Resolve the raw address from a DNS SRV, A record
        // to an IP address
        server_t* dnsSrvRecords =
            SipSrvLookup::servers(rawAddress.data(),
                                  "sip",
                                  OsSocket::UDP,
                                  port);

        // Do a DNS SRV or A record lookup
        // If we started with an IP address, we will still get an IP
        // address in the result
        UtlString address;
        if(dnsSrvRecords[0].isValidServerT())
        {
            // Get the highest priority address and port from the
            // list with randomization of those according to the
            // weights.
            // Note: we are not doing any failover here as that is
            // a little tricky with the NAT stuff.  We cannot change
            // addresses with every transaction as we may get different
            // ports and addresses every time we send a ping.  For now
            // we do one DNS SRV lookup at the begining of time and
            // stick to that result.
            dnsSrvRecords[0].getIpAddressFromServerT(address);
            port = dnsSrvRecords[0].getPortFromServerT();

            // If the ping URL or DNS SRV did not specify a port
            // bind it to the default port.
            if (!portIsValid(port))
            {
               port = SIP_PORT;
            }
        }

        // Did not get a valid response from the DNS lookup
        else
        {
            // Configured with a bad DNS name that did not resolve.
            // Or the DNS server did not respond.
            if(!rawAddress.isNull())
            {
                OsSysLog::add(FAC_SIP, PRI_INFO,
                    "SipUdpServer::run DNS lookup failed for ping host: %s in URI: %s",
                    rawAddress.data(), mNatPingUrl.data());
            }
            // Else no ping address, this means we are not supposed to
            // do a ping
        }
        // Free the list of server addresses.
        delete[] dnsSrvRecords;

        // Get the address to be used in the callId scoping
        int dummyPort;
        UtlString callId;
        
        if (mSipUserAgent)
        {
            mSipUserAgent->getViaInfo(OsSocket::UDP, callId, dummyPort);
        }

        // Make up a call Id
        long epochTime = OsDateTime::getSecsSinceEpoch();
        int randNum = rand();
        char callIdPrefix[80];
        sprintf(callIdPrefix, "%ld%d-ping@", epochTime, randNum);
        callId.insert(0,callIdPrefix);

        while(mNatPingFrequencySeconds > 0 &&
            !mNatPingUrl.isNull() &&
            !mNatPingMethod.isNull() &&
            !address.isNull())
        {
            // Send a no-op SIP message to the
            // server to keep a port open through a NAT
            // based firewall
            SipMessage pingMessage;
            pingMessage.setRequestData(mNatPingMethod, cannonizedPingUrl.data(),
                from.data(), mNatPingUrl.data(), callId, cseq, contact.data());

            // Get the UDP via info from the SipUserAgent
            UtlString viaAddress;
            int viaPort;
            
            if (mSipUserAgent)
            {
                mSipUserAgent->getViaInfo(OsSocket::UDP, viaAddress, viaPort);
            }
            pingMessage.addVia(viaAddress.data(), viaPort, SIP_TRANSPORT_UDP);

            // Mark the via so the receiver knows we support and want the
            // received port to be set
            pingMessage.setLastViaTag("", "rport");
#           ifdef TEST_PRINT            
            osPrintf("Sending ping to %s %d, From: %s\n",
                address.data(), port, contact.data());
#           endif
            
            // Send from the same UDP port that we receive from
            if (mSipUserAgent)
            {
                mSipUserAgent->sendSymmetricUdp(pingMessage, address.data(), port);
            }

            cseq++;

            // Wait until it is time to send another ping
            delay(mNatPingFrequencySeconds * 1000);
        }
    }

    return(mNatPingFrequencySeconds);
}
Пример #6
0
/* //////////////////////////// PROTECTED ///////////////////////////////// */
void Connection::postTaoListenerMessage(int state, int newCause, int isLocal)
{
    int eventId = PtEvent::EVENT_INVALID;
    int termEventId = PtEvent::EVENT_INVALID;
    UtlString causeStr;
    causeStr.remove(0);

#ifdef TEST_PRINT
    Os::Logger::instance().log(FAC_CP, PRI_DEBUG, "Connection::postTaoListenerMessage: "
                  "Enter- %s state %d cause %d "
                  "eventid-  %d termeventid %d",
                  (isLocal?"LOCAL":"REMOTE"),
                  state, newCause,
                  eventId, termEventId);
#endif

    switch(state)
    {
    case CONNECTION_IDLE:
        eventId = PtEvent::CONNECTION_CREATED;
        termEventId = PtEvent::TERMINAL_CONNECTION_IDLE;
        break;

    case CONNECTION_INITIATED:
        eventId = PtEvent::CONNECTION_INITIATED;
        termEventId = PtEvent::TERMINAL_CONNECTION_CREATED;
        break;

    case CONNECTION_QUEUED:
        eventId = PtEvent::CONNECTION_QUEUED;
        termEventId = PtEvent::CONNECTION_CREATED;
        break;

    case CONNECTION_OFFERING:
        eventId = PtEvent::CONNECTION_OFFERED;
        break;

    case CONNECTION_DIALING:
        eventId = PtEvent::CONNECTION_DIALING ;
        break;

    case CONNECTION_ALERTING:
        eventId = PtEvent::CONNECTION_ALERTING;
        termEventId = PtEvent::TERMINAL_CONNECTION_RINGING;
        break;

    case CONNECTION_ESTABLISHED:
        eventId = PtEvent::CONNECTION_ESTABLISHED;
        termEventId = PtEvent::TERMINAL_CONNECTION_TALKING;
        break;

    case CONNECTION_FAILED:
        eventId = PtEvent::CONNECTION_FAILED;
        termEventId = PtEvent::TERMINAL_CONNECTION_DROPPED;
        break;

    case CONNECTION_DISCONNECTED:
        eventId = PtEvent::CONNECTION_DISCONNECTED;
        termEventId = PtEvent::TERMINAL_CONNECTION_DROPPED;
        break;

    case PtEvent::TERMINAL_CONNECTION_HELD:
        termEventId = PtEvent::TERMINAL_CONNECTION_HELD;
        break;

    default:
        eventId = PtEvent::CONNECTION_UNKNOWN;
        termEventId = PtEvent::TERMINAL_CONNECTION_UNKNOWN;
        break;

    }

    int cause;
    switch(newCause)
    {
     case CONNECTION_CAUSE_UNKNOWN:
        cause = PtEvent::CAUSE_UNKNOWN;
        causeStr.append("CAUSE_UNKNOWN");
        break;
    case CONNECTION_CAUSE_REDIRECTED:
        cause = PtEvent::CAUSE_REDIRECTED;
        causeStr.append("CAUSE_REDIRECTED");
        break ;

     case CONNECTION_CAUSE_NETWORK_CONGESTION:
        cause = PtEvent::CAUSE_NETWORK_CONGESTION;
        causeStr.append("CAUSE_NETWORK_CONGESTION");
        break;

     case CONNECTION_CAUSE_NETWORK_NOT_OBTAINABLE:
        cause = PtEvent::CAUSE_NETWORK_NOT_OBTAINABLE;
        causeStr.append("CAUSE_NETWORK_NOT_OBTAINABLE");
        break;

     case CONNECTION_CAUSE_DEST_NOT_OBTAINABLE:
        cause = PtEvent::CAUSE_DESTINATION_NOT_OBTAINABLE;
        causeStr.append("CAUSE_DESTINATION_NOT_OBTAINABLE");
        break;

     case CONNECTION_CAUSE_INCOMPATIBLE_DESTINATION:
        cause = PtEvent::CAUSE_INCOMPATIBLE_DESTINATION;
        causeStr.append("CAUSE_INCOMPATIBLE_DESTINATION");
        break;

     case CONNECTION_CAUSE_NOT_ALLOWED:
        cause = PtEvent::CAUSE_NOT_ALLOWED;
        causeStr.append("CAUSE_NOT_ALLOWED");
        break;

     case CONNECTION_CAUSE_NETWORK_NOT_ALLOWED:
        cause = PtEvent::CAUSE_NETWORK_NOT_ALLOWED;
        causeStr.append("CAUSE_NETWORK_NOT_ALLOWED");
        break;

    case CONNECTION_CAUSE_BUSY:
    case CONNECTION_CAUSE_SERVICE_UNAVAILABLE:
        cause = PtEvent::CAUSE_BUSY;
        causeStr.append("CAUSE_BUSY");
        break ;

    case CONNECTION_CAUSE_CANCELLED:
        cause = PtEvent::CAUSE_CALL_CANCELLED;
        causeStr.append("CAUSE_CALL_CANCELLED");
        break ;

    case CONNECTION_CAUSE_TRANSFER:
        cause = PtEvent::CAUSE_TRANSFER;
        causeStr.append("CAUSE_TRANSFER");
        break;

    default:
    case CONNECTION_CAUSE_NORMAL:
        cause = PtEvent::CAUSE_NORMAL;
        causeStr.append("CAUSE_NORMAL");
        break;
    }

    int cnt = 0;
    if (mpListenerCnt)
        cnt = mpListenerCnt->getRef();

    if (cnt > 0)
    {
        TaoObjHandle* pListeners;
        pListeners = new TaoObjHandle[cnt];
        mpListeners->getActiveObjects(pListeners, cnt);

        UtlString callId;

        // Use the connection call id first -- followed by call if
        // unavailable
        getCallId(&callId);                          // arg[0], callId
        if (callId.isNull())
        {
            mpCall->getCallId(callId);
#ifdef TEST_PRINT
            Os::Logger::instance().log(FAC_CP, PRI_DEBUG, "Connection::postTaoListenerMessage: "
                          "Connection call id not found, "
                          "Using CpCall Id = %s ",
                          callId.data());
#endif
        }

        callId += TAOMESSAGE_DELIMITER + mLocalAddress;        // arg[1], localAddress

        UtlString remoteAddress;
        getRemoteAddress(&remoteAddress, TRUE);

        if (remoteAddress.isNull())                            // arg[2], remote address
        {
            callId += TAOMESSAGE_DELIMITER + (UtlString)"UNKNOWN";    // not available yet
        }
        else
        {
            callId += TAOMESSAGE_DELIMITER + remoteAddress;
        }

        char buff[128];
        sprintf(buff, "%d", (int)mRemoteIsCallee);
        callId += TAOMESSAGE_DELIMITER + UtlString(buff);    // arg[3], remoteIsCallee

        sprintf(buff, "%d", cause);
        callId += TAOMESSAGE_DELIMITER + UtlString(buff);    // arg[4], cause

        if (mRemoteIsCallee)
        {
            remoteAddress.insert(0, "foreign-terminal-");
            callId += TAOMESSAGE_DELIMITER + remoteAddress;    // arg[5], remote terminal name
        }
        else
        {
            mpCall->getLocalTerminalId(buff, 127);
            callId += TAOMESSAGE_DELIMITER + UtlString(buff);    // arg[5], local terminal name
        }

        if (isLocal)                                        // TAO_OFFER_PARAM_LOCAL_CONNECTION
        {
            callId += TAOMESSAGE_DELIMITER + "1";            // arg[6], isLocal
        }
        else
        {
            callId += TAOMESSAGE_DELIMITER + "0";            // isLocal
        }

        sprintf(buff, "%d", mResponseCode);
        callId += TAOMESSAGE_DELIMITER + UtlString(buff);    // arg[7], SIP response code

        callId += TAOMESSAGE_DELIMITER + mResponseText;        // arg[8], SIP response text

        int argCnt = 9;
        if(mpCall)
        {
            int metaEventId = 0;
            int metaEventType = PtEvent::META_EVENT_NONE;
            int numCalls = 0;
            const UtlString* metaEventCallIds = NULL;
            mpCall->getMetaEvent(metaEventId, metaEventType, numCalls,
                &metaEventCallIds);
            if (metaEventId != PtEvent::META_EVENT_NONE)
            {
                sprintf(buff, "%d", metaEventId);
                callId += TAOMESSAGE_DELIMITER + UtlString(buff);    // arg[9], meta event id
                sprintf(buff, "%d", metaEventType);
                callId += TAOMESSAGE_DELIMITER + UtlString(buff);    // arg[10], meta code
                argCnt += 2;
                for (int i = 0; i < numCalls; i++)
                {
                    if (metaEventCallIds && metaEventCallIds[i])
                    {
                        callId += TAOMESSAGE_DELIMITER + metaEventCallIds[i];    // meta call ids
                        argCnt++;
                    }
                }
            }
        }

        TaoMessage msg(TaoMessage::EVENT,
                       0,
                       0,
                       eventId,
                       0,
                       argCnt,
                       callId);

        UtlString eventIdStr;
        if (eventId != PtEvent::EVENT_INVALID)
        {
            for (int i = 0; i < cnt; i++) // post connection events
            {
                ((OsServerTask*) pListeners[i])->postMessage((OsMsg&)msg);
            }
            mpCall->getStateString(eventId, &eventIdStr);
            mpCallManager->logCallState(callId.data(), eventIdStr.data(), causeStr);
        }

        if (termEventId != PtEvent::EVENT_INVALID)    // post terminal connection events
        {
            msg.setObjHandle(termEventId);
            for (int i = 0; i < cnt; i++)
            {
                ((OsServerTask*) pListeners[i])->postMessage((OsMsg&)msg);
            }

            mpCall->getStateString(termEventId, &eventIdStr);
            mpCallManager->logCallState(callId.data(), eventIdStr.data(), causeStr);

        }

        delete[] pListeners;
        callId.remove(0);
        eventIdStr.remove(0);
        remoteAddress.remove(0);
    }
#ifdef TEST_PRINT
    Os::Logger::instance().log(FAC_CP, PRI_DEBUG, "Connection::postTaoListenerMessage: "
                  "Leave- %s state %d cause %d "
                  "eventid-  %d termeventid %d",
                  (isLocal?"LOCAL":"REMOTE"),
                  state, newCause,
                  eventId, termEventId);
#endif

    causeStr.remove(0);
}
Пример #7
0
AuthPlugin::AuthResult
CallerAlias::authorizeAndModify(const UtlString& id,    /**< The authenticated identity of the
                                                         *   request originator, if any (the null
                                                         *   string if not).
                                                         *   This is in the form of a SIP uri
                                                         *   identity value as used in the
                                                         *   credentials database (user@domain)
                                                         *   without the scheme or any parameters.
                                                         */
                                const Url&  requestUri, ///< parsed target Uri
                                RouteState& routeState, ///< the state for this request.  
                                const UtlString& method,///< the request method
                                AuthResult  priorResult,///< results from earlier plugins.
                                SipMessage& request,    ///< see AuthPlugin regarding modifying
                                bool bSpiralingRequest, ///< spiraling indication 
                                UtlString&  reason      ///< rejection reason
                                )
{
   // get the call-id to use in logging
   UtlString callId;
   request.getCallIdField(&callId);

   if (   (priorResult != DENY) // no point in modifying a request that won't be sent
       )   
   {
      UtlString callerFrom;
      UtlString callerFromTagOffsetStr;
      UtlString aliasFrom;
      UtlString aliasFromTagOffsetStr;
      UtlString originalFromTag;

      if (   !routeState.getParameter(mInstanceName.data(), CALLER_FROM_PARAM, callerFrom)
          || !routeState.getParameter(mInstanceName.data(), CALLER_TAG_OFFSET_PARAM, callerFromTagOffsetStr)
          || !routeState.getParameter(mInstanceName.data(), ALIAS_FROM_PARAM, aliasFrom)
          || !routeState.getParameter(mInstanceName.data(), ALIAS_TAG_OFFSET_PARAM, aliasFromTagOffsetStr)
          || !routeState.originalCallerFromTagValue(mInstanceName.data(), originalFromTag)
          )
      {
         if (   routeState.isMutable()
             && routeState.directionIsCallerToCalled(mInstanceName.data())
             ) // a new dialog?
         {
            /*
             * Get the callers identity by getting the caller URI and:
             *    remove all parameters
             *    remove the scheme name
             */
            UtlString callerIdentity;

            UtlString originalFromField;
            request.getFromField(&originalFromField);
            Url originalFromUrl(originalFromField);
            
            /*
             * Extract the from identity as a key for the caller alias table
             * Start with the From header field (someday we should use the Identity if present)
             */
            Url fromUrl(originalFromUrl);
            fromUrl.removeParameters(); // parameters are not relevant for this 
         
            Url::Scheme fromUrlScheme = fromUrl.getScheme();
            switch (fromUrlScheme)
            {
            case Url::SipsUrlScheme:
               // sips and sip are equivalent for identity purposes,
               //   so just set to sip 
               fromUrl.setScheme(Url::SipUrlScheme);
               //   and fall through to extract the identity...

            case Url::SipUrlScheme:
               // case Url::TelUrlScheme: will go here, since 'tel' and 'sip' are the same length
               fromUrl.getUri(callerIdentity);
               callerIdentity.remove(0,4 /* strlen("sip:") */); // strip off the scheme name
               break;

            default:
               // for all other schemes, treat identity as null
               Os::Logger::instance().log(FAC_SIP, PRI_WARNING,
                             "CallerAlias[%s]::check4andApplyAlias From uses unsupported scheme '%s'"
                             " - using null identity",
                             mInstanceName.data(),
                             Url::schemeName(fromUrlScheme)
                             );
               break;
            }

            /*
             * Determine whether the identity is one for which this proxy
             * is authoritative; if not, we will not use wildcard matches.
             */
            bool identityIsLocal = mpSipRouter->isLocalDomain(fromUrl);
            
            // now we have callerIdentity set; use for looking up each contact.
            Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                          "CallerAlias[%s]::check4andApplyAlias "
                          "\n  caller '%s' %s",
                          mInstanceName.data(),
                          callerIdentity.data(),
                          identityIsLocal ? "is local" : "is not local"
                          );

            /*
             * Examine the request URI,
             * checking for a caller alias set for its domain(including asssociated gateway sipxecsLineid)  with callerIdentity
             */

            UtlString sipxecsLineIdField;
            requestUri.getUrlParameter(SIPX_SIPXECS_LINEID_URI_PARAM, sipxecsLineIdField);

            Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                             "getUrlParameter: sipxecsLineid[%s]"
                             " in CallerAlias",
                             sipxecsLineIdField.data()
                             );

            UtlString targetDomain;
            requestUri.getHostWithPort(targetDomain);

            if (!(sipxecsLineIdField.isNull()))
            {
                targetDomain.append(";").append(SIPX_SIPXECS_LINEID_URI_PARAM).append("=").append(sipxecsLineIdField.data());
            }

            Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                          "CallerAlias::targetDomain [%s]",
                          targetDomain.data()
                          );

            // look up any caller alias for this identity and contact domain
            UtlString callerAlias;
            if (identityIsLocal && getCallerAlias(callerIdentity, targetDomain, callerAlias) )
            {
               // found a caller alias, so rewrite the From information
               /*
                * The From header requires special handling
                * - we need to preserve the tag, if any, from the original header
                */
               originalFromUrl.getFieldParameter("tag", originalFromTag);

               Url newFromUrl(callerAlias.data());
               newFromUrl.removeFieldParameter("tag"); // specifying a tag is a no-no
               if ( !originalFromTag.isNull() )
               {
                  newFromUrl.setFieldParameter("tag", originalFromTag.data());
               }
               UtlString newFromFieldValue;
               newFromUrl.toString(newFromFieldValue);
                   
               // log the change we are making before stripping the tag from the field values
               Os::Logger::instance().log( FAC_SIP, PRI_INFO,
                             "CallerAlias[%s]::check4andApplyAlias call %s set caller alias\n"
                             "  Original-From: %s\n"
                             "  Aliased-From:  %s",
                             mInstanceName.data(), callId.data(),
                             originalFromField.data(),
                             newFromFieldValue.data()
                             );

               // rewrite the caller identity with the aliased value
               request.setRawFromField(newFromFieldValue.data());

               // Factor the tag values out of the field values stored in the RouteState
               //  We do this because otherwise we'll end up encoding and sending two copies
               //  of the tag; since some phones send really long tag values (no one knows why),
               //  this can cause such large Record-Route headers that they cause interop problems.
               if ( ! originalFromTag.isNull() )
               {
                  // find the offset of the tag value in the callers from field
                  ssize_t callerFromTagOffset;
                  callerFromTagOffset = originalFromField.index(originalFromTag);
                  callerFromTagOffsetStr.appendNumber(callerFromTagOffset);
                  // strip the tag value from the original From value to be stored in the RouteState
                  originalFromField.replace(callerFromTagOffset, originalFromTag.length(), "");
                  
                  // find the offset of the tag value in the aliased from field
                  ssize_t aliasFromTagOffset;
                  aliasFromTagOffset = newFromFieldValue.index(originalFromTag);
                  aliasFromTagOffsetStr.appendNumber(aliasFromTagOffset);
                  // strip the tag value from the aliased From value to be stored in the RouteState
                  newFromFieldValue.replace(aliasFromTagOffset, originalFromTag.length(), "");
               }

               // save the original and new values so that we can fix them later
               routeState.setParameter(mInstanceName.data(),
                                       CALLER_FROM_PARAM,originalFromField);
               routeState.setParameter(mInstanceName.data(),
                                       CALLER_TAG_OFFSET_PARAM,callerFromTagOffsetStr);
               routeState.setParameter(mInstanceName.data(),
                                       ALIAS_FROM_PARAM,newFromFieldValue);
               routeState.setParameter(mInstanceName.data(),
                                       ALIAS_TAG_OFFSET_PARAM,aliasFromTagOffsetStr);
            }
            else
            {
               Os::Logger::instance().log( FAC_SIP, PRI_DEBUG,
                             "CallerAlias[%s]::check4andApplyAlias call %s found no alias",
                             mInstanceName.data(), callId.data()
                             );
            }
         }
         else
         {
            Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                          "CallerAlias[%s]::authorizeAndModify "
                          "not mutable - no rewrite",
                          mInstanceName.data()                          
                          );
         }
      }
      else // the callerFrom and aliasFrom parameters were found
      {
         /*
          * This request has had its From rewritten, so fix either the From
          * or the To depending on which direction this request is going.
          */
         if (!request.isResponse()) // can't modify responses, so don't bother
         {
            size_t tagOffset;
            
            if (routeState.directionIsCallerToCalled(mInstanceName.data()))
            {
               // replace the from tag value in the stored aliased header
               tagOffset = strtol(aliasFromTagOffsetStr.data(), NULL, 10);
               aliasFrom.insert(tagOffset, originalFromTag);

               // put the aliased header into the message
               request.setRawFromField(aliasFrom);
               Os::Logger::instance().log(FAC_AUTH, PRI_DEBUG, "CallerAlias[%s]::authorizeAndModify "
                             "call %s reset From",
                             mInstanceName.data(), callId.data()
                             );
            }
            else // direction is Called to Caller
            {
               // replace the from tag value in the stored original header
               tagOffset = strtol(callerFromTagOffsetStr.data(), NULL, 10);
               callerFrom.insert(tagOffset, originalFromTag);

               request.setRawToField(callerFrom.data());
               Os::Logger::instance().log(FAC_AUTH, PRI_DEBUG, "CallerAlias[%s]::authorizeAndModify "
                             "call %s reset To",
                             mInstanceName.data(), callId.data()
                             );
            }
         }
      }
   }
   return AuthPlugin::CONTINUE;
}