MSX Networking – Developers, developers, developers, developers….

Antes de mais nada eu quero deixar aqui o meu agradecimento pelo feedback recebido sobre o primeiro post da série sobre Networking no MSX, pois a movimentação e receptividade do publico já a colocam como uma das mais lidas desde que lancei o blog, então fica aqui o meu . obrigado a todos :).

OptoNet Card.

Quem acompanha de perto as novidades da comunidade local do MSX, sabe que no ano passado o Luis Fernando Luca, iniciou o desenvolvimento  de uma placa multi-função que conta com interface de rede ethernet, interface serial e também entrada para cartão micro SD.

Pois bem, os avanços feitos por ele e relatados nas principais listas de discussão nacionais de MSX, já haviam deixado a comunidade bastante empolgada, principalmente depois do primeiro vídeo dos testes onde o próprio Luca junto do Fábio Belavenuto, demonstraram dois MSX conversando através de um chat escrito em MSX-BASIC, utilizado nos testes, conforme pode ser visto nesse post aqui.

Alguns meses depois o Luca informou, nas listas, o seu interesse em lançar um lote de sua placa, “para desenvolvedores”, pois dessa forma seria possível detectar e corrigir problemas na placa, bem como fazer melhorias no hardware e por ultimo, proporcionar novos desenvolvimentos de software para essa placa. Então, da mesma forma como fiz quando a TecnoBytes lançou a sua Obsonet, corri para adquirir a minha e assim começar a desenvolver coisas legais para a OptoNet e também ajudar em tudo mais o que eu puder em seu desenvolvimento.

OptoNet card + MSX TurboR A1ST
OptoNet card + MSX TurboR A1ST

A engenharia de software

Placa nas mãos, férias do trabalho, era hora de arregaçar as mangas e começar a me divertir um pouco com a OptoNet. Já no primeiro dia testei o funcionamento da plaquinha utilizando os samples disponibilizados pelo Luca em seu site e em 15 minutos já havia planejado a minha estratégia para desenvolver softwares para a OptoNet sem que ficasse algo específico só para essa placa, pois até o momento que escrevo esse post, a OptoNet não conta com BIOS alguma e nada que a compatibilize com a UNAPI, que é o “padrão de facto” para Networking no MSX.

Então para que todo o software escrito para a OptoNet não ficasse disponível somente para essa placa, eu precisaria escrever uma abstração de sockets, de tal forma que eu pudesse especificar qual device driver utilizar no momento da criação do socket de rede, dessa forma eu poderia ter um device driver para a OptoNet e futuramente um device driver para dispositivos baseados em UNAPI, compatibilizando assim os softwares escritos para a OptoNet com as placas UNAPI compliance, como Obsonet e DenyoNet.

DenyoNet UNAPI compatible card
DenyoNet UNAPI compatible card

Infelizmente o MSX-DOS é um sistema operacional muito antigo e desprovido de uma camada abstrata para device drivers, como podemos ver em sistemas operacionais mais modernos, incluindo o pai do MSX-DOS, o MS-DOS em suas versões mais modernas, conforme pode ser lido aqui no site da Dr.Dobs sobre como adicionar device drivers ao MS-DOS.

Então para “burlar” essa deficiencia do sistema operacional, uma abstração foi escrita de tal forma a definir uma interface para dispositivos que suportam comunicação de dados e uma implementação que gerencia o registro dos device drivers bem como seu e fluxo de funcionamento pela aplicação.

Software layers
Software layers

Com base nessas idéias eu já tinha todos os requisitos prontos para começar a escrever uma abstração de qualidade, bem como um primeiro device driver a ser utilizado como um test case para essa idéia toda, assim em um dia ininterrupto de trabalho eu já tinha tanto a abstração de sockets, quanto o device driver para a OptoNet, implementados e com isso o framework que estou desenvolvendo em paralelo às ferramentas disponibilizadas por mim nos ultimos meses, por exemplo o MSXDUMP, agora tem suporte a funções de comunicação em rede, seja ela ethernet, Serial ou JoyNet, bastando apenas criar os device drivers específicos para cada uma dessas possibilidades existentes e inclusive outras que poderão vir no futuro :).

