ccn_face_mgmt.c

Go to the documentation of this file.
00001 /**
00002  * @file ccn_face_mgmt.c
00003  * @brief Support for parsing and creating FaceInstance elements.
00004  * 
00005  * Part of the CCNx C Library.
00006  *
00007  * Copyright (C) 2009 Palo Alto Research Center, Inc.
00008  *
00009  * This library is free software; you can redistribute it and/or modify it
00010  * under the terms of the GNU Lesser General Public License version 2.1
00011  * as published by the Free Software Foundation.
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00015  * Lesser General Public License for more details. You should have received
00016  * a copy of the GNU Lesser General Public License along with this library;
00017  * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
00018  * Fifth Floor, Boston, MA 02110-1301 USA.
00019  */
00020 #include <stddef.h>
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 
00025 #include <ccn/ccn.h>
00026 #include <ccn/charbuf.h>
00027 #include <ccn/coding.h>
00028 #include <ccn/face_mgmt.h>
00029 #include <ccn/sockcreate.h>
00030 
00031 /**
00032  * Parse a ccnb-ecoded FaceInstance into an internal representation
00033  *
00034  * The space used for the various strings is held by the charbuf.
00035  * A client may replace the strings with other pointers, but then
00036  * assumes responsibilty for managing those pointers.
00037  * @returns pointer to newly allocated structure describing the face, or
00038  *          NULL if there is an error.
00039  */
00040 struct ccn_face_instance *
00041 ccn_face_instance_parse(const unsigned char *p, size_t size)
00042 {
00043     struct ccn_buf_decoder decoder;
00044     struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, p, size);
00045     struct ccn_charbuf *store = ccn_charbuf_create();
00046     struct ccn_face_instance *result;
00047     const unsigned char *val;
00048     size_t sz;
00049     int action_off = -1;
00050     int ccnd_id_off = -1;
00051     int host_off = -1;
00052     int port_off = -1;
00053     int mcast_off = -1;
00054     
00055     if (store == NULL)
00056         return(NULL);
00057     result = calloc(1, sizeof(*result));
00058     if (result == NULL) {
00059         ccn_charbuf_destroy(&store);
00060         return(NULL);
00061     }
00062     result->store = store;
00063     if (ccn_buf_match_dtag(d, CCN_DTAG_FaceInstance)) {
00064         ccn_buf_advance(d);
00065         action_off = ccn_parse_tagged_string(d, CCN_DTAG_Action, store);
00066         if (ccn_buf_match_dtag(d, CCN_DTAG_PublisherPublicKeyDigest)) {
00067             ccn_buf_advance(d);
00068             if (ccn_buf_match_blob(d, &val, &sz)) {
00069                 ccn_buf_advance(d);
00070                 if (sz != 32)
00071                     d->decoder.state = -__LINE__;
00072             }
00073             ccn_buf_check_close(d);
00074             if (d->decoder.state >= 0) {
00075                 ccnd_id_off = store->length;
00076                 ccn_charbuf_append(store, val, sz);
00077                 result->ccnd_id_size = sz;
00078             }
00079         }
00080         result->faceid = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FaceID);
00081         result->descr.ipproto = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_IPProto);
00082         host_off = ccn_parse_tagged_string(d, CCN_DTAG_Host, store);
00083         port_off = ccn_parse_tagged_string(d, CCN_DTAG_Port, store);
00084         mcast_off = ccn_parse_tagged_string(d, CCN_DTAG_MulticastInterface, store);
00085         result->descr.mcast_ttl = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_MulticastTTL);
00086         result->lifetime = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FreshnessSeconds);
00087         ccn_buf_check_close(d);
00088     }
00089     else
00090         d->decoder.state = -__LINE__;
00091     
00092     if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state))
00093         ccn_face_instance_destroy(&result);
00094     else {
00095         char *b = (char *)store->buf;
00096         result->action = (action_off == -1) ? NULL : b + action_off;
00097         result->ccnd_id = (ccnd_id_off == -1) ? NULL : store->buf + ccnd_id_off;
00098         result->descr.address = (host_off == -1) ? NULL : b + host_off;
00099         result->descr.port = (port_off == -1) ? NULL : b + port_off;
00100         result->descr.source_address = (mcast_off == -1) ? NULL : b + mcast_off;
00101     }
00102     return(result);
00103 }
00104 
00105 /**
00106  * Destroy the result of ccn_face_instance_parse().
00107  */
00108 void
00109 ccn_face_instance_destroy(struct ccn_face_instance **pfi)
00110 {
00111     if (*pfi == NULL)
00112         return;
00113     ccn_charbuf_destroy(&(*pfi)->store);
00114     free(*pfi);
00115     *pfi = NULL;
00116 }
00117 
00118 //<!ELEMENT FaceInstance  (Action?, PublisherPublicKeyDigest?, FaceID?, IPProto?, Host?, Port?, MulticastInterface?, MulticastTTL?, FreshnessSeconds?)>
00119 /**
00120  * Marshal an internal face instance representation into ccnb form
00121  */
00122 int
00123 ccnb_append_face_instance(struct ccn_charbuf *c,
00124                           const struct ccn_face_instance *fi)
00125 {
00126     int res;
00127     res = ccnb_element_begin(c, CCN_DTAG_FaceInstance);
00128     if (fi->action != NULL)
00129         res |= ccnb_tagged_putf(c, CCN_DTAG_Action, "%s",
00130                                 fi->action);
00131     if (fi->ccnd_id_size != 0)
00132         res |= ccnb_append_tagged_blob(c, CCN_DTAG_PublisherPublicKeyDigest,
00133                                           fi->ccnd_id, fi->ccnd_id_size);
00134     if (fi->faceid != ~0)
00135         res |= ccnb_tagged_putf(c, CCN_DTAG_FaceID, "%u",
00136                                    fi->faceid);
00137     if (fi->descr.ipproto >= 0)
00138         res |= ccnb_tagged_putf(c, CCN_DTAG_IPProto, "%d",
00139                                    fi->descr.ipproto);
00140     if (fi->descr.address != NULL)
00141         res |= ccnb_tagged_putf(c, CCN_DTAG_Host, "%s",
00142                                    fi->descr.address);
00143     if (fi->descr.port != NULL)
00144         res |= ccnb_tagged_putf(c, CCN_DTAG_Port, "%s",
00145                                    fi->descr.port);    
00146     if (fi->descr.source_address != NULL)
00147         res |= ccnb_tagged_putf(c, CCN_DTAG_MulticastInterface, "%s",
00148                                    fi->descr.source_address);
00149     if (fi->descr.mcast_ttl >= 0 && fi->descr.mcast_ttl != 1)
00150         res |= ccnb_tagged_putf(c, CCN_DTAG_MulticastTTL, "%d",
00151                                    fi->descr.mcast_ttl);
00152     if (fi->lifetime >= 0)
00153         res |= ccnb_tagged_putf(c, CCN_DTAG_FreshnessSeconds, "%d",
00154                                    fi->lifetime);    
00155     res |= ccnb_element_end(c);
00156     return(res);
00157 }
Generated on Fri May 13 16:27:02 2011 for Content-Centric Networking in C by  doxygen 1.6.3