MpResourceTopology* CpTopologyGraphFactoryImpl::buildUnicastConnectionResourceTopology()
{
    MpResourceTopology* resourceTopology = new MpResourceTopology();

    OsStatus result;
    result = resourceTopology->addResource(DEFAULT_RTP_INPUT_RESOURCE_TYPE,
                                           DEFAULT_RTP_INPUT_RESOURCE_NAME);
    assert(result == OS_SUCCESS);

    // Add decoder resource
    UtlString decodeName = DEFAULT_DECODE_RESOURCE_NAME;
    decodeName.append("-0");
    result = resourceTopology->addResource(DEFAULT_DECODE_RESOURCE_TYPE,
                                           decodeName,
                                           MP_INVALID_CONNECTION_ID,
                                           0);
    assert(result == OS_SUCCESS);

#ifdef INSERT_DELAY_RESOURCE // [
    // Add delay resource
    UtlString delayName = DEFAULT_DELAY_RESOURCE_NAME CONNECTION_NAME_SUFFIX "-0";
    result = resourceTopology->addResource(DEFAULT_DELAY_RESOURCE_TYPE,
                                           delayName,
                                           MP_INVALID_CONNECTION_ID,
                                           0);
    assert(result == OS_SUCCESS);
#endif // INSERT_DELAY_RESOURCE ]

    // Add Voice Activity Notifier resource
    UtlString activityNotifName = DEFAULT_VOICE_ACTIVITY_NOTIFIER_RESOURCE_NAME
                                  CONNECTION_NAME_SUFFIX "-0";
    result = resourceTopology->addResource(DEFAULT_VOICE_ACTIVITY_NOTIFIER_RESOURCE_TYPE,
                                           activityNotifName,
                                           MP_INVALID_CONNECTION_ID,
                                           0);
    assert(result == OS_SUCCESS);

    // Abstract port number to be used when connecting to bridge.
#ifdef INSERT_SPEAKER_SELECTOR // [
    int logicalPortNum = -1;
#else // INSERT_SPEAKER_SELECTOR ][
    int logicalPortNum = resourceTopology->getNextLogicalPortNumber();
#endif // !INSERT_SPEAKER_SELECTOR ]

    // Link RTP input -> decoder
    result = resourceTopology->addConnection(DEFAULT_RTP_INPUT_RESOURCE_NAME, 0, 
                                             decodeName, 0);
    assert(result == OS_SUCCESS);
    UtlString &prevResourceName = decodeName;

    // -> Input connection Voice Activity Notifier
    result = resourceTopology->addConnection(prevResourceName, 0, 
                                             activityNotifName, 0);
    assert(result == OS_SUCCESS);
    prevResourceName = activityNotifName;

#ifdef INSERT_DELAY_RESOURCE // [
    // -> Delay
    result = resourceTopology->addConnection(prevResourceName, 0, 
                                             delayName, 0);
    assert(result == OS_SUCCESS);
    prevResourceName = delayName;
#endif // INSERT_DELAY_RESOURCE ]

    // Mark last resource as RTP Stream Output
    UtlString streamOutputName(VIRTUAL_NAME_RTP_STREAM_OUTPUT "-0");
    result = resourceTopology->addVirtualOutput(prevResourceName, 0,
                                                streamOutputName, 0);
    assert(result == OS_SUCCESS);

    // -> bridge
    result = resourceTopology->addConnection(prevResourceName, 0, 
                                             VIRTUAL_NAME_CONNECTION_PORTS, logicalPortNum);
    assert(result == OS_SUCCESS);

    addOutputConnectionTopology(resourceTopology, logicalPortNum);

    return(resourceTopology);
}
// Constructor
SipPersistentSubscriptionMgr::SipPersistentSubscriptionMgr(
   const UtlString& component,
   const UtlString& domain,
   const UtlString& fileName) :
   mComponent(component),
   mDomain(domain),
   mSubscriptionDBInstance(SubscriptionDB::getInstance(fileName)),
   mPersistenceTimer(mPersistTask.getMessageQueue(), 0),
   mPersistTask(mSubscriptionDBInstance)
{
   OsSysLog::add(FAC_SIP, PRI_DEBUG,
                 "SipPersistentSubscriptionMgr:: "
                 "mComponent = '%s', mDomain = '%s', fileName = '%s'",
                 mComponent.data(), mDomain.data(), fileName.data());

   // Start the persist task.
   mPersistTask.start();

   // Read the subscription table and initialize the SipSubscriptionMgr.

   unsigned long now = OsDateTime::getSecsSinceEpoch();
   ResultSet rs;
   mSubscriptionDBInstance->getAllRows(rs);
   UtlSListIterator itor(rs);
   UtlHashMap* rowp;
   while ((rowp = dynamic_cast <UtlHashMap*> (itor())))
   {
      if (OsSysLog::willLog(FAC_SIP, PRI_DEBUG))
      {
         UtlString out;
         UtlHashMapIterator itor(*rowp);
         UtlString* key;
         UtlContainable* value;
         while ((key = dynamic_cast <UtlString*> (itor())))
         {
            value = itor.value();
            if (!out.isNull())
            {
               out.append(", ");
            }
            out.append(*key);
            out.append(" = ");
            if (value->getContainableType() == UtlString::TYPE)
            {
               out.append("'");
               out.append(*(dynamic_cast <UtlString*> (value)));
               out.append("'");
            }
            else if (value->getContainableType() == UtlInt::TYPE)
            {
               out.appendNumber((int) (*(dynamic_cast <UtlInt*> (value))));
            }
            else
            {
               out.append(value->getContainableType());
            }
         }
         OsSysLog::add(FAC_SIP, PRI_DEBUG,
                       "SipPersistentSubscriptionMgr:: "
                       "table row: %s",
                       out.data());
      }

      // First, filter for rows that have the right component and have
      // not yet expired.
      UtlString* componentp =
         dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gComponentKey));
      assert(componentp);
      int expires =
         *(dynamic_cast <UtlInt*> (rowp->findValue(&SubscriptionDB::gExpiresKey)));
      if (componentp->compareTo(mComponent) == 0 &&
          expires - now >= 0)
      {
         OsSysLog::add(FAC_SIP, PRI_DEBUG,
                       "SipPersistentSubscriptionMgr:: "
                       "loading row");

         // Extract the values from the row.
         const UtlString* top =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gToKey));
         const UtlString* fromp =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gFromKey));
         const UtlString* callidp =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gCallidKey));
         const UtlString* eventtypep =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gEventtypeKey));
         const UtlString* eventidp =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gIdKey));
         // Correct the null string if it is returned as
         // SPECIAL_IMDB_NULL_VALUE.
         if (eventidp->compareTo(special_imdb_null_value) == 0)
         {
            eventidp = &null_string;
         }
         int subcseq =
            *(dynamic_cast <UtlInt*> (rowp->findValue(&SubscriptionDB::gSubscribecseqKey)));
         const UtlString* urip =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gUriKey));
         const UtlString* contactp =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gContactKey));
         const UtlString* routep =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gRecordrouteKey));
         // Correct the null string if it is returned as
         // SPECIAL_IMDB_NULL_VALUE.
         if (routep->compareTo(special_imdb_null_value) == 0)
         {
            routep = &null_string;
         }
         int notifycseq =
            *(dynamic_cast <UtlInt*> (rowp->findValue(&SubscriptionDB::gNotifycseqKey)));
         const UtlString* acceptp =
            dynamic_cast <UtlString*> (rowp->findValue(&SubscriptionDB::gAcceptKey));
         int version =
            *(dynamic_cast <UtlInt*> (rowp->findValue(&SubscriptionDB::gVersionKey)));

         // Use SipSubscriptionMgr to update the in-memory data.

         // Construct a fake SUBSCRIBE request to carry most of the data
         // that updateDialogInfo needs.
         SipMessage subscribeRequest;
         subscribeRequest.setSubscribeData(urip->data(),
                                           fromp->data(),
                                           top->data(),
                                           callidp->data(),
                                           subcseq,
                                           eventtypep->data(),
                                           acceptp->data(),
                                           eventidp->data(),
                                           contactp->data(),
                                           routep->data(),
                                           expires - now);

         // Variables to hold the output of insertDialogInfo.
         UtlString subscribeDialogHandle;
         UtlBoolean isNew, isSubscriptionExpired;
         SipMessage subscribeResponse;
         UtlBoolean ret =
            SipSubscriptionMgr::insertDialogInfo(subscribeRequest,
                                                 // *urip is the request-URI of
                                                 // of the SUBSCRIBE.
                                                 *urip,
                                                 *eventtypep,
                                                 subscribeDialogHandle,
                                                 isNew,
                                                 isSubscriptionExpired,
                                                 subscribeResponse);
         if (!ret)
         {
            OsSysLog::add(FAC_SIP, PRI_ERR,
                          "SipPersistentSubscriptionMgr:: "
                          "insertDialogInfo failed urip = '%s', subscribeDialogHandle = '%s'",
                          urip->data(), subscribeDialogHandle.data());
         }
         else
         {
            // Set the next NOTIFY CSeq value.
            // (The data in IMDB has already been set.)
            SipSubscriptionMgr::setNextNotifyCSeq(subscribeDialogHandle,
                                                  notifycseq,
                                                  version);
         }
      }
   }
}
예제 #3
0
bool FileRpcReplaceFile::execute(const HttpRequestContext& requestContext,
                                 UtlSList&                 params,
                                 void*                     userData,
                                 XmlRpcResponse&           response,
                                 ExecutionStatus&          status)
{

   const int  minPermissions = 0100;
   const int  maxPermissions = 0777;

   bool result = false;
   status = XmlRpcMethod::FAILED;

   if (4 != params.entries())
   {
      handleExtraExecuteParam(name(), response, status);
   }
   else
   {
      if (!params.at(0) || !params.at(0)->isInstanceOf(UtlString::TYPE))
      {
         handleMissingExecuteParam(name(), PARAM_NAME_CALLING_HOST, response, status);
      }
      else
      {
         UtlString* pCallingHostname = dynamic_cast<UtlString*>(params.at(0));

         if (!params.at(1) || !params.at(1)->isInstanceOf(UtlString::TYPE))
         {
            handleMissingExecuteParam(name(), PARAM_NAME_FILE_NAME, response, status);
         }
         else
         {
            UtlString* pfileName = dynamic_cast<UtlString*>(params.at(1));

            if (!params.at(2) || !params.at(2)->isInstanceOf(UtlInt::TYPE))
            {
               handleMissingExecuteParam(name(), PARAM_NAME_FILE_PERMISSIONS, response, status);
            }
            else
            {
               UtlInt* pfilePermissions = dynamic_cast<UtlInt*>(params.at(2));
           
               if (!params.at(3) || !params.at(3)->isInstanceOf(UtlString::TYPE))
               {
                  handleMissingExecuteParam(name(), PARAM_NAME_FILE_DATA, response, status);
               }
               else
               {
                  UtlBool method_result(true);
                  SipxRpc* pSipxRpcImpl = ((SipxRpc *)userData);

                  if(validCaller(requestContext, *pCallingHostname, response, *pSipxRpcImpl, name()))
                  {
                     // Check the resource permissions.  To be added when available.
                     FileResource* fileResource =
                        FileResourceManager::getInstance()->find(pfileName->data());
                     if (!fileResource)
                     {
                        UtlString faultMsg;
                        faultMsg.append("File '");
                        faultMsg.append(*pfileName);
                        faultMsg.append("' not declared as a resource by any sipXecs process");
                        OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "FileRpc::replaceFile %s",
                                      faultMsg.data());
                        result=false;
                        response.setFault(FileRpcMethod::InvalidParameter, faultMsg);
                     }
                     else if (!fileResource->isWriteable())
                     {
                        UtlString faultMsg;
                        faultMsg.append("File '");
                        faultMsg.append(*pfileName);
                        faultMsg.append("' is not writeable (configAccess='read-only')");
                        OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "FileRpc::replaceFile %s",
                                      faultMsg.data());
                        result=false;
                        response.setFault(FileRpcMethod::InvalidParameter, faultMsg);
                     }
                     else if (   ( pfilePermissions->getValue() <= minPermissions )
                              || ( pfilePermissions->getValue() > maxPermissions ))
                     {
                        UtlString faultMsg;
                        faultMsg.appendNumber(pfilePermissions->getValue(),"File permissions %04o");
                        faultMsg.appendNumber(minPermissions,"not within valid range (%04o - ");
                        faultMsg.appendNumber(maxPermissions,"%04o)");
                        OsSysLog::add(FAC_SUPERVISOR, PRI_ERR, "FileRpc::replaceFile %s",
                                      faultMsg.data());
                        result = false;
                        response.setFault(FileRpcMethod::InvalidParameter, faultMsg);
                     }
                     else
                     {
                        // Write out the file.
                        UtlString* pfileData = dynamic_cast<UtlString*>(params.at(3));
                        UtlString faultMsg;
                        if((result=replicateFile(*pfileName,*pfilePermissions,*pfileData,faultMsg )))
                        {
                           // Construct and set the response.
                           response.setResponse(&method_result);
                           status = XmlRpcMethod::OK;

                           // Tell anyone who cares that this changed
                           fileResource->modified();
                        }
                        else
                        {
                           // Replication failed.
                           response.setFault(FileRpcMethod::InvalidParameter, faultMsg);
                        }
                     }
                  }
               }
            }
         }
      }
   }

   return result;
}
예제 #4
0
// Do preliminary processing of message to log it,
// clean up its data, and extract any needed source address.
void SipClient::preprocessMessage(SipMessage& msg,
                                  const UtlString& msgText,
                                  int msgLength)
{
   // Canonicalize short field names.
   msg.replaceShortFieldNames();

   // Get the send address.
   UtlString fromIpAddress;
   int fromPort;
   msg.getSendAddress(&fromIpAddress, &fromPort);

   // Log the message.
   // Only bother processing if the logs are enabled
   if (   mpSipUserAgent->isMessageLoggingEnabled()
          || Os::Logger::instance().willLog(FAC_SIP_INCOMING, PRI_INFO)
      )
   {
      UtlString logMessage;
      logMessage.append("Read SIP message:\n");
      logMessage.append("----Local Host:");
      logMessage.append(mLocalHostAddress);
      logMessage.append("---- Port: ");
      logMessage.appendNumber(
                 portIsValid(mLocalHostPort) ? mLocalHostPort : defaultPort());
      logMessage.append("----\n");
      logMessage.append("----Remote Host:");
      logMessage.append(fromIpAddress);
      logMessage.append("---- Port: ");
      logMessage.appendNumber(
                 portIsValid(fromPort) ? fromPort : defaultPort());
      logMessage.append("----\n");

      logMessage.append(msgText.data(), msgLength);
      UtlString messageString;
      logMessage.append(messageString);
      logMessage.append("====================END====================\n");

      // Send the message to the SipUserAgent for its internal log.
      mpSipUserAgent->logMessage(logMessage.data(), logMessage.length());
      // Write the message to the syslog.
      Os::Logger::instance().log(FAC_SIP_INCOMING, PRI_INFO, "%s", logMessage.data());
   }

   // Set the date field if not present
   long epochDate;
   if (!msg.getDateField(&epochDate))
   {
      msg.setDateField();
   }

   // Set the protocol and time.
   msg.setSendProtocol(mSocketType);
   msg.setTransportTime(touchedTime);

   // Keep track of where this message came from
   msg.setSendAddress(fromIpAddress.data(), fromPort);

   // Keep track of the interface on which this message was
   // received.
   msg.setInterfaceIpPort(mClientSocket->getLocalIp(), mClientSocket->getLocalHostPort());

   if (mReceivedAddress.isNull())
   {
      mReceivedAddress = fromIpAddress;
      mRemoteReceivedPort = fromPort;
   }

   // If this is a request...
   if (!msg.isResponse())
   {
      UtlString lastAddress;
      int lastPort;
      UtlString lastProtocol;
      int receivedPort;
      UtlBoolean receivedSet;
      UtlBoolean maddrSet;
      UtlBoolean receivedPortSet;

      // Fill in 'received' and 'rport' in top Via if needed.
      msg.setReceivedViaParams(fromIpAddress, fromPort);

      // Derive information about the other end of the connection
      // from the Via that the other end provided.

      // Get the addresses from the topmost Via.
      msg.getTopVia(&lastAddress, &lastPort, &lastProtocol,
                    &receivedPort, &receivedSet, &maddrSet,
                    &receivedPortSet);

      // :QUERY: Should this test be mClientSocket->isConnected()?
      if (   (   mSocketType == OsSocket::TCP
                 || mSocketType == OsSocket::SSL_SOCKET
                )
             && !receivedPortSet
         )
      {
         // we can use this socket as if it were
         // connected to the port specified in the
         // via field
         mRemoteReceivedPort = lastPort;
      }

      // Keep track of the address the other
      // side said they sent from.  Note, this cannot
      // be trusted unless this transaction is
      // authenticated
      if (mRemoteViaAddress.isNull())
      {
         mRemoteViaAddress = lastAddress;
         mRemoteViaPort =
            portIsValid(lastPort) ? lastPort : defaultPort();
      }
   }

   //
   // Call all sip input processors
   //
   system_tap_sip_rx(fromIpAddress.data(), portIsValid(fromPort) ? fromPort : defaultPort(),
           mLocalHostAddress.data(), portIsValid(mLocalHostPort) ? mLocalHostPort : defaultPort(),
           msgText.data(), msgLength);

   mpSipUserAgent->executeAllSipInputProcessors(msg, fromIpAddress.data(), portIsValid(fromPort) ? fromPort : defaultPort());
}
예제 #5
0
UtlBoolean UtlString::findToken(const char* token,
                                const char* delimiter,
                                const char* suffix,
                                bool regex) const
{
    RegEx*   ptmpRegEx = NULL;
    UtlBoolean  matched = FALSE;

    // build regular expression
    UtlString regExpStr;
    // find beginning of line or delimiter
    regExpStr.append("(^|");
    regExpStr.append(delimiter);
    regExpStr.append(')');

    // allow whitespace around token
    regExpStr.append(SWS);

    // Insert 'token' correctly, based on the value of 'regex'.
    if (regex)
    {
       // 'token' is a regexp.
       // Must parenthesize 'token', as it may contain operations with
       // low precedence.
       regExpStr.append('(');
       regExpStr.append(token);
       regExpStr.append(')');
    }
    else
    {
       // 'token' is a literal string and must be quoted.
       UtlString quoted;
       RegEx::Quotemeta(token, quoted);
       regExpStr.append(quoted);
    }

    // More whitespace.
    regExpStr.append(SWS);

    // find another delimiter, end of line or (optional) suffix
    regExpStr.append('(');
    regExpStr.append(delimiter);
    if (suffix)
    {
       regExpStr.append('|');
       regExpStr.append(suffix);
    }
    regExpStr.append("|$)");
    // "(^|" delimiter ")" SWS "\Q" token "\E" SWS "(" delimiter "|" suffix "|$)");
    // e.g., with delimiter = "," and suffix= ";" 
    //      '( ^|,) SWS \Q token \E SWS (,|;|$)'
    // e.g., with delimiter = "," and without suffix
    //      '( ^|,) SWS \Q token \E SWS (,|$)'

#ifdef TEST_FINDTOKEN
    OsSysLog::add( FAC_LOG, PRI_DEBUG
                  ,"UtlString::findToken: "
                   "built regexp '%s' to find '%s' with delimiter '%s' "
                   "suffix '%s'"
                  ,regExpStr.data(),token, delimiter,
                   suffix);
#endif

    try
    {
       // Compile regExpStr into a RegEx, set the case-insensitive flag.
       ptmpRegEx = new RegEx(regExpStr.data(), PCRE_CASELESS);
    }
    catch(const char* compileError)
    {
        OsSysLog::add( FAC_LOG, PRI_ERR
                      ,"UtlString::findToken: "
                       "Invalid regexp '%s' for '%s': "
                       "compile error '%s'"
                      ,regExpStr.data()
                      ,data()
                      ,compileError
                      );
    }

    if (ptmpRegEx)
    {
        matched = ptmpRegEx->Search(data());
        delete ptmpRegEx;
    }

#ifdef TEST_FINDTOKEN
    OsSysLog::add( FAC_LOG, PRI_DEBUG
                  ,"UtlString::findToken: "
                   "'%s' with delimiter '%s' %sfound in '%s': "
                  ,token
                  ,delimiter
                  ,(matched ? "":"not ")
                  ,data()
                  );
#endif
    return matched;
}
예제 #6
0
파일: Url.cpp 프로젝트: John-Chan/sipXtapi
void Url::toString(UtlString& urlString) const
{
   UtlBoolean isNameAddr = FALSE;

   // This is a replace operation; clear the storage string
   urlString.remove(0);

   if ( !mDisplayName.isNull() )
   {
      urlString.append(mDisplayName);
      isNameAddr = TRUE;
   }

   bool haveUrlParams = (   (   mpUrlParameters
                             || const_cast<Url*>(this)->parseUrlParameters()
                             )
                         && mpUrlParameters->entries()
                         );
   bool haveHdrParams = (   (   mpHeaderOrQueryParameters
                             || const_cast<Url*>(this)->parseHeaderOrQueryParameters()
                             )
                         && mpHeaderOrQueryParameters->entries()
                         );

   bool haveFldParams = (   (   mpFieldParameters
                             || const_cast<Url*>(this)->parseFieldParameters()
                             )
                         && mpFieldParameters->entries()
                         );
   
   // If this should be nameAddr as opposed to addrSpec
   // (i.e. do we need anglebrackets)
   if (   isNameAddr                             // There was a Display name
       || mAngleBracketsIncluded                 // Explicit setting from the caller
       || haveFldParams
       || (   ( SipUrlScheme == mScheme || SipsUrlScheme == mScheme )
           && ( haveUrlParams || haveHdrParams )
           )
       )
   {
       urlString.append("<", 1);
       isNameAddr = TRUE;
   }

   UtlString theAddrSpec;
   const_cast<Url*>(this)->getUri(theAddrSpec);
   urlString.append(theAddrSpec);
   
   // Add the terminating angle bracket
   if(isNameAddr)
   {
      urlString.append(">", 1);
   }

   // Add the field parameters
   if(haveFldParams)
   {
      UtlDListIterator fieldParamIterator(*mpFieldParameters);
      NameValuePair* fieldParam = NULL;
      UtlString fieldParamValue;

      while ((fieldParam = (NameValuePair*) fieldParamIterator()))
      {
         urlString.append(";", 1);
         urlString.append(*fieldParam);
         fieldParamValue = fieldParam->getValue();
         if(!fieldParamValue.isNull())
         {
            urlString.append("=", 1);
            Url::gen_value_escape(fieldParamValue);
            urlString.append(fieldParamValue);
         }
      }
   }
}
예제 #7
0
void SipClient::getClientNames(UtlString& clientNames) const
{
    char portString[40];

    // host DNS name
    sprintf(portString, "%d", mRemoteHostPort);
    clientNames = " remote host: ";
    clientNames.append(mRemoteHostName);
    clientNames.append(":");
    clientNames.append(portString);

    // host IP address
    clientNames.append(" remote IP: ");
    clientNames.append(mRemoteSocketAddress);
    clientNames.append(":");
    clientNames.append(portString);

    // via address
    clientNames.append(" remote Via address: ");
    clientNames.append(mRemoteViaAddress);
    clientNames.append(":");
    clientNames.appendNumber(mRemoteViaPort);

    // received address
    clientNames.append(" received address: ");
    clientNames.append(mReceivedAddress);
    clientNames.append(":");
    clientNames.appendNumber(mRemoteReceivedPort);
}
예제 #8
0
파일: OsSysLog.cpp 프로젝트: xaccc/sipXtapi
// Unescapes previously escaped Quotes and CrLfs 
UtlString OsSysLog::unescape(const UtlString& source)
{
   UtlString    results ;        
   const char* pStart = source.data() ;
   const char* pTraverse = pStart ;
   const char* pLast = pStart ;
   UtlBoolean   bLastWasEscapeChar = false;

   while (*pTraverse)
   {
      if (bLastWasEscapeChar)
      {
         switch (*pTraverse)
         {
            case '\\':
            case '"':
               if (pLast < pTraverse)
               {
                  results.append(pLast, pTraverse-pLast-1);               
               }
               pLast = pTraverse + 1 ;
               results.append(*pTraverse) ;
               break ;
            case 'r':
               if (pLast < pTraverse)
               {
                  results.append(pLast, pTraverse-pLast-1);               
               }
               pLast = pTraverse + 1 ;
               results.append("\r") ;
               break ;
            case 'n':
               if (pLast < pTraverse)
               {
                  results.append(pLast, pTraverse-pLast-1);               
               }
               pLast = pTraverse + 1 ;
               results.append("\n") ;
               break;
            default:
               // Invalid/Illegal Escape Character
               break ;
         }
         bLastWasEscapeChar = false ;
      }
      else
      {
         if (*pTraverse == '\\')
         {
            bLastWasEscapeChar = true ;
         }
      }

      pTraverse++ ;
   }

   // if nothing to escape, short-circuit
   if (pLast == pStart)
   {
      return source ;
   } 
   else if (pLast < pTraverse)
   {
      results.append(pLast, (pTraverse-1)-pLast);
   }  
  
   return results ;
}
예제 #9
0
// ---------------------------------------------------------------------------
//
//   main
//
// ---------------------------------------------------------------------------
int main(int argC, char* argV[])
{

    // Check command line and extract arguments.
    if (argC < 2)
    {
        usage();
        return 1;
    }

    const char*                xmlFile = 0;
    AbstractDOMParser::ValSchemes valScheme = AbstractDOMParser::Val_Always;

    bool                       doNamespaces       = true;
    bool                       doSchema           = true;
    bool                       schemaFullChecking = true;
    bool                       doList = false;
    bool                       errorOccurred = false;
    char                       localeStr[64];

    UtlString schemaLocationPairs;

    memset(localeStr, 0, sizeof localeStr);

    int argInd;
    for (argInd = 1; argInd < argC; argInd++)
    {
        // Break out on first parm not starting with a dash
        if (argV[argInd][0] != '-')
            break;

        // Watch for special case help request
        if (!strcmp(argV[argInd], "-?"))
        {
           usage();
           return 2;
        }
        if (!strcmp(argV[argInd], "--version"))
        {
           XERCES_STD_QUALIFIER cerr
              << "xsdvalid version " << SipXcommserverlibVersion
              << " build " << SipXcommserverlibBuildStamp
              << "\n  xerces-c library version " << gXercesVersionStr
              << "\n" << XERCES_STD_QUALIFIER endl;

           return 0;
        }
        else if (!strcmp(argV[argInd], "-l")
                 ||  !strcmp(argV[argInd], "-L"))
        {
           doList = true;
        }
        else if (   !strncmp(argV[argInd], "-s", 2)
                 || !strncmp(argV[argInd], "--schema", 9)
                 )
        {
           if (argInd+2 < argC)
           {
              if (!schemaLocationPairs.isNull())
              {
                 schemaLocationPairs.append(" ");
              }
              schemaLocationPairs.append(argV[++argInd]);
              schemaLocationPairs.append(" ");
              schemaLocationPairs.append(argV[++argInd]);
           }
           else
           {
              XERCES_STD_QUALIFIER cerr
                 << "Option '" << argV[argInd]
                 << "' must be followed by <schema-namespace> <schema-location>\n"
                 << XERCES_STD_QUALIFIER endl;
              return 2;
           }
        }
        else if (   !strncmp(argV[argInd], "-S", 2)
                 || !strncmp(argV[argInd], "--schema-list", 14)
                 )
        {
           if (argInd+1 < argC)
           {
              // the input is a list file
              XERCES_STD_QUALIFIER ifstream fin;
              fin.open(argV[++argInd]);

              if (fin.fail()) {
                 XERCES_STD_QUALIFIER cerr
                    <<"Cannot open schema location file '"
                    << argV[argInd] << "'"
                    << XERCES_STD_QUALIFIER endl;
                 return 2;
              }

              int lineNo = 0;
              while (1)
              {
                 char line[1000];
                 //initialize the array to zeros
                 memset(line, 0, sizeof (line));
                 #define WHITESPACE " \t\n\v\f\r"

                 if (! fin.eof() ) {
                    fin.getline (line, sizeof(line));
                    lineNo++;

                    char* first = strtok(line, WHITESPACE);
                    // Ignore empty lines and comment lines.
                    if (first == NULL || *first == '#')
                       continue;

                    char* second = strtok(NULL, WHITESPACE);

                    char* third = strtok(NULL, WHITESPACE);

                    if (!(second != NULL && third == NULL)) {
                       XERCES_STD_QUALIFIER cerr
                          << "Line " << lineNo
                          << " of schema location file '" << argV[argInd]
                          << "' does not contain two fields.\n"
                          << XERCES_STD_QUALIFIER endl;
                       return 2;
                    }

                    if (!schemaLocationPairs.isNull())
                    {
                       schemaLocationPairs.append(" ");
                    }
                    schemaLocationPairs.append(first);
                    schemaLocationPairs.append(" ");
                    schemaLocationPairs.append(second);
                 }
                 else
                    break;
              }

              fin.close();
           }
           else
           {
              XERCES_STD_QUALIFIER cerr
                 << "Option '" << argV[argInd]
                 << "' must be followed by <file-name>\n"
                 << XERCES_STD_QUALIFIER endl;
              return 2;
           }
        }
        else
        {
           XERCES_STD_QUALIFIER cerr << "Unknown option '" << argV[argInd]
                                     << "', ignoring it\n" << XERCES_STD_QUALIFIER endl;
        }
    }

    //
    //  There should be only one and only one parameter left, and that
    //  should be the file name.
    //
    if (argInd != argC - 1)
    {
        usage();
        return 1;
    }

    // Initialize the XML4C system
    try
    {
        if (strlen(localeStr))
        {
            XMLPlatformUtils::Initialize(localeStr);
        }
        else
        {
            XMLPlatformUtils::Initialize();
        }
    }
    catch (const XMLException& toCatch)
    {
       XERCES_STD_QUALIFIER cerr << "Error during initialization! :\n"
                                 << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
       return 1;
    }
    catch (...)
    {
       XERCES_STD_QUALIFIER cerr << "Unexpected error during initialization!\n";
       return 1;
    }

    // Instantiate the DOM parser.
    static const XMLCh gLS[] = { chLatin_L, chLatin_S, chNull };
    DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(gLS);
    DOMBuilder        *parser = ((DOMImplementationLS*)impl)->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0);

    parser->setFeature(XMLUni::fgDOMNamespaces, doNamespaces);
    parser->setFeature(XMLUni::fgXercesSchema, doSchema);
    parser->setFeature(XMLUni::fgXercesSchemaFullChecking, schemaFullChecking);

    if (valScheme == AbstractDOMParser::Val_Auto)
    {
        parser->setFeature(XMLUni::fgDOMValidateIfSchema, true);
    }
    else if (valScheme == AbstractDOMParser::Val_Never)
    {
        parser->setFeature(XMLUni::fgDOMValidation, false);
    }
    else if (valScheme == AbstractDOMParser::Val_Always)
    {
        parser->setFeature(XMLUni::fgDOMValidation, true);
    }

    if (!schemaLocationPairs.isNull())
    {
       XMLCh* propertyValue = XMLString::transcode(schemaLocationPairs.data());
       parser->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,
                           propertyValue
                           );
    }

    // enable datatype normalization - default is off
    parser->setFeature(XMLUni::fgDOMDatatypeNormalization, true);

    // And create our error handler and install it
    XSDValidErrorHandler errorHandler;
    parser->setErrorHandler(&errorHandler);

    //
    //  Get the starting time and kick off the parse of the indicated
    //  file. Catch any exceptions that might propagate out of it.
    //
    unsigned long duration;

    bool more = true;
    XERCES_STD_QUALIFIER ifstream fin;

    // the input is a list file
    if (doList)
        fin.open(argV[argInd]);

    if (fin.fail()) {
        XERCES_STD_QUALIFIER cerr <<"Cannot open the list file: " << argV[argInd] << XERCES_STD_QUALIFIER endl;
        return 2;
    }

    while (more)
    {
        char fURI[1000];
        //initialize the array to zeros
        memset(fURI,0,sizeof(fURI));

        if (doList) {
            if (! fin.eof() ) {
                fin.getline (fURI, sizeof(fURI));
                if (!*fURI)
                    continue;
                else {
                    xmlFile = fURI;
                    XERCES_STD_QUALIFIER cerr << "==Parsing== " << xmlFile << XERCES_STD_QUALIFIER endl;
                }
            }
            else
                break;
        }
        else {
            xmlFile = argV[argInd];
            more = false;
        }

        //reset error count first
        errorHandler.resetErrors();

        XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *doc = 0;

        try
        {
            // reset document pool
            parser->resetDocumentPool();

            const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
            doc = parser->parseURI(xmlFile);
            const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
            duration = endMillis - startMillis;
        }

        catch (const XMLException& toCatch)
        {
            XERCES_STD_QUALIFIER cerr << "\nError during parsing: '" << xmlFile << "'\n"
                 << "Exception message is:  \n"
                 << StrX(toCatch.getMessage()) << "\n" << XERCES_STD_QUALIFIER endl;
            errorOccurred = true;
            continue;
        }
        catch (const DOMException& toCatch)
        {
            const unsigned int maxChars = 2047;
            XMLCh errText[maxChars + 1];

            XERCES_STD_QUALIFIER cerr << "\nDOM Error during parsing: '" << xmlFile << "'\n"
                 << "DOMException code is:  " << toCatch.code << XERCES_STD_QUALIFIER endl;

            if (DOMImplementation::loadDOMExceptionMsg(toCatch.code, errText, maxChars))
                 XERCES_STD_QUALIFIER cerr << "Message is: " << StrX(errText) << XERCES_STD_QUALIFIER endl;

            errorOccurred = true;
            continue;
        }
        catch (...)
        {
            XERCES_STD_QUALIFIER cerr << "\nUnexpected exception during parsing: '" << xmlFile << "'\n";
            errorOccurred = true;
            continue;
        }
    }

    //
    //  Delete the parser itself.  Must be done prior to calling Terminate, below.
    //
    parser->release();

    // And call the termination method
    XMLPlatformUtils::Terminate();

    if (doList)
        fin.close();

    return errorOccurred || errorHandler.getSawErrors() ? 1 : 0;
}
예제 #10
0
파일: OsSysLog.cpp 프로젝트: xaccc/sipXtapi
//:Parses a log string into its parts.
OsStatus OsSysLog::parseLogString(const char *szSource,
                                  UtlString& date,
                                  UtlString& eventCount,
                                  UtlString& facility,
                                  UtlString& priority,
                                  UtlString& hostname,
                                  UtlString& taskname,
                                  UtlString& taskId,
                                  UtlString& processId,
                                  UtlString& content)
{
   #define PS_DATE         0
   #define PS_EVENTCOUNT   1
   #define PS_FACILITY     2
   #define PS_PRIORITY     3
   #define PS_HOSTNAME     4
   #define PS_TASKNAME     5
   #define PS_TASKID       6
   #define PS_PROCESSID    7
   #define PS_CONTENT      8

   const char* pTraverse = szSource ;  // Traverses the source string
   UtlBoolean   bWithinQuote = FALSE;   // Are we within a quoted string?
   UtlBoolean   bEscapeNext = FALSE;    // The next char is an escape char.
   int         iParseState ;           // What are we parsing (PS_*)
   
   // Clean all of the passed objects
   date.remove(0) ;
   eventCount.remove(0) ;
   facility.remove(0) ;
   priority.remove(0) ;
   hostname.remove(0) ;
   taskname.remove(0) ;
   processId.remove(0) ;
   content.remove(0) ;

   // Loop through the source string and add characters to the appropriate
   // data object
   iParseState = PS_DATE ;
   while (*pTraverse)
   {
      switch (*pTraverse)
      {
         case ':':
            if (!bWithinQuote)
            {
               iParseState++ ;
               pTraverse++ ;
               continue ;
            }
            break ;
         case '"':
            if (!bEscapeNext)
            {
               bWithinQuote = !bWithinQuote;
               pTraverse++ ;
               continue ;
            }
            break ;
         case '\\':
            bEscapeNext = true ;
            break ;
      }

      switch (iParseState)
      {
         case PS_DATE:
            date.append(*pTraverse) ;
            break ;
         case PS_EVENTCOUNT:
            eventCount.append(*pTraverse) ;
            break ;
         case PS_FACILITY:
            facility.append(*pTraverse) ;
            break ;
         case PS_PRIORITY:
            priority.append(*pTraverse) ;
            break ;
         case PS_HOSTNAME:
            hostname.append(*pTraverse) ;
            break ;
         case PS_TASKNAME:
            taskname.append(*pTraverse) ;
            break ;
         case PS_TASKID:
            taskId.append(*pTraverse) ;
            break ;
         case PS_PROCESSID:
            processId.append(*pTraverse) ;
            break ;
         case PS_CONTENT:
            content.append(*pTraverse) ;
            break ;
      }

      pTraverse++ ;
   }

   content = unescape(content) ;

   return OS_SUCCESS ;
}
예제 #11
0
파일: OsSysLog.cpp 프로젝트: xaccc/sipXtapi
// Returns an escaped version of the specified source string
UtlString OsSysLog::escape(const UtlString& source)
{
   UtlString    results ;        
   const char* pStart = source.data() ;
   const char* pTraverse = pStart ;
   const char* pLast = pStart ;

   while (*pTraverse)
   {
      switch (*pTraverse)
      {
         case '\\':
            // Copy old data
            if (pLast < pTraverse)
            {
               results.append(pLast, pTraverse-pLast);               
            }
            pLast = pTraverse + 1 ;

            // Add escaped Text
            results.append("\\\\") ;
            break ;
         case '\r':
            // Copy old data
            if (pLast < pTraverse)
            {
               results.append(pLast, pTraverse-pLast);               
            }
            pLast = pTraverse + 1 ;

            // Add escaped Text
            results.append("\\r") ;
            break ;
         case '\n':
            // Copy old data
            if (pLast < pTraverse)
            {
               results.append(pLast, pTraverse-pLast);               
            }
            pLast = pTraverse + 1 ;

            // Add escaped Text
            results.append("\\n") ;
            break ;
         case '\"':
            // Copy old data
            if (pLast < pTraverse)
            {
               results.append(pLast, pTraverse-pLast);
            }
            pLast = pTraverse + 1 ;

            // Add escaped Text
            results.append("\\\"") ;
            break ;            
         default:
            break ;
      }
      pTraverse++ ;
   }

   // if nothing to escape, short-circuit
   if (pLast == pStart)
   {
      return source ;
   } 
   else if (pLast < pTraverse)
   {
      results.append(pLast, pTraverse-pLast);
   }
  
   return results ;
}
예제 #12
0
RedirectPlugin::LookUpStatus
SipRedirectorMapping::lookUp(
   const SipMessage& message,
   const UtlString& requestString,
   const Url& requestUri,
   const UtlString& method,
   ContactList& contactList,
   RequestSeqNo requestSeqNo,
   int redirectorNo,
   SipRedirectorPrivateStorage*& privateStorage,
   ErrorDescriptor& errorDescriptor)
{
   UtlString callTag = "UNK";
   UtlString permissionName;
   ResultSet urlMappingRegistrations;
   ResultSet urlMappingPermissions;

   // @JC This variable is strangely overloaded
   // If we have no permissions then add any encountered
   // contacts. If we do have permissions then the
   // permission must match
   UtlBoolean permissionFound = TRUE;

   if (mMappingRulesLoaded == OS_SUCCESS)
   {
      mMap.getContactList(
         requestUri,
         urlMappingRegistrations,
         urlMappingPermissions,
         callTag);
   }

   int numUrlMappingPermissions = urlMappingPermissions.getSize();

   Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp "
                 "got %d UrlMapping Permission requirements for %d contacts",
                 mLogName.data(), numUrlMappingPermissions,
                 urlMappingRegistrations.getSize());

   if (numUrlMappingPermissions > 0)
   {
      // check if we have field parameter that indicates that some permissions should be ignored
      UtlString ignorePermissionStr;
      // :KLUDGE: remove const_cast and uri declaration after XSL-88 gets fixed
      Url& uri = const_cast<Url&>(requestUri);
      uri.getUrlParameter("sipx-noroute", ignorePermissionStr);

      EntityRecord entity;
     std::set<std::string> permissions;
     if (_dataStore.entityDB().findByIdentityOrAlias(requestUri, entity))
        permissions = entity.permissions();
     size_t numDBPermissions = permissions.size();

      for (int i = 0; i<numUrlMappingPermissions; i++)
      {
         UtlHashMap record;
         urlMappingPermissions.getIndex(i, record);
         UtlString permissionKey("permission");
         UtlString urlMappingPermissionStr =
            *((UtlString*) record.findValue(&permissionKey));
         Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                       "%s::lookUp checking permissions DB for "
                       "urlMappingPermissions[%d] = '%s'",
                       mLogName.data(), i,
                       urlMappingPermissionStr.data());

         // Try to match the permission
         // so assume it cannot be found unless we
         // see a match in the IMDB
         permissionFound = FALSE;

         // if the permission we are looking for is the one the we are supposed to ignore,
         // than assume that permission is not found
         if (urlMappingPermissionStr.compareTo(ignorePermissionStr, UtlString::ignoreCase) == 0)
         {
             Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                           "%s::lookUp ignoring permission '%s'",
                           mLogName.data(),
                           ignorePermissionStr.data());
             continue;
         }



         
         
         UtlString permissionsFound;
         for (std::set<std::string>::const_iterator iter = permissions.begin();
             iter != permissions.end(); iter++)
         {
            UtlString dbPermissionStr = iter->c_str();

            bool equal = dbPermissionStr.compareTo(urlMappingPermissionStr, UtlString::ignoreCase) == 0;
 
            if (Os::Logger::instance().willLog(FAC_SIP, PRI_DEBUG))
            {
               permissionsFound.append(" ");
               permissionsFound.append(dbPermissionStr);
               if (equal)
               {
                  permissionsFound.append("[matches]");
               }
            }
            if (equal)
            {
               // matching permission found in IMDB
               permissionFound = TRUE;
               break;
            }
            dbPermissionStr.remove(0);
         }
         Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                       "%s::lookUp %d permissions configured for request URI '%s'.  Checking: %s",
                       mLogName.data(), numDBPermissions,
                       requestUri.toString().data(),
                       permissionsFound.data());

         if (permissionFound)
         {
            break;
         }
         urlMappingPermissionStr.remove(0);
      }
   }

   // either there were no requirements to match against voicemail
   // or there were and we found a match in the IMDB for the URI
   // so now add the contacts to the SIP message
   if (permissionFound)
   {
      int numUrlMappingRegistrations = urlMappingRegistrations.getSize();

      Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                    "%s::lookUp got %d UrlMapping Contacts",
                    mLogName.data(), numUrlMappingRegistrations);

      if (numUrlMappingRegistrations > 0)
      {
         for (int i = 0; i < numUrlMappingRegistrations; i++)
         {
            UtlHashMap record;
            urlMappingRegistrations.getIndex(i, record);
            UtlString contactKey("contact");
            UtlString contact= *(dynamic_cast <UtlString*> (record.findValue(&contactKey)));

            Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                          "%s::lookUp contact = '%s'",
                          mLogName.data(), contact.data());
            Url contactUri(contact);
            Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                          "%s::lookUp contactUri = '%s'",
                          mLogName.data(), contactUri.toString().data());
            // We no longer check for recursive loops here because we
            // have comprehensive loop detection in the proxy.
            UtlString recordRoute;
            UtlString curCallDest;
            if (message.getRecordRouteField(0,&recordRoute)) {
               Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                          "%s::lookUp RecordRouteField = '%s'",
                          mLogName.data(), recordRoute.data());
            }
            contactUri.setUrlParameter(SIP_SIPX_CALL_DEST_FIELD, callTag.data());

            // Add the contact.
            contactList.add( contactUri, *this );
         }
      }
   }

   return RedirectPlugin::SUCCESS;
}
예제 #13
0
void SipDialogEvent::buildBody(int& version) const
{
    UtlString dialogEvent;
    UtlString singleLine;
    char buffer[20];
    char durationBuffer[20];

    // Return the XML version.
    version = mVersion;

    // Construct the xml document of dialog event
    dialogEvent = UtlString(XML_VERSION_1_0);

    // Dialog Information Structure
    dialogEvent.append(BEGIN_DIALOG_INFO);

    Url entityUri(mEntity);
    sprintf(buffer, "%d", mVersion);

    dialogEvent.append(VERSION_EQUAL);
    singleLine = DOUBLE_QUOTE + UtlString(buffer) + DOUBLE_QUOTE;
    dialogEvent += singleLine;

    dialogEvent.append(STATE_EQUAL);
    singleLine = DOUBLE_QUOTE + mDialogState + DOUBLE_QUOTE;
    dialogEvent += singleLine;

    dialogEvent.append(ENTITY_EQUAL);
    singleLine = DOUBLE_QUOTE + entityUri.toString() + DOUBLE_QUOTE;
    dialogEvent += singleLine;
    dialogEvent.append(END_LINE);

    // Take the lock (we will be modifying the state even though 'this'
    // is read-only).
    ((SipDialogEvent*)this)->mLock.acquire();

    // Dialog elements
    UtlSListIterator dialogIterator(mDialogs);
    Dialog* pDialog;
    while ((pDialog = (Dialog *) dialogIterator()))
    {
        UtlString id, callId, localTag, remoteTag, direction;
        pDialog->getDialog(id, callId, localTag, remoteTag, direction);

        dialogEvent.append(BEGIN_DIALOG);
        singleLine = DOUBLE_QUOTE + id + DOUBLE_QUOTE;
        dialogEvent += singleLine;
        if (!callId.isNull())
        {
            dialogEvent.append(CALL_ID_EQUAL);
            singleLine = DOUBLE_QUOTE + callId + DOUBLE_QUOTE;
            dialogEvent += singleLine;
        }

        if (!localTag.isNull())
        {
            dialogEvent.append(LOCAL_TAG_EQUAL);
            singleLine = DOUBLE_QUOTE + localTag + DOUBLE_QUOTE;
            dialogEvent += singleLine;
        }

        if (!remoteTag.isNull())
        {
            dialogEvent.append(REMOTE_TAG_EQUAL);
            singleLine = DOUBLE_QUOTE + remoteTag + DOUBLE_QUOTE;
            dialogEvent += singleLine;
        }

        if (!direction.isNull())
        {
            dialogEvent.append(DIRECTION_EQUAL);
            singleLine = DOUBLE_QUOTE + direction + DOUBLE_QUOTE;
            dialogEvent += singleLine;
        }
        dialogEvent.append(END_LINE);

        // State element
        UtlString state, event, code;
        pDialog->getState(state, event, code);

        dialogEvent.append(BEGIN_STATE);
        if (!event.isNull())
        {
            dialogEvent.append(EVENT_EQUAL);
            singleLine = DOUBLE_QUOTE + event + DOUBLE_QUOTE;
            dialogEvent += singleLine;
        }

        if (!code.isNull())
        {
            dialogEvent.append(CODE_EQUAL);
            singleLine = DOUBLE_QUOTE + code + DOUBLE_QUOTE;
            dialogEvent += singleLine;
        }

        // End of state element
        singleLine = END_BRACKET + state + END_STATE;
        dialogEvent += singleLine;

        // Duration element
        int duration = pDialog->getDuration();
        if (duration !=0)
        {
            duration = OsDateTime::getSecsSinceEpoch() - pDialog->getDuration();
            sprintf(durationBuffer, "%d", duration);
            dialogEvent += BEGIN_DURATION + UtlString(durationBuffer) + END_DURATION;
        }

        // Local element
        UtlString identity, displayName, target;
        pDialog->getLocalIdentity(identity, displayName);
        pDialog->getLocalTarget(target);

        dialogEvent.append(BEGIN_LOCAL);
        if (!identity.isNull())
        {
            dialogEvent.append(BEGIN_IDENTITY);
            if (!displayName.isNull())
            {
                NameValueTokenizer::frontBackTrim(&displayName, "\"");
                dialogEvent.append(DISPLAY_EQUAL);
                singleLine = DOUBLE_QUOTE + displayName + DOUBLE_QUOTE;
                dialogEvent += singleLine;
            }

            singleLine = END_BRACKET + identity + END_IDENTITY;
            dialogEvent += singleLine;
        }

        if (!target.isNull() && target.compareTo("sip:") != 0)
        {
            singleLine = BEGIN_TARTGET + target + END_TARGET;
            dialogEvent += singleLine;
        }

        // End of local element
        dialogEvent.append(END_LOCAL);

        // Remote element
        pDialog->getRemoteIdentity(identity, displayName);
        pDialog->getRemoteTarget(target);

        dialogEvent.append(BEGIN_REMOTE);
        if (!identity.isNull())
        {
            dialogEvent.append(BEGIN_IDENTITY);
            if (!displayName.isNull())
            {
                NameValueTokenizer::frontBackTrim(&displayName, "\"");
                dialogEvent.append(DISPLAY_EQUAL);
                singleLine = DOUBLE_QUOTE + displayName + DOUBLE_QUOTE;
                dialogEvent += singleLine;
            }

            singleLine = END_BRACKET + identity + END_IDENTITY;
            dialogEvent += singleLine;
        }

        if (!target.isNull() && target.compareTo("sip:") != 0)
        {
            singleLine = BEGIN_TARTGET + target + END_TARGET;
            dialogEvent += singleLine;
        }

        // End of remote element
        dialogEvent.append(END_REMOTE);

        // End of dialog element
        dialogEvent.append(END_DIALOG);
    }

    // End of dialog-info element
    dialogEvent.append(END_DIALOG_INFO);

    // Update body text and version number (even though 'this' is read-only).
    ((SipDialogEvent*)this)->mBody = dialogEvent;
    ((SipDialogEvent*)this)->bodyLength = dialogEvent.length();
    ((SipDialogEvent*)this)->mVersion++;

    ((SipDialogEvent*)this)->mLock.release();

    OsSysLog::add(FAC_SIP, PRI_DEBUG, "SipDialogEvent::buildBody Dialog content = \n%s",
                  mBody.data());
}
MpResourceTopology* CpTopologyGraphFactoryImpl::buildMulticastConnectionResourceTopology()
{
    MpResourceTopology* resourceTopology = new MpResourceTopology();
    OsStatus result;

    // Add multicast RTP input
    result = resourceTopology->addResource(DEFAULT_MCAST_RTP_INPUT_RESOURCE_TYPE,
                                           DEFAULT_RTP_INPUT_RESOURCE_NAME);
    assert(result == OS_SUCCESS);

    // Add stream resources and link them with RTP input and bridge
    UtlString decodeName = DEFAULT_DECODE_RESOURCE_NAME;
    UtlString activityNotifName = DEFAULT_VOICE_ACTIVITY_NOTIFIER_RESOURCE_NAME;
    activityNotifName.append(CONNECTION_NAME_SUFFIX);
#ifdef INSERT_DELAY_RESOURCE // [
    UtlString delayName = DEFAULT_DELAY_RESOURCE_NAME;
    delayName.append(CONNECTION_NAME_SUFFIX);
#endif // INSERT_DELAY_RESOURCE ]
    for (int i=0; i<mNumMcastStreams; i++)
    {
       // Construct names of resources for this stream
       UtlString streamSuffix;
       streamSuffix.appendFormat(STREAM_NAME_SUFFIX, i);
       UtlString tmpDecodeName(decodeName);
       tmpDecodeName.append(streamSuffix);
       UtlString tmpActivityNotifName(activityNotifName);
       tmpActivityNotifName.append(streamSuffix);
#ifdef INSERT_DELAY_RESOURCE // [
       UtlString tmpDelayName(delayName);
       tmpDelayName.append(streamSuffix);
#endif // INSERT_DELAY_RESOURCE ]

       // Add decoder
       result = resourceTopology->addResource(DEFAULT_DECODE_RESOURCE_TYPE,
                                              tmpDecodeName,
                                              MP_INVALID_CONNECTION_ID,
                                              i);
       assert(result == OS_SUCCESS);

       // Add Voice Activity Notifier
       result = resourceTopology->addResource(DEFAULT_VOICE_ACTIVITY_NOTIFIER_RESOURCE_TYPE,
                                              tmpActivityNotifName,
                                              MP_INVALID_CONNECTION_ID,
                                              i);
       assert(result == OS_SUCCESS);

#ifdef INSERT_DELAY_RESOURCE // [
       // Add delay resource
       result = resourceTopology->addResource(DEFAULT_DELAY_RESOURCE_TYPE,
                                              tmpDelayName,
                                              MP_INVALID_CONNECTION_ID,
                                              i);
       assert(result == OS_SUCCESS);
#endif // INSERT_DELAY_RESOURCE ]

       // Link RTP input -> decoder
       result = resourceTopology->addConnection(DEFAULT_RTP_INPUT_RESOURCE_NAME, i,
                                                tmpDecodeName, 0);
       assert(result == OS_SUCCESS);
       UtlString &lastResourceName = tmpDecodeName;

       // -> Voice Activity Notifier
       result = resourceTopology->addConnection(lastResourceName, 0,
                                                tmpActivityNotifName, 0);
       assert(result == OS_SUCCESS);
       lastResourceName = tmpActivityNotifName;

#ifdef INSERT_DELAY_RESOURCE // [
       // -> Delay
       result = resourceTopology->addConnection(lastResourceName, 0,
                                                tmpDelayName, 0);
       assert(result == OS_SUCCESS);
       lastResourceName = tmpDelayName;
#endif // INSERT_DELAY_RESOURCE ]

       // Mark last resource as RTP Stream Output
       UtlString streamOutputName(VIRTUAL_NAME_RTP_STREAM_OUTPUT);
       streamOutputName.append(streamSuffix);
       result = resourceTopology->addVirtualOutput(lastResourceName, 0,
                                                   streamOutputName, 0);
       assert(result == OS_SUCCESS);

       // -> bridge
       result = resourceTopology->addConnection(lastResourceName, 0,
                                                VIRTUAL_NAME_CONNECTION_PORTS,
                                                MpResourceTopology::MP_TOPOLOGY_NEXT_AVAILABLE_PORT);
       assert(result == OS_SUCCESS);
    }


    addOutputConnectionTopology(resourceTopology, -1);

    return(resourceTopology);
}
예제 #15
0
// get a description of the FileResource (for use in logging)
void FileResource::appendDescription(UtlString&  description /**< returned description */) const
{
   description.append("file '");
   description.append(data());
   description.append("'");
}
예제 #16
0
OsStatus EmailNotifier::handleAlarm(const OsTime alarmTime, 
      const UtlString& callingHost, 
      const cAlarmData* alarmData, 
      const UtlString& alarmMsg)
{
   OsStatus retval = OS_FAILED;

   UtlString body;
   UtlString tempStr;

   body = mEmailStrIntro;
   body.append("\n");
   
   assembleMsg(mEmailStrAlarm, alarmData->getCode(), tempStr);
   body.append(tempStr);
   body.append("\n");
   
   assembleMsg(mEmailStrHost, callingHost, tempStr);
   body.append(tempStr);
   body.append("\n");
   
   OsDateTime logTime(alarmTime);
   UtlString strTime;
   logTime.getIsoTimeStringZus(strTime);
   assembleMsg(mEmailStrTime, strTime, tempStr);
   body.append(tempStr);
   body.append("\n");
   
   UtlString sevStr = OsSysLog::priorityName(alarmData->getSeverity());
   assembleMsg(mEmailStrSeverity, sevStr, tempStr);
   body.append(tempStr);
   body.append("\n");
   assembleMsg(mEmailStrDescription, alarmMsg, tempStr);
   body.append(tempStr);
   body.append("\n");
   assembleMsg(mEmailStrResolution, alarmData->getResolution(), tempStr);
   body.append(tempStr);
   OsSysLog::add(FAC_ALARM, PRI_DEBUG, "AlarmServer: email body is %s", body.data());

   MailMessage message( mEmailStrFrom, mReplyTo, mSmtpServer );
   message.Body(body);
   
   UtlSList subjectParams;
   UtlString codeStr(alarmData->getCode());
   UtlString titleStr(alarmData->getShortTitle());
   subjectParams.append(&codeStr);
   subjectParams.append(&titleStr);
   assembleMsg(mEmailStrSubject, subjectParams, tempStr);
   message.Subject(tempStr);

   //execute the mail command for each user
   UtlSListIterator iterator(mContacts);
   UtlString* pObject;
   while ( (pObject = dynamic_cast<UtlString*>(iterator())))
   {
      message.To(*pObject, *pObject);
   }

   // delegate send to separate task so as not to block
   EmailSendTask::getInstance()->sendMessage(message);

   return retval;
}
예제 #17
0
RedirectPlugin::LookUpStatus
SipRedirectorRegDB::lookUp(
   const SipMessage& message,
   UtlString& requestString,
   Url& requestUri,
   const UtlString& method,
   ContactList& contactList,
   RequestSeqNo requestSeqNo,
   int redirectorNo,
   SipRedirectorPrivateStorage*& privateStorage,
   ErrorDescriptor& errorDescriptor)
{
   unsigned long timeNow = OsDateTime::getSecsSinceEpoch();
   
   // Local copy of requestUri
   Url requestUriCopy = requestUri;

   // Look for any grid parameter and remove it.
   UtlString gridParameter;
   UtlBoolean gridPresent =
      requestUriCopy.getUrlParameter("grid", gridParameter, 0);
   if (gridPresent)
   {
      requestUriCopy.removeUrlParameter("grid");
   }
   if (Os::Logger::instance().willLog(FAC_SIP, PRI_DEBUG))
   {
      UtlString temp;
      requestUriCopy.getUri(temp);
      Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                    "%s::lookUp gridPresent = %d, gridParameter = '%s', "
                    "requestUriCopy after removing grid = '%s'",
                    mLogName.data(), gridPresent, gridParameter.data(),
                    temp.data());
   }

   RegDB::Bindings registrations;

   // Give the ~~in~ URIs separate processing.
   UtlString user;
   requestUriCopy.getUserId(user);
   RegDB* regDb = SipRegistrar::getInstance(NULL)->getRegDB();
   if (user.index(URI_IN_PREFIX) == 0)
   {
      // This is a ~~in~ URI.
      // Check for an '&' separator.
      ssize_t s = user.last('&');
      if (s != UTL_NOT_FOUND)
      {
         // This is a ~~in~[user]&[instrument] URI.
         const char* instrumentp = user.data() + s + 1;
         UtlString u;
         u.append(user,
                  sizeof (URI_IN_PREFIX) - 1,
                  s - (sizeof (URI_IN_PREFIX) - 1));
         requestUriCopy.setUserId(u);

         //regDB->
         //   getUnexpiredContactsUserInstrument(requestUriCopy, instrumentp, timeNow, registrations);
         UtlString identity;
         requestUriCopy.getIdentity(identity);
         regDb->getUnexpiredContactsUserInstrument(identity.str(), instrumentp, timeNow, registrations);
      }
      else
      {
         // This is a ~~in~[instrument] URI.
         const char* instrumentp = user.data() + sizeof (URI_IN_PREFIX) - 1;
         regDb->getUnexpiredContactsInstrument(instrumentp, timeNow, registrations);
      }         
   }
   else
   {
      // Note that getUnexpiredContactsUser will reduce the requestUri to its
      // identity (user/host/port) part before searching in the
      // database.  The requestUri identity is matched against the
      // "identity" column of the database, which is the identity part of
      // the "uri" column which is stored in registration.xml.

      UtlString identity;
     requestUriCopy.getIdentity(identity);
     regDb->getUnexpiredContactsUser(identity.str(), timeNow, registrations);

   }

   int numUnexpiredContacts = registrations.size();

   Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                 "%s::lookUp got %d unexpired contacts",
                 mLogName.data(), numUnexpiredContacts);

   // Check for a per-user call forward timer.
   // Don't set timer if we're not going to forward to voicemail.
   std::ostringstream userCfwdTimer;
   bool foundUserCfwdTimer = false;

   if (method.compareTo(SIP_INVITE_METHOD) == 0)
   {
      UtlString noRoute;
      requestUriCopy.getUrlParameter("sipx-noroute", noRoute);

      if ((!noRoute.isNull()) && (noRoute.compareTo("Voicemail") == 0))
      {
          // This is not a call scenerio controlled by this users "forward to voicemail" timer
      }
      else
      {
          UtlString identity;
          requestUriCopy.getIdentity(identity);
          EntityRecord entity;

          EntityDB* entityDb = SipRegistrar::getInstance(NULL)->getEntityDB();
          foundUserCfwdTimer = entityDb->findByIdentity(identity.str(), entity);
          if (foundUserCfwdTimer)
            userCfwdTimer << entity.callForwardTime();
      }
   }

   for (RegDB::Bindings::const_iterator iter = registrations.begin(); iter != registrations.end(); iter++)
   {
      // Query the Registration DB for the contact, expires and qvalue columns.

      Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                    "%s::lookUp contact = '%s', qvalue = '%s', path = '%s'",
                    mLogName.data(), iter->getContact().c_str(), iter->getQvalue().c_str(), iter->getPath().c_str() );
      Url contactUri(iter->getContact().c_str());

      // If available set the per-user call forward timer.
      if (foundUserCfwdTimer)
      {
          contactUri.setHeaderParameter("expires", userCfwdTimer.str().c_str());
      }

      // If the contact URI is the same as the request URI, ignore it.
      if (!contactUri.isUserHostPortEqual(requestUriCopy))
      {
         // Check if the q-value from the database is valid, and if so,
         // add it into contactUri.
         if (!iter->getQvalue().empty())
         {
            // :TODO: (XPL-3) need a RegEx copy constructor here
            // Check if q value is numeric and between the range 0.0 and 1.0.
            static RegEx qValueValid("^(0(\\.\\d{0,3})?|1(\\.0{0,3})?)$");
            if (qValueValid.Search(iter->getQvalue().c_str()))
            {
               contactUri.setFieldParameter(SIP_Q_FIELD, iter->getQvalue().c_str());
            }
         }

         // Re-apply any grid parameter.
         if (gridPresent)
         {
            contactUri.setUrlParameter("grid", gridParameter);
         }

         contactUri.setUrlParameter(SIP_SIPX_CALL_DEST_FIELD, "INT");
         // Check if database contained a Path value.  If so, add a Route
         // header parameter to the contact with the Path vector taken from
         // the registration data.
         if (!iter->getPath().empty())
         {
            UtlString existingRouteValue;
            std::string pathVector = iter->getPath();
            if ( contactUri.getHeaderParameter(SIP_ROUTE_FIELD, existingRouteValue))
            {
               // there is already a Route header parameter in the contact; append it to the
               // Route derived from the Path vector.
                pathVector += SIP_MULTIFIELD_SEPARATOR;
                pathVector += existingRouteValue.str();
            }
            contactUri.setHeaderParameter(SIP_ROUTE_FIELD, pathVector.c_str());
         }

         // Add the contact.
         contactList.add( contactUri, *this );
      }
   }

   return RedirectPlugin::SUCCESS;
}
예제 #18
0
UtlBoolean SmimeBody::encrypt(HttpBody* bodyToEncrypt,
                              int numRecipients,
                              const char* derPublicKeyCerts[],
                              int derPubliceKeyCertLengths[])
{
    UtlBoolean encryptionSucceeded = FALSE;

    // Clean up an residual decrypted body or encrypted body content.
    // Should typically not be any.
    if(mpDecryptedBody)
    {
        delete mpDecryptedBody;
        mpDecryptedBody = NULL;
    }
    mBody.remove(0);


    if(bodyToEncrypt)
    {
        UtlString dataToEncrypt;
        UtlString contentType = bodyToEncrypt->getContentType();

        // Add the content-type and content-encoding headers to
        // the body to be decrypted so that when the otherside
        // decrypts this body, it can tell what the content is
        dataToEncrypt ="Content-Type: ";
        dataToEncrypt.append(contentType);
        dataToEncrypt.append(END_OF_LINE_DELIMITER);
        dataToEncrypt.append("Content-Transfer-Encoding: binary");
        dataToEncrypt.append(END_OF_LINE_DELIMITER);
        dataToEncrypt.append(END_OF_LINE_DELIMITER);

        // Append the real body content
        const char* dataPtr;
        ssize_t dataLength;
        bodyToEncrypt->getBytes(&dataPtr, &dataLength);
        dataToEncrypt.append(dataPtr, dataLength);

        // Attach the decrypted version of the body for
        // future reference.
        mpDecryptedBody = bodyToEncrypt;

        UtlString encryptedData;

#ifdef ENABLE_OPENSSL_SMIME
        OsSysLog::add(FAC_SIP, PRI_ERR,
            "SmimeBody::opensslSmimeEncrypt not implemented");

#elif ENABLE_NSS_SMIME
        UtlBoolean encryptedDataInBase64Format = FALSE;

        encryptionSucceeded =
            nssSmimeEncrypt(numRecipients,
                            derPublicKeyCerts,
                            derPubliceKeyCertLengths,
                            dataToEncrypt.data(),
                            dataToEncrypt.length(),
                            encryptedDataInBase64Format,
                            mBody);
#endif

        encryptedData = mBody;
        // There should always be content if encryption succeeds
        if(encryptionSucceeded &&
           encryptedData.length() <= 0)
        {
            encryptionSucceeded = FALSE;
            OsSysLog::add(FAC_SIP, PRI_ERR,
                "SmimeBody::encrypt no encrypted content");
        }
    }

    return(encryptionSucceeded);
}
예제 #19
0
파일: Url.cpp 프로젝트: John-Chan/sipXtapi
void Url::getUri(UtlString& urlString)
{
   // Insert the scheme
    urlString = schemeName(mScheme);
    urlString.append(":",1);
    
    switch(mScheme)
    {
    case FileUrlScheme:
    case FtpUrlScheme:
    case HttpUrlScheme:
    case HttpsUrlScheme:
    case RtspUrlScheme:
       urlString.append("//",2);
       break;

    case SipUrlScheme:
    case SipsUrlScheme:
    case MailtoUrlScheme:
    default:
       break;
    }

    // Add the user 
    if (FileUrlScheme != mScheme) // no user defined in a file url
    {
       if(!mUserId.isNull())
       {
          urlString.append(mUserId);
          if(!mPassword.isNull() || mPasswordSet)
          {
             urlString.append(":", 1);
             urlString.append(mPassword);
          }
          urlString.append("@", 1);
       }
    }

    // Add the host
    urlString.append(mHostAddress);
    if(mHostPort > 0)
    {
       char portBuffer[20];
       sprintf(portBuffer, ":%d", mHostPort);
       urlString.append(portBuffer);
    }

    // Add the path
    switch(mScheme)
    {
    case FileUrlScheme:
    case FtpUrlScheme:
    case HttpUrlScheme:
    case HttpsUrlScheme:
    case RtspUrlScheme:
       if(!mPath.isNull())
       {
          urlString.append(mPath);
       }
       break;

    case SipUrlScheme:
    case SipsUrlScheme:
    case MailtoUrlScheme:
    default:
       break;
    }

    // Add the URL parameters
    if (   (   mpUrlParameters
            || const_cast<Url*>(this)->parseUrlParameters()
            )
        && mpUrlParameters->entries()
        )
    {
        UtlDListIterator urlParamIterator(*mpUrlParameters);
        NameValuePair* urlParam = NULL;
        UtlString urlParamValue;

        while ((urlParam = (NameValuePair*) urlParamIterator()))
        {
            urlString.append(";", 1);
            urlString.append(*urlParam);
            urlParamValue = urlParam->getValue();
            if(!urlParamValue.isNull())
            {
                urlString.append("=", 1);
                HttpMessage::escape(urlParamValue);
                urlString.append(urlParamValue);
            }
        }
    }
    
    // Add the header parameters
    if (   (   mpHeaderOrQueryParameters
            || const_cast<Url*>(this)->parseHeaderOrQueryParameters()
            )
        && mpHeaderOrQueryParameters->entries()
        )
    {
        UtlDListIterator headerParamIterator(*mpHeaderOrQueryParameters);
        NameValuePairInsensitive* headerParam = NULL;
        UtlString headerParamValue;
        UtlBoolean firstHeader = TRUE;

        while ((headerParam = static_cast<NameValuePairInsensitive*>(headerParamIterator())))
        {
            // Add separator for first header parameter
            if(firstHeader)
            {
                urlString.append("?", 1);
                firstHeader = FALSE;
            }
            else
            {
                urlString.append("&", 1);
            }

            urlString.append(*headerParam);
            headerParamValue = headerParam->getValue();
            if(!headerParamValue.isNull())
            {
                urlString.append("=", 1);
                HttpMessage::escape(headerParamValue);
                urlString.append(headerParamValue);
            }
        }
    }
}
예제 #20
0
static void nssOutToUtlString(void *sink, const char *data, unsigned long dataLength)
{
    printf("nssOutToUtlString recieved %d bytes\n", dataLength);
    UtlString* outputSink = (UtlString*) sink;
    outputSink->append(data, dataLength);
}
예제 #21
0
// Thread execution code.
int SipClient::run(void* runArg)
{
   OsMsg*    pMsg = NULL;
   OsStatus  res;
   // Buffer to hold data read from the socket but not yet parsed
   // into incoming SIP messages.
   UtlString readBuffer;
   bool      waitingToReportErr  = FALSE;    // controls whether to read-select on socket
   bool      tcpOnErrWaitForSend = TRUE;
   int       repeatedEOFs = 0;

   Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                 "SipClient[%s]::run start  "
                 "tcpOnErrWaitForSend-%d waitingToReportErr-%d mbTcpOnErrWaitForSend-%d repeatedEOFs-%d",
                 mName.data(), tcpOnErrWaitForSend, waitingToReportErr,
                 mbTcpOnErrWaitForSend, repeatedEOFs);

   // Wait structure:
   struct pollfd fds[2];
   // Incoming message on the message queue (to be sent on the socket).
   fds[0].fd = mPipeReadingFd;
   // Socket ready to write (to continue sending message).
   // Socket ready to read (message to be received).

   do
   {
      assert(repeatedEOFs < 20);
      // The file descriptor for the socket may changemsg->getSendAddress(&fromIpAddress, &fromPort);, as OsSocket's
      // can be re-opened.
      fds[1].fd = mClientSocket->getSocketDescriptor();

      // Initialize the revents members.
      // This may not be necessary (the man page is not clear), but
      // Valgrind flags 'fds[*].revents' as undefined if they aren't
      // initialized.
      fds[0].revents = 0;
      fds[1].revents = 0;

      fds[0].events = POLLIN;   // only read-select on pipe

      // For non-blocking connect failures, don't read-select on socket if
      // the initial read showed an error but we have to wait to report it.
      if (!waitingToReportErr)
      {
          // This is the normal path.
          // Read the socket only if the socket is not shared.
          // If it is shared, the ancestral SipClient will read it.
          // If multiple threads attempt to read the socket, poll() may
          // succeed but another may read the data, leaving us to block on
          // read.
          fds[1].events = mbSharedSocket ? 0 : POLLIN;

          // Set wait for writing the socket if there is queued messages to
          // send.
          if (mWriteQueued)
          {
             // Wait for output on the socket to not block.
             fds[1].events |= POLLOUT;
          }

      }
      else
      {
          // just waiting to report error, ignore the socket
          fds[1].fd =-1;
          fds[1].events = 0;
      }

      // If there is residual data in the read buffer,
      // pretend the socket is ready to read.
      if (!readBuffer.isNull())
      {
         fds[1].revents = POLLIN;
      }
      else
      {
         // Otherwise, call poll() to wait.
         int resPoll = poll(&fds[0], sizeof (fds) / sizeof (fds[0]),
                        POLL_TIMEOUT);
         assert(resPoll >= 0 || (resPoll == -1 && errno == EINTR));
         if (resPoll != 0)
         {
             Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                           "SipClient[%s]::run "
                           "resPoll= %d revents: fd[0]= %x fd[1]= %x",
                           mName.data(),
                           resPoll, fds[0].revents, fds[1].revents );
         }
      }

      if ((fds[1].revents & (POLLERR | POLLHUP)) != 0)
      {
          Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                        "SipClient[%s]::run "
                        "SipMessage::poll error(%d) ",
                        mName.data(), errno);

          if (OsSocket::isFramed(mClientSocket->getIpProtocol()))
          {
              Os::Logger::instance().log(FAC_SIP, PRI_ERR,
                            "SipClient[%s]::run "
                            "SipMessage::poll error(%d) got POLLERR | POLLHUP on UDP socket",
                            mName.data(), errno);

          }
          else	// eg. tcp socket
          // This client's socket is a connection-oriented protocol and the
          // connection has been terminated (probably by the remote end).
          // We must terminate the SipClient.
          // We drop the queued messages, but we do not report them to
          // SipUserAgent as failed sends.  This will cause SipUserAgent to
          // retry the send using the same transport (rather than continuing
          // to the next transport), which should cause a new connection to
          // be made to the remote end.
          {
              // On non-blocking connect failures, we need to get the first send message
              // in order to successfully trigger the protocol fallback mechanism
              if (!tcpOnErrWaitForSend)
              {
                 // Return all buffered messages with a transport error indication.
                 emptyBuffer(TRUE);
                 clientStopSelf();
              }
              else
              {
                 fds[1].revents &= ~(POLLERR | POLLHUP);  // clear error bit if waiting
                 waitingToReportErr = TRUE;
              }
          }
      }

      // Check for message queue messages (fds[0]) before checking the socket(fds[1]),
      // to make sure that we process shutdown messages promptly, even
      // if we would be spinning trying to service the socket.
      else if ((fds[0].revents & POLLIN) != 0)
      {
         // Poll finished because the pipe is ready to read.
         // (One byte in pipe means message available in queue.)
         // Only a SipClient with a derived SipClientWriteBuffer
         // uses the pipe in the Sip message send process

         // Check to see how many messages are in the queue.
         int numberMsgs = (getMessageQueue())->numMsgs();
         Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                       "SipClient[%s]::run got pipe-select  "
                       "Number of Messages waiting: %d",
                       mName.data(),
                       numberMsgs);
         int i;
         char buffer[1];
         for (i = 0; i < numberMsgs; i++)
         {
            // Receive the messages.
            res = receiveMessage((OsMsg*&) pMsg, OsTime::NO_WAIT);
            assert(res == OS_SUCCESS);

            // Normally, this is a SIP message for the write buffer.  Once we have gotten
            // here, we are able to report any initial non-blocking connect error.
            mbTcpOnErrWaitForSend = FALSE;
            tcpOnErrWaitForSend = FALSE;
            Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                          "SipClient[%s]::run got pipe-select  "
                          "mbTcpOnErrWaitForSend-%d waitingToReportErr-%d mbTcpOnErrWaitForSend-%d repeatedEOFs-%d",
                          mName.data(), mbTcpOnErrWaitForSend, waitingToReportErr,
                          mbTcpOnErrWaitForSend, repeatedEOFs);

            // Read 1 byte from the pipe to clear it for this message.  One byte is
            // inserted into the pipe for each message.
            assert(read(mPipeReadingFd, &buffer, 1) == 1);

            if (!handleMessage(*pMsg))            // process the message (from queue)
            {
               OsServerTask::handleMessage(*pMsg);
            }

            if (!pMsg->getSentFromISR())
            {
               pMsg->releaseMsg();                         // free the message
            }

            // In order to report an unframed(eg TCP) socket error to SipUserAgent dispatcher,
            // the error must be carried in a sip message from the client's message queue.
            // The message holds all the identifying information.
            if (waitingToReportErr)
            {
                // Return all buffered messages with a transport error indication.
                emptyBuffer(TRUE);
                clientStopSelf();
            }
         }
      } // end reading msg-available-for-output-queue pipe

      else if ((fds[1].revents & POLLOUT) != 0)
      {
         // Poll finished because socket is ready to write.

         // Call method to continue writing data.
         writeMore();
      }
      else if ((fds[1].revents & POLLIN) != 0)
      {
         // Poll finished because socket is ready to read.

         // Read message.
         // Must allocate a new message because SipUserAgent::dispatch will
         // take ownership of it.

         SipMessage* msg = new SipMessage;
         int res = msg->read(mClientSocket,
                             HTTP_DEFAULT_SOCKET_BUFFER_SIZE,
                             &readBuffer);

         if (res >= 65536)
         {
           //
           // This is more than the allowable size of a SIP message.  Discard!
           //
            UtlString remoteHostAddress;
            int remoteHostPort;
            msg->getSendAddress(&remoteHostAddress, &remoteHostPort);
            OS_LOG_WARNING(FAC_SIP, "Received a SIP Message ("
             << res << " bytes) beyond the maximum allowable size from host "
             << remoteHostAddress.data() << ":" << remoteHostPort);
            delete msg;
            readBuffer.remove(0);
            continue;
         }

         // Use readBuffer to hold any unparsed data after the message
         // we read.
         // Note that if a message was successfully parsed, readBuffer
         // still contains as its prefix the characters of that message.
         // We save them for logging purposes below and will delete them later.

         UtlString remoteHostAddress;
         int remoteHostPort;
         msg->getSendAddress(&remoteHostAddress, &remoteHostPort);
         if (!mClientSocket->isSameHost(remoteHostAddress.data(), mLocalHostAddress.data()))
         {
           try
           {
             if (!remoteHostAddress.isNull())
             {
               boost::asio::ip::address remoteIp = boost::asio::ip::address::from_string(remoteHostAddress.data());

               if (rateLimit().isBannedAddress(remoteIp))
               {
                  delete msg;
                  readBuffer.remove(0);
                  continue;
               }

               rateLimit().logPacket(remoteIp, 0);
             }
           }
           catch(const std::exception& e)
           {
             Os::Logger::instance().log(FAC_SIP_INCOMING, PRI_CRIT, 
               "SipClient[%s]::run rate limit exception: %s",  mName.data(), e.what());
           }
         }


         // Note that input was processed at this time.
         touch();

         //
         // Count the CR/LF to see if this is a keep-alive
         //
         int crlfCount = 0;
         for (int i = 0; i < res; i++)
         {
           if (readBuffer(i) == '\r' || readBuffer(i) == '\n')
           {
             crlfCount++;
           } else
           {
             break;
           }
         }

         if (res == crlfCount)
         {
             repeatedEOFs = 0;
             // The 'message' was a keepalive (CR-LF or CR-LF-CR-LF).
             UtlString fromIpAddress;
             int fromPort;
             UtlString buffer;
             int bufferLen;

             // send one CRLF set in the reply
             buffer.append("\r\n");
             bufferLen = buffer.length();

             // Get the send address for response.
             msg->getSendAddress(&fromIpAddress, &fromPort);
             if ( !portIsValid(fromPort))
             {
                 fromPort = defaultPort();
             }

            // Log the message at DEBUG level.
            // Only bother processing if the logs are enabled
            if (   mpSipUserAgent->isMessageLoggingEnabled()
                   || Os::Logger::instance().willLog(FAC_SIP_INCOMING, PRI_DEBUG)
               )
            {
               UtlString logMessage;
               logMessage.append("Read keepalive message:\n");
               logMessage.append("----Local Host:");
               logMessage.append(mLocalHostAddress);
               logMessage.append("---- Port: ");
               logMessage.appendNumber(
                  portIsValid(mLocalHostPort) ? mLocalHostPort : defaultPort());
               logMessage.append("----\n");
               logMessage.append("----Remote Host:");
               logMessage.append(fromIpAddress);
               logMessage.append("---- Port: ");
               logMessage.appendNumber(
                  portIsValid(fromPort) ? fromPort : defaultPort());
               logMessage.append("----\n");

               logMessage.append(readBuffer.data(), res);
               UtlString messageString;
               logMessage.append(messageString);
               logMessage.append("====================END====================\n");

               // Don't bother to send the message to the SipUserAgent for its internal log.

               // Write the message to the syslog.
               Os::Logger::instance().log(FAC_SIP_INCOMING, PRI_DEBUG, "%s", logMessage.data());
            }

            // send the CR-LF response message
            switch (mSocketType)
            {
            case OsSocket::TCP:
            {
               Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                             "SipClient[%s]::run send TCP keep-alive CR-LF response, ",
                             mName.data());
               SipClientSendMsg sendMsg(OsMsg::OS_EVENT,
                                        SipClientSendMsg::SIP_CLIENT_SEND_KEEP_ALIVE,
                                        fromIpAddress,
                                        fromPort);
                handleMessage(sendMsg);     // add newly created keep-alive to write buffer
            }
               break;
            case OsSocket::UDP:
            {
                Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                              "SipClient[%s]::run send UDP keep-alive CR-LF response, ",
                              mName.data());
               (dynamic_cast <OsDatagramSocket*> (mClientSocket))->write(buffer.data(),
                                                                         bufferLen,
                                                                         fromIpAddress,
                                                                         fromPort);
            }
               break;
            default:
               break;
            }

            // Delete the SipMessage allocated above, which is no longer needed.
            delete msg;

            // Now that logging is done, remove the parsed bytes and
            // remember any unparsed input for later use.
            readBuffer.remove(0, res);
         }  // end keep-alive msg

         else if (res > 0)      // got message, but not keep-alive
         {
            // Message successfully read.
            repeatedEOFs = 0;

            // Do preliminary processing of message to log it,
            // clean up its data, and extract any needed source address.
            preprocessMessage(*msg, readBuffer, res);

            // Dispatch the message.
            // dispatch() takes ownership of *msg.
            mpSipUserAgent->dispatch(msg);

            // Now that logging is done, remove the parsed bytes and
            // remember any unparsed input for later use.
            readBuffer.remove(0, res);
         }  // end process read of >0 bytes
         else
         {
            // Something went wrong while reading the message.
            // (Possibly EOF on a connection-oriented socket.)
            repeatedEOFs++;

            // Delete the SipMessage allocated above, which is no longer needed.
            delete msg;
            Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                          "SipClient[%s]::run SipMessage::read returns %d (error(%d) or EOF), "
                          "readBuffer = '%.1000s'",
                          mName.data(), res, errno, readBuffer.data());

            Os::Logger::instance().log(FAC_SIP, PRI_DEBUG,
                          "SipClient[%s]::run error wait status  "
                          "tcpOnErrWaitForSend-%d waitingToReportErr-%d "
                          "mbTcpOnErrWaitForSend-%d repeatedEOFs-%d "
                          "protocol %d framed %d",
                          mName.data(),
                          tcpOnErrWaitForSend, waitingToReportErr,
                          mbTcpOnErrWaitForSend, repeatedEOFs,
                          mClientSocket->getIpProtocol(),
                          OsSocket::isFramed(mClientSocket->getIpProtocol()));

            // If the socket is not framed (is connection-oriented),
            // we need to abort the connection and post a message
            // :TODO: This doesn't work right for framed connection-oriented
            // protocols (like SCTP), but OsSocket doesn't have an EOF-query
            // method -- we need to close all connection-oriented
            // sockets as well in case it was an EOF.
            // Define a virtual function that returns the correct bit.
            if (!OsSocket::isFramed(mClientSocket->getIpProtocol()))
            {
                // On non-blocking connect failures, we need to get the first send message
                // in order to successfully trigger the protocol fallback mechanism
                if (!tcpOnErrWaitForSend)
                {
                   // Return all buffered messages with a transport error indication.
                   emptyBuffer(TRUE);
                   clientStopSelf();
                }
                else
                {
                   fds[1].revents &= ~(POLLERR | POLLHUP);  // clear error bit if waiting
                   waitingToReportErr = TRUE;
                }
            }
            // Delete the data read so far, which will not have been
            // deleted by HttpMessage::read.
            readBuffer.remove(0);
         }
      } // end POLLIN reading socket
   }
   while (isStarted());

   return 0;        // and then exit
}
예제 #22
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;
}
예제 #23
0
int SipSendCommand::execute(int argc, char* argv[])
{
        int commandStatus = CommandProcessor::COMMAND_FAILED;
        UtlString messageBuffer;
        char buffer[1025];
        int bufferSize = 1024;
        int charsRead;

        if(argc != 2 && argc != 3)
        {
                printf("Usage: %s %s", argv[0], UsageMsg);
        }

        else
        {
        int transactionCount = 1;
        if(argc == 3) transactionCount = atoi(argv[2]);

        FILE* sipMessageFile = fopen(argv[1], "r");
                if(sipMessageFile)
                {
                        //printf("opened file: \"%s\"\n", argv[1]);
                        do
                        {
                                charsRead = fread(buffer, 1, bufferSize, sipMessageFile);
                                if(charsRead > 0)
                                {
                                        messageBuffer.append(buffer, charsRead);
                                }
                        }
                        while(charsRead);
            fclose(sipMessageFile);

                        //printf("Read file contents:\n%s\n====END====\n", messageBuffer.data());
                        SipMessage message(messageBuffer.data());
            UtlString callId;
            message.getCallIdField(&callId);
            char callIdBuffer[500];
            OsTime start;
            OsDateTime::getCurTimeSinceBoot(start);
            int transactionIndex;
            for(transactionIndex = 0; transactionIndex < transactionCount;
            transactionIndex++)
            {
                            if(sipUserAgent->send(message))
                            {
                                    commandStatus = CommandProcessor::COMMAND_SUCCESS;
                            }
                            else
                            {
                                    printf("Failed to send SIP message");
                    break;
                            }
                sprintf(callIdBuffer, "%d-%s", transactionIndex + 1,
                    callId.data());
                message.setCallIdField(callIdBuffer);
            }
            OsTime finish;
            OsDateTime::getCurTimeSinceBoot(finish);
            OsTime lapse = finish - start;
            double seconds = lapse.seconds() +
                ((double) lapse.usecs())/1000000.0;
            double transPerSecond = ((double) transactionIndex) / seconds;
            printf("Transactions: %d Seconds: %f tps: %f spt: %f\n",
                transactionIndex, seconds, transPerSecond,
                1.0/transPerSecond);

                }
                else
                {
                        printf("send file: \"%s\" does not exist\n", argv[1]);
                        commandStatus = CommandProcessor::COMMAND_FAILED;
                }
        }

        return(commandStatus);
}
예제 #24
0
   void testMultipleInput()
      {
         // Table of test cases.
         struct test {
            int          numInputs;
            const char*  inputs[6];
            const char*  output;
         };
         struct test tests[] = {
            // Varying length strings of 0's.
            // 0
            { 2, { "", "" },
              "d41d8cd98f00b204e9800998ecf8427e" },
            // 1
            { 2, { "0", "" },
              "cfcd208495d565ef66e7dff9f98764da" },
            // 2
            { 2, { "0", "0" },
              "b4b147bc522828731f1a016bfa72c073" },
            // 3
            { 3, { "00", "0", "0" },
              "4a7d1ed414474e4033ac29ccb8653d9b" },
            // 4
            { 2, { "000", "00000" },
              "dd4b21e9ef71e1291183a46b913ae6f2" },
            // 5
            { 1, { "0000000000000000" },
              "1e4a1b03d1b6cd8a174a826f76e009f4" },
            // 6
            { 3, { "", "0000000", "0000000000000000000000000" },
              "cd9e459ea708a948d5c2f5a6ca8838cf" },
            // 7
            { 2, { "000000000000000", "0000000000000000000000000000000000000000000000000" },
              "10eab6008d5642cf42abd2aa41f847cb" },
            // 8
            { 1, { "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" },
              "aa70aaf67b3bab5029b76cee92e18afe" },
            // Varying length strings of the ASCII characters.
            // 8
            { 2, { " ", "" },
              "7215ee9c7d9dc229d2921a40e899ec5f" },
            // 9
            { 2, { " ", "!" },
              "220c1c252883eadad5590fc9e6a61739" },
            // 10
            { 2, { " !\"", "#" },
              "1a8bed44f8555d8318157f1e649a99b5" },
            // 11
            { 2, { " !\"#", "$%&'" },
              "04281adcae556d29c613104883b36133" },
            // 12
            { 2, { " ", "!\"#$%&'()*+,-./" },
              "35ba6d08f0e34c15b9d0b09998960eb6" },
            // 13
            { 2, { " !\"#$%&'()*+,-.", "/0123456789:;<=>?" },
              "bf61e899560fabde2f6d76f405a6eb70" },
            // 14
            { 2, { " !\"#$%&'()*+,-./0123456789:;<=>?@A", "BCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" },
              "c654a1965b312ddee3bd884e044a7658" },
            // 15
            { 2, { " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDE", "FGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ " },
              "6c16dd02a16a44568a8fd4b9bf2fdddd" },
            // Strings of length 65:  Since MD5 processes chars in blocks
            // of 64, this tests behavior across block boundaries.
            // 16
            { 2, { "00000000000000000000000000000000000000000000000000000000000000000", "00000000000000000000000000000000000000000000000000000000000000000" },
              "c7f6509e1fde3ebc0c246b98ca17ca53" },
            // 17
            { 1, { " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" },
              "bf35d3d5ee617924bbaabfef05b78d30" },
            // A couple of more normal strings.
            // 18
            { 5, { "john.salesman", ":", "sales/example.com", ":", "5+5=10" },
              "91ffcb1f8353fe113ccf7169ee27402e" },
            // 19
            { 1, { "GET:/private/prices.html" },
              "254bd53db6966fa1387fa1973bb5e53c" }
         };

         UtlString prefix("prefix/");
         bool allPassed=true;
         for (unsigned int testcase = 0;
              testcase < sizeof(tests) / sizeof(struct test);
              testcase++
              )
         {
            NetMd5Codec md5;
            NetMd5Codec md5sig;
            UtlString concatenatedInput;
            
            for (int input = 0; input < tests[testcase].numInputs; input++)
            {
               concatenatedInput.append(tests[testcase].inputs[input]);
               
               md5.hash(tests[testcase].inputs[input],
                        strlen(tests[testcase].inputs[input])
                        );
               md5sig.hash(tests[testcase].inputs[input],
                           strlen(tests[testcase].inputs[input])
                           );
            }
            UtlString actualOutputSegmented(prefix);
            md5.appendHashValue(actualOutputSegmented);

            UtlString prefixedOutputConcatenated(prefix);
            UtlString actualOutputConcatenated;
            NetMd5Codec::encode(concatenatedInput.data(), actualOutputConcatenated);
            prefixedOutputConcatenated.append(actualOutputConcatenated);
            
            if (actualOutputSegmented.compareTo(prefixedOutputConcatenated) != 0)
            {
               allPassed=false;
               OsSysLog::add(FAC_SIP, PRI_ERR,
                             "md5 multiple input test %d, segmented: %s\n  concatenated: %s",
                             testcase, actualOutputSegmented.data(), prefixedOutputConcatenated.data());
            }
            
            UtlString sigOutputSegmented(prefix);
            md5sig.appendBase64Sig(sigOutputSegmented);

            UtlString sigPrefixedOutputConcatenated(prefix);
            UtlString sigOutputConcatenated;
            NetMd5Codec::encodeBase64Sig(concatenatedInput.data(), sigOutputConcatenated);
            sigPrefixedOutputConcatenated.append(sigOutputConcatenated);
            
            if (sigOutputSegmented.compareTo(sigPrefixedOutputConcatenated) != 0)
            {
               allPassed=false;
               OsSysLog::add(FAC_SIP, PRI_ERR,
                             "md5 multiple input test %d, segmented: %s\n  concatenated: %s",
                             testcase, sigOutputSegmented.data(), sigPrefixedOutputConcatenated.data());
            }

            UtlString expectedOutput(prefix);
            expectedOutput.append(tests[testcase].output);
            
            if (actualOutputSegmented.compareTo(expectedOutput) != 0)
            {
               allPassed=false;
               OsSysLog::add(FAC_SIP, PRI_ERR,
                             "md5 multiple input test %d, expected: %s\n  received: %s",
                             testcase, actualOutputSegmented.data(), expectedOutput.data());
            }
         }
         
         CPPUNIT_ASSERT(allPassed);

         
      }