How it works

O principal objetivo da abstração de sockets é a simplicidade, aliado ao poder de qualquer implementação de sockets existente em qualquer plataforma com mais memória e poder de processamento. Abaixo segue um exemplo de como abrir uma conexão com outra ponta, enviar e receber dados utilizando a implementação de sockets desenvolvida.

{$v- c- u- a+ r-}

{$i types.pas}
{$i funcptr.pas}
{$i sockdefs.pas}     (* Socket structures *)
{$i socket.pas}       (* Socket abstract implementation *)
{$i helpstr.pas}
{$i optonet.pas}      (* OptoNet low level functions and driver *)
                      (* implementation for socket support *)

(*
 * Main block
 *)

Var
       packet          : TSocketPacket;
       socket          : TSocket;
       strData         : TString;

Begin
  { Initialize the socket to use the OPTONET driver }
  InitSocket( socket, Addr( OptoNetDrvSocketInit ) );

  { Socket configuration }
  socket.strIPAddress := '192.168.1.1';  { The IP address to connect }
  socket.nPort := 8080;  { The port to connect }

  (* The OPTONET CARD, actually, support ONLY UDP connection.
   * When the firmware to support TCP connection,
   * the SOCK_STREAM option will be available
   *)
  socket.Connection.SocketType := SOCK_DGRAM; 

  strData := 'THIS IS THE PACKET DATA TO SEND';

  If( SocketConnect( socket ) = SocketSuccess )  Then
  Begin
    { Packet data buffer configuration }
    packet.pData := Ptr( Addr( strData ) ); { Weird TP3 pointer deference }
    packet.nSize := Length( strData ) + 1;  { + 1 for the first byte containing}
                                            { the size of the String }

    { Send the packet to another peer }
    If( SocketSendPacket( socket, packet ) <> SocketSuccess )  Then
      WriteLn( 'Error to send the packet to peer.' );

    { Receive the packet from another peer }
    If( SocketRecvPacket( socket, packet ) <> SocketSuccess )  Then
      WriteLn( 'Error to receive the packet from peer.' );

    If( SocketDisconnect( socket ) <> SocketSuccess )  Then
      WriteLn( 'Error to disconnect from peer.' );
  End
  Else
    WriteLn( 'Error to connect to the specified address:port.' );
End.

O código acima contém tudo o que precisamos para Conectar -> Enviar um pacote -> Receber um pacote -> Desconectar e apesar do UDP ser um protocolo ConnectionLess, eu optei por fazer o device driver da OptoNet necessitar de um Connect pois o firmware da OptoNet necessita de algumas chamadas que explicitamente fazem algumas limpezas em seus buffers internos no momento em que vamos setar o IP e porta de conexão, então ao forçar um Connect para comunicação via UDP, ficamos com a falsa impressão de que  UDP tem uma conexão estabelecida, tudo isso apenas para evitar de a cada Send ou Receive seja feito esse mesmo procedimento de limpeza explicita de buffer no firmware, o que acarretaria em uma perda forçada de pacotes com o modelo implementado atualmente no firmware.

Lembrando que isso são apenas impressões de um desenvolvedor de software de comunicação, de como um modelo de comunicação deveria ser, segundo os padrões já estabelecidos na industria de software, por isso, quando fizermos todos os ajustes necessários no firmware, para que o mesmo esteja adequado a esses padrões, certamente o modelo implementado pelo device driver implementado para a OptoNet, será ajustado para ficar de acordo com o padrão de comunicação UDP universalmente conhecido e aceito pelos desenvolvedores de software de comunicação.

No driver da OptoNet, o Disconnect é meramente ilustrativo, pois na versão final do device driver, ele não será aceito em conexões UDP, bem como o Connect.

Manifest Network Tools

