ctucx.git: serial2tcp

serial to tcp/ip bridge

commit cb1c08a15367dbd7338bf8c12af74674dbb0fe79
Author: Milan Pässler <me@pbb.lc>
Date: Sun, 14 Jul 2019 21:21:26 +0200

initial commit
2 files changed, 63 insertions(+), 0 deletions(-)
A
serial2tcp.nimble
|
12
++++++++++++
A
src/serial2tcp.nim
|
51
+++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/serial2tcp.nimble b/serial2tcp.nimble
@@ -0,0 +1,12 @@
+# Package
+
+version       = "0.1.0"
+author        = "Milan P\xC3\xA4ssler"
+description   = "A new awesome nimble package"
+license       = "AGPL-3.0"
+srcDir        = "src"
+bin           = @["serial2tcp"]
+
+# Dependencies
+
+requires "nim >= 0.20.0"
diff --git a/src/serial2tcp.nim b/src/serial2tcp.nim
@@ -0,0 +1,51 @@
+import asyncnet
+import asyncdispatch
+import threadpool
+import sequtils
+import os
+import strutils
+
+var tcpClients: seq[AsyncSocket]
+tcpClients = @[]
+
+proc broadcast(msg: string) =
+  for client in tcpClients:
+    try:
+      asyncCheck client.send(msg)
+    except:
+      client.close()
+      tcpClients.keepIf(proc(x: AsyncSocket): bool = x != client)
+
+proc serveTcp(port: int) {.async.} =
+  var socket = newAsyncSocket()
+  socket.setSockOpt(OptReuseAddr, true)
+  socket.bindAddr(Port(port))
+  socket.listen()
+
+  while true:
+    let client = await socket.accept()
+    tcpClients.add(client)
+
+proc asyncReadLine*(file: File): Future[string] =
+  var fut = newFuture[string]()
+  var flowVar = spawn file.readLine()
+
+  addTimer(50, false, proc(fd: AsyncFD): bool =
+      if flowVar.isReady():
+        fut.complete(^flowVar)
+        return true
+    )
+
+  return fut
+
+proc readSerial(serial: string) {.async.} =
+  let file = open(serial, fmReadWrite)
+  while true:
+    let line = await file.asyncReadLine()
+    broadcast(line & '\n')
+
+let port = parseInt(paramStr(1))
+let serial = paramStr(2)
+asyncCheck serveTcp(port)
+asyncCheck readSerial(serial)
+runForever()