3
#include "resip/stack/Helper.hxx"
4
#include "resip/stack/SipMessage.hxx"
5
#include "resip/dum/ClientPublication.hxx"
6
#include "resip/dum/Dialog.hxx"
7
#include "resip/dum/DialogUsageManager.hxx"
8
#include "resip/dum/DumTimeout.hxx"
9
#include "rutil/Logger.hxx"
10
#include "resip/dum/PublicationHandler.hxx"
13
#define RESIPROCATE_SUBSYSTEM Subsystem::DUM
15
using namespace resip;
17
ClientPublicationHandle
18
ClientPublication::getHandle()
20
return ClientPublicationHandle(mDum, getBaseHandle().getId());
23
ClientPublication::ClientPublication(DialogUsageManager& dum,
25
SharedPtr<SipMessage> req)
26
: NonDialogUsage(dum, dialogSet),
27
mWaitingForResponse(false),
28
mPendingPublish(false),
30
mEventType(req->header(h_Event).value()),
32
mDocument(mPublish->releaseContents().release())
34
DebugLog( << "ClientPublication::ClientPublication: " << mId);
37
ClientPublication::~ClientPublication()
39
DebugLog( << "ClientPublication::~ClientPublication: " << mId);
40
mDialogSet.mClientPublication = 0;
45
ClientPublication::end()
51
ClientPublication::end(bool immediate)
53
InfoLog (<< "End client publication to " << mPublish->header(h_RequestLine).uri());
56
mPublish->header(h_Expires).value() = 0;
65
class ClientPublicationEndCommand : public DumCommandAdapter
68
ClientPublicationEndCommand(ClientPublication& clientPublication, bool immediate)
69
: mClientPublication(clientPublication), mImmediate(immediate)
74
virtual void executeCommand()
76
mClientPublication.end(mImmediate);
79
virtual EncodeStream& encodeBrief(EncodeStream& strm) const
81
return strm << "ClientPublicationEndCommand";
84
ClientPublication& mClientPublication;
89
ClientPublication::endCommand(bool immediate)
91
mDum.post(new ClientPublicationEndCommand(*this, immediate));
95
ClientPublication::dispatch(const SipMessage& msg)
97
ClientPublicationHandler* handler = mDum.getClientPublicationHandler(mEventType);
102
DebugLog( << "Dropping stray request to ClientPublication usage: " << msg);
106
const int code = msg.header(h_StatusLine).statusCode();
113
mWaitingForResponse = false;
117
if (mPublish->exists(h_Expires) && mPublish->header(h_Expires).value() == 0)
119
handler->onRemove(getHandle(), msg);
123
else if (msg.exists(h_SIPETag) && msg.exists(h_Expires))
125
mPublish->header(h_SIPIfMatch) = msg.header(h_SIPETag);
128
mPublish->releaseContents();
130
mDum.addTimer(DumTimeout::Publication,
131
Helper::aBitSmallerThan(msg.header(h_Expires).value()),
134
handler->onSuccess(getHandle(), msg);
138
// Any PUBLISH/200 must have an ETag. This should not happen. Not
139
// sure what the app can do in this case.
140
WarningLog (<< "PUBLISH/200 received with no ETag " << mPublish->header(h_From).uri());
141
handler->onFailure(getHandle(), msg);
150
InfoLog(<< "SIPIfMatch failed -- republish");
151
mPublish->remove(h_SIPIfMatch);
155
else if (code == 423) // interval too short
157
if (msg.exists(h_MinExpires))
159
mPublish->header(h_Expires).value() = msg.header(h_MinExpires).value();
160
update(mDocument); // !dys! since contents not released until on success, no need to call update any more.
164
handler->onFailure(getHandle(), msg);
169
else if (code == 408 ||
170
(code == 503 && msg.getReceivedTransport() == 0) ||
179
msg.exists(h_RetryAfter)))
181
int retryMinimum = 0;
182
if (msg.exists(h_RetryAfter))
184
retryMinimum = msg.header(h_RetryAfter).value();
187
// RFC 3261:20.33 Retry-After
188
int retry = handler->onRequestRetry(getHandle(), retryMinimum, msg);
191
DebugLog(<< "Application requested failure on Retry-After");
192
handler->onFailure(getHandle(), msg);
196
else if (retry == 0 && retryMinimum == 0)
198
DebugLog(<< "Application requested immediate retry on Retry-After");
204
retry = resipMax(retry, retryMinimum);
205
DebugLog(<< "Application requested delayed retry on Retry-After: " << retry);
206
mDum.addTimer(DumTimeout::Publication,
216
handler->onFailure(getHandle(), msg);
225
InfoLog (<< "Sending pending PUBLISH: " << mPublish->brief());
232
ClientPublication::dispatch(const DumTimeout& timer)
234
if (timer.seq() == mTimerSeq)
241
ClientPublication::refresh(unsigned int expiration)
243
if (expiration == 0 && mPublish->exists(h_Expires))
245
expiration = mPublish->header(h_Expires).value();
250
class ClientPublicationRefreshCommand : public DumCommandAdapter
253
ClientPublicationRefreshCommand(ClientPublication& clientPublication, unsigned int expiration)
254
: mClientPublication(clientPublication),
255
mExpiration(expiration)
260
virtual void executeCommand()
262
mClientPublication.refresh(mExpiration);
265
virtual EncodeStream& encodeBrief(EncodeStream& strm) const
267
return strm << "ClientPublicationRefreshCommand";
271
ClientPublication& mClientPublication;
272
unsigned int mExpiration;
276
ClientPublication::refreshCommand(unsigned int expiration)
278
mDum.post(new ClientPublicationRefreshCommand(*this, expiration));
282
ClientPublication::update(const Contents* body)
284
InfoLog (<< "Updating presence document: " << mPublish->header(h_To).uri());
286
if (mDocument != body)
291
mDocument = body->clone();
299
mPublish->setContents(mDocument);
303
class ClientPublicationUpdateCommand : public DumCommandAdapter
306
ClientPublicationUpdateCommand(ClientPublication& clientPublication, const Contents* body)
307
: mClientPublication(clientPublication),
308
mBody(body?body->clone():0)
313
virtual void executeCommand()
315
mClientPublication.update(mBody.get());
318
virtual EncodeStream& encodeBrief(EncodeStream& strm) const
320
return strm << "ClientPublicationUpdateCommand";
324
ClientPublication& mClientPublication;
325
std::auto_ptr<Contents> mBody;
329
ClientPublication::updateCommand(const Contents* body)
331
mDum.post(new ClientPublicationUpdateCommand(*this, body));
335
ClientPublication::send(SharedPtr<SipMessage> request)
337
if (mWaitingForResponse)
339
mPendingPublish = true;
343
request->header(h_CSeq).sequence()++;
345
mWaitingForResponse = true;
346
mPendingPublish = false;
351
ClientPublication::dump(EncodeStream& strm) const
353
strm << "ClientPublication " << mId << " " << mPublish->header(h_From).uri();
357
/* ====================================================================
358
* The Vovida Software License, Version 1.0
360
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
362
* Redistribution and use in source and binary forms, with or without
363
* modification, are permitted provided that the following conditions
366
* 1. Redistributions of source code must retain the above copyright
367
* notice, this list of conditions and the following disclaimer.
369
* 2. Redistributions in binary form must reproduce the above copyright
370
* notice, this list of conditions and the following disclaimer in
371
* the documentation and/or other materials provided with the
375
* 3. The names "VOCAL", "Vovida Open Communication Application Library",
376
* and "Vovida Open Communication Application Library (VOCAL)" must
377
* not be used to endorse or promote products derived from this
378
* software without prior written permission. For written
379
* permission, please contact vocal@vovida.org.
381
* 4. Products derived from this software may not be called "VOCAL", nor
382
* may "VOCAL" appear in their name, without prior written
383
* permission of Vovida Networks, Inc.
385
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
386
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
387
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
388
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
389
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
390
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
391
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
392
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
393
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
394
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
395
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
396
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
399
* ====================================================================
401
* This software consists of voluntary contributions made by Vovida
402
* Networks, Inc. and many individuals on behalf of Vovida Networks,
403
* Inc. For more information on Vovida Networks, Inc., please see
404
* <http://www.vovida.org/>.