Após a implementação do device driver e da abstração de sockets, faltava “apenas” criar aplicações que fizessem uso real de todo o potêncial dessa nova peça do framework.

A partir daí sairam as duas primeiras ferramentas de uma Suite que denominei de Manifest Network Tools, sendo essas ferramentas parte de um file transfer (SEND.COM e RECV.COM), capaz de fazer a transferência de arquivos entre máquinas MSX, utilizando UDP, com garantia de entrega pois apesar de UDP ser um protocolo que não garante a entrega de pacotes, implementei um protocolo simples baseado em ACK, que garante que todos os pacotes foram entregues a seu destino.

Send file transfer
Send file transfer (Manifest Network Tool)

A operação das ferramentas é simples e basta apenas iniciar o RECV.COM na máquina que irá receber o arquivo e o SEND.COM na máquina que irá enviar o arquivo e aguardar o envio do arquivo até o destino. Cada uma das ferramentas tem um controle de fluxo, Timeout e numero de tentativas de recepção de pacotes, antes de reportar falha na conexão.

Cada uma das opções de linha de comando é explicada na própria tela de help das ferramentas e que também descrevo abaixo:

OPÇÕES DE LINHA DE COMANDO

-h Mostra o Help da aplicação;
-a <ip_address> Especifica o endereço IP de cada ponta que irá estabelecer comunicação. O RECV.COM deve especificar o IP de onde está o SEND.COM e vice-versa;
-p <port_number> Especifica o número da porta a se conectar ou que estará escutando (no caso do RECV.COM);

Recv file transfer
Recv file transfer (Manifest Network Tool)

Infelizmente os testes, tanto do RECV.COM quanto do SEND.COM, foram feitos utilizando um MSX e um PC, pois não tenho 2 placas OptoNet, entretanto utilizando um cliente similar que criei no Linux para o PC, pude testar vários casos e otimizar o SEND.COM e o RECV.COM no MSX, mas ainda é necessário fazer um teste real entre 2 MSX enviando e recebendo dados através dessas ferramentas, o que poderá ser feito agora pela comunidade de MSX e que já possui a OptoNet :).

Known Bugs

Infelizmente nem tudo é um mar de rosas e alguns bugs foram detectados por mim, tanto na OptoNet, quanto nas ferramentas que criei.

Alguns problemas encontrados na OptoNet:

  1. Percebi que ao utilizar a velocidade máxima do MSX para enviar comandos para a placa, a mesma trava, sendo necessário desligar o MSX, uma vez que o PIC é um circuito a parte e um simples reboot no MSX não é suficiente para resetar o PIC. Nesse caso eu tentei dar sleeps entre as chamadas à OptoNet (na camada do device driver) para evitar os travamentos, entretanto mesmo assim a comunicação fica instável e também mais lenta devido aos sleeps. Quando resolvermos isso, irei remover os sleeps e teremos um driver mais rápido e estável.
  2. No TurboR há constantes travamentos na máquina, algumas vezes durante o uso e outras no boot (Necessito testar em outros TurboR’s que tenho aqui);
  3. Em máquinas com impressora embutida (ex: National FS4700) a comunicação com a placa fica instável, apenas consegue enviar comandos para a placa mas não recebe;
  4. No HitBit HB-T7 (com modem interno) a placa não recebeu nem enviou nenhum pacote, me passando a impressão de que não está funcionando nesse micro. O Emiliano Fraga, no GDMSX, me reportou que no HitBit dele a placa também não funcionou, então acredito que o problema esteja relacionado com os HitBit’s de maneira geral, mas necessita de mais fontes de informação para se confirmar isso;

Alguns problemas das ferramentas SEND.COM e RECV.COM:

  1. Adicionar parâmetros para que o usuário possa definir o Timeout da comunicação e número de tentativas (retries);
  2. Adicionar o conceito de sessão às ferramentas, pois hoje é possivel que mais de um cliente (SEND.COM) se conecte a um servidor (RECV.COM), causando danos na comunicação e consequentemente no arquivo enviado;

