Commit 56c923be authored by Andreas Schmidt's avatar Andreas Schmidt

Block coding works.

parent 240e2d91
......@@ -8,7 +8,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
find_package (Threads)
add_subdirectory(prrt)
add_library(PRRT prrt/socket.c prrt/block.c prrt/block.h prrt/packet.c prrt/packet.h prrt/feedback_receiver.c prrt/feedback_receiver.h prrt/data_transmitter.c prrt/data_transmitter.h)
add_library(PRRT prrt/socket.c prrt/block.c prrt/block.h prrt/packet.c prrt/packet.h prrt/feedback_receiver.c prrt/feedback_receiver.h prrt/data_transmitter.c prrt/data_transmitter.h prrt/coding_params.c prrt/coding_params.h prrt/vdmcode/block_code.c prrt/vdmcode/block_code.h prrt/coding_params.c prrt/coding_params.h)
add_library(UTIL util/common.c util/common.h util/list.c util/list.h)
add_executable(sender sender.c)
......
#include "block.h"
void PrrtBlock_free(PrrtBlock **mblock) {
}
int PrrtBlock_alloc(PrrtBlock **mblock, PrrtCodingParams *cpar) {
*mblock = malloc(sizeof(PrrtBlock));
return 0;
}
#ifndef PRRT_BLOCK_H
#define PRRT_BLOCK_H
#include "../util/list.h"
#include "coding_params.h"
typedef struct {
int data_count;
int redundancy_count;
PrrtCodingParams coding_params;
List* data_blocks;
List* redundancy_blocks;
short is_coded;
} PrrtBlock;
/**
* Allocate space for a block.
*/
int PrrtBlock_alloc(PrrtBlock **mblock, PrrtCodingParams *cpar);
/**
* Frees the PrrtBlock data structure.
*/
void PrrtBlock_free(PrrtBlock **mblock);
#endif //PRRT_BLOCK_H
//
// Created by andreas on 09.02.16.
//
#include "coding_params.h"
//
// Created by andreas on 09.02.16.
//
#ifndef PRRT_CODING_PARAMS_H
#define PRRT_CODING_PARAMS_H
typedef struct {
} PrrtCodingParams;
#endif //PRRT_CODING_PARAMS_H
This diff is collapsed.
/*
* fec.c -- forward error correction based on Vandermonde matrices
* 980624
* (C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it)
*
* Portions derived from code by Phil Karn (karn@ka9q.ampr.org),
* Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari
* Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#ifndef PRRT_BLOCK_CODE_H
#define PRRT_BLOCK_CODE_H
#ifndef GF_BITS
#define GF_BITS 8 /* code over GF(2**GF_BITS) - change to suit */
#endif
#include <linux/types.h>
#include <stdint.h>
/*
* You should not need to change anything beyond this point.
* The first part of the file implements linear algebra in GF.
*
* gf is the type used to store an element of the Galois Field.
* Must constain at least GF_BITS bits.
*
* Note: unsigned char will work up to GF(256) but int seems to run
* faster on the Pentium. We use int whenever have to deal with an
* index, since they are generally faster.
*/
#if (GF_BITS < 2 || GF_BITS >16)
#error "GF_BITS must be 2 .. 16"
#endif
#if (GF_BITS <= 8)
typedef unsigned char gf;
#else
typedef unsigned short gf;
#endif
#define GF_SIZE ((1 << GF_BITS) - 1) /* powers of \alpha */
#define FEC_MAGIC 0xFECC0DEC
/**
* Struct holding parameters for a coder.
*/
struct FecParams {
uint64_t magic;
int k, n; /* parameters of the code */
gf *enc_matrix;
};
/**
* This struture contains the members for a coder that can en/decode.
* To change the code you need to free the old coder and allocate a new one.
*/
typedef struct PrrtCoder {
struct FecParams params;
gf gf_exp[2*GF_SIZE]; /* index->poly form conversion table */
int gf_log[GF_SIZE + 1];/* Poly->index form conversion table */
gf inverse[GF_SIZE+1]; /* inverse of field elem. */
/* inv[\alpha**i]=\alpha**(GF_SIZE-i-1) */
#if (GF_BITS <= 8)
gf gf_mul_table[GF_SIZE + 1][GF_SIZE + 1];
#endif
int count_num;
uint64_t tot_encoding_time;
} PrrtCoder;
/**
* This functions updates the coder with the new parameters.
* \param k number of data packets in one block
* \param n overall number of packets in one block
* \return 0 on success, -1 if parameters are invalid, -2 if no memory
*/
int PrrtCoder_get_coder(PrrtCoder **cod, int n, int k);
/**
* Free the coder object.
*/
void PrrtCoder_destroy(PrrtCoder *cod) ;
/**
* This function creates an encoded packet from some given packets.
* We are using a (k,n) systematic block code. This function takes k packets as source (the first
* k) and creates one of the n-k remaining packets. Index is the number of the packet and therefore
* lies between k and n (k <= index < n).
* \param src an array of pointers to the source packets
* \param dst the pointer to a preallocatet space for the new packet.
* \param index this is the position of the new packet in the resulting set of encoded packets
* \param sz the size of the packets that should be encoded
*/
void PrrtCoder_encode(PrrtCoder *cod, gf **src, gf *dst, int index, int sz) ;
/**
* This function decodes a set of packets.
* It takes a set of packets that is given as an array of pointers to the packets. Because this
* is an (k,n) systematic code there have to be k pointers in the array. If data packet i(< k) is
* present it should be at position i-1 (e.g. packet 1 at 0, 2 at 1) and index[i-1] should be set
* to i-1. If data packet i is not present, but replacement packet (k < )j(<= n) is present, its
* data can be pointed to at pkt[i-1]. Index[i-1] should then be set to j-1.
* \param pkt these are the pointers to the data of the different packets.
* \param index this is the position of the packets in the block code.
* \param sz the size of the data of the packets
*/
int PrrtCoder_decode(PrrtCoder *cod, gf **pkt, int *index, int sz) ;
#endif //PRRT_BLOCK_CODE_H
\ No newline at end of file
......@@ -5,29 +5,74 @@
#include "prrt/packet.h"
#include "defines.h"
#include "util/common.h"
#include "prrt/vdmcode/block_code.h"
#define NUM_THREADS 10
void *PrintHello(void *threadid) {
long tid;
tid = (long) threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
void print_gf(gf* start, int len) {
printf("GF: ");
int i;
for (i = 0; i < len; i++) {
gf s = *(start + i);
printf("%d", s);
if(i != len-1) {
printf(",");
}
}
printf("\n");
}
int main() {
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t<NUM_THREADS; t++) {
printf("In main: creating thread: %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void*) t);
if(rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
char* msg = "This is a test message.";
int j;
int n = 7;
int k = 4;
int length = 3;
printf("Start\n");
PrrtCoder* coder = NULL;
PrrtCoder_get_coder(&coder, n, k);
gf** src = malloc(sizeof(gf*) * k);
for (j = 0; j < k; j++) {
src[j] = malloc(sizeof(gf) * length);
memset(src[j], 0, sizeof(gf) * length);
}
src[0][0] = 1; src[0][1] = 2; src[0][2] = 1;
src[1][0] = 0; src[1][1] = 2; src[1][2] = 1;
src[2][0] = 4; src[2][1] = 1; src[2][2] = 6;
for (j = 0; j < k; j++) {
print_gf(src[j], length);
}
printf("---- ENC ----\n");
gf** fec = malloc(sizeof(gf*) * n);
for(j = 0; j < n; j++) {
fec[j] = malloc(sizeof(gf) * length);
memset(fec[j], 0, sizeof(gf) * length);
PrrtCoder_encode(coder, src, fec[j], j, length); // gf **src, gf *fec, int index, int sz
print_gf(fec[j], length);
}
// TODO: introduce missing packets
printf("---- DEC ----\n");
int *idx_p = malloc(k * sizeof(int));
for(j = 0; j < k; j++) {
idx_p[j] = j;
}
memcpy(fec[0], fec[6], sizeof(gf) * length);
idx_p[0] = 6;
PrrtCoder_decode(coder, fec, idx_p, length);
for(j = 0; j < k; j++) {
printf("Dec (%d) ", idx_p[j]);
print_gf(fec[j], length);
}
pthread_exit(NULL);
return 0;
}
\ No newline at end of file
......@@ -3,4 +3,8 @@
int print_buffer(char* buf, int length);
#define PERROR(fmt, args...) \
printf("PRRT ERROR: " fmt, ## args);
#endif //PRRT_COMMON_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment