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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2585 - (hide annotations) (download)
Sun Apr 11 18:07:52 2004 UTC (15 years, 9 months ago) by jason
Original Path: main/sip/resiprocate/dum/Dialog.cxx
File size: 12781 byte(s)
*** empty log message ***

1 ken 2556 #include "resiprocate/Contents.hxx"
2     //#include "resiprocate/OctetContents.hxx"
3     //#include "resiprocate/HeaderFieldValueList.hxx"
4 ken 2540 #include "resiprocate/sam/Dialog.hxx"
5 ken 2556 #include "resiprocate/sam/ClientInviteSession.hxx"
6 ken 2520
7     using namespace resip;
8     using namespace std;
9    
10 ken 2556 class ServerInviteSession;
11    
12 jason 2577 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 jason 2578 void
130     Dialog::dispatch(const SipMessage& msg)
131     {
132 jason 2583 BaseUsage* usage = findUsage(msg);
133     if (usage)
134     {
135     usage->dispatch(msg);
136     }
137 jason 2585 else // no matching usage
138 jason 2583 {
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 jason 2584 case REFER: //!jf! does this create a server subs?
155     usage = mDum.createServerSubscription(msg);
156     break;
157 jason 2583
158 jason 2584 case NOTIFY:
159     usage = mDum.createClientSubscription(msg);
160     break;
161 jason 2583
162 jason 2584 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 jason 2583 }
174     }
175     else if (msg.isResponse())
176     {
177 jason 2584 // !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 jason 2585 // Drop on the floor
187 jason 2584 break;
188    
189     case SUBSCRIBE:
190     case REFER: //!jf! does this create a server subs?
191     usage = mDum.createClientSubscription(msg);
192     break;
193    
194     case NOTIFY:
195     usage = mDum.createClientSubscription(msg);
196     break;
197    
198     case PUBLISH:
199     usage = mDum.createClientPublication(msg);
200     break;
201    
202     case REGISTER:
203     usage = mDum.createClientRegistration(msg);
204     break;
205    
206     default:
207     usage = mDum.createClientOutOfDialog(msg);
208     break;
209     }
210 jason 2583 }
211    
212     assert(usage);
213     mUsages.push_back(usage);
214     }
215 jason 2578 }
216    
217 jason 2583 BaseUsage*
218     Dialog::findUsage(const SipMessage& msg)
219     {
220     switch (msg.header(h_CSeq).method())
221     {
222     case INVITE: // new INVITE
223 jason 2585 case CANCEL:
224     case ACK:
225 jason 2583 return mInviteSession;
226 jason 2585
227 jason 2583 case SUBSCRIBE:
228     case REFER:
229     case NOTIFY:
230 jason 2585 for (std::vector<ClientSubscription*>::iterator i=mClientSubscriptions.begin();
231     i != mClientSubscriptions.end(); i++)
232     {
233     if (i->matches(msg))
234     {
235     return *i;
236     }
237     }
238 jason 2583 break;
239     case REGISTER:
240 jason 2585 InfoLog (<< "Received REGISTER inside an existing dialog. This is not supported. ");
241     DebugLog (<< msg);
242     break;
243    
244 jason 2583 case PUBLISH:
245 jason 2585 if (msg.isRequest())
246     {
247     return mServerPublication;
248     }
249     else if (msg.isRequest())
250     {
251     return mClientPublication;
252     }
253 jason 2583 break;
254 jason 2585
255     default:
256     if (msg.isRequest())
257     {
258     return mServerOutOfDialogReq;
259     }
260     else if (msg.isRequest())
261     {
262     return mClientOutOfDialogReq;
263     }
264     break;
265 jason 2583 }
266 jason 2585 return 0;
267 jason 2583 }
268    
269 ken 2556 DialogId Dialog::getId() const
270 ken 2520 {
271 jason 2583 return mId;
272 ken 2520 }
273    
274     BaseUsage&
275     Dialog::findInvSession()
276     {
277 jason 2583 std::list<BaseUsage*>::iterator it = mUsages.begin();
278 ken 2520 BaseUsage *usage;
279     while (it != mUsages.end())
280     {
281 ken 2556 usage = it->next();
282     if ((dynamic_cast<ClientInviteSession*>(usage) != NULL) ||
283     (dynamic_cast<ServerInviteSession*>(usage) != NULL))
284 ken 2520 {
285     return *usage;
286     }
287     }
288 ken 2521 return BaseUsage::empty();
289 ken 2520 }
290    
291     UsageSet
292     Dialog::findSubscriptions()
293     {
294 ken 2521 std::list<BaseUsage*>::iterator it = mUsages.begin();
295 ken 2520 BaseUsage *usage;
296     UsageSet usageSet;
297     while (it != mUsages.end())
298     {
299     usage = it.next();
300 ken 2521 if ((dynamic_cast<ClientSubscription*>(usage) != null) ||
301     (dynamic_cast<ServerSubscription*>(usage) != null))
302 ken 2520 {
303     usageSet.push_back(*usage);
304     }
305     }
306     return usageSet:
307     }
308    
309     BaseUsage&
310     Dialog::findRegistration()
311     {
312 ken 2521 std::list<BaseUsage*>::iterator it = mUsages.begin();
313 ken 2520 BaseUsage *usage;
314     while (it != mUsages.end())
315     {
316     usage = it.next();
317 ken 2521 if ((dynamic_cast<CientRegistration*>(usage) != null) ||
318     (dynamic_cast<ServerRegistration*>(usage) != null))
319 ken 2520 {
320     return *usage;
321     }
322     }
323 ken 2521 return BaseUsage::empty();
324 ken 2520 }
325    
326    
327     BaseUsage&
328     Dialog::findPublication()
329     {
330 ken 2521 std::list<BaseUsage*>::iterator it = mUsages.begin();
331 ken 2520 BaseUsage *usage;
332     while (it != mUsages.end())
333     {
334     usage = it.next();
335 ken 2521 if ((dynamic_cast<CientPublication*>(usage) != null) ||
336     (dynamic_cast<ServerPublication*>(usage) != null))
337 ken 2520 {
338 ken 2521 return *usage;
339 ken 2520 }
340     }
341 ken 2521 return BaseUsage::empty();
342 ken 2520 }
343    
344     UsageSet
345     Dialog::findOutOfDialogs()
346     {
347 ken 2521 std::list<BaseUsage*>::iterator it = mUsages.begin();
348 ken 2520 BaseUsage *usage;
349     UsageSet usageSet;
350     while (it != mUsages.end())
351     {
352     usage = it.next();
353 ken 2521 if ((dynamic_cast<ClientOutOfDialogReq*>(usage) != null) ||
354     (dynamic_cast<ServerOutOfDialogReq*>(usage) != null))
355 ken 2520 {
356     usageSet.push_back(*usage);
357     }
358     }
359     return usageSet:
360     }
361 jason 2535
362     void
363 jason 2577 Dialog::dispatch(const SipMessage& msg)
364 jason 2539 {
365 jason 2577 if (msg.isRequest())
366 jason 2539 {
367 jason 2577 switch (request.header(h_RequestLine).getMethod())
368     {
369     // a NOTIFY is the only request that can
370     // create a full dialog (when the 2xx from the
371     // SUBSCRIBE arrives *after* the NOTIFY
372     case NOTIFY :
373     processNotify(msg);
374     break;
375 jason 2539
376 jason 2577 case REFER:
377     // !jf! wierdo
378     // affects an InvSession and a ServerSubscription
379     break;
380 jason 2539
381 jason 2577 case SUBSCRIBE:
382     processSubscribe(msg);
383     break;
384 jason 2539
385 jason 2577 case CANCEL:
386     // should only occur when canceling a re-INVITE
387     case INVITE:
388     // should only occur for a re-INVITE
389     case ACK:
390     case PRACK:
391     case BYE:
392     case UPDATE:
393     case INFO:
394     processInviteRelated(msg);
395     break;
396 jason 2539
397 jason 2577 case REGISTER:
398     {
399     assert(0); // already handled
400     break;
401     }
402 jason 2539
403 jason 2577 case PUBLISH:
404     assert(0);
405     break;
406 jason 2539
407 jason 2577 case MESSAGE:
408     case OPTIONS:
409     assert(0);
410     break;
411 jason 2539
412 jason 2577 default:
413     assert(0);
414     break;
415 jason 2539 }
416 jason 2577 }
417     else if (msg.isResponse())
418     {
419    
420     }
421     else
422     {
423     assert(0);
424     }
425 jason 2539 }
426    
427     void
428 jason 2535 Dialog::processNotify(const SipMessage& notify)
429     {
430     if (notify.isRequest())
431     {
432     if (findSubscriptions().empty())
433     {
434     SubscriptionCreator* creator = dynamic_cast<SubscriptionCreator*>(DialogSetId(notify).getCreator());
435     if (creator)
436     {
437     creator->makeNewSubscription(notify);
438     }
439     }
440     else
441     {
442     for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
443     {
444     ClientSubscription* sub = dynamic_cast<ClientSubscription*>(*i);
445     if (sub && sub->matches(notify))
446     {
447     sub->process(notify);
448     break;
449     }
450     }
451     }
452     }
453     }
454 jason 2539
455     void
456     Dialog::processSubscribe(const SipMessage& subscribe)
457     {
458     for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
459     {
460     ServerSubscription* sub = dynamic_cast<ServerSubscription*>(*i);
461     if (sub && sub->matches(subscribe))
462     {
463     sub->process(subscribe); // a resubscribe or unsubscribe
464     return;
465     }
466     }
467    
468     // a subscribe on an existing dialog with a different BaseUsage
469     ServerSubscription* sub = new ServerSubscription(mDum, subscribe);
470     }
471    
472     void
473     Dialog::processInviteRelated(const SipMessage& msg)
474     {
475     for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
476     {
477     ServerInvSession* server = dynamic_cast<ServerInvSession*>(*i);
478     ClientInvSession* client = dynamic_cast<ClientInvSession*>(*i);
479     if (server)
480     {
481     server->process(msg);
482     break;
483     }
484     else if (client)
485     {
486     client->process(msg);
487     break;
488     }
489     }
490     }

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27