apps/dtnquery/dtnquery.c
changeset 64 1296a0283271
parent 32 64b5c8f5be17
child 65 333724f2f7cf
--- a/apps/dtnquery/dtnquery.c	Tue Oct 18 11:52:07 2011 +0100
+++ b/apps/dtnquery/dtnquery.c	Mon Oct 24 18:28:33 2011 +0100
@@ -1,5 +1,5 @@
 /*
- *    Copyright 2004-2006 Intel Corporation
+ *    Copyright 2010-2011 Trinity College Dublin
  * 
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -43,7 +43,6 @@
 #define DTN_BPQ_RECV 2
 #define DTN_BPQ_SEND_RECV 3
 
-#define DTN_BPQ_BLOCK_TYPE 0xC8
 
 // Find the maximum commandline length
 #ifdef __FreeBSD__
@@ -375,7 +374,7 @@
     }
 
     // if no reply-to eid set, use the src eid
-    if (*reply_eid_name == NULL)
+    if (reply_eid_name == NULL)
         strncpy(reply_eid_name, src_eid_name, PATH_MAX);
     
     return 0;
@@ -513,7 +512,6 @@
 * parse eid:
 *  
 * code lifted from dtnsend
-* todo: check this
 *******************************************************************************/
 dtn_endpoint_id_t *
 parse_eid(dtn_handle_t handle,
@@ -563,7 +561,6 @@
         return -1;
     }
 
-//    if ( (dest_fd = open(destination, O_WRONLY | O_CREAT, 0644)) < 0) {
     if ( (dest_fd = creat(destination, 0644)) < 0) {
         fprintf(stderr, "error opening output file for writing '%s': %s\n",
                 destination, strerror(errno));
@@ -587,22 +584,30 @@
         return -1;
     }
 
-    printf("%d byte file from [%s]: transit time=%d ms, written to '%s'\n",
+    if (verbose) printf("%d byte file from [%s]: transit time=%d ms, written to '%s'\n",
            (int)fileinfo.st_size, bundle_spec.source.uri, 0, destination);
 
     return 0;
 }
 
 /*******************************************************************************
-* bpq to char array:
-* encode as SDNVs,
-*   BPQ-kind             1-byte
-*   matching rule type   1-byte
-*   BPQ-value-length     SDNV
-*   BPQ-value            n-bytes
-*   number of fragments  SDNV
-*   fragment offsets     SDNV
-*   fragment lengths     SDNV
+* bpq to char array
+* encode the following information:
+*
+*   BPQ-kind             		1-byte
+*   Matching rule 				1-byte
+*
+*   Creation time-stamp	sec		SDNV
+*   Creation time-stamp	seq		SDNV
+*   Source EID length			SDNV
+*   Source EID 					n-bytes
+*
+*   Query value length     		SDNV
+*   Query value            		n-bytes
+*
+*   Number of fragments  		SDNV
+*   Fragment offsets    		SDNV
+*   Fragment lengths     		SDNV
 *
 * @return The number of bytes or -1 on error
 *******************************************************************************/
