1 |
#include "resip/dum/DialogUsageManager.hxx" |
2 |
#include "resip/dum/ClientRegistration.hxx" |
3 |
#include "resip/dum/ClientInviteSession.hxx" |
4 |
#include "resip/dum/ServerInviteSession.hxx" |
5 |
#include "resip/dum/ClientAuthManager.hxx" |
6 |
|
7 |
#include "resip/dum/RegistrationHandler.hxx" |
8 |
#include "resip/dum/InviteSessionHandler.hxx" |
9 |
#include "resip/dum/DumShutdownHandler.hxx" |
10 |
|
11 |
#include "resip/dum/MasterProfile.hxx" |
12 |
#include "resip/stack/ShutdownMessage.hxx" |
13 |
|
14 |
#include "resip/stack/SdpContents.hxx" |
15 |
#include "resip/stack/Pkcs7Contents.hxx" |
16 |
#include "resip/stack/MultipartSignedContents.hxx" |
17 |
#include "resip/stack/MultipartAlternativeContents.hxx" |
18 |
#include "resip/stack/Mime.hxx" |
19 |
|
20 |
#include "resip/stack/SecurityAttributes.hxx" |
21 |
#include "resip/stack/Helper.hxx" |
22 |
|
23 |
#include "rutil/Log.hxx" |
24 |
#include "rutil/Logger.hxx" |
25 |
|
26 |
#ifdef WIN32 |
27 |
#include "resip/stack/WinSecurity.hxx" |
28 |
#endif |
29 |
|
30 |
#include "TestDumHandlers.hxx" |
31 |
|
32 |
#include <time.h> |
33 |
#include <sstream> |
34 |
|
35 |
using namespace std; |
36 |
using namespace resip; |
37 |
|
38 |
#define RESIPROCATE_SUBSYSTEM Subsystem::TEST |
39 |
|
40 |
|
41 |
class TestSMIMEInviteHandler : public TestClientRegistrationHandler, |
42 |
public TestInviteSessionHandler, |
43 |
public TestDumShutdownHandler |
44 |
{ |
45 |
public: |
46 |
|
47 |
TestSMIMEInviteHandler(Security *sec) : handles(0), security(sec), registered(0), done(0), dumShutDown(0), connected(0), callFailed(false) |
48 |
{ |
49 |
} |
50 |
|
51 |
virtual ~TestSMIMEInviteHandler() |
52 |
{ |
53 |
} |
54 |
|
55 |
void resetRegistered(void) |
56 |
{ |
57 |
registered = 0; |
58 |
} |
59 |
|
60 |
bool isConnected(void) |
61 |
{ |
62 |
return (connected == 2); |
63 |
} |
64 |
|
65 |
bool isDumShutDown(void) |
66 |
{ |
67 |
return (dumShutDown == 2); |
68 |
} |
69 |
|
70 |
bool isRegistered(void) |
71 |
{ |
72 |
return (registered == 2); |
73 |
} |
74 |
|
75 |
bool isDone(void) |
76 |
{ |
77 |
return (done == 2); |
78 |
|
79 |
} |
80 |
|
81 |
bool isCallFailed(void) |
82 |
{ |
83 |
return callFailed; |
84 |
} |
85 |
|
86 |
SdpContents* generateBody() |
87 |
{ |
88 |
HeaderFieldValue* hfv; |
89 |
Data* txt = new Data("v=0\r\n" |
90 |
"o=1900 369696545 369696545 IN IP4 192.168.2.15\r\n" |
91 |
"s=X-Lite\r\n" |
92 |
"c=IN IP4 192.168.2.15\r\n" |
93 |
"t=0 0\r\n" |
94 |
"m=audio 8000 RTP/AVP 8 3 101\r\n" |
95 |
"a=rtpmap:8 pcma/8000\r\n" |
96 |
"a=rtpmap:3 gsm/8000\r\n" |
97 |
"a=rtpmap:101 telephone-event/8000\r\n" |
98 |
"a=fmtp:101 0-15\r\n"); |
99 |
|
100 |
hfv = new HeaderFieldValue(txt->data(), txt->size()); |
101 |
SdpContents *sdp = new SdpContents(hfv, Mime("application", "sdp")); |
102 |
return sdp; |
103 |
} |
104 |
|
105 |
|
106 |
virtual void onSuccess(ClientRegistrationHandle r, |
107 |
const SipMessage& response) |
108 |
{ |
109 |
InfoLog( << "ClientRegistrationHandler::onSuccess" ); |
110 |
handles.push_back(r); |
111 |
registered++; |
112 |
} |
113 |
|
114 |
virtual void onConnected(ClientInviteSessionHandle, |
115 |
const SipMessage& msg) |
116 |
{ |
117 |
InfoLog( << "ClientInviteSessionHandler::onConnected" ); |
118 |
connected++; |
119 |
} |
120 |
|
121 |
virtual void onFailure(ClientInviteSessionHandle, |
122 |
const SipMessage& msg) |
123 |
{ |
124 |
InfoLog( << "TestInviteSessionHander::onFailure" ); |
125 |
callFailed = true; |
126 |
} |
127 |
|
128 |
virtual void onNewSession(ServerInviteSessionHandle is, |
129 |
InviteSession::OfferAnswerType oat, |
130 |
const SipMessage& msg) |
131 |
{ |
132 |
InfoLog( << "ServerInviteSessionHandler::onNewSession" ); |
133 |
sis = is; |
134 |
is->provisional(180); |
135 |
} |
136 |
|
137 |
virtual void onConnected(InviteSessionHandle, |
138 |
const SipMessage& msg) |
139 |
{ |
140 |
InfoLog( << "InviteSessionHandler::onConnected()" ); |
141 |
connected++; |
142 |
} |
143 |
|
144 |
virtual void onTerminated(InviteSessionHandle, |
145 |
InviteSessionHandler::TerminatedReason reason, |
146 |
const SipMessage* msg) |
147 |
{ |
148 |
InfoLog( << "InviteSessionHandler::onTerminated"); |
149 |
done++; |
150 |
} |
151 |
|
152 |
virtual void onOffer(InviteSessionHandle is, |
153 |
const SipMessage& msg, |
154 |
const SdpContents& sdp) |
155 |
{ |
156 |
InfoLog( << "InviteSessionHandler::onOffer" ); |
157 |
InfoLog( << "Server received SDP: " << sdp ); |
158 |
|
159 |
const SecurityAttributes *attr = msg.getSecurityAttributes(); |
160 |
if (attr) |
161 |
{ |
162 |
InfoLog( << *attr ); |
163 |
} |
164 |
else |
165 |
{ |
166 |
InfoLog( << "no Security Attributes" ); |
167 |
} |
168 |
|
169 |
if (sis.isValid()) |
170 |
{ |
171 |
NameAddr fromAor(msg.header(h_From).uri()); |
172 |
NameAddr toAor(msg.header(h_To).uri()); |
173 |
is->provideAnswer(*generateBody()); |
174 |
sis->accept(); |
175 |
} |
176 |
} |
177 |
|
178 |
virtual void onAnswer(InviteSessionHandle, |
179 |
const SipMessage& msg, |
180 |
const SdpContents& sdp) |
181 |
{ |
182 |
InfoLog( << "InviteSessionHandler::onAnswer"); |
183 |
InfoLog( << "Client received SDP: " << sdp ); |
184 |
|
185 |
const SecurityAttributes *attr = msg.getSecurityAttributes(); |
186 |
if (attr) |
187 |
{ |
188 |
InfoLog( << *attr ); |
189 |
} |
190 |
else |
191 |
{ |
192 |
InfoLog( << "no Security Attributes" ); |
193 |
} |
194 |
|
195 |
} |
196 |
|
197 |
virtual void onDumCanBeDeleted() |
198 |
{ |
199 |
InfoLog( << "DumShutDownHandler::onDumCanBeDeleted" ); |
200 |
dumShutDown++; |
201 |
} |
202 |
|
203 |
virtual void onReferNoSub(InviteSessionHandle, const SipMessage& msg) |
204 |
{ |
205 |
InfoLog(<< "InviteSessionHandler::onReferNoSub(): " << msg.brief()); |
206 |
} |
207 |
|
208 |
public: |
209 |
std::vector<ClientRegistrationHandle> handles; |
210 |
ServerInviteSessionHandle sis; |
211 |
|
212 |
private: |
213 |
Security *security; |
214 |
int registered; |
215 |
int done; |
216 |
int dumShutDown; |
217 |
int connected; |
218 |
bool callFailed; |
219 |
|
220 |
}; |
221 |
|
222 |
|
223 |
int |
224 |
main (int argc, char** argv) |
225 |
{ |
226 |
if ( argc < 5 ) { |
227 |
cout << "usage: " << argv[0] << " sip:user1 passwd1 sip:user2 passwd2" << endl; |
228 |
return 1; |
229 |
} |
230 |
|
231 |
Log::initialize(Log::Cout, Log::Debug, argv[0]); |
232 |
|
233 |
NameAddr clientAor(argv[1]); |
234 |
Data clientPasswd(argv[2]); |
235 |
NameAddr serverAor(argv[3]); |
236 |
Data serverPasswd(argv[4]); |
237 |
|
238 |
#ifdef WIN32 |
239 |
Security* security = new WinSecurity; |
240 |
#else |
241 |
Security* security = new Security; |
242 |
#endif |
243 |
|
244 |
TestSMIMEInviteHandler handler(security); |
245 |
|
246 |
// set up UAC |
247 |
SipStack clientStack(security); |
248 |
DialogUsageManager clientDum(clientStack); |
249 |
srand(time(NULL)); |
250 |
clientDum.addTransport(UDP, 10000 + rand()&0x7fff, V4); |
251 |
clientDum.addTransport(TCP, 10000 + rand()&0x7fff, V4); |
252 |
clientDum.addTransport(TLS, 10000 + rand()&0x7fff, V4); |
253 |
#ifdef USE_IPV6 |
254 |
clientDum.addTransport(UDP, 10000 + rand()&0x7fff, V6); |
255 |
clientDum.addTransport(TCP, 10000 + rand()&0x7fff, V6); |
256 |
clientDum.addTransport(TLS, 10000 + rand()&0x7fff, V6); |
257 |
#endif |
258 |
|
259 |
SharedPtr<MasterProfile> clientProfile(new MasterProfile); |
260 |
auto_ptr<ClientAuthManager> clientAuth(new ClientAuthManager()); |
261 |
|
262 |
clientDum.setClientAuthManager(clientAuth); |
263 |
clientDum.setClientRegistrationHandler(&handler); |
264 |
clientDum.setInviteSessionHandler(&handler); |
265 |
|
266 |
clientProfile->setDefaultFrom(clientAor); |
267 |
clientProfile->setDigestCredential(clientAor.uri().host(),clientAor.uri().user(),clientPasswd); |
268 |
clientProfile->setDefaultRegistrationTime(60); |
269 |
clientProfile->addSupportedMethod(INVITE); |
270 |
clientProfile->addSupportedMimeType(INVITE, Mime("application", "pkcs7-mime")); |
271 |
clientProfile->addSupportedMimeType(INVITE, Mime("multipart", "signed")); |
272 |
clientProfile->addSupportedMimeType(INVITE, Mime("multipart", "alternative")); |
273 |
clientDum.setMasterProfile(clientProfile); |
274 |
|
275 |
//set up UAS |
276 |
SipStack serverStack(security); |
277 |
DialogUsageManager serverDum(serverStack); |
278 |
//serverDum.addTransport(UDP, 10000 + rand()&0x7fff, V4); |
279 |
serverDum.addTransport(TCP, 10000 + rand()&0x7fff, V4); |
280 |
//serverDum.addTransport(TLS, 10000 + rand()&0x7fff, V4); |
281 |
|
282 |
SharedPtr<MasterProfile> serverProfile(new MasterProfile); |
283 |
std::auto_ptr<ClientAuthManager> serverAuth(new ClientAuthManager); |
284 |
|
285 |
serverDum.setClientAuthManager(serverAuth); |
286 |
serverDum.setClientRegistrationHandler(&handler); |
287 |
serverDum.setInviteSessionHandler(&handler); |
288 |
|
289 |
serverProfile->setDefaultFrom(serverAor); |
290 |
serverProfile->setDigestCredential(serverAor.uri().host(),serverAor.uri().user(),serverPasswd); |
291 |
serverProfile->setDefaultRegistrationTime(60); |
292 |
serverProfile->addSupportedMethod(INVITE); |
293 |
serverProfile->addSupportedMimeType(INVITE, Mime("application", "pkcs7-mime")); |
294 |
serverProfile->addSupportedMimeType(INVITE, Mime("multipart", "signed")); |
295 |
serverProfile->addSupportedMimeType(INVITE, Mime("multipart", "alternative")); |
296 |
serverDum.setMasterProfile(serverProfile); |
297 |
|
298 |
enum |
299 |
{ |
300 |
Registering, |
301 |
Inviting, |
302 |
Waiting, |
303 |
HangingUp, |
304 |
Unregistering, |
305 |
ShuttingDown, |
306 |
Finished |
307 |
} state; |
308 |
time_t endTime; |
309 |
|
310 |
// register client and server |
311 |
SharedPtr<SipMessage> clientRegMessage = clientDum.makeRegistration(clientAor); |
312 |
clientDum.send(clientRegMessage); |
313 |
SharedPtr<SipMessage> serverRegMessage = serverDum.makeRegistration(serverAor); |
314 |
serverDum.send(serverRegMessage); |
315 |
state = Registering; |
316 |
|
317 |
while (state != Finished) |
318 |
{ |
319 |
FdSet fdset; |
320 |
|
321 |
clientStack.buildFdSet(fdset); |
322 |
serverStack.buildFdSet(fdset); |
323 |
|
324 |
int err = fdset.selectMilliSeconds(resipMin((int)clientStack.getTimeTillNextProcessMS(), 50)); |
325 |
assert ( err != -1 ); |
326 |
|
327 |
clientStack.process(fdset); |
328 |
serverStack.process(fdset); |
329 |
while(clientDum.process() || serverDum.process()); |
330 |
|
331 |
switch (state) |
332 |
{ |
333 |
case Registering: |
334 |
{ |
335 |
if (handler.isRegistered()) |
336 |
{ |
337 |
InfoLog( << "Sending INVITE request" ); |
338 |
clientDum.send(clientDum.makeInviteSession(serverAor, |
339 |
handler.generateBody())); |
340 |
state = Inviting; |
341 |
} |
342 |
break; |
343 |
} |
344 |
|
345 |
case Inviting: |
346 |
{ |
347 |
if (handler.isConnected()) |
348 |
{ |
349 |
InfoLog( << "Starting timer, waiting for 5 seconds" ); |
350 |
endTime = time(NULL) + 5; |
351 |
state = Waiting; |
352 |
} |
353 |
break; |
354 |
} |
355 |
|
356 |
case Waiting: |
357 |
{ |
358 |
if (handler.isCallFailed()) |
359 |
{ |
360 |
InfoLog( << "Call Failed" ); |
361 |
for (std::vector<ClientRegistrationHandle>::iterator it = handler.handles.begin(); |
362 |
it != handler.handles.end(); it++) |
363 |
{ |
364 |
(*it)->end(); |
365 |
} |
366 |
state = Unregistering; |
367 |
} |
368 |
|
369 |
if (time(NULL) > endTime) |
370 |
{ |
371 |
InfoLog( << "Timer expired, hanging up" ); |
372 |
handler.sis->end(); |
373 |
state = HangingUp; |
374 |
} |
375 |
break; |
376 |
} |
377 |
|
378 |
case HangingUp: |
379 |
{ |
380 |
if (handler.isDone()) |
381 |
{ |
382 |
for (std::vector<ClientRegistrationHandle>::iterator it = handler.handles.begin(); |
383 |
it != handler.handles.end(); it++) |
384 |
{ |
385 |
(*it)->end(); |
386 |
} |
387 |
state = Unregistering; |
388 |
} |
389 |
break; |
390 |
} |
391 |
|
392 |
case Unregistering: |
393 |
{ |
394 |
if (handler.isRegistered()) |
395 |
{ |
396 |
InfoLog( << "Shutting down" ); |
397 |
serverDum.shutdown(&handler); |
398 |
clientDum.shutdown(&handler); |
399 |
state = ShuttingDown; |
400 |
} |
401 |
break; |
402 |
} |
403 |
|
404 |
case ShuttingDown: |
405 |
{ |
406 |
if (handler.isDumShutDown()) |
407 |
{ |
408 |
InfoLog( << "Finished" ); |
409 |
state = Finished; |
410 |
} |
411 |
|
412 |
break; |
413 |
} |
414 |
|
415 |
default: |
416 |
{ |
417 |
InfoLog( << "Unrecognised state" ); |
418 |
assert(0); |
419 |
} |
420 |
} |
421 |
|
422 |
} |
423 |
|
424 |
return 0; |
425 |
|
426 |
} |
427 |
|
428 |
/* ==================================================================== |
429 |
* The Vovida Software License, Version 1.0 |
430 |
* |
431 |
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. |
432 |
* |
433 |
* Redistribution and use in source and binary forms, with or without |
434 |
* modification, are permitted provided that the following conditions |
435 |
* are met: |
436 |
* |
437 |
* 1. Redistributions of source code must retain the above copyright |
438 |
* notice, this list of conditions and the following disclaimer. |
439 |
* |
440 |
* 2. Redistributions in binary form must reproduce the above copyright |
441 |
* notice, this list of conditions and the following disclaimer in |
442 |
* the documentation and/or other materials provided with the |
443 |
* distribution. |
444 |
* |
445 |
* 3. The names "VOCAL", "Vovida Open Communication Application Library", |
446 |
* and "Vovida Open Communication Application Library (VOCAL)" must |
447 |
* not be used to endorse or promote products derived from this |
448 |
* software without prior written permission. For written |
449 |
* permission, please contact vocal@vovida.org. |
450 |
* |
451 |
* 4. Products derived from this software may not be called "VOCAL", nor |
452 |
* may "VOCAL" appear in their name, without prior written |
453 |
* permission of Vovida Networks, Inc. |
454 |
* |
455 |
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED |
456 |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
457 |
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND |
458 |
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA |
459 |
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES |
460 |
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, |
461 |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
462 |
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
463 |
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
464 |
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
465 |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE |
466 |
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
467 |
* DAMAGE. |
468 |
* |
469 |
* ==================================================================== |
470 |
* |
471 |
* This software consists of voluntary contributions made by Vovida |
472 |
* Networks, Inc. and many individuals on behalf of Vovida Networks, |
473 |
* Inc. For more information on Vovida Networks, Inc., please see |
474 |
* <http://www.vovida.org/>. |
475 |
* |
476 |
*/ |