|
1 /* |
|
2 * Copyright 2004-2006 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 #ifdef HAVE_CONFIG_H |
|
18 # include <dtn-config.h> |
|
19 #endif |
|
20 |
|
21 #include <errno.h> |
|
22 #include <stdio.h> |
|
23 #include <stdlib.h> |
|
24 #include <fcntl.h> |
|
25 #include <string.h> |
|
26 #include <limits.h> |
|
27 #include <sys/types.h> |
|
28 #include <sys/socket.h> |
|
29 #include <sys/stat.h> |
|
30 #include <netinet/in.h> |
|
31 #include <stdlib.h> |
|
32 #include <unistd.h> |
|
33 |
|
34 #include "dtn_api.h" |
|
35 #include "dtn_ipc.h" |
|
36 |
|
37 //---------------------------------------------------------------------- |
|
38 int |
|
39 dtn_open(dtn_handle_t* h) |
|
40 { |
|
41 dtnipc_handle_t* handle; |
|
42 |
|
43 handle = (dtnipc_handle_t *) malloc(sizeof(struct dtnipc_handle)); |
|
44 if (!handle) { |
|
45 *h = NULL; |
|
46 return DTN_EINTERNAL; |
|
47 } |
|
48 |
|
49 if (dtnipc_open(handle) != 0) { |
|
50 int ret = handle->err; |
|
51 free(handle); |
|
52 *h = NULL; |
|
53 return ret; |
|
54 } |
|
55 |
|
56 xdr_setpos(&handle->xdr_encode, 0); |
|
57 xdr_setpos(&handle->xdr_decode, 0); |
|
58 |
|
59 *h = (dtn_handle_t)handle; |
|
60 return DTN_SUCCESS; |
|
61 } |
|
62 |
|
63 //---------------------------------------------------------------------- |
|
64 int |
|
65 dtn_close(dtn_handle_t handle) |
|
66 { |
|
67 dtnipc_close((dtnipc_handle_t *)handle); |
|
68 free(handle); |
|
69 return DTN_SUCCESS; |
|
70 } |
|
71 |
|
72 //---------------------------------------------------------------------- |
|
73 int |
|
74 dtn_errno(dtn_handle_t handle) |
|
75 { |
|
76 return ((dtnipc_handle_t*)handle)->err; |
|
77 } |
|
78 |
|
79 //---------------------------------------------------------------------- |
|
80 void |
|
81 dtn_set_errno(dtn_handle_t handle, int err) |
|
82 { |
|
83 ((dtnipc_handle_t*)handle)->err = err; |
|
84 } |
|
85 |
|
86 //---------------------------------------------------------------------- |
|
87 int |
|
88 dtn_build_local_eid(dtn_handle_t h, |
|
89 dtn_endpoint_id_t* local_eid, |
|
90 const char* tag) |
|
91 { |
|
92 int status; |
|
93 dtnipc_handle_t* handle = (dtnipc_handle_t*)h; |
|
94 XDR* xdr_encode = &handle->xdr_encode; |
|
95 XDR* xdr_decode = &handle->xdr_decode; |
|
96 struct dtn_service_tag_t service_tag; |
|
97 |
|
98 // check if the handle is in the middle of poll |
|
99 if (handle->in_poll) { |
|
100 handle->err = DTN_EINPOLL; |
|
101 return -1; |
|
102 } |
|
103 |
|
104 // validate the tag length |
|
105 size_t len = strlen(tag) + 1; |
|
106 if (len > DTN_MAX_ENDPOINT_ID) { |
|
107 handle->err = DTN_EINVAL; |
|
108 return -1; |
|
109 } |
|
110 |
|
111 // pack the request |
|
112 memset(&service_tag, 0, sizeof(service_tag)); |
|
113 memcpy(&service_tag.tag[0], tag, len); |
|
114 if (!xdr_dtn_service_tag_t(xdr_encode, &service_tag)) { |
|
115 handle->err = DTN_EXDR; |
|
116 return -1; |
|
117 } |
|
118 |
|
119 // send the message |
|
120 if (dtnipc_send(handle, DTN_LOCAL_EID) != 0) { |
|
121 return -1; |
|
122 } |
|
123 |
|
124 // get the reply |
|
125 if (dtnipc_recv(handle, &status) < 0) { |
|
126 return -1; |
|
127 } |
|
128 |
|
129 // handle server-side errors |
|
130 if (status != DTN_SUCCESS) { |
|
131 handle->err = status; |
|
132 return -1; |
|
133 } |
|
134 |
|
135 // unpack the response |
|
136 memset(local_eid, 0, sizeof(*local_eid)); |
|
137 if (!xdr_dtn_endpoint_id_t(xdr_decode, local_eid)) { |
|
138 handle->err = DTN_EXDR; |
|
139 return -1; |
|
140 } |
|
141 |
|
142 return 0; |
|
143 } |
|
144 |
|
145 //---------------------------------------------------------------------- |
|
146 int |
|
147 dtn_register(dtn_handle_t h, |
|
148 dtn_reg_info_t *reginfo, |
|
149 dtn_reg_id_t* newregid) |
|
150 { |
|
151 int status; |
|
152 dtnipc_handle_t* handle = (dtnipc_handle_t*)h; |
|
153 XDR* xdr_encode = &handle->xdr_encode; |
|
154 XDR* xdr_decode = &handle->xdr_decode; |
|
155 |
|
156 // check if the handle is in the middle of poll |
|
157 if (handle->in_poll) { |
|
158 handle->err = DTN_EINPOLL; |
|
159 return -1; |
|
160 } |
|
161 |
|
162 // pack the request |
|
163 if (!xdr_dtn_reg_info_t(xdr_encode, reginfo)) { |
|
164 handle->err = DTN_EXDR; |
|
165 return -1; |
|
166 } |
|
167 |
|
168 // send the message |
|
169 if (dtnipc_send(handle, DTN_REGISTER) != 0) { |
|
170 return -1; |
|
171 } |
|
172 |
|
173 // get the reply |
|
174 if (dtnipc_recv(handle, &status) < 0) { |
|
175 return -1; |
|
176 } |
|
177 |
|
178 // handle server-side errors |
|
179 if (status != DTN_SUCCESS) { |
|
180 handle->err = status; |
|
181 return -1; |
|
182 } |
|
183 |
|
184 // unpack the response |
|
185 if (!xdr_dtn_reg_id_t(xdr_decode, newregid)) { |
|
186 handle->err = DTN_EXDR; |
|
187 return -1; |
|
188 } |
|
189 |
|
190 return 0; |
|
191 } |
|
192 |
|
193 //---------------------------------------------------------------------- |
|
194 int |
|
195 dtn_unregister(dtn_handle_t h, dtn_reg_id_t regid) |
|
196 { |
|
197 int status; |
|
198 dtnipc_handle_t* handle = (dtnipc_handle_t*)h; |
|
199 |
|
200 XDR* xdr_encode = &handle->xdr_encode; |
|
201 |
|
202 // check if the handle is in the middle of poll |
|
203 if (handle->in_poll) { |
|
204 handle->err = DTN_EINPOLL; |
|
205 return -1; |
|
206 } |
|
207 |
|
208 // pack the request |
|
209 if (!xdr_dtn_reg_id_t(xdr_encode, ®id)) { |
|
210 handle->err = DTN_EXDR; |
|
211 return -1; |
|
212 } |
|
213 |
|
214 // send the message |
|
215 if (dtnipc_send(handle, DTN_UNREGISTER) != 0) { |
|
216 return -1; |
|
217 } |
|
218 |
|
219 // get the reply |
|
220 if (dtnipc_recv(handle, &status) < 0) { |
|
221 return -1; |
|
222 } |
|
223 |
|
224 // handle server-side errors |
|
225 if (status != DTN_SUCCESS) { |
|
226 handle->err = status; |
|
227 return -1; |
|
228 } |
|
229 |
|
230 return 0; |
|
231 } |
|
232 |
|
233 //---------------------------------------------------------------------- |
|
234 int |
|
235 dtn_find_registration(dtn_handle_t h, |
|
236 dtn_endpoint_id_t *eid, |
|
237 dtn_reg_id_t* regid) |
|
238 { |
|
239 int status; |
|
240 dtnipc_handle_t* handle = (dtnipc_handle_t*)h; |
|
241 XDR* xdr_encode = &handle->xdr_encode; |
|
242 XDR* xdr_decode = &handle->xdr_decode; |
|
243 |
|
244 // check if the handle is in the middle of poll |
|
245 if (handle->in_poll) { |
|
246 handle->err = DTN_EINPOLL; |
|
247 return -1; |
|
248 } |
|
249 |
|
250 // pack the request |
|
251 if (!xdr_dtn_endpoint_id_t(xdr_encode, eid)) { |
|
252 handle->err = DTN_EXDR; |
|
253 return -1; |
|
254 } |
|
255 |
|
256 // send the message |
|
257 if (dtnipc_send(handle, DTN_FIND_REGISTRATION) != 0) { |
|
258 return -1; |
|
259 } |
|
260 |
|
261 // get the reply |
|
262 if (dtnipc_recv(handle, &status) < 0) { |
|
263 return -1; |
|
264 } |
|
265 |
|
266 // handle server-side errors |
|
267 if (status != DTN_SUCCESS) { |
|
268 handle->err = status; |
|
269 return -1; |
|
270 } |
|
271 |
|
272 // unpack the response |
|
273 if (!xdr_dtn_reg_id_t(xdr_decode, regid)) { |
|
274 handle->err = DTN_EXDR; |
|
275 return -1; |
|
276 } |
|
277 |
|
278 return 0; |
|
279 } |
|
280 |
|
281 //---------------------------------------------------------------------- |
|
282 int |
|
283 dtn_change_registration(dtn_handle_t h, |
|
284 dtn_reg_id_t regid, |
|
285 dtn_reg_info_t *reginfo) |
|
286 { |
|
287 (void)regid; |
|
288 (void)reginfo; |
|
289 |
|
290 // XXX/demmer implement me |
|
291 dtnipc_handle_t* handle = (dtnipc_handle_t*)h; |
|
292 |
|
293 // check if the handle is in the middle of poll |
|
294 if (handle->in_poll) { |
|
295 handle->err = DTN_EINPOLL; |
|
296 return -1; |
|
297 } |
|
298 |
|
299 handle->err = DTN_EINTERNAL; |
|
300 return -1; |
|
301 } |
|
302 |
|
303 //---------------------------------------------------------------------- |
|
304 int |
|
305 dtn_bind(dtn_handle_t h, dtn_reg_id_t regid) |
|
306 { |
|
307 dtnipc_handle_t* handle = (dtnipc_handle_t*)h; |
|
308 XDR* xdr_encode = &handle->xdr_encode; |
|
309 |
|
310 // check if the handle is in the middle of poll |
|
311 if (handle->in_poll) { |
|
312 handle->err = DTN_EINPOLL; |
|
313 return -1; |
|
314 } |
|
315 |
|
316 // pack the request |
|
317 if (!xdr_dtn_reg_id_t(xdr_encode, ®id)) { |
|
318 handle->err = DTN_EXDR; |
|
319 return -1; |
|
320 } |
|
321 |
|
322 // send the message |
|
323 if (dtnipc_send_recv(handle, DTN_BIND) < 0) { |
|
324 return -1; |
|
325 } |
|
326 |
|
327 return 0; |
|
328 } |
|
329 |
|
330 //---------------------------------------------------------------------- |
|
331 int |
|
332 dtn_unbind(dtn_handle_t h, dtn_reg_id_t regid) |
|
333 { |
|
334 dtnipc_handle_t* handle = (dtnipc_handle_t*)h; |
|
335 XDR* xdr_encode = &handle->xdr_encode; |
|
336 |
|
337 // check if the handle is in the middle of poll |
|
338 if (handle->in_poll) { |
|
339 handle->err = DTN_EINPOLL; |
|
340 return -1; |
|
341 } |
|
342 |
|
343 // pack the request |
|
344 if (!xdr_dtn_reg_id_t(xdr_encode, ®id)) { |
|
345 handle->err = DTN_EXDR; |
|
346 return -1; |
|
347 } |
|
348 |
|
349 // send the message |
|
350 if (dtnipc_send_recv(handle, DTN_UNBIND) < 0) { |
|
351 return -1; |
|
352 } |
|
353 |
|
354 return 0; |
|
355 } |
|
356 |
|
357 //---------------------------------------------------------------------- |
|
358 int |
|
359 dtn_send(dtn_handle_t h, |
|
360 dtn_reg_id_t regid, |
|
361 dtn_bundle_spec_t* spec, |
|
362 dtn_bundle_payload_t* payload, |
|
363 dtn_bundle_id_t* id) |
|
364 { |
|
365 dtnipc_handle_t* handle = (dtnipc_handle_t*)h; |
|
366 XDR* xdr_encode = &handle->xdr_encode; |
|
367 XDR* xdr_decode = &handle->xdr_decode; |
|
368 |
|
369 // check if the handle is in the middle of poll |
|
370 if (handle->in_poll) { |
|
371 handle->err = DTN_EINPOLL; |
|
372 return -1; |
|
373 } |
|
374 |
|
375 // pack the arguments |
|
376 if ((!xdr_dtn_reg_id_t(xdr_encode, ®id)) || |
|
377 (!xdr_dtn_bundle_spec_t(xdr_encode, spec)) || |
|
378 (!xdr_dtn_bundle_payload_t(xdr_encode, payload))) { |
|
379 handle->err = DTN_EXDR; |
|
380 return -1; |
|
381 } |
|
382 |
|
383 // send the message |
|
384 if (dtnipc_send_recv(handle, DTN_SEND) < 0) { |
|
385 return -1; |
|
386 } |
|
387 |
|
388 // unpack the bundle id return value |
|
389 memset(id, 0, sizeof(id)); |
|
390 |
|
391 if (!xdr_dtn_bundle_id_t(xdr_decode, id)) |
|
392 { |
|
393 handle->err = DTN_EXDR; |
|
394 return DTN_EXDR; |
|
395 } |
|
396 |
|
397 return 0; |
|
398 } |
|
399 |
|
400 //---------------------------------------------------------------------- |
|
401 int |
|
402 dtn_cancel(dtn_handle_t h, |
|
403 dtn_bundle_id_t* id) |
|
404 { |
|
405 dtnipc_handle_t* handle = (dtnipc_handle_t*)h; |
|
406 XDR* xdr_encode = &handle->xdr_encode; |
|
407 |
|
408 // check if the handle is in the middle of poll |
|
409 if (handle->in_poll) { |
|
410 handle->err = DTN_EINPOLL; |
|
411 return -1; |
|
412 } |
|
413 |
|
414 // pack the arguments |
|
415 if (!xdr_dtn_bundle_id_t(xdr_encode, id)) { |
|
416 handle->err = DTN_EXDR; |
|
417 return -1; |
|
418 } |
|
419 |
|
420 // send the message |
|
421 if (dtnipc_send_recv(handle, DTN_CANCEL) < 0) { |
|
422 return -1; |
|
423 } |
|
424 |
|
425 return 0; |
|
426 } |
|
427 |
|
428 //---------------------------------------------------------------------- |
|
429 int |
|
430 dtn_recv(dtn_handle_t h, |
|
431 dtn_bundle_spec_t* spec, |
|
432 dtn_bundle_payload_location_t location, |
|
433 dtn_bundle_payload_t* payload, |
|
434 dtn_timeval_t timeout) |
|
435 { |
|
436 dtnipc_handle_t* handle = (dtnipc_handle_t*)h; |
|
437 XDR* xdr_encode = &handle->xdr_encode; |
|
438 XDR* xdr_decode = &handle->xdr_decode; |
|
439 |
|
440 if (handle->in_poll) { |
|
441 handle->in_poll = 0; |
|
442 |
|
443 int poll_status = 0; |
|
444 if (dtnipc_recv(handle, &poll_status) != 0) { |
|
445 return -1; |
|
446 } |
|
447 |
|
448 if (poll_status != DTN_SUCCESS) { |
|
449 handle->err = poll_status; |
|
450 return -1; |
|
451 } |
|
452 } |
|
453 |
|
454 // zero out the spec and payload structures |
|
455 memset(spec, 0, sizeof(*spec)); |
|
456 memset(payload, 0, sizeof(*payload)); |
|
457 |
|
458 // pack the arguments |
|
459 if ((!xdr_dtn_bundle_payload_location_t(xdr_encode, &location)) || |
|
460 (!xdr_dtn_timeval_t(xdr_encode, &timeout))) |
|
461 { |
|
462 handle->err = DTN_EXDR; |
|
463 return -1; |
|
464 } |
|
465 |
|
466 // send the message |
|
467 if (dtnipc_send_recv(handle, DTN_RECV) < 0) { |
|
468 return -1; |
|
469 } |
|
470 |
|
471 // unpack the bundle |
|
472 if (!xdr_dtn_bundle_spec_t(xdr_decode, spec) || |
|
473 !xdr_dtn_bundle_payload_t(xdr_decode, payload)) |
|
474 { |
|
475 handle->err = DTN_EXDR; |
|
476 return -1; |
|
477 } |
|
478 |
|
479 // if the app requested memory delivery but the payload was too |
|
480 // big, then the API server delivered the bundle in a file |
|
481 // instead, so read in the data here |
|
482 if (location == DTN_PAYLOAD_MEM && payload->location == DTN_PAYLOAD_FILE) |
|
483 { |
|
484 char filename[PATH_MAX]; |
|
485 strncpy(filename, payload->filename.filename_val, PATH_MAX); |
|
486 |
|
487 int fd = open(filename, O_RDONLY, 0); |
|
488 if (fd <= 0) { |
|
489 fprintf(stderr, "DTN API internal error opening payload file %s: %s\n", |
|
490 filename, strerror(errno)); |
|
491 return DTN_EXDR; |
|
492 } |
|
493 |
|
494 struct stat st; |
|
495 if (fstat(fd, &st) != 0) { |
|
496 fprintf(stderr, "DTN API internal error getting stat of payload file: %s\n", |
|
497 strerror(errno)); |
|
498 return DTN_EXDR; |
|
499 } |
|
500 |
|
501 dtn_free_payload(payload); |
|
502 |
|
503 payload->location = DTN_PAYLOAD_MEM; |
|
504 unsigned int len = st.st_size; |
|
505 payload->buf.buf_len = len; |
|
506 payload->buf.buf_val = (char*)malloc(len); |
|
507 |
|
508 char* bp = payload->buf.buf_val; |
|
509 do { |
|
510 int n = read(fd, bp, len); |
|
511 |
|
512 if (n <= 0) { |
|
513 fprintf(stderr, |
|
514 "DTN API internal error reading payload file (%d/%u): %s\n", |
|
515 n, len, strerror(errno)); |
|
516 return DTN_EXDR; |
|
517 } |
|
518 |
|
519 len -= n; |
|
520 bp += n; |
|
521 } while (len > 0); |
|
522 |
|
523 close(fd); |
|
524 |
|
525 if (unlink(filename) != 0) { |
|
526 fprintf(stderr, "DTN API internal error removing payload file %s: %s\n", |
|
527 filename, strerror(errno)); |
|
528 return DTN_EXDR; |
|
529 } |
|
530 } |
|
531 else if (location != payload->location) |
|
532 { |
|
533 fprintf(stderr, |
|
534 "DTN API internal error: location != payload location\n"); |
|
535 // shouldn't happen |
|
536 handle->err = DTN_EXDR; |
|
537 return -1; |
|
538 } |
|
539 |
|
540 return 0; |
|
541 } |
|
542 |
|
543 //---------------------------------------------------------------------- |
|
544 int |
|
545 dtn_session_update(dtn_handle_t h, |
|
546 unsigned int* status, |
|
547 dtn_endpoint_id_t* session, |
|
548 dtn_timeval_t timeout) |
|
549 { |
|
550 dtnipc_handle_t* handle = (dtnipc_handle_t*)h; |
|
551 XDR* xdr_encode = &handle->xdr_encode; |
|
552 XDR* xdr_decode = &handle->xdr_decode; |
|
553 |
|
554 if (handle->in_poll) { |
|
555 handle->in_poll = 0; |
|
556 |
|
557 int poll_status = 0; |
|
558 if (dtnipc_recv(handle, &poll_status) != 0) { |
|
559 return -1; |
|
560 } |
|
561 |
|
562 if (poll_status != DTN_SUCCESS) { |
|
563 handle->err = poll_status; |
|
564 return -1; |
|
565 } |
|
566 } |
|
567 |
|
568 // pack the arguments |
|
569 if ((!xdr_dtn_timeval_t(xdr_encode, &timeout))) |
|
570 { |
|
571 handle->err = DTN_EXDR; |
|
572 return -1; |
|
573 } |
|
574 |
|
575 // send the message |
|
576 if (dtnipc_send_recv(handle, DTN_SESSION_UPDATE) < 0) { |
|
577 return -1; |
|
578 } |
|
579 |
|
580 memset(status, 0, sizeof(*status)); |
|
581 memset(session, 0, sizeof(*session)); |
|
582 |
|
583 // unpack the status / session |
|
584 if (!xdr_u_int(xdr_decode, status) || |
|
585 !xdr_dtn_endpoint_id_t(xdr_decode, session)) |
|
586 { |
|
587 handle->err = DTN_EXDR; |
|
588 return -1; |
|
589 } |
|
590 |
|
591 return 0; |
|
592 } |
|
593 |
|
594 //---------------------------------------------------------------------- |
|
595 int |
|
596 dtn_poll_fd(dtn_handle_t h) |
|
597 { |
|
598 dtnipc_handle_t* handle = (dtnipc_handle_t*)h; |
|
599 return handle->sock; |
|
600 } |
|
601 |
|
602 //---------------------------------------------------------------------- |
|
603 int |
|
604 dtn_begin_poll(dtn_handle_t h, dtn_timeval_t timeout) |
|
605 { |
|
606 dtnipc_handle_t* handle = (dtnipc_handle_t*)h; |
|
607 XDR* xdr_encode = &handle->xdr_encode; |
|
608 |
|
609 // check if the handle is already in the middle of poll |
|
610 if (handle->in_poll) { |
|
611 handle->err = DTN_EINPOLL; |
|
612 return -1; |
|
613 } |
|
614 |
|
615 handle->in_poll = 1; |
|
616 |
|
617 if ((!xdr_dtn_timeval_t(xdr_encode, &timeout))) |
|
618 { |
|
619 handle->err = DTN_EXDR; |
|
620 return -1; |
|
621 } |
|
622 |
|
623 // send the message but don't block for the response code -- we'll |
|
624 // grab it in dtn_recv or dtn_cancel_poll |
|
625 if (dtnipc_send(handle, DTN_BEGIN_POLL) < 0) { |
|
626 return -1; |
|
627 } |
|
628 |
|
629 return handle->sock; |
|
630 } |
|
631 |
|
632 //---------------------------------------------------------------------- |
|
633 int |
|
634 dtn_cancel_poll(dtn_handle_t h) |
|
635 { |
|
636 dtnipc_handle_t* handle = (dtnipc_handle_t*)h; |
|
637 |
|
638 // make sure the handle is already in the middle of poll |
|
639 if (! (handle->in_poll)) { |
|
640 handle->err = DTN_EINVAL; |
|
641 return -1; |
|
642 } |
|
643 |
|
644 // clear the poll flag |
|
645 handle->in_poll = 0; |
|
646 |
|
647 // send the message and get two response codes, one from poll |
|
648 // command, and one from the cancel request. |
|
649 int poll_status = dtnipc_send_recv(handle, DTN_CANCEL_POLL); |
|
650 if (poll_status != DTN_SUCCESS && poll_status != DTN_ETIMEOUT) { |
|
651 handle->err = poll_status; |
|
652 return -1; |
|
653 } |
|
654 |
|
655 int cancel_status; |
|
656 if (dtnipc_recv(handle, &cancel_status) != 0) { |
|
657 return -1; |
|
658 } |
|
659 handle->err = cancel_status; |
|
660 |
|
661 if (cancel_status != DTN_SUCCESS) { |
|
662 return -1; |
|
663 } |
|
664 |
|
665 return 0; |
|
666 } |
|
667 |
|
668 /************************************************************* |
|
669 * |
|
670 * Utility Functions |
|
671 * |
|
672 *************************************************************/ |
|
673 void |
|
674 dtn_copy_eid(dtn_endpoint_id_t* dst, dtn_endpoint_id_t* src) |
|
675 { |
|
676 memcpy(dst->uri, src->uri, DTN_MAX_ENDPOINT_ID); |
|
677 } |
|
678 |
|
679 //---------------------------------------------------------------------- |
|
680 int |
|
681 dtn_parse_eid_string(dtn_endpoint_id_t* eid, const char* str) |
|
682 { |
|
683 char *s; |
|
684 size_t len; |
|
685 |
|
686 len = strlen(str) + 1; |
|
687 |
|
688 // check string length |
|
689 if (len > DTN_MAX_ENDPOINT_ID) { |
|
690 return DTN_ESIZE; |
|
691 } |
|
692 |
|
693 // make sure there's a colon |
|
694 s = strchr(str, ':'); |
|
695 if (!s) { |
|
696 return DTN_EINVAL; |
|
697 } |
|
698 |
|
699 // XXX/demmer make sure the scheme / ssp are comprised only of |
|
700 // legal URI characters |
|
701 memcpy(&eid->uri[0], str, len); |
|
702 |
|
703 return 0; |
|
704 } |
|
705 |
|
706 //---------------------------------------------------------------------- |
|
707 int |
|
708 dtn_set_payload(dtn_bundle_payload_t* payload, |
|
709 dtn_bundle_payload_location_t location, |
|
710 char* val, int len) |
|
711 { |
|
712 memset(payload, 0, sizeof(dtn_bundle_payload_t)); |
|
713 payload->location = location; |
|
714 |
|
715 if (location == DTN_PAYLOAD_MEM && len > DTN_MAX_BUNDLE_MEM) { |
|
716 return DTN_ESIZE; |
|
717 } |
|
718 |
|
719 switch (location) { |
|
720 case DTN_PAYLOAD_MEM: |
|
721 payload->buf.buf_val = val; |
|
722 payload->buf.buf_len = len; |
|
723 break; |
|
724 case DTN_PAYLOAD_FILE: |
|
725 case DTN_PAYLOAD_TEMP_FILE: |
|
726 payload->filename.filename_val = val; |
|
727 payload->filename.filename_len = len; |
|
728 break; |
|
729 } |
|
730 |
|
731 return 0; |
|
732 } |
|
733 |
|
734 //---------------------------------------------------------------------- |
|
735 void |
|
736 dtn_free_payload(dtn_bundle_payload_t* payload) |
|
737 { |
|
738 xdr_free((xdrproc_t)xdr_dtn_bundle_payload_t, (char*)payload); |
|
739 } |
|
740 |
|
741 //---------------------------------------------------------------------- |
|
742 const char* |
|
743 dtn_status_report_reason_to_str(dtn_status_report_reason_t reason) |
|
744 { |
|
745 switch (reason) { |
|
746 case REASON_NO_ADDTL_INFO: |
|
747 return "no additional information"; |
|
748 |
|
749 case REASON_LIFETIME_EXPIRED: |
|
750 return "lifetime expired"; |
|
751 |
|
752 case REASON_FORWARDED_UNIDIR_LINK: |
|
753 return "forwarded over unidirectional link"; |
|
754 |
|
755 case REASON_TRANSMISSION_CANCELLED: |
|
756 return "transmission cancelled"; |
|
757 |
|
758 case REASON_DEPLETED_STORAGE: |
|
759 return "depleted storage"; |
|
760 |
|
761 case REASON_ENDPOINT_ID_UNINTELLIGIBLE: |
|
762 return "endpoint id unintelligible"; |
|
763 |
|
764 case REASON_NO_ROUTE_TO_DEST: |
|
765 return "no known route to destination"; |
|
766 |
|
767 case REASON_NO_TIMELY_CONTACT: |
|
768 return "no timely contact"; |
|
769 |
|
770 case REASON_BLOCK_UNINTELLIGIBLE: |
|
771 return "block unintelligible"; |
|
772 |
|
773 default: |
|
774 return "(unknown reason)"; |
|
775 } |
|
776 } |