diff --git a/.vscode/launch.json b/.vscode/launch.json
index 31e7df83762744c2c32c5dc5ff824e1e5d8a4fda..11891954316b6c34d718bd10c6437f1a38fa4e1f 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -1,28 +1,33 @@
-{
-    // Use IntelliSense to learn about possible attributes.
-    // Hover to view descriptions of existing attributes.
-    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
-    "version": "0.2.0",
-    "configurations": [
-        {
-            "type": "gdb",
-            "request": "attach",
-            "name": "Debug embedded",
-            "usewsl": true,
-            "gdbpath": "arm-none-eabi-gdb",
-            "executable": "./target/thumbv7em-none-eabihf/debug/d7018e_coap",
-            "target": "192.168.1.4:3333",
-            "remote": true,
-            "autorun": [
-                "monitor reset init",
-                "monitor arm semihosting enable",
-                "monitor tpiu config internal /tmp/itm.log uart off 84000000", 
-                "monitor itm port 0 on",
-                "load",
-                "monitor reset init",
-                "continue"
-            ],
-            "cwd": "${workspaceRoot}"
-        },
-    ]
+{
+    // Use IntelliSense to learn about possible attributes.
+    // Hover to view descriptions of existing attributes.
+    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Debug",
+            "type": "gdb",
+            "request": "launch",
+            "target": "./bin/executable",
+            "cwd": "${workspaceRoot}"
+        },
+        {
+            "type": "gdb",
+            "request": "attach",
+            "name": "Debug embedded",
+            "gdbpath": "/usr/bin/arm-none-eabi-gdb",
+            "executable": "./target/thumbv7em-none-eabihf/debug/app",
+            "target": "192.168.1.4:3333",
+            "remote": true,
+            "autorun": [
+                "monitor reset init",
+                "monitor arm semihosting enable",
+                "monitor tpiu config internal itm.log uart off 64000000",
+                "monitor itm port 0 on",
+                "load",
+                "monitor reset init"
+            ],
+            "cwd": "${workspaceRoot}"
+        },
+    ]
 }
\ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
index bd0ae4f2161c9e1ce87a78cebf6b3d215aaedcb6..f15fdf04ab47c2ea89a8aad09ca6500f43f8aa03 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,65 +1,20 @@
 [package]
-name = "d7018e_coap"
+name = "xoap"
 version = "0.1.0"
-authors = ["Joakim Lundberg <joakim@joakimlundberg.com>"]
-categories = ["embedded", "hardware-support", "no-std"]
-description = "CoAP on embedded rust"
+description = "A CoAP library for bare-metal applications"
 readme = "README.md"
-repository = "https://github.com/Shawnshank/D7018E_Project"
-keywords = ["CoAP", "Embedded", "arm", "stm32"]
+documentation = ""
+repository = ""
 license = "MIT OR Apache-2.0"
+authors = ["Joakim Lundberg <joakim@joakimlundberg.com>"]
+keywords = ["CoAP", "xoap"]
 
 [dependencies]
-cortex-m-semihosting = "0.2.0"
-static-ref = "0.2.0"
-volatile-register = "0.2.0"
-m = "0.1.1"
-heapless = "0.2.4"
-f4 = {git = "https://github.com/jsjolund/f4"}
-#xoap = { path = "../projects/xoap", version = "0.1.0", default-features = false, features = ["baremetal"] }# git = "https://github.com/Shawnshank/xoap"
-
-[dependencies.smoltcp]
-git = "https://github.com/m-labs/smoltcp"
-rev = "cd893e6a"
-default-features = false
-features = ["proto-ipv4", "socket-tcp"]
-
-[dependencies.stm32f40x]
-git = "https://gitlab.henriktjader.com/pln/STM32F40x.git"
-features = ["rt"]
-version = "0.2.0"
-
-[dependencies.cast]
-default-features = false
-version = "0.2.2"
-
-[dependencies.cortex-m]
-version = "0.3.1"
-
-[dependencies.either]
-default-features = false
-version = "1.3.0"
-
-[dependencies.embedded-hal]
-git = "https://github.com/japaric/embedded-hal"
-rev = "7d904f515d15fd5fe7ea34e18820ea83e2651fa2"
-
-[dependencies.nb]
-git = "https://github.com/japaric/nb"
-
-[dependencies.cortex-m-rt]
-features = ["abort-on-panic"]
-version = "0.3.8"
-
-[dependencies.cortex-m-debug]
-git = "https://gitlab.henriktjader.com/pln/cortex-m-debug.git"
-
-[dependencies.cortex-m-rtfm]
-version = "0.2.0"
+# Baremetal dependencies
+heapless = {version = "0.2.1"}
+#nb = {git = "https://github.com/japaric/nb", optional = true}
+cast = {default-features = false, version = "0.2.2", optional = true}
 
