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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2588 - (hide annotations) (download)
Sun Apr 11 18:30:31 2004 UTC (15 years, 9 months ago) by jason
File size: 13271 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 jason 2588 mClientSubscriptions(),
16     mServerSubscription(0),
17     mInviteSession(0),
18     mClientRegistration(0),
19     mServerRegistration(0),
20     mClientPublication(0),
21     mServerPublication(0),
22     mClientOutOfDialogReq(0),
23     mServerOutOfDialogReq(0),
24     mType(Fake),
25     mLocalTag(),
26     mRemoteTag(),
27     mCallId(msg.header(h_CallID)),
28     mRouteSet(),
29     mMe(),
30 jason 2577 mLocalCSeq(0),
31     mRemoteCSeq(0),
32 jason 2588 mRemoteTarget()
33 jason 2577 {
34     assert(msg.isFromWire());
35    
36 jason 2588 if (request.header(h_CSeq).method() == INVITE)
37     {
38     mType = Invitation;
39     }
40     else if (request.header(h_CSeq).method() == SUBSCRIBE)
41     {
42     mType = Subscription;
43     }
44    
45 jason 2577 if (msg.isRequest()) // UAS
46     {
47     const SipMessage& request = msg;
48     mRouteSet = request.header(h_RecordRoutes);
49    
50     switch (request.header(h_CSeq).method())
51     {
52     case INVITE:
53     case SUBSRIBE:
54     if (request.exists(h_Contacts) && request.header(h_Contacts).size() == 1)
55     {
56     NameAddr& contact = request.header(h_Contacts).front();
57     if (isEqualNoCase(contact.uri().scheme(), Symbols::Sips) ||
58     isEqualNoCase(contact.uri().scheme(), Symbols::Sip))
59     {
60     mRemoteTarget = contact;
61     }
62     else
63     {
64     InfoLog (<< "Got an INVITE or SUBSCRIBE with invalid scheme");
65     DebugLog (<< request);
66     throw Exception("Invalid dialog", __FILE__, __LINE__);
67     }
68     }
69     else
70     {
71     InfoLog (<< "Got an INVITE or SUBSCRIBE that doesn't have exactly one contact");
72     DebugLog (<< request);
73     throw Exception("Invalid dialog", __FILE__, __LINE__);
74     }
75     break;
76     }
77    
78     mRemoteCSeq = request.header(h_CSeq).sequence();
79     mLocalCSeq = 0;
80    
81     if ( response.header(h_From).exists(p_tag) ) // 2543 compat
82     {
83     mRemoteTag = response.header(h_From).param(p_tag);
84     }
85     if ( response.header(h_To).exists(p_tag) ) // 2543 compat
86     {
87     mLocalTag = response.header(h_To).param(p_tag);
88     }
89     mMe = response.header(h_To);
90    
91     //mDialogId = mCallId;
92     //mDialogId.param(p_toTag) = mLocalTag;
93     //mDialogId.param(p_fromTag) = mRemoteTag;
94     }
95     else if (msg.isResponse())
96     {
97     const SipMessage& response = msg;
98     if (response.exists(h_RecordRoutes))
99     {
100     mRouteSet = response.header(h_RecordRoutes).reverse();
101     }
102    
103     switch (response.header(h_CSeq).method())
104     {
105     case INVITE:
106     case SUBSRIBE:
107     if (response.exists(h_Contacts) && response.header(h_Contacts).size() == 1)
108     {
109     NameAddr& contact = response.header(h_Contacts).front();
110     if (isEqualNoCase(contact.uri().scheme(), Symbols::Sips) ||
111     isEqualNoCase(contact.uri().scheme(), Symbols::Sip))
112     {
113     mRemoteTarget = contact;
114     }
115     else
116     {
117     InfoLog (<< "Got an INVITE or SUBSCRIBE with invalid scheme");
118     DebugLog (<< response);
119     throw Exception("Invalid dialog", __FILE__, __LINE__);
120     }
121     }
122     else
123     {
124     InfoLog (<< "Got an INVITE or SUBSCRIBE that doesn't have exactly one contact");
125     DebugLog (<< response);
126     throw Exception("Invalid dialog", __FILE__, __LINE__);
127     }
128     break;
129     }
130    
131     mLocalCSeq = response.header(h_CSeq).sequence();
132    
133     if ( response.header(h_From).exists(p_tag) ) // 2543 compat
134     {
135     mLocalTag = response.header(h_From).param(p_tag);
136     }
137     if ( response.header(h_To).exists(p_tag) ) // 2543 compat
138     {
139     mRemoteTag = response.header(h_To).param(p_tag);
140     }
141     mMe = response.header(h_From);
142    
143     //mDialogId = mCallId;
144     //mDialogId.param(p_toTag) = mLocalTag;
145     //mDialogId.param(p_fromTag) = mRemoteTag;
146     }
147     }
148    
149 jason 2588 DialogId
150     Dialog::getId() const
151     {
152     return mId;
153     }
154    
155    
156 jason 2578 void
157     Dialog::dispatch(const SipMessage& msg)
158     {
159 jason 2583 BaseUsage* usage = findUsage(msg);
160     if (usage)
161     {
162     usage->dispatch(msg);
163     }
164 jason 2585 else // no matching usage
165 jason 2583 {
166     if (msg.isRequest())
167     {
168     switch (msg.header(h_CSeq).method())
169     {
170     case INVITE: // new INVITE
171     usage = mDum.createServerInviteSession(msg);
172     break;
173    
174     case ACK:
175     case CANCEL:
176     InfoLog (<< "Drop stray ACK or CANCEL in dialog on the floor");
177     DebugLog (<< msg);
178     break;
179    
180     case SUBSCRIBE:
181 jason 2584 case REFER: //!jf! does this create a server subs?
182     usage = mDum.createServerSubscription(msg);
183     break;
184 jason 2583
185 jason 2584 case NOTIFY:
186     usage = mDum.createClientSubscription(msg);
187     break;
188 jason 2583
189 jason 2584 case PUBLISH:
190     usage = mDum.createServerPublication(msg);
191     break;
192    
193     case REGISTER:
194     usage = mDum.createServerRegistration(msg);
195     break;
196    
197     default:
198     usage = mDum.createServerOutOfDialog(msg);
199     break;
200 jason 2583 }
201     }
202     else if (msg.isResponse())
203     {
204 jason 2584 // !jf! should this only be for 2xx responses?
205     switch (msg.header(h_CSeq).method())
206     {
207     case INVITE:
208     usage = mDum.createClientInviteSession(msg);
209     break;
210    
211     case ACK:
212     case CANCEL:
213 jason 2585 // Drop on the floor
214 jason 2584 break;
215    
216     case SUBSCRIBE:
217     case REFER: //!jf! does this create a server subs?
218     usage = mDum.createClientSubscription(msg);
219     break;
220    
221     case NOTIFY:
222     usage = mDum.createClientSubscription(msg);
223     break;
224    
225     case PUBLISH:
226     usage = mDum.createClientPublication(msg);
227     break;
228    
229     case REGISTER:
230     usage = mDum.createClientRegistration(msg);
231     break;
232    
233     default:
234     usage = mDum.createClientOutOfDialog(msg);
235     break;
236     }
237 jason 2583 }
238    
239     assert(usage);
240     mUsages.push_back(usage);
241     }
242 jason 2578 }
243    
244 jason 2583 BaseUsage*
245     Dialog::findUsage(const SipMessage& msg)
246     {
247     switch (msg.header(h_CSeq).method())
248     {
249     case INVITE: // new INVITE
250 jason 2585 case CANCEL:
251     case ACK:
252 jason 2583 return mInviteSession;
253 jason 2585
254 jason 2583 case SUBSCRIBE:
255     case REFER:
256     case NOTIFY:
257 jason 2585 for (std::vector<ClientSubscription*>::iterator i=mClientSubscriptions.begin();
258     i != mClientSubscriptions.end(); i++)
259     {
260     if (i->matches(msg))
261     {
262     return *i;
263     }
264     }
265 jason 2583 break;
266     case REGISTER:
267 jason 2585 InfoLog (<< "Received REGISTER inside an existing dialog. This is not supported. ");
268     DebugLog (<< msg);
269     break;
270    
271 jason 2583 case PUBLISH:
272 jason 2585 if (msg.isRequest())
273     {
274     return mServerPublication;
275     }
276     else if (msg.isRequest())
277     {
278     return mClientPublication;
279     }
280 jason 2583 break;
281 jason 2585
282     default:
283     if (msg.isRequest())
284     {
285     return mServerOutOfDialogReq;
286     }
287     else if (msg.isRequest())
288     {
289     return mClientOutOfDialogReq;
290     }
291     break;
292 jason 2583 }
293 jason 2585 return 0;
294 jason 2583 }
295    
296 ken 2556 DialogId Dialog::getId() const
297 ken 2520 {
298 jason 2583 return mId;
299 ken 2520 }
300    
301     BaseUsage&
302     Dialog::findInvSession()
303     {
304 jason 2583 std::list<BaseUsage*>::iterator it = mUsages.begin();
305 ken 2520 BaseUsage *usage;
306     while (it != mUsages.end())
307     {
308 ken 2556 usage = it->next();
309     if ((dynamic_cast<ClientInviteSession*>(usage) != NULL) ||
310     (dynamic_cast<ServerInviteSession*>(usage) != NULL))
311 ken 2520 {
312     return *usage;
313     }
314     }
315 ken 2521 return BaseUsage::empty();
316 ken 2520 }
317    
318     UsageSet
319     Dialog::findSubscriptions()
320     {
321 ken 2521 std::list<BaseUsage*>::iterator it = mUsages.begin();
322 ken 2520 BaseUsage *usage;
323     UsageSet usageSet;
324     while (it != mUsages.end())
325     {
326     usage = it.next();
327 ken 2521 if ((dynamic_cast<ClientSubscription*>(usage) != null) ||
328     (dynamic_cast<ServerSubscription*>(usage) != null))
329 ken 2520 {
330     usageSet.push_back(*usage);
331     }
332     }
333     return usageSet:
334     }
335    
336     BaseUsage&
337     Dialog::findRegistration()
338     {
339 ken 2521 std::list<BaseUsage*>::iterator it = mUsages.begin();
340 ken 2520 BaseUsage *usage;
341     while (it != mUsages.end())
342     {
343     usage = it.next();
344 ken 2521 if ((dynamic_cast<CientRegistration*>(usage) != null) ||
345     (dynamic_cast<ServerRegistration*>(usage) != null))
346 ken 2520 {
347     return *usage;
348     }
349     }
350 ken 2521 return BaseUsage::empty();
351 ken 2520 }
352    
353    
354     BaseUsage&
355     Dialog::findPublication()
356     {
357 ken 2521 std::list<BaseUsage*>::iterator it = mUsages.begin();
358 ken 2520 BaseUsage *usage;
359     while (it != mUsages.end())
360     {
361     usage = it.next();
362 ken 2521 if ((dynamic_cast<CientPublication*>(usage) != null) ||
363     (dynamic_cast<ServerPublication*>(usage) != null))
364 ken 2520 {
365 ken 2521 return *usage;
366 ken 2520 }
367     }
368 ken 2521 return BaseUsage::empty();
369 ken 2520 }
370    
371     UsageSet
372     Dialog::findOutOfDialogs()
373     {
374 ken 2521 std::list<BaseUsage*>::iterator it = mUsages.begin();
375 ken 2520 BaseUsage *usage;
376     UsageSet usageSet;
377     while (it != mUsages.end())
378     {
379     usage = it.next();
380 ken 2521 if ((dynamic_cast<ClientOutOfDialogReq*>(usage) != null) ||
381     (dynamic_cast<ServerOutOfDialogReq*>(usage) != null))
382 ken 2520 {
383     usageSet.push_back(*usage);
384     }
385     }
386     return usageSet:
387     }
388 jason 2535
389     void
390 jason 2577 Dialog::dispatch(const SipMessage& msg)
391 jason 2539 {
392 jason 2577 if (msg.isRequest())
393 jason 2539 {
394 jason 2577 switch (request.header(h_RequestLine).getMethod())
395     {
396     // a NOTIFY is the only request that can
397     // create a full dialog (when the 2xx from the
398     // SUBSCRIBE arrives *after* the NOTIFY
399     case NOTIFY :
400     processNotify(msg);
401     break;
402 jason 2539
403 jason 2577 case REFER:
404     // !jf! wierdo
405     // affects an InvSession and a ServerSubscription
406     break;
407 jason 2539
408 jason 2577 case SUBSCRIBE:
409     processSubscribe(msg);
410     break;
411 jason 2539
412 jason 2577 case CANCEL:
413     // should only occur when canceling a re-INVITE
414     case INVITE:
415     // should only occur for a re-INVITE
416     case ACK:
417     case PRACK:
418     case BYE:
419     case UPDATE:
420     case INFO:
421     processInviteRelated(msg);
422     break;
423 jason 2539
424 jason 2577 case REGISTER:
425     {
426     assert(0); // already handled
427     break;
428     }
429 jason 2539
430 jason 2577 case PUBLISH:
431     assert(0);
432     break;
433 jason 2539
434 jason 2577 case MESSAGE:
435     case OPTIONS:
436     assert(0);
437     break;
438 jason 2539
439 jason 2577 default:
440     assert(0);
441     break;
442 jason 2539 }
443 jason 2577 }
444     else if (msg.isResponse())
445     {
446    
447     }
448     else
449     {
450     assert(0);
451     }
452 jason 2539 }
453    
454     void
455 jason 2535 Dialog::processNotify(const SipMessage& notify)
456     {
457     if (notify.isRequest())
458     {
459     if (findSubscriptions().empty())
460     {
461     SubscriptionCreator* creator = dynamic_cast<SubscriptionCreator*>(DialogSetId(notify).getCreator());
462     if (creator)
463     {
464     creator->makeNewSubscription(notify);
465     }
466     }
467     else
468     {
469     for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
470     {
471     ClientSubscription* sub = dynamic_cast<ClientSubscription*>(*i);
472     if (sub && sub->matches(notify))
473     {
474     sub->process(notify);
475     break;
476     }
477     }
478     }
479     }
480     }
481 jason 2539
482     void
483     Dialog::processSubscribe(const SipMessage& subscribe)
484     {
485     for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
486     {
487     ServerSubscription* sub = dynamic_cast<ServerSubscription*>(*i);
488     if (sub && sub->matches(subscribe))
489     {
490     sub->process(subscribe); // a resubscribe or unsubscribe
491     return;
492     }
493     }
494    
495     // a subscribe on an existing dialog with a different BaseUsage
496     ServerSubscription* sub = new ServerSubscription(mDum, subscribe);
497     }
498    
499     void
500     Dialog::processInviteRelated(const SipMessage& msg)
501     {
502     for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
503     {
504     ServerInvSession* server = dynamic_cast<ServerInvSession*>(*i);
505     ClientInvSession* client = dynamic_cast<ClientInvSession*>(*i);
506     if (server)
507     {
508     server->process(msg);
509     break;
510     }
511     else if (client)
512     {
513     client->process(msg);
514     break;
515     }
516     }
517     }

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27