/[resiprocate]/main/sip/resiprocate/dum/Dialog.cxx
ViewVC logotype

Contents of /main/sip/resiprocate/dum/Dialog.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2583 - (show annotations) (download)
Sun Apr 11 17:38:09 2004 UTC (15 years, 9 months ago) by jason
File size: 10449 byte(s)
*** empty log message ***

1 #include "resiprocate/Contents.hxx"
2 //#include "resiprocate/OctetContents.hxx"
3 //#include "resiprocate/HeaderFieldValueList.hxx"
4 #include "resiprocate/sam/Dialog.hxx"
5 #include "resiprocate/sam/ClientInviteSession.hxx"
6
7 using namespace resip;
8 using namespace std;
9
10 class ServerInviteSession;
11
12 Dialog::Dialog(DialogUsageManager& dum, const SipMessage& msg)
13 : mId(msg),
14 mDum(dum),
15 mLocalCSeq(0),
16 mRemoteCSeq(0),
17 mCallId(msg.header(h_CallID))
18 {
19 assert(msg.isFromWire());
20
21 if (msg.isRequest()) // UAS
22 {
23 const SipMessage& request = msg;
24 mRouteSet = request.header(h_RecordRoutes);
25
26 switch (request.header(h_CSeq).method())
27 {
28 case INVITE:
29 case SUBSRIBE:
30 if (request.exists(h_Contacts) && request.header(h_Contacts).size() == 1)
31 {
32 NameAddr& contact = request.header(h_Contacts).front();
33 if (isEqualNoCase(contact.uri().scheme(), Symbols::Sips) ||
34 isEqualNoCase(contact.uri().scheme(), Symbols::Sip))
35 {
36 mRemoteTarget = contact;
37 }
38 else
39 {
40 InfoLog (<< "Got an INVITE or SUBSCRIBE with invalid scheme");
41 DebugLog (<< request);
42 throw Exception("Invalid dialog", __FILE__, __LINE__);
43 }
44 }
45 else
46 {
47 InfoLog (<< "Got an INVITE or SUBSCRIBE that doesn't have exactly one contact");
48 DebugLog (<< request);
49 throw Exception("Invalid dialog", __FILE__, __LINE__);
50 }
51 break;
52 }
53
54 mRemoteCSeq = request.header(h_CSeq).sequence();
55 mLocalCSeq = 0;
56
57 if ( response.header(h_From).exists(p_tag) ) // 2543 compat
58 {
59 mRemoteTag = response.header(h_From).param(p_tag);
60 }
61 if ( response.header(h_To).exists(p_tag) ) // 2543 compat
62 {
63 mLocalTag = response.header(h_To).param(p_tag);
64 }
65 mMe = response.header(h_To);
66
67 //mDialogId = mCallId;
68 //mDialogId.param(p_toTag) = mLocalTag;
69 //mDialogId.param(p_fromTag) = mRemoteTag;
70 }
71 else if (msg.isResponse())
72 {
73 const SipMessage& response = msg;
74 if (response.exists(h_RecordRoutes))
75 {
76 mRouteSet = response.header(h_RecordRoutes).reverse();
77 }
78
79 switch (response.header(h_CSeq).method())
80 {
81 case INVITE:
82 case SUBSRIBE:
83 if (response.exists(h_Contacts) && response.header(h_Contacts).size() == 1)
84 {
85 NameAddr& contact = response.header(h_Contacts).front();
86 if (isEqualNoCase(contact.uri().scheme(), Symbols::Sips) ||
87 isEqualNoCase(contact.uri().scheme(), Symbols::Sip))
88 {
89 mRemoteTarget = contact;
90 }
91 else
92 {
93 InfoLog (<< "Got an INVITE or SUBSCRIBE with invalid scheme");
94 DebugLog (<< response);
95 throw Exception("Invalid dialog", __FILE__, __LINE__);
96 }
97 }
98 else
99 {
100 InfoLog (<< "Got an INVITE or SUBSCRIBE that doesn't have exactly one contact");
101 DebugLog (<< response);
102 throw Exception("Invalid dialog", __FILE__, __LINE__);
103 }
104 break;
105 }
106
107 mLocalCSeq = response.header(h_CSeq).sequence();
108
109 if ( response.header(h_From).exists(p_tag) ) // 2543 compat
110 {
111 mLocalTag = response.header(h_From).param(p_tag);
112 }
113 if ( response.header(h_To).exists(p_tag) ) // 2543 compat
114 {
115 mRemoteTag = response.header(h_To).param(p_tag);
116 }
117 mMe = response.header(h_From);
118
119 //mDialogId = mCallId;
120 //mDialogId.param(p_toTag) = mLocalTag;
121 //mDialogId.param(p_fromTag) = mRemoteTag;
122
123 BaseUsage* usage = mCreator->makeUsage(response);
124 assert(usage);
125 mUsages.push_back(usage);
126 }
127 }
128
129 void
130 Dialog::dispatch(const SipMessage& msg)
131 {
132 BaseUsage* usage = findUsage(msg);
133 if (usage)
134 {
135 usage->dispatch(msg);
136 }
137 else
138 {
139 if (msg.isRequest())
140 {
141 switch (msg.header(h_CSeq).method())
142 {
143 case INVITE: // new INVITE
144 usage = mDum.createServerInviteSession(msg);
145 break;
146
147 case ACK:
148 case CANCEL:
149 InfoLog (<< "Drop stray ACK or CANCEL in dialog on the floor");
150 DebugLog (<< msg);
151 break;
152
153 case SUBSCRIBE:
154
155
156 }
157 }
158 else if (msg.isResponse())
159 {
160 }
161
162 BaseUsage* usage = mCreator->makeUsage(msg);
163 assert(usage);
164 mUsages.push_back(usage);
165 }
166 }
167
168 BaseUsage*
169 Dialog::findUsage(const SipMessage& msg)
170 {
171 switch (msg.header(h_CSeq).method())
172 {
173 case INVITE: // new INVITE
174 return mInviteSession;
175 case SUBSCRIBE:
176 case REFER:
177 case NOTIFY:
178 break;
179 case REGISTER:
180 assert(0);
181 case PUBLISH:
182 break;
183 case MESSAGE :
184 case OPTIONS :
185 case INFO :
186 break;
187 }
188 }
189
190 DialogId Dialog::getId() const
191 {
192 return mId;
193 }
194
195 BaseUsage&
196 Dialog::findInvSession()
197 {
198 std::list<BaseUsage*>::iterator it = mUsages.begin();
199 BaseUsage *usage;
200 while (it != mUsages.end())
201 {
202 usage = it->next();
203 if ((dynamic_cast<ClientInviteSession*>(usage) != NULL) ||
204 (dynamic_cast<ServerInviteSession*>(usage) != NULL))
205 {
206 return *usage;
207 }
208 }
209 return BaseUsage::empty();
210 }
211
212 UsageSet
213 Dialog::findSubscriptions()
214 {
215 std::list<BaseUsage*>::iterator it = mUsages.begin();
216 BaseUsage *usage;
217 UsageSet usageSet;
218 while (it != mUsages.end())
219 {
220 usage = it.next();
221 if ((dynamic_cast<ClientSubscription*>(usage) != null) ||
222 (dynamic_cast<ServerSubscription*>(usage) != null))
223 {
224 usageSet.push_back(*usage);
225 }
226 }
227 return usageSet:
228 }
229
230 BaseUsage&
231 Dialog::findRegistration()
232 {
233 std::list<BaseUsage*>::iterator it = mUsages.begin();
234 BaseUsage *usage;
235 while (it != mUsages.end())
236 {
237 usage = it.next();
238 if ((dynamic_cast<CientRegistration*>(usage) != null) ||
239 (dynamic_cast<ServerRegistration*>(usage) != null))
240 {
241 return *usage;
242 }
243 }
244 return BaseUsage::empty();
245 }
246
247
248 BaseUsage&
249 Dialog::findPublication()
250 {
251 std::list<BaseUsage*>::iterator it = mUsages.begin();
252 BaseUsage *usage;
253 while (it != mUsages.end())
254 {
255 usage = it.next();
256 if ((dynamic_cast<CientPublication*>(usage) != null) ||
257 (dynamic_cast<ServerPublication*>(usage) != null))
258 {
259 return *usage;
260 }
261 }
262 return BaseUsage::empty();
263 }
264
265 UsageSet
266 Dialog::findOutOfDialogs()
267 {
268 std::list<BaseUsage*>::iterator it = mUsages.begin();
269 BaseUsage *usage;
270 UsageSet usageSet;
271 while (it != mUsages.end())
272 {
273 usage = it.next();
274 if ((dynamic_cast<ClientOutOfDialogReq*>(usage) != null) ||
275 (dynamic_cast<ServerOutOfDialogReq*>(usage) != null))
276 {
277 usageSet.push_back(*usage);
278 }
279 }
280 return usageSet:
281 }
282
283 void
284 Dialog::dispatch(const SipMessage& msg)
285 {
286 if (msg.isRequest())
287 {
288 switch (request.header(h_RequestLine).getMethod())
289 {
290 // a NOTIFY is the only request that can
291 // create a full dialog (when the 2xx from the
292 // SUBSCRIBE arrives *after* the NOTIFY
293 case NOTIFY :
294 processNotify(msg);
295 break;
296
297 case REFER:
298 // !jf! wierdo
299 // affects an InvSession and a ServerSubscription
300 break;
301
302 case SUBSCRIBE:
303 processSubscribe(msg);
304 break;
305
306 case CANCEL:
307 // should only occur when canceling a re-INVITE
308 case INVITE:
309 // should only occur for a re-INVITE
310 case ACK:
311 case PRACK:
312 case BYE:
313 case UPDATE:
314 case INFO:
315 processInviteRelated(msg);
316 break;
317
318 case REGISTER:
319 {
320 assert(0); // already handled
321 break;
322 }
323
324 case PUBLISH:
325 assert(0);
326 break;
327
328 case MESSAGE:
329 case OPTIONS:
330 assert(0);
331 break;
332
333 default:
334 assert(0);
335 break;
336 }
337 }
338 else if (msg.isResponse())
339 {
340
341 }
342 else
343 {
344 assert(0);
345 }
346 }
347
348 void
349 Dialog::processNotify(const SipMessage& notify)
350 {
351 if (notify.isRequest())
352 {
353 if (findSubscriptions().empty())
354 {
355 SubscriptionCreator* creator = dynamic_cast<SubscriptionCreator*>(DialogSetId(notify).getCreator());
356 if (creator)
357 {
358 creator->makeNewSubscription(notify);
359 }
360 }
361 else
362 {
363 for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
364 {
365 ClientSubscription* sub = dynamic_cast<ClientSubscription*>(*i);
366 if (sub && sub->matches(notify))
367 {
368 sub->process(notify);
369 break;
370 }
371 }
372 }
373 }
374 }
375
376 void
377 Dialog::processSubscribe(const SipMessage& subscribe)
378 {
379 for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
380 {
381 ServerSubscription* sub = dynamic_cast<ServerSubscription*>(*i);
382 if (sub && sub->matches(subscribe))
383 {
384 sub->process(subscribe); // a resubscribe or unsubscribe
385 return;
386 }
387 }
388
389 // a subscribe on an existing dialog with a different BaseUsage
390 ServerSubscription* sub = new ServerSubscription(mDum, subscribe);
391 }
392
393 void
394 Dialog::processInviteRelated(const SipMessage& msg)
395 {
396 for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
397 {
398 ServerInvSession* server = dynamic_cast<ServerInvSession*>(*i);
399 ClientInvSession* client = dynamic_cast<ClientInvSession*>(*i);
400 if (server)
401 {
402 server->process(msg);
403 break;
404 }
405 else if (client)
406 {
407 client->process(msg);
408 break;
409 }
410 }
411 }

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27