-[profile.release]
-lto = true
+[dev-dependencies]
+quickcheck = "0.2.27"
 
-[profile.dev]
-incremental = false
-codegen-units = 1
\ No newline at end of file
diff --git a/README.md b/README.md
index 2f7fa8be0dd3a62b87131a8ae61a45e52bb840ce..453de44328ba9aab2cae0a9c6fdbff1eb37fa259 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,22 @@
-# Embedded rust with CoAP
-This project aims to make [CoAP](https://tools.ietf.org/html/rfc7252) on ARM embedded systems coded with [Rust](https://www.rust-lang.org) a thing.
-
-This project is part of the course D7018E at [LuleƄ tekniska universitet](https://www.ltu.se) taught by [Per Lindgren](https://www.ltu.se/staff/p/pln-1.11258).
-
-## Installation
-
-## Crates used
-- [coap](http://covertness.github.io/coap-rs/coap/index.html) 
-- [smoltcp](https://crates.io/crates/smoltcp)
-
-
-## ESP8266
-As a WiFi bridge the ESP8266 is used and communicates with the CoAP server/client over USART using [SLIP](https://tools.ietf.org/html/rfc1055)
-### Firmware
-The firmware used for the esp8266 module is [esp-just-slip](https://github.com/krzychb/esp-just-slip)
+# XoAP (NOT WORKING YET)
+[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
+
+CoAp for embedded systems in Rust.
+
+Based on [coap](http://covertness.github.io/coap-rs/coap/index.html) by Covertness
+
+## Installation
+
+First add this to your `Cargo.toml`:
+
+```toml
+[dependencies.xoap]
+version = "0.1.0"
+git = "https://github.com/Shawnshank/xoap"
+```
+
+Then, add this to your crate root:
+
+```rust
+extern crate xoap;
+```
diff --git a/src/header.rs b/src/header.rs
new file mode 100644
index 0000000000000000000000000000000000000000..5c219034d97475c5b4ded1bca909554212d5a8df
--- /dev/null
+++ b/src/header.rs
@@ -0,0 +1,161 @@
+/// Defines the header for a CoAP message
+
+pub const MAX_OPTIONS: usize = 10;
+
+/* Fixed 4 bytes (Sent/Recived header) */
+pub struct HeaderRaw {  
+    ver_type_tkl: u8;
+    code: u8,
+    ID: u16,
+} 
+
+pub struct Header {
+    version: const u8 = 1,
+    type: MessageType,
+    tkl: u8,
+    code: u8,
+    ID: u16,
+}
+
+// Only use piggyback responses
+pub struct Token {
+    value: u8,
+}
+
+pub enum MessageType {
+    None = -1,
+    Confirmable = 0,
+    NonConfirmable = 1,
+    Acknowledgement = 2,
+    Reset = 3,
+}
+
+impl HeaderRaw {
+    pub fn new() -> Self {
+        HeaderRaw {
+            ver_type_tkl: 64, // version = 1 the rest is 0
+            code: 0,
+            ID: 0,
+        }
+    }
+
+    pub fn decode_raw(&self) -> Header {
+        let newHeader = Header::new();
+        newHeader.set_tkl(self.ver_type_tkl & 0x0F);
+        newHeader.set_type(number_to_type((self.ver_type_tkl >> 4) & 0x02);
+        newHeader.set_code(self.code);
+        newHeader.set_ID(self.ID);
+
+        return newHeader;
+    }
+}
+
+impl Header{
+    pub fn new() -> Self {
+        Header {
+            //version: 1,
+            type: MessageType::None,
+            tkl: 0,
+            code: 0,
+            ID: 0,
+        }
+    }
+
+    pub fn build_raw(&self) -> HeaderRaw {
+        let newHeader = HeaderRaw::new();
+        newHeader.ver_type_tkl = (1 << 6) | self.type_to_number(get_type()) << 4 | self.get_tkl();
+        newHeader.code = self.get_code();
+        newHeader.ID = self.get_ID();
+
+        return newHeader;
+    }
+
+    #[inline]
+    pub fn get_version(&self) -> u8 {
+        self.version
+    }
+
+    #[inline]
+    pub fn get_type(&self) -> MessageType {
+        self.type
+    }
+
+    #[inline]
+    pub fn set_type(&mut self, t: MessageType) {
+        self.type = t;
+    }
+
+    #[inline]
+    pub fn get_tkl(&self) -> u8 {
+        self.tkl
+    }
+
+    #[inline]
+    pub fn set_tkl(&mut self, t: u8) {
+        self.tkl = t;
+    }
+
+    #[inline]
+    pub fn get_code(&self) -> u8 {
+        self.code
+    }
+
+    #[inline]
+    pub fn set_code(&mut self, c: u8) {
+        self.code = c;
+    }
+
+    #[inline]
+    pub fn get_ID(&self) -> u16 {
+        self.type
+    }
+
+    #[inline]
+    pub fn set_ID(&mut self, id: u16) {
+        self.ID = id;
+    }
+
+    #[inline]
+    pub fn get_classcode(&self) -> u8 {
+        self.code >> 5
+    }
+
+    #[inline]
+    pub fn set_classcode(&mut self, c: u8) {
+        let detailcode = self.code & 0x1F;
+        self.code = (c<<5) | detailcode;
+    }
+
+    #[inline]
+    pub fn get_detailcode(&self) -> u8 {
+        self.code & 0x1F
+    }
+
+    #[inline]
+    pub fn set_detailcode(&mut self, c: u8) {
+        let classcode = self.code & 0xE0;
+        self.code = c | classcode;
+    }
+
+    #[inline]
+    pub fn type_to_number(t: MessageType) -> u8 {
+        let num = match t => {
+            MessageType::Confirmable        => 0,
+            MessageType::NonConfirmable     => 1,
+            MessageType::Acknowledgement    => 2,
+            MessageType::Reset              => 3,
+            _ => -1,       
+        } 
+    }
+
+    #[inline]
+    pub fn number_to_type(n: u8) {
+        let type = match n {
+            0 => MessageType::Confirmable,
+            1 => MessageType::NonConfirmable,
+            2 => MessageType::Acknowledgement,
+            3 => MessageType::Reset,
+            _ => MessageType::None,
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000000000000000000000000000000000000..b4b89b47df86f14414d41089a9782df71f8cdb75
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,9 @@
+// Xoap lib CoAP for ARM microcontrollers
+
+#![no_std]
+#![warn(unreachable_patterns)]
+
+extern crate heapless;
+
+pub mod header;
+pub mod options;
\ No newline at end of file
diff --git a/src/options.rs b/src/options.rs
new file mode 100644
index 0000000000000000000000000000000000000000..7c5355109bbc83b1b599ae52e9a01bec7db2ea0e
--- /dev/null
+++ b/src/options.rs
@@ -0,0 +1,152 @@
+use heapless::Vec;
+use heapless::String;
+
+pub const MAX_VALUE_LENGTH: usize = 255; 
+pub const MAX_OPTIONS: usize = 10;
+
+/*
++-----+---+---+---+---+----------------+--------+--------+-------------+
+| No. | C | U | N | R | Name           | Format | Length | Default     |
++-----+---+---+---+---+----------------+--------+--------+-------------+
+| 1   | x |   |   | x | If-Match       | opaque | 0-8    | (none)      |
+| 3   | x | x | - |   | Uri-Host       | string | 1-255  | (see note 1)|
+| 4   |   |   |   | x | ETag           | opaque | 1-8    | (none)      |
+| 5   | x |   |   |   | If-None-Match  | empty  | 0      | (none)      |
+| 7   | x | x | - |   | Uri-Port       | uint   | 0-2    | (see note 1)|
+| 8   |   |   |   | x | Location-Path  | string | 0-255  | (none)      |
+| 11  | x | x | - | x | Uri-Path       | string | 0-255  | (none)      |
+| 12  |   |   |   |   | Content-Format | uint   | 0-2    | (none)      |
+| 14  |   | x | - |   | Max-Age        | uint   | 0-4    | 60          |
+| 15  | x | x | - | x | Uri-Query      | string | 0-255  | (none)      |
+| 17  | x |   |   |   | Accept         | uint   | 0-2    | (none)      |
+| 20  |   |   |   | x | Location-Query | string | 0-255  | (none)      |
+| 28  |   |   | x |   | Size2          | uint   | 0-4    | (none)      |
+| 35  | x | x | - |   | Proxy-Uri      | string | 1-1034 | (none)      |
+| 39  | x | x | - |   | Proxy-Scheme   | string | 1-255  | (none)      |
+| 60  |   |   | x |   | Size1          | uint   | 0-4    | (none)      |
++-----+---+---+---+---+----------------+--------+--------+-------------+
+C = Critical, U = Unsafe, N = No-cache-Key, R = Repeatable,
+*/
+
+pub enum ValueFormat {
+    empty   = 0,    // A zero-length sequence of bytes.
+    opaque  = 1,    // An opaque sequence of bytes.
+    uint,   = 2,    // A non-negative integer that is represented in network byte order using the number of bytes given by the Option Length field.
+    string, = 3,    // A Unicode string that is encoded using UTF-8 [RFC3629] in Net-Unicode form [RFC5198].
+    block,  = 4, 
+}
+
+pub struct Format {
+    delta: u8,      // u4
+    length: u8,     // u4
+    value: u8,      // TODO
+} 
+
+impl Format {
+    pub fn new() -> Self {
+        Format {
+            delta: 0,
+            length: 0,
+            value: 0,   // TODO     // Network byte order - Big-endian
+        }
+    }
+}
+
+pub enum Options {
+    None            = 0,    // Internal
+    IfMatch         = 1,
+    URIHost         = 3,
+    ETag            = 4,
+    IfNoneMatch     = 5,
+    URIPort         = 7,
+    LocationPath    = 8,
+    URIPath         = 11,
+    ContentFormat   = 12,
+    MaxAge          = 14,
+    URIQuery        = 15,
+    Accept          = 17,
+    LocationQuery   = 20,
+    Size2           = 28,
+    ProxyURI        = 35,
+    ProxyScheme     = 39,
+    Size1           = 60,
+}
+
+pub struct OptionHeader {
+    number: u8,
+    name: u8,
+    type: u8,
+    minLen: u8,
+    maxLen: u8,
+    multipleValues: u8,
+    defaultValue: u8,
+}
+
+impl OptionHeader {
+    pub fn new()
+}
+
+pub struct CoAPOption {
+    opt: Options,
+    format: Format,
+    length: u8,
+}
+
+impl CoAPOption {
+    pub fn new() -> Self {
+        CoAPOption {
+            opt: Options::None,
+            format: Format::new(),
+            length: 0,
+        }
+    }
+
+    pub fn
+}
+
+pub fn option_to_number(opt: Options) -> u8 {
+    let num = match opt  {
+        Options::None           => 0,
+        Options::IfMatch        => 1,
+        Options::URIHost        => 3,
+        Options::ETag           => 4,
+        Options::IfNoneMatch    => 5,
+        Options::URIPort        => 7,
+        Options::LocationPath   => 8,
+        Options::URIPath        => 11,
+        Options::ContentFormat  => 12,
+        Options::MaxAge         => 14,
+        Options::URIQuery       => 15,
+        Options::Accept         => 17,
+        Options::LocationQuery  => 20,
+        Options::Size2          => 28,
+        Options::ProxyURI       => 35,
+        Options::ProxyScheme    => 39,
+        Options::Size1          => 60,
+        _ => (),
+    }
+    return num;
+}
+
+pub fn number_to_option(num: u8) -> Options {
+    let opt = match num  {
+        1   => Options::IfMatch,
+        3   => Options::URIHost,
+        4   => Options::ETag,
+        5   => Options::IfNoneMatch,
+        7   => Options::URIPort,
+        8   => Options::LocationPath,
+        11  => Options::URIPath,
+        12  => Options::ContentFormat,
+        14  => Options::MaxAge,
+        15  => Options::URIQuery,
+        17  => Options::Accept,
+        20  => Options::LocationQuery,
+        28  => Options::Size2,
+        35  => Options::ProxyURI,
+        39  => Options::ProxyScheme ,
+        60  => Options::Size1,
+        _ => (),
+    }
+    return opt;
+}
\ No newline at end of file
diff --git a/src/packet.rs b/src/packet.rs
new file mode 100644
index 0000000000000000000000000000000000000000..a10c79c5e0643294d9897040bfd322288968e4d7
--- /dev/null
+++ b/src/packet.rs
@@ -0,0 +1,14 @@
+use heapless::Vec;
+
+use header;
+use options;
+
+const MAX_PACKET_SIZE: usize = 255;     // Maximum amount of bytes in a singel packet
+
+pub let PacketRaw: Vec<u8, [u8; MAX_PACKET_SIZE]> = Vec::new();
+
+pub struct Packet {
+    header: header::HeaderRaw,
+    token: u32,     // Should be 8 bytes
+    options: Vec<options::CoAPOption, [options::CoAPOption; options::MAX_OPTIONS]
+}
\ No newline at end of file