@@ -612,9 +617,9 @@
     size_t buf_len,
     int verbose)
 {
-    int i=0, j=0, k=0;
-    int q_encoding_len, f_encoding_len, encoding_len;    
-    char encoding[PATH_MAX];
+    int j=0, q_encoding_len, f_encoding_len, encoding_len;
+    u_int i=0, k=0;
+    u_char encoding[PATH_MAX];
 
     memset(buf, 0, buf_len);
 
@@ -624,70 +629,152 @@
     // matching rule type   1-byte
     if (i < buf_len)    buf[i++] = (char) bpq->matching_rule;
 
-    // BPQ-value-length     SDNV
-    if ( (q_encoding_len = sdnv_encode (bpq->query.query_len, encoding, PATH_MAX)) == -1 )
+    // Timestamp secs (SDNV)
+	if ( (q_encoding_len = sdnv_encode (bpq->original_id.creation_ts.secs,
+										encoding, PATH_MAX)) == -1 ) {
+		fprintf (stderr, "Error encoding creation timestamp secs\n");
+		return -1;
+	} else {
+		for (j=0; i<buf_len && j<q_encoding_len; ++j)
+	        buf[i++] = encoding[j];
+	}
+
+    // Timestamp seqno (SDNV)
+	if ( (q_encoding_len = sdnv_encode (bpq->original_id.creation_ts.seqno,
+										encoding, PATH_MAX)) == -1 ) {
+		fprintf (stderr, "Error encoding creation timestamp seqno\n");
+		return -1;
+	} else {
+		for (j=0; i<buf_len && j<q_encoding_len; ++j)
+	        buf[i++] = encoding[j];
+	}
+
+    // Source EID len (SDNV)
+	if ( (q_encoding_len = sdnv_encode (bpq->original_id.source_len,
+										encoding, PATH_MAX)) == -1 ) {
+		fprintf (stderr, "Error encoding source EID len\n");
+		return -1;
+	} else {
+		for (j=0; i<buf_len && j<q_encoding_len; ++j)
+	        buf[i++] = encoding[j];
+	}
+
+    // Source EID n-bytes
+	 if ( (i + bpq->original_id.source_len) < buf_len ) {
+		memcpy(&(buf[i]), bpq->original_id.source.uri, bpq->original_id.source_len);
+		i += bpq->original_id.source_len;
+	} else {
+		fprintf (stderr, "Error encoding query value\n");
+		return -1;
+	}
+
+
+    // Query length (SDNV)
+    if ( (q_encoding_len = sdnv_encode (bpq->query.query_len,
+    									encoding, PATH_MAX)) == -1 ) {
+    	fprintf (stderr, "Error encoding query len\n");
         return -1;
-    for (j=0; i<buf_len && j<q_encoding_len; ++j)
-        buf[i++] = encoding[j];
+    } else {
+    	for (j=0; i<buf_len && j<q_encoding_len; ++j)
+    		buf[i++] = encoding[j];
+    }
 
-    // BPQ-value            n-bytes
-    for (j=0; i<buf_len && j<bpq->query.query_len; ++j)
-        buf[i++] = bpq->query.query_val[j];
+    // Query value n-bytes
+    if ( (i + bpq->query.query_len) < buf_len ) {
+    	memcpy(&(buf[i]), bpq->query.query_val, bpq->query.query_len);
+    	i += bpq->query.query_len;
+    } else {
+    	fprintf (stderr, "Error encoding query value\n");
+    	return -1;
+    }
+
 
     // number of fragments  SDNV
-    if ( (f_encoding_len = sdnv_encode (bpq->fragments.num_frag_returned, encoding, PATH_MAX)) == -1 )
+    if ( (f_encoding_len = sdnv_encode (bpq->fragments.num_frag_returned,
+    									encoding, PATH_MAX)) == -1 ){
+    	fprintf (stderr, "Error encoding number of fragments\n");
         return -1;
-    for (j=0; i<buf_len && j<f_encoding_len; ++j)
-        buf[i++] = encoding[j];
-    
+    } else {
+    	for (j=0; i<buf_len && j<f_encoding_len; ++j)
+    		buf[i++] = encoding[j];
+    }
+
     for (k=0; k<bpq->fragments.num_frag_returned; ++k) {
 
         // fragment offsets     SDNV
-        if ( (encoding_len = sdnv_encode (bpq->fragments.frag_offsets[k], encoding, PATH_MAX)) == -1 )
-            return -1;
-        for (j=0; i<buf_len && j<encoding_len; ++j)
-            buf[i++] = encoding[j];
+        if ( (encoding_len = sdnv_encode (bpq->fragments.frag_offsets[k],
+        								  encoding, PATH_MAX)) == -1 ) {
+        	fprintf (stderr, "Error encoding fragment offset[%d]\n", k);
+        	return -1;
+        } else {
+        	for (j=0; i<buf_len && j<encoding_len; ++j)
+        		buf[i++] = encoding[j];
+        }
 
         // fragment lengths     SDNV
-        if ( (encoding_len = sdnv_encode (bpq->fragments.frag_lenghts[k], encoding, PATH_MAX)) == -1 )
-            return -1;
-        for (j=0; i<buf_len && j<encoding_len; ++j)
-            buf[i++] = encoding[j];
+        if ( (encoding_len = sdnv_encode (bpq->fragments.frag_lenghts[k],
+        								  encoding, PATH_MAX)) == -1 ) {
+        	fprintf (stderr, "Error encoding fragment length[%d]\n", k);
+        	return -1;
+        } else {
+        	for (j=0; i<buf_len && j<encoding_len; ++j)
+        		buf[i++] = encoding[j];
+        }
     }
 
     if (verbose) {
         fprintf (stdout, "\nbpq_to_char_array (buf_len:%d, i:%d):\n",buf_len,i);
         fprintf (stdout, "             kind: %d\n", (int) buf[0]);
         fprintf (stdout, "    matching rule: %d\n", (int) buf[1]);
+
+        fprintf (stdout, "  creation ts sec: %d\n",
+        		 (int) bpq->original_id.creation_ts.secs);
+        fprintf (stdout, "  creation ts seq: %d\n",
+        		 (int) bpq->original_id.creation_ts.seqno);
+        fprintf (stdout, "   source eid len: %d\n",
+        		 (int) bpq->original_id.source_len);
+        fprintf (stdout, "       source eid: %s\n",
+        		       bpq->original_id.source.uri);
+
         fprintf (stdout, "        query len: %d\n", bpq->query.query_len);
         fprintf (stdout, "   q_encoding_len: %d\n", q_encoding_len);
         fprintf (stdout, "        query val: %s\n", bpq->query.query_val);
+
         fprintf (stdout, "     fragment len: %d\n", bpq->fragments.num_frag_returned);
         fprintf (stdout, "   f_encoding_len: %d\n\n", f_encoding_len);
     }
-    
+
     return i;
 }
