Socat para compartilhar um link serial entre vários processos

5

Eu tenho um cenário em que vários processos na mesma caixa desejam se comunicar com um dispositivo serial. O Processo A precisa de comunicação bidirecional com a porta serial, e o Processo B só precisa ser capaz de gravar na porta serial. O dispositivo serial está continuamente lançando dados, enquanto os dois processos gravam periodicamente na porta. O ambiente é Cygwin no Windows (os processos são processos do Windows), mas a porta serial pode ser movida para uma máquina virtual * nix se alguém tiver uma solução somente Linux.

Meu "diagrama de rede" é o seguinte:

                                         /--<->--[Process A]
[serial device]-ttyS0--<->--[socat]-udp-<
                                         \--<<<--[Process B]

Minha primeira tentativa foi configurar uma instância socat com udp-recvfrom e a opção fork. Isso funciona para o primeiro pacote - um processo se separa da socat, envia os dados para o dispositivo serial e começa a ler os dados do dispositivo serial. No entanto, esse processo bifurcado agora tem a porta serial aberta para leitura-gravação, para que nenhum outro forke seja iniciado com êxito.

Alguém pode pensar em alguma maneira de fazer isso funcionar? Posso pensar nos seguintes caminhos, mas não encontrei configurações para fazer nenhum deles funcionar:

  • Use a opção udp-recv do socat para receber de qualquer pessoa, mas encontre uma maneira de enviar respostas para um endereço específico.
  • Use duas socats unidirecionais, uma para gravar na porta e outra para ler na porta. Eu precisaria então de uma maneira de combinar esses dois fluxos unidirecionais em um fluxo bidirecional, mas não sei como.
por John Walthour 28.11.2012 / 15:43

1 resposta

1

Eu encontrei uma solução. Envolve 4 instâncias de socat, organizadas no diagrama de rede abaixo:

                               /-<-[A - udp receiver] <=udp= [D - udp sender]-<-\
ttyS0 <--> [B - serial adapter]                                                  [C - tcp adapter] <=tcp=> Process A
                               \->-------------------------------------------->-/
  • Socat "B" fala com a porta serial, recebe entrada em stdin e saídas para stdout.
  • O Socat "A" ouve os pacotes UDP de qualquer lugar e os envia para o stdout, onde são canalizados para o socat "B".
  • O Socat "C" escuta uma conexão TCP do Processo A. Os dados vindos da socat "A" aparecem em stdin e são roteados para o Processo A. Os dados do Processo A são enviados para a saída "soc" "D".
  • O Socat "D" pega dados de stdin e os envia por UDP para a sociedade "A".

O processo B envia pacotes UDP para socat "B" quando ele quer injetar tráfego.

O comando bash para criar essa monstruosidade é o seguinte:

socat -d -d -d -lpA_udp_rxr -u -T5 udp-recv:1111 - 2>>log.txt |
socat -d -d -d -lpB_serial_adapter -t5 - /dev/ttyS0,raw 2>>log.txt |
socat -d -d -d -lpC_tcp_adapter -T5 - tcp4-listen:3333 2>>log.txt |
socat -d -d -d -lpD_udp_sender -u -T5 - udp:localhost:1111,sourceport=2222 2>>log.txt 

Isso também define um tempo limite de 5 segundos e registra muitos detalhes em "log.txt". Números de porta substituídos por segurança.

    
por 28.11.2012 / 19:52

Tags