Projeto Final: Fio sem fio

 

 

Para simular um dispositivo conectado na porta serial no cliente foi utilizado o módulo GSM/GPRS quadband com pilha TCP/IP embutida SIM900, utilizando um conversor Serial-USB da FTDI.

 

 

O SIM900 possui suporte para o modo transparente (transparente mode) que proporciona um modo de dados (data mode) especial para envio e recebimento de dados utilizando TCP/IP. Uma vez que a conexão é estabelecida em modo transparente, o módulo entra em modo de dados e todos os dados recebidos a partir da porta serial são tratados como pacotes de dados para serem transferidos posteriormente. Do mesmo modo, todos os dados recebidos são enviados diretamente para a porta serial. No modo transparente, os comandos AT não estão disponíveis e para utilizá-los novamente deve-se alternar para o modo de comando (command mode).


Para ativar o modo transparente, o comando AT+CIPMODE deve ser definido para 1. O comando AT+CIPCCFG é usado para configurar o modo de transferência e possui 4 parâmetros: NmRetry, WaitTm, SendSz, Esc. NmRetry é o número de tentativas que deve ser feita para um pacote IP. WaitTm é o número de intervalos de 200ms deve-se aguardar por dados de entrada antes de enviar o pacote. SendSz é o tamanho do bloco de dados a ser recebido a partir da porta serial antes de enviar. O parâmetro Esc indica se uma "sequence escape" é permitida e por padrão é setado em TRUE.


Para alternar entre o modo de dados e o modo de comando, pode ser utilizada uma "sequence escape" caso o parâmetro Esc do comando AT+CIPCCFG for TRUE (padrão). A "sequence espace" padrão é "+++", e para utilizá-la, deve-se existir um período ocioso de 1000ms antes da seqüência e um período ocioso de 500ms após a seqüência. Além disso, o intervalo entre cada "+" não deve exceder 500ms, caso contrário ele será tratado como dados TCP/IP. O comando ATO pode ser usado para alternar do modo de comando para o modo de dados caso a conexão esteja ativa.

Funcionamento da aplicação: 


Comandos utilizados:

AT+CIPSHUT
Desativa o GPRS PDP Context.

AT + CIPMUX
Inicia uma conexão Multi-Ip.
0 - IP único
1 - Conexão Multi-IP

AT+CIPMODE
Seleciona a aplicação em modo TCP/IP.
0 - Modo normal
1 - Modo transparente

AT+CGATT?
Verifica se o MS está ligado à rede GPRS.

AT+CSTT
Faz as configurações de APN, com nome de usuário e senha.

AT+CIICR
Usado para iniciar uma conexão sem fio.

AT+CIFSR
Utilizado para obtér o endereço ip local.

AT+CIPSTART
Inicia a conexão TCP e UDP.


Implementação

void setup() {
  sim900.begin(19200);  // the GPRS baud rate   
  Serial.begin(19200);    // the GPRS baud rate 
  delay(3000);
  statusConnection = 0;
}

boolean tcpCreateConnection(String destination, String port) {
  if (!sendCommandAndWaitResp("AT+CIPSHUT""OK"33000)) {
      return false;
  }
  if (!sendCommandAndWaitResp("AT+CIPMUX=0""OK"3100)) {
      return false;
  }
  if (!sendCommandAndWaitResp("AT+CIPMODE=1""OK"3100)) {
      return false;
  }
  if (!sendCommandAndWaitResp("AT+CGATT?""OK"3100)) {
      return false;
  }
  if (!sendCommandAndWaitResp("AT+CSTT=\"tim.br\"\"tim\"\"tim\"""OK"3100)) {
      return false;
  }
  if (!sendCommandAndWaitResp("AT+CIICR""OK"34000)) {
      return false;
  }
   if (!sendCommandAndWaitResp("AT+CIFSR""."33000)) {
      return false;
  }
   if (!sendCommandAndWaitResp("AT+CIPSTART=\"tcp\",\"" + destination + "\",\"" + port + "\"""CONNECT"3,1000)) {
      return false;
  } else {
        Serial.println("Conectou!");
      statusConnection = 1;
      return true;
  }
}

