Exemple #1
0
static int bundle_encode_block(struct bundle_block_t *block, uint8_t *buffer, int max_len)
{
	uint32_t offs = 0;
	int ret;
	uint32_t value;

	/* Encode the next block */
	buffer[offs] = block->type;
	offs++;

	/* Flags */
	ret = sdnv_encode(block->flags, &buffer[offs], max_len - offs);
	if (ret < 0)
		return -1;
	offs += ret;

	/* Blocksize */
	value = block->block_size;
	ret = sdnv_encode(value, &buffer[offs], max_len - offs);
	if (ret < 0)
		return -1;
	offs += ret;

	/* Payload */
	memcpy(&buffer[offs], block->payload, block->block_size);
	offs += block->block_size;

	return offs;
}
Exemple #2
0
int dtntp_discovery_add_service(uint8_t * ipnd_buffer, int length, int * offset) {
	char string_buffer[60];
	int len;
	udtn_timeval_t tv;
	float rating;

	// get local clock rating
	rating = dtntp_get_rating();

	// do not send sync beacons if clock rating is zero
	if (rating == 0.0) return 0;

	// get local time
	udtn_gettimeofday(&tv);

	// do not send sync beacons if the clock timestamp is wrong
	if (tv.tv_sec < UDTN_CLOCK_DTN_EPOCH_OFFSET) return 0;

	// Convert timestamp into DTN time
	tv.tv_sec -= UDTN_CLOCK_DTN_EPOCH_OFFSET;

	len = sprintf(string_buffer, DTNTP_SERVICE_TAG);
	(*offset) += sdnv_encode(len, ipnd_buffer + (*offset), length - (*offset));
	memcpy(ipnd_buffer + (*offset), string_buffer, len);
	(*offset) += len;

	if (rating < 1.0f) {
		len = sprintf(string_buffer, "version=2;quality=0.%lu;timestamp=%li;", \
				(unsigned long)(rating * 1000000), tv.tv_sec);
	}
	else {
		len = sprintf(string_buffer, "version=2;quality=1.0;timestamp=%li;", \
				tv.tv_sec);
	}

	(*offset) += sdnv_encode(len, ipnd_buffer + (*offset), length - (*offset));
	memcpy(ipnd_buffer + (*offset), string_buffer, len);
	(*offset) += len;

	return 1;
}
Exemple #3
0
/**
 * \brief Encodes the age extension block
 * \param bundlemem Bundle MMEM Pointer
 * \param buffer Block Payload Pointer
 * \param max_len Block Payload Length
 * \return Length of encoded block payload
 */
