|
reSIProcate/repro
9694
|
00001 #include <cassert> 00002 #include <sstream> 00003 00004 #include <resip/stack/Symbols.hxx> 00005 #include <resip/stack/Tuple.hxx> 00006 #include <rutil/Data.hxx> 00007 #include <rutil/DnsUtil.hxx> 00008 #include <rutil/Logger.hxx> 00009 #include <rutil/ParseBuffer.hxx> 00010 #include <rutil/Socket.hxx> 00011 #include <rutil/TransportType.hxx> 00012 #include <rutil/Timer.hxx> 00013 00014 #include "repro/XmlRpcServerBase.hxx" 00015 #include "repro/XmlRpcConnection.hxx" 00016 #include "repro/RegSyncServer.hxx" 00017 00018 using namespace repro; 00019 using namespace resip; 00020 using namespace std; 00021 00022 #define RESIPROCATE_SUBSYSTEM Subsystem::REPRO 00023 00024 00025 RegSyncServer::RegSyncServer(resip::InMemorySyncRegDb* regDb, 00026 int port, 00027 IpVersion version) : 00028 XmlRpcServerBase(port, version), 00029 mRegDb(regDb) 00030 { 00031 assert(mRegDb); 00032 mRegDb->setHandler(this); 00033 } 00034 00035 RegSyncServer::~RegSyncServer() 00036 { 00037 mRegDb->setHandler(0); 00038 } 00039 00040 void 00041 RegSyncServer::sendResponse(unsigned int connectionId, 00042 unsigned int requestId, 00043 const Data& responseData, 00044 unsigned int resultCode, 00045 const Data& resultText) 00046 { 00047 std::stringstream ss; 00048 ss << Symbols::CRLF << responseData << " <Result Code=\"" << resultCode << "\""; 00049 ss << ">" << resultText.xmlCharDataEncode() << "</Result>" << Symbols::CRLF; 00050 XmlRpcServerBase::sendResponse(connectionId, requestId, ss.str().c_str(), resultCode >= 200 /* isFinal */); 00051 } 00052 00053 void 00054 RegSyncServer::sendRegistrationModifiedEvent(unsigned int connectionId, const resip::Uri& aor) 00055 { 00056 ContactList contacts; 00057 00058 mRegDb->getContacts(aor, contacts); 00059 sendRegistrationModifiedEvent(connectionId, aor, contacts); 00060 } 00061 00062 void 00063 RegSyncServer::sendRegistrationModifiedEvent(unsigned int connectionId, const resip::Uri& aor, const ContactList& contacts) 00064 { 00065 std::stringstream ss; 00066 bool infoFound = false; 00067 00068 ss << "<reginfo>" << Symbols::CRLF; 00069 ss << " <aor>" << Data::from(aor).xmlCharDataEncode() << "</aor>" << Symbols::CRLF; 00070 ContactList::const_iterator cit = contacts.begin(); 00071 for(; cit != contacts.end(); cit++) 00072 { 00073 const ContactInstanceRecord& rec = *cit; 00074 if(!rec.mReceivedFrom.onlyUseExistingConnection) 00075 { 00076 streamContactInstanceRecord(ss, rec); 00077 infoFound = true; 00078 } 00079 } 00080 ss << "</reginfo>" << Symbols::CRLF; 00081 00082 if(infoFound) 00083 { 00084 sendEvent(connectionId, ss.str().c_str()); 00085 } 00086 } 00087 00088 void 00089 RegSyncServer::handleRequest(unsigned int connectionId, unsigned int requestId, const resip::Data& request) 00090 { 00091 DebugLog (<< "RegSyncServer::handleRequest: connectionId=" << connectionId << ", requestId=" << requestId << ", request=" << request); 00092 00093 try 00094 { 00095 ParseBuffer pb(request); 00096 XMLCursor xml(pb); 00097 00098 if(isEqualNoCase(xml.getTag(), "InitialSync")) 00099 { 00100 handleInitialSyncRequest(connectionId, requestId, xml); 00101 } 00102 else 00103 { 00104 WarningLog(<< "RegSyncServer::handleRequest: Received XML message with unknown method: " << xml.getTag()); 00105 sendResponse(connectionId, requestId, Data::Empty, 400, "Unknown method"); 00106 } 00107 } 00108 catch(resip::BaseException& e) 00109 { 00110 WarningLog(<< "RegSyncServer::handleRequest: ParseException: " << e); 00111 sendResponse(connectionId, requestId, Data::Empty, 400, "Parse error"); 00112 } 00113 } 00114 00115 void 00116 RegSyncServer::handleInitialSyncRequest(unsigned int connectionId, unsigned int requestId, XMLCursor& xml) 00117 { 00118 InfoLog(<< "RegSyncServer::handleInitialSyncRequest"); 00119 00120 // Check for correct Version 00121 unsigned int version = 0; 00122 if(xml.firstChild()) 00123 { 00124 if(isEqualNoCase(xml.getTag(), "request")) 00125 { 00126 if(xml.firstChild()) 00127 { 00128 if(isEqualNoCase(xml.getTag(), "version")) 00129 { 00130 if(xml.firstChild()) 00131 { 00132 version = xml.getValue().convertUnsignedLong(); 00133 xml.parent(); 00134 } 00135 } 00136 xml.parent(); 00137 } 00138 } 00139 xml.parent(); 00140 } 00141 00142 if(version == REGSYNC_VERSION) 00143 { 00144 mRegDb->initialSync(connectionId); 00145 sendResponse(connectionId, requestId, Data::Empty, 200, "Initial Sync Completed."); 00146 } 00147 else 00148 { 00149 sendResponse(connectionId, requestId, Data::Empty, 505, "Version not supported."); 00150 } 00151 } 00152 00153 void 00154 RegSyncServer::streamContactInstanceRecord(std::stringstream& ss, const ContactInstanceRecord& rec) 00155 { 00156 UInt64 now = Timer::getTimeSecs(); 00157 00158 ss << " <contactinfo>" << Symbols::CRLF; 00159 ss << " <contacturi>" << Data::from(rec.mContact.uri()).xmlCharDataEncode() << "</contacturi>" << Symbols::CRLF; 00160 // If contact is expired or removed, then pass expires time as 0, otherwise send number of seconds until expirey 00161 ss << " <expires>" << (((rec.mRegExpires == 0) || (rec.mRegExpires <= now)) ? 0 : (rec.mRegExpires-now)) << "</expires>" << Symbols::CRLF; 00162 ss << " <lastupdate>" << now-rec.mLastUpdated << "</lastupdate>" << Symbols::CRLF; 00163 if(rec.mReceivedFrom.getPort() != 0) 00164 { 00165 resip::Data binaryFlowToken; 00166 Tuple::writeBinaryToken(rec.mReceivedFrom,binaryFlowToken); 00167 ss << " <receivedfrom>" << binaryFlowToken.base64encode() << "</receivedfrom>" << Symbols::CRLF; 00168 } 00169 if(rec.mPublicAddress.getType() != UNKNOWN_TRANSPORT) 00170 { 00171 resip::Data binaryFlowToken; 00172 Tuple::writeBinaryToken(rec.mPublicAddress,binaryFlowToken); 00173 ss << " <publicaddress>" << binaryFlowToken.base64encode() << "</publicaddress>" << Symbols::CRLF; 00174 } 00175 NameAddrs::const_iterator naIt = rec.mSipPath.begin(); 00176 for(; naIt != rec.mSipPath.end(); naIt++) 00177 { 00178 ss << " <sippath>" << Data::from(naIt->uri()).xmlCharDataEncode() << "</sippath>" << Symbols::CRLF; 00179 } 00180 if(!rec.mInstance.empty()) 00181 { 00182 ss << " <instance>" << rec.mInstance.xmlCharDataEncode() << "</instance>" << Symbols::CRLF; 00183 } 00184 if(rec.mRegId != 0) 00185 { 00186 ss << " <regid>" << rec.mRegId << "</regid>" << Symbols::CRLF; 00187 } 00188 ss << " </contactinfo>" << Symbols::CRLF; 00189 } 00190 00191 void 00192 RegSyncServer::onAorModified(const resip::Uri& aor, const ContactList& contacts) 00193 { 00194 sendRegistrationModifiedEvent(0, aor, contacts); 00195 } 00196 00197 void 00198 RegSyncServer::onInitialSyncAor(unsigned int connectionId, const resip::Uri& aor, const ContactList& contacts) 00199 { 00200 sendRegistrationModifiedEvent(connectionId, aor, contacts); 00201 } 00202 00203 /* ==================================================================== 00204 * The Vovida Software License, Version 1.0 00205 * 00206 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00207 * Copyright (c) 2010 SIP Spectrum, Inc. All rights reserved. 00208 * 00209 * Redistribution and use in source and binary forms, with or without 00210 * modification, are permitted provided that the following conditions 00211 * are met: 00212 * 00213 * 1. Redistributions of source code must retain the above copyright 00214 * notice, this list of conditions and the following disclaimer. 00215 * 00216 * 2. Redistributions in binary form must reproduce the above copyright 00217 * notice, this list of conditions and the following disclaimer in 00218 * the documentation and/or other materials provided with the 00219 * distribution. 00220 * 00221 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00222 * and "Vovida Open Communication Application Library (VOCAL)" must 00223 * not be used to endorse or promote products derived from this 00224 * software without prior written permission. For written 00225 * permission, please contact vocal@vovida.org. 00226 * 00227 * 4. Products derived from this software may not be called "VOCAL", nor 00228 * may "VOCAL" appear in their name, without prior written 00229 * permission of Vovida Networks, Inc. 00230 * 00231 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00232 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00233 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00234 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00235 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00236 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00237 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00238 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00239 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00240 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00241 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00242 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00243 * DAMAGE. 00244 * 00245 * ==================================================================== 00246 * 00247 * This software consists of voluntary contributions made by Vovida 00248 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00249 * Inc. For more information on Vovida Networks, Inc., please see 00250 * <http://www.vovida.org/>. 00251 * 00252 */
1.7.5.1