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