acpi_actor/src/acpi_actor.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)