diff --git a/.gitignore b/.gitignore
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..be60ba4ba10b667314730f52599a8b87bd5e00c5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*.o
+.vscode/
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 1aa601e7f92667314805137327237211aa6d1ea7..d819753b4a3bd627db7dcf8bd5e9a76fe315da6a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,10 @@
 # You can use clang if you prefer
 CC = gcc
-
-# Feel free to add other C flags
 CFLAGS += -c -std=gnu99 -Wall -Werror -Wextra -O2
-# By default, we colorize the output, but this might be ugly in log files, so feel free to remove the following line.
 CFLAGS += -D_COLOR
 
-# You may want to add something here
-LDFLAGS +=
+HEADERS_DIR = -Iheaders
+LDFLAGS = -lz
 
 # Adapt these as you want to fit with your project
 SENDER_SOURCES = $(wildcard src/sender.c src/log.c)
@@ -19,7 +16,7 @@ RECEIVER_OBJECTS = $(RECEIVER_SOURCES:.c=.o)
 SENDER = sender
 RECEIVER = receiver
 
-all: $(SENDER) $(RECEIVER)
+all: debug $(SENDER) $(RECEIVER)
 
 $(SENDER): $(SENDER_OBJECTS)
 	$(CC) $(SENDER_OBJECTS) -o $@ $(LDFLAGS)
@@ -28,11 +25,11 @@ $(RECEIVER): $(RECEIVER_OBJECTS)
 	$(CC) $(RECEIVER_OBJECTS) -o $@ $(LDFLAGS)
 
 %.o: %.c
-	$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)
+	$(CC) $(HEADERS_DIR) $(CFLAGS) $< -o $@ $(LDFLAGS)
 
 .PHONY: clean mrproper
 
-clean:
+clean: mrproper
 	rm -f $(SENDER_OBJECTS) $(RECEIVER_OBJECTS)
 
 mrproper:
diff --git a/README.md b/README.md
index afcd6691d8f0f55fd60f8f1eeee85a3a922456e5..cf89af80a13e9df43202bebfa7016693ab52106b 100644
--- a/README.md
+++ b/README.md
@@ -1,19 +1,19 @@
-# My Wonderful LINFO1341 Project
+# Implementation of TRTP Protocol - LINFO1341 Project
 
-The very first thing you might want to do in this folder is the following command:
-```bash
-git init
-```
+## Introduction 
 
-This will initialize your Git repository.
-You should also put it in a **private** repository (GitHub, GitLab, Bitbucket,... it is up to you but it **has to** stay private).
+For a 3rd year bachelors Computer Networks given to computer science students at UCLouvain, we had to implement a transport protocol. The protocol is entitled Truncated Relieable Transport Protocol (TRTP)on top of a Ipv6 Network layer. The implementation also implement the Forward Erasure Correction (FEC) to recover corrupted packets. The full description is to be found in the `statement.pdf`.
 
-The Makefile contains all the required targets, but you might want to extend their behavior.
+## Folder Organization 
 
-Very basic skelettons of receiver and sender source files are present, have a look to understand how you can enable logging or not.
+```
+| `headers\`
+| `src\`
+| `tests\`
+```
 
-A very simple test case is present, you probably want to update it.
+## Execution
 
-You might be interested in the link simulator that can be found at https://github.com/cnp3/Linksimulator
+## Testing
 
