1 |
jason |
2725 |
#include "resiprocate/SipMessage.hxx" |
2 |
jason |
2846 |
#include "resiprocate/SdpContents.hxx" |
3 |
jason |
2725 |
#include "resiprocate/dum/Dialog.hxx" |
4 |
|
|
#include "resiprocate/dum/DialogUsageManager.hxx" |
5 |
|
|
#include "resiprocate/dum/InviteSession.hxx" |
6 |
jason |
2846 |
#include "resiprocate/dum/InviteSessionHandler.hxx" |
7 |
derek |
2961 |
#include "resiprocate/dum/UsageUseException.hxx" |
8 |
jason |
2856 |
#include "resiprocate/os/Logger.hxx" |
9 |
jason |
2555 |
|
10 |
jason |
2856 |
#define RESIPROCATE_SUBSYSTEM Subsystem::DUM |
11 |
jason |
2846 |
|
12 |
davidb |
2603 |
using namespace resip; |
13 |
|
|
|
14 |
derek |
2990 |
unsigned long |
15 |
|
|
InviteSession::T1 = 500; |
16 |
|
|
|
17 |
|
|
unsigned long |
18 |
|
|
InviteSession::T2 = 8 * T1; |
19 |
|
|
|
20 |
|
|
unsigned long |
21 |
|
|
InviteSession::TimerH = 64 * T1; |
22 |
|
|
|
23 |
derek |
2976 |
InviteSession::InviteSession(DialogUsageManager& dum, Dialog& dialog, State initialState) |
24 |
davidb |
2603 |
: BaseUsage(dum, dialog), |
25 |
derek |
2976 |
mState(initialState), |
26 |
jason |
2846 |
mOfferState(Nothing), |
27 |
jason |
2725 |
mCurrentLocalSdp(0), |
28 |
|
|
mCurrentRemoteSdp(0), |
29 |
|
|
mProposedLocalSdp(0), |
30 |
derek |
2965 |
mProposedRemoteSdp(0), |
31 |
derek |
2990 |
mNextOfferOrAnswerSdp(0), |
32 |
|
|
mCurrentRetransmit200(0) |
33 |
|
|
|
34 |
jason |
2555 |
{ |
35 |
derek |
3006 |
InfoLog ( << "^^^ InviteSession::InviteSession " << this); |
36 |
jason |
2846 |
assert(mDum.mInviteSessionHandler); |
37 |
jason |
2555 |
} |
38 |
|
|
|
39 |
derek |
2858 |
InviteSession::~InviteSession() |
40 |
|
|
{ |
41 |
derek |
3006 |
InfoLog ( << "^^^ InviteSession::~InviteSession " << this); |
42 |
derek |
2965 |
delete mCurrentLocalSdp; |
43 |
|
|
delete mCurrentRemoteSdp; |
44 |
|
|
delete mProposedLocalSdp; |
45 |
|
|
delete mProposedRemoteSdp; |
46 |
|
|
delete mNextOfferOrAnswerSdp; |
47 |
derek |
2858 |
mDialog.mInviteSession = 0; |
48 |
|
|
} |
49 |
jason |
2846 |
|
50 |
jason |
2866 |
void |
51 |
|
|
InviteSession::setOffer(const SdpContents* sdp) |
52 |
|
|
{ |
53 |
derek |
2965 |
if (mProposedRemoteSdp) |
54 |
|
|
{ |
55 |
|
|
throw UsageUseException("Cannot set an offer with an oustanding remote offer", __FILE__, __LINE__); |
56 |
|
|
} |
57 |
|
|
mNextOfferOrAnswerSdp = static_cast<SdpContents*>(sdp->clone()); |
58 |
jason |
2866 |
} |
59 |
|
|
|
60 |
|
|
void |
61 |
|
|
InviteSession::setAnswer(const SdpContents* sdp) |
62 |
|
|
{ |
63 |
derek |
2965 |
if (mProposedLocalSdp ) |
64 |
|
|
{ |
65 |
|
|
throw UsageUseException("Cannot set an answer with an oustanding offer", __FILE__, __LINE__); |
66 |
|
|
} |
67 |
|
|
mNextOfferOrAnswerSdp = static_cast<SdpContents*>(sdp->clone()); |
68 |
jason |
2866 |
} |
69 |
|
|
|
70 |
jason |
2555 |
const SdpContents* |
71 |
|
|
InviteSession::getLocalSdp() |
72 |
|
|
{ |
73 |
jason |
2725 |
return mCurrentLocalSdp; |
74 |
jason |
2555 |
} |
75 |
|
|
|
76 |
|
|
const SdpContents* |
77 |
|
|
InviteSession::getRemoteSdp() |
78 |
|
|
{ |
79 |
jason |
2725 |
return mCurrentRemoteSdp; |
80 |
jason |
2555 |
} |
81 |
davidb |
2575 |
|
82 |
jason |
2941 |
InviteSessionHandle |
83 |
|
|
InviteSession::getSessionHandle() |
84 |
|
|
{ |
85 |
|
|
return InviteSessionHandle(mDum, getBaseHandle().getId()); |
86 |
|
|
} |
87 |
|
|
|
88 |
derek |
2990 |
|
89 |
jason |
2856 |
void |
90 |
derek |
2990 |
InviteSession::dispatch(const DumTimeout& timeout) |
91 |
|
|
{ |
92 |
|
|
if (timeout.type() == DumTimeout::Retransmit200 && mState == Accepting) |
93 |
|
|
{ |
94 |
derek |
3001 |
mDum.send(mFinalResponse); |
95 |
derek |
2990 |
mDum.addTimer(DumTimeout::Retransmit200, resipMin(T2, mCurrentRetransmit200*2), getBaseHandle(), 0); |
96 |
|
|
} |
97 |
|
|
else if (timeout.type() == DumTimeout::WaitForAck && mState != Connected) |
98 |
|
|
{ |
99 |
|
|
mDialog.makeResponse(mLastResponse, mLastRequest, 408); |
100 |
|
|
mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), mLastResponse); |
101 |
|
|
delete this; |
102 |
|
|
} |
103 |
|
|
} |
104 |
|
|
|
105 |
|
|
void |
106 |
jason |
2856 |
InviteSession::dispatch(const SipMessage& msg) |
107 |
|
|
{ |
108 |
|
|
std::pair<OfferAnswerType, const SdpContents*> offans; |
109 |
|
|
offans = InviteSession::getOfferOrAnswer(msg); |
110 |
|
|
|
111 |
derek |
2961 |
switch(mState) |
112 |
jason |
2856 |
{ |
113 |
derek |
2961 |
case Terminated: |
114 |
derek |
2978 |
//!dcm! -- 481 behaviour here, should pretty much die on anything |
115 |
derek |
2997 |
//eventually 200 to BYE could be handled further out |
116 |
|
|
if (msg.isResponse()) |
117 |
derek |
2961 |
{ |
118 |
derek |
2997 |
int code = msg.header(h_StatusLine).statusCode(); |
119 |
|
|
if ((code == 200 && msg.header(h_CSeq).method() == BYE) || code > 399) |
120 |
|
|
{ |
121 |
|
|
mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), msg); |
122 |
|
|
delete this; |
123 |
derek |
3006 |
return; |
124 |
derek |
2997 |
} |
125 |
derek |
2961 |
} |
126 |
|
|
break; |
127 |
|
|
case Connected: |
128 |
|
|
// reINVITE |
129 |
|
|
if (msg.isRequest()) |
130 |
|
|
{ |
131 |
|
|
switch(msg.header(h_RequestLine).method()) |
132 |
|
|
{ |
133 |
|
|
case INVITE: |
134 |
|
|
mDialog.update(msg); |
135 |
|
|
mDum.mInviteSessionHandler->onDialogModified(getSessionHandle(), msg); |
136 |
jason |
2856 |
|
137 |
derek |
2961 |
if (offans.first != None) |
138 |
|
|
{ |
139 |
derek |
2976 |
incomingSdp(msg, offans.second); |
140 |
derek |
2961 |
} |
141 |
|
|
break; |
142 |
jason |
2856 |
|
143 |
derek |
2961 |
case BYE: |
144 |
derek |
2978 |
mState = Terminated; |
145 |
|
|
mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), msg); |
146 |
|
|
mDialog.makeResponse(mLastResponse, msg, 200); |
147 |
|
|
send(mLastResponse); |
148 |
derek |
2961 |
break; |
149 |
jason |
2856 |
|
150 |
derek |
2961 |
case UPDATE: |
151 |
|
|
assert(0); |
152 |
|
|
break; |
153 |
jason |
2856 |
|
154 |
derek |
2961 |
case INFO: |
155 |
|
|
mDum.mInviteSessionHandler->onInfo(getSessionHandle(), msg); |
156 |
|
|
break; |
157 |
jason |
2856 |
|
158 |
derek |
2961 |
case REFER: |
159 |
|
|
assert(0); // !jf! |
160 |
|
|
mDum.mInviteSessionHandler->onRefer(getSessionHandle(), msg); |
161 |
|
|
break; |
162 |
jason |
2856 |
|
163 |
derek |
2961 |
default: |
164 |
|
|
InfoLog (<< "Ignoring request in an INVITE dialog: " << msg.brief()); |
165 |
|
|
break; |
166 |
|
|
} |
167 |
derek |
3006 |
} |
168 |
|
|
else |
169 |
|
|
{ |
170 |
|
|
//!dcm! -- need to change this logic for when we don't have an ACK yet |
171 |
|
|
if ( msg.header(h_StatusLine).statusCode() == 200) |
172 |
|
|
{ |
173 |
|
|
//retransmist ack |
174 |
|
|
mDum.send(mAck); |
175 |
|
|
} |
176 |
|
|
} |
177 |
derek |
2976 |
case Accepting: |
178 |
|
|
if (msg.isRequest() && msg.header(h_RequestLine).method() == ACK) |
179 |
|
|
{ |
180 |
|
|
mState = Connected; |
181 |
|
|
mDum.mInviteSessionHandler->onConnected(getSessionHandle(), msg); |
182 |
|
|
if (offans.first != None) |
183 |
|
|
{ |
184 |
|
|
InviteSession::incomingSdp(msg, offans.second); |
185 |
|
|
} |
186 |
|
|
} |
187 |
|
|
else |
188 |
|
|
{ |
189 |
derek |
2997 |
ErrLog ( << "Spurious message sent to UAS " << msg ); |
190 |
|
|
return; |
191 |
derek |
2976 |
} |
192 |
|
|
break; |
193 |
derek |
2961 |
default: |
194 |
derek |
3024 |
DebugLog ( << "Throwing away strange message: " << msg ); |
195 |
|
|
//throw message away |
196 |
|
|
// assert(0); //all other cases should be handled in base classes |
197 |
|
|
|
198 |
jason |
2856 |
} |
199 |
|
|
} |
200 |
|
|
|
201 |
derek |
2955 |
SipMessage& |
202 |
derek |
3039 |
InviteSession::makeRefer(const NameAddr& referTo) |
203 |
derek |
2955 |
{ |
204 |
derek |
2981 |
assert(0); |
205 |
|
|
return mLastRequest; |
206 |
derek |
2955 |
} |
207 |
jason |
2856 |
|
208 |
jason |
2809 |
SipMessage& |
209 |
jason |
2621 |
InviteSession::end() |
210 |
|
|
{ |
211 |
derek |
3006 |
InfoLog ( << "InviteSession::end, state: " << mState); |
212 |
derek |
2961 |
switch (mState) |
213 |
|
|
{ |
214 |
|
|
case Terminated: |
215 |
derek |
2965 |
throw UsageUseException("Cannot end a session that has already been cancelled.", __FILE__, __LINE__); |
216 |
derek |
2961 |
break; |
217 |
|
|
case Connected: |
218 |
derek |
3006 |
case Accepting: |
219 |
|
|
InfoLog ( << "InviteSession::end, connected or Accepting" ); |
220 |
derek |
2961 |
mDialog.makeRequest(mLastRequest, BYE); |
221 |
derek |
2985 |
//new transaction |
222 |
|
|
assert(mLastRequest.header(h_Vias).size() == 1); |
223 |
|
|
mLastRequest.header(h_Vias).front().param(p_branch).reset(); |
224 |
derek |
2961 |
mState = Terminated; |
225 |
|
|
return mLastRequest; |
226 |
|
|
break; |
227 |
|
|
default: |
228 |
|
|
assert(0); // out of states |
229 |
|
|
} |
230 |
derek |
2981 |
throw UsageUseException("Programmer error", __FILE__, __LINE__); //make VC++ happy |
231 |
jason |
2621 |
} |
232 |
|
|
|
233 |
jason |
2809 |
// If sdp==0, it means the last offer failed |
234 |
derek |
2965 |
// !dcm! -- eventually handle confused UA's that send offers/answers at |
235 |
|
|
// inappropriate times, probably with a different callback |
236 |
jason |
2846 |
void |
237 |
|
|
InviteSession::incomingSdp(const SipMessage& msg, const SdpContents* sdp) |
238 |
jason |
2809 |
{ |
239 |
|
|
switch (mOfferState) |
240 |
|
|
{ |
241 |
jason |
2846 |
case Nothing: |
242 |
jason |
2809 |
assert(mCurrentLocalSdp == 0); |
243 |
|
|
assert(mCurrentRemoteSdp == 0); |
244 |
jason |
2846 |
mProposedRemoteSdp = static_cast<SdpContents*>(sdp->clone()); |
245 |
jason |
2809 |
mOfferState = Offerred; |
246 |
jason |
2846 |
mDum.mInviteSessionHandler->onOffer(getSessionHandle(), msg, sdp); |
247 |
jason |
2809 |
break; |
248 |
|
|
|
249 |
|
|
case Offerred: |
250 |
|
|
mCurrentLocalSdp = mProposedLocalSdp; |
251 |
jason |
2846 |
mCurrentRemoteSdp = static_cast<SdpContents*>(sdp->clone()); |
252 |
jason |
2809 |
mProposedLocalSdp = 0; |
253 |
|
|
mProposedRemoteSdp = 0; |
254 |
|
|
mOfferState = Answered; |
255 |
jason |
2846 |
mDum.mInviteSessionHandler->onAnswer(getSessionHandle(), msg, sdp); |
256 |
jason |
2809 |
break; |
257 |
|
|
|
258 |
|
|
case Answered: |
259 |
|
|
assert(mProposedLocalSdp == 0); |
260 |
|
|
assert(mProposedRemoteSdp == 0); |
261 |
jason |
2846 |
mProposedRemoteSdp = static_cast<SdpContents*>(sdp->clone()); |
262 |
jason |
2809 |
mOfferState = CounterOfferred; |
263 |
jason |
2846 |
mDum.mInviteSessionHandler->onOffer(getSessionHandle(), msg, sdp); |
264 |
jason |
2809 |
break; |
265 |
derek |
2965 |
|
266 |
jason |
2809 |
case CounterOfferred: |
267 |
|
|
assert(mCurrentLocalSdp); |
268 |
|
|
assert(mCurrentRemoteSdp); |
269 |
jason |
2846 |
mOfferState = Answered; |
270 |
jason |
2809 |
if (sdp) |
271 |
|
|
{ |
272 |
derek |
2965 |
delete mCurrentLocalSdp; |
273 |
|
|
delete mCurrentRemoteSdp; |
274 |
jason |
2809 |
mCurrentLocalSdp = mProposedLocalSdp; |
275 |
jason |
2846 |
mCurrentRemoteSdp = static_cast<SdpContents*>(sdp->clone()); |
276 |
derek |
2965 |
mProposedLocalSdp = 0; |
277 |
|
|
mProposedRemoteSdp = 0; |
278 |
|
|
mOfferState = Answered; |
279 |
jason |
2846 |
mDum.mInviteSessionHandler->onAnswer(getSessionHandle(), msg, sdp); |
280 |
jason |
2809 |
} |
281 |
|
|
else |
282 |
|
|
{ |
283 |
|
|
mProposedLocalSdp = 0; |
284 |
|
|
mProposedRemoteSdp = 0; |
285 |
jason |
2846 |
// !jf! is this right? |
286 |
|
|
mDum.mInviteSessionHandler->onOfferRejected(getSessionHandle(), msg); |
287 |
jason |
2809 |
} |
288 |
|
|
break; |
289 |
|
|
} |
290 |
|
|
} |
291 |
|
|
|
292 |
derek |
2965 |
void |
293 |
|
|
InviteSession::send(SipMessage& msg) |
294 |
|
|
{ |
295 |
|
|
if (msg.isRequest()) |
296 |
|
|
{ |
297 |
|
|
//unless the message is an ACK(in which case it is mAck) |
298 |
|
|
//strip out the SDP after sending |
299 |
|
|
if (msg.header(h_RequestLine).getMethod() == ACK) |
300 |
|
|
{ |
301 |
|
|
mDum.send(msg); |
302 |
|
|
} |
303 |
|
|
else |
304 |
|
|
{ |
305 |
|
|
mDum.send(msg); |
306 |
|
|
msg.releaseContents(); |
307 |
|
|
} |
308 |
|
|
} |
309 |
|
|
else |
310 |
|
|
{ |
311 |
|
|
int code = msg.header(h_StatusLine).statusCode(); |
312 |
|
|
//!dcm! -- probably kill this object earlier, handle 200 to bye in |
313 |
|
|
//DialogUsageManager...very soon |
314 |
|
|
if (msg.header(h_CSeq).method() == BYE && code == 200) //!dcm! -- not 2xx? |
315 |
|
|
|
316 |
|
|
{ |
317 |
|
|
mState = Terminated; |
318 |
|
|
mDum.send(msg); |
319 |
|
|
delete this; |
320 |
|
|
} |
321 |
derek |
2978 |
else if (code >= 200 && code < 300 && msg.header(h_CSeq).method() == INVITE) |
322 |
derek |
2965 |
{ |
323 |
derek |
2978 |
assert(&msg == &mFinalResponse); |
324 |
derek |
2990 |
mCurrentRetransmit200 = T1; |
325 |
|
|
mDum.addTimer(DumTimeout::Retransmit200, mCurrentRetransmit200, getBaseHandle(), 0); |
326 |
|
|
mDum.addTimer(DumTimeout::WaitForAck, TimerH, getBaseHandle(), 0); |
327 |
|
|
|
328 |
|
|
//!dcm! -- this should be mFinalResponse...maybe assign here in |
329 |
derek |
2965 |
//case the user wants to be very strange |
330 |
|
|
if (mNextOfferOrAnswerSdp) |
331 |
|
|
{ |
332 |
|
|
msg.setContents(static_cast<SdpContents*>(mNextOfferOrAnswerSdp->clone())); |
333 |
|
|
sendSdp(mNextOfferOrAnswerSdp); |
334 |
derek |
2997 |
mNextOfferOrAnswerSdp = 0; |
335 |
derek |
2978 |
} |
336 |
|
|
mDum.send(msg); |
337 |
|
|
} |
338 |
|
|
else |
339 |
|
|
{ |
340 |
|
|
mDum.send(msg); |
341 |
|
|
msg.releaseContents(); |
342 |
|
|
} |
343 |
derek |
2965 |
} |
344 |
|
|
} |
345 |
|
|
|
346 |
jason |
2621 |
void |
347 |
derek |
2965 |
InviteSession::sendSdp(SdpContents* sdp) |
348 |
jason |
2809 |
{ |
349 |
|
|
switch (mOfferState) |
350 |
|
|
{ |
351 |
jason |
2846 |
case Nothing: |
352 |
jason |
2809 |
assert(mCurrentLocalSdp == 0); |
353 |
|
|
assert(mCurrentRemoteSdp == 0); |
354 |
derek |
2965 |
mProposedLocalSdp = sdp; |
355 |
jason |
2809 |
mOfferState = Offerred; |
356 |
|
|
break; |
357 |
|
|
|
358 |
|
|
case Offerred: |
359 |
derek |
2965 |
mCurrentLocalSdp = sdp; |
360 |
jason |
2809 |
mCurrentRemoteSdp = mProposedRemoteSdp; |
361 |
|
|
mProposedLocalSdp = 0; |
362 |
|
|
mProposedRemoteSdp = 0; |
363 |
|
|
mOfferState = Answered; |
364 |
|
|
break; |
365 |
|
|
|
366 |
|
|
case Answered: |
367 |
|
|
assert(mProposedLocalSdp == 0); |
368 |
|
|
assert(mProposedRemoteSdp == 0); |
369 |
derek |
2965 |
mProposedLocalSdp = sdp; |
370 |
jason |
2809 |
mOfferState = CounterOfferred; |
371 |
|
|
break; |
372 |
|
|
|
373 |
|
|
case CounterOfferred: |
374 |
|
|
assert(mCurrentLocalSdp); |
375 |
|
|
assert(mCurrentRemoteSdp); |
376 |
|
|
if (sdp) |
377 |
|
|
{ |
378 |
jason |
2846 |
mCurrentLocalSdp = static_cast<SdpContents*>(sdp->clone()); |
379 |
jason |
2809 |
mCurrentRemoteSdp = mProposedRemoteSdp; |
380 |
|
|
} |
381 |
|
|
else |
382 |
|
|
{ |
383 |
|
|
mProposedLocalSdp = 0; |
384 |
|
|
mProposedRemoteSdp = 0; |
385 |
|
|
} |
386 |
|
|
mOfferState = Answered; |
387 |
|
|
break; |
388 |
|
|
} |
389 |
|
|
} |
390 |
|
|
|
391 |
jason |
2846 |
std::pair<InviteSession::OfferAnswerType, const SdpContents*> |
392 |
|
|
InviteSession::getOfferOrAnswer(const SipMessage& msg) const |
393 |
|
|
{ |
394 |
|
|
std::pair<InviteSession::OfferAnswerType, const SdpContents*> ret; |
395 |
|
|
ret.first = None; |
396 |
|
|
|
397 |
|
|
const SdpContents* contents = dynamic_cast<const SdpContents*>(msg.getContents()); |
398 |
|
|
if (contents) |
399 |
|
|
{ |
400 |
|
|
static Token c100rel(Symbols::C100rel); |
401 |
derek |
2976 |
if (msg.isRequest() || msg.header(h_StatusLine).responseCode() == 200 || |
402 |
jason |
2846 |
msg.exists(h_Supporteds) && msg.header(h_Supporteds).find(c100rel)) |
403 |
|
|
{ |
404 |
|
|
switch (mOfferState) |
405 |
|
|
{ |
406 |
|
|
case None: |
407 |
|
|
ret.first = Offer; |
408 |
|
|
ret.second = contents; |
409 |
|
|
break; |
410 |
|
|
|
411 |
|
|
case Offerred: |
412 |
|
|
ret.first = Answer; |
413 |
|
|
ret.second = contents; |
414 |
|
|
break; |
415 |
|
|
|
416 |
|
|
case Answered: |
417 |
|
|
ret.first = Offer; |
418 |
|
|
ret.second = contents; |
419 |
|
|
break; |
420 |
|
|
|
421 |
|
|
case CounterOfferred: |
422 |
|
|
ret.first = Answer; |
423 |
|
|
ret.second = contents; |
424 |
|
|
break; |
425 |
|
|
} |
426 |
|
|
} |
427 |
|
|
} |
428 |
|
|
return ret; |
429 |
|
|
} |
430 |
|
|
|
431 |
jason |
2809 |
void |
432 |
jason |
2621 |
InviteSession::copyAuthorizations(SipMessage& request) |
433 |
|
|
{ |
434 |
jason |
2725 |
#if 0 |
435 |
jason |
2621 |
if (mLastRequest.exists(h_ProxyAuthorizations)) |
436 |
|
|
{ |
437 |
|
|
// should make the next auth (change nextNonce) |
438 |
|
|
request.header(h_ProxyAuthorizations) = mLastRequest.header(h_ProxyAuthorizations); |
439 |
|
|
} |
440 |
|
|
if (mLastRequest.exists(h_ProxyAuthorizations)) |
441 |
|
|
{ |
442 |
|
|
// should make the next auth (change nextNonce) |
443 |
|
|
request.header(h_ProxyAuthorizations) = mLastRequest.header(h_ProxyAuthorizations); |
444 |
|
|
} |
445 |
jason |
2725 |
#endif |
446 |
jason |
2621 |
} |
447 |
|
|
|
448 |
derek |
2955 |
SipMessage& |
449 |
derek |
2965 |
InviteSession::rejectOffer(int statusCode) |
450 |
|
|
{ |
451 |
derek |
2976 |
mDialog.makeResponse(mLastResponse, mLastRequest, statusCode); |
452 |
|
|
return mLastResponse; |
453 |
derek |
2965 |
} |
454 |
|
|
|
455 |
|
|
SipMessage& |
456 |
derek |
2955 |
InviteSession::targetRefresh(const NameAddr& localUri) |
457 |
|
|
{ |
458 |
|
|
assert(0); |
459 |
derek |
2981 |
return mLastRequest; |
460 |
derek |
2955 |
} |
461 |
davidb |
2576 |
|
462 |
derek |
2981 |
SipMessage& |
463 |
|
|
InviteSession::ackConnection() |
464 |
|
|
{ |
465 |
|
|
//if not a reinvite, and a pending offer exists, throw |
466 |
|
|
makeAck(); |
467 |
derek |
2985 |
//new transaction |
468 |
|
|
assert(mAck.header(h_Vias).size() == 1); |
469 |
|
|
mAck.header(h_Vias).front().param(p_branch).reset(); |
470 |
derek |
2981 |
return mAck; |
471 |
|
|
} |
472 |
|
|
|
473 |
derek |
2955 |
void |
474 |
derek |
2965 |
InviteSession::makeAck() |
475 |
derek |
2849 |
{ |
476 |
derek |
2965 |
mAck = mLastRequest; |
477 |
derek |
2992 |
|
478 |
|
|
InfoLog ( << "InviteSession::makeAck:before: " << mAck ); |
479 |
|
|
|
480 |
derek |
2965 |
mDialog.makeRequest(mAck, ACK); |
481 |
|
|
if (mNextOfferOrAnswerSdp) |
482 |
|
|
{ |
483 |
|
|
mAck.setContents(static_cast<SdpContents*>(mNextOfferOrAnswerSdp->clone())); |
484 |
|
|
sendSdp(mNextOfferOrAnswerSdp); |
485 |
derek |
2997 |
mNextOfferOrAnswerSdp = 0; |
486 |
derek |
2992 |
} |
487 |
|
|
|
488 |
|
|
InfoLog ( << "InviteSession::makeAck:after: " << mAck ); |
489 |
derek |
2849 |
} |
490 |
|
|
|
491 |
davidb |
2575 |
/* ==================================================================== |
492 |
|
|
* The Vovida Software License, Version 1.0 |
493 |
|
|
* |
494 |
|
|
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. |
495 |
|
|
* |
496 |
|
|
* Redistribution and use in source and binary forms, with or without |
497 |
|
|
* modification, are permitted provided that the following conditions |
498 |
|
|
* are met: |
499 |
|
|
* |
500 |
|
|
* 1. Redistributions of source code must retain the above copyright |
501 |
|
|
* notice, this list of conditions and the following disclaimer. |
502 |
|
|
* |
503 |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
504 |
|
|
* notice, this list of conditions and the following disclaimer in |
505 |
|
|
* the documentation and/or other materials provided with the |
506 |
|
|
|
507 |
|
|
* distribution. |
508 |
|
|
* |
509 |
|
|
* 3. The names "VOCAL", "Vovida Open Communication Application Library", |
510 |
|
|
* and "Vovida Open Communication Application Library (VOCAL)" must |
511 |
|
|
* not be used to endorse or promote products derived from this |
512 |
|
|
* software without prior written permission. For written |
513 |
|
|
* permission, please contact vocal@vovida.org. |
514 |
|
|
* |
515 |
|
|
* 4. Products derived from this software may not be called "VOCAL", nor |
516 |
|
|
* may "VOCAL" appear in their name, without prior written |
517 |
|
|
* permission of Vovida Networks, Inc. |
518 |
|
|
* |
519 |
|
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED |
520 |
|
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
521 |
|
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND |
522 |
|
|
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA |
523 |
|
|
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES |
524 |
|
|
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, |
525 |
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
526 |
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
527 |
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
528 |
|
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
529 |
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE |
530 |
|
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
531 |
|
|
* DAMAGE. |
532 |
|
|
* |
533 |
|
|
* ==================================================================== |
534 |
|
|
* |
535 |
|
|
* This software consists of voluntary contributions made by Vovida |
536 |
|
|
* Networks, Inc. and many individuals on behalf of Vovida Networks, |
537 |
|
|
* Inc. For more information on Vovida Networks, Inc., please see |
538 |
|
|
* <http://www.vovida.org/>. |
539 |
|
|
* |
540 |
|
|
*/ |