00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <errno.h>
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include <sys/types.h>
00023 #include <sys/socket.h>
00024 #include <netinet/in.h>
00025 #include <stdlib.h>
00026
00027 #include "dtn_api.h"
00028 #include "dtn_ipc.h"
00029
00030
00031 int
00032 dtn_open(dtn_handle_t* h)
00033 {
00034 dtnipc_handle_t* handle;
00035
00036 handle = (dtnipc_handle_t *) malloc(sizeof(struct dtnipc_handle));
00037 if (!handle) {
00038 *h = NULL;
00039 return DTN_EINTERNAL;
00040 }
00041
00042 if (dtnipc_open(handle) != 0) {
00043 int ret = handle->err;
00044 free(handle);
00045 *h = NULL;
00046 return ret;
00047 }
00048
00049 xdr_setpos(&handle->xdr_encode, 0);
00050 xdr_setpos(&handle->xdr_decode, 0);
00051
00052 *h = (dtn_handle_t)handle;
00053 return DTN_SUCCESS;
00054 }
00055
00056
00057 int
00058 dtn_close(dtn_handle_t handle)
00059 {
00060 dtnipc_close((dtnipc_handle_t *)handle);
00061 free(handle);
00062 return DTN_SUCCESS;
00063 }
00064
00065
00066 int
00067 dtn_errno(dtn_handle_t handle)
00068 {
00069 return ((dtnipc_handle_t*)handle)->err;
00070 }
00071
00072
00073 char*
00074 dtn_strerror(int err)
00075 {
00076 switch(err) {
00077 case DTN_SUCCESS: return "success";
00078 case DTN_EINVAL: return "invalid argument";
00079 case DTN_EXDR: return "error in xdr routines";
00080 case DTN_ECOMM: return "error in ipc communication";
00081 case DTN_ECONNECT: return "error connecting to server";
00082 case DTN_ETIMEOUT: return "operation timed out";
00083 case DTN_ESIZE: return "payload too large";
00084 case DTN_ENOTFOUND: return "not found";
00085 case DTN_EINTERNAL: return "internal error";
00086 case DTN_EINPOLL: return "illegal operation called after dtn_poll";
00087 case DTN_EBUSY: return "registration already in use";
00088 case DTN_EMSGTYPE: return "unknown ipc message type";
00089 case DTN_ENOSPACE: return "no storage space";
00090 case -1: return "(invalid error code -1)";
00091 }
00092
00093
00094
00095
00096
00097 static char buf[128];
00098 snprintf(buf, sizeof(buf), "(unknown error %d)", err);
00099 return buf;
00100 }
00101
00102
00103 int
00104 dtn_build_local_eid(dtn_handle_t h,
00105 dtn_endpoint_id_t* local_eid,
00106 const char* tag)
00107 {
00108 int status;
00109 dtnipc_handle_t* handle = (dtnipc_handle_t*)h;
00110 XDR* xdr_encode = &handle->xdr_encode;
00111 XDR* xdr_decode = &handle->xdr_decode;
00112 struct dtn_service_tag_t service_tag;
00113
00114
00115 if (handle->in_poll) {
00116 handle->err = DTN_EINPOLL;
00117 return -1;
00118 }
00119
00120
00121 size_t len = strlen(tag) + 1;
00122 if (len > DTN_MAX_ENDPOINT_ID) {
00123 handle->err = DTN_EINVAL;
00124 return -1;
00125 }
00126
00127
00128 memset(&service_tag, 0, sizeof(service_tag));
00129 memcpy(&service_tag.tag[0], tag, len);
00130 if (!xdr_dtn_service_tag_t(xdr_encode, &service_tag)) {
00131 handle->err = DTN_EXDR;
00132 return -1;
00133 }
00134
00135
00136 if (dtnipc_send(handle, DTN_LOCAL_EID) != 0) {
00137 return -1;
00138 }
00139
00140
00141 if (dtnipc_recv(handle, &status) < 0) {
00142 return -1;
00143 }
00144
00145
00146 if (status != DTN_SUCCESS) {
00147 handle->err = status;
00148 return -1;
00149 }
00150
00151
00152 memset(local_eid, 0, sizeof(*local_eid));
00153 if (!xdr_dtn_endpoint_id_t(xdr_decode, local_eid)) {
00154 handle->err = DTN_EXDR;
00155 return -1;
00156 }
00157
00158 return 0;
00159 }
00160
00161
00162 int
00163 dtn_register(dtn_handle_t h,
00164 dtn_reg_info_t *reginfo,
00165 dtn_reg_id_t* newregid)
00166 {
00167 int status;
00168 dtnipc_handle_t* handle = (dtnipc_handle_t*)h;
00169 XDR* xdr_encode = &handle->xdr_encode;
00170 XDR* xdr_decode = &handle->xdr_decode;
00171
00172
00173 if (handle->in_poll) {
00174 handle->err = DTN_EINPOLL;
00175 return -1;
00176 }
00177
00178
00179 if (!xdr_dtn_reg_info_t(xdr_encode, reginfo)) {
00180 handle->err = DTN_EXDR;
00181 return -1;
00182 }
00183
00184
00185 if (dtnipc_send(handle, DTN_REGISTER) != 0) {
00186 return -1;
00187 }
00188
00189
00190 if (dtnipc_recv(handle, &status) < 0) {
00191 return -1;
00192 }
00193
00194
00195 if (status != DTN_SUCCESS) {
00196 handle->err = status;
00197 return -1;
00198 }
00199
00200
00201 if (!xdr_dtn_reg_id_t(xdr_decode, newregid)) {
00202 handle->err = DTN_EXDR;
00203 return -1;
00204 }
00205
00206 return 0;
00207 }
00208
00209
00210 int
00211 dtn_unregister(dtn_handle_t h, dtn_reg_id_t regid)
00212 {
00213 int status;
00214 dtnipc_handle_t* handle = (dtnipc_handle_t*)h;
00215
00216 XDR* xdr_encode = &handle->xdr_encode;
00217
00218
00219 if (handle->in_poll) {
00220 handle->err = DTN_EINPOLL;
00221 return -1;
00222 }
00223
00224
00225 if (!xdr_dtn_reg_id_t(xdr_encode, ®id)) {
00226 handle->err = DTN_EXDR;
00227 return -1;
00228 }
00229
00230
00231 if (dtnipc_send(handle, DTN_UNREGISTER) != 0) {
00232 return -1;
00233 }
00234
00235
00236 if (dtnipc_recv(handle, &status) < 0) {
00237 return -1;
00238 }
00239
00240
00241 if (status != DTN_SUCCESS) {
00242 handle->err = status;
00243 return -1;
00244 }
00245
00246 return 0;
00247 }
00248
00249
00250 int
00251 dtn_find_registration(dtn_handle_t h,
00252 dtn_endpoint_id_t *eid,
00253 dtn_reg_id_t* regid)
00254 {
00255 int status;
00256 dtnipc_handle_t* handle = (dtnipc_handle_t*)h;
00257 XDR* xdr_encode = &handle->xdr_encode;
00258 XDR* xdr_decode = &handle->xdr_decode;
00259
00260
00261 if (handle->in_poll) {
00262 handle->err = DTN_EINPOLL;
00263 return -1;
00264 }
00265
00266
00267 if (!xdr_dtn_endpoint_id_t(xdr_encode, eid)) {
00268 handle->err = DTN_EXDR;
00269 return -1;
00270 }
00271
00272
00273 if (dtnipc_send(handle, DTN_FIND_REGISTRATION) != 0) {
00274 return -1;
00275 }
00276
00277
00278 if (dtnipc_recv(handle, &status) < 0) {
00279 return -1;
00280 }
00281
00282
00283 if (status != DTN_SUCCESS) {
00284 handle->err = status;
00285 return -1;
00286 }
00287
00288
00289 if (!xdr_dtn_reg_id_t(xdr_decode, regid)) {
00290 handle->err = DTN_EXDR;
00291 return -1;
00292 }
00293
00294 return 0;
00295 }
00296
00297
00298 int
00299 dtn_change_registration(dtn_handle_t h,
00300 dtn_reg_id_t regid,
00301 dtn_reg_info_t *reginfo)
00302 {
00303 (void)regid;
00304 (void)reginfo;
00305
00306
00307 dtnipc_handle_t* handle = (dtnipc_handle_t*)h;
00308
00309
00310 if (handle->in_poll) {
00311 handle->err = DTN_EINPOLL;
00312 return -1;
00313 }
00314
00315 handle->err = DTN_EINTERNAL;
00316 return -1;
00317 }
00318
00319
00320 int
00321 dtn_bind(dtn_handle_t h, dtn_reg_id_t regid)
00322 {
00323 dtnipc_handle_t* handle = (dtnipc_handle_t*)h;
00324 XDR* xdr_encode = &handle->xdr_encode;
00325
00326
00327 if (handle->in_poll) {
00328 handle->err = DTN_EINPOLL;
00329 return -1;
00330 }
00331
00332
00333 if (!xdr_dtn_reg_id_t(xdr_encode, ®id)) {
00334 handle->err = DTN_EXDR;
00335 return -1;
00336 }
00337
00338
00339 if (dtnipc_send_recv(handle, DTN_BIND) < 0) {
00340 return -1;
00341 }
00342
00343 return 0;
00344 }
00345
00346
00347 int
00348 dtn_unbind(dtn_handle_t h, dtn_reg_id_t regid)
00349 {
00350 dtnipc_handle_t* handle = (dtnipc_handle_t*)h;
00351 XDR* xdr_encode = &handle->xdr_encode;
00352
00353
00354 if (handle->in_poll) {
00355 handle->err = DTN_EINPOLL;
00356 return -1;
00357 }
00358
00359
00360 if (!xdr_dtn_reg_id_t(xdr_encode, ®id)) {
00361 handle->err = DTN_EXDR;
00362 return -1;
00363 }
00364
00365
00366 if (dtnipc_send_recv(handle, DTN_UNBIND) < 0) {
00367 return -1;
00368 }
00369
00370 return 0;
00371 }
00372
00373
00374 int
00375 dtn_send(dtn_handle_t h,
00376 dtn_bundle_spec_t* spec,
00377 dtn_bundle_payload_t* payload,
00378 dtn_bundle_id_t* id)
00379 {
00380 dtnipc_handle_t* handle = (dtnipc_handle_t*)h;
00381 XDR* xdr_encode = &handle->xdr_encode;
00382 XDR* xdr_decode = &handle->xdr_decode;
00383
00384
00385 if (handle->in_poll) {
00386 handle->err = DTN_EINPOLL;
00387 return -1;
00388 }
00389
00390
00391 if ((!xdr_dtn_bundle_spec_t(xdr_encode, spec)) ||
00392 (!xdr_dtn_bundle_payload_t(xdr_encode, payload))) {
00393 handle->err = DTN_EXDR;
00394 return -1;
00395 }
00396
00397
00398 if (dtnipc_send_recv(handle, DTN_SEND) < 0) {
00399 return -1;
00400 }
00401
00402
00403 memset(id, 0, sizeof(id));
00404
00405 if (!xdr_dtn_bundle_id_t(xdr_decode, id))
00406 {
00407 handle->err = DTN_EXDR;
00408 return DTN_EXDR;
00409 }
00410
00411 return 0;
00412 }
00413
00414
00415 int
00416 dtn_recv(dtn_handle_t h,
00417 dtn_bundle_spec_t* spec,
00418 dtn_bundle_payload_location_t location,
00419 dtn_bundle_payload_t* payload,
00420 dtn_timeval_t timeout)
00421 {
00422 dtnipc_handle_t* handle = (dtnipc_handle_t*)h;
00423 XDR* xdr_encode = &handle->xdr_encode;
00424 XDR* xdr_decode = &handle->xdr_decode;
00425
00426 if (handle->in_poll) {
00427 int poll_status = 0;
00428 if (dtnipc_recv(handle, &poll_status) != 0) {
00429 return -1;
00430 }
00431
00432 if (poll_status != DTN_SUCCESS) {
00433 handle->err = poll_status;
00434 return -1;
00435 }
00436 }
00437
00438
00439
00440 memset(spec, 0, sizeof(*spec));
00441 memset(payload, 0, sizeof(*payload));
00442
00443
00444 if ((!xdr_dtn_bundle_payload_location_t(xdr_encode, &location)) ||
00445 (!xdr_dtn_timeval_t(xdr_encode, &timeout)))
00446 {
00447 handle->err = DTN_EXDR;
00448 return -1;
00449 }
00450
00451
00452 if (dtnipc_send_recv(handle, DTN_RECV) < 0) {
00453 return -1;
00454 }
00455
00456
00457 if (!xdr_dtn_bundle_spec_t(xdr_decode, spec) ||
00458 !xdr_dtn_bundle_payload_t(xdr_decode, payload))
00459 {
00460 handle->err = DTN_EXDR;
00461 return -1;
00462 }
00463
00464 return 0;
00465 }
00466
00467
00468 int
00469 dtn_begin_poll(dtn_handle_t h, dtn_timeval_t timeout)
00470 {
00471 dtnipc_handle_t* handle = (dtnipc_handle_t*)h;
00472 XDR* xdr_encode = &handle->xdr_encode;
00473
00474
00475 if (handle->in_poll) {
00476 handle->err = DTN_EINPOLL;
00477 return -1;
00478 }
00479
00480 handle->in_poll = 1;
00481
00482 if ((!xdr_dtn_timeval_t(xdr_encode, &timeout)))
00483 {
00484 handle->err = DTN_EXDR;
00485 return -1;
00486 }
00487
00488
00489
00490 if (dtnipc_send(handle, DTN_BEGIN_POLL) < 0) {
00491 return -1;
00492 }
00493
00494 return 0;
00495 }
00496
00497
00498 int
00499 dtn_cancel_poll(dtn_handle_t h)
00500 {
00501 dtnipc_handle_t* handle = (dtnipc_handle_t*)h;
00502
00503
00504 if (! (handle->in_poll)) {
00505 handle->err = DTN_EINVAL;
00506 return -1;
00507 }
00508
00509
00510 handle->in_poll = 0;
00511
00512
00513
00514
00515
00516 if (dtnipc_send_recv(handle, DTN_CANCEL_POLL) < 0) {
00517 return -1;
00518 }
00519
00520 return 0;
00521 }
00522
00523
00524
00525
00526
00527
00528 void
00529 dtn_copy_eid(dtn_endpoint_id_t* dst, dtn_endpoint_id_t* src)
00530 {
00531 memcpy(dst->uri, src->uri, DTN_MAX_ENDPOINT_ID);
00532 }
00533
00534
00535 int
00536 dtn_parse_eid_string(dtn_endpoint_id_t* eid, const char* str)
00537 {
00538 char *s;
00539 size_t len;
00540
00541 len = strlen(str) + 1;
00542
00543
00544 if (len > DTN_MAX_ENDPOINT_ID) {
00545 return DTN_ESIZE;
00546 }
00547
00548
00549 s = strchr(str, ':');
00550 if (!s) {
00551 return DTN_EINVAL;
00552 }
00553
00554
00555
00556 memcpy(&eid->uri[0], str, len);
00557
00558 return 0;
00559 }
00560
00561
00562 int
00563 dtn_set_payload(dtn_bundle_payload_t* payload,
00564 dtn_bundle_payload_location_t location,
00565 char* val, int len)
00566 {
00567 memset(payload, 0, sizeof(dtn_bundle_payload_t));
00568 payload->location = location;
00569
00570 if (location == DTN_PAYLOAD_MEM && len > DTN_MAX_BUNDLE_MEM) {
00571 return DTN_ESIZE;
00572 }
00573
00574 switch (location) {
00575 case DTN_PAYLOAD_MEM:
00576 payload->buf.buf_val = val;
00577 payload->buf.buf_len = len;
00578 break;
00579 case DTN_PAYLOAD_FILE:
00580 case DTN_PAYLOAD_TEMP_FILE:
00581 payload->filename.filename_val = val;
00582 payload->filename.filename_len = len;
00583 break;
00584 }
00585
00586 return 0;
00587 }
00588
00589
00590 void
00591 dtn_free_payload(dtn_bundle_payload_t* payload)
00592 {
00593 xdr_free((xdrproc_t)xdr_dtn_bundle_payload_t, (char*)payload);
00594 }
00595
00596
00597 const char*
00598 dtn_status_report_reason_to_str(dtn_status_report_reason_t reason)
00599 {
00600 switch (reason) {
00601 case REASON_NO_ADDTL_INFO:
00602 return "no additional information";
00603
00604 case REASON_LIFETIME_EXPIRED:
00605 return "lifetime expired";
00606
00607 case REASON_FORWARDED_UNIDIR_LINK:
00608 return "forwarded over unidirectional link";
00609
00610 case REASON_TRANSMISSION_CANCELLED:
00611 return "transmission cancelled";
00612
00613 case REASON_DEPLETED_STORAGE:
00614 return "depleted storage";
00615
00616 case REASON_ENDPOINT_ID_UNINTELLIGIBLE:
00617 return "endpoint id unintelligible";
00618
00619 case REASON_NO_ROUTE_TO_DEST:
00620 return "no known route to destination";
00621
00622 case REASON_NO_TIMELY_CONTACT:
00623 return "no timely contact";
00624
00625 case REASON_BLOCK_UNINTELLIGIBLE:
00626 return "block unintelligible";
00627
00628 default:
00629 return "(unknown reason)";
00630 }
00631 }