-And finally, if this message is still there at your final submission, it looks like you forgot to provide a proper README.
\ No newline at end of file
+## System Architecture
\ No newline at end of file
diff --git a/src/log.h b/headers/log.h
similarity index 100%
rename from src/log.h
rename to headers/log.h
diff --git a/headers/packet_interface.h b/headers/packet_interface.h
new file mode 100644
index 0000000000000000000000000000000000000000..37b5c9c087dc731f8f8b572974b0542cd8aadc0f
--- /dev/null
+++ b/headers/packet_interface.h
@@ -0,0 +1,182 @@
+/**
+ * @file packet_interface.h
+ * @brief This header contains structs and definitions needed in order to encode and decode TRTP packets 
+ */
+
+#ifndef __PACKET_INTERFACE_H_
+#define __PACKET_INTERFACE_H_
+
+#include <stddef.h> /* size_t */
+#include <stdint.h> /* uintx_t */
+#include <stdio.h>  /* ssize_t */
+
+/* Raccourci pour struct pkt */
+typedef struct pkt pkt_t;
+
+/* Types de paquets */
+typedef enum {
+    PTYPE_DATA = 1,
+    PTYPE_ACK = 2,
+    PTYPE_NACK = 3,
+} ptypes_t;
+
+/* Taille maximale permise pour le payload */
+#define MAX_PAYLOAD_SIZE 512
+/* Taille maximale de Window */
+#define MAX_WINDOW_SIZE 31
+
+/* Valeur de retours des fonctions */
+typedef enum {
+    PKT_OK = 0,     /* Le paquet a ete traite avec succes */
+    E_TYPE,         /* Erreur liee au champs Type */
+    E_TR,           /* Erreur liee au champ TR */
+    E_LENGTH,       /* Erreur liee au champs Length  */
+    E_CRC,          /* CRC invalide */
+    E_WINDOW,       /* Erreur liee au champs Window */
+    E_SEQNUM,       /* Numero de sequence invalide */
+    E_NOMEM,        /* Pas assez de memoire */
+    E_NOHEADER,     /* Le paquet n'a pas de header (trop court) */
+    E_UNCONSISTENT, /* Le paquet est incoherent */
+} pkt_status_code;
+
+/* Alloue et initialise une struct pkt
+ * @return: NULL en cas d'erreur */
+pkt_t* pkt_new();
+/* Libere le pointeur vers la struct pkt, ainsi que toutes les
+ * ressources associees
+ */
+void pkt_del(pkt_t*);
+
+/*
+ * Decode des donnees recues et cree une nouvelle structure pkt.
+ * Le paquet recu est en network byte-order.
+ * La fonction verifie que:
+ * - Le CRC32 du header recu est le même que celui decode a la fin
+ *   du header (en considerant le champ TR a 0)
+ * - S'il est present, le CRC32 du payload recu est le meme que celui
+ *   decode a la fin du payload
+ * - Le type du paquet est valide
+ * - La longueur du paquet et le champ TR sont valides et coherents
+ *   avec le nombre d'octets recus.
+ *
+ * @data: L'ensemble d'octets constituant le paquet recu
+ * @len: Le nombre de bytes recus
+ * @pkt: Une struct pkt valide
+ * @post: pkt est la representation du paquet recu
+ *
+ * @return: Un code indiquant si l'operation a reussi ou representant
+ *         l'erreur rencontree.
+ */
+pkt_status_code pkt_decode(const char *data, const size_t len, pkt_t *pkt);
+
+/*
+ * Encode une struct pkt dans un buffer, prêt a être envoye sur le reseau
+ * (c-a-d en network byte-order), incluant le CRC32 du header et
+ * eventuellement le CRC32 du payload si celui-ci est non nul.
+ *
+ * @pkt: La structure a encoder
+ * @buf: Le buffer dans lequel la structure sera encodee
+ * @len: La taille disponible dans le buffer
+ * @len-POST: Le nombre de d'octets ecrit dans le buffer
+ * @return: Un code indiquant si l'operation a reussi ou E_NOMEM si
+ *         le buffer est trop petit.
+ */
+pkt_status_code pkt_encode(const pkt_t*, char *buf, size_t *len);
+
+/* Accesseurs pour les champs toujours presents du paquet.
+ * Les valeurs renvoyees sont toutes dans l'endianness native
+ * de la machine!
+ */
+ptypes_t pkt_get_type     (const pkt_t*);
+uint8_t  pkt_get_tr       (const pkt_t*);
+uint8_t  pkt_get_window   (const pkt_t*);
+uint8_t  pkt_get_seqnum   (const pkt_t*);
+uint16_t pkt_get_length   (const pkt_t*);
+uint32_t pkt_get_timestamp(const pkt_t*);
+uint32_t pkt_get_crc1     (const pkt_t*);
+/* Renvoie un pointeur vers le payload du paquet, ou NULL s'il n'y
+ * en a pas.
+ */
+const char* pkt_get_payload(const pkt_t*);
+/* Renvoie le CRC2 dans l'endianness native de la machine. Si
+ * ce field n'est pas present, retourne 0.
+ */
+uint32_t pkt_get_crc2(const pkt_t*);
+
+/* Setters pour les champs obligatoires du paquet. Si les valeurs
+ * fournies ne sont pas dans les limites acceptables, les fonctions
+ * doivent renvoyer un code d'erreur adapte.
+ * Les valeurs fournies sont dans l'endianness native de la machine!
+ */
+pkt_status_code pkt_set_type     (pkt_t*, const ptypes_t type);
+pkt_status_code pkt_set_tr       (pkt_t*, const uint8_t tr);
+pkt_status_code pkt_set_window   (pkt_t*, const uint8_t window);
+pkt_status_code pkt_set_seqnum   (pkt_t*, const uint8_t seqnum);
+pkt_status_code pkt_set_length   (pkt_t*, const uint16_t length);
+pkt_status_code pkt_set_timestamp(pkt_t*, const uint32_t timestamp);
+pkt_status_code pkt_set_crc1     (pkt_t*, const uint32_t crc1);
+/* Defini la valeur du champs payload du paquet.
+ * @data: Une succession d'octets representants le payload
+ * @length: Le nombre d'octets composant le payload
+ * @POST: pkt_get_length(pkt) == length */
+pkt_status_code pkt_set_payload(pkt_t*,
+                                const char *data,
+                                const uint16_t length);
+/* Setter pour CRC2. Les valeurs fournies sont dans l'endianness
+ * native de la machine!
+ */
+pkt_status_code pkt_set_crc2(pkt_t*, const uint32_t crc2);
+
+
+/*
+ * Decode un varuint (entier non signe de taille variable  dont le premier bit indique la longueur)
+ * encode en network byte-order dans le buffer data disposant d'une taille maximale len.
+ * @post: place à l'adresse retval la valeur en host byte-order de l'entier de taille variable stocke
+ * dans data si aucune erreur ne s'est produite
+ * @return:
+ *
+ *          -1 si data ne contient pas un varuint valide (la taille du varint
+ * est trop grande par rapport à la place disponible dans data)
+ *
+ *          le nombre de bytes utilises si aucune erreur ne s'est produite
+ */
+ssize_t varuint_decode(const uint8_t *data, const size_t len, uint16_t *retval);
+
+
+/*
+ * Encode un varuint en network byte-order dans le buffer data disposant d'une
+ * taille maximale len.
+ * @pre: val < 0x8000 (val peut être encode en varuint)
+ * @return:
+ *           -1 si data ne contient pas une taille suffisante pour encoder le varuint
+ *
+ *           la taille necessaire pour encoder le varuint (1 ou 2 bytes) si aucune erreur ne s'est produite
+ */
+ssize_t varuint_encode(uint16_t val, uint8_t *data, const size_t len);
+
+
+/*
+ * @pre: data pointe vers un buffer d'au moins 1 byte
+ * @return: la taille en bytes du varuint stocke dans data, soit 1 ou 2 bytes.
+ */
+size_t varuint_len(const uint8_t *data);
+
+
+/*
+ * @return: la taille en bytes que prendra la valeur val
+ * une fois encodee en varuint si val contient une valeur varuint valide (val < 0x8000).
+            -1 si val ne contient pas une valeur varuint valide
+ */
+ssize_t varuint_predict_len(uint16_t val);
+
+
+/*
+ * Retourne la longueur du header en bytes si le champs pkt->length
+ * a une valeur valide pour un champs de type varuint (i.e. pkt->length < 0x8000).
+ * Retourne -1 sinon
+ * @pre: pkt contient une adresse valide (!= NULL)
+ */
+ssize_t predict_header_length(const pkt_t *pkt);
+
+
+#endif  /* __PACKET_INTERFACE_H_ */
\ No newline at end of file
diff --git a/headers/receiver.h b/headers/receiver.h
new file mode 100644
index 0000000000000000000000000000000000000000..c1fcb39dc5a5e3a8f6b3b68c0b849b86fbd58fdc
--- /dev/null
+++ b/headers/receiver.h
@@ -0,0 +1,4 @@
+/**
+ * @file receiver.h
+ * @brief   This header contains all the structures and functions definitions that ae going to be used by the receiver.c 
+ */
\ No newline at end of file
diff --git a/headers/sender.h b/headers/sender.h
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/packet_interface.c b/src/packet_interface.c
new file mode 100644
index 0000000000000000000000000000000000000000..d119a7c67ffae6ffed81dbf24b85a9384e8affe2
--- /dev/null
+++ b/src/packet_interface.c
@@ -0,0 +1,208 @@
+#include "packet_interface.h"
+
+#include <arpa/inet.h>
+#include <zlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+/*************** Structures definition ***************/
+struct __attribute__((__packed__)) pkt {
+    header_t header;
+    uint8_t payload[512];
+};
+
+typedef uint8_t header_t[32];
+
+/************* Functions definition *************/
+pkt_t* pkt_new()
+{
+    pkt_t * toReturn = (pkt_t *) malloc(sizeof(pkt_t));
+    return  toReturn;
+}
+
+void pkt_del(pkt_t *pkt)
+{
+    free(pkt);
+}
+
+/**
+ * @brief Calculates the CRC32
+ * 
+ * @param buffer    : The buffer on which to calculate CRC32.
+ * @param len       : The number of bytes of the buffer.
+ * @return uint32_t 
+ */
+uint32_t calculate_crc(char * buffer, uint32_t len)
+{
+    return (uint32_t) crc32(0, (const void *) buffer, len);
+}
+
+pkt_status_code pkt_decode_data_fec(const char *data, const size_t len, pkt_t *pkt)
+{
+    
+}
+
+pkt_status_code pkt_decode_ack_nack(const char *data, const size_t len, pkt_t *pkt)
+{
+    if (len < 8)
+        return E_NOHEADER;
+    
+    // REMINDER : *data will read the first byte
+    ptypes_t type = ((*data) & 0xC0) >> 6; 
+    if ( type != PTYPE_ACK && type != PTYPE_NACK )
+        return E_TYPE;
+
+    if ( ((*data) & 0x20) != 0)
+        return E_TR;
+    
+    uint8_t seqnum, window;
+    memcpy((char *) &seqnum, data+1, 1);
+    memcpy((char *) &window, data, 1);
+    window = window & 0x1F;
+    if (seqnum > window)
+        return E_SEQNUM;
+
+    // CheckSum no need to set TR at 0 as it should be at 0
+    char crc[4];
+    memcpy(crc, data+4, 4);
+    if (calculate_crc(data, 4) != ntohl((uint32_t) crc))
+        return E_CRC;    
+}
+
+pkt_status_code pkt_decode(const char *data, const size_t len, pkt_t *pkt)
+{
+    int is_ack_nack = len <= 8; // Maximum ACK or NACK size is 12 bytes
+    if (is_ack_nack)
+        return pkt_decode_ack_nack(data, len, pkt);
+    else
+        return pkt_decode_data_fec(data, len, pkt);
+}
+
+pkt_status_code pkt_encode(const pkt_t* pkt, char *buf, size_t *len)
+{
+    /* Your code will be inserted here */
+}
+
+ptypes_t pkt_get_type  (const pkt_t* pkt)
+{
+    /* Your code will be inserted here */
+}
+
+uint8_t  pkt_get_tr(const pkt_t* pkt)
+{
+    /* Your code will be inserted here */
+}
+
+uint8_t  pkt_get_window(const pkt_t* pkt)
+{
+    /* Your code will be inserted here */
+}
+
+uint8_t  pkt_get_seqnum(const pkt_t* pkt)
+{
+    /* Your code will be inserted here */
+}
+
+uint16_t pkt_get_length(const pkt_t* pkt)
+{
+    /* Your code will be inserted here */
+}
+
+uint32_t pkt_get_timestamp   (const pkt_t* pkt)
+{
+    /* Your code will be inserted here */
+}
+
+uint32_t pkt_get_crc1   (const pkt_t* pkt)
+{
+    /* Your code will be inserted here */
+}
+
+uint32_t pkt_get_crc2   (const pkt_t* pkt)
+{
+    /* Your code will be inserted here */
+}
+
+const char* pkt_get_payload(const pkt_t* pkt)
+{
+    /* Your code will be inserted here */
+}
+
+
+pkt_status_code pkt_set_type(pkt_t *pkt, const ptypes_t type)
+{
+    /* Your code will be inserted here */
+}
+
+pkt_status_code pkt_set_tr(pkt_t *pkt, const uint8_t tr)
+{
+    /* Your code will be inserted here */
+}
+
+pkt_status_code pkt_set_window(pkt_t *pkt, const uint8_t window)
+{
+    /* Your code will be inserted here */
+}
+
+pkt_status_code pkt_set_seqnum(pkt_t *pkt, const uint8_t seqnum)
+{
+    /* Your code will be inserted here */
+}
+
+pkt_status_code pkt_set_length(pkt_t *pkt, const uint16_t length)
+{
+    /* Your code will be inserted here */
+}
+
+pkt_status_code pkt_set_timestamp(pkt_t *pkt, const uint32_t timestamp)
+{
+    /* Your code will be inserted here */
+}
+
+pkt_status_code pkt_set_crc1(pkt_t *pkt, const uint32_t crc1)
+{
+    /* Your code will be inserted here */
+}
+
+pkt_status_code pkt_set_crc2(pkt_t *pkt, const uint32_t crc2)
+{
+    /* Your code will be inserted here */
+}
+
+pkt_status_code pkt_set_payload(pkt_t *pkt,
+                                const char *data,
+                                const uint16_t length)
+{
+    /* Your code will be inserted here */
+}
+
+
+ssize_t varuint_decode(const uint8_t *data, const size_t len, uint16_t *retval)
+{
+    /* Your code will be inserted here */
+}
+
+
+ssize_t varuint_encode(uint16_t val, uint8_t *data, const size_t len)
+{
+    /* Your code will be inserted here */
+}
+
+size_t varuint_len(const uint8_t *data)
+{
+    /* Your code will be inserted here */
+}
+
+
+ssize_t varuint_predict_len(uint16_t val)
+{
+    /* Your code will be inserted here */
+}
+
+
+ssize_t predict_header_length(const pkt_t *pkt)
+{
+    /* Your code will be inserted here */
+}
\ No newline at end of file
diff --git a/statement.pdf b/statement.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..ad289f5ca0f4a03278573b7632151b1b1897d12e
Binary files /dev/null and b/statement.pdf differ
diff --git a/test b/test
new file mode 100755
index 0000000000000000000000000000000000000000..6a4d932ce38e508374b215828ab9d9780ddde912
Binary files /dev/null and b/test differ
diff --git a/test.c b/test.c
new file mode 100644
index 0000000000000000000000000000000000000000..5a5644f804aa58e9c9e69ee54797622c6f64bc16
--- /dev/null
+++ b/test.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include <zlib.h>
+
+int main() {
+  char * arr = "123456789";
+  printf("%ld\n", crc32(0, (const void *) arr, 9));
+  return 0;
+}
+  
\ No newline at end of file
diff --git a/test_files/dummy.txt b/test_files/dummy.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3af24e47a473fb2b4392ba53dec1e1ae0212df9d
--- /dev/null
+++ b/test_files/dummy.txt
@@ -0,0 +1 @@
+Hello Receiver I'm a Friendly Sender !
\ No newline at end of file