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

Contents of /main/resip/dum/Dialog.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2584 - (show annotations) (download)
Sun Apr 11 17:48:59 2004 UTC (15 years, 8 months ago) by jason
Original Path: main/sip/resiprocate/dum/Dialog.cxx
File size: 12037 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 case REFER: //!jf! does this create a server subs?
155 usage = mDum.createServerSubscription(msg);
156 break;
157
158 case NOTIFY:
159 usage = mDum.createClientSubscription(msg);
160 break;
161
162 case PUBLISH:
163 usage = mDum.createServerPublication(msg);
164 break;
165
166 case REGISTER:
167 usage = mDum.createServerRegistration(msg);
168 break;
169
170 default:
171 usage = mDum.createServerOutOfDialog(msg);
172 break;
173 }
174 }
175 else if (msg.isResponse())
176 {
177 // !jf! should this only be for 2xx responses?
178 switch (msg.header(h_CSeq).method())
179 {
180 case INVITE:
181 usage = mDum.createClientInviteSession(msg);
182 break;
183
184 case ACK:
185 case CANCEL:
186 break;
187
188 case SUBSCRIBE:
189 case REFER: //!jf! does this create a server subs?
190 usage = mDum.createClientSubscription(msg);
191 break;
192
193 case NOTIFY:
194 usage = mDum.createClientSubscription(msg);
195 break;
196
197 case PUBLISH:
198 usage = mDum.createClientPublication(msg);
199 break;
200
201 case REGISTER:
202 usage = mDum.createClientRegistration(msg);
203 break;
204
205 default:
206 usage = mDum.createClientOutOfDialog(msg);
207 break;
208 }
209 }
210
211 BaseUsage* usage = mCreator->makeUsage(msg);
212 assert(usage);
213 mUsages.push_back(usage);
214 }
215 }
216
217 BaseUsage*
218 Dialog::findUsage(const SipMessage& msg)
219 {
220 switch (msg.header(h_CSeq).method())
221 {
222 case INVITE: // new INVITE
223 return mInviteSession;
224 case SUBSCRIBE:
225 case REFER:
226 case NOTIFY:
227 break;
228 case REGISTER:
229 assert(0);
230 case PUBLISH:
231 break;
232 case MESSAGE :
233 case OPTIONS :
234 case INFO :
235 break;
236 }
237 }
238
239 DialogId Dialog::getId() const
240 {
241 return mId;
242 }
243
244 BaseUsage&
245 Dialog::findInvSession()
246 {
247 std::list<BaseUsage*>::iterator it = mUsages.begin();
248 BaseUsage *usage;
249 while (it != mUsages.end())
250 {
251 usage = it->next();
252 if ((dynamic_cast<ClientInviteSession*>(usage) != NULL) ||
253 (dynamic_cast<ServerInviteSession*>(usage) != NULL))
254 {
255 return *usage;
256 }
257 }
258 return BaseUsage::empty();
259 }
260
261 UsageSet
262 Dialog::findSubscriptions()
263 {
264 std::list<BaseUsage*>::iterator it = mUsages.begin();
265 BaseUsage *usage;
266 UsageSet usageSet;
267 while (it != mUsages.end())
268 {
269 usage = it.next();
270 if ((dynamic_cast<ClientSubscription*>(usage) != null) ||
271 (dynamic_cast<ServerSubscription*>(usage) != null))
272 {
273 usageSet.push_back(*usage);
274 }
275 }
276 return usageSet:
277 }
278
279 BaseUsage&
280 Dialog::findRegistration()
281 {
282 std::list<BaseUsage*>::iterator it = mUsages.begin();
283 BaseUsage *usage;
284 while (it != mUsages.end())
285 {
286 usage = it.next();
287 if ((dynamic_cast<CientRegistration*>(usage) != null) ||
288 (dynamic_cast<ServerRegistration*>(usage) != null))
289 {
290 return *usage;
291 }
292 }
293 return BaseUsage::empty();
294 }
295
296
297 BaseUsage&
298 Dialog::findPublication()
299 {
300 std::list<BaseUsage*>::iterator it = mUsages.begin();
301 BaseUsage *usage;
302 while (it != mUsages.end())
303 {
304 usage = it.next();
305 if ((dynamic_cast<CientPublication*>(usage) != null) ||
306 (dynamic_cast<ServerPublication*>(usage) != null))
307 {
308 return *usage;
309 }
310 }
311 return BaseUsage::empty();
312 }
313
314 UsageSet
315 Dialog::findOutOfDialogs()
316 {
317 std::list<BaseUsage*>::iterator it = mUsages.begin();
318 BaseUsage *usage;
319 UsageSet usageSet;
320 while (it != mUsages.end())
321 {
322 usage = it.next();
323 if ((dynamic_cast<ClientOutOfDialogReq*>(usage) != null) ||
324 (dynamic_cast<ServerOutOfDialogReq*>(usage) != null))
325 {
326 usageSet.push_back(*usage);
327 }
328 }
329 return usageSet:
330 }
331
332 void
333 Dialog::dispatch(const SipMessage& msg)
334 {
335 if (msg.isRequest())
336 {
337 switch (request.header(h_RequestLine).getMethod())
338 {
339 // a NOTIFY is the only request that can
340 // create a full dialog (when the 2xx from the
341 // SUBSCRIBE arrives *after* the NOTIFY
342 case NOTIFY :
343 processNotify(msg);
344 break;
345
346 case REFER:
347 // !jf! wierdo
348 // affects an InvSession and a ServerSubscription
349 break;
350
351 case SUBSCRIBE:
352 processSubscribe(msg);
353 break;
354
355 case CANCEL:
356 // should only occur when canceling a re-INVITE
357 case INVITE:
358 // should only occur for a re-INVITE
359 case ACK:
360 case PRACK:
361 case BYE:
362 case UPDATE:
363 case INFO:
364 processInviteRelated(msg);
365 break;
366
367 case REGISTER:
368 {
369 assert(0); // already handled
370 break;
371 }
372
373 case PUBLISH:
374 assert(0);
375 break;
376
377 case MESSAGE:
378 case OPTIONS:
379 assert(0);
380 break;
381
382 default:
383 assert(0);
384 break;
385 }
386 }
387 else if (msg.isResponse())
388 {
389
390 }
391 else
392 {
393 assert(0);
394 }
395 }
396
397 void
398 Dialog::processNotify(const SipMessage& notify)
399 {
400 if (notify.isRequest())
401 {
402 if (findSubscriptions().empty())
403 {
404 SubscriptionCreator* creator = dynamic_cast<SubscriptionCreator*>(DialogSetId(notify).getCreator());
405 if (creator)
406 {
407 creator->makeNewSubscription(notify);
408 }
409 }
410 else
411 {
412 for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
413 {
414 ClientSubscription* sub = dynamic_cast<ClientSubscription*>(*i);
415 if (sub && sub->matches(notify))
416 {
417 sub->process(notify);
418 break;
419 }
420 }
421 }
422 }
423 }
424
425 void
426 Dialog::processSubscribe(const SipMessage& subscribe)
427 {
428 for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
429 {
430 ServerSubscription* sub = dynamic_cast<ServerSubscription*>(*i);
431 if (sub && sub->matches(subscribe))
432 {
433 sub->process(subscribe); // a resubscribe or unsubscribe
434 return;
435 }
436 }
437
438 // a subscribe on an existing dialog with a different BaseUsage
439 ServerSubscription* sub = new ServerSubscription(mDum, subscribe);
440 }
441
442 void
443 Dialog::processInviteRelated(const SipMessage& msg)
444 {
445 for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
446 {
447 ServerInvSession* server = dynamic_cast<ServerInvSession*>(*i);
448 ClientInvSession* client = dynamic_cast<ClientInvSession*>(*i);
449 if (server)
450 {
451 server->process(msg);
452 break;
453 }
454 else if (client)
455 {
456 client->process(msg);
457 break;
458 }
459 }
460 }

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27