|
1 /* |
|
2 * Copyright 2007 Intel Corporation |
|
3 * |
|
4 * Licensed under the Apache License, Version 2.0 (the "License"); |
|
5 * you may not use this file except in compliance with the License. |
|
6 * You may obtain a copy of the License at |
|
7 * |
|
8 * http://www.apache.org/licenses/LICENSE-2.0 |
|
9 * |
|
10 * Unless required by applicable law or agreed to in writing, software |
|
11 * distributed under the License is distributed on an "AS IS" BASIS, |
|
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
13 * See the License for the specific language governing permissions and |
|
14 * limitations under the License. |
|
15 */ |
|
16 |
|
17 #include <map> |
|
18 #include <string> |
|
19 |
|
20 using namespace std; |
|
21 |
|
22 typedef map<unsigned int, dtn_handle_t> HandleMap; |
|
23 |
|
24 HandleMap Handles; |
|
25 static unsigned int HandleID = 1; |
|
26 |
|
27 //---------------------------------------------------------------------- |
|
28 int |
|
29 dtn_open() |
|
30 { |
|
31 dtn_handle_t ret = 0; |
|
32 int err = dtn_open(&ret); |
|
33 if (err != DTN_SUCCESS) { |
|
34 return -1; |
|
35 } |
|
36 |
|
37 unsigned int i = HandleID++; |
|
38 Handles[i] = ret; |
|
39 return i; |
|
40 } |
|
41 |
|
42 //---------------------------------------------------------------------- |
|
43 static dtn_handle_t |
|
44 find_handle(int i) |
|
45 { |
|
46 HandleMap::iterator iter = Handles.find(i); |
|
47 if (iter == Handles.end()) |
|
48 return NULL; |
|
49 return iter->second; |
|
50 } |
|
51 |
|
52 //---------------------------------------------------------------------- |
|
53 void |
|
54 dtn_close(int handle) |
|
55 { |
|
56 dtn_handle_t h = find_handle(handle); |
|
57 if (!h) return; |
|
58 dtn_close(h); |
|
59 } |
|
60 |
|
61 //---------------------------------------------------------------------- |
|
62 int |
|
63 dtn_errno(int handle) |
|
64 { |
|
65 dtn_handle_t h = find_handle(handle); |
|
66 if (!h) return DTN_EINVAL; |
|
67 return dtn_errno(h); |
|
68 } |
|
69 |
|
70 //---------------------------------------------------------------------- |
|
71 string |
|
72 dtn_build_local_eid(int handle, const char* service_tag) |
|
73 { |
|
74 dtn_handle_t h = find_handle(handle); |
|
75 if (!h) return ""; |
|
76 |
|
77 dtn_endpoint_id_t eid; |
|
78 memset(&eid, 0, sizeof(eid)); |
|
79 dtn_build_local_eid(h, &eid, service_tag); |
|
80 return string(eid.uri); |
|
81 } |
|
82 |
|
83 //---------------------------------------------------------------------- |
|
84 static int |
|
85 build_reginfo(dtn_reg_info_t* reginfo, |
|
86 const string& endpoint, |
|
87 unsigned int flags, |
|
88 unsigned int expiration, |
|
89 bool init_passive, |
|
90 const string& script) |
|
91 { |
|
92 memset(reginfo, 0, sizeof(dtn_reg_info_t)); |
|
93 |
|
94 strcpy(reginfo->endpoint.uri, endpoint.c_str()); |
|
95 reginfo->flags = flags; |
|
96 reginfo->expiration = expiration; |
|
97 reginfo->init_passive = init_passive; |
|
98 reginfo->script.script_len = script.length(); |
|
99 reginfo->script.script_val = (char*)script.c_str(); |
|
100 |
|
101 return 0; |
|
102 } |
|
103 |
|
104 //---------------------------------------------------------------------- |
|
105 int |
|
106 dtn_register(int handle, |
|
107 const string& endpoint, |
|
108 unsigned int flags, |
|
109 int expiration, |
|
110 bool init_passive, |
|
111 const string& script) |
|
112 { |
|
113 dtn_handle_t h = find_handle(handle); |
|
114 if (!h) return -1; |
|
115 |
|
116 dtn_reg_info_t reginfo; |
|
117 build_reginfo(®info, endpoint, flags, expiration, |
|
118 init_passive, script); |
|
119 |
|
120 dtn_reg_id_t regid = 0; |
|
121 int ret = dtn_register(h, ®info, ®id); |
|
122 if (ret != DTN_SUCCESS) { |
|
123 return -1; |
|
124 } |
|
125 return regid; |
|
126 } |
|
127 |
|
128 //---------------------------------------------------------------------- |
|
129 int |
|
130 dtn_unregister(int handle, dtn_reg_id_t regid) |
|
131 { |
|
132 dtn_handle_t h = find_handle(handle); |
|
133 if (!h) return -1; |
|
134 |
|
135 return dtn_unregister(h, regid); |
|
136 } |
|
137 |
|
138 //---------------------------------------------------------------------- |
|
139 int |
|
140 dtn_find_registration(int handle, const string& endpoint) |
|
141 { |
|
142 dtn_handle_t h = find_handle(handle); |
|
143 if (!h) return -1; |
|
144 |
|
145 dtn_endpoint_id_t eid; |
|
146 strcpy(eid.uri, endpoint.c_str()); |
|
147 |
|
148 dtn_reg_id_t regid = 0; |
|
149 |
|
150 int err = dtn_find_registration(h, &eid, ®id); |
|
151 if (err != DTN_SUCCESS) { |
|
152 return -1; |
|
153 } |
|
154 |
|
155 return regid; |
|
156 } |
|
157 |
|
158 //---------------------------------------------------------------------- |
|
159 int |
|
160 dtn_change_registration(int handle, |
|
161 dtn_reg_id_t regid, |
|
162 const string& endpoint, |
|
163 unsigned int action, |
|
164 int expiration, |
|
165 bool init_passive, |
|
166 const string& script) |
|
167 { |
|
168 dtn_handle_t h = find_handle(handle); |
|
169 if (!h) return -1; |
|
170 |
|
171 dtn_reg_info_t reginfo; |
|
172 build_reginfo(®info, endpoint, action, expiration, |
|
173 init_passive, script); |
|
174 |
|
175 return dtn_change_registration(h, regid, ®info); |
|
176 } |
|
177 |
|
178 //---------------------------------------------------------------------- |
|
179 int |
|
180 dtn_bind(int handle, int regid) |
|
181 { |
|
182 dtn_handle_t h = find_handle(handle); |
|
183 if (!h) return -1; |
|
184 return dtn_bind(h, regid); |
|
185 } |
|
186 |
|
187 //---------------------------------------------------------------------- |
|
188 int |
|
189 dtn_unbind(int handle, int regid) |
|
190 { |
|
191 dtn_handle_t h = find_handle(handle); |
|
192 if (!h) return -1; |
|
193 return dtn_unbind(h, regid); |
|
194 } |
|
195 |
|
196 //---------------------------------------------------------------------- |
|
197 struct dtn_bundle_id { |
|
198 string source; |
|
199 unsigned int creation_secs; |
|
200 unsigned int creation_seqno; |
|
201 }; |
|
202 |
|
203 //---------------------------------------------------------------------- |
|
204 dtn_bundle_id* |
|
205 dtn_send(int handle, |
|
206 int regid, |
|
207 const string& source, |
|
208 const string& dest, |
|
209 const string& replyto, |
|
210 unsigned int priority, |
|
211 unsigned int dopts, |
|
212 unsigned int expiration, |
|
213 unsigned int payload_location, |
|
214 const string& payload_data, |
|
215 const string& sequence_id = "", |
|
216 const string& obsoletes_id = "") |
|
217 { |
|
218 dtn_handle_t h = find_handle(handle); |
|
219 if (!h) return NULL; |
|
220 |
|
221 dtn_bundle_spec_t spec; |
|
222 memset(&spec, 0, sizeof(spec)); |
|
223 |
|
224 strcpy(spec.source.uri, source.c_str()); |
|
225 strcpy(spec.dest.uri, dest.c_str()); |
|
226 strcpy(spec.replyto.uri, replyto.c_str()); |
|
227 spec.priority = (dtn_bundle_priority_t)priority; |
|
228 spec.dopts = dopts; |
|
229 spec.expiration = expiration; |
|
230 |
|
231 if (sequence_id.length() != 0) { |
|
232 spec.sequence_id.data.data_val = const_cast<char*>(sequence_id.c_str()); |
|
233 spec.sequence_id.data.data_len = sequence_id.length(); |
|
234 } |
|
235 |
|
236 if (obsoletes_id.length() != 0) { |
|
237 spec.obsoletes_id.data.data_val = const_cast<char*>(obsoletes_id.c_str()); |
|
238 spec.obsoletes_id.data.data_len = obsoletes_id.length(); |
|
239 } |
|
240 |
|
241 dtn_bundle_payload_t payload; |
|
242 memset(&payload, 0, sizeof(payload)); |
|
243 |
|
244 switch (payload_location) { |
|
245 case DTN_PAYLOAD_MEM: |
|
246 payload.location = DTN_PAYLOAD_MEM; |
|
247 payload.buf.buf_val = (char*)payload_data.data(); |
|
248 payload.buf.buf_len = payload_data.length(); |
|
249 break; |
|
250 case DTN_PAYLOAD_FILE: |
|
251 payload.location = DTN_PAYLOAD_FILE; |
|
252 payload.filename.filename_val = (char*)payload_data.data(); |
|
253 payload.filename.filename_len = payload_data.length(); |
|
254 break; |
|
255 case DTN_PAYLOAD_TEMP_FILE: |
|
256 payload.location = DTN_PAYLOAD_TEMP_FILE; |
|
257 payload.filename.filename_val = (char*)payload_data.data(); |
|
258 payload.filename.filename_len = payload_data.length(); |
|
259 break; |
|
260 default: |
|
261 dtn_set_errno(h, DTN_EINVAL); |
|
262 return NULL; |
|
263 } |
|
264 |
|
265 dtn_bundle_id_t id; |
|
266 memset(&id, 0, sizeof(id)); |
|
267 int err = dtn_send(h, regid, &spec, &payload, &id); |
|
268 if (err != DTN_SUCCESS) { |
|
269 return NULL; |
|
270 } |
|
271 |
|
272 dtn_bundle_id* ret = new dtn_bundle_id(); |
|
273 ret->source = id.source.uri; |
|
274 ret->creation_secs = id.creation_ts.secs; |
|
275 ret->creation_seqno = id.creation_ts.seqno; |
|
276 |
|
277 return ret; |
|
278 } |
|
279 |
|
280 //---------------------------------------------------------------------- |
|
281 int |
|
282 dtn_cancel(int handle, const dtn_bundle_id& id) |
|
283 { |
|
284 dtn_handle_t h = find_handle(handle); |
|
285 if (!h) return -1; |
|
286 |
|
287 dtn_bundle_id_t id2; |
|
288 strcpy(id2.source.uri, id.source.c_str()); |
|
289 id2.creation_ts.secs = id.creation_secs; |
|
290 id2.creation_ts.seqno = id.creation_seqno; |
|
291 return dtn_cancel(h, &id2); |
|
292 } |
|
293 |
|
294 //---------------------------------------------------------------------- |
|
295 struct dtn_status_report { |
|
296 dtn_bundle_id bundle_id; |
|
297 unsigned int reason; |
|
298 unsigned int flags; |
|
299 unsigned int receipt_ts_secs; |
|
300 unsigned int receipt_ts_seqno; |
|
301 unsigned int custody_ts_secs; |
|
302 unsigned int custody_ts_seqno; |
|
303 unsigned int forwarding_ts_secs; |
|
304 unsigned int forwarding_ts_seqno; |
|
305 unsigned int delivery_ts_secs; |
|
306 unsigned int delivery_ts_seqno; |
|
307 unsigned int deletion_ts_secs; |
|
308 unsigned int deletion_ts_seqno; |
|
309 unsigned int ack_by_app_ts_secs; |
|
310 unsigned int ack_by_app_ts_seqno; |
|
311 }; |
|
312 |
|
313 //---------------------------------------------------------------------- |
|
314 string |
|
315 dtn_status_report_reason_to_str(unsigned int reason) |
|
316 { |
|
317 return dtn_status_report_reason_to_str((dtn_status_report_reason_t)reason); |
|
318 } |
|
319 |
|
320 //---------------------------------------------------------------------- |
|
321 struct dtn_bundle { |
|
322 string source; |
|
323 string dest; |
|
324 string replyto; |
|
325 unsigned int priority; |
|
326 unsigned int dopts; |
|
327 unsigned int expiration; |
|
328 unsigned int creation_secs; |
|
329 unsigned int creation_seqno; |
|
330 unsigned int delivery_regid; |
|
331 string sequence_id; |
|
332 string obsoletes_id; |
|
333 string payload; |
|
334 dtn_status_report* status_report; |
|
335 }; |
|
336 |
|
337 //---------------------------------------------------------------------- |
|
338 dtn_bundle* |
|
339 dtn_recv(int handle, unsigned int payload_location, int timeout) |
|
340 { |
|
341 dtn_handle_t h = find_handle(handle); |
|
342 if (!h) return NULL; |
|
343 |
|
344 dtn_bundle_spec_t spec; |
|
345 memset(&spec, 0, sizeof(spec)); |
|
346 |
|
347 dtn_bundle_payload_t payload; |
|
348 memset(&payload, 0, sizeof(payload)); |
|
349 |
|
350 dtn_bundle_payload_location_t location = |
|
351 (dtn_bundle_payload_location_t)payload_location; |
|
352 |
|
353 int err = dtn_recv(h, &spec, location, &payload, timeout); |
|
354 if (err != DTN_SUCCESS) { |
|
355 return NULL; |
|
356 } |
|
357 |
|
358 dtn_bundle* bundle = new dtn_bundle(); |
|
359 bundle->source = spec.source.uri; |
|
360 bundle->dest = spec.dest.uri; |
|
361 bundle->replyto = spec.replyto.uri; |
|
362 bundle->priority = spec.priority; |
|
363 bundle->dopts = spec.dopts; |
|
364 bundle->expiration = spec.expiration; |
|
365 bundle->creation_secs = spec.creation_ts.secs; |
|
366 bundle->creation_seqno = spec.creation_ts.seqno; |
|
367 bundle->delivery_regid = spec.delivery_regid; |
|
368 |
|
369 switch(location) { |
|
370 case DTN_PAYLOAD_MEM: |
|
371 bundle->payload.assign(payload.buf.buf_val, |
|
372 payload.buf.buf_len); |
|
373 break; |
|
374 case DTN_PAYLOAD_FILE: |
|
375 case DTN_PAYLOAD_TEMP_FILE: |
|
376 bundle->payload.assign(payload.filename.filename_val, |
|
377 payload.filename.filename_len); |
|
378 break; |
|
379 default: |
|
380 dtn_set_errno(h, DTN_EINVAL); |
|
381 return NULL; |
|
382 } |
|
383 |
|
384 if (payload.status_report) { |
|
385 dtn_status_report* sr_dst = new dtn_status_report(); |
|
386 dtn_bundle_status_report_t* sr_src = payload.status_report; |
|
387 |
|
388 sr_dst->bundle_id.source = sr_src->bundle_id.source.uri; |
|
389 sr_dst->bundle_id.creation_secs = sr_src->bundle_id.creation_ts.secs; |
|
390 sr_dst->bundle_id.creation_seqno = sr_src->bundle_id.creation_ts.seqno; |
|
391 sr_dst->reason = sr_src->reason; |
|
392 sr_dst->flags = sr_src->flags; |
|
393 sr_dst->receipt_ts_secs = sr_src->receipt_ts.secs; |
|
394 sr_dst->receipt_ts_seqno = sr_src->receipt_ts.seqno; |
|
395 sr_dst->custody_ts_secs = sr_src->custody_ts.secs; |
|
396 sr_dst->custody_ts_seqno = sr_src->custody_ts.seqno; |
|
397 sr_dst->forwarding_ts_secs = sr_src->forwarding_ts.secs; |
|
398 sr_dst->forwarding_ts_seqno = sr_src->forwarding_ts.seqno; |
|
399 sr_dst->delivery_ts_secs = sr_src->delivery_ts.secs; |
|
400 sr_dst->delivery_ts_seqno = sr_src->delivery_ts.seqno; |
|
401 sr_dst->deletion_ts_secs = sr_src->deletion_ts.secs; |
|
402 sr_dst->deletion_ts_seqno = sr_src->deletion_ts.seqno; |
|
403 sr_dst->ack_by_app_ts_secs = sr_src->ack_by_app_ts.secs; |
|
404 sr_dst->ack_by_app_ts_seqno = sr_src->ack_by_app_ts.seqno; |
|
405 |
|
406 bundle->status_report = sr_dst; |
|
407 } else { |
|
408 bundle->status_report = NULL; |
|
409 } |
|
410 |
|
411 return bundle; |
|
412 } |
|
413 |
|
414 //---------------------------------------------------------------------- |
|
415 struct dtn_session_info { |
|
416 unsigned int status; |
|
417 string session; |
|
418 }; |
|
419 |
|
420 //---------------------------------------------------------------------- |
|
421 dtn_session_info* |
|
422 dtn_session_update(int handle, int timeout) |
|
423 { |
|
424 dtn_handle_t h = find_handle(handle); |
|
425 if (!h) return NULL; |
|
426 |
|
427 unsigned int status = 0; |
|
428 dtn_endpoint_id_t session; |
|
429 memset(&session, 0, sizeof(session)); |
|
430 |
|
431 int err = dtn_session_update(h, &status, &session, timeout); |
|
432 if (err != DTN_SUCCESS) { |
|
433 return NULL; |
|
434 } |
|
435 |
|
436 dtn_session_info* s = new dtn_session_info(); |
|
437 s->status = status; |
|
438 s->session = session.uri; |
|
439 |
|
440 return s; |
|
441 } |
|
442 |
|
443 //---------------------------------------------------------------------- |
|
444 int |
|
445 dtn_poll_fd(int handle) |
|
446 { |
|
447 dtn_handle_t h = find_handle(handle); |
|
448 if (!h) return DTN_EINVAL; |
|
449 |
|
450 return dtn_poll_fd(h); |
|
451 } |
|
452 |
|
453 //---------------------------------------------------------------------- |
|
454 int |
|
455 dtn_begin_poll(int handle, int timeout) |
|
456 { |
|
457 dtn_handle_t h = find_handle(handle); |
|
458 if (!h) return DTN_EINVAL; |
|
459 |
|
460 return dtn_begin_poll(h, timeout); |
|
461 } |
|
462 |
|
463 //---------------------------------------------------------------------- |
|
464 int |
|
465 dtn_cancel_poll(int handle) |
|
466 { |
|
467 dtn_handle_t h = find_handle(handle); |
|
468 if (!h) return DTN_EINVAL; |
|
469 |
|
470 return dtn_cancel_poll(h); |
|
471 } |