diff --git a/PKGBUILD b/PKGBUILD index 3324998..142fae5 100644 --- a/PKGBUILD +++ b/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 diff --git a/src/bt_dbus.nim b/src/bt_dbus.nim index cbea6c1..4342c92 100644 --- a/src/bt_dbus.nim +++ b/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: