ctucx.git: serial2tcp

serial to tcp/ip bridge

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
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(getEnv("PORT"))
let serial = getEnv("SERIAL_DEVICE")


asyncCheck serveTcp(port)
asyncCheck readSerial(serial)
runForever()