/[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 2584 - (hide annotations) (download)
Sun Apr 11 17:48:59 2004 UTC (15 years, 9 months ago) by jason
File size: 12037 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     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 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     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 jason 2583 }
210    
211     BaseUsage* usage = mCreator->makeUsage(msg);
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     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 ken 2556 DialogId Dialog::getId() const
240 ken 2520 {
241 jason 2583 return mId;
242 ken 2520 }
243    
244     BaseUsage&
245     Dialog::findInvSession()
246     {
247 jason 2583 std::list<BaseUsage*>::iterator it = mUsages.begin();
248 ken 2520 BaseUsage *usage;
249     while (it != mUsages.end())
250     {
251 ken 2556 usage = it->next();
252     if ((dynamic_cast<ClientInviteSession*>(usage) != NULL) ||
253     (dynamic_cast<ServerInviteSession*>(usage) != NULL))
254 ken 2520 {
255     return *usage;
256     }
257     }
258 ken 2521 return BaseUsage::empty();
259 ken 2520 }
260    
261     UsageSet
262     Dialog::findSubscriptions()
263     {
264 ken 2521 std::list<BaseUsage*>::iterator it = mUsages.begin();
265 ken 2520 BaseUsage *usage;
266     UsageSet usageSet;
267     while (it != mUsages.end())
268     {
269     usage = it.next();
270 ken 2521 if ((dynamic_cast<ClientSubscription*>(usage) != null) ||
271     (dynamic_cast<ServerSubscription*>(usage) != null))
272 ken 2520 {
273     usageSet.push_back(*usage);
274     }
275     }
276     return usageSet:
277     }
278    
279     BaseUsage&
280     Dialog::findRegistration()
281     {
282 ken 2521 std::list<BaseUsage*>::iterator it = mUsages.begin();
283 ken 2520 BaseUsage *usage;
284     while (it != mUsages.end())
285     {
286     usage = it.next();
287 ken 2521 if ((dynamic_cast<CientRegistration*>(usage) != null) ||
288     (dynamic_cast<ServerRegistration*>(usage) != null))
289 ken 2520 {
290     return *usage;
291     }
292     }
293 ken 2521 return BaseUsage::empty();
294 ken 2520 }
295    
296    
297     BaseUsage&
298     Dialog::findPublication()
299     {
300 ken 2521 std::list<BaseUsage*>::iterator it = mUsages.begin();
301 ken 2520 BaseUsage *usage;
302     while (it != mUsages.end())
303     {
304     usage = it.next();
305 ken 2521 if ((dynamic_cast<CientPublication*>(usage) != null) ||
306     (dynamic_cast<ServerPublication*>(usage) != null))
307 ken 2520 {
308 ken 2521 return *usage;
309 ken 2520 }
310     }
311 ken 2521 return BaseUsage::empty();
312 ken 2520 }
313    
314     UsageSet
315     Dialog::findOutOfDialogs()
316     {
317 ken 2521 std::list<BaseUsage*>::iterator it = mUsages.begin();
318 ken 2520 BaseUsage *usage;
319     UsageSet usageSet;
320     while (it != mUsages.end())
321     {
322     usage = it.next();
323 ken 2521 if ((dynamic_cast<ClientOutOfDialogReq*>(usage) != null) ||
324     (dynamic_cast<ServerOutOfDialogReq*>(usage) != null))
325 ken 2520 {
326     usageSet.push_back(*usage);
327     }
328     }
329     return usageSet:
330     }
331 jason 2535
332     void
333 jason 2577 Dialog::dispatch(const SipMessage& msg)
334 jason 2539 {
335 jason 2577 if (msg.isRequest())
336 jason 2539 {
337 jason 2577 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 jason 2539
346 jason 2577 case REFER:
347     // !jf! wierdo
348     // affects an InvSession and a ServerSubscription
349     break;
350 jason 2539
351 jason 2577 case SUBSCRIBE:
352     processSubscribe(msg);
353     break;
354 jason 2539
355 jason 2577 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 jason 2539
367 jason 2577 case REGISTER:
368     {
369     assert(0); // already handled
370     break;
371     }
372 jason 2539
373 jason 2577 case PUBLISH:
374     assert(0);
375     break;
376 jason 2539
377 jason 2577 case MESSAGE:
378     case OPTIONS:
379     assert(0);
380     break;
381 jason 2539
382 jason 2577 default:
383     assert(0);
384     break;
385 jason 2539 }
386 jason 2577 }
387     else if (msg.isResponse())
388     {
389    
390     }
391     else
392     {
393     assert(0);
394     }
395 jason 2539 }
396    
397     void
398 jason 2535 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 jason 2539
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