boolean sendCommandAndWaitResp(String comando, String respostaEsperada, int tentativas, int delayEntreTentativas) {
    String resposta;
    while (tentativas > 0) {

        sim900.println(comando);
        delay(delayEntreTentativas);

        resposta = "";
        while(sim900.available()!=0) {
            resposta.concat((char)sim900.read());
        }

        if (resposta.indexOf(respostaEsperada) >= 0) {
            debugMessage("OK Comando: " + comando + " Resposta esperada: " + respostaEsperada);
            return true;
        }
        tentativas--;
    }
    debugMessage("ERRO Comando : " + comando + " Resposta esperada: " + respostaEsperada + "Resposta recebida: " + resposta);
    return false;
}


Estrutura

Utilizamos uma estrutura baseada no modelo cliente-servidor onde, o cliente é o dispositivo conectado na porta serial. O estabelecimento da conexão entre o servidor e o dispositivo, será feita pelo dispositivo (cliente), que terá que iniciar a conexão e mantê-la viva para poder receber requisições do servidor. Isso ocorre pois, as operadoras 3G não permitem que isto seja feito de forma direta, devido a problemas de segurança.

O emulador de porta serial no sistema operacional sobre o qual o servidor executa emulará a serial tal qual implementado pelo dispositivo fim, incluindo taxa de bits. Tal sincronização é feita com base em um cabeçalho transmitido no início da comunicação (em implementação). Essas informações são obtidas utilizando o stty.
 

 Funcionamento

 Toda a vez que alguma informação é escrita na porta serial, esta informação é "capturada" pela aplicação. Essa informação é então cifrada e enviada via "Serial CHAT" para o servidor. Este, ao receber alguma informação, decifra-a e escreve na sua porta serial "emulada". O servidor ao identificar que uma informação foi escrita na porta emulada, cifra essa informação e envia para o cliente (dispositivo) via Serial CHAT.


Módulos

Nossa aplicação foi desenvolvida em 3 módulos.

  • Escrita/Leitura na serial: Módulo responsável pela comunicação com a porta serial enviando escrita e efetuando leituras.
     
  • Comunicação: Módulo da aplicação responsável pela comunicação do servidor com o cliente (dispositivo) e do cliente com o servidor. Esse módulo é denominado "Serial CHAT". 
     
  • Segurança: Esse módulo é responsável por cifrar e decifrar as mensagens que são trocadas durante a comunicação entre cliente e servidor.


Testes feitos (app_writer.cc, app_read.cc, app_cipher.cc):

1. Escrita na serial:

  1.1. Escrever conteúdo "a" na porta serial.
        Esperado: Ler conteúdo "b" no CUTECOM.

  1.2. Escrever conteúdo "abc" na porta serial.
         Esperado: Ler conteúdo "bcd" no CUTECOM.

  1.3. Escrever conteúdo "abc" na porta serial com a aplicação.
         Esperado: Ler conteúdo "bcd" da porta serial com a aplicação.

2. Leitura da serial:

   2.1 - Escrever conteúdo "a" no CUTECOM.
   Esperado: Ler conteúdo "b" na porta serial.

   2.2 - Escrever conteúdo "abc" no CUTECOM.
   2- Esperado: Ler conteúdo "bcd" na porta serial.

3. Comunicação:

   3.1 - Enviar conteúdo "a" do servidor para cliente.
           Esperado: Cliente receber "a".

   3.2 - Enviar conteúdo "abc" do servidor para cliente.
            Esperado: Cliente receber "abc".

   3.3 - Enviar conteúdo "a" do cliente para servidor.
           Esperado: Cliente receber "a".

   3.4 - Enviar conteúdo "abc" do cliente para servidor.
            Esperado: Cliente receber "abc".

4. Segurança:

   4.1 - Cifrar uma informação utilizando o algoritmo AES com chave de 128 bits.
            Esperado obter a mensagem cifrada.

   4.2 - Decifrar uma mensagem utilizando a chave 128 bits utilizada durante a cifragem.
            Esperado obter a informação decifrada.


