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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2583 - (hide annotations) (download)
Sun Apr 11 17:38:09 2004 UTC (15 years, 8 months ago) by jason
Original Path: main/sip/resiprocate/dum/Dialog.cxx
File size: 10449 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    
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 jason 2578 }
167    
168 jason 2583 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 ken 2556 DialogId Dialog::getId() const
191 ken 2520 {
192 jason 2583 return mId;
193 ken 2520 }
194    
195     BaseUsage&
196     Dialog::findInvSession()
197     {
198 jason 2583 std::list<BaseUsage*>::iterator it = mUsages.begin();
199 ken 2520 BaseUsage *usage;
200     while (it != mUsages.end())
201     {
202 ken 2556 usage = it->next();
203     if ((dynamic_cast<ClientInviteSession*>(usage) != NULL) ||
204     (dynamic_cast<ServerInviteSession*>(usage) != NULL))
205 ken 2520 {
206     return *usage;
207     }
208     }
209 ken 2521 return BaseUsage::empty();
210 ken 2520 }
211    
212     UsageSet
213     Dialog::findSubscriptions()
214     {
215 ken 2521 std::list<BaseUsage*>::iterator it = mUsages.begin();
216 ken 2520 BaseUsage *usage;
217     UsageSet usageSet;
218     while (it != mUsages.end())
219     {
220     usage = it.next();
221 ken 2521 if ((dynamic_cast<ClientSubscription*>(usage) != null) ||
222     (dynamic_cast<ServerSubscription*>(usage) != null))
223 ken 2520 {
224     usageSet.push_back(*usage);
225     }
226     }
227     return usageSet:
228     }
229    
230     BaseUsage&
231     Dialog::findRegistration()
232     {
233 ken 2521 std::list<BaseUsage*>::iterator it = mUsages.begin();
234 ken 2520 BaseUsage *usage;
235     while (it != mUsages.end())
236     {
237     usage = it.next();
238 ken 2521 if ((dynamic_cast<CientRegistration*>(usage) != null) ||
239     (dynamic_cast<ServerRegistration*>(usage) != null))
240 ken 2520 {
241     return *usage;
242     }
243     }
244 ken 2521 return BaseUsage::empty();
245 ken 2520 }
246    
247    
248     BaseUsage&
249     Dialog::findPublication()
250     {
251 ken 2521 std::list<BaseUsage*>::iterator it = mUsages.begin();
252 ken 2520 BaseUsage *usage;
253     while (it != mUsages.end())
254     {
255     usage = it.next();
256 ken 2521 if ((dynamic_cast<CientPublication*>(usage) != null) ||
257     (dynamic_cast<ServerPublication*>(usage) != null))
258 ken 2520 {
259 ken 2521 return *usage;
260 ken 2520 }
261     }
262 ken 2521 return BaseUsage::empty();
263 ken 2520 }
264    
265     UsageSet
266     Dialog::findOutOfDialogs()
267     {
268 ken 2521 std::list<BaseUsage*>::iterator it = mUsages.begin();
269 ken 2520 BaseUsage *usage;
270     UsageSet usageSet;
271     while (it != mUsages.end())
272     {
273     usage = it.next();
274 ken 2521 if ((dynamic_cast<ClientOutOfDialogReq*>(usage) != null) ||
275     (dynamic_cast<ServerOutOfDialogReq*>(usage) != null))
276 ken 2520 {
277     usageSet.push_back(*usage);
278     }
279     }
280     return usageSet:
281     }
282 jason 2535
283     void
284 jason 2577 Dialog::dispatch(const SipMessage& msg)
285 jason 2539 {
286 jason 2577 if (msg.isRequest())
287 jason 2539 {
288 jason 2577 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 jason 2539
297 jason 2577 case REFER:
298     // !jf! wierdo
299     // affects an InvSession and a ServerSubscription
300     break;
301 jason 2539
302 jason 2577 case SUBSCRIBE:
303     processSubscribe(msg);
304     break;
305 jason 2539
306 jason 2577 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 jason 2539
318 jason 2577 case REGISTER:
319     {
320     assert(0); // already handled
321     break;
322     }
323 jason 2539
324 jason 2577 case PUBLISH:
325     assert(0);
326     break;
327 jason 2539
328 jason 2577 case MESSAGE:
329     case OPTIONS:
330     assert(0);
331     break;
332 jason 2539
333 jason 2577 default:
334     assert(0);
335     break;
336 jason 2539 }
337 jason 2577 }
338     else if (msg.isResponse())
339     {
340    
341     }
342     else
343     {
344     assert(0);
345     }
346 jason 2539 }
347    
348     void
349 jason 2535 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 jason 2539
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