diff --git a/Message.cpp b/Message.cpp
index 70721303f56e8b6f947a812be00cfe916ba7b65d..b2aaa19e956a6f6962082ecbc07882443fd575cf 100644
--- a/Message.cpp
+++ b/Message.cpp
@@ -1,60 +1,87 @@
 #include "Message.h"
-#include <bitset>
 #include "definitions.h"
 
 BYTE Message::calcParity() {
-    char parity = 0x00;
-    char *m = this->header.c_ctrl.begin + this->header.c_ctrl.sizeSeq + this->header.c_ctrl.seqType + (char *)(&data[0]);
-    for(int i=0; i < strlen(m); ++i) {
+    BYTE parity = 0x00;
+    vector<BYTE> m = getMessage();
+    //Begin and parity bytes are not taken in account in parity
+    for(int i=1; i < m.size()-1; ++i) {
         parity = parity^m[i];
     }
-    this->header.c_ctrl.parity = parity;
+    this->parity = parity;
     return parity;
 }
 
 bool Message::checkParity() {
     BYTE parity = this->calcParity();
-    return (parity == this->header.c_ctrl.parity);
-}
-
-vector<int> Message::getBitFieldsAsInt(){
-    vector<int> bits;
-    // bitset<8> begin(messages[i].header.i_ctrl.begin);
-    // bitset<6> size(messages[i].header.i_ctrl.size);
-    // bitset<6> sequence(messages[i].header.i_ctrl.sequence);
-    // bitset<4> type(messages[i].header.i_ctrl.type);
-    // bitset<8> parity(messages[i].header.i_ctrl.parity);
-    bits.push_back((int)bitset<8>(header.i_ctrl.begin).to_ulong());
-    bits.push_back((int)bitset<6>(header.i_ctrl.size).to_ulong());
-    bits.push_back((int)bitset<6>(header.i_ctrl.sequence).to_ulong());
-    bits.push_back((int)bitset<4>(header.i_ctrl.type).to_ulong());
-    bits.push_back((int)bitset<8>(header.i_ctrl.parity).to_ulong());
-    return bits;
-
-}
-
-string Message::getSendData() {
-    calcParity();
-    string s(data.begin(), data.end());
-    int size = data.size();
-    //TODO: quebrar em partes aqui? ou tem que quebrar no protocolo?
-    header.i_ctrl.size = size;
-    header.i_ctrl.sequence = 1;
-    char *fill;
-    if(size < 63) {
-        fill = (char*) malloc((63-size)*sizeof(char));
-        memset(fill, 0, (63-size)*sizeof(char));
+    return (parity == this->parity.to_ulong());
+}
+
+void Message::setBitFields(BYTE begin, BYTE sizeSeq, BYTE seqType, BYTE parity){
+    //if the size of val passed in the bitset constructor is greater than the bitset size,
+    // only the least significant bits of val are taken into consideration.
+    this->begin = bitset<BEGIN_S>(begin);
+    this->size = bitset<SIZE_S>(sizeSeq >> 2);
+    this->sequence = bitset<SEQUENCE_S>((sizeSeq << 4) | (seqType >> 4));
+    this->type = bitset<TYPE_S>(seqType);
+    this->parity = bitset<PARITY_S>(parity);
+}
+
+vector<BYTE> Message::getBitFieldsAsBytes(){
+    vector<BYTE> bitFields;
+    bitFields.push_back((BYTE)begin.to_ulong());
+    bitFields.push_back((BYTE)size.to_ulong());
+    bitFields.push_back((BYTE)sequence.to_ulong());
+    bitFields.push_back((BYTE)type.to_ulong());
+    bitFields.push_back((BYTE)parity.to_ulong());
+    return bitFields;
+}
+
+vector<BYTE> Message::getMessage(){
+    vector<BYTE> msg = getBitFieldsAsBytes();
+    msg.insert(msg.end()-2, data.begin(), data.end());
+    return msg;
+}
+
+char* Message::getMessageAsCharPointer(){
+    return reinterpret_cast<char*> (getMessage().data());
+}
+
+int Message::getMessageSize(){
+    return size.to_ulong()+4;
+}
+
+// string Message::getSendData() {
+//     calcParity();
+//     string s(data.begin(), data.end());
+//     int size = data.size();
+//     //TODO: quebrar em partes aqui? ou tem que quebrar no protocolo?
+//     header.i_ctrl.size = size;
+//     header.i_ctrl.sequence = 1;
+//     char *fill;
+//     if(size < 63) {
+//         fill = (char*) malloc((63-size)*sizeof(char));
+//         memset(fill, 0, (63-size)*sizeof(char));
+//     }
+//     string d;
+//     d += header.c_ctrl.begin;
+//     d += header.c_ctrl.sizeSeq;
+//     d += header.c_ctrl.seqType;
+//     d += s.c_str();
+//     d += fill;
+//     d += header.c_ctrl.parity;
+//     return d;
+// }
+
+ostream& operator<<(ostream& os, const Message& msg){
+    os << '|' << msg.begin << '|' << msg.size << '|' << msg.sequence << '|' << msg.type << '|';
+    for(int i=0; i<msg.data.size(); ++i){
+        os << bitset<8>(msg.data[i]);
     }
-    string d;
-    d += header.c_ctrl.begin;
-    d += header.c_ctrl.sizeSeq;
-    d += header.c_ctrl.seqType;
-    d += s.c_str();
-    d += fill;
-    d += header.c_ctrl.parity;
-    return d;
+    os << '|' << msg.parity << '|';
+    return os;
 }
 
 Message::Message() {
-    this->header.i_ctrl.begin = BEGIN;
+    this->begin = bitset<BEGIN_S>(BEGIN);
 }
diff --git a/Message.h b/Message.h
index 99c8b433fa38a8a6ac79fafe5cc08fbcd8141355..24f3bbe6d9b344cd5926a26584e3268868de2f8b 100644
--- a/Message.h
+++ b/Message.h
@@ -5,13 +5,23 @@
 class Message {
 
 public:
-    Header header;
+    bitset<BEGIN_S> begin;
+    bitset<SIZE_S> size;
+    bitset<SEQUENCE_S> sequence;
+    bitset<TYPE_S> type;
+    bitset<PARITY_S> parity;
     vector<BYTE> data;
+
     BYTE calcParity();
     bool checkParity();
-    string getSendData();
-    vector<int> getBitFieldsAsInt();
+    // string getSendData();
+    void setBitFields(BYTE begin, BYTE sizeSeq, BYTE seqType, BYTE parity);
+    vector<BYTE> getBitFieldsAsBytes();
+    vector<BYTE> getMessage();
+    char* getMessageAsCharPointer();
+    int getMessageSize();
 
     Message();
 };
+ostream& operator<<(ostream& os, const Message& msg);
 #endif
diff --git a/Protocol.cpp b/Protocol.cpp
index 3b77f03f49089530ca01b9891b7beceabe97bd40..c47bf94ff93839d0b02d8678208b0899e5a5ff32 100644
--- a/Protocol.cpp
+++ b/Protocol.cpp
@@ -1,5 +1,4 @@
 #include <sys/socket.h>
-#include <bitset>
 #include "Protocol.h"
 #include "definitions.h"
 
@@ -12,23 +11,16 @@ void Protocol::setMessages(vector<Message> messages){
 }
 
 bool Protocol::sendMessages(int socket, int window) {
-    //FIXME: seqType char is wrong, could be because of how sequence is being set
     for(int i=0; i < messages.size(); ++i) {
-        vector<BYTE> msg;
-        msg.push_back(messages[i].header.c_ctrl.begin);
-        cout << "vector begin: "<< bitset<8>(msg[0]) << endl;
-        cout << "sizeSeq: " << bitset<8>(messages[i].header.c_ctrl.sizeSeq) << endl;
-        cout << "seqType: " << bitset<8>(messages[i].header.c_ctrl.seqType) << endl;
-        msg.push_back(messages[i].header.c_ctrl.sizeSeq);
-        cout << "vector sizeSeq: "<< bitset<8>(msg[1]) << endl;
-        msg.push_back(messages[i].header.c_ctrl.seqType);
-        msg.insert(msg.end(), messages[i].data.begin(), messages[i].data.end());
-        msg.push_back(messages[i].header.c_ctrl.parity);
-        char* data = reinterpret_cast<char*> (msg.data());
-        cout << "msg size: " << bitset<6>(messages[i].header.i_ctrl.size) << endl;
-        cout << "pointer begin: "<< bitset<8>(data[0]) << "|\t";
-        cout << "msg isize: " << messages[i].getBitFieldsAsInt()[1] << endl;
-        send(socket, data, messages[i].getBitFieldsAsInt()[1]+4, 0);
+        cout << "message: " << messages[i] << endl;
+        vector<BYTE> message = messages[i].getMessage();
+        char* msg = reinterpret_cast<char*> (message.data());
+        cout << "char* msg: ";
+        for(int j=0;j<message.size();++j){
+            cout << bitset<8>(msg[j]);
+        }
+        cout <<endl;
+        send(socket, msg, messages[i].getMessageSize(), 0);
     }
     return true;
 }
@@ -52,9 +44,9 @@ void Protocol::setData(vector<BYTE> data, int type){
     int i;
     for (i=0; i <= ((int)data.size())-MAXSIZE; i+=MAXSIZE){
         Message msg = Message();
-        msg.header.i_ctrl.size = MAXSIZE;
-        msg.header.i_ctrl.sequence = messages.size()%(MAXSIZE+1);
-        msg.header.i_ctrl.type = type;
+        msg.size = bitset<SIZE_S>(MAXSIZE);
+        msg.sequence = bitset<SEQUENCE_S>(messages.size()%(MAXSIZE+1));
+        msg.type = bitset<TYPE_S>(type);
         first = data.begin()+i;
         last = data.begin()+i+MAXSIZE+1;
         vector<BYTE> subvector(first, last);
@@ -63,22 +55,20 @@ void Protocol::setData(vector<BYTE> data, int type){
         messages.push_back(msg);
     }
     if(i < data.size()){
-        cout << "entrou if"<< endl;
         Message msg = Message();
-        msg.header.i_ctrl.sequence = messages.size()%(MAXSIZE+1);
-        msg.header.i_ctrl.type = type;
+        msg.sequence = bitset<SEQUENCE_S>(messages.size()%(MAXSIZE+1));
+        msg.type = bitset<TYPE_S>(type);
         int size = ((int)data.size())-i;
-        cout << "real size " << size<<endl;
         first = data.begin()+i;
         last = data.begin()+size+1;
         vector<BYTE> subvector(first, last);
         msg.data = subvector;
         if(size < MINSIZE){
+            BYTE zero = 0x00;
+            msg.data.insert(msg.data.begin(), MINSIZE-size, zero);
             size = MINSIZE;
-            msg.data.insert(msg.data.begin(), MINSIZE-size, 0x0);
         }
-        cout << "modified size " << size<<endl;
-        msg.header.i_ctrl.size = size;
+        msg.size = bitset<SIZE_S>(size);
         msg.calcParity();
         messages.push_back(msg);
     }
@@ -89,41 +79,55 @@ int Protocol::recvMessage(int sockt){
     int r = recv(sockt, dataRec, MAXSIZE+4, 0);
     cout << "recv response: " << r << endl;
     cout << bitset<8>(dataRec[0]) << bitset<8>(dataRec[1]) << bitset<8>(dataRec[2]) << "|\t";
-    Message msg;
-    msg.header.c_ctrl.begin = dataRec[0];
-    if(msg.header.i_ctrl.begin != BEGIN){
+    if(dataRec[0] != BEGIN){
         return NOISE;
     }
-    msg.header.c_ctrl.sizeSeq = dataRec[1];
-    msg.header.c_ctrl.seqType = dataRec[2];
-    if(msg.header.i_ctrl.sequence != ((messages.back().header.i_ctrl.sequence+1)%(MAXSIZE+1))){
+    Message msg = Message();
+    int size = (int)(dataRec[1]>>2);
+    msg.setBitFields(dataRec[0], dataRec[1], dataRec[2], dataRec[size+3]);
+    if(msg.sequence.to_ulong() != ((messages.back().sequence.to_ulong()+1)%(MAXSIZE+1))){
         return SEQ_MISS;
     }
-    msg.header.c_ctrl.parity = dataRec[3+msg.header.i_ctrl.size];
     if(!msg.checkParity()){
         return INCONSISTENT;
     }
-    if(msg.header.i_ctrl.type == ENDTX){
+    if(msg.type.to_ulong() == ENDTX){
         return ENDTX;
     }
 
-    BYTE msgData[msg.header.i_ctrl.size];
-    memcpy(msgData,dataRec+3,msg.header.i_ctrl.size);
-    msg.data.insert(msg.data.end(), msgData, msgData+msg.header.i_ctrl.size);
+    BYTE msgData[size];
+    memcpy(msgData,dataRec+3,size);
+    msg.data.insert(msg.data.end(), msgData, msgData+size);
     messages.push_back(msg);
-    return msg.header.i_ctrl.type;
+    return (int)msg.type.to_ulong();
 }
 
-// void Protocol::recvWholeData(int sockt, int window){
-//     int status;
-//     while((status=this->recvMessage(sockt)) != ENDTX){
-//         if(status > 0){
-//             if(messages.back().header.i_ctrl.sequence % window == 0){
-//                 //TODO: send ACK
-//             }
-//         }
-//     }
-// }
+void Protocol::transmit(int sockt, int type, int window){
+    int status;
+    for(int i=0; i < messages.size(); ++i){
+        //TODO: send part of output back
+        status = recvMessage(sockt);
+        if(!status){
+            //TODO: send part of output back again
+        }else if(status == 1){
+            //TODO: send another part of output back
+        }else{
+            //TODO: send NACK back
+        }
+    }
+}
+
+void Protocol::receive(int sockt, int type, int window){
+    int status;
+    do{
+        status = recvMessage(sockt);
+        if(status == type){
+            //TODO: send ACK back
+        }else{
+            //TODO: send NACK back
+        }
+    }while(status != ENDTX);
+}
 
 void Protocol::addMessage(Message msg) {
     messages.push_back(msg);
diff --git a/Protocol.h b/Protocol.h
index 3c9e073e446d2f371ce59f7913343c32792d5bdb..8475424efe026b74983904a8f423a32d5d49fbd8 100644
--- a/Protocol.h
+++ b/Protocol.h
@@ -17,6 +17,8 @@ public:
     string getDataAsString();
     int recvMessage(int sockt);
     void addMessage(Message msg);
+    void transmit(int sockt, int type, int window);
+    void receive(int sockt, int type, int window);
 
     Protocol();
 };
diff --git a/client.cpp b/client.cpp
index 7b3bbf37eb6044ae55fa689c9bba85df80cfb6da..a41ebf9f8482c99624c88d06b886f1a52f836b28 100644
--- a/client.cpp
+++ b/client.cpp
@@ -32,6 +32,7 @@ int main(){
                 //TODO
             }else if(command == "lsr"){
                 Message msg = Message();
+                line.replace(line.find("lsr"), string("lsr").length(), "ls");
                 protocol.setData(vector<BYTE>(line.begin(), line.end()), LS);
                 protocol.sendMessages(sockt, WAIT_STOP);
                 // TODO: imprimir resposta
diff --git a/definitions.h b/definitions.h
index cab7dad5aa1eb89057910753c99809acacc7ab03..a5305db8e80d31492227baabe1c443ead7c1a19e 100644
--- a/definitions.h
+++ b/definitions.h
@@ -4,6 +4,7 @@
 #include <iostream>
 #include <string.h>
 #include <vector>
+#include <bitset>
 #include <cstdlib>
 
 using namespace std;
@@ -44,24 +45,15 @@ using namespace std;
 #define SEQ_MISS -2
 #define INCONSISTENT -3
 
+//Bit fields size
+#define BEGIN_S 8
+#define SIZE_S 6
+#define SEQUENCE_S 6
+#define TYPE_S 4
+#define PARITY_S 8
+
 //Data types
 #define BYTE unsigned char
 
-typedef struct{
-	int begin   : 8,
-        size    : 6,
-        sequence: 6,
-        type    : 4,
-        parity  : 8;
-}i_Control;
-
-typedef struct{
-	char begin,sizeSeq,seqType,parity;
-}c_Control;
-
-typedef union {
-	c_Control c_ctrl;
-    i_Control i_ctrl;
-}Header;
 
 #endif