|
reSIProcate/DialogUsageManager
9694
|
00001 #ifdef HAVE_CONFIG_H 00002 #include "config.h" 00003 #endif 00004 00005 #include "resip/dum/DialogUsageManager.hxx" 00006 #include "resip/dum/ClientRegistration.hxx" 00007 #include "resip/dum/ClientInviteSession.hxx" 00008 #include "resip/dum/ServerInviteSession.hxx" 00009 #include "resip/dum/ClientAuthManager.hxx" 00010 00011 #include "resip/dum/RegistrationHandler.hxx" 00012 #include "resip/dum/InviteSessionHandler.hxx" 00013 #include "resip/dum/DumShutdownHandler.hxx" 00014 00015 #include "resip/dum/MasterProfile.hxx" 00016 #include "resip/stack/ShutdownMessage.hxx" 00017 00018 #include "resip/stack/SdpContents.hxx" 00019 #include "resip/stack/Pkcs7Contents.hxx" 00020 #include "resip/stack/MultipartSignedContents.hxx" 00021 #include "resip/stack/MultipartAlternativeContents.hxx" 00022 #include "resip/stack/Mime.hxx" 00023 00024 #include "resip/stack/SecurityAttributes.hxx" 00025 #include "resip/stack/Helper.hxx" 00026 00027 #include "rutil/FdPoll.hxx" 00028 #include "rutil/Log.hxx" 00029 #include "rutil/Logger.hxx" 00030 00031 #ifdef WIN32 00032 #include "resip/stack/ssl/WinSecurity.hxx" 00033 #else 00034 #include "resip/stack/ssl/Security.hxx" 00035 #endif 00036 00037 #include "TestDumHandlers.hxx" 00038 00039 #include <time.h> 00040 #include <sstream> 00041 00042 using namespace std; 00043 using namespace resip; 00044 00045 #define RESIPROCATE_SUBSYSTEM Subsystem::TEST 00046 00047 00048 class TestSMIMEInviteHandler : public TestClientRegistrationHandler, 00049 public TestInviteSessionHandler, 00050 public TestDumShutdownHandler 00051 { 00052 public: 00053 00054 TestSMIMEInviteHandler(Security *sec) : handles(0), security(sec), registered(0), done(0), dumShutDown(0), connected(0), callFailed(false) 00055 { 00056 } 00057 00058 virtual ~TestSMIMEInviteHandler() 00059 { 00060 } 00061 00062 void resetRegistered(void) 00063 { 00064 registered = 0; 00065 } 00066 00067 bool isConnected(void) 00068 { 00069 return (connected == 2); 00070 } 00071 00072 bool isDumShutDown(void) 00073 { 00074 return (dumShutDown == 2); 00075 } 00076 00077 bool isRegistered(void) 00078 { 00079 return (registered == 2); 00080 } 00081 00082 bool isDone(void) 00083 { 00084 return (done == 2); 00085 00086 } 00087 00088 bool isCallFailed(void) 00089 { 00090 return callFailed; 00091 } 00092 00093 SdpContents* generateBody() 00094 { 00095 Data* txt = new Data("v=0\r\n" 00096 "o=1900 369696545 369696545 IN IP4 192.168.2.15\r\n" 00097 "s=X-Lite\r\n" 00098 "c=IN IP4 192.168.2.15\r\n" 00099 "t=0 0\r\n" 00100 "m=audio 8000 RTP/AVP 8 3 101\r\n" 00101 "a=rtpmap:8 pcma/8000\r\n" 00102 "a=rtpmap:3 gsm/8000\r\n" 00103 "a=rtpmap:101 telephone-event/8000\r\n" 00104 "a=fmtp:101 0-15\r\n"); 00105 00106 HeaderFieldValue hfv(txt->data(), txt->size()); 00107 SdpContents *sdp = new SdpContents(hfv, Mime("application", "sdp")); 00108 return sdp; 00109 } 00110 00111 00112 virtual void onSuccess(ClientRegistrationHandle r, 00113 const SipMessage& response) 00114 { 00115 InfoLog( << "ClientRegistrationHandler::onSuccess" ); 00116 handles.push_back(r); 00117 registered++; 00118 } 00119 00120 virtual void onConnected(ClientInviteSessionHandle, 00121 const SipMessage& msg) 00122 { 00123 InfoLog( << "ClientInviteSessionHandler::onConnected" ); 00124 connected++; 00125 } 00126 00127 using TestClientRegistrationHandler::onFailure; 00128 virtual void onFailure(ClientInviteSessionHandle, 00129 const SipMessage& msg) 00130 { 00131 InfoLog( << "TestInviteSessionHander::onFailure" ); 00132 callFailed = true; 00133 } 00134 00135 using TestInviteSessionHandler::onNewSession; 00136 virtual void onNewSession(ServerInviteSessionHandle is, 00137 InviteSession::OfferAnswerType oat, 00138 const SipMessage& msg) 00139 { 00140 InfoLog( << "ServerInviteSessionHandler::onNewSession" ); 00141 sis = is; 00142 is->provisional(180); 00143 } 00144 00145 virtual void onConnected(InviteSessionHandle, 00146 const SipMessage& msg) 00147 { 00148 InfoLog( << "InviteSessionHandler::onConnected()" ); 00149 connected++; 00150 } 00151 00152 virtual void onTerminated(InviteSessionHandle, 00153 InviteSessionHandler::TerminatedReason reason, 00154 const SipMessage* msg) 00155 { 00156 InfoLog( << "InviteSessionHandler::onTerminated"); 00157 done++; 00158 } 00159 00160 virtual void onOffer(InviteSessionHandle is, 00161 const SipMessage& msg, 00162 const SdpContents& sdp) 00163 { 00164 InfoLog( << "InviteSessionHandler::onOffer" ); 00165 InfoLog( << "Server received SDP: " << sdp ); 00166 00167 const SecurityAttributes *attr = msg.getSecurityAttributes(); 00168 if (attr) 00169 { 00170 InfoLog( << *attr ); 00171 } 00172 else 00173 { 00174 InfoLog( << "no Security Attributes" ); 00175 } 00176 00177 if (sis.isValid()) 00178 { 00179 NameAddr fromAor(msg.header(h_From).uri()); 00180 NameAddr toAor(msg.header(h_To).uri()); 00181 is->provideAnswer(*generateBody()); 00182 sis->accept(); 00183 } 00184 } 00185 00186 virtual void onAnswer(InviteSessionHandle, 00187 const SipMessage& msg, 00188 const SdpContents& sdp) 00189 { 00190 InfoLog( << "InviteSessionHandler::onAnswer"); 00191 InfoLog( << "Client received SDP: " << sdp ); 00192 00193 const SecurityAttributes *attr = msg.getSecurityAttributes(); 00194 if (attr) 00195 { 00196 InfoLog( << *attr ); 00197 } 00198 else 00199 { 00200 InfoLog( << "no Security Attributes" ); 00201 } 00202 00203 } 00204 00205 virtual void onDumCanBeDeleted() 00206 { 00207 InfoLog( << "DumShutDownHandler::onDumCanBeDeleted" ); 00208 dumShutDown++; 00209 } 00210 00211 virtual void onReferNoSub(InviteSessionHandle, const SipMessage& msg) 00212 { 00213 InfoLog(<< "InviteSessionHandler::onReferNoSub(): " << msg.brief()); 00214 } 00215 00216 public: 00217 std::vector<ClientRegistrationHandle> handles; 00218 ServerInviteSessionHandle sis; 00219 00220 private: 00221 Security *security; 00222 int registered; 00223 int done; 00224 int dumShutDown; 00225 int connected; 00226 bool callFailed; 00227 00228 }; 00229 00230 00231 int 00232 main (int argc, char** argv) 00233 { 00234 if ( argc < 5 ) { 00235 cout << "usage: " << argv[0] << " sip:user1 passwd1 sip:user2 passwd2" << endl; 00236 return 1; 00237 } 00238 00239 Log::initialize(Log::Cout, Log::Debug, argv[0]); 00240 00241 NameAddr clientAor(argv[1]); 00242 Data clientPasswd(argv[2]); 00243 NameAddr serverAor(argv[3]); 00244 Data serverPasswd(argv[4]); 00245 00246 #ifdef WIN32 00247 Security* security = new WinSecurity; 00248 #else 00249 Security* security = new Security; 00250 #endif 00251 00252 TestSMIMEInviteHandler handler(security); 00253 00254 // Shared FdPollGrp 00255 std::auto_ptr<FdPollGrp> pollGrp(FdPollGrp::create()); 00256 00257 // set up UAC 00258 SipStack clientStack(security, 00259 DnsStub::EmptyNameserverList, 00260 0, 00261 false, 00262 0, 00263 0, 00264 pollGrp.get()); 00265 DialogUsageManager clientDum(clientStack); 00266 srand(time(NULL)); 00267 clientDum.addTransport(UDP, 0, V4); 00268 clientDum.addTransport(TCP, 0, V4); 00269 clientDum.addTransport(TLS, 0, V4); 00270 #ifdef USE_IPV6 00271 clientDum.addTransport(UDP, 0, V6); 00272 clientDum.addTransport(TCP, 0, V6); 00273 clientDum.addTransport(TLS, 0, V6); 00274 #endif 00275 00276 SharedPtr<MasterProfile> clientProfile(new MasterProfile); 00277 auto_ptr<ClientAuthManager> clientAuth(new ClientAuthManager()); 00278 00279 clientDum.setClientAuthManager(clientAuth); 00280 clientDum.setClientRegistrationHandler(&handler); 00281 clientDum.setInviteSessionHandler(&handler); 00282 00283 clientProfile->setDefaultFrom(clientAor); 00284 clientProfile->setDigestCredential(clientAor.uri().host(),clientAor.uri().user(),clientPasswd); 00285 clientProfile->setDefaultRegistrationTime(60); 00286 clientProfile->addSupportedMethod(INVITE); 00287 clientProfile->addSupportedMimeType(INVITE, Mime("application", "pkcs7-mime")); 00288 clientProfile->addSupportedMimeType(INVITE, Mime("multipart", "signed")); 00289 clientProfile->addSupportedMimeType(INVITE, Mime("multipart", "alternative")); 00290 clientDum.setMasterProfile(clientProfile); 00291 00292 //set up UAS 00293 SipStack serverStack(security, 00294 DnsStub::EmptyNameserverList, 00295 0, 00296 false, 00297 0, 00298 0, 00299 pollGrp.get()); 00300 DialogUsageManager serverDum(serverStack); 00301 //serverDum.addTransport(UDP, 0, V4); 00302 serverDum.addTransport(TCP, 0, V4); 00303 //serverDum.addTransport(TLS, 0, V4); 00304 00305 SharedPtr<MasterProfile> serverProfile(new MasterProfile); 00306 std::auto_ptr<ClientAuthManager> serverAuth(new ClientAuthManager); 00307 00308 serverDum.setClientAuthManager(serverAuth); 00309 serverDum.setClientRegistrationHandler(&handler); 00310 serverDum.setInviteSessionHandler(&handler); 00311 00312 serverProfile->setDefaultFrom(serverAor); 00313 serverProfile->setDigestCredential(serverAor.uri().host(),serverAor.uri().user(),serverPasswd); 00314 serverProfile->setDefaultRegistrationTime(60); 00315 serverProfile->addSupportedMethod(INVITE); 00316 serverProfile->addSupportedMimeType(INVITE, Mime("application", "pkcs7-mime")); 00317 serverProfile->addSupportedMimeType(INVITE, Mime("multipart", "signed")); 00318 serverProfile->addSupportedMimeType(INVITE, Mime("multipart", "alternative")); 00319 serverDum.setMasterProfile(serverProfile); 00320 00321 enum 00322 { 00323 Registering, 00324 Inviting, 00325 Waiting, 00326 HangingUp, 00327 Unregistering, 00328 ShuttingDown, 00329 Finished 00330 } state; 00331 time_t endTime=0; 00332 00333 // register client and server 00334 SharedPtr<SipMessage> clientRegMessage = clientDum.makeRegistration(clientAor); 00335 clientDum.send(clientRegMessage); 00336 SharedPtr<SipMessage> serverRegMessage = serverDum.makeRegistration(serverAor); 00337 serverDum.send(serverRegMessage); 00338 state = Registering; 00339 00340 while (state != Finished) 00341 { 00342 // This waits on IO for both stacks; this is the canonical way to drive 00343 // multiple stacks with the same thread. We could make two calls to 00344 // process(), but this requires more calls to epoll_wait/select. 00345 pollGrp->waitAndProcess(resipMin(clientStack.getTimeTillNextProcessMS(), 00346 serverStack.getTimeTillNextProcessMS())); 00347 clientStack.processTimers(); 00348 serverStack.processTimers(); 00349 00350 while(clientDum.process() || serverDum.process()); 00351 00352 switch (state) 00353 { 00354 case Registering: 00355 { 00356 if (handler.isRegistered()) 00357 { 00358 InfoLog( << "Sending INVITE request" ); 00359 clientDum.send(clientDum.makeInviteSession(serverAor, 00360 handler.generateBody())); 00361 state = Inviting; 00362 } 00363 break; 00364 } 00365 00366 case Inviting: 00367 { 00368 if (handler.isConnected()) 00369 { 00370 InfoLog( << "Starting timer, waiting for 5 seconds" ); 00371 endTime = time(NULL) + 5; 00372 state = Waiting; 00373 } 00374 break; 00375 } 00376 00377 case Waiting: 00378 { 00379 if (handler.isCallFailed()) 00380 { 00381 InfoLog( << "Call Failed" ); 00382 for (std::vector<ClientRegistrationHandle>::iterator it = handler.handles.begin(); 00383 it != handler.handles.end(); it++) 00384 { 00385 (*it)->end(); 00386 } 00387 state = Unregistering; 00388 } 00389 00390 if (time(NULL) > endTime) 00391 { 00392 InfoLog( << "Timer expired, hanging up" ); 00393 handler.sis->end(); 00394 state = HangingUp; 00395 } 00396 break; 00397 } 00398 00399 case HangingUp: 00400 { 00401 if (handler.isDone()) 00402 { 00403 for (std::vector<ClientRegistrationHandle>::iterator it = handler.handles.begin(); 00404 it != handler.handles.end(); it++) 00405 { 00406 (*it)->end(); 00407 } 00408 state = Unregistering; 00409 } 00410 break; 00411 } 00412 00413 case Unregistering: 00414 { 00415 if (handler.isRegistered()) 00416 { 00417 InfoLog( << "Shutting down" ); 00418 serverDum.shutdown(&handler); 00419 clientDum.shutdown(&handler); 00420 state = ShuttingDown; 00421 } 00422 break; 00423 } 00424 00425 case ShuttingDown: 00426 { 00427 if (handler.isDumShutDown()) 00428 { 00429 InfoLog( << "Finished" ); 00430 state = Finished; 00431 } 00432 00433 break; 00434 } 00435 00436 default: 00437 { 00438 InfoLog( << "Unrecognised state" ); 00439 assert(0); 00440 } 00441 } 00442 00443 } 00444 00445 return 0; 00446 00447 } 00448 00449 /* ==================================================================== 00450 * The Vovida Software License, Version 1.0 00451 * 00452 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00453 * 00454 * Redistribution and use in source and binary forms, with or without 00455 * modification, are permitted provided that the following conditions 00456 * are met: 00457 * 00458 * 1. Redistributions of source code must retain the above copyright 00459 * notice, this list of conditions and the following disclaimer. 00460 * 00461 * 2. Redistributions in binary form must reproduce the above copyright 00462 * notice, this list of conditions and the following disclaimer in 00463 * the documentation and/or other materials provided with the 00464 * distribution. 00465 * 00466 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00467 * and "Vovida Open Communication Application Library (VOCAL)" must 00468 * not be used to endorse or promote products derived from this 00469 * software without prior written permission. For written 00470 * permission, please contact vocal@vovida.org. 00471 * 00472 * 4. Products derived from this software may not be called "VOCAL", nor 00473 * may "VOCAL" appear in their name, without prior written 00474 * permission of Vovida Networks, Inc. 00475 * 00476 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00477 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00478 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00479 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00480 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00481 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00482 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00483 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00484 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00485 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00486 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00487 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00488 * DAMAGE. 00489 * 00490 * ==================================================================== 00491 * 00492 * This software consists of voluntary contributions made by Vovida 00493 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00494 * Inc. For more information on Vovida Networks, Inc., please see 00495 * <http://www.vovida.org/>. 00496 * 00497 */
1.7.5.1