uint8_t bundle_ageing_encode_age_extension_block(struct mmem *bundlemem, uint8_t *buffer, int max_len) {
	struct bundle_t *bundle;
	uint32_t length = 0;
	uint8_t offset = 0;
	uint8_t tmpbuffer[10];
	uint32_t flags = 0;
	int ret;

	if( bundlemem == NULL ) {
		return 0;
	}

	bundle = (struct bundle_t *) MMEM_PTR(bundlemem);
	if( bundle == NULL ) {
		return 0;
	}

#if UDTN_SUPPORT_LONG_AEB
	/* Update the age value
	 * 4294967 = 0xFFFFFFFF / 1000
	 */
	if( bundle_ageing_get_age(bundlemem) > 4294967 ) {
		// Keep use of 64 bit data types as low as possible for performance reasons
		uint64_t age = 0;
		age = ((uint64_t) bundle_ageing_get_age(bundlemem)) * ((uint64_t) 1000);
		length = sdnv_encode_long(age, tmpbuffer, 10);
	} else {
		uint32_t age = 0;
		age = bundle_ageing_get_age(bundlemem) * 1000;
		length = sdnv_encode(age, tmpbuffer, 10);
	}
#else
	uint32_t age = 0;
	age = bundle_ageing_get_age(bundlemem) * 1000;
	length = sdnv_encode(age, tmpbuffer, 10);
#endif

	/* Encode the next block */
	buffer[offset] = BUNDLE_BLOCK_TYPE_AEB;
	offset++;

	/* Flags */
	flags = BUNDLE_BLOCK_FLAG_REPL;
	ret = sdnv_encode(flags, &buffer[offset], max_len - offset);
	if (ret < 0) {
		return 0;
	}
	offset += ret;

	/* Blocksize */
	ret = sdnv_encode(length, &buffer[offset], max_len - offset);
	if (ret < 0) {
		return 0;
	}
	offset += ret;

	/* Payload */
	memcpy(&buffer[offset], tmpbuffer, length);
	offset += length;

	return offset;
}
Exemple #4
0
int main(int argc, char* argv[])
{
    size_t i;
    memset(buf, 0, sizeof(buf));
    
    progname = strrchr(argv[0], '/');
    if (progname == 0) {
        progname = argv[0];
    } else {
        progname++;
    }
    
    if (!strcmp(progname, "num2sdnv")) {
        mode = ENCODE;
    } else if (!strcmp(progname, "sdnv2num")) {
        mode = DECODE;
    }

    argv++;
    argc--;
    
    while (argc > 1) {
        char* arg = argv[0];
        argv++;
        argc--;
        
        if (!strcmp(arg, "-e")) {
            mode = ENCODE;
        } else if (!strcmp(arg, "-d")) {
            mode = DECODE;
        } else {
            fprintf(stderr, "unknown argument %s\n", arg);
            exit(1);
        }
    }

    if (argc != 1 || mode == 0) {
        fprintf(stderr, "usage: %s [-de] <num>\n"
                " -e   encode number to sdnv\n"
                " -d   decode sdnv to number\n",
                progname);
        exit(1);
    }

    numstr = argv[0];
    if (mode == ENCODE) {
        if (numstr[0] == '0' && numstr[1] == 'x') {
            val = strtoull(numstr + 2, &end, 16);
        } else {
            val = strtoull(numstr, &end, 10);
        }
        if (*end != '\0') {
            fprintf(stderr, "invalid number %s\n", numstr);
            exit(1);
        }
        
        len = sdnv_encode(val, buf, sizeof(buf));
    } else {
        if (numstr[0] == '0' && numstr[1] == 'x') {
            numstr += 2;
        }

        if ((strlen(numstr) % 2) != 0) {
            fprintf(stderr, "number string %s must contain full bytes\n",
                    numstr);
            exit(1);
        }
        
        for (i = 0; i < strlen(numstr) / 2; ++i) {
            buf[i] = (HEXTONUM(numstr[2*i]) << 4) +
                     HEXTONUM(numstr[2*i + 1]);
        }
        len = sdnv_decode(buf, strlen(numstr)/2, &val);
    }

    printf("val:  %llu (0x%llx)\n", (unsigned long long)val, (unsigned long long)val);
    printf("len:  %d\n", len);
    printf("sdnv: ");
    if (len > 0) {
        for (i = 0; i < (size_t)len; ++i) {
            printf("%c%c", hex[(buf[i] >> 4) & 0xf], hex[buf[i] & 0xf]);
        }
    }
    printf("\n");

    return 0;
}
Exemple #5
0
int bundle_encode_bundle(struct mmem *bundlemem, uint8_t *buffer, int max_len)
{
	uint8_t i;
	uint32_t value, offs = 0, blklen_offs;
	int ret, blklen_size;
	struct bundle_t *bundle = (struct bundle_t *) MMEM_PTR(bundlemem);
	struct bundle_block_t *block;

	/* Hardcode the version to 0x06 */
	buffer[0] = 0x06;
	offs++;

	/* Flags */
	ret = sdnv_encode(bundle->flags, &buffer[offs], max_len - offs);
	if (ret < 0)
		return -1;
	offs += ret;

	/* Block length will be calculated later
	 * reserve one byte for now */
	blklen_offs = offs;
	offs++;

	/* Destination node + SSP */
	ret = sdnv_encode(bundle->dst_node, &buffer[offs], max_len - offs);
	if (ret < 0)
		return -1;
	offs += ret;

	ret = sdnv_encode_long(bundle->dst_srv, &buffer[offs], max_len - offs);
	if (ret < 0)
		return -1;
	offs += ret;

	/* Source node + SSP */
	ret = sdnv_encode(bundle->src_node, &buffer[offs], max_len - offs);
	if (ret < 0)
		return -1;
	offs += ret;

	ret = sdnv_encode_long(bundle->src_srv, &buffer[offs], max_len - offs);
	if (ret < 0)
		return -1;
	offs += ret;

	/* Report-to node + SSP */
	ret = sdnv_encode(bundle->rep_node, &buffer[offs], max_len - offs);
	if (ret < 0)
		return -1;
	offs += ret;

	ret = sdnv_encode(bundle->rep_srv, &buffer[offs], max_len - offs);
	if (ret < 0)
		return -1;
	offs += ret;

	/* Custodian node + SSP */
	ret = sdnv_encode(bundle->cust_node, &buffer[offs], max_len - offs);
	if (ret < 0)
		return -1;
	offs += ret;

	ret = sdnv_encode(bundle->cust_srv, &buffer[offs], max_len - offs);
	if (ret < 0)
		return -1;
	offs += ret;

	/* Creation Timestamp */
	ret = sdnv_encode_long(bundle->tstamp, &buffer[offs], max_len - offs);
	if (ret < 0)
		return -1;
	offs += ret;

	/* Creation Timestamp Sequence Number */
	ret = sdnv_encode(bundle->tstamp_seq, &buffer[offs], max_len - offs);
	if (ret < 0)
		return -1;
	offs += ret;

	/* Lifetime */
	ret = sdnv_encode(bundle->lifetime, &buffer[offs], max_len - offs);
	if (ret < 0)
		return -1;
	offs += ret;

	/* Directory Length */
	ret = sdnv_encode(0l, &buffer[offs], max_len - offs);
	if (ret < 0)
		return -1;
	offs += ret;

	if (bundle->flags & BUNDLE_FLAG_FRAGMENT) {
		LOG(LOGD_DTN, LOG_BUNDLE, LOGL_INF, "Bundle is a fragment");

		/* Fragment Offset */
		ret = sdnv_encode(bundle->frag_offs, &buffer[offs], max_len - offs);
		if (ret < 0)
			return -1;
		offs += ret;

		/* Total App Data Unit Length */
		ret = sdnv_encode(bundle->app_len, &buffer[offs], max_len - offs);
		if (ret < 0)
			return -1;
		offs += ret;
	}

	/* Calculate block length value */
	value = offs - blklen_offs - 1;
	blklen_size = sdnv_encoding_len(value);
	/* Move the data around */
	if (blklen_size > 1) {
		memmove(&buffer[blklen_offs+blklen_size], &buffer[blklen_offs+1], value);
	}
	ret = sdnv_encode(value, &buffer[blklen_offs], blklen_size);

	offs += ret-1;

	/* Encode Bundle Age Block - always as first block */
	offs += bundle_ageing_encode_age_extension_block(bundlemem, &buffer[offs], max_len - offs);

	block = (struct bundle_block_t *) bundle->block_data;
	for (i=0;i<bundle->num_blocks;i++) {
		offs += bundle_encode_block(block, &buffer[offs], max_len - offs);

		/* Reference the next block */
		block = (struct bundle_block_t *) &block->payload[block->block_size];
	}

	return offs;
}