1 |
#include "resiprocate/SipStack.hxx" |
2 |
#include "resiprocate/dum/ClientAuthManager.hxx" |
3 |
#include "resiprocate/dum/ClientRegistration.hxx" |
4 |
#include "resiprocate/dum/ClientSubscription.hxx" |
5 |
#include "resiprocate/dum/DialogUsageManager.hxx" |
6 |
#include "resiprocate/dum/RegistrationHandler.hxx" |
7 |
#include "resiprocate/dum/Profile.hxx" |
8 |
#include "resiprocate/dum/PublicationHandler.hxx" |
9 |
#include "resiprocate/dum/SubscriptionHandler.hxx" |
10 |
#include "resiprocate/dum/ServerSubscription.hxx" |
11 |
#include "resiprocate/os/Log.hxx" |
12 |
#include "resiprocate/os/Logger.hxx" |
13 |
#include "resiprocate/os/ParseBuffer.hxx" |
14 |
#include "resiprocate/os/Subsystem.hxx" |
15 |
#include "resiprocate/dum/AppDialogSet.hxx" |
16 |
#include "resiprocate/dum/AppDialog.hxx" |
17 |
#include "resiprocate/dum/AppDialogSetFactory.hxx" |
18 |
#include "resiprocate/Pidf.hxx" |
19 |
//#include "resiprocate/MultipartMixedContents.hxx" |
20 |
#include "resiprocate/GenericContents.hxx" |
21 |
|
22 |
|
23 |
#include <iostream> |
24 |
#include <fstream> |
25 |
|
26 |
#define RESIPROCATE_SUBSYSTEM Subsystem::TEST |
27 |
|
28 |
using namespace resip; |
29 |
using namespace std; |
30 |
|
31 |
class RlsRegistrationHandler : public ClientRegistrationHandler |
32 |
{ |
33 |
public: |
34 |
virtual void onSuccess(ClientRegistrationHandle h, const SipMessage& response) |
35 |
{ |
36 |
InfoLog( << "onSuccess: " << response ); |
37 |
} |
38 |
|
39 |
virtual void onRemoved(ClientRegistrationHandle) |
40 |
{ |
41 |
} |
42 |
|
43 |
virtual void onFailure(ClientRegistrationHandle, const SipMessage& response) |
44 |
{ |
45 |
InfoLog ( << "Client::Failure: " << response ); |
46 |
exit(-1); |
47 |
} |
48 |
}; |
49 |
|
50 |
Contents* readFromFile(string filename) |
51 |
{ |
52 |
ifstream is; |
53 |
is.open (filename.c_str(), ios::binary ); |
54 |
|
55 |
if (!is.good()) |
56 |
{ |
57 |
exit(-1); |
58 |
} |
59 |
|
60 |
// get length of file: |
61 |
is.seekg (0, ios::end); |
62 |
int length = is.tellg(); |
63 |
is.seekg (0, ios::beg); |
64 |
|
65 |
// allocate memory: |
66 |
char* buffer = new char[length]; |
67 |
|
68 |
// read data as a block: |
69 |
is.read (buffer,length); |
70 |
|
71 |
Mime mimeType; |
72 |
|
73 |
ParseBuffer pb(buffer, length); |
74 |
pb.skipChars("Content-Type:"); |
75 |
pb.skipWhitespace(); |
76 |
mimeType.parse(pb); |
77 |
pb.skipChars(Symbols::CRLF); |
78 |
|
79 |
HeaderFieldValue hfv(pb.position(), length - (pb.position() - pb.start())); |
80 |
GenericContents orig(&hfv, mimeType); |
81 |
|
82 |
GenericContents * copy = new GenericContents(orig); |
83 |
delete buffer; |
84 |
return copy; |
85 |
} |
86 |
|
87 |
|
88 |
class RlsServerSubscriptionHandler : public ServerSubscriptionHandler |
89 |
{ |
90 |
public: |
91 |
class RlsSubscription |
92 |
{ |
93 |
public: |
94 |
RlsSubscription() : |
95 |
currentContent(0) |
96 |
{ |
97 |
} |
98 |
|
99 |
RlsSubscription(ServerSubscriptionHandle h, int pos) : |
100 |
handle(h), |
101 |
currentContent(pos) |
102 |
{ |
103 |
} |
104 |
|
105 |
ServerSubscriptionHandle handle; |
106 |
int currentContent; |
107 |
}; |
108 |
|
109 |
//first file is a full notification, no restriction on the rest |
110 |
RlsServerSubscriptionHandler(const vector<string> inputFiles) |
111 |
{ |
112 |
for (vector<string>::const_iterator it = inputFiles.begin(); it != inputFiles.end(); it++) |
113 |
{ |
114 |
mContentsList.push_back(readFromFile(*it)); |
115 |
} |
116 |
} |
117 |
|
118 |
virtual void onNewSubscription(ServerSubscriptionHandle handle, const SipMessage& sub) |
119 |
{ |
120 |
InfoLog ( << "onNewSubscription: " << sub.header(h_RequestLine) << "\t" << |
121 |
sub.header(h_From) << "\t" << handle->getAppDialog()->getDialogId()); |
122 |
assert(mHandleMap.find(handle->getAppDialog()->getDialogId()) == mHandleMap.end()); |
123 |
mHandleMap[handle->getAppDialog()->getDialogId()] = RlsSubscription(handle, 1); |
124 |
handle->send(handle->accept()); |
125 |
SipMessage& notify = handle->update(mContentsList[0]); |
126 |
notify.header(h_Requires).push_back(Token("eventlist")); |
127 |
handle->send(notify); |
128 |
} |
129 |
|
130 |
virtual void onTerminated(ServerSubscriptionHandle sub) |
131 |
{ |
132 |
InfoLog ( << "onTerminated: " << sub->getAppDialog()->getDialogId()); |
133 |
mHandleMap.erase(sub->getAppDialog()->getDialogId()); |
134 |
} |
135 |
|
136 |
//refresh resets to beginning |
137 |
virtual void onRefresh(ServerSubscriptionHandle handle, const SipMessage& sub) |
138 |
{ |
139 |
DialogToHandle::iterator it = mHandleMap.find(handle->getAppDialog()->getDialogId()); |
140 |
if (it == mHandleMap.end()) |
141 |
{ |
142 |
assert(0); |
143 |
} |
144 |
else |
145 |
{ |
146 |
ServerSubscriptionHandle handle = it->second.handle; |
147 |
it->second.currentContent = 0; |
148 |
SipMessage& notify = handle->update(mContentsList[it->second.currentContent++]); |
149 |
notify.header(h_Requires).push_back(Token("eventlist")); |
150 |
handle->send(notify); |
151 |
} |
152 |
} |
153 |
|
154 |
virtual bool hasDefaultExpires() const |
155 |
{ |
156 |
return true; |
157 |
} |
158 |
|
159 |
virtual int getDefaultExpires() const |
160 |
{ |
161 |
return 600; |
162 |
} |
163 |
|
164 |
virtual void sendNextNotify() |
165 |
{ |
166 |
for (DialogToHandle::iterator it = mHandleMap.begin(); it != mHandleMap.end(); it++) |
167 |
{ |
168 |
ServerSubscriptionHandle handle = it->second.handle; |
169 |
if (it->second.currentContent > mContentsList.size()) |
170 |
{ |
171 |
handle->end(); |
172 |
} |
173 |
else |
174 |
{ |
175 |
SipMessage& notify = handle->update(mContentsList[it->second.currentContent++]); |
176 |
notify.header(h_Requires).push_back(Token("eventlist")); |
177 |
handle->send(notify); |
178 |
} |
179 |
} |
180 |
} |
181 |
|
182 |
virtual ~RlsServerSubscriptionHandler() |
183 |
{ |
184 |
//clean up map, contents |
185 |
} |
186 |
private: |
187 |
typedef map<DialogId, RlsSubscription> DialogToHandle; |
188 |
DialogToHandle mHandleMap; |
189 |
typedef vector<Contents*> ContentsList; |
190 |
vector<Contents*> mContentsList; |
191 |
}; |
192 |
|
193 |
|
194 |
int |
195 |
main (int argc, char** argv) |
196 |
{ |
197 |
if (argc == 1) |
198 |
{ |
199 |
cerr << "Usage: rlsServer contentsFile (SPACE contentsFile) << endl"; |
200 |
return -1; |
201 |
} |
202 |
|
203 |
Log::initialize(Log::Cout, Log::Debug, argv[0]); |
204 |
|
205 |
vector<string> inputFiles; |
206 |
for (int i = 1; i < argc; i++) |
207 |
{ |
208 |
inputFiles.push_back(string(argv[i])); |
209 |
} |
210 |
|
211 |
RlsServerSubscriptionHandler subServerHandler(inputFiles); |
212 |
|
213 |
NameAddr from("sip:testRlsServer@internal.xten.net"); |
214 |
Profile profile; |
215 |
profile.setDefaultFrom(from); |
216 |
profile.clearSupportedMethods(); |
217 |
profile.addSupportedMethod(SUBSCRIBE); |
218 |
|
219 |
profile.validateAcceptEnabled() = false; |
220 |
profile.validateContentLanguageEnabled() = false; |
221 |
profile.validateContentEnabled() = false; |
222 |
|
223 |
DialogUsageManager dum; |
224 |
dum.addTransport(UDP, 15060); |
225 |
// dum.addTransport(TCP, 15060); |
226 |
|
227 |
dum.setProfile(&profile); |
228 |
dum.addServerSubscriptionHandler("presence", &subServerHandler); |
229 |
|
230 |
RlsRegistrationHandler regHandler; |
231 |
dum.setClientRegistrationHandler(®Handler); |
232 |
|
233 |
SipMessage & regMessage = dum.makeRegistration(from); |
234 |
InfoLog( << regMessage << "Generated register: " << endl << regMessage ); |
235 |
dum.send( regMessage ); |
236 |
|
237 |
while (true) |
238 |
{ |
239 |
FdSet fdset; |
240 |
dum.buildFdSet(fdset); |
241 |
int err = fdset.selectMilliSeconds(100); |
242 |
assert ( err != -1 ); |
243 |
dum.process(fdset); |
244 |
|
245 |
// char c; |
246 |
// char str[256]; |
247 |
// if (!cin.eof()) |
248 |
// { |
249 |
// c=cin.get(); |
250 |
// if ( c == 'n' || c == 'q') |
251 |
// { |
252 |
// if (c == 'q') |
253 |
// { |
254 |
// break; |
255 |
// } |
256 |
// else |
257 |
// { |
258 |
// subServerHandler.sendNextNotify(); |
259 |
// } |
260 |
// } |
261 |
// else |
262 |
// { |
263 |
// cin >> str; |
264 |
// cout << " You have entered [" << str << "] enter n to send the next notify or q to quit " << endl; |
265 |
// } |
266 |
// } |
267 |
} |
268 |
|
269 |
return 0; |
270 |
|
271 |
} |
272 |
|
273 |
/* ==================================================================== |
274 |
* The Vovida Software License, Version 1.0 |
275 |
* |
276 |
* Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. |
277 |
* |
278 |
* Redistribution and use in source and binary forms, with or without |
279 |
* modification, are permitted provided that the following conditions |
280 |
* are met: |
281 |
* |
282 |
* 1. Redistributions of source code must retain the above copyright |
283 |
* notice, this list of conditions and the following disclaimer. |
284 |
* |
285 |
* 2. Redistributions in binary form must reproduce the above copyright |
286 |
* notice, this list of conditions and the following disclaimer in |
287 |
* the documentation and/or other materials provided with the |
288 |
* distribution. |
289 |
* |
290 |
* 3. The names "VOCAL", "Vovida Open Communication Application Library", |
291 |
* and "Vovida Open Communication Application Library (VOCAL)" must |
292 |
* not be used to endorse or promote products derived from this |
293 |
* software without prior written permission. For written |
294 |
* permission, please contact vocal@vovida.org. |
295 |
* |
296 |
* 4. Products derived from this software may not be called "VOCAL", nor |
297 |
* may "VOCAL" appear in their name, without prior written |
298 |
* permission of Vovida Networks, Inc. |
299 |
* |
300 |
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED |
301 |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
302 |
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND |
303 |
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA |
304 |
* NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES |
305 |
* IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, |
306 |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
307 |
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
308 |
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
309 |
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
310 |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE |
311 |
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
312 |
* DAMAGE. |
313 |
* |
314 |
* ==================================================================== |
315 |
* |
316 |
* This software consists of voluntary contributions made by Vovida |
317 |
* Networks, Inc. and many individuals on behalf of Vovida Networks, |
318 |
* Inc. For more information on Vovida Networks, Inc., please see |
319 |
* <http://www.vovida.org/>. |
320 |
* |
321 |
*/ |