Skip to content
Snippets Groups Projects
Select Git revision
  • master default protected
1 result

messages.cpp

Blame
  • messages.cpp 11.70 KiB
    // Implementado por: Eduardo Machado e Victor Perszel
    // 2015
    
    #include "messages.h"
    
    //######################### MÉTODOS DA CLASSE Message #########################
    
    int Message::sendCD(unsigned char* dirName){
      int error, success = 0, garbage, rv;
      char *receiptMessage = (char*)malloc(sizeof(char*)*64);
      struct pollfd ufds[1]; // usado para timeout em recv
      SubMessage changeDir, answer;
    
      ufds[0].fd = soquete;
      ufds[0].events = POLLIN;
    
      changeDir.setData(dirName,3,0);
    
      while(!success){
        error = send(soquete, changeDir.objToString(), changeDir.getSize()+4, 0);
        if (error == -1){
          cout << "Erro ao tentar mudar de diretório (messages.cpp::sendCD)" << endl;
        }
    
        garbage = 0;
        while((garbage < 10) && (!success)){
          // vetor de pollfd, numero de buffers observados, timeout(ms)
          rv = poll(ufds, 1, 500);
          if(rv){
            if(rv == -1){
              cout << "Erro no recebimento de resposta (messages.cpp::sendCD)" << endl;
              return -1;
            } else {
              recv(soquete, receiptMessage, 68*sizeof(char), 0);
              answer.stringToObj((unsigned char*)receiptMessage);
              // Lê começo da mensagem e vê se tem o delimitador de início
              if(answer.getStartMessage() == 0x7E){ // 0x7E = 01111110
                success = 1;
                if(answer.getType() == 8){ // 8 = OK
                  // Tá ok para mudar de Diretório
                  return 0; // YAY
                } else if(answer.getType() == 0){ // 0 = NACK
                  // NACK
                  success = 0; // reenvia pedido
                } else if(answer.getType() == 14){ //14 = 0xE --> Erro
                  // ERRO
                  if(answer.getData()[0] == '0'){
                    cout << "Diretório Inexistente\n" << endl;
                    return -1;
                  } else if (answer.getData()[0] == '1'){
                    cout << "Sem permissão para acessar o diretório\n" << endl;
                    return -1;
                  } else {
                    success = 0; // reenvia pedido
                  }
                }
              }
            }
          } else{
            cout << "Tempo limite de resposta excedido :c\n" << endl;
            cout << "TIMEOUT ATINGIDO (messages.cpp::sendData)" << endl;
          }
          garbage++;
        }
      }
    }
    
    int Message::sendLS(unsigned char* options){
      int error, success = 0, garbage, rv;
      char *receiptMessage = (char*)malloc(sizeof(char*)*64);
      struct pollfd ufds[1]; // usado para timeout em recv
      String listagem;
      SubMessage listDir, answer, ack, nack;
    
      ufds[0].fd = soquete;
      ufds[0].events = POLLIN;
    
      listDir.setData(options,4,0);
    
      while(!success){
        error = send(soquete, listDir.objToString(), listDir.getSize()+4, 0);
        if (error == -1){
          cout << "Erro ao tentar listar diretorio (messages.cpp::sendLS)" << endl;
        }
    
        garbage = 0;
        while((garbage < 10) && (!success)){
          // vetor de pollfd, numero de buffers observados, timeout(ms)
          rv = poll(ufds, 1, 500);
          if(rv){
            if(rv == -1){
              cout << "Erro no recebimento de resposta (messages.cpp::sendLS)" << endl;
              return -1;
            } else {
              recv(soquete, receiptMessage, 68*sizeof(char), 0);
              answer.stringToObj((unsigned char*)receiptMessage);
              // Lê começo da mensagem e vê se tem o delimitador de início
              if(answer.getStartMessage() == 0x7E){ // 0x7E = 01111110
                success = 1;
                if(answer.getType() == 10){ // 10 = 0xA --> (A)mostra
                  // Mostra as mensagens
                  if(answer.checkParity()){ // Caso a paridade dê errado
                    nack.setData(answer.getSeq(),0,0); // Manda um nack
                    send(soquete,nack.objToString(),nack.getSize()+4, 0);
                    success = 0;
                  } else {
                    strcat(listagem,answer.getData()); // Põe o valor recebido em "listagem"
                    success = 0;
                    while(!success){
                      rv = poll(ufds, 1, 500); // Observa por novas mensagens
                      if(rv){
                        recv(soquete, receiptMessage, 68*sizeof(char), 0);
                        answer.stringToObj((unsigned char*)receiptMessage);
                        if(answer.getStartMessage() == 0x7E){
                          if(answer.getType() == 10){ // 10 = 0xA --> (A)mostra
                            strcat(listagem,answer.getData()); // Põe em "listagem"
                            ack.setData(answer.getSeq(),1,0);
                            send(soquete, ack.objToString(), ack.getSize()+4, 0); // Manda um ACK
                          } else if (answer.getType() == 15) { // Se for FIM
                            ack.setData(answer.getSeq(),1,0);
                            success = 1;
                          }
                        }
                      } else {
                        // TIMEOUT
                      }
                    }
                  }
                  return 0; // YAY
                } else if(answer.getType() == 0){ // 0 = NACK
                  // NACK
                  success = 0; // reenvia pedido
                } else if(answer.getType() == 14){ //14 = 0xE --> Erro
                  // ERRO
                  if(answer.getData()[0] == '0'){
                    cout << "Opção inválida, por favor tente -l, -a ou -la\n" << endl;
                    return -1;
                  } else {
                    success = 0; // reenvia pedido
                  }
                }
              }
            }
          } else{
            cout << "Tempo limite de resposta excedido :c\n" << endl;
            cout << "TIMEOUT ATINGIDO (messages.cpp::sendData)" << endl;
          }
          garbage++;
        }
      }
    }
    
    int Message::sendData(unsigned char* stringMessage){
      int numberOfMessages, sizeLastMessage, size=0;
      int i, j, k, garbage, error, rv, success = 0;
      unsigned char* subData; // a parte da mensagem que vai em cada sequencia
      char *receiptMessage = (char*)malloc(sizeof(char*)*64);
      char *erro1, *erro2, *sucesso, *buffer;
      struct pollfd ufds[1]; // usado para timeout em recv
      SubMessage answer, end;
    
      ufds[0].fd = soquete;
      ufds[0].events = POLLIN;
    
      // Calcula o tamanho da msg
      while( stringMessage[size] != '\0'){
        size++;
      }
    
      // Verifica quantas mensagens serao necessarias
      if (size%64){
        numberOfMessages = (size/64) + 1;
      } else {
        numberOfMessages = (size/64);
      }
      sizeLastMessage = size%64;
      numberOfMessages++;  // +1 = Mensagem de FIM
    
      // Cria as sub mensagens
      SubMessage subMensagem[numberOfMessages];
    
      // string usada para dividir a mensagem de entrada e colocar na parte de data das SubMessages
      subData = (unsigned char*) malloc(sizeof(unsigned char) * 64);
    
      int tipo = 13; // 13 = 0xD --> Dados
    
      // Divide a mensagem
      k = 0; // k é a numero da sequencia na submensagem
      for(i = 0; i < numberOfMessages-1; ++i){
        for(j = 0; j < 64; ++j){
          subData[j] = stringMessage[(i*64)+j];
        }
        subMensagem[i].setData(subData, tipo, k);
        ++k;
        if(k == 64){ // Caso estoure o número de bits de sequencia
          k = 0;
        }
      }
      if (sizeLastMessage){
        // Caso a última mensagem não seja completa realoca subData para o tamanho da última mensagem
        subData = (unsigned char*) realloc(subData, sizeof(unsigned char) * sizeLastMessage);
        for(j = 0; j < sizeLastMessage; ++j){
          subData[j] = stringMessage[(i*64)+j];
        }
        subMensagem[i].setData(subData, tipo, k);
        ++k;
      }else{
        // Caso contrario continua com o tamanho maior
        for(j = 0; j < 64; ++j){
          subData[j] = stringMessage[(i*64)+j];
        }
        subMensagem[i].setData(subData, tipo, k);
        ++k;
      }
      // Seta mensagem de FIM
      i++;
      subMensagem[i].setData((unsigned char*)"FIM", 15, k); // Dados = "FIM", tipo = 0xF, sequencia = proxima
    
      // Caso haja só uma ou duas mensagens
      if (numberOfMessages < 4){
        while(!success){
          if(numberOfMessages < 1) {
            cout << "Algo parece estranho, sua mensagem contém conteúdo?\n" << endl;
            cout << "Erro: Mensagem nula (messages.cpp::sendData)" << endl;
            return -1;
          }
          // manda a primeira msg
          error = send(soquete, subMensagem[0].objToString() , subMensagem[i].getSize()+4, 0);
          if(numberOfMessages > 1) // Se forem 2 ou 3 msgs, manda a segunda
            error = send(soquete, subMensagem[1].objToString() , subMensagem[i].getSize()+4, 0);
          if(numberOfMessages > 2) // Se forem 3 msgs, manda a terceira
            error = send(soquete, subMensagem[2].objToString() , subMensagem[i].getSize()+4, 0);
    
          if(error == -1){
            cout << "Problema com o envio da mensagem (messages.cpp::sendData)" << endl;
          }
    
          // vetor de pollfd, numero de buffers observados, timeout(ms)
          rv = poll(ufds, 1, 500);
          if(rv){
            if(rv == -1){
              cout << "Erro no recebimento de resposta (messages.cpp::sendData)" << endl;
            } else {
              recv(soquete, receiptMessage, 68*sizeof(char), 0);
              answer.stringToObj((unsigned char*)receiptMessage);
              // Lê começo da mensagem e vê se tem o delimitador de início
              if(answer.getStartMessage() == 0x7E){ // 0x7E = 01111110
                if(numberOfMessages == 1){
                  if(answer.getData()[0] == '1'){
                    success = 1; // YAY
                  } else {
                    cout << "Mensagem entregue com erro (messages.cpp::sendData)" << endl;
                  }
                } else if (numberOfMessages == 2){ // numero de mensagens = 2
                  if(answer.getData() == (unsigned char*)"1 1"){ // aceitou ambas as msgs
                    success = 1; // YAY
                  } else {
                    cout << "Mensagem entregue com erro (messages.cpp::sendData)" << endl;
                  }
                } else { // numbero de mensagens = 3
                  if(answer.getData() == (unsigned char*)"1 2"){ // aceitou ambas as msgs
                    success = 1; // YAY
                  } else {
                    cout << "Mensagem entregue com erro (messages.cpp::sendData)" << endl;
                  }
                }
              }
            }
          } else {
            cout << "Tempo limite de resposta excedido :c\n" << endl;
            cout << "TIMEOUT ATINGIDO (messages.cpp::sendData)" << endl;
          }
        }
        success = 0;
      } else if (numberOfMessages > 3){
        i = 0;
        while (i < numberOfMessages - 2){
          error = send(soquete, subMensagem[i].objToString() , subMensagem[i].getSize()+4, 0);
          error = send(soquete, subMensagem[i+1].objToString() , subMensagem[i].getSize()+4, 0);
          error = send(soquete, subMensagem[i+2].objToString() , subMensagem[i].getSize()+4, 0);
    
          success = 0;
          garbage = 0;
          while((garbage < 10) && (!success)){ // Tenta 10 vezes para evitar reenviar a mensagem quando recebe lixo
            // vetor de pollfd, numero de buffers observados, timeout(ms)
            rv = poll(ufds, 1, 500);
            if(rv){
              if(rv == -1){
                cout << "Erro no recebimento de resposta (messages.cpp::sendData)" << endl;
                return -1;
              } else {
                recv(soquete, receiptMessage, 68*sizeof(char), 0);
                answer.stringToObj((unsigned char*)receiptMessage);
                // Lê começo da mensagem e vê se tem o delimitador de início
                if(answer.getStartMessage() == 0x7E){ // 0x7E = 01111110
                  success = 1;
                  if(answer.getType() == 1) {
                    sprintf(erro1, "%d", i);
                    sprintf(erro2, "%d", i+1);
                    sprintf(sucesso, "%d", i+2);
                    if(answer.getData() == (unsigned char*)erro1){
                      i += 1;
                    } else if (answer.getData() == (unsigned char*)erro2){
                      i += 2;
                    } else if (answer.getData() == (unsigned char*)sucesso){
                      i += 3;
                    } else {
                      success = 0;
                    }
                  }
                }
              }
            } else {
              cout << "Tempo limite de resposta excedido :c\n" << endl;
              cout << "TIMEOUT ATINGIDO (messages.cpp::sendData)" << endl;
            }
            garbage++;
          }
        }
      }
      return 0;
    }