void testSupportedAndRequiredFields() { SipUserAgent sipUA( 5090, 5090, 5091, NULL, NULL, // default publicAddress and defaultUser "127.0.0.1" ); // Supported CPPUNIT_ASSERT( ! sipUA.isExtensionAllowed( "nope" ) ); UtlString supported( "supported-1" ); sipUA.allowExtension( supported ); UtlString tmp; sipUA.getSupportedExtensions( tmp ); CPPUNIT_ASSERT( supported == tmp ); supported.toUpper(); CPPUNIT_ASSERT( sipUA.isExtensionAllowed( supported ) ); CPPUNIT_ASSERT( ! sipUA.isExtensionAllowed( "nope" ) ); // Required CPPUNIT_ASSERT( ! sipUA.isExtensionRequired( "nope" ) ); UtlString required( "required-1, required-2, required-3" ); UtlString copy_required( required ); copy_required += ','; ssize_t prev = 0; ssize_t index = copy_required.index( ',', prev ); while( UTL_NOT_FOUND != index ) { UtlString field = copy_required( prev, index - prev ); field.strip( UtlString::both ); sipUA.requireExtension( field ); prev = index + 1; index = copy_required.index( ',', prev ); } sipUA.getRequiredExtensions( tmp ); CPPUNIT_ASSERT( required == tmp ); index = copy_required.index( ',', prev ); while( UTL_NOT_FOUND != index ) { UtlString field = copy_required( prev, index - prev ); field.strip( UtlString::both ); field.toUpper(); CPPUNIT_ASSERT( sipUA.isExtensionRequired( field ) ); prev = index + 1; index = copy_required.index( ',', prev ); } CPPUNIT_ASSERT( ! sipUA.isExtensionRequired( "nope" ) ); }
OsStatus ForwardRules::getRouteTo(UtlString& RouteToString, bool& authRequired, TiXmlNode* nodeWithRouteToChild) { OsStatus currentStatus = OS_FAILED; nodeWithRouteToChild->ToElement(); TiXmlNode* routeToNode = NULL; TiXmlNode* routeToText = NULL; //get the user text value from it routeToNode = nodeWithRouteToChild->FirstChild(XML_TAG_ROUTETO); if(routeToNode) { if(routeToNode && routeToNode->Type() != TiXmlNode::ELEMENT) { return currentStatus; } TiXmlElement* routeToElement = routeToNode->ToElement(); const char* authRequiredPtr = routeToElement->Attribute(XML_ATT_AUTHREQUIRED); //set the authRequired attribute authRequired=getYN(authRequiredPtr, false) ; //defaults to false RouteToString.remove(0); routeToText = routeToElement->FirstChild(); if(routeToText && routeToText->Type() == TiXmlNode::TEXT) { TiXmlText* routeTo = routeToText->ToText(); if (routeTo) { RouteToString.append(routeTo->Value()); } } // TinyXML compresses white space, so an all white space element becomes // zero length, but just in case, let's strip it ourselves. RouteToString.strip(UtlString::both); if (RouteToString.length() > 0) { // The route is not empty. Declare success currentStatus = OS_SUCCESS; } else if (authRequired) { // The Route can be empty, as long as authRequired is set. // This means just route to the authProxy. currentStatus = OS_SUCCESS; } else { // Empty or missing route, and no authRequired...that's not allowed. currentStatus = OS_FAILED; } } return currentStatus; }
void Url::getDisplayName(UtlString& displayName) const { displayName = mDisplayName; if (isDigitString(mDisplayName.data())) { displayName.strip(UtlString::both, '\"'); } }
void writeBranchId(int outputFileDescriptor, UtlString& branchId) { branchId.strip(UtlString::both); UtlString node("\t\t\t<branchId>"); node.append(branchId); node.append("</branchId>\n"); write(outputFileDescriptor, node.data(), node.length()); }
DirectoryResource* DirectoryResourceManager::findFilename(const char* fullName ///< full path to a file ) { OsPath fullFileName(fullName); UtlString dirName = fullFileName.getDirName(); UtlString fileName; fileName.append(fullName, dirName.length(), UtlString::UTLSTRING_TO_END); dirName.strip(UtlString::trailing, OsPath::separator[0]); DirectoryResource* found = NULL; Os::Logger::instance().log(FAC_SUPERVISOR, PRI_DEBUG, "DirectoryResourceManager::findFilename: path '%s' file '%s'", dirName.data(), fileName.data()); { OsLock tableMutex(mDirectoryResourceTableLock); UtlSListIterator directories(mDirectoryResourceTable); DirectoryResource* dir; while (!found && (dir = dynamic_cast<DirectoryResource*>(directories.findNext(&dirName)))) { if ( dir->matches(fileName) ) { found = dir; } } } if (found) { UtlString matched; found->appendDescription(matched); Os::Logger::instance().log(FAC_SUPERVISOR, PRI_DEBUG, "DirectoryResourceManager::findFilename: '%s' matches %s", fullName, matched.data()); } else { Os::Logger::instance().log(FAC_SUPERVISOR, PRI_WARNING, "DirectoryResourceManager::findFilename: no match found for '%s'", fullName); } return found; }
UtlBoolean SipRegistrar::handleMessage( OsMsg& eventMessage ) { UtlBoolean handled = FALSE; int msgType = eventMessage.getMsgType(); int msgSubType = eventMessage.getMsgSubType(); if ( (msgType == OsMsg::PHONE_APP) && (msgSubType == SipMessage::NET_SIP_MESSAGE) ) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipRegistrar::handleMessage()" " Start processing SIP message") ; const SipMessage* message = ((SipMessageEvent&)eventMessage).getMessage(); UtlString callId; if ( message ) { message->getCallIdField(&callId); UtlString method; message->getRequestMethod(&method); if ( !message->isResponse() ) // is a request ? { if ( method.compareTo(SIP_REGISTER_METHOD) == 0 ) { //send to Register Thread sendToRegistrarServer(eventMessage); } else if ( method.compareTo(SIP_OPTIONS_METHOD) == 0 ) { UtlString requestUri; message->getRequestUri(&requestUri); // Check if the OPTIONS request URI is addressed to a user or // to the domain. if (!requestUri.contains("@")) { UtlString contentEncoding; message->getContentEncodingField(&contentEncoding); UtlString disallowedExtensions; int extensionIndex = 0; UtlString extension; disallowedExtensions.remove(0); while(message->getRequireExtension(extensionIndex, &extension)) { if(!(mSipUserAgent->isExtensionAllowed(extension.data())) ) { if(!disallowedExtensions.isNull()) { disallowedExtensions.append(SIP_MULTIFIELD_SEPARATOR); disallowedExtensions.append(SIP_SINGLE_SPACE); } disallowedExtensions.append(extension.data()); } extensionIndex++; } //delete leading and trailing white spaces disallowedExtensions = disallowedExtensions.strip(UtlString::both); SipMessage response; // Check if the extensions are supported if(!disallowedExtensions.isNull() ) { // error response - bad extension response.setRequestBadExtension(message, disallowedExtensions); } // Check if the encoding is supported // i.e. no encoding else if(!contentEncoding.isNull()) { // error response - content encoding response.setRequestBadContentEncoding(message,""); } else { // Send an OK, the allowed field will get added to all final responses. // Options 200 response response.setResponseData(message, SIP_OK_CODE, SIP_OK_TEXT); } mSipUserAgent->send(response); } else { //OPTIONS is addressed to a user, send to redirect thread sendToRedirectServer(eventMessage); } } else { //send to redirect thread sendToRedirectServer(eventMessage); } } else { // responses are ignored. } } else { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipRegistrar::handleMessage no message." ) ; } handled = TRUE; } else if ( OsMsg::OS_SHUTDOWN == msgType ) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipRegistrar::handleMessage shutting down all tasks"); // Do an orderly shutdown of all the various threads. if ( mSipUserAgent ) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipRegistrar::handleMessage shutting down SipUserAgent"); mSipUserAgent->shutdown(); delete mSipUserAgent ; mSipUserAgent = NULL ; } if ( mRegistrarPersist ) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipRegistrar::handleMessage shutting down RegistrarPersist"); mRegistrarPersist->requestShutdown(); delete mRegistrarPersist; mRegistrarPersist = NULL; } if ( mRedirectServer ) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipRegistrar::handleMessage shutting down RedirectServer"); mRedirectServer->requestShutdown(); delete mRedirectServer; mRedirectServer = NULL; mRedirectMsgQ = NULL; } if ( mRegistrarServer ) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipRegistrar::handleMessage shutting down RegistrarServer"); mRegistrarServer->requestShutdown(); delete mRegistrarServer; mRegistrarServer = NULL; mRegistrarMsgQ = NULL; } if ( mRegisterEventServer ) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipRegistrar::handleMessage shutting down RegisterEventServer"); delete mRegisterEventServer; mRegisterEventServer = NULL; } OsTask::requestShutdown(); // tell OsServerTask::run to exit handled = TRUE; } else { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "SipRegistrar::handleMessage unhandled type %d/%d", msgType, msgSubType ) ; } return handled; }
UtlBoolean DialByNameDB::getDigitStrings ( const UtlString& displayName, UtlSList& rDTMFStrings ) const { UtlString lowerString = displayName; lowerString.toLower(); lowerString = lowerString.strip(UtlString::both, '"'); UtlTokenizer next( lowerString ); UtlString token; UtlSList names; // Parse the Display name into a list of names // The algorithm for breaking up the string is as follows // if the string has > 2 tokens (forget about , separators) // create multiple entries in the IMDB for the all combinations // so for example // John Peter Smith Jr would result in DTMF entries for // PeterSmithJrJohn, SmithJrJohnPeter and JrJohnPeterSmith // @JC Added - separator for MIT's Avery-Smith example while (next.next(token, "\t\n,- ")) { names.insert ( new UtlString ( token ) ); } size_t numNames = names.entries(); if ( numNames > 0 ) { UtlString reorderedString; unsigned int splitPosition = 1; do { unsigned int i; UtlString firstNames; for ( i=0; i<splitPosition; i++ ) { firstNames += *(UtlString*)names.at(i); } UtlString lastNames; for ( i = splitPosition; i<numNames; i++) { lastNames += *(UtlString*)names.at(i); } // add the new string reorderedString = lastNames + firstNames; unsigned int len = reorderedString.length(); // calculate thd DTMF digits for the display name // firstly strip all , 's and spaces UtlString digitString; for ( i = 0; i<len; i++ ) { int offset = (int) ( reorderedString(i) - 'a' ); // filter out white space and comma separators if ( (offset >= 0) && (offset < 26) ) digitString += digitmap[ offset ]; } rDTMFStrings.insert ( new UtlString (digitString) ); splitPosition++; } while ( splitPosition<numNames ); } // call the desctuctors on all the temp strings names.destroyAll(); return TRUE; }
void writeBranchNodeData(int outputFileDescriptor, UtlString& time, UtlString& source, UtlString& destination, UtlString& sourceAddress, UtlString& destinationAddress, UtlString& transactionId, UtlString& frameId, UtlString& method, UtlString& responseCode, UtlString& responseText, UtlString& message) { time.strip(UtlString::both); source.strip(UtlString::both); destination.strip(UtlString::both); sourceAddress.strip(UtlString::both); destinationAddress.strip(UtlString::both); transactionId.strip(UtlString::both); frameId.strip(UtlString::both); method.strip(UtlString::both); responseCode.strip(UtlString::both); responseText.strip(UtlString::both); //message.strip(UtlString::both); UtlString node("\t\t<time>"); node.append(time); node.append("</time>\n"); if(!source.isNull()) { node.append("\t\t<source>"); node.append(source); node.append("</source>\n"); } if(!destination.isNull()) { node.append("\t\t<destination>"); node.append(destination); node.append("</destination>\n"); } node.append("\t\t<sourceAddress>"); node.append(sourceAddress); node.append("</sourceAddress>\n"); node.append("\t\t<destinationAddress>"); node.append(destinationAddress); node.append("</destinationAddress>\n"); node.append("\t\t<transactionId>"); node.append(transactionId); node.append("</transactionId>\n"); if(!method.isNull()) { node.append("\t\t<method>"); node.append(method); node.append("</method>\n"); } else { node.append("\t\t<responseCode>"); node.append(responseCode); node.append("</responseCode>\n"); node.append("\t\t<responseText>"); node.append(responseText); node.append("</responseText>\n"); } node.append("\t\t<frameId>"); node.append(frameId); node.append("</frameId>\n"); node.append("\t\t<message><![CDATA["); node.append(message); node.append("]]></message>\n"); write(outputFileDescriptor, node.data(), node.length()); }
void SipRedirectorGateway::processForm(const HttpRequestContext& requestContext, const HttpMessage& request, HttpMessage*& response) { UtlString string_get("get"); UtlString string_set("set"); UtlString string_prefix("prefix"); UtlString string_destination("destination"); OsSysLog::add(FAC_SIP, PRI_DEBUG, "%s::processForm entered", mLogName.data()); UtlString* user; // Process the request. // Get the body of the request. const HttpBody* request_body = request.getBody(); OsSysLog::add(FAC_SIP, PRI_DEBUG, "%s::processForm A *** request body is '%s'", mLogName.data(), request_body->getBytes()); // Get the values from the form. if (request_body->isMultipart()) { // Extract the values from the form data. UtlHashMap values; int c = request_body->getMultipartCount(); for (int i = 0; i < c; i++) { UtlString* name = new UtlString; if (request_body->getMultipart(i)->getPartHeaderValue("name", *name)) { const char* v; int l; request_body->getMultipartBytes(i, &v, &l); // Strip leading and trailing whitespace from values. UtlString* value = new UtlString(v, l); value->strip(UtlString::both); OsSysLog::add(FAC_SIP, PRI_CRIT, "%s::processForm " "form value '%s' = '%s'", mLogName.data(), name->data(), value->data()); // 'name' and 'value' are now owned by 'values'. values.insertKeyAndValue(name, value); } else { // 'name' is not owned by 'values' and we have to delete it. delete name; } } if (values.findValue(&string_get)) { // This is a "get gateway" request. // Insert the HTML into the response. HttpBody* response_body = new HttpBody(form, -1, CONTENT_TYPE_TEXT_HTML); response->setBody(response_body); } else if (values.findValue(&string_set)) { // This is a "set gateway" request. // Validate the routing prefix. UtlString* prefix = dynamic_cast <UtlString*> (values.findValue(&string_prefix)); if (prefixIsValid(*prefix)) { // Validate the destination. UtlString* destination = dynamic_cast <UtlString*> (values.findValue(&string_destination)); if (destination_is_valid(destination)) { OsSysLog::add(FAC_SIP, PRI_CRIT, "%s::processForm " "add mapping '%s' -> '%s'", mLogName.data(), prefix->data(), destination->data()); mMapLock.acquire(); // Insert the mapping. mMapUserToContacts.insertKeyAndValue(prefix, destination); mMapContactsToUser.insertKeyAndValue(destination, prefix); mMapLock.release(); writeMappings(); } } // Insert the HTML into the response. HttpBody* response_body = new HttpBody(form, -1, CONTENT_TYPE_TEXT_HTML); response->setBody(response_body); } else { // Incomprehensible request. // Insert the HTML into the response. HttpBody* response_body = new HttpBody(form, -1, CONTENT_TYPE_TEXT_HTML); response->setBody(response_body); } } else { // Incomprehensible request. // Insert the default HTML into the response. HttpBody* response_body = new HttpBody(form, -1, CONTENT_TYPE_TEXT_HTML); response->setBody(response_body); } #if 0 #if 0 // This is quite a chore, because getMultipartBytes gets the entire // multipart section, including the trailing delimiter, rather than just // the body, which is what we need. const char* value; int length; request_body->getMultipartBytes(0, &value, &length); #if 0 OsSysLog::add(FAC_SIP, PRI_DEBUG, "%s::processForm A *** seeing '%.*s'", mLogName.data(), length, value); #endif // Advance 'value' over the first \r\n\r\n, which ends the headers. const char* s = strstr(value, "\r\n\r\n"); if (s) { s += 4; // Allow for length of \r\n\r\n. length -= s - value; value = s; } OsSysLog::add(FAC_SIP, PRI_DEBUG, "%s::processForm B *** seeing '%.*s'", mLogName.data(), length, value); #if 0 // Search backward for the last \r, excepting the one in the second-to-last // position, which marks the end of the contents. if (length >= 3) { for (s = value + length - 3; !(s == value || *s == '\r'); s--) { /* empty */ } length = s - value; } OsSysLog::add(FAC_SIP, PRI_DEBUG, "%s::processForm seeing '%.*s'", mLogName.data(), length, value); #endif // Add the mappings. const char* error_msg; int error_location; UtlBoolean success = addMappings(value, length, user, error_msg, error_location); // Construct the response. response = new HttpMessage(); // Send 200 OK reply. response->setResponseFirstHeaderLine(HTTP_PROTOCOL_VERSION, HTTP_OK_CODE, HTTP_OK_TEXT); // Construct the HTML. char buffer1[100]; #if 0 OsSysLog::add(FAC_SIP, PRI_DEBUG, "%s::processForm *** domain '%s'", mLogName.data(), Gatewayredirector->mDomainName.data()); #endif if (success) { OsSysLog::add(FAC_SIP, PRI_DEBUG, "%s::processForm success user '%s'", mLogName.data(), user->data()); sprintf(buffer1, "<code>sip:<font size=\"+1\">%s</font>@%s:65070</code> redirects to:<br />", user->data(), Gatewayredirector->mDomainName.data()); } else { OsSysLog::add(FAC_SIP, PRI_DEBUG, "%s::processForm failure error_msg '%s', error_location %d", mLogName.data(), error_msg, error_location); strcpy(buffer1, "<i>Error:</i>"); } // Transcribe the input value into buffer2. char buffer2[FORM_SIZE]; char* p; int i; if (success) { // An impossible location. error_location = -1; } for (p = buffer2, i = 0; ; i++) { // If this is the error location, insert the error message. if (i == error_location) { *p++ = '!'; *p++ = '-'; *p++ = '-'; strcpy(p, error_msg); p += strlen(error_msg); *p++ = '-'; *p++ = '-'; *p++ = '!'; } // Test for ending the loop after testing to insert the error message, // because the error message may be after the last character. if (i >= length) { break; } switch (value[i]) { case '<': *p++ = '&'; *p++ = 'l'; *p++ = 't'; *p++ = ';'; break; case '>': *p++ = '&'; *p++ = 'g'; *p++ = 't'; *p++ = ';'; break; case '&': *p++ = '&'; *p++ = 'a'; *p++ = 'm'; *p++ = 'p'; *p++ = ';'; break; default: *p++ = value[i]; break; } } *p++ = '\0'; #endif #endif }