コード例 #1
0
ファイル: reed_solomon.c プロジェクト: xwuxjim333/kodo-c
int main()
{
    // Seed the random number generator to produce different data every time
    srand(time(NULL));

    // Set the number of symbols and the symbol size
    uint32_t max_symbols = 10;
    uint32_t max_symbol_size = 100;

    // Here we select the codec we wish to use
    int32_t codec = kodoc_reed_solomon;

    // Here we select the finite field to use.
    // For the Reed-Solomon codec, we need to choose kodoc_binary8
    int32_t finite_field = kodoc_binary8;

    kodoc_factory_t encoder_factory =
        kodoc_new_encoder_factory(codec, finite_field,
                                 max_symbols, max_symbol_size);

    kodoc_factory_t decoder_factory =
        kodoc_new_decoder_factory(codec, finite_field,
                                 max_symbols, max_symbol_size);

    kodoc_coder_t encoder = kodoc_factory_build_coder(encoder_factory);
    kodoc_coder_t decoder = kodoc_factory_build_coder(decoder_factory);

    // Allocate some storage for a "payload". The payload is what we would
    // eventually send over a network.
    uint32_t bytes_used;
    uint32_t payload_size = kodoc_payload_size(encoder);
    uint8_t* payload = (uint8_t*) malloc(payload_size);

    // Allocate input and output data buffers
    uint32_t block_size = kodoc_block_size(encoder);
    uint8_t* data_in = (uint8_t*) malloc(block_size);
    uint8_t* data_out = (uint8_t*) malloc(block_size);

    // Fill the input buffer with random data
    uint32_t i = 0;
    for(; i < block_size; ++i)
        data_in[i] = rand() % 256;

    // Assign the data buffers to the encoder and decoder
    kodoc_set_const_symbols(encoder, data_in, block_size);
    kodoc_set_mutable_symbols(decoder, data_out, block_size);

    // Install a custom trace function for the decoder
    kodoc_set_trace_callback(decoder, trace_callback, NULL);

    uint32_t lost_payloads = 0;
    uint32_t received_payloads = 0;
    while (!kodoc_is_complete(decoder))
    {
        // The encoder will use a certain amount of bytes of the payload buffer
        bytes_used = kodoc_write_payload(encoder, payload);
        printf("Payload generated by encoder, bytes used = %d\n", bytes_used);

        // Simulate a channel with a 50% loss rate
        if (rand() % 2)
        {
            lost_payloads++;
            printf("Symbol lost on channel\n\n");
            continue;
        }

        // Pass the generated packet to the decoder
        received_payloads++;
        kodoc_read_payload(decoder, payload);
        printf("Payload processed by decoder, current rank = %d\n\n",
               kodoc_rank(decoder));
    }

    printf("Number of lost payloads: %d\n", lost_payloads);
    printf("Number of received payloads: %d\n", received_payloads);

    // Check that we properly decoded the data
    if (memcmp(data_in, data_out, block_size) == 0)
    {
        printf("Data decoded correctly\n");
    }
    else
    {
        printf("Unexpected failure to decode, please file a bug report :)\n");
    }

    // Free the allocated buffers and the kodo objects
    free(data_in);
    free(data_out);
    free(payload);

    kodoc_delete_coder(encoder);
    kodoc_delete_coder(decoder);

    kodoc_delete_factory(encoder_factory);
    kodoc_delete_factory(decoder_factory);

    return 0;
}
コード例 #2
0
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 max_symbols = 10;
    uint32_t max_symbol_size = 100;

    // Here we select the codec we wish to use
    int32_t codec = kodoc_full_vector;

    // Here we select the finite field to use.
    // Some common choices are: kodoc_binary, kodoc_binary4, kodoc_binary8
    int32_t finite_field = kodoc_binary;

    // First, we create an encoder & decoder factory.
    // The factories are used to build actual encoders/decoders
    kodoc_factory_t encoder_factory =
        kodoc_new_encoder_factory(codec, finite_field,
                                 max_symbols, max_symbol_size);

    kodoc_factory_t decoder_factory =
        kodoc_new_decoder_factory(codec, finite_field,
                                 max_symbols, max_symbol_size);

    // If we wanted to build an encoder or decoder with a smaller number of
    // symbols or a different symbol size, then this can be adjusted using the
    // following functions:
    // kodoc_factory_set_symbols(...) and kodoc_factory_set_symbol_size(...)
    // We can however not exceed the maximum values that were used when
    // creating the factory.

    kodoc_coder_t encoder = kodoc_factory_build_coder(encoder_factory);
    kodoc_coder_t decoder = kodoc_factory_build_coder(decoder_factory);

    uint32_t bytes_used;
    uint32_t payload_size = kodoc_payload_size(encoder);
    uint8_t* payload = (uint8_t*) malloc(payload_size);

    uint32_t block_size = kodoc_block_size(encoder);
    uint8_t* data_in = (uint8_t*) malloc(block_size);
    uint8_t* data_out = (uint8_t*) malloc(block_size);

    uint32_t i = 0;
    for(; i < block_size; ++i)
        data_in[i] = rand() % 256;

    kodoc_set_const_symbols(encoder, data_in, block_size);
    kodoc_set_mutable_symbols(decoder, data_out, block_size);

    // Most of the network coding algorithms supports a mode of operation
    // which is known as systematic coding. This basically means that
    // initially all symbols are sent once un-coded. The rational behind this
    // is that if no errors occur during the transmission we will not have
    // performed any unnecessary coding operations. An encoder will exit the
    // systematic phase automatically once all symbols have been sent un-coded
    // once.
    //
    // With Kodo we can ask an encoder whether it supports systematic encoding
    // or not using the following functions:

    if (kodoc_is_systematic_on(encoder))
    {
        printf("Systematic encoding enabled\n");
    }
    else
    {
        printf("Systematic encoding disabled\n");
    }

    // If we do not wish to use systematic encoding, but to do full coding
    // from the beginning we can turn systematic coding off using the following
    // API:
    //
    // if (kodoc_has_set_systematic_off(encoder))
    // {
    //    kodoc_set_systematic_off(encoder);
    // }

    // Install a custom trace function for the decoder
    kodoc_set_trace_callback(decoder, trace_callback, NULL);

    while (!kodoc_is_complete(decoder))
    {
        // The encoder will use a certain amount of bytes of the payload
        // buffer. It will never use more than payload_size, but it might
        // use less.
        bytes_used = kodoc_write_payload(encoder, payload);
        printf("Payload generated by encoder, rank = %d, bytes used = %d\n",
               kodoc_rank(encoder), bytes_used);

        // Pass the generated packet to the decoder
        kodoc_read_payload(decoder, payload);
        printf("Payload processed by decoder, current rank = %d\n",
               kodoc_rank(decoder));
    }

    if (memcmp(data_in, data_out, 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_out);
    free(payload);

    kodoc_delete_coder(encoder);
    kodoc_delete_coder(decoder);

    kodoc_delete_factory(encoder_factory);
    kodoc_delete_factory(decoder_factory);

    return 0;
}
コード例 #3
0
int main()
{
    // Seed random number generator to produce different results 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
    uint8_t max_symbols = 10;
    uint8_t max_symbol_size = 100;

    int32_t codec = kodoc_full_vector;
    int32_t finite_field = kodoc_binary8;

    // In the following we will make an encoder/decoder factory.
    // The factories are used to build actual encoders/decoder
    kodoc_factory_t encoder_factory =
        kodoc_new_encoder_factory(codec, finite_field,
                                  max_symbols, max_symbol_size);

    kodoc_factory_t decoder_factory =
        kodoc_new_decoder_factory(codec, finite_field,
                                  max_symbols, max_symbol_size);

    // If we wanted to build an encoder or decoder with a smaller number of
    // symbols or a different symbol size, then this can be adjusted using the
    // following functions:
    //      kodoc_factory_set_symbols(...)
    //      kodoc_factory_set_symbol_size(...)
    // We cannot exceed the maximum values which was used when building
    // the factory.
    kodoc_coder_t encoder = kodoc_factory_build_coder(encoder_factory);
    kodoc_coder_t decoder = kodoc_factory_build_coder(decoder_factory);

    // Allocate some storage for a "payload" the payload is what we would
    // eventually send over a network
    uint32_t payload_size = kodoc_payload_size(encoder);
    uint8_t* payload = (uint8_t*) malloc(payload_size);

    // Allocate some data to encode. In this case we make a buffer
    // with the same size as the encoder's block size (the max.
    // amount a single encoder can encode)
    uint32_t block_size = kodoc_block_size(encoder);
    uint8_t* data_in = (uint8_t*) malloc(block_size);

    // Just for fun - fill the data with random data
    uint32_t i = 0;
    for (; i < block_size; ++i)
    {
        data_in[i] = rand() % 256;
    }

    kodoc_set_const_symbols(encoder, data_in, block_size);

    uint8_t* data_out = (uint8_t*) malloc(block_size);
    kodoc_set_mutable_symbols(decoder, data_out, block_size);

    printf("Starting encoding / decoding\n");
    while (!kodoc_is_complete(decoder))
    {
        // If the chosen codec stack supports systematic coding
        if (kodoc_has_systematic_interface(encoder))
        {
            // With 50% probability toggle systematic
            if ((rand() % 2) == 0)
            {
                if (kodoc_is_systematic_on(encoder))
                {
                    printf("Turning systematic OFF\n");
                    kodoc_set_systematic_off(encoder);
                }
                else
                {
                    printf("Turn systematic ON\n");
                    kodoc_set_systematic_on(encoder);
                }
            }
        }

        // Encode a packet into the payload buffer
        kodoc_write_payload(encoder, payload);

        if ((rand() % 2) == 0)
        {
            printf("Drop packet\n");
            continue;
        }

        // Pass that packet to the decoder
        kodoc_read_payload(decoder, payload);

        printf("Rank of decoder %d\n", kodoc_rank(decoder));

        // Symbols that were received in the systematic phase correspond
        // to the original source symbols and are therefore marked as
        // decoded
        printf("Symbols decoded %d\n", kodoc_symbols_uncoded(decoder));
    }

    if (memcmp(data_in, data_out, block_size) == 0)
    {
        printf("Data decoded correctly\n");
    }
    else
    {
        printf("Unexpected failure to decode, please file a bug report :)\n");
    }

    free(data_in);
    free(payload);

    kodoc_delete_coder(encoder);
    kodoc_delete_coder(decoder);

    kodoc_delete_factory(encoder_factory);
    kodoc_delete_factory(decoder_factory);

    return 0;
}
コード例 #4
0
JNIEXPORT
jboolean JNICALL Java_com_steinwurf_dummy_1android_MainActivity_runKodo(
    JNIEnv* env, jobject thiz)
{
    // Seed random number generator to produce different results 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 max_symbols = 42;
    uint32_t max_symbol_size = 160;

    // Select the coding to use
    int32_t code_type = kodoc_full_vector;

    // Select the finite field
    int32_t finite_field = kodoc_binary;

    // Create the factories
    kodoc_factory_t encoder_factory =
        kodoc_new_encoder_factory(code_type, finite_field,
                                  max_symbols, max_symbol_size);

    kodoc_factory_t decoder_factory =
        kodoc_new_decoder_factory(code_type, finite_field,
                                  max_symbols, max_symbol_size);

    // Create the coders
    kodoc_coder_t encoder = kodoc_factory_build_coder(encoder_factory);
    kodoc_coder_t decoder = kodoc_factory_build_coder(decoder_factory);

    // Generate the data
    uint32_t payload_size = kodoc_payload_size(encoder);
    uint8_t* payload = (uint8_t*) malloc(payload_size);

    uint32_t block_size = kodoc_block_size(encoder);
    uint8_t* data_in = (uint8_t*) malloc(block_size);

    uint32_t i = 0;
    for (; i < block_size; ++i)
        data_in[i] = rand() % 256;

    // Set the date to encode
    kodoc_set_const_symbols(encoder, data_in, block_size);

    uint8_t* data_out = (uint8_t*) malloc(block_size);
    kodoc_set_mutable_symbols(decoder, data_out, block_size);

    // Run the decoding
    while (!kodoc_is_complete(decoder))
    {
        kodoc_write_payload(encoder, payload);
        kodoc_read_payload(decoder, payload);
    }

    // Check if the decoding was successful
    bool success = false;
    if (memcmp(data_in, data_out, block_size) == 0)
        success = true;

    // Clean up
    free(data_in);
    free(data_out);
    free(payload);

    kodoc_delete_coder(encoder);
    kodoc_delete_coder(decoder);

    kodoc_delete_factory(encoder_factory);
    kodoc_delete_factory(decoder_factory);

    return success;
}
コード例 #5
0
void test_sliding_window(uint32_t max_symbols, uint32_t max_symbol_size,
                         int32_t finite_field)
{
    kodoc_factory_t encoder_factory = kodoc_new_encoder_factory(
        kodoc_sliding_window, finite_field, max_symbols, max_symbol_size);

    kodoc_factory_t decoder_factory = kodoc_new_decoder_factory(
        kodoc_sliding_window, finite_field, max_symbols, max_symbol_size);

    kodoc_coder_t encoder = kodoc_factory_build_coder(encoder_factory);
    kodoc_coder_t decoder = kodoc_factory_build_coder(decoder_factory);

    EXPECT_EQ(max_symbols,kodoc_factory_max_symbols(encoder_factory));
    EXPECT_EQ(max_symbol_size,kodoc_factory_max_symbol_size(encoder_factory));
    EXPECT_EQ(max_symbols, kodoc_symbols(encoder));
    EXPECT_EQ(max_symbol_size,kodoc_symbol_size(encoder));

    EXPECT_EQ(max_symbols, kodoc_factory_max_symbols(decoder_factory));
    EXPECT_EQ(max_symbol_size, kodoc_factory_max_symbol_size(decoder_factory));
    EXPECT_EQ(max_symbols, kodoc_symbols(decoder));
    EXPECT_EQ(max_symbol_size, kodoc_symbol_size(decoder));

    EXPECT_EQ(max_symbols * max_symbol_size, kodoc_block_size(encoder));
    EXPECT_EQ(max_symbols * max_symbol_size, kodoc_block_size(decoder));

    EXPECT_TRUE(kodoc_factory_max_payload_size(encoder_factory) >=
                kodoc_payload_size(encoder));

    EXPECT_TRUE(kodoc_factory_max_payload_size(decoder_factory) >=
                kodoc_payload_size(decoder));

    EXPECT_EQ(kodoc_factory_max_payload_size(encoder_factory),
              kodoc_factory_max_payload_size(decoder_factory));

    uint32_t feedback_size = 0;

    EXPECT_EQ(kodoc_feedback_size(encoder), kodoc_feedback_size(decoder));

    feedback_size = kodoc_feedback_size(encoder);
    EXPECT_TRUE(feedback_size > 0);

    // Allocate some storage for a "payload" the payload is what we would
    // eventually send over a network
    uint32_t payload_size = kodoc_payload_size(encoder);
    uint8_t* payload = (uint8_t*) malloc(payload_size);
    uint8_t* feedback = (uint8_t*) malloc(feedback_size);

    // Allocate some data to encode. In this case we make a buffer
    // with the same size as the encoder's block size (the max.
    // amount a single encoder can encode)
    uint32_t block_size = kodoc_block_size(encoder);
    uint8_t* data_in = (uint8_t*) malloc(block_size);
    uint8_t* data_out = (uint8_t*) malloc(block_size);

    // Just for fun - fill the data with random data
    for (uint32_t i = 0; i < block_size; ++i)
        data_in[i] = rand() % 256;

    // Install a custom trace function for the encoder and decoder
    kodoc_set_trace_callback(encoder, encoder_trace_callback, NULL);
    kodoc_set_trace_callback(decoder, decoder_trace_callback, NULL);

    // Assign the data buffer to the encoder so that we may start
    // to produce encoded symbols from it
    kodoc_set_const_symbols(encoder, data_in, block_size);

    kodoc_set_mutable_symbols(decoder, data_out, block_size);

    EXPECT_TRUE(kodoc_is_complete(decoder) == 0);

    while (!kodoc_is_complete(decoder))
    {
        // Encode the packet into the payload buffer
        uint32_t payload_used = kodoc_write_payload(encoder, payload);
        EXPECT_TRUE(payload_used <= kodoc_payload_size(encoder));

        // Pass that packet to the decoder
        kodoc_read_payload(decoder, payload);
        // All payloads must be innovative due to the perfect feedback
        EXPECT_TRUE(kodoc_is_partially_complete(decoder) != 0);

        kodoc_write_feedback(decoder, feedback);
        kodoc_read_feedback(encoder, feedback);
    }
    EXPECT_TRUE(kodoc_is_complete(decoder) != 0);

    // Check if we properly decoded the data
    EXPECT_EQ(memcmp(data_in, data_out, block_size), 0);

    // Check that the trace functions were called at least once
    EXPECT_GT(encoder_trace_called, 0U);
    EXPECT_GT(decoder_trace_called, 0U);

    free(data_in);
    free(data_out);
    free(payload);
    free(feedback);

    kodoc_delete_coder(encoder);
    kodoc_delete_coder(decoder);

    kodoc_delete_factory(encoder_factory);
    kodoc_delete_factory(decoder_factory);
}
コード例 #6
0
int main()
{
    // Seed random number generator to produce different results 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 max_symbols = 3;
    uint32_t max_symbol_size = 16;

    int32_t codec = kodoc_full_vector;
    int32_t finite_field = kodoc_binary8;

    // In the following we will make an encoder/decoder factory.
    // The factories are used to build actual encoders/decoder
    kodoc_factory_t encoder_factory =
        kodoc_new_encoder_factory(codec, finite_field,
                                  max_symbols, max_symbol_size);

    kodoc_factory_t decoder_factory =
        kodoc_new_decoder_factory(codec, finite_field,
                                  max_symbols, max_symbol_size);

    // If we wanted to build an encoder or decoder with a smaller number of
    // symbols or a different symbol size, then this can be adjusted using the
    // following functions:
    //      kodoc_factory_set_symbols(...)
    //      kodoc_factory_set_symbol_size(...)
    // We cannot exceed the maximum values which was used when building
    // the factory.
    kodoc_coder_t encoder = kodoc_factory_build_coder(encoder_factory);
    kodoc_coder_t decoder = kodoc_factory_build_coder(decoder_factory);

    // Allocate some storage for a "payload" the payload is what we would
    // eventually send over a network
    uint32_t payload_size = kodoc_payload_size(encoder);
    uint8_t* payload = (uint8_t*) malloc(payload_size);

    // Allocate some data to encode. In this case we make a buffer
    // with the same size as the encoder's block size (the max.
    // amount a single encoder can encode)
    uint32_t block_size = kodoc_block_size(encoder);
    uint8_t* data_in = (uint8_t*) malloc(block_size);

    // Just for fun - fill the data with random data
    uint32_t i = 0;
    for (; i < block_size; ++i)
    {
        data_in[i] = rand() % 256;
    }

    // Install the stdout trace function for the encoder (everything will
    // be printed to stdout without filtering)
    kodoc_set_trace_stdout(encoder);
    // Set a custom zone prefix for the encoder (this helps to differentiate
    // the trace output of the encoder and the decoder)
    kodoc_set_zone_prefix(encoder, "Encoder");

    // Install a custom trace function for the decoder (we can process and
    // filter the data in our trace callback)
    kodoc_set_trace_callback(decoder, trace_callback, NULL);
    // Set a custom zone prefix for the decoder
    kodoc_set_zone_prefix(decoder, "Decoder");

    kodoc_set_const_symbols(encoder, data_in, block_size);

    uint8_t* data_out = (uint8_t*) malloc(block_size);
    kodoc_set_mutable_symbols(decoder, data_out, block_size);

    while (!kodoc_is_complete(decoder))
    {
        kodoc_write_payload(encoder, payload);

        if ((rand() % 2) == 0)
        {
            continue;
        }

        kodoc_read_payload(decoder, payload);
    }

    if (memcmp(data_in, data_out, 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_out);
    free(payload);

    kodoc_delete_coder(encoder);
    kodoc_delete_coder(decoder);

    kodoc_delete_factory(encoder_factory);
    kodoc_delete_factory(decoder_factory);

    return 0;
}
コード例 #7
0
int main()
{
    // Seed the random number generator to produce different data every time
    srand(time(NULL));

    // Set the number of symbols and the symbol size
    uint32_t max_symbols = 10;
    uint32_t max_symbol_size = 100;

    // Here we select the codec we wish to use
    int32_t codec = kodoc_perpetual;

    // Here we select the finite field to use.
    // kodoc_binary8 is common choice for the perpetual codec
    int32_t finite_field = kodoc_binary8;

    // First, we create an encoder & decoder factory.
    // The factories are used to build actual encoders/decoders
    kodoc_factory_t encoder_factory =
        kodoc_new_encoder_factory(codec, finite_field,
                                  max_symbols, max_symbol_size);

    kodoc_factory_t decoder_factory =
        kodoc_new_decoder_factory(codec, finite_field,
                                  max_symbols, max_symbol_size);

    kodoc_coder_t encoder = kodoc_factory_build_coder(encoder_factory);
    kodoc_coder_t decoder = kodoc_factory_build_coder(decoder_factory);

    // The perpetual encoder supports three operation modes:
    //
    // 1) Random pivot mode (default):
    //    The pivot element is drawn at random
    // 2) Pseudo-systematic
    //    Pivot elements are generated with indices 0,1,2,...,n
    //    After that, the pivots are drawn at random.
    // 3) Pre-charging
    //    For the first "width" symbols, the pivot index is 0. After that,
    ///   the pseudo-systematic mode is used. Finally, pivots are drawn at
    ///   random. The resulting indices: 0(width times),1,2,...,n
    //
    // The operation mode is set with the following API.
    // Note that if both pre-charging and pseudo-systematic is enabled,
    // pre-charging takes precedence.

    // Enable the pseudo-systematic operation mode - faster
    kodoc_set_pseudo_systematic(encoder, 1);

    // Enable the pre-charing operation mode - even faster
    //kodoc_set_pre_charging(encoder, 1);

    printf("Pseudo-systematic flag: %d\n", kodoc_pseudo_systematic(encoder));
    printf("Pre-charging flag: %d\n", kodoc_pre_charging(encoder));

    // The width of the perpetual code can be set either as a number of symbols
    // using kodoc_set_width(), or as a ratio of the number of symbols using
    // kodoc_set_width_ratio().
    //
    // The default width is set to 10% of the number of symbols.
    printf("The width ratio defaults to: %0.2f"
           " (therefore the calculated width is %d)\n",
           kodoc_width_ratio(encoder), kodoc_width(encoder));

    /// When modifying the width, the width ratio will change as well
    kodoc_set_width(encoder, 4);
    printf("The width was set to: %d "
           " (therefore the calculated width ratio is %0.2f)\n",
           kodoc_width(encoder), kodoc_width_ratio(encoder));

    /// When modifying the width ratio, the width will change as well
    kodoc_set_width_ratio(encoder, 0.2);
    printf("The width ratio was set to: %0.2f"
           " (therefore the calculated width is %d)\n",
           kodoc_width_ratio(encoder), kodoc_width(encoder));

    // Allocate some storage for a "payload". The payload is what we would
    // eventually send over a network.
    uint32_t bytes_used;
    uint32_t payload_size = kodoc_payload_size(encoder);
    uint8_t* payload = (uint8_t*) malloc(payload_size);

    // Allocate input and output data buffers
    uint32_t block_size = kodoc_block_size(encoder);
    uint8_t* data_in = (uint8_t*) malloc(block_size);
    uint8_t* data_out = (uint8_t*) malloc(block_size);

    // Fill the input buffer with random data
    uint32_t i = 0;
    for (; i < block_size; ++i)
        data_in[i] = rand() % 256;

    // Assign the data buffers to the encoder and decoder
    kodoc_set_const_symbols(encoder, data_in, block_size);
    kodoc_set_mutable_symbols(decoder, data_out, block_size);

    // Install a custom trace function for the decoder
    kodoc_set_trace_callback(decoder, trace_callback, NULL);

    uint32_t lost_payloads = 0;
    uint32_t received_payloads = 0;
    while (!kodoc_is_complete(decoder))
    {
        // The encoder will use a certain amount of bytes of the payload buffer
        bytes_used = kodoc_write_payload(encoder, payload);
        printf("Payload generated by encoder, bytes used = %d\n", bytes_used);

        // Simulate a channel with a 50% loss rate
        if (rand() % 2)
        {
            lost_payloads++;
            printf("Symbol lost on channel\n\n");
            continue;
        }

        // Pass the generated packet to the decoder
        received_payloads++;
        kodoc_read_payload(decoder, payload);
        printf("Payload processed by decoder, current rank = %d\n\n",
               kodoc_rank(decoder));
    }

    printf("Number of lost payloads: %d\n", lost_payloads);
    printf("Number of received payloads: %d\n", received_payloads);

    // Check that we properly decoded the data
    if (memcmp(data_in, data_out, block_size) == 0)
    {
        printf("Data decoded correctly\n");
    }
    else
    {
        printf("Unexpected failure to decode, please file a bug report :)\n");
    }

    // Free the allocated buffers and the kodo objects
    free(data_in);
    free(data_out);
    free(payload);

    kodoc_delete_coder(encoder);
    kodoc_delete_coder(decoder);

    kodoc_delete_factory(encoder_factory);
    kodoc_delete_factory(decoder_factory);

    return 0;
}
コード例 #8
0
ファイル: sparse_seed.c プロジェクト: xwuxjim333/kodo-c
int main()
{
    // Seed the random number generator to produce different data every time
    srand(time(NULL));

    // Set the number of symbols and the symbol size
    uint32_t max_symbols = 10;
    uint32_t max_symbol_size = 100;

    // Here we select the codec we wish to use
    int32_t codec = kodoc_sparse_seed;

    // Here we select the finite field to use.
    // For the sparse seed codec, we can choose kodoc_binary, kodoc_binary4 or
    // kodoc_binary8 (kodoc_binary is recommended for high performance)
    int32_t finite_field = kodoc_binary8;

    kodoc_factory_t encoder_factory =
        kodoc_new_encoder_factory(codec, finite_field,
                                 max_symbols, max_symbol_size);

    kodoc_factory_t decoder_factory =
        kodoc_new_decoder_factory(codec, finite_field,
                                 max_symbols, max_symbol_size);

    kodoc_coder_t encoder = kodoc_factory_build_coder(encoder_factory);
    kodoc_coder_t decoder = kodoc_factory_build_coder(decoder_factory);

    // The coding vector density on the encoder is set with
    // kodoc_set_density().
    // Note: the density can be adjusted at any time. This feature can be used
    // to adapt to changing network conditions.
    printf("The density defaults to: %0.2f\n", kodoc_density(encoder));
    kodoc_set_density(encoder, 0.4);
    printf("The density was set to: %0.2f\n", kodoc_density(encoder));
    // A low density setting can lead to a large number of redundant symbols.
    // In practice, the value should be tuned to the specific scenario.

    // Allocate some storage for a "payload". The payload is what we would
    // eventually send over a network.
    uint32_t bytes_used;
    uint32_t payload_size = kodoc_payload_size(encoder);
    uint8_t* payload = (uint8_t*) malloc(payload_size);

    // Allocate input and output data buffers
    uint32_t block_size = kodoc_block_size(encoder);
    uint8_t* data_in = (uint8_t*) malloc(block_size);
    uint8_t* data_out = (uint8_t*) malloc(block_size);

    // Fill the input buffer with random data
    uint32_t i = 0;
    for(; i < block_size; ++i)
        data_in[i] = rand() % 256;

    // Assign the data buffers to the encoder and decoder
    kodoc_set_const_symbols(encoder, data_in, block_size);
    kodoc_set_mutable_symbols(decoder, data_out, block_size);

    // Install a custom trace function for the decoder
    kodoc_set_trace_callback(decoder, trace_callback, NULL);

    uint32_t lost_payloads = 0;
    uint32_t received_payloads = 0;
    while (!kodoc_is_complete(decoder))
    {
        // The encoder will use a certain amount of bytes of the payload buffer
        bytes_used = kodoc_write_payload(encoder, payload);
        printf("Payload generated by encoder, bytes used = %d\n", bytes_used);

        // Simulate a channel with a 50% loss rate
        if (rand() % 2)
        {
            lost_payloads++;
            printf("Symbol lost on channel\n\n");
            continue;
        }

        // Pass the generated packet to the decoder
        received_payloads++;
        kodoc_read_payload(decoder, payload);
        printf("Payload processed by decoder, current rank = %d\n\n",
               kodoc_rank(decoder));
    }

    printf("Number of lost payloads: %d\n", lost_payloads);
    printf("Number of received payloads: %d\n", received_payloads);

    // Check that we properly decoded the data
    if (memcmp(data_in, data_out, block_size) == 0)
    {
        printf("Data decoded correctly\n");
    }
    else
    {
        printf("Unexpected failure to decode, please file a bug report :)\n");
    }

    // Free the allocated buffers and the kodo objects
    free(data_in);
    free(data_out);
    free(payload);

    kodoc_delete_coder(encoder);
    kodoc_delete_coder(decoder);

    kodoc_delete_factory(encoder_factory);
    kodoc_delete_factory(decoder_factory);

    return 0;
}