pw_rpc: Generic method invocations and tests
- Restructure the BUILD.gn file to define the pw_rpc server library with
a template. This makes it simple to build different versions of the
pw_rpc server library.
- Define the ServerContext class, which provides context for a
particular RPC invocation.
- Have the server invoke RPCs if it finds a method with matching IDs.
- Implement a test version of the Method class and expand the server
tests.
Change-Id: Id1f46a88f2618a649d72f8c694ee829aef80588c
diff --git a/pw_rpc/BUILD.gn b/pw_rpc/BUILD.gn
index 5226243..37aeba1 100644
--- a/pw_rpc/BUILD.gn
+++ b/pw_rpc/BUILD.gn
@@ -18,32 +18,69 @@
config("default_config") {
include_dirs = [ "public" ]
+ visibility = [ ":*" ]
}
-source_set("pw_rpc") {
- deps = [ ":protos_pwpb" ]
+# pw_rpc servers depend on the protobuf library used to encode and decode
+# requests and responses when invoking methods. This template is used to create
+# instances of the pw_rpc server library with different implementations.
+#
+# The implementation parameter must refer to a library that provides the
+# definition of the Method class in pw_rpc/internal/method.h. The Method class
+# provides the Invoke function, which handles the server use to call into the
+# RPC functions themselves.
+template("_pw_rpc_server_library") {
+ assert(defined(invoker.implementation),
+ "_pw_rpc_server_library requires an implementation to be set")
+
+ source_set(target_name) {
+ forward_variables_from(invoker, "*")
+
+ public_configs = [ ":default_config" ]
+ public_deps = [
+ ":common",
+ dir_pw_span,
+ dir_pw_status,
+ implementation,
+ ]
+ deps = [
+ dir_pw_assert,
+ dir_pw_log,
+ ]
+ public = [
+ "public/pw_rpc/server.h",
+ "public/pw_rpc/server_context.h",
+ ]
+ sources = [
+ "public/pw_rpc/internal/service.h",
+ "public/pw_rpc/internal/service_registry.h",
+ "server.cc",
+ "service.cc",
+ "service_registry.cc",
+ ]
+ allow_circular_includes_from = [ implementation ]
+ friend = [ ":*" ]
+ }
+}
+
+# Classes with no dependencies on the protobuf library for method invocations.
+source_set("common") {
public_configs = [ ":default_config" ]
public_deps = [
+ ":protos_pwpb",
dir_pw_assert,
- dir_pw_log,
dir_pw_span,
dir_pw_status,
]
- public = [
- "public/pw_rpc/channel.h",
- "public/pw_rpc/server.h",
- ]
+ public = [ "public/pw_rpc/channel.h" ]
sources = [
"channel.cc",
"packet.cc",
+ "public/pw_rpc/internal/base_method.h",
"public/pw_rpc/internal/packet.h",
- "public/pw_rpc/internal/service.h",
- "public/pw_rpc/internal/service_registry.h",
- "server.cc",
- "service.cc",
- "service_registry.cc",
]
friend = [ ":*" ]
+ visibility = [ ":*" ]
}
pw_proto_library("protos") {
@@ -61,18 +98,37 @@
]
}
-pw_test("server_test") {
- deps = [
- ":protos_pwpb",
- ":pw_rpc",
- ]
- sources = [ "server_test.cc" ]
+# RPC server for tests only. A mock method implementation is used.
+_pw_rpc_server_library("test_server") {
+ implementation = ":test_method"
+ visibility = [ ":*" ]
+}
+
+config("test_config") {
+ include_dirs = [ "test_public" ]
+ visibility = [ ":test_method" ]
+}
+
+source_set("test_method") {
+ public_configs = [ ":test_config" ]
+ public = [ "test_public/pw_rpc/internal/method.h" ]
+ public_deps = [ ":common" ]
+ visibility = [ ":test_server" ]
}
pw_test("packet_test") {
deps = [
- ":pw_rpc",
+ ":common",
dir_pw_protobuf,
]
sources = [ "packet_test.cc" ]
}
+
+pw_test("server_test") {
+ deps = [
+ ":protos_pwpb",
+ ":test_server",
+ dir_pw_assert,
+ ]
+ sources = [ "server_test.cc" ]
+}