Onde baixar os fontes e os binários.

No ultimo domingo, liberei silenciosamente no repositório do Old Skool Tech, os fontes e binários da Suite Manifest Network Tools v0.0, onde eu estava apenas aguardando esse post para fazer o anuncio oficial :).

http://sourceforge.net/projects/oldskooltech/files/MSX/Manifest%20Network%20Tools/v0.0/manifest-src.zip/download
Fontes (Zip)

http://sourceforge.net/projects/oldskooltech/files/MSX/Manifest%20Network%20Tools/v0.0/manifest-src.lhz/download
Fontes (Lhz) 

http://sourceforge.net/projects/oldskooltech/files/MSX/Manifest%20Network%20Tools/v0.0/manifest-bin.zip/download
Binários (Zip)

http://sourceforge.net/projects/oldskooltech/files/MSX/Manifest%20Network%20Tools/v0.0/manifest-bin.lhz/download
Binários (Lhz)

Bom, acredito que estamos caminhando bem rápido e em breve teremos cada vez mais, versões estáveis, tanto da OptoNet quanto das ferramentas que a utilizam.

Até os próximos posts.

[]’s
PopolonY2k

Referência na internet

MSX Networking (Parte I)
http://www.popolony2k.com.br/?p=2150

OptoTech card for MSX
http://www.optotech.net.br/fzanoto/msx.htm

MicroSD Card (Wikipedia)
http://pt.wikipedia.org/wiki/MicroSD

OptoNet chat (MSX-BASIC code)
http://www.optotech.net.br/fzanoto/CHAT_FB2.BAS

Video de demonstração de chat utilizando a OptoNet (Retrocomputaria Plus)
http://www.retrocomputaria.com.br/plus/?p=4606

TecnoBytes Classic Computers
http://www.tecnobytes.com.br/

Obsonet (MSX Resource Center)
http://www.msx.org/articles/obsonet

GDMSX (Desenvolvimento de software e coisas legais para MSX)
http://groups.google.com/group/gdmsx

Network sockets (Wikipedia)
http://en.wikipedia.org/wiki/Network_socket

Device driver (Wikipedia)
http://en.wikipedia.org/wiki/Device_driver

DenyoNet (Konamiman blog)
http://konamiman.blogspot.com.br/2010/03/denyonet.html

MSX-DOS (Wikipedia)
http://en.wikipedia.org/wiki/MSX-DOS

MS-DOS (Wikipedia)
https://en.wikipedia.org/wiki/MS-DOS

Writing device drivers for MS-DOS (Dr. Dobbs)
http://www.drdobbs.com/writing-ms-dos-device-drivers/184402277

Test Case (Wikipedia)
http://en.wikipedia.org/wiki/Test_case

MSXDUMP (PopolonY2k Rulezz)
http://www.popolony2k.com.br/?p=2125

ConnectionLess communication (Wikipedia)
http://en.wikipedia.org/wiki/Connectionless_communication

Acknowledgment (Data Networks – Wikipedia)
http://en.wikipedia.org/wiki/Acknowledgement_(data_networks)

Old Skool Tech (Sourceforge.net)
http://sourceforge.net/projects/oldskooltech/

4 thoughts on “MSX Networking – Developers, developers, developers, developers….”

  1. Simplesmente SENSACIONAL, cara tu é fo** mesmo, ta ficando show.
    Já baixei e vou testar aqui.

    1. Opa @Edson…

      …obrigado pelas considerações :).

      Existem instabilidades, principalmente no fato da placa não suportar uma transferência entre MSX->Placa, em alta velocidade, então pode ser que ao tentar a primeira vez, exista um travamento da placa, mas nada que um liga/desliga no MSX resolva.

      Quando acontece isso comigo eu tento uma ou duas vezes e passa a funcionar, depois disso funciona sempre.

      Temos um bom caminho a percorrer para ajustar o firmware dessa placa.

      Fico no aguardo de suas impressões e feedback.

      []’s
      PopolonY2k

Leave a Reply