+
 /*******************************************************************************
-* char array to bpq:
-* decode as SDNVs,
-*   BPQ-kind             1-byte
-*   matching rule type   1-byte
-*   BPQ-value-length     SDNV
-*   BPQ-value            n-bytes
-*   number of fragments  SDNV
-*   fragment offsets     SDNV
-*   fragment lengths     SDNV
+* char array to bpq
+* decode the following information:
+*
+*   BPQ-kind             		1-byte
+*   Matching rule 				1-byte
 *
-* @return DTN_SUCCESS or -1 on error
+*   Creation time-stamp	sec		SDNV
+*   Creation time-stamp	seq		SDNV
+*   Source EID length			SDNV
+*   Source EID 					n-bytes
+*
+*   Query value length     		SDNV
+*   Query value            		n-bytes
+*
+*   Number of fragments  		SDNV
+*   Fragment offsets    		SDNV
+*   Fragment lengths     		SDNV
+*
+* @return The number of bytes or -1 on error
 *******************************************************************************/
 int
-char_array_to_bpq(const char* buf,
+char_array_to_bpq(const u_char* buf,
     size_t buf_len,
     dtn_bpq_extension_block_data_t * bpq,
-    int verbose) 
+    int verbose)
 {
-    int i=0, j=0;
+    u_int i=0, j=0;
     int q_decoding_len, f_decoding_len, decoding_len;
 
     // BPQ-kind             1-byte
@@ -696,30 +783,85 @@
     // matching rule type   1-byte
     if (i<buf_len) bpq->matching_rule = (u_int) buf[i++];
 
+
+
+    // Creation time-stamp sec     SDNV
+    if ( (q_decoding_len = sdnv_decode (&(buf[i]),
+    									buf_len - i,
+    									&(bpq->original_id.creation_ts.secs))) == -1 ) {
+        fprintf (stderr, "Error decoding creation time-stamp sec\n");
+        return -1;
+    }
+    i += q_decoding_len;
+
+    // Creation time-stamp seq     SDNV
+    if ( (q_decoding_len = sdnv_decode (&(buf[i]),
+    									buf_len - i,
+    									&(bpq->original_id.creation_ts.seqno))) == -1 ) {
+        fprintf (stderr, "Error decoding creation time-stamp seq\n");
+        return -1;
+    }
+    i += q_decoding_len;
+
+    // Source EID length     SDNV
+    if ( (q_decoding_len = sdnv_decode (&(buf[i]),
+    									buf_len - i,
+    									&(bpq->original_id.source_len))) == -1 ) {
+        fprintf (stderr, "Error decoding source EID length\n");
+        return -1;
+    }
+    i += q_decoding_len;
+
+    // Source EID            n-bytes
+    if (i<buf_len && bpq->original_id.source_len <= DTN_MAX_ENDPOINT_ID) {
+    	strncpy(bpq->original_id.source.uri, &(buf[i]), bpq->original_id.source_len);
+    	i += bpq->original_id.source_len;
+    } else {
+    	fprintf (stderr, "Error copying source EID\n");
+		return -1;
+    }
+
     // BPQ-value-length     SDNV
-    if ( (q_decoding_len = sdnv_decode (&(buf[i]), buf_len - i, &(bpq->query.query_len))) == -1 )
+    if ( (q_decoding_len = sdnv_decode (&(buf[i]),
+    									buf_len - i,
+    									&(bpq->query.query_len))) == -1 ) {
+        fprintf (stderr, "Error decoding BPQ-value-length\n");
         return -1;
+    }
     i += q_decoding_len;
 
     // BPQ-value            n-bytes
     if (i<buf_len) bpq->query.query_val = &(buf[i]);
-    i += bpq->query.query_len;
+    	i += bpq->query.query_len;
+
 
     // number of fragments  SDNV
-    if ( (f_decoding_len = sdnv_decode (&(buf[i]), buf_len - i, &(bpq->fragments.num_frag_returned))) == -1 )
+    if ( (f_decoding_len = sdnv_decode (&(buf[i]),
+    									buf_len - i,
+    									&(bpq->fragments.num_frag_returned))) == -1 ) {
+        fprintf (stderr, "Error decoding number of fragments\n");
         return -1;
+    }
     i += f_decoding_len;
 
     for (j=0; i<buf_len && j<bpq->fragments.num_frag_returned; ++j) {
 
         // fragment offsets     SDNV
-        if ( (decoding_len = sdnv_decode (&(buf[i]), buf_len - i, &(bpq->fragments.frag_offsets[j]))) == -1 )
+        if ( (decoding_len = sdnv_decode (&(buf[i]),
+        								  buf_len - i,
+        								  &(bpq->fragments.frag_offsets[j]))) == -1 ) {
+            fprintf (stderr, "Error decoding fragment[%d] offset\n", j);
             return -1;
+        }
         i += decoding_len;
 
         // fragment lengths     SDNV
-        if ( (decoding_len = sdnv_decode (&(buf[i]), buf_len - i, &(bpq->fragments.frag_lenghts[j]))) == -1 )
+        if ( (decoding_len = sdnv_decode (&(buf[i]),
+        								  buf_len - i,
+        								  &(bpq->fragments.frag_lenghts[j]))) == -1 ) {
+            fprintf (stderr, "Error decoding fragment[%d] length\n", j);
             return -1;
+        }
         i += decoding_len;
     }
 
@@ -730,9 +872,20 @@
         fprintf (stdout, "\nchar_array_to_bpq (buf_len:%d, i:%d):\n",buf_len, i);
         fprintf (stdout, "             kind: %d\n", (int) buf[0]);
         fprintf (stdout, "    matching rule: %d\n", (int) buf[1]);
+
+        fprintf (stdout, "  creation ts sec: %d\n",
+        		 (int) bpq->original_id.creation_ts.secs);
+        fprintf (stdout, "  creation ts seq: %d\n",
+        		 (int) bpq->original_id.creation_ts.seqno);
+        fprintf (stdout, "   source eid len: %d\n",
+        		 (int) bpq->original_id.source_len);
+        fprintf (stdout, "       source eid: %s\n",
+        		 (int) bpq->original_id.source.uri);
+
         fprintf (stdout, "        query len: %d\n", bpq->query.query_len);
         fprintf (stdout, "   q_decoding_len: %d\n", q_decoding_len);
         fprintf (stdout, "        query val: %s\n", bpq->query.query_val);
+
         fprintf (stdout, "     fragment len: %d\n", bpq->fragments.num_frag_returned);
         fprintf (stdout, "   f_decoding_len: %d\n\n", f_decoding_len);
     }
@@ -828,7 +981,10 @@
 
 /*******************************************************************************
 * recv bpq:
-* todo.
+* given a registration handle, listen for count bundles.
+* if count is 0 - listen forever
+* as new bundles arrive save the payload as filename
+* if filename is NULL, use the query value as the filename
 *******************************************************************************/
 int
 recv_bpq(dtn_handle_t handle,
@@ -888,7 +1044,7 @@
                     break;
                 }
                 
-                ret = char_array_to_bpq(bpq_blocks[i].data.data_val,
+                ret = char_array_to_bpq((u_char*)bpq_blocks[i].data.data_val,
                                         bpq_blocks[i].data.data_len,
                                         &bpq_block_data,
                                         verbose);
@@ -899,7 +1055,7 @@
                 }
 
                 if (verbose) fprintf(stdout, "BPQ query(%s)\n", bpq_block_data.query.query_val);
-                if (*filename == NULL)
+                if (filename == NULL)
                     strncpy(filename, bpq_block_data.query.query_val, PATH_MAX);
     
                 break;