52 lines
1.6 KiB
Nim
52 lines
1.6 KiB
Nim
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
|
# SPDX-License-Identifier: Unlicense
|
|
|
|
import std/asyncdispatch
|
|
import preserves, syndicate, syndicate/relays
|
|
import ./netlink
|
|
|
|
type AcpiGenlEvent {.packed, preservesRecord: "acpi_event".} = object
|
|
## Found in the Linux source, see linux/drivers/acpi/event.c
|
|
device_class: array[20, char]
|
|
bus_id: array[15, char]
|
|
`type`, data: uint32
|
|
|
|
proc toPreserveHook(chars: openarray[char]; E = void): Preserve[E] =
|
|
## Hack to convert fixed-width character strings to Preserves strings.
|
|
result = Preserve[E](kind: pkString, string: newStringOfCap(len(chars)))
|
|
for c in chars:
|
|
if c == '\0': break
|
|
add(result.string, c)
|
|
|
|
proc recvAcpiEvent(nls: NetlinkSocket; family: uint16): AcpiGenlEvent =
|
|
var msg = recvMsg(nls)
|
|
if msg.hdr.n.nlmsg_type == family:
|
|
var parser: NlattrParser
|
|
while parse(parser, msg):
|
|
# If there is a label on these events then I haven't found it.
|
|
if copyObj(result, parser): return
|
|
next(parser)
|
|
|
|
proc relayEvents(ds: Cap; facet: Facet) =
|
|
var info: MulticastInfo
|
|
block:
|
|
let nls = openSocket()
|
|
info = resolveMulticastInfo(nls, "acpi_event\0")
|
|
close(nls)
|
|
let mcast = openSocket(int info.mcastGrpId)
|
|
while true:
|
|
let event = recvAcpiEvent(mcast, info.familyId)
|
|
run(facet) do (turn: var Turn):
|
|
message(turn, ds, event)
|
|
poll()
|
|
|
|
# TODO seccomp
|
|
|
|
type Args {.preservesDictionary.} = object
|
|
machine: Cap
|
|
|
|
runActor("main") do (turn: var Turn; root: Cap):
|
|
connectStdio(turn, root)
|
|
onPublish(turn, root, ?Args) do (ds: Cap):
|
|
relayEvents(ds, turn.facet)
|