applib/dtn_api.c
changeset 0 2b3e5ec03512
equal deleted inserted replaced
-1:000000000000 0:2b3e5ec03512
       
     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, &regid)) {
       
   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, &regid)) {
       
   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, &regid)) {
       
   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, &regid)) ||
       
   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 }