UtlBoolean SipPersistentSubscriptionMgr::updateDialogInfo(
   const SipMessage& subscribeRequest,
   UtlString& resourceId,
   UtlString& eventTypeKey,
   UtlString& eventType,
   UtlString& subscribeDialogHandle,
   UtlBoolean& isNew,
   UtlBoolean& isSubscriptionExpired,
   SipMessage& subscribeResponse,
   SipSubscribeServerEventHandler& handler)
{
   OsSysLog::add(FAC_SIP, PRI_DEBUG,
                 "SipPersistentSubscriptionMgr::updateDialogInfo "
                 "resourceId = '%s', eventTypeKey = '%s'",
                 resourceId.data(), eventTypeKey.data());

   UtlBoolean ret;

   // Call SipSubscriptionMgr to update the in-memory data.
   ret = SipSubscriptionMgr::updateDialogInfo(subscribeRequest,
                                              resourceId,
                                              eventTypeKey,
                                              eventType,
                                              subscribeDialogHandle,
                                              isNew,
                                              isSubscriptionExpired,
                                              subscribeResponse,
                                              handler);

   // If that succeeded, update the IMDB.
   if (ret)
   {
      UtlString requestUri;
      UtlString callId;
      UtlString contactEntry;
      UtlString to;
      UtlString from;
      UtlString route;
      UtlString accept;

      subscribeRequest.getRequestUri(&requestUri);
      subscribeRequest.getCallIdField(&callId);
      subscribeRequest.getContactEntry(0, &contactEntry);
      subscribeRequest.getToField(&to);
      subscribeRequest.getFromField(&from);
      subscribeRequest.buildRouteField(&route);
      accept.append(subscribeRequest.getHeaderValue(0, SIP_ACCEPT_FIELD));

      int expires = 0;
      subscribeResponse.getExpiresField(&expires);
      expires += OsDateTime::getSecsSinceEpoch();

      int subscribeCseq;
      UtlString subscribeCseqMethod;
      subscribeRequest.getCSeqField(&subscribeCseq, &subscribeCseqMethod);

      OsSysLog::add(FAC_SIP, PRI_DEBUG,
                    "SipPersistentSubscriptionMgr::updateDialogInfo "
                    "mComponent = '%s', requestUri = '%s', callId = '%s', contactEntry = '%s', expires = %d, to = '%s', from = '%s', key = '%s', route = '%s', accept = '%s'",
                    mComponent.data(), requestUri.data(),
                    callId.data(), contactEntry.data(), expires,
                    to.data(), from.data(), resourceId.data(), route.data(),
                    accept.data());

      // Attempt to update an existing row.
      int now = (int)OsDateTime::getSecsSinceEpoch();
      ret = mSubscriptionDBInstance->updateSubscribeUnexpiredSubscription(
         mComponent, to, from, callId, eventTypeKey, "",
         now, expires, subscribeCseq);
      
      if (!ret)
      {
         // Add a new row.

         // This call assumes that eventTypeKey is OK for use as the <eventtype>,
         // and that the NOTIFY CSeq's will start at 1.  0 is used as
         // the initial XML version.
         ret = mSubscriptionDBInstance->insertRow(
            mComponent, requestUri, callId, contactEntry,
            expires, subscribeCseq, eventTypeKey, "",
            to, from, resourceId, route, 1, accept, 0);

         if (!ret)
         {
            OsSysLog::add(FAC_SIP, PRI_ERR,
                          "SipPersistantSubscriptionMgr::addSubscription "
                          "Could not update or insert record in database");
         }
      }

      // Start the save timer.
      mPersistenceTimer.oneshotAfter(sPersistInterval);
   }

   return ret;
}
예제 #26
0
void sipxSubscribeClientSubCallback(SipSubscribeClient::SubscriptionState newState,
                                   const char* earlyDialogHandle,
                                   const char* dialogHandle,
                                   void* applicationData,
                                   int responseCode,
                                   const char* responseText,
                                   long expiration,
                                   const SipMessage* subscribeResponse)
{
    SIPX_SUB subscriptionHandle = (SIPX_SUB)applicationData;
    SIPX_SUBSCRIPTION_DATA* subscriptionData =
        (SIPX_SUBSCRIPTION_DATA*) gpSubHandleMap->findHandle(subscriptionHandle);

    if(subscriptionData && subscriptionData->pInst)
    {
        SIPX_SUBSTATUS_INFO pInfo;
        pInfo.nSize = sizeof(SIPX_SUBSTATUS_INFO);
        UtlString userAgent;
        if(subscribeResponse)
        {
            subscribeResponse->getUserAgentField(&userAgent);
        }
        pInfo.szSubServerUserAgent = userAgent;
        pInfo.hSub = subscriptionHandle;
        // TODO: Should probably set some cause codes based upon
        // the response code from the sip message
        pInfo.cause = SUBSCRIPTION_CAUSE_NORMAL;
        UtlString errorState;

        switch(newState)
        {
        case SipSubscribeClient::SUBSCRIPTION_INITIATED: // Early dialog
            pInfo.state = SIPX_SUBSCRIPTION_PENDING;
            break;

        case SipSubscribeClient::SUBSCRIPTION_SETUP:     // Established dialog
            pInfo.state = SIPX_SUBSCRIPTION_ACTIVE;
            break;

        case SipSubscribeClient::SUBSCRIPTION_TERMINATED:
            pInfo.state = SIPX_SUBSCRIPTION_EXPIRED;
            break;

        default:
            {
                pInfo.state = SIPX_SUBSCRIPTION_FAILED;
                errorState = "unknown: ";
                char numBuf[20];
                sprintf(numBuf, "%d", newState);
                errorState.append(numBuf);
            }
            break;
        }

        // If the dialog changed from and early dialog to an
        // established dialog, update the dialog handle in the
        // subcription data structure
        if(earlyDialogHandle && dialogHandle &&
            SipDialog::isEarlyDialog(*subscriptionData->pDialogHandle))
        {
            *(subscriptionData->pDialogHandle) = dialogHandle;
        }

        // Fire the event if it is a supported state change
        if(errorState.isNull())
        {
            sipxFireEvent(subscriptionData->pInst->pCallManager,
                       EVENT_CATEGORY_SUB_STATUS,
                       &pInfo);
        }
        else
        {
            OsSysLog::add(FAC_SIPXTAPI, PRI_ERR,
                "sipxSubscribeClientSubCallback: invalid SubscriptionState: %s",
                errorState.data());
        }
    }

    // Cannot find subsription data for this handle
    else
    {
        OsSysLog::add(FAC_SIPXTAPI, PRI_ERR,
            "sipxSubscribeClientSubCallback: cannot find subscription data for handle: %p",
            applicationData);
    }
}
예제 #27
0
int SipLSendCommand::execute(int argc, char* argv[])
{
        int commandStatus = CommandProcessor::COMMAND_FAILED;
        UtlString messageBuffer;
        char buffer[1025];
        int bufferSize = 1024;
        int charsRead;

        printf("send command with %d arguments\n", argc);
        if(argc != 5)
        {
                UtlString usage;
                getUsage(argv[0], &usage);
                printf("%s", usage.data());
        }

        else
        {
        UtlString protocol(argv[2]);
        protocol.toUpper();

        UtlString hostAddress(argv[3]);
        int hostPort = atoi(argv[4]);

        FILE* sipMessageFile = fopen(argv[1], "r");
                if(sipMessageFile && portIsValid(hostPort) && !hostAddress.isNull() &&
            (protocol.compareTo("TCP") == 0 || protocol.compareTo("UDP") == 0))
                {
                        //printf("opened file: \"%s\"\n", argv[1]);
                        do
                        {
                                charsRead = fread(buffer, 1, bufferSize, sipMessageFile);
                                if(charsRead > 0)
                                {
                                        messageBuffer.append(buffer, charsRead);
                                }
                        }
                        while(charsRead);
            fclose(sipMessageFile);

            OsSocket* writeSocket = NULL;
            if(protocol.compareTo("TCP") == 0)
                writeSocket = new OsConnectionSocket(hostPort ,hostAddress);
            else if(protocol.compareTo("UDP") == 0)
                writeSocket = new OsDatagramSocket(hostPort ,hostAddress);

                        //printf("Read file contents:\n%s\n====END====\n", messageBuffer.data());
                        //SipMessage message(messageBuffer.data());

            int bytesSent;
                        if((bytesSent = writeSocket->write(messageBuffer.data(),
                                                                                        messageBuffer.length())) > 0)
                        {
                                commandStatus = CommandProcessor::COMMAND_SUCCESS;
                        }
                        else
                        {
                                printf("Failed to send SIP message");
                        }
            printf("Send message with %d bytes\n", bytesSent);
                }
                else if(!sipMessageFile)
                {
                        printf("send file: \"%s\" does not exist\n", argv[1]);
                        commandStatus = CommandProcessor::COMMAND_FAILED;
                }
        else if (!portIsValid(hostPort))
        {
                        printf("Invalid destination port: %s\n", argv[4]);
                        commandStatus = CommandProcessor::COMMAND_FAILED;
                }
        else if(hostAddress.isNull())
        {
                        printf("Invalid destination address: %s\n", argv[3]);
                        commandStatus = CommandProcessor::COMMAND_FAILED;
                }
        else if(protocol.compareTo("TCP")  && protocol.compareTo("UDP"))
        {
                        printf("Invalid protocol: %s\n", argv[2]);
                        commandStatus = CommandProcessor::COMMAND_FAILED;
                }

        }

        return(commandStatus);
}
예제 #28
0
// Renders a string describing this decoder.
OsStatus StreamWAVFormatDecoder::toString(UtlString& string)
{
   string.append("WAV") ;

   return OS_SUCCESS ;
}
예제 #29
0
bool FileRpcReplaceFile::replicateFile(UtlString& path_and_name,
                                       UtlInt&    file_permissions,
                                       UtlString& file_content,
                                       UtlString& errorMsg
                                       )
{
   OsStatus rc;
   bool     result = false;
   errorMsg.remove(0);

   UtlString temporaryLocation(path_and_name);
   temporaryLocation += ".new";
   OsFile temporaryFile(temporaryLocation);

   // create a new file with the specified path and file name except with a .new extension.
   if (temporaryFile.open(OsFile::CREATE) == OS_SUCCESS)
   {
      UtlString     pdecodedData;
      size_t bytesRead;

      if ( !NetBase64Codec::decode( file_content, pdecodedData ))
      {
         // Write failed.
         errorMsg.append("Failed to decode file data from base64 for '");
         errorMsg.append(path_and_name);
         errorMsg.append("'");
         OsSysLog::add(FAC_SUPERVISOR, PRI_INFO, "FileRpcReplaceFile::replicateFile %s",
                       errorMsg.data());
      }
      else
      {
         rc = temporaryFile.write(pdecodedData.data(), pdecodedData.length(), bytesRead);
         temporaryFile.close();
         if (rc == OS_SUCCESS)
         {
            rc = temporaryFile.rename(path_and_name);
            if (rc == OS_SUCCESS)
            {
               int int_rc;
               OsSysLog::add(FAC_SUPERVISOR, PRI_INFO, "FileRpcReplaceFile::replicateFile"
                                   " updated file '%s'", path_and_name.data());
               rc = temporaryFile.remove(TRUE);

               // Change the permissions on the file as indicated.
               int_rc = chmod( path_and_name.data(), file_permissions.getValue() ); 
               result = true;
            }
            else
            {
               // Write succeeded, but rename failed.
               errorMsg.append("Failed to rename temporary file from '");
               errorMsg.append(temporaryLocation);
               errorMsg.append("' to '");
               errorMsg.append(path_and_name);
               errorMsg.append("'");
               OsSysLog::add(FAC_SUPERVISOR, PRI_INFO, "FileRpcReplaceFile::replicateFile %s",
                             errorMsg.data());
            }
         }
         else
         {
            // Write failed.
            errorMsg.append("Failed to write to temporary file '");
            errorMsg.append(temporaryLocation);
            errorMsg.append("'");
            OsSysLog::add(FAC_SUPERVISOR, PRI_INFO, "FileRpcReplaceFile::replicateFile %s",
                          errorMsg.data());
         }
      }
   }
   else
   {
      // Open failed.
      errorMsg.append("Failed to create temporary file '");
      errorMsg.append(temporaryLocation);
      errorMsg.append("'");
      OsSysLog::add(FAC_SUPERVISOR, PRI_INFO, "FileRpcReplaceFile::replicateFile %s",
                    errorMsg.data());
   }

   return result;
}
예제 #30
0
// get a description of the SipxProcessResource (for use in logging)
void SipxProcessResource::appendDescription(UtlString&  description /**< returned description */) const
{
   description.append("process '");
   description.append(data());
   description.append("'");
}