bt_dbus: bypass nim-dbus getPrimitive bug with robust custom parser
This commit is contained in:
parent
d250f8b6ab
commit
7e3c8c8e47
2 changed files with 105 additions and 8 deletions
6
PKGBUILD
6
PKGBUILD
|
|
@ -41,12 +41,14 @@ build() {
|
|||
patch_dbus
|
||||
rm -rf "$srcdir/nimcache"
|
||||
nim c \
|
||||
--path:"$NIMBLE_DIR/pkgs2" \
|
||||
--noNimblePath \
|
||||
--nimblePath:"$NIMBLE_DIR/pkgs2" \
|
||||
--nimcache:"$srcdir/nimcache" \
|
||||
--mm:orc -d:release --opt:speed --hints:off \
|
||||
-o:build/nbt src/nbt.nim
|
||||
nim c \
|
||||
--path:"$NIMBLE_DIR/pkgs2" \
|
||||
--noNimblePath \
|
||||
--nimblePath:"$NIMBLE_DIR/pkgs2" \
|
||||
--nimcache:"$srcdir/nimcache" \
|
||||
--mm:orc -d:release --opt:speed --hints:off \
|
||||
-o:build/nimbt-daemon src/nimbt_daemon.nim
|
||||
|
|
|
|||
107
src/bt_dbus.nim
107
src/bt_dbus.nim
|
|
@ -22,6 +22,8 @@ proc newBluezConn*(): BluezConn =
|
|||
result.adapters = @[]
|
||||
result.devices = @[]
|
||||
|
||||
proc readDbusValueRaw*(iter: ptr DBusMessageIter): DbusValue
|
||||
|
||||
proc dbusCall*(bz: BluezConn; path, iface, methodName: string; args: openarray[DbusValue] = []): Reply =
|
||||
var msg = makeCall(BluezDest, path.ObjectPath, iface, methodName)
|
||||
for a in args:
|
||||
|
|
@ -32,8 +34,8 @@ proc dbusCall*(bz: BluezConn; path, iface, methodName: string; args: openarray[D
|
|||
|
||||
proc dbusGet*(bz: BluezConn; path, iface, prop: string): DbusValue =
|
||||
let reply = bz.dbusCall(path, PropIface, "Get", @[iface.asDbusValue, prop.asDbusValue])
|
||||
var iter = reply.iterate()
|
||||
var val = iter.unpackCurrent(DbusValue)
|
||||
var inputIter = reply.iterate()
|
||||
var val = readDbusValueRaw(cast[ptr DBusMessageIter](addr inputIter))
|
||||
if val != nil and val.kind == dtVariant:
|
||||
val = val.variantValue
|
||||
result = val
|
||||
|
|
@ -47,8 +49,8 @@ proc dbusCallMethod*(bz: BluezConn; path, iface, methodName: string; args: opena
|
|||
|
||||
proc dbusGetAll*(bz: BluezConn; path, iface: string): Table[string, DbusValue] =
|
||||
let reply = bz.dbusCall(path, PropIface, "GetAll", @[iface.asDbusValue])
|
||||
var iter = reply.iterate()
|
||||
let val = iter.unpackCurrent(DbusValue)
|
||||
var inputIter = reply.iterate()
|
||||
let val = readDbusValueRaw(cast[ptr DBusMessageIter](addr inputIter))
|
||||
if val.kind == dtArray:
|
||||
for entry in val.arrayValue:
|
||||
if entry.kind == dtDictEntry:
|
||||
|
|
@ -107,10 +109,103 @@ proc propsToAdapter(path: string; props: Table[string, DbusValue]): Adapter =
|
|||
result.discoverable = props.getOrDefault("Discoverable", DbusValue(kind: dtBool, boolValue: false)).boolValue
|
||||
result.pairable = props.getOrDefault("Pairable", DbusValue(kind: dtBool, boolValue: false)).boolValue
|
||||
|
||||
proc readDbusValueRaw(iter: ptr DBusMessageIter): DbusValue =
|
||||
let kind = cast[DbusTypeChar](dbus_message_iter_get_arg_type(iter))
|
||||
case kind:
|
||||
of dtNull:
|
||||
return DbusValue(kind: dtNull)
|
||||
of dtBool:
|
||||
var v: dbus_uint32_t
|
||||
dbus_message_iter_get_basic(iter, addr v)
|
||||
return DbusValue(kind: dtBool, boolValue: v != 0)
|
||||
of dtDouble:
|
||||
var v: float64
|
||||
dbus_message_iter_get_basic(iter, addr v)
|
||||
return DbusValue(kind: dtDouble, doubleValue: v)
|
||||
of dtInt32:
|
||||
var v: int32
|
||||
dbus_message_iter_get_basic(iter, addr v)
|
||||
return DbusValue(kind: dtInt32, int32Value: v)
|
||||
of dtInt16:
|
||||
var v: int16
|
||||
dbus_message_iter_get_basic(iter, addr v)
|
||||
return DbusValue(kind: dtInt16, int16Value: v)
|
||||
of dtUint16:
|
||||
var v: uint16
|
||||
dbus_message_iter_get_basic(iter, addr v)
|
||||
return DbusValue(kind: dtUint16, uint16Value: v)
|
||||
of dtUint64:
|
||||
var v: uint64
|
||||
dbus_message_iter_get_basic(iter, addr v)
|
||||
return DbusValue(kind: dtUint64, uint64Value: v)
|
||||
of dtUint32:
|
||||
var v: dbus_uint32_t
|
||||
dbus_message_iter_get_basic(iter, addr v)
|
||||
return DbusValue(kind: dtUint32, uint32Value: v)
|
||||
of dtInt64:
|
||||
var v: int64
|
||||
dbus_message_iter_get_basic(iter, addr v)
|
||||
return DbusValue(kind: dtInt64, int64Value: v)
|
||||
of dtByte:
|
||||
var v: uint8
|
||||
dbus_message_iter_get_basic(iter, addr v)
|
||||
return DbusValue(kind: dtByte, byteValue: v)
|
||||
of dtString:
|
||||
var s: cstring
|
||||
dbus_message_iter_get_basic(iter, addr s)
|
||||
return DbusValue(kind: dtString, stringValue: $s)
|
||||
of dtObjectPath:
|
||||
var s: cstring
|
||||
dbus_message_iter_get_basic(iter, addr s)
|
||||
return DbusValue(kind: dtObjectPath, objectPathValue: ($s).ObjectPath)
|
||||
of dtSignature:
|
||||
var s: cstring
|
||||
dbus_message_iter_get_basic(iter, addr s)
|
||||
return DbusValue(kind: dtSignature, signatureValue: ($s).Signature)
|
||||
of dtVariant:
|
||||
var subiter: DBusMessageIter
|
||||
dbus_message_iter_recurse(iter, addr subiter)
|
||||
let subvalue = readDbusValueRaw(addr subiter)
|
||||
return DbusValue(kind: dtVariant, variantType: subvalue.kind, variantValue: subvalue)
|
||||
of dtDictEntry:
|
||||
var subiter: DBusMessageIter
|
||||
dbus_message_iter_recurse(iter, addr subiter)
|
||||
let key = readDbusValueRaw(addr subiter)
|
||||
discard dbus_message_iter_next(addr subiter)
|
||||
let val = readDbusValueRaw(addr subiter)
|
||||
return DbusValue(kind: dtDictEntry, dictKey: key, dictValue: val)
|
||||
of dtArray:
|
||||
var subiter: DBusMessageIter
|
||||
dbus_message_iter_recurse(iter, addr subiter)
|
||||
var values: seq[DbusValue]
|
||||
var subkind: DbusType
|
||||
while true:
|
||||
let subkindInt = dbus_message_iter_get_arg_type(addr subiter)
|
||||
subkind = cast[DbusTypeChar](subkindInt)
|
||||
if subkind.kind == dtNull: break
|
||||
values.add(readDbusValueRaw(addr subiter))
|
||||
if dbus_message_iter_has_next(addr subiter) == 0: break
|
||||
discard dbus_message_iter_next(addr subiter)
|
||||
if values.len > 0 and subkind.kind == dtDictEntry:
|
||||
subkind.keyType = values[0].dictKey.kind
|
||||
subkind.valueType = values[0].dictValue.kind
|
||||
return DbusValue(kind: dtArray, arrayValueType: subkind, arrayValue: values)
|
||||
of dtStruct:
|
||||
var subiter: DBusMessageIter
|
||||
dbus_message_iter_recurse(iter, addr subiter)
|
||||
var values: seq[DbusValue]
|
||||
while true:
|
||||
values.add(readDbusValueRaw(addr subiter))
|
||||
if dbus_message_iter_has_next(addr subiter) == 0: break
|
||||
discard dbus_message_iter_next(addr subiter)
|
||||
return DbusValue(kind: dtStruct, structValues: values)
|
||||
else:
|
||||
raise newException(DbusException, "nim-bt does not support D-Bus type " & $kind)
|
||||
|
||||
proc refresh*(bz: BluezConn) =
|
||||
let reply = bz.dbusCall(BluezPath, ObjMgrIface, "GetManagedObjects")
|
||||
var iter = reply.iterate()
|
||||
let root = iter.unpackCurrent(DbusValue)
|
||||
var inputIter = reply.iterate()
|
||||
let root = readDbusValueRaw(cast[ptr DBusMessageIter](addr inputIter))
|
||||
bz.adapters = @[]
|
||||
bz.devices = @[]
|
||||
if root.kind == dtArray:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue