Hi, I am trying to write an application which passes data between a serial port and a tcp socket. The problem is that when I send data via the serial port, it passes through fine, but if I send data to the TCP socket, it doesn't get read until the next time the serial port is written, and then, only a single character is read. I'm sure I'm missing something WRT futures and await. Here's the code:
import "serial.nim/src/serial" # just my copy of a fixed version. normally would be "import serial"
import sequtils, strutils, streams
import asyncnet
import asyncdispatch
when isMainModule:
for port in listSerialPorts():
echo port
var clients {.threadvar.}: seq[AsyncSocket]
proc processSocketRx(client: AsyncSocket, port: AsyncSerialPort) {.async.} =
echo("processSocketRx")
while true:
echo("processSerialRx: Waiting for socket data.")
let data = await client.recv(5)
echo("processSerialRx socket data: ", $data)
if data.len == 0: break
echo("processSerialRx: Writing port data.")
discard await port.write(data)
echo("processSerialRx: Port data written.")
proc processSerialRx(client: AsyncSocket, port: AsyncSerialPort) {.async.} =
var
buff = newString(1024)
numReceived: int32
while true:
echo("processSerialRx: waiting for port data.")
numReceived = await port.read(addr buff[0], int32(len(buff)))
echo("processSerialRx port data: ", $buff)
if numReceived == 0: break
let clientSendFuture = client.send(buff)
await clientSendFuture
proc main() {.async.} =
let serialPort = newAsyncSerialPort( "/dev/ttyUSB0" )
serialPort.open(115200, Parity.None, 8, StopBits.One, Handshake.None)
echo("Serving.")
clients = @[]
var server = newAsyncSocket()
server.setSockOpt(OptReuseAddr, true)
server.bindAddr(Port(5008))
server.listen()
while true:
let client = await server.accept()
echo("Client Connected.")
let txTask = processSerialRx(client, serialPort)
let rxTask = processSocketRx(client, serialPort)
echo("Awaiting....")
await txTask or rxTask
#await txTask
#await rxTask
echo("Closing port.")
serialPort.close()
asyncCheck main()
runForever()
Does anyone have a clue as to what I am doing wrong?
Just a stab in the dark but is the serial port utf friendly? Because I think Nim uses utf8, and it's actually not 8 bits, it's a variable length encoding and 8 bits is the minimum.
Have you tried sending your data as cstrings instead of regular strings?
Hi, I'm using Telnet->My Application->GTK Term as the test setup so everything is indeed cstrings. no multibyte characters are sent.
But the serial port works fine, it's actually the socket read which appears to be stalling. When I send characters from Telnet, they do not appear on the console (echo("processSerialRx socket data: ", $data)) until I then send some data to the serial port from gtkterm.
I's almost as if there's a bug in async sockets.