diff --git a/.clang-format b/.clang-format index 48b2c6783230f1acd882f2f22477a5cc0a032df5..f4ed5e02136e649c81425083182ea639ffcb594e 100644 --- a/.clang-format +++ b/.clang-format @@ -14,11 +14,11 @@ AlignTrailingComments: true AllowAllArgumentsOnNextLine: true AllowAllParametersOfDeclarationOnNextLine: true AllowShortEnumsOnASingleLine: true -AllowShortBlocksOnASingleLine: Never +AllowShortBlocksOnASingleLine: true AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: All AllowShortLambdasOnASingleLine: All -AllowShortIfStatementsOnASingleLine: Never +AllowShortIfStatementsOnASingleLine: true AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None @@ -29,20 +29,20 @@ AttributeMacros: BinPackArguments: true BinPackParameters: true BraceWrapping: - AfterCaseLabel: false - AfterClass: false - AfterControlStatement: Never - AfterEnum: false - AfterFunction: false + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true AfterNamespace: false AfterObjCDeclaration: false - AfterStruct: false - AfterUnion: false + AfterStruct: true + AfterUnion: true AfterExternBlock: false - BeforeCatch: false - BeforeElse: false + BeforeCatch: true + BeforeElse: true BeforeLambdaBody: false - BeforeWhile: false + BeforeWhile: true IndentBraces: false SplitEmptyFunction: true SplitEmptyRecord: true diff --git a/test_files/example.txt b/example.txt similarity index 100% rename from test_files/example.txt rename to example.txt diff --git a/test_files/fileLocal2 b/fileLocal2 similarity index 100% rename from test_files/fileLocal2 rename to fileLocal2 diff --git a/test_files/foto.jpg b/foto.jpg similarity index 100% rename from test_files/foto.jpg rename to foto.jpg diff --git a/headers/client.h b/headers/client.h index 67cb295a92a604a9eecffb0aa713c3d88897efe0..3523ef1fcd95137291140acf9d805ab98e80eb48 100644 --- a/headers/client.h +++ b/headers/client.h @@ -2,6 +2,7 @@ #ifndef _CLIENT_ #define _CLIENT_ +#include <arpa/inet.h> #include <bits/stdc++.h> #include <fstream> #include <iostream> @@ -15,9 +16,8 @@ #include <string.h> #include <sys/ioctl.h> #include <sys/socket.h> -#include <sys/types.h> #include <sys/stat.h> -#include <arpa/inet.h> +#include <sys/types.h> // include local #include "conexao.h" @@ -51,6 +51,7 @@ private: bool verify_ack(frame *received, frame *sent); frame *receive_ack(frame *f); vector<frame *> create_frames(vector<char> data, int type); + vector<frame *> create_frames_midia(vector<char> data); int send_frame_socket(frame *f); int start_transmission(); int end_transmission(); @@ -62,7 +63,7 @@ public: string userInput; // ------- Construtores ------ // - client(conexao *socketAddr) { socket = socketAddr; }; + client(conexao *socketAddr) { socket = socketAddr; } // ---------- Funcoes -------- // void run(); @@ -71,41 +72,33 @@ public: // ------------------------------ PRIVATE --------------------------------- // // Verifica se recebeu um ack valido -frame *client::receive_ack(frame *f) -{ +frame *client::receive_ack(frame *f) { frame *ack_res = NULL; // se recebemos algo, e NÃO ẽ o ACK que estamos // esperando, continuamos tentando receber do { ack_res = socket->receive_frame(); - if (ack_res && ack_res->get_tipo() == ERRO) - { + if (ack_res && ack_res->get_tipo() == ERRO) { cout << "Espaco insulficiente no destino\n"; return NULL; } - - } while ( - ack_res && - !(verify_ack(ack_res, f) && - ack_res->get_dado()[0] == f->get_seq()) - ); + } while (ack_res && + !(verify_ack(ack_res, f) && ack_res->get_dado()[0] == f->get_seq())); return ack_res; } // Solicita ao socket que envie um frame -int client::send_frame_socket(frame *f) -{ +int client::send_frame_socket(frame *f) { // Fica tentando enviar o frame até receber o ack - frame* ack_res = NULL; + frame *ack_res = NULL; int retries = 0; do { // envia um frame da fila socket->send_frame(f); ack_res = receive_ack(f); retries++; - } while (ack_res == NULL && retries < NUM_RETRIES); if (ack_res == NULL && retries == NUM_RETRIES) { @@ -119,13 +112,11 @@ int client::send_frame_socket(frame *f) } // Inicia a transmissao com o servidor -int client::start_transmission() -{ +int client::start_transmission() { cout << "\tIniciando transmissao\n"; - frame *ini = new frame(INIT, 0, vector<char>(1,0)); + frame *ini = new frame(INIT, 0, vector<char>(1, 0)); int enviado = send_frame_socket(ini); - if ( !enviado ) - { + if (!enviado) { cout << "\tFalha ao iniciar a transmissao\n"; return 0; } @@ -135,13 +126,11 @@ int client::start_transmission() } // Encerra a transmissao com o servidor -int client::end_transmission() -{ +int client::end_transmission() { cout << "\tEncerrando a transmissao\n"; - frame *end= new frame(FIMT, 0, vector<char>(1,0)); + frame *end = new frame(FIMT, 0, vector<char>(1, 0)); int enviado = send_frame_socket(end); - if ( !enviado ) - { + if (!enviado) { cout << "\tFalha ao encerrar a transmissao\n"; return 0; } @@ -157,7 +146,9 @@ int client::end_transmission() * @return int */ int client::send_frames(vector<frame *> frames) { - if ( !start_transmission() ) { return 0; } + if (frames.empty()) { return 0; } + + if (!start_transmission()) { return 0; } // Envia um frame por vez for (size_t i = 0; i < frames.size(); i++) { @@ -166,8 +157,7 @@ int client::send_frames(vector<frame *> frames) { frames[i]->imprime(DEC); int enviado = send_frame_socket(frames[i]); - if ( !enviado ) - { + if (!enviado) { cout << "\tFalha ao enviar o frame\n"; return 0; } @@ -175,7 +165,7 @@ int client::send_frames(vector<frame *> frames) { cout << "\tFrame enviado com sucesso\n"; } - if ( !end_transmission() ) { return 0; } + if (!end_transmission()) { return 0; } cout << "\tTerminou de enviar todos os frames\n"; return 1; } @@ -190,7 +180,7 @@ int client::send_frames(vector<frame *> frames) { * @return false */ bool client::verify_ack(frame *received, frame *sent) { - return ( received->get_tipo() == ACK && received->chk_crc8()); + return (received->get_tipo() == ACK && received->chk_crc8()); } /** @@ -203,15 +193,23 @@ int client::send_message(vector<char> data, int type) { int messageSize = data.size(); vector<frame *> frames; - frames = create_frames(data, type); + + switch (type) { + case TEXTO: + frames = create_frames(data, type); + break; + + case MIDIA: + frames = create_frames_midia(data); + break; + } return send_frames(frames); } -string client::calc_file_size(string fileName) -{ +string client::calc_file_size(string fileName) { struct stat buffer; - if ( stat(fileName.c_str(), &buffer) == -1 ) { + if (stat(fileName.c_str(), &buffer) == -1) { cout << "Arquivo inexistente. Operacao abortada\n"; return {}; } @@ -220,22 +218,15 @@ string client::calc_file_size(string fileName) return to_string(fileSize); } -vector<char> client::read_file(string fileName) -{ - fstream file; - file.open(fileName, ios::in); - - string teste; +vector<char> client::read_file(string fileName) { + ifstream file; + file.open(fileName, ios::binary); + vector<char> fileData; - char c; - while ( (file.get(c), file.eof() == false) ) - { - fileData.push_back(c); - teste.push_back(c); - } + for (char c; (file.read(&c, 1), file.eof()) == false; fileData.push_back(c)) + ; file.close(); - cout << "vetor criado: " << teste << "\n"; return fileData; } @@ -244,41 +235,24 @@ vector<char> client::read_file(string fileName) * */ void client::send_file() { + vector<char> fileNameVector; string fileName; + do { - cout << "Digite o nome do arquivo(maximo de " << TAM_DADOS << " char):\n"; + cout << "Digite o nome do arquivo(maximo de " << TAM_DADOS + << " char):\n"; getline(cin, fileName); - } while ( fileName.size() > TAM_DADOS ); + } while (fileName.size() > TAM_DADOS); - // Envia o primeiro frame com o tamanho do arquivo - string fileSize = calc_file_size(fileName); - if ( fileSize.empty() ) { return; } + fileNameVector.insert(fileNameVector.begin(), fileName.begin(), + fileName.end()); - cout << "Tamanho do arquivo: " << fileSize << "\n"; - cout << "Enviando tamanho do arquivo\n"; - if (!send_message(vector<char>(fileSize.begin(), fileSize.end()), MIDIA)) - { - cout << "Limite de timout, arquivo nao foi enviado\n"; + if (!send_message(fileNameVector, MIDIA)) { + cout << "Falha ao enviar o arquivo\n"; return; } - // Envia o segundo frame com o nome do arquivo -// cout << "Enviando nome do arquivo\n"; -// if (!send_message(vector<char>(fileName.begin(), fileName.end()), MIDIA)) -// { -// cout << "Limite de timout, arquivo nao foi enviado\n"; -// return; -// } -// -// cout << "Enviando arquivo\n"; -// vector<char> file = read_file(fileName); -// if (file.empty() || !send_message(file, DADOS)) -// { -// cout << "Limite de timout, arquivo nao foi enviado\n"; -// return; -// } -// -// cout << "Arquivo enviado com sucesso\n"; + cout << "Arquivo enviado com sucesso\n"; } /** @@ -290,7 +264,7 @@ void client::send_text(string message) { cout << "Enviando mensagem\n"; - vector<char> data (message.begin(), message.end()); + vector<char> data(message.begin(), message.end()); if (!send_message(data, TEXTO)) cout << "Limite de timout, mensagem nao foi enviada\n"; @@ -298,6 +272,43 @@ void client::send_text(string message) { cout << "Mensagem enviada com sucesso\n"; } +vector<frame *> client::create_frames_midia(vector<char> vectorName) { + vector<frame *> framesToSend; + vector<frame *> framesAux; + + // Cria um vetor com o tamanho do arquivo + vector<char> vectorTam; + string fileName = string(vectorName.begin(), vectorName.end()); + string fileSize = calc_file_size(fileName); + if (fileSize.empty()) { return vector<frame *>(); } + vectorTam.insert(vectorTam.begin(), fileSize.begin(), fileSize.end()); + + // Adiciona o tamanho no primeiro frame a ser enviado + framesAux = create_frames(vectorTam, MIDIA); + framesToSend.insert(framesToSend.end(), framesAux.begin(), framesAux.end()); + + // Adiciona o nome no segundo frame a ser enviado + framesAux = create_frames(vectorName, MIDIA); + framesToSend.insert(framesToSend.end(), framesAux.begin(), framesAux.end()); + + // Cria um vetor com os dados do arquivo + vector<char> vectorData = read_file(fileName); + if (vectorData.empty()) { + cout << "Falha ao abrir o arquivo para leitura\n"; + return vector<frame *>(); + } + + // Adiciona os dados do arquivo + framesAux = create_frames(vectorData, DADOS); + framesToSend.insert(framesToSend.end(), framesAux.begin(), framesAux.end()); + + // Arruma a sequencia dos frames + for (int i = 0; i < framesToSend.size(); i++) + framesToSend[i]->set_seq(i%16); + + return framesToSend; +} + /** * @brief Creates a vector with all the frames to be sent * @@ -308,13 +319,14 @@ vector<frame *> client::create_frames(vector<char> data, int type) { vector<frame *> frames; int i = 0; - int frameCnt = (data.size()/TAM_DADOS) + bool(data.size()%TAM_DADOS); + int frameCnt = (data.size() / TAM_DADOS) + bool(data.size() % TAM_DADOS); while (i < frameCnt) { frame *f = new frame(); f->set_tipo(type); f->set_seq(i); - f->set_dado(vector<char>(data.data()+i*TAM_DADOS, data.data()+ - min(data.size(), (size_t)(i+1)*TAM_DADOS))); + f->set_dado(vector<char>( + data.data() + i * TAM_DADOS, + data.data() + min(data.size(), (size_t)(i + 1) * TAM_DADOS))); frames.push_back(f); i++; } @@ -325,23 +337,18 @@ vector<frame *> client::create_frames(vector<char> data, int type) { bool client::string_has(string str, vector<string> strList) { for (int i = 0; i < strList.size(); i++) { - if (str.find(strList[i]) != string::npos) { - return true; - } + if (str.find(strList[i]) != string::npos) { return true; } } return false; } char client::string_cmd(string str) { - if (string_has(str, CMD_HELP)) - return 'h'; + if (string_has(str, CMD_HELP)) return 'h'; - if (string_has(str, CMD_EXIT)) - return 'e'; + if (string_has(str, CMD_EXIT)) return 'e'; - if (string_has(str, CMD_SEND)) - return 's'; + if (string_has(str, CMD_SEND)) return 's'; return 'm'; } @@ -350,8 +357,8 @@ void client::print_help() { cout << "Comandos disponiveis:\n"; cout << "help ou -h ou h ou HELP ou Help ou H ou ajuda ou Ajuda ou AJUDA\n"; cout << "exit ou -e ou e ou EXIT ou Exit ou E ou sair ou Sair ou SAIR\n"; - cout - << "send ou -s ou s ou SEND ou Send ou S ou enviar ou Enviar ou ENVIAR\n"; + cout << "send ou -s ou s ou SEND ou Send ou S ou enviar ou Enviar ou " + "ENVIAR\n"; cout << "para enviar uma mensagem, digite a mensagem e pressione enter\n"; } diff --git a/headers/conexao.h b/headers/conexao.h index f736ce341e23eb6cd32d51f1397d6882a89c79ba..072f624f117fe78e95151a584bfeca290043a263 100644 --- a/headers/conexao.h +++ b/headers/conexao.h @@ -122,9 +122,7 @@ int conexao::send_frame(frame *f) { cout << hex << (int(bufferSend[i]) & 0xff) << " "; } cout << "\n"; - if (byteSend < 0) { - cout << "Erro no sendto" << byteSend << "\n"; - } + if (byteSend < 0) { cout << "Erro no sendto" << byteSend << "\n"; } return byteSend; } @@ -144,8 +142,7 @@ int conexao::add_escapes(char *f, char *out) { for (size_t i = 0; i < sizeof(frame); i++) { out[j++] = f[i]; - if (f[i] == 0x88 || f[i] == 0x81) - out[j++] = 0xFF; + if (f[i] == 0x88 || f[i] == 0x81) out[j++] = 0xFF; } return j; @@ -156,8 +153,7 @@ int conexao::remove_escapes(char *f, char *out) { for (size_t i = 0; j < sizeof(frame); i++) { out[j++] = f[i]; - if (f[i] == 0x88 || f[i] == 0x81) - i++; + if (f[i] == 0x88 || f[i] == 0x81) i++; } return j; diff --git a/headers/crc8.h b/headers/crc8.h index a479e6765f620fba670d1e00692f98a48430db02..2a9e5a6c132102bacefced2f1a7d950b8713765a 100644 --- a/headers/crc8.h +++ b/headers/crc8.h @@ -1,8 +1,8 @@ #ifndef _CRC8_ #define _CRC8_ -#include <string> #include "macros.h" +#include <string> using namespace std; diff --git a/headers/macros.h b/headers/macros.h index ea108d03dcf188d1163d84cef6345367851930bc..a936d2fd44134ddbf5398f985340968d5de3535f 100644 --- a/headers/macros.h +++ b/headers/macros.h @@ -8,22 +8,23 @@ #define MASKR(des) (1 << des) // Macro que fica em 1 ou 0 de acordo com o valor do bit avaliado -#define BIT(value, des) ( (value & MASKR(des)) ? 1 : 0 ) +#define BIT(value, des) ((value & MASKR(des)) ? 1 : 0) // Macro que zera uma sequencia de bits -#define ZERA(value) ( value &= ~value ) +#define ZERA(value) (value &= ~value) // Macro que coloca todos os bits de uma sequencia em 1 -#define UM(seq) ( seq |= ~seq ) +#define UM(seq) (seq |= ~seq) // Macro que zera determinado bit de uma sequencia -#define ZERABIT(seq, bit) ( seq &= ~MASKR(bit) ) +#define ZERABIT(seq, bit) (seq &= ~MASKR(bit)) // Macro para a "p" potencia de 2 -#define BITPOW(p) ( MASKR(6) ) +#define BITPOW(p) (MASKR(6)) // Macro que imprime uma sequencia de bits -#define IMPRIME(seq, tam) for ( int i = tam-1; i >= 0; i-- ) \ - cout << BIT(seq, i); \ - cout << "\n"; +#define IMPRIME(seq, tam) \ + for (int i = tam - 1; i >= 0; i--) \ + cout << BIT(seq, i); \ + cout << "\n"; #endif diff --git a/headers/server.h b/headers/server.h index 9a8c362945906eea47bd3d19b60432d1dc0b4db5..d45e9e691d81c0b0139d4519c52740907393f207 100644 --- a/headers/server.h +++ b/headers/server.h @@ -2,11 +2,13 @@ #ifndef _SERVER_ #define _SERVER_ +#include <arpa/inet.h> #include <bits/stdc++.h> #include <fstream> #include <iostream> #include <linux/if.h> #include <linux/if_packet.h> +#include <mutex> #include <net/ethernet.h> #include <netinet/in.h> #include <stdio.h> @@ -14,11 +16,9 @@ #include <string.h> #include <sys/ioctl.h> #include <sys/socket.h> -#include <sys/types.h> -#include <mutex> +#include <sys/stat.h> // For stat() and mkdir() functions #include <sys/statvfs.h> - -#include <arpa/inet.h> +#include <sys/types.h> // include local #include "conexao.h" @@ -47,8 +47,13 @@ private: frame *receive_frame_socket(); int receive_valid_frame(frame **f); unsigned long chk_available_size(); - long long receive_file_size(frame *f); + int receive_file_size(frame *f); void start_receveing_message(); + bool create_received_dir(); + string receive_file_name(); + int receive_file_data(string fileName); + bool verify_crc8(frame *f); + bool verify_seq(int seq, int lastSeq); public: // ------- Construtores ------ // @@ -106,33 +111,29 @@ int server::send_nack(frame *fReceive) { } // Recebe uma mensagem em forma de texto -void server::receive_text(frame *f) -{ +void server::receive_text(frame *f) { string textoReceive; textoReceive.append(f->get_dado()); int lastSeq = f->get_seq(); - + do { - if ( !receive_valid_frame(&f) ) { continue; } - if ( f->get_tipo() != TEXTO ) { continue; } - if ( f->get_seq() == lastSeq) { continue; } - + if (!receive_valid_frame(&f)) { return; } + if (f->get_tipo() != TEXTO) { continue; } + if (f->get_seq() == lastSeq) { continue; } + lastSeq = f->get_seq(); textoReceive.append(f->get_dado()); - - } while ( f->get_tipo() != FIMT ); + } while (f->get_tipo() != FIMT); cout << "Mensagem recebida: " << textoReceive << "\n"; } // Verifica o espaco disponivel em disco -unsigned long server::chk_available_size() -{ +unsigned long server::chk_available_size() { struct statvfs st; - if ( statvfs(FILE_DESTINATION, &st) == -1 ) - { + if (statvfs(FILE_DESTINATION, &st) == -1) { cout << "Erro no statvfs, abortado\n"; - //send_error(); + // send_error(); return -1; } @@ -140,45 +141,212 @@ unsigned long server::chk_available_size() } // Recebe o frame com o tamanho do arquivo -long long server::receive_file_size(frame *f) -{ +int server::receive_file_size(frame *f) { + + /* + > verifica a sequencia do frame e o tipo + > se o frame nao for a sequencia esperada, envia um ack(0) e espera receber + a sequencia esperada > se o frame for o esperado, verifica o crc8 > se o + crc estiver certo, envia um ack e continua > se estiver errado, envia um + nack e espera receber o proximo frame + */ + cout << "Recebendo tamanho do frame\n"; + do { + if ( f->get_tipo() != MIDIA ) { continue; } + if ( f->get_seq() == 0 && verify_crc8(f) ) { break; } + + if ( f->get_seq() != 0 ) + cout << "Sequencia errada\n"; + else + cout << "Crc errado\n"; + + cout << "Aguardando frame\n"; + + f = receive_frame_socket(); + if (!f) { return 0; } + + cout << "Frame recebido\n"; + + } while (true); + unsigned long availSize = chk_available_size(); - if ( availSize == -1 ) { return -1; } + if (availSize == -1) { return -1; } - unsigned long fileSize = stoi(f->get_dado()); + cout << "Frame file size:" << f->get_dado() << "\n"; + int fileSize = stoi(f->get_dado()); - if ( fileSize > availSize*0.9 ) - { + if (fileSize > availSize * 0.9) { cout << "Tamanho do arquivo muito grande, abortado\n"; - //send_error(); - return -1; + // send_error(); + return 0; } cout << "Espaco suficiente em disco\n"; return 1; } -void server::receive_midia(frame *f) -{ - //if ( !create_received_dir) { return; } - if ( !receive_file_size(f) ) { return; } - //if ( !receive_file_name() { return; } - //receive_file_data(); +bool server::create_received_dir() { + + // check if the directory exists + struct stat info; + if (stat(FILE_DESTINATION, &info) == 0 && (info.st_mode & S_IFDIR)) { + cout << "Diretorio ja existe\n"; + return true; + } + + // create the directory + if (mkdir(FILE_DESTINATION, 0700) == -1) { + cout << "Erro ao criar o diretorio\n"; + return false; + } + + cout << "Diretorio criado com sucesso\n"; + return true; +} + +string server::receive_file_name() { + frame *fReceive; + + // Aguarda receber um frame do tipo midia com o nome do arquivo + // E com a sequencia de numero 2 + /* + > recebe o frame e verifica se o tipo e a sequencia estao corretos + > se estiverem, verifica o crc8 + > se estiver correto, envia um ack e continua + > se estiver errado, envia um nack e espera receber o proximo frame + */ + cout << "Recebendo nome do arquivo\n"; + + do { + cout << "Aguardando frame\n"; + fReceive = receive_frame_socket(); + if (!fReceive) { return string{}; } + + cout << "Frame recebido\n"; + + if (fReceive->get_tipo() != MIDIA) { continue; } + if ( fReceive->get_seq() != 1 ) + { + cout << "Sequencia errada\n"; + fReceive->set_seq(0); + send_ack(fReceive); + continue; + } + + if (verify_crc8(fReceive)) { break; } + + cout << "Crc invalido, aguardando retransmissao\n"; + + } while (true); + + cout << "Nome do arquivo recebido com sucesso\n"; + cout << "Nome do arquivo: " << fReceive->get_dado() << "\n"; + + return string(fReceive->get_dado()); +} + +bool server::verify_seq(int seq, int lastSeq) { + cout << "seq: " << seq << " lastSeq: " << dec << lastSeq << "\n"; + if ( seq == 0 ) + { + if ( lastSeq != 15 ) { return false; } + return true; + } + + if (seq != lastSeq + 1) { return false; } + return true; +} + +int server::receive_file_data(string fileName) { + string fileDestination; + fileDestination.append(FILE_DESTINATION); + fileDestination.push_back('/'); + fileDestination.append(fileName); + + // Abre o arquivo para escrita + ofstream file; + file.open(fileDestination, ios::binary); + if (!file.is_open()) { + cout << "Falha ao criar o arquivo. Abortado\n"; + return 0; + } + + cout << "Arquivo criado com sucesso\n"; + + int lastSeq = 1; + frame *f; + + cout << "\tRecebendo dados arquivo\n"; + do { + cout << "Aguardando frame\n"; + + // Fica tentando receber um frame + f = receive_frame_socket(); + if (f == NULL) { return 0; } + + cout << "Frame recebido\n"; + f->imprime(HEX); + + if (f->get_tipo() == FIMT) { break; } + + if (f->get_tipo() != DADOS) { continue; } + + if (f->get_seq() == lastSeq) { continue; } + + // Recebeu um frame com uma sequencia errada + if (!verify_seq(f->get_seq(), lastSeq)) { + cout << "Frame com a sequencia errada; Pedindo a certa\n"; + f->set_seq(lastSeq); + send_ack(f); + continue; + } + + if (!verify_crc8(f)) { + cout << "Crc invalido\n"; + continue; + } + + cout << "Seq " << int(f->get_seq()) << "recebida com sucesso\n"; + lastSeq = f->get_seq(); + file.write(f->get_dado(), f->get_tam()); + + } while (true); + + cout << "Dados do arquivo recebido com sucesso\n"; + send_ack(f); + + file.close(); + return 1; +} + +void server::receive_midia(frame *f) { + cout << "Recebendo frame midia\n"; + if (!create_received_dir()) { return; } + if (!receive_file_size(f)) { return; } + + string fileName = receive_file_name(); + + if (fileName.size() == 0) { return; } + + if ( !receive_file_data(fileName) ) { + cout << "Falha ao receber o arquivo\n"; + return; + } + + cout << "Arquivo recebido com sucesso\n"; } // Recebe um frame do cliente -frame *server::receive_frame_socket() -{ +frame *server::receive_frame_socket() { frame *fReceive; int retries = 0; - do - { + do { retries++; - if ( ! (fReceive = socket->receive_frame()) ) { continue; } - } while ( fReceive == NULL && retries < NUM_RETRIES ); + if (!(fReceive = socket->receive_frame())) { continue; } + } while (fReceive == NULL && retries < NUM_RETRIES); - if ( fReceive == NULL && retries == NUM_RETRIES ) { + if (fReceive == NULL && retries == NUM_RETRIES) { cout << "Desisti de receber o frame\n"; return NULL; } @@ -186,52 +354,55 @@ frame *server::receive_frame_socket() return fReceive; } -int server::receive_valid_frame(frame **f) -{ - int crc8; +bool server::verify_crc8(frame *f) { + int crc8 = f->chk_crc8(); + if (!crc8) { + send_nack(f); + } + else + send_ack(f); + return crc8; +} + +int server::receive_valid_frame(frame **f) { do { // Se nao conseguir receber o frame, mata a comunicacao *f = receive_frame_socket(); - if ( *f == NULL ) { return 0; } + if (*f == NULL) { return 0; } // Avisa o cliente se nao conseguiu receber o frame - crc8 = (*f)->chk_crc8(); - if ( crc8 ) { send_ack(*f); break; } - send_nack(*f); - - } while ( !crc8 ); - + } while (!verify_crc8(*f)); return 1; } -void server::start_receveing_message() -{ - int endTransmission = 0; +void server::start_receveing_message() { + int continueTransmission = 1; + cout << "Recebendo frames\n"; frame *f; - do { - if ( !receive_valid_frame(&f) ) { return; } - if ( !f ) { return; } + do { + if (!receive_valid_frame(&f)) { return; } + if (!f) { return; } int frameType = f->get_tipo(); - switch (frameType) - { - case TEXTO: - receive_text(f); - endTransmission = 1; - break; - - case MIDIA: - receive_midia(f); - endTransmission = 1; - break; - - default: - break; } - } while ( !endTransmission ); -} + switch (frameType) { + case TEXTO: + receive_text(f); + continueTransmission = 0; + break; + case MIDIA: + receive_midia(f); + continueTransmission = 0; + break; + + default: + break; + } + + } while (continueTransmission); +} // ------------------------------- PUBLIC --------------------------------- // @@ -241,16 +412,20 @@ void server::run() { /*-- listening local ip and waiting for messages --*/ /*-- ignore if the package is not valid --*/ frame *fReceive; - if ( ! (fReceive = socket->receive_frame()) ) { continue; } + if (!(fReceive = socket->receive_frame())) { continue; } cout << "Frame recebido:" << endl; fReceive->imprime(HEX); // Verifica se o frame eh de inicio de transmissao e se nao veio com erro int frameType = fReceive->get_tipo(); - if ( frameType != INIT ) { continue; } - - if ( !fReceive->chk_crc8() ) { send_nack(fReceive); continue; } + if (frameType != INIT) { cout << "Frame ignorado, n eh INIT\n"; continue; } + + cout << "Frame de INIT\n"; + if (!fReceive->chk_crc8()) { + send_nack(fReceive); + continue; + } send_ack(fReceive); start_receveing_message(); diff --git a/received/foto.jpg b/received/foto.jpg new file mode 100644 index 0000000000000000000000000000000000000000..42cedf4a23e28ccea764d16047faa18f7149ddb8 Binary files /dev/null and b/received/foto.jpg differ diff --git a/received/saida.txt b/received/saida.txt new file mode 100644 index 0000000000000000000000000000000000000000..1a56033fe38d2af10a0efb1223f107d4b1601fa8 Binary files /dev/null and b/received/saida.txt differ diff --git a/received/texto.txt b/received/texto.txt new file mode 100644 index 0000000000000000000000000000000000000000..16914e72e0641b9e2ae68d9c8aef608f1fed464f --- /dev/null +++ b/received/texto.txt @@ -0,0 +1,35 @@ + //string fileSize = calc_file_size(fileName); + //if (fileSize.empty()) { return; } + //franesFile.insert(framesFile.end(), fileSize.begin(), fileSize.end()); + + //cout << "Tamanho do arquivo: " << fileSize << "\n"; + //cout << "Enviando tamanho do arquivo\n"; + //if (!send_message(vector<char>(fileSize.begin(), fileSize.end()), MIDIA)) { + // cout << "Limite de timout, arquivo nao foi enviado\n"; + // return; + //} + + // Envia o segundo frame com o nome do arquivo + //cout << "Enviando nome do arquivo\n"; + //string name = "NAME"; + //vector<char> fileNameVector(name.begin(), name.end()); + //fileNameVector.insert(fileNameVector.end(), fileName.begin(), fileName.end()); + + //if (!send_message(fileNameVector, MIDIA)) { + // cout << "Limite de timout, arquivo nao foi enviado\n"; + // return; + //} + + //cout << "Enviando arquivo\n"; + //vector<char> file = read_file(fileName); + //if ( file.empty()) + //{ + // cout << "Falha ao abrir o arquivo para leitura\n"; + // return; + //} + + //if (!send_message(file, DADOS)) { + // cout << "Limite de timout, arquivo nao foi enviado\n"; + // return; + //} + diff --git a/saida.txt b/saida.txt new file mode 100644 index 0000000000000000000000000000000000000000..1a56033fe38d2af10a0efb1223f107d4b1601fa8 Binary files /dev/null and b/saida.txt differ diff --git a/src/crc8.cpp b/src/crc8.cpp index dc69487e82ca6bb49c63b1e6191a604ece2a8d10..dbbc6c06718d68f1c6829ef2a0adad9c7ddc9892 100644 --- a/src/crc8.cpp +++ b/src/crc8.cpp @@ -1,5 +1,5 @@ -#include <iostream> #include <iomanip> +#include <iostream> #include <string> #include "../headers/crc8.h" @@ -12,35 +12,30 @@ using namespace std; uint8_t crc8_table[256]; // Gera a tabela com os valores do crc -void gen_crc8_table() -{ +void gen_crc8_table() { // Calcula o crc para todos os valores de 1 a 255 - for ( int divident = 0; divident < 256; divident++ ) - { - unsigned int currByte = divident; - + for (int divident = 0; divident < 256; divident++) { + unsigned int currByte = divident; + // Calcula bit a bit - for ( int bit = 0; bit < 8; bit++ ) - { + for (int bit = 0; bit < 8; bit++) { currByte <<= 1; - + // Se o bit mais significativo for 1, faz a divisao - if ( currByte & 0x100 ) { currByte ^= POLINOMIO; } + if (currByte & 0x100) { currByte ^= POLINOMIO; } } - crc8_table[divident] = uint8_t(currByte); + crc8_table[divident] = uint8_t(currByte); } } -uint8_t calc_crc8(uint8_t *msg, int tamBytes) -{ +uint8_t calc_crc8(uint8_t *msg, int tamBytes) { uint8_t crc = 0; - for ( int i = 0; i < tamBytes; i++ ) - { + for (int i = 0; i < tamBytes; i++) { uint8_t data = msg[i] ^ crc; crc = crc8_table[data]; } - + return crc; } diff --git a/src/exemplo.cpp b/src/exemplo.cpp index cbad342a25a068ad22e2a1c52c767a21a506eeb9..c2ae18adda8cb11ae85768c586f59b8779ec949d 100644 --- a/src/exemplo.cpp +++ b/src/exemplo.cpp @@ -2,12 +2,12 @@ #include <vector> // include local +#include "../headers/client.h" #include "../headers/conexao.h" #include "../headers/crc8.h" #include "../headers/frame.h" #include "../headers/macros.h" #include "../headers/server.h" -#include "../headers/client.h" using namespace std; @@ -15,57 +15,51 @@ using namespace std; typedef enum { CLIENT, SERVER } STATUS_E; -int get_status( char *argv ) -{ - if ( !strcmp( argv, "client") ) { return CLIENT; } - if ( !strcmp( argv, "server") ) { return SERVER; } - else { return -1; } +int get_status(char *argv) { + if (!strcmp(argv, "client")) { return CLIENT; } + if (!strcmp(argv, "server")) { + return SERVER; + } else { + return -1; + } } int main(int argc, char *argv[]) { gen_crc8_table(); - char* device = argv[2]; + char *device = argv[2]; cout << "Device: " << device << endl; conexao socket(device); int status = get_status(argv[1]); - switch ( status ) - { - case CLIENT: - { - client cliente(&socket); - cliente.run(); - } - break; - - case SERVER: - { - server servidor(&socket); - servidor.run(); - } - break; + switch (status) { + case CLIENT: { + client cliente(&socket); + cliente.run(); + } break; - default: - cout << "Comando invalido\n"; - break; - } + case SERVER: { + server servidor(&socket); + servidor.run(); + } break; + default: + cout << "Comando invalido\n"; + break; + } + // thread clientSend(&client::run, &cliente); -// thread clientSend(&client::run, &cliente); + // server servidor(&local, &target); + // thread serverReceive(&server::run, &servidor); -// server servidor(&local, &target); -// thread serverReceive(&server::run, &servidor); + // int receive = 0; + // while (true) { + // receive++; + // } -// int receive = 0; -// while (true) { -// receive++; -// } - -// serverReceive.join(); -// clientSend.join(); + // serverReceive.join(); + // clientSend.join(); return 0; } - diff --git a/texto.txt b/texto.txt new file mode 100644 index 0000000000000000000000000000000000000000..16914e72e0641b9e2ae68d9c8aef608f1fed464f --- /dev/null +++ b/texto.txt @@ -0,0 +1,35 @@ + //string fileSize = calc_file_size(fileName); + //if (fileSize.empty()) { return; } + //franesFile.insert(framesFile.end(), fileSize.begin(), fileSize.end()); + + //cout << "Tamanho do arquivo: " << fileSize << "\n"; + //cout << "Enviando tamanho do arquivo\n"; + //if (!send_message(vector<char>(fileSize.begin(), fileSize.end()), MIDIA)) { + // cout << "Limite de timout, arquivo nao foi enviado\n"; + // return; + //} + + // Envia o segundo frame com o nome do arquivo + //cout << "Enviando nome do arquivo\n"; + //string name = "NAME"; + //vector<char> fileNameVector(name.begin(), name.end()); + //fileNameVector.insert(fileNameVector.end(), fileName.begin(), fileName.end()); + + //if (!send_message(fileNameVector, MIDIA)) { + // cout << "Limite de timout, arquivo nao foi enviado\n"; + // return; + //} + + //cout << "Enviando arquivo\n"; + //vector<char> file = read_file(fileName); + //if ( file.empty()) + //{ + // cout << "Falha ao abrir o arquivo para leitura\n"; + // return; + //} + + //if (!send_message(file, DADOS)) { + // cout << "Limite de timout, arquivo nao foi enviado\n"; + // return; + //} + diff --git a/todo.txt b/todo.txt index 2242c510feec551c963ab6cdbc898e1356cba81b..bb047c2b84a429f02ea16c90521530d292d3d1b9 100644 --- a/todo.txt +++ b/todo.txt @@ -1,8 +1,8 @@ -> Ver se os frames que estao vindo sao arquivos e juntar eles no arquivo --> Arrumar nome arquivo > 63 +-> Arrumar receive valid frame, retries --> Testar tamanho antes de enviar o arquivo +-> Arrumar nome arquivo > 63 -> Arrumar a interface