nim-bt/src/bt_socket.nim
Niko Marmeladkov 2601611a46
Initial commit: nimbt v0.1.0
Lightweight Bluetooth manager for Linux with:
- D-Bus BlueZ client via nim-dbus
- CLI binary (nbt) — list, scan, power, connect, etc.
- Daemon (nimbt-daemon) — event loop + UNIX socket IPC
- JSON, TOML, YAML config support
- Nerd Font icons + plain/JSON output modes
- Autoconnect engine for trusted devices
- systemd user service unit
- Arch Linux PKGBUILD
2026-05-30 10:25:53 +03:00

67 lines
1.8 KiB
Nim

import os, posix, json, strutils, tables
import bt_types
const SocketPathEnv* = "NIMBT_SOCKET"
proc defaultSocketPath*: string =
let runtimeDir = getEnv("XDG_RUNTIME_DIR")
if runtimeDir.len > 0:
result = runtimeDir / "nimbt.sock"
else:
result = "/tmp/nimbt.sock"
proc getSocketPath*: string =
result = getEnv(SocketPathEnv)
if result.len == 0:
result = defaultSocketPath()
proc parseCmd*(line: string): SocketCmd =
let node = parseJson(line)
result.id = node["id"].getInt(0)
let cmdStr = node["cmd"].getStr("")
if cmdStr.len > 0:
result.cmd = parseEnum[SocketCmdKind](cmdStr, scList)
result.args = initTable[string, string]()
if node.hasKey("args") and node["args"].kind == JObject:
for k, v in node["args"].fields:
result.args[k] = v.getStr("")
proc cmdToJson*(cmd: SocketCmd): string =
var argsNode = newJObject()
for k, v in cmd.args:
argsNode[k] = %v
let node = %*{"id": cmd.id, "cmd": $cmd.cmd, "args": argsNode}
result = $node & "\n"
proc respToJson*(resp: SocketResp): string =
let node = %*{
"id": resp.id,
"ok": resp.ok,
"data": resp.data,
"error": resp.error,
"stream": resp.stream
}
result = $node & "\n"
proc sendResponse*(fd: cint; resp: SocketResp) =
let data = respToJson(resp)
discard write(fd, data.cstring, data.len)
proc recvCommand*(fd: cint; timeoutMs: int = 100): SocketCmd =
var buf: array[8192, char]
var line = ""
while true:
var pfd: TPollfd
pfd.fd = fd
pfd.events = POLLIN
pfd.revents = 0
let ret = poll(addr pfd, 1.Tnfds, timeoutMs.cint)
if ret <= 0: return
let n = read(fd, addr buf, buf.len)
if n <= 0: return
for i in 0..<n:
if buf[i] == '\n':
if line.len > 0:
return parseCmd(line)
else:
line.add(buf[i])