smoketestclientlib.c

Go to the documentation of this file.
00001 /**
00002  * @file smoketestclientlib.c
00003  * Simple program for smoke-test of ccn client lib.
00004  * 
00005  * A CCNx program.
00006  *
00007  * Copyright (C) 2009, 2010 Palo Alto Research Center, Inc.
00008  *
00009  * This work is free software; you can redistribute it and/or modify it under
00010  * the terms of the GNU General Public License version 2 as published by the
00011  * Free Software Foundation.
00012  * This work is distributed in the hope that it will be useful, but WITHOUT ANY
00013  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
00015  * for more details. You should have received a copy of the GNU General Public
00016  * License along with this program; if not, write to the
00017  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019  */
00020 #include <errno.h>
00021 #include <fcntl.h>
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <sys/types.h>
00026 #include <ccn/ccn.h>
00027 #include <unistd.h>
00028 
00029 void printraw(const void *r, int n)
00030 {
00031     int i, l;
00032     const unsigned char *p = r;
00033     while (n > 0) {
00034         l = (n > 40 ? 40 : n);
00035         for (i = 0; i < l; i++)
00036             printf(" %c", (' ' <= p[i] && p[i] <= '~') ? p[i] : '.');
00037         printf("\n");
00038         for (i = 0; i < l; i++)
00039             printf("%02X", p[i]);
00040         printf("\n");
00041         p += l;
00042         n -= l;
00043     }
00044 }
00045 
00046 enum ccn_upcall_res
00047 incoming_content(struct ccn_closure *selfp,
00048                  enum ccn_upcall_kind kind,
00049                  struct ccn_upcall_info *info)
00050 {
00051     if (kind == CCN_UPCALL_FINAL)
00052         return(CCN_UPCALL_RESULT_OK);
00053     if (kind == CCN_UPCALL_INTEREST_TIMED_OUT)
00054         return(CCN_UPCALL_RESULT_REEXPRESS);
00055     if (kind != CCN_UPCALL_CONTENT && kind != CCN_UPCALL_CONTENT_UNVERIFIED)
00056         return(CCN_UPCALL_RESULT_ERR);
00057     printf("Got content matching %d components:\n", info->pi->prefix_comps);
00058     printraw(info->content_ccnb, info->pco->offset[CCN_PCO_E]);
00059     return(CCN_UPCALL_RESULT_OK);
00060 }
00061 
00062 /* Use some static data for this simple program */
00063 static struct ccn_closure incoming_content_action = {
00064     .p = &incoming_content
00065 };
00066 
00067 static unsigned char rawbuf[1024*1024];
00068 static ssize_t rawlen;
00069 
00070 enum ccn_upcall_res
00071 outgoing_content(struct ccn_closure *selfp,
00072                  enum ccn_upcall_kind kind,
00073                  struct ccn_upcall_info *info)
00074 {
00075     int res = 0;
00076     if (kind == CCN_UPCALL_FINAL) {
00077         printf("CCN_UPCALL_FINAL for outgoing_content()\n");
00078         return(CCN_UPCALL_RESULT_ERR);
00079     }
00080     printf("Got interest matching %d components, kind = %d\n", info->matched_comps, kind);
00081     if (kind == CCN_UPCALL_INTEREST) {
00082         res = ccn_put(info->h, rawbuf, rawlen);
00083         if (res == -1) {
00084             fprintf(stderr, "error sending data");
00085             return(CCN_UPCALL_RESULT_ERR);
00086         }
00087         else {
00088             printf("Sent my content:\n");
00089             printraw(rawbuf, rawlen);
00090             return(CCN_UPCALL_RESULT_INTEREST_CONSUMED);
00091         }
00092     }
00093     else
00094         return(CCN_UPCALL_RESULT_ERR);
00095 }
00096 
00097 static struct ccn_closure interest_filter = {
00098     .p = &outgoing_content
00099 };
00100 
00101 int
00102 main(int argc, char **argv)
00103 {
00104     int opt;
00105     int res;
00106     char *filename = NULL;
00107     int rep = 1;
00108     struct ccn *ccn = NULL;
00109     struct ccn_parsed_interest interest = {0};
00110     int i;
00111     struct ccn_charbuf *c = ccn_charbuf_create();
00112     struct ccn_charbuf *templ = ccn_charbuf_create();
00113     struct ccn_indexbuf *comps = ccn_indexbuf_create();
00114     while ((opt = getopt(argc, argv, "hf:n:")) != -1) {
00115         switch (opt) {
00116             default:
00117             case 'h':
00118                 fprintf(stderr, "provide names of files containing ccnb format interests and content\n");
00119                 exit(1);
00120             case 'n':
00121                 rep = atoi(optarg);
00122                 break;
00123         }
00124     }
00125     argc -= optind;
00126     argv += optind;
00127     ccn = ccn_create();
00128     if (ccn_connect(ccn, NULL) == -1) {
00129         perror("ccn_connect");
00130         exit(1);
00131     }
00132     for (i = 0; argv[i] != NULL; i++) {
00133         filename = argv[i];
00134         close(0);
00135         res = open(filename, O_RDONLY);
00136         if (res != 0) {
00137             perror(filename);
00138             exit(1);
00139         }
00140         fprintf(stderr, "Reading %s ... ", filename);
00141         rawlen = read(0, rawbuf, sizeof(rawbuf));
00142         if (rawlen < 0) {
00143             perror("skipping");
00144             continue;
00145         }
00146         res = ccn_parse_interest(rawbuf, rawlen, &interest, NULL);
00147         if (res >= 0) {
00148             size_t name_start = interest.offset[CCN_PI_B_Name];
00149             size_t name_size = interest.offset[CCN_PI_E_Name] - name_start;
00150             templ->length = 0;
00151             ccn_charbuf_append(templ, rawbuf, rawlen);
00152             fprintf(stderr, "Registering interest with %d name components\n", res);
00153             c->length = 0;
00154             ccn_charbuf_append(c, rawbuf + name_start, name_size);
00155             // XXX - res is currently ignored
00156             ccn_express_interest(ccn, c, &incoming_content_action, templ);
00157         }
00158         else {
00159             struct ccn_parsed_ContentObject obj = {0};
00160             int k;
00161             res = ccn_parse_ContentObject(rawbuf, rawlen, &obj, comps);
00162             if (res >= 0) {
00163                 fprintf(stderr, "Offering content\n");
00164                 /* We won't listen for interests with fewer than 2 name component */
00165                 for (k = comps->n - 1; k >= 2; k--) {
00166                     c->length = 0;
00167                     ccn_charbuf_append_tt(c, CCN_DTAG_Name, CCN_DTAG);
00168                     ccn_charbuf_append(c, rawbuf+comps->buf[0], comps->buf[k] - comps->buf[0]);
00169                     ccn_charbuf_append_closer(c);
00170                     res = ccn_set_interest_filter(ccn, c, &interest_filter);
00171                     if (res < 0) abort();
00172                 }
00173                 res = ccn_run(ccn, 1000);
00174                 /* Stop listening for these interests now */
00175                 for (k = comps->n - 1; k >= 2; k--) {
00176                     c->length = 0;
00177                     ccn_charbuf_append_tt(c, CCN_DTAG_Name, CCN_DTAG);
00178                     ccn_charbuf_append(c, rawbuf+comps->buf[0], comps->buf[k] - comps->buf[0]);
00179                     ccn_charbuf_append_closer(c);
00180                     res = ccn_set_interest_filter(ccn, c, NULL);
00181                     if (res < 0) abort();
00182                 }
00183             }
00184             else {
00185                 fprintf(stderr, "what's that?\n");
00186             }
00187         }
00188     }
00189     fprintf(stderr, "Running for 8 more seconds\n");
00190     res = ccn_run(ccn, 8000);
00191     ccn_destroy(&ccn);
00192     exit(0);
00193 }
Generated on Fri May 13 16:27:03 2011 for Content-Centric Networking in C by  doxygen 1.6.3