Permalink
Browse files

Complete API + more examples

  • Loading branch information...
petya2164 committed Oct 2, 2018
1 parent daebcee commit 6006064592c605450a910d8b7c8ab3a232441937
@@ -82,7 +82,7 @@ def install(properties):
def coverage_settings(options):
options['required_line_coverage'] = 100.0
options['required_line_coverage'] = 72.0
def main():
@@ -1,4 +1,4 @@
// Copyright Steinwurf ApS 2015.
// Copyright Steinwurf ApS 2018.
// Distributed under the "STEINWURF EVALUATION LICENSE 1.0".
// See accompanying file LICENSE.rst or
// http://www.steinwurf.com/licensing
@@ -0,0 +1,115 @@
// Copyright Steinwurf ApS 2018.
// Distributed under the "STEINWURF EVALUATION LICENSE 1.0".
// See accompanying file LICENSE.rst or
// http://www.steinwurf.com/licensing
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <kodo_rlnc_c/encoder.h>
#include <kodo_rlnc_c/decoder.h>
/// @example symbol_status_updater.c
///
/// Simple example showing the result of enabling the symbol status updater.
int main()
{
// Seed the random number generator to produce different data every time
srand(time(NULL));
// Set the number of symbols (i.e. the generation size in RLNC
// terminology) and the size of a symbol in bytes
uint32_t symbols = 50;
uint32_t symbol_size = 160;
// Here we select the finite field to use.
// To show the effect of the symbol status updater we need to use a
// smaller field.
int32_t finite_field = krlnc_binary;
// First, we create an encoder & decoder factory.
// The factories are used to build actual encoders/decoders
krlnc_encoder_factory_t encoder_factory = krlnc_new_encoder_factory(
finite_field, symbols, symbol_size);
krlnc_decoder_factory_t decoder_factory = krlnc_new_decoder_factory(
finite_field, symbols, symbol_size);
krlnc_encoder_t encoder = krlnc_encoder_factory_build(encoder_factory);
// Create two decoders: one which has the status updater turned on and one
// which has it off.
krlnc_decoder_t decoder1 = krlnc_decoder_factory_build(decoder_factory);
krlnc_decoder_t decoder2 = krlnc_decoder_factory_build(decoder_factory);
krlnc_decoder_set_status_updater_on(decoder2);
printf("decoder 1 status updater: %d\n",
krlnc_decoder_is_status_updater_enabled(decoder1));
printf("decoder 2 status updater: %d\n",
krlnc_decoder_is_status_updater_enabled(decoder2));
uint32_t payload_size = krlnc_encoder_payload_size(encoder);
uint8_t* payload1 = (uint8_t*) malloc(payload_size);
uint8_t* payload2 = (uint8_t*) malloc(payload_size);
uint32_t block_size = krlnc_encoder_block_size(encoder);
uint8_t* data_in = (uint8_t*) malloc(block_size);
uint8_t* data_out1 = (uint8_t*) malloc(block_size);
uint8_t* data_out2 = (uint8_t*) malloc(block_size);
uint32_t i = 0;
for (; i < block_size; ++i)
data_in[i] = rand() % 256;
krlnc_encoder_set_const_symbols(encoder, data_in, block_size);
krlnc_decoder_set_mutable_symbols(decoder1, data_out1, block_size);
krlnc_decoder_set_mutable_symbols(decoder2, data_out2, block_size);
// Skip the systematic phase as the effect of the symbol status decoder is
// only visible when reading coded packets.
krlnc_encoder_set_systematic_off(encoder);
while (!krlnc_decoder_is_complete(decoder1))
{
krlnc_encoder_write_payload(encoder, payload1);
// Copy payload1, because the decoder modifies the payload buffer
// during read_payload, so we cannot use the same payload twice!
memcpy(payload2, payload1, payload_size);
// Pass the generated packet to the decoder
krlnc_decoder_read_payload(decoder1, payload1);
krlnc_decoder_read_payload(decoder2, payload2);
printf("decoder1: %d\n", krlnc_decoder_symbols_uncoded(decoder1));
printf("decoder2: %d\n", krlnc_decoder_symbols_uncoded(decoder2));
printf("-----------------\n");
}
if (memcmp(data_in, data_out1, block_size) == 0 &&
memcmp(data_in, data_out2, block_size) == 0)
{
printf("Data decoded correctly\n");
}
else
{
printf("Unexpected failure to decode, please file a bug report :)\n");
}
free(data_in);
free(data_out1);
free(data_out2);
free(payload1);
free(payload2);
krlnc_delete_encoder(encoder);
krlnc_delete_decoder(decoder1);
krlnc_delete_decoder(decoder2);
krlnc_delete_encoder_factory(encoder_factory);
krlnc_delete_decoder_factory(decoder_factory);
return 0;
}
@@ -0,0 +1,7 @@
#! /usr/bin/env python
# encoding: utf-8
bld.program(features='cxx limit_includes',
source='symbol_status_updater.c',
target='symbol_status_updater',
use=['kodo_rlnc_c_static'])
@@ -0,0 +1,193 @@
// Copyright Steinwurf ApS 2018.
// Distributed under the "STEINWURF EVALUATION LICENSE 1.0".
// See accompanying file LICENSE.rst or
// http://www.steinwurf.com/licensing
#include <stdint.h>
#include <stdlib.h>
#include <kodo_rlnc_c/decoder.h>
#ifdef _WIN32
#include <winsock2.h>
typedef int socklen_t;
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#endif
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <assert.h>
// Count the total number of packets received in order to decode
unsigned int rx_packets;
static void exit_on_sigint(int sig)
{
(void) sig;
printf("\nTotal number of received packets: %d\n", rx_packets);
exit(0);
}
int main(int argc, char* argv[])
{
// Variables needed for the network / socket usage
int32_t socket_descriptor = 0;
int32_t return_code = 0;
int32_t bytes_received = 0;
socklen_t remote_address_size;
struct sockaddr_in remote_address;
struct sockaddr_in local_address;
// Variables needed for the coding
uint32_t symbols = 32;
uint32_t symbol_size = 160;
int32_t finite_field = krlnc_binary8;
krlnc_decoder_factory_t decoder_factory = NULL;
krlnc_decoder_t decoder = NULL;
// The buffer used to receive incoming packets
uint32_t payload_size = 0;
uint8_t* payload = 0;
// Keeps track of which symbols have been decoded
uint8_t* decoded = (uint8_t*) malloc(sizeof(uint8_t) * symbols);
// Initialize winsock if on Windows
#ifdef _WIN32
WORD versionWanted = MAKEWORD(1, 1);
WSADATA wsaData;
return_code = WSAStartup(versionWanted, &wsaData);
if (return_code != 0)
{
// Tell the user that we could not find a usable
// Winsock DLL.
printf("WSAStartup failed with error: %d\n", return_code);
exit(1);
}
#endif
// Initialize global variables
rx_packets = 0;
if (argc < 3)
{
printf("usage : %s <port> <symbols>\n", argv[0]);
exit(1);
}
// Socket creation
socket_descriptor = socket(AF_INET, SOCK_DGRAM, 0);
if (socket_descriptor < 0)
{
printf("%s: cannot open socket \n", argv[0]);
exit(1);
}
// Bind local server port
local_address.sin_family = AF_INET;
local_address.sin_addr.s_addr = htonl(INADDR_ANY);
local_address.sin_port = htons(atoi(argv[1]));
return_code = bind(socket_descriptor, (struct sockaddr*) &local_address,
sizeof(local_address));
if (return_code < 0)
{
printf("%s: cannot bind port number %d \n", argv[0], atoi(argv[1]));
exit(1);
}
// Install signal handler
signal(SIGINT, exit_on_sigint);
// Initialize the factory with the chosen symbols and symbol size
symbols = atoi(argv[2]);
// Create the encoder factory
decoder_factory = krlnc_new_decoder_factory(
finite_field, symbols, symbol_size);
decoder = krlnc_decoder_factory_build(decoder_factory);
// Create the buffer needed for the payload
payload_size = krlnc_decoder_payload_size(decoder);
payload = (uint8_t*) malloc(payload_size);
uint32_t block_size = krlnc_decoder_block_size(decoder);
uint8_t* data_out = (uint8_t*) malloc(block_size);
krlnc_decoder_set_mutable_symbols(decoder, data_out, block_size);
// Zero initialize the decoded array */
memset(decoded, '\0', sizeof(uint8_t) * symbols);
printf("%s: waiting for data on UDP port %u\n", argv[0], atoi(argv[1]));
// Receiver loop
while (!krlnc_decoder_is_complete(decoder))
{
// Receive message
remote_address_size = sizeof(remote_address);
bytes_received = recvfrom(
socket_descriptor, payload, payload_size, 0,
(struct sockaddr*) &remote_address, &remote_address_size);
if (bytes_received < 0)
{
printf("%s: recvfrom error %d\n", argv[0], bytes_received);
fflush(stdout);
continue;
}
// Print received message
printf("%s: UDP packet from %s:%u : %d\n",
argv[0],inet_ntoa(remote_address.sin_addr),
ntohs(remote_address.sin_port), bytes_received);
++rx_packets;
// Packet got through - pass that packet to the decoder
krlnc_decoder_read_payload(decoder, payload);
if (krlnc_decoder_is_partially_complete(decoder))
{
uint32_t i = 0;
for (; i < symbols; ++i)
{
if (!krlnc_decoder_is_symbol_uncoded(decoder, i))
continue;
if (!decoded[i])
{
// Update that this symbol now has been decoded,
// in a real application we could copy out the symbol
// using the krlnc_copy_from_symbol(..) or use the data_out
// directly.
printf("Symbol %d was decoded\n", i);
decoded[i] = 1;
}
}
}
}
printf("Data decoded!\n");
// Cleanup
free(decoded);
free(payload);
krlnc_delete_decoder(decoder);
krlnc_delete_decoder_factory(decoder_factory);
return 0;
}
Oops, something went wrong.

0 comments on commit 6006064

Please sign in to comment.