Para visualizar o estado atual da porta serial e verificar se as flags foram corretamente "aplicadas". A  cada utilização da nossa aplicação, verificamos o estado atual da porta serial através do stty.

 speed 9600 baud; line = 0;

intr = <undef>; quit = <undef>; erase = <undef>; kill = <undef>; eof = <undef>; start = <undef>; stop = <undef>; susp = <undef>; rprnt = <undef>;
werase = <undef>; lnext = <undef>; flush = <undef>; min = 0; time = 0;
-brkint -icrnl -imaxbel
-opost -onlcr
-isig -icanon -iexten -echo -echoe -echok -echoctl -echoke

 O código fonte da aplicação encontra-se em https://github.com/rafaeldelucena/so2-final


Objetivo:

O trabalho consiste em transmitir dados de um periférico conectado via comunicação serial para uma estação remota usando a internet. Para escrita utilizaremos um processo que será responsável pela captura dos dados da porta serial. Esses dados serão escritos em um buffer, que posteriormente será criptografado e enviados para a interface de rede correspondente a um modem 3G em uma porta específica.

Para leitura, um processo se conectará ao servidor remoto na porta especificada, decifrando os dados recebidos e emulando os dados em um virtual COM.

 


Processo de escrita no lado do servidor.


Processo de atualização no servidor.



Processo de escrita no cliente.



Processo de leitura no cliente.



Requirements

Serial Communication [1]:
Serial communication requires that you specify the following four parameters:
The baud rate of the transmission
The number of data bits encoding a character
The sense of the optional parity bit
The number of stop bits



Each transmitted character is packaged in a character frame that consists of a single start bit followed by the data bits, the optional parity bit, and the stop bit or bits. Figure 1 shows a typical character frame encoding the letter m.


Figure 1

 

Data bits are transmitted upside down and backwards. That is, inverted logic is used, and the order of transmission is from least significant bit (LSB) to most significant bit (MSB). To interpret the data bits in a character frame, you must read from right to left and read 1 for negative voltage and 0 for positive voltage. This yields 1101101 (binary) or 6D (hex). An ASCII conversion table shows that this is the letter m.

 

Signal Definitions [2]

The RS-232 standard defines some 18 different signals for serial communications. Of these, only six are generally available in the UNIX environment.

GND - Logic Ground

Technically the logic ground is not a signal, but without it none of the other signals will operate. Basically, the logic ground acts as a reference voltage so that the electronics know which voltages are positive or negative.

TXD - Transmitted Data

The TXD signal carries data transmitted from your workstation to the computer or device on the other end (like a MODEM). A mark voltage is interpreted as a value of 1, while a space voltage is interpreted as a value of 0.

RXD - Received Data

The RXD signal carries data transmitted from the computer or device on the other end to your workstation. Like TXD, mark and space voltages are interpreted as 1 and 0, respectively.

DCD - Data Carrier Detect

The DCD signal is received from the computer or device on the other end of your serial cable. A space voltage on this signal line indicates that the computer or device is currently connected or on line. DCD is not always used or available.

DTR - Data Terminal Ready

The DTR signal is generated by your workstation and tells the computer or device on the other end that you are ready (a space voltage) or not-ready (a mark voltage). DTR is usually enabled automatically whenever you open the serial interface on the workstation.

CTS - Clear To Send

The CTS signal is received from the other end of the serial cable. A space voltage indicates that it is alright to send more serial data from your workstation. CTS is usually used to regulate the flow of serial data from your workstation to the other end.

RTS - Request To Send

The RTS signal is set to the space voltage by your workstation to indicate that more data is ready to be sent. Like CTS, RTS helps to regulate the flow of data between your workstation and the computer or device on the other end of the serial cable. Most workstations leave this signal set to the space voltage all the time.




Links

[1] Comunicação Serial:
/>[2] Serial Programming Guide for POSIX Operating Systems:
/>[3] TLDP Serial Programming HOWTO:
/>[4] PySerial:
/>[5] Com2TCP:
/>[6] Serial to TCP:

Código

so2.tar.gz