reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
ContactInstanceRecord.cxx
Go to the documentation of this file.
1#include <sstream>
2
6#include "rutil/XMLCursor.hxx"
7#include "rutil/Timer.hxx"
8
9using namespace resip;
10
12 mRegExpires(0),
13 mLastUpdated(Timer::getTimeSecs()),
14 mRegId(0),
15 mSyncContact(false),
16 mUseFlowRouting(false),
17 mUserInfo(0),
18 mUserData(0)
19{
20}
21
23 mUserData(0)
24{
25 *this = rhs;
26}
27
29{
30 if (&rhs != this)
31 {
32 mContact = rhs.mContact;
37 mSipPath = rhs.mSipPath;
38 mInstance = rhs.mInstance;
40 mRegId = rhs.mRegId;
43 mUserInfo = rhs.mUserInfo;
44 if(mUserData && rhs.mUserData == 0)
45 {
46 delete mUserData;
47 mUserData = 0;
48 }
49 else if(mUserData == 0 && rhs.mUserData)
50 {
51 mUserData = new Data(*rhs.mUserData);
52 }
53 else if(rhs.mUserData)
54 {
55 *mUserData = *rhs.mUserData;
56 }
57 // else both are already NULL
58 }
59
60 return(*this);
61}
62
64{
65 if(mUserData)
66 {
67 delete mUserData;
68 mUserData = 0;
69 }
70}
71
72bool
74{
75 if((mRegId != 0 && !mInstance.empty()) ||
76 (rhs.mRegId != 0 && !rhs.mInstance.empty()))
77 {
78 // If regId and instanceId is specified on either, then outbound RFC5626 is
79 // in use - match only if both instance id and reg-id match - ignore contact URI
80 return mInstance == rhs.mInstance &&
81 mRegId == rhs.mRegId;
82 }
83 else if (mRegId == 0 && rhs.mRegId == 0 &&
84 !mInstance.empty() && !rhs.mInstance.empty())
85 {
86 // If RegId is not specified on either but instance Id is, then look for instanceId
87 // match only - RFC5627 matching (even though we don't fully support GRUU yet)
88 return mInstance == rhs.mInstance;
89 }
90 else
91 {
92 // otherwise both instance (if specified) and contact must match
93 return mInstance == rhs.mInstance &&
94 mContact.uri() == rhs.mContact.uri();
95 }
96}
97
98void ContactInstanceRecord::stream(std::iostream& ss) const
99{
101
102 ss << " <contactinfo>" << Symbols::CRLF;
103 ss << " <contacturi>" << Data::from(mContact).xmlCharDataEncode() << "</contacturi>" << Symbols::CRLF;
104 // If contact is expired or removed, then pass expires time as 0, otherwise send number of seconds until expiry
105 ss << " <expires>" << (((mRegExpires == 0) || (mRegExpires <= now)) ? 0 : (mRegExpires-now)) << "</expires>" << Symbols::CRLF;
106 ss << " <lastupdate>" << now-mLastUpdated << "</lastupdate>" << Symbols::CRLF;
107 if(mReceivedFrom.getPort() != 0)
108 {
109 resip::Data binaryFlowToken;
110 Tuple::writeBinaryToken(mReceivedFrom,binaryFlowToken);
111 ss << " <receivedfrom>" << binaryFlowToken.base64encode() << "</receivedfrom>" << Symbols::CRLF;
112 }
114 {
115 resip::Data binaryFlowToken;
116 Tuple::writeBinaryToken(mPublicAddress,binaryFlowToken);
117 ss << " <publicaddress>" << binaryFlowToken.base64encode() << "</publicaddress>" << Symbols::CRLF;
118 }
119 NameAddrs::const_iterator naIt = mSipPath.begin();
120 for(; naIt != mSipPath.end(); naIt++)
121 {
122 ss << " <sippath>" << Data::from(naIt->uri()).xmlCharDataEncode() << "</sippath>" << Symbols::CRLF;
123 }
124 if(!mInstance.empty())
125 {
126 ss << " <instance>" << mInstance.xmlCharDataEncode() << "</instance>" << Symbols::CRLF;
127 }
128 if(mRegId != 0)
129 {
130 ss << " <regid>" << mRegId << "</regid>" << Symbols::CRLF;
131 }
132 if (!mUserAgent.empty())
133 {
134 ss << " <useragent>" << mUserAgent.xmlCharDataEncode() << "</useragent>" << Symbols::CRLF;
135 }
136
137 if(mUserData != 0 && mUserData->size())
138 {
139 ss << " <userdata>" << *mUserData << "</userdata>" << Symbols::CRLF;
140 }
141 ss << " </contactinfo>" << Symbols::CRLF;
142}
143
145{
146 bool success = false;
147 // Reset this members
148 *this = ContactInstanceRecord();
149 if(now <= 0)
150 {
151 now = Timer::getTimeSecs();
152 }
153
154 if(isEqualNoCase(xml.getTag(), "contactinfo"))
155 {
156 if(xml.firstChild())
157 {
158 do
159 {
160 if(isEqualNoCase(xml.getTag(), "contacturi"))
161 {
162 if(xml.firstChild())
163 {
164 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: contacturi=" << xml.getValue());
166 xml.parent();
167 success = true;
168 }
169 }
170 else if(isEqualNoCase(xml.getTag(), "expires"))
171 {
172 if(xml.firstChild())
173 {
174 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: expires=" << xml.getValue());
175 uint64_t expires = xml.getValue().convertUInt64();
176 mRegExpires = (expires == 0 ? 0 : now+expires);
177 xml.parent();
178 }
179 }
180 else if(isEqualNoCase(xml.getTag(), "lastupdate"))
181 {
182 if(xml.firstChild())
183 {
184 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: lastupdate=" << xml.getValue());
185 mLastUpdated = now-xml.getValue().convertUInt64();
186 xml.parent();
187 }
188 }
189 else if(isEqualNoCase(xml.getTag(), "receivedfrom"))
190 {
191 if(xml.firstChild())
192 {
194 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: receivedfrom=" << xml.getValue() << " tuple=" << mReceivedFrom);
195 xml.parent();
196 }
197 }
198 else if(isEqualNoCase(xml.getTag(), "publicaddress"))
199 {
200 if(xml.firstChild())
201 {
203 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: publicaddress=" << xml.getValue() << " tuple=" << mPublicAddress);
204 xml.parent();
205 }
206 }
207 else if(isEqualNoCase(xml.getTag(), "sippath"))
208 {
209 if(xml.firstChild())
210 {
211 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: sippath=" << xml.getValue());
213 xml.parent();
214 }
215 }
216 else if(isEqualNoCase(xml.getTag(), "instance"))
217 {
218 if(xml.firstChild())
219 {
220 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: instance=" << xml.getValue());
222 xml.parent();
223 }
224 }
225 else if(isEqualNoCase(xml.getTag(), "regid"))
226 {
227 if(xml.firstChild())
228 {
229 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: regid=" << xml.getValue());
231 xml.parent();
232 }
233 }
234 else if (isEqualNoCase(xml.getTag(), "useragent"))
235 {
236 if (xml.firstChild())
237 {
238 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: useragent=" << xml.getValue());
240 xml.parent();
241 }
242 }
243 else if(isEqualNoCase(xml.getTag(), "userdata"))
244 {
245 if(xml.firstChild())
246 {
247 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: userdata=" << xml.getValue());
248 if(mUserData == 0)
249 {
250 mUserData = new Data("");
251 }
253 xml.parent();
254 }
255 }
256 } while(xml.nextSibling());
257 xml.parent();
258 }
259 }
260
261 return(success);
262}
263
264
267{
269 c.mContact = contact;
270 return c;
271}
272
275 uint64_t expires, // absolute time in secs
276 const SipMessage& msg)
277{
279 c.mContact = contact;
280 c.mRegExpires = expires;
281 c.mReceivedFrom = msg.getSource();
283 if (msg.exists(h_Paths))
284 {
285 c.mSipPath = msg.header(h_Paths);
286 }
287 if (contact.exists(p_Instance))
288 {
289 c.mInstance = contact.param(p_Instance);
290 }
291 if (contact.exists(p_regid))
292 {
293 c.mRegId = contact.param(p_regid);
294 }
295 // !jf! need to fill in mServerSessionId here
296 return c;
297
298}
299
300
A single contact record, bound to an Aor during registration.
bool operator==(const ContactInstanceRecord &rhs) const
void stream(std::iostream &ss) const
ContactInstanceRecord & operator=(const ContactInstanceRecord &rhs)
bool deserialize(resip::XMLCursor &xml, uint64_t now=0)
void * mUserInfo
can be used to map user record information (database record id for faster updates?...
static ContactInstanceRecord makeRemoveDelta(const NameAddr &contact)
static ContactInstanceRecord makeUpdateDelta(const NameAddr &contact, uint64_t expires, const SipMessage &msg)
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
Data xmlCharDataDecode() const
Performs in-place XML Character Data un-escaping of a Data.
Definition Data.cxx:1464
Data base64decode() const
Performs RFC 3548 Base 64 decoding of the contents of this data.
Definition Data.cxx:2607
Data base64encode(bool useUrlSafe=false) const
Performs RFC 3548 Base 64 encoding of the contents of this data.
Definition Data.cxx:2682
unsigned long convertUnsignedLong() const
Definition Data.cxx:1724
Data xmlCharDataEncode() const
Performs in-place XML Character Data escaping of a Data.
Definition Data.cxx:1454
uint64_t convertUInt64() const
Takes the contents of the Data and converts them to an unsigned 64-bit integer.
Definition Data.cxx:1758
bool empty() const noexcept
Checks whether the Data is empty.
Definition Data.hxx:591
size_type size() const noexcept
Returns the number of bytes in this Data.
Definition Data.hxx:599
static Data from(const T &x)
Converts from arbitrary other type to Data.
Definition Data.hxx:398
static Tuple getClientPublicAddress(const SipMessage &request)
Look at Via headers, and find the first public IP address closest to the sending client.
Definition Helper.cxx:2400
Represents the "name-addr" and the "addr-spec" elements in the RFC 3261 grammar.
Definition NameAddr.hxx:19
bool exists(const Param< NameAddr > &paramType) const
Definition NameAddr.cxx:477
const Data & param(const ExtensionParameter &param) const
Const accessor for non-natively-supported parameter types.
iterator end()
Returns an iterator pointing to the last header field value.
iterator begin()
Returns an iterator pointing to the first header field value.
void push_back(const T &t)
Inserts a header field value at the back of this container.
Represents a SIP message.
const RequestLine & header(const RequestLineType &l) const
Returns the RequestLine. This is only valid for request messages.
bool exists(const HeaderBase &headerType) const
Returns true if the given header field is present, false otherwise.
const Tuple & getSource() const
Returns the source tuple that the message was received from only makes sense for messages received fr...
static const char * CRLF
Definition Symbols.hxx:21
This class is used to get the current system time.
Definition Timer.hxx:31
static uint64_t getTimeSecs()
Returns the current clock time in seconds.
Definition Timer.hxx:78
static Tuple makeTupleFromBinaryToken(const Data &binaryToken, const Data &salt=Data::Empty)
Definition Tuple.cxx:328
static void writeBinaryToken(const Tuple &tuple, Data &container, const Data &salt=Data::Empty)
Definition Tuple.cxx:266
int getPort() const
Definition Tuple.cxx:466
TransportType getType() const
Definition Tuple.hxx:122
const Data & getValue() const
const Data & getTag() const
dcm! – add UnusedChecking(_enum) below;
bool isEqualNoCase(const Data &left, const Data &right)
Definition Data.hxx:1116
unsigned long long uint64_t
Definition Stun.hxx:39
@ UNKNOWN_TRANSPORT