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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2577 - (show annotations) (download)
Sun Apr 11 01:23:13 2004 UTC (15 years, 9 months ago) by jason
File size: 9322 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 BaseUsage* usage = mCreator->makeUsage(response);
72 assert(usage);
73 mUsages.push_back(usage);
74
75 }
76 else if (msg.isResponse())
77 {
78 const SipMessage& response = msg;
79 if (response.exists(h_RecordRoutes))
80 {
81 mRouteSet = response.header(h_RecordRoutes).reverse();
82 }
83
84 switch (response.header(h_CSeq).method())
85 {
86 case INVITE:
87 case SUBSRIBE:
88 if (response.exists(h_Contacts) && response.header(h_Contacts).size() == 1)
89 {
90 NameAddr& contact = response.header(h_Contacts).front();
91 if (isEqualNoCase(contact.uri().scheme(), Symbols::Sips) ||
92 isEqualNoCase(contact.uri().scheme(), Symbols::Sip))
93 {
94 mRemoteTarget = contact;
95 }
96 else
97 {
98 InfoLog (<< "Got an INVITE or SUBSCRIBE with invalid scheme");
99 DebugLog (<< response);
100 throw Exception("Invalid dialog", __FILE__, __LINE__);
101 }
102 }
103 else
104 {
105 InfoLog (<< "Got an INVITE or SUBSCRIBE that doesn't have exactly one contact");
106 DebugLog (<< response);
107 throw Exception("Invalid dialog", __FILE__, __LINE__);
108 }
109 break;
110 }
111
112 mLocalCSeq = response.header(h_CSeq).sequence();
113
114 if ( response.header(h_From).exists(p_tag) ) // 2543 compat
115 {
116 mLocalTag = response.header(h_From).param(p_tag);
117 }
118 if ( response.header(h_To).exists(p_tag) ) // 2543 compat
119 {
120 mRemoteTag = response.header(h_To).param(p_tag);
121 }
122 mMe = response.header(h_From);
123
124 //mDialogId = mCallId;
125 //mDialogId.param(p_toTag) = mLocalTag;
126 //mDialogId.param(p_fromTag) = mRemoteTag;
127
128 BaseUsage* usage = mCreator->makeUsage(response);
129 assert(usage);
130 mUsages.push_back(usage);
131 }
132 }
133
134 DialogId Dialog::getId() const
135 {
136 return mId;
137 }
138
139 BaseUsage&
140 Dialog::findInvSession()
141 {
142 std::list<BaseUsage*>::iterator it = mUsages.begin();
143 BaseUsage *usage;
144 while (it != mUsages.end())
145 {
146 usage = it->next();
147 if ((dynamic_cast<ClientInviteSession*>(usage) != NULL) ||
148 (dynamic_cast<ServerInviteSession*>(usage) != NULL))
149 {
150 return *usage;
151 }
152 }
153 return BaseUsage::empty();
154 }
155
156 UsageSet
157 Dialog::findSubscriptions()
158 {
159 std::list<BaseUsage*>::iterator it = mUsages.begin();
160 BaseUsage *usage;
161 UsageSet usageSet;
162 while (it != mUsages.end())
163 {
164 usage = it.next();
165 if ((dynamic_cast<ClientSubscription*>(usage) != null) ||
166 (dynamic_cast<ServerSubscription*>(usage) != null))
167 {
168 usageSet.push_back(*usage);
169 }
170 }
171 return usageSet:
172 }
173
174 BaseUsage&
175 Dialog::findRegistration()
176 {
177 std::list<BaseUsage*>::iterator it = mUsages.begin();
178 BaseUsage *usage;
179 while (it != mUsages.end())
180 {
181 usage = it.next();
182 if ((dynamic_cast<CientRegistration*>(usage) != null) ||
183 (dynamic_cast<ServerRegistration*>(usage) != null))
184 {
185 return *usage;
186 }
187 }
188 return BaseUsage::empty();
189 }
190
191
192 BaseUsage&
193 Dialog::findPublication()
194 {
195 std::list<BaseUsage*>::iterator it = mUsages.begin();
196 BaseUsage *usage;
197 while (it != mUsages.end())
198 {
199 usage = it.next();
200 if ((dynamic_cast<CientPublication*>(usage) != null) ||
201 (dynamic_cast<ServerPublication*>(usage) != null))
202 {
203 return *usage;
204 }
205 }
206 return BaseUsage::empty();
207 }
208
209 UsageSet
210 Dialog::findOutOfDialogs()
211 {
212 std::list<BaseUsage*>::iterator it = mUsages.begin();
213 BaseUsage *usage;
214 UsageSet usageSet;
215 while (it != mUsages.end())
216 {
217 usage = it.next();
218 if ((dynamic_cast<ClientOutOfDialogReq*>(usage) != null) ||
219 (dynamic_cast<ServerOutOfDialogReq*>(usage) != null))
220 {
221 usageSet.push_back(*usage);
222 }
223 }
224 return usageSet:
225 }
226
227 void
228 Dialog::dispatch(const SipMessage& msg)
229 {
230 if (msg.isRequest())
231 {
232 switch (request.header(h_RequestLine).getMethod())
233 {
234 // a NOTIFY is the only request that can
235 // create a full dialog (when the 2xx from the
236 // SUBSCRIBE arrives *after* the NOTIFY
237 case NOTIFY :
238 processNotify(msg);
239 break;
240
241 case REFER:
242 // !jf! wierdo
243 // affects an InvSession and a ServerSubscription
244 break;
245
246 case SUBSCRIBE:
247 processSubscribe(msg);
248 break;
249
250 case CANCEL:
251 // should only occur when canceling a re-INVITE
252 case INVITE:
253 // should only occur for a re-INVITE
254 case ACK:
255 case PRACK:
256 case BYE:
257 case UPDATE:
258 case INFO:
259 processInviteRelated(msg);
260 break;
261
262 case REGISTER:
263 {
264 assert(0); // already handled
265 break;
266 }
267
268 case PUBLISH:
269 assert(0);
270 break;
271
272 case MESSAGE:
273 case OPTIONS:
274 assert(0);
275 break;
276
277 default:
278 assert(0);
279 break;
280 }
281 }
282 else if (msg.isResponse())
283 {
284
285 }
286 else
287 {
288 assert(0);
289 }
290 }
291
292 void
293 Dialog::processNotify(const SipMessage& notify)
294 {
295 if (notify.isRequest())
296 {
297 if (findSubscriptions().empty())
298 {
299 SubscriptionCreator* creator = dynamic_cast<SubscriptionCreator*>(DialogSetId(notify).getCreator());
300 if (creator)
301 {
302 creator->makeNewSubscription(notify);
303 }
304 }
305 else
306 {
307 for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
308 {
309 ClientSubscription* sub = dynamic_cast<ClientSubscription*>(*i);
310 if (sub && sub->matches(notify))
311 {
312 sub->process(notify);
313 break;
314 }
315 }
316 }
317 }
318 }
319
320 void
321 Dialog::processSubscribe(const SipMessage& subscribe)
322 {
323 for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
324 {
325 ServerSubscription* sub = dynamic_cast<ServerSubscription*>(*i);
326 if (sub && sub->matches(subscribe))
327 {
328 sub->process(subscribe); // a resubscribe or unsubscribe
329 return;
330 }
331 }
332
333 // a subscribe on an existing dialog with a different BaseUsage
334 ServerSubscription* sub = new ServerSubscription(mDum, subscribe);
335 }
336
337 void
338 Dialog::processInviteRelated(const SipMessage& msg)
339 {
340 for (std::list<BaseUsage*>::iterator i=mUsages.begin(); i!=mUsages.end(); i++)
341 {
342 ServerInvSession* server = dynamic_cast<ServerInvSession*>(*i);
343 ClientInvSession* client = dynamic_cast<ClientInvSession*>(*i);
344 if (server)
345 {
346 server->process(msg);
347 break;
348 }
349 else if (client)
350 {
351 client->process(msg);
352 break;
353 }
354 }
355 }

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27