rewrite fake-nmea to not need socat
This commit is contained in:
parent
01e260e9aa
commit
64789d1fe9
@ -1,10 +1,72 @@
|
|||||||
(local { : sleep } (require :posix.unistd))
|
(local { : sleep : close } (require :posix.unistd))
|
||||||
|
(local sock (require :posix.sys.socket))
|
||||||
|
(local poll (require :posix.poll))
|
||||||
|
(local { : view } (require :fennel))
|
||||||
|
|
||||||
|
(fn handle-client [fd event]
|
||||||
|
(case event
|
||||||
|
{:HUP true}
|
||||||
|
(do
|
||||||
|
(print fd " disconnected")
|
||||||
|
(close fd)
|
||||||
|
(values fd nil))
|
||||||
|
{:IN true}
|
||||||
|
(do
|
||||||
|
(sock.recv fd 1024) ; discard input and carry on
|
||||||
|
nil)))
|
||||||
|
|
||||||
|
(fn accept-new-connection [server-sock event]
|
||||||
|
(case event
|
||||||
|
{:IN true}
|
||||||
|
(do
|
||||||
|
(print "new connection")
|
||||||
|
(let [connected (sock.accept server-sock)]
|
||||||
|
(print connected)
|
||||||
|
(values connected handle-client)))
|
||||||
|
{:HUP true}
|
||||||
|
(do
|
||||||
|
(print "HUP on server socket")
|
||||||
|
(os.exit 1))
|
||||||
|
_
|
||||||
|
(values nil nil)))
|
||||||
|
|
||||||
|
(fn server-socket [path]
|
||||||
|
(let [s (assert (sock.socket sock.AF_UNIX sock.SOCK_STREAM 0))
|
||||||
|
sa { :family sock.AF_UNIX
|
||||||
|
:path path
|
||||||
|
}]
|
||||||
|
(assert (sock.bind s sa))
|
||||||
|
(assert (sock.listen s 10))
|
||||||
|
s))
|
||||||
|
|
||||||
|
(fn read-with-rewind [handle]
|
||||||
|
(let [(s err) (handle:read "L")]
|
||||||
|
(if s
|
||||||
|
s
|
||||||
|
(if (and (not err) (handle:seek "set" 0)) ; eof
|
||||||
|
(read-with-rewind handle)
|
||||||
|
(error err)))))
|
||||||
|
|
||||||
|
(fn write-sentences [handle outputs]
|
||||||
|
(var done false)
|
||||||
|
(while (not done)
|
||||||
|
(let [l (read-with-rewind handle)]
|
||||||
|
(if (string.match l "GNS") (set done true))
|
||||||
|
(each [fd action (pairs outputs)]
|
||||||
|
(when (sock.getpeername fd) ; cheeky
|
||||||
|
(sock.send fd l))))))
|
||||||
|
|
||||||
(let [[filename socketname] arg
|
(let [[filename socketname] arg
|
||||||
socket (io.popen (.. "socat - unix-listen:" socketname) :w)]
|
server (server-socket socketname)
|
||||||
|
fd-actions { server accept-new-connection }]
|
||||||
(with-open [handle (io.open filename :r)]
|
(with-open [handle (io.open filename :r)]
|
||||||
(each [l (handle:lines "L")]
|
(while true
|
||||||
(if (string.match l "GNS") (sleep 1))
|
(let [poll-fds (collect [fd _ (pairs fd-actions)]
|
||||||
(socket:write l)
|
(values fd {:events { :IN true } }))]
|
||||||
(socket:flush)
|
(if (> (poll.poll poll-fds (* 1 1000)) 0)
|
||||||
)))
|
(each [fd v (pairs poll-fds)]
|
||||||
|
(when (. v :revents)
|
||||||
|
(print :polled fd (view v.revents))
|
||||||
|
(let [(k v) ((. fd-actions fd) fd v.revents)]
|
||||||
|
(and k (tset fd-actions k v)))))
|
||||||
|
(write-sentences handle fd-actions))))))
|
||||||
|
Loading…
Reference in New Issue
Block a user