From 6f609ccc5a586791e1dee27718e1e1a6569b6b9f Mon Sep 17 00:00:00 2001 From: Jan Romann Date: Mon, 18 Mar 2024 18:09:26 +0100 Subject: [PATCH] feat: add initial NDN binding implementation --- lib/binding_ndn.dart | 13 +++ lib/src/binding_ndn/ndn_config.dart | 25 +++++ lib/src/binding_ndn/ndn_consumer.dart | 92 +++++++++++++++++++ lib/src/binding_ndn/ndn_consumer_factory.dart | 40 ++++++++ 4 files changed, 170 insertions(+) create mode 100644 lib/binding_ndn.dart create mode 100644 lib/src/binding_ndn/ndn_config.dart create mode 100644 lib/src/binding_ndn/ndn_consumer.dart create mode 100644 lib/src/binding_ndn/ndn_consumer_factory.dart diff --git a/lib/binding_ndn.dart b/lib/binding_ndn.dart new file mode 100644 index 00000000..dc52b812 --- /dev/null +++ b/lib/binding_ndn.dart @@ -0,0 +1,13 @@ +// Copyright 2024 Contributors to the Eclipse Foundation. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// SPDX-License-Identifier: BSD-3-Clause + +/// Protocol binding for Named Data Networking (NDN). Follows +/// an experimental [NDN Protocol Binding specification]. +/// +/// [NDN Protocol Binding specification]: https://github.com/JKRhb/wot-binding-templates/tree/ndn-binding +library binding_ndn; + +export "src/binding_ndn/ndn_consumer_factory.dart"; diff --git a/lib/src/binding_ndn/ndn_config.dart b/lib/src/binding_ndn/ndn_config.dart new file mode 100644 index 00000000..ce899416 --- /dev/null +++ b/lib/src/binding_ndn/ndn_config.dart @@ -0,0 +1,25 @@ +// Copyright 2024 Contributors to the Eclipse Foundation. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// SPDX-License-Identifier: BSD-3-Clause + +import "package:meta/meta.dart"; + +import "ndn_consumer.dart"; + +@immutable + +/// Configuration class used by [NdnClient]s. +class NdnConfig { + /// + const NdnConfig({ + this.faceUri, + }); + + /// [Uri] of the local NDN Forwarding Daemon (NFD). + /// + /// If `null`, then the default [Uri] will be used, connecting the + /// [NdnClient] to the NFD via a Unix Socket. + final Uri? faceUri; +} diff --git a/lib/src/binding_ndn/ndn_consumer.dart b/lib/src/binding_ndn/ndn_consumer.dart new file mode 100644 index 00000000..6d70db42 --- /dev/null +++ b/lib/src/binding_ndn/ndn_consumer.dart @@ -0,0 +1,92 @@ +// Copyright 2024 Contributors to the Eclipse Foundation. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// SPDX-License-Identifier: BSD-3-Clause + +import "package:dart_ndn/dart_ndn.dart"; +import "package:meta/meta.dart"; + +import "../../core.dart"; +import "ndn_config.dart"; + +/// A WoT [ProtocolClient] acting as an NDN consumer. +@immutable +class NdnClient implements ProtocolClient { + /// Creates a new [NdnClient] from an NDN [_consumer]. + const NdnClient(this._consumer); + + /// Asynchronously creates a new [NdnClient] from an [NdnConfig]. + static Future create(NdnConfig config) async { + final consumer = await Consumer.create(config.faceUri); + return NdnClient(consumer); + } + + final Consumer _consumer; + + @override + Stream discoverDirectly( + Uri uri, { + bool disableMulticast = false, + }) { + // TODO: implement discoverDirectly + throw UnimplementedError(); + } + + @override + Stream discoverWithCoreLinkFormat(Uri uri) { + // TODO: implement discoverWithCoreLinkFormat + throw UnimplementedError(); + } + + @override + Future invokeResource(AugmentedForm form, Content content) { + // TODO: implement invokeResource + throw UnimplementedError(); + } + + @override + Future readResource(AugmentedForm form) async { + // TODO: Add Name.fromUri + final name = Name.fromString(form.href.path); + + final result = await _consumer.expressInterest(name); + + switch (result) { + case DataReceived(:final data): + final iterable = [data.content ?? []]; + + return Content(form.contentType, Stream.fromIterable(iterable)); + default: + throw Exception("TODO"); + } + } + + @override + Future requestThingDescription(Uri url) { + // TODO: implement requestThingDescription + throw UnimplementedError(); + } + + @override + Future stop() async { + await _consumer.shutdown(); + } + + @override + Future subscribeResource( + AugmentedForm form, { + required void Function(Content content) next, + void Function(Exception error)? error, + required void Function() complete, + }) { + // TODO: implement subscribeResource + throw UnimplementedError(); + } + + @override + Future writeResource(AugmentedForm form, Content content) { + // TODO: implement writeResource + throw UnimplementedError(); + } +} diff --git a/lib/src/binding_ndn/ndn_consumer_factory.dart b/lib/src/binding_ndn/ndn_consumer_factory.dart new file mode 100644 index 00000000..f3d8058a --- /dev/null +++ b/lib/src/binding_ndn/ndn_consumer_factory.dart @@ -0,0 +1,40 @@ +// Copyright 2024 Contributors to the Eclipse Foundation. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// SPDX-License-Identifier: BSD-3-Clause + +import "../../core.dart"; +import "ndn_config.dart"; +import "ndn_consumer.dart"; + +/// A [ProtocolClientFactory] that produces +class NdnConsumerFactory implements ProtocolClientFactory { + NdnConsumerFactory(this.ndnConfig); + + /// The [NdnConfig] acting as the blueprint for creating + final NdnConfig ndnConfig; + + @override + Future createClient() async { + return NdnClient.create(ndnConfig); + } + + @override + bool destroy() { + return true; + } + + @override + bool init() { + return true; + } + + @override + Set get schemes => {"ndn"}; + + @override + bool supportsOperation(OperationType operationType, String? subprotocol) { + return operationType == OperationType.readproperty && subprotocol == null; + } +}