diff --git a/samples/modules/thrift/hello/client/CMakeLists.txt b/samples/modules/thrift/hello/client/CMakeLists.txt new file mode 100644 index 00000000000000..44860f78da4b40 --- /dev/null +++ b/samples/modules/thrift/hello/client/CMakeLists.txt @@ -0,0 +1,61 @@ +# Copyright 2022 Meta +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(thrift_hello_server) + +FILE(GLOB app_sources + src/*.cpp +) + +include(${ZEPHYR_BASE}/modules/thrift/cmake/thrift.cmake) + +set(generated_sources "") +set(gen_dir ${ZEPHYR_BINARY_DIR}/misc/generated/thrift_hello) +list(APPEND generated_sources ${gen_dir}/gen-cpp/hello_types.h) +list(APPEND generated_sources ${gen_dir}/gen-cpp/Hello.cpp) +list(APPEND generated_sources ${gen_dir}/gen-cpp/Hello.h) +list(APPEND app_sources ${generated_sources}) + +thrift( + app + cpp + :no_skeleton + ${gen_dir} + ${ZEPHYR_BASE}/samples/modules/thrift/hello/hello.thrift + "" + ${generated_sources} +) + +target_sources(app PRIVATE ${app_sources}) + +# needed because std::iterator was deprecated with -std=c++17 +target_compile_options(app PRIVATE -Wno-deprecated-declarations) + +# convert .pem files to array data at build time +zephyr_include_directories(${gen_dir}) + +generate_inc_file_for_target( + app + ${ZEPHYR_BASE}/samples/modules/thrift/hello/qemu-cert.pem + ${gen_dir}/qemu_cert.pem.inc + ) + +generate_inc_file_for_target( + app + ${ZEPHYR_BASE}/samples/modules/thrift/hello/qemu-key.pem + ${gen_dir}/qemu_key.pem.inc + ) + +generate_inc_file_for_target( + app + ${ZEPHYR_BASE}/samples/modules/thrift/hello/native-cert.pem + ${gen_dir}/native_cert.pem.inc + ) + +generate_inc_file_for_target( + app + ${ZEPHYR_BASE}/samples/modules/thrift/hello/native-key.pem + ${gen_dir}/native_key.pem.inc + ) diff --git a/samples/modules/thrift/hello/client/Kconfig b/samples/modules/thrift/hello/client/Kconfig new file mode 100644 index 00000000000000..8a15c50347e29d --- /dev/null +++ b/samples/modules/thrift/hello/client/Kconfig @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2022 Meta + +source "Kconfig.zephyr" + +config THRIFT_COMPACT_PROTOCOL + bool "Use TCompactProtocol in samples" + depends on THRIFT + help + Enable this option to use TCompactProtocol in samples diff --git a/samples/modules/thrift/hello/client/Makefile b/samples/modules/thrift/hello/client/Makefile new file mode 100644 index 00000000000000..dabdf64c0ca74c --- /dev/null +++ b/samples/modules/thrift/hello/client/Makefile @@ -0,0 +1,44 @@ +# Copyright 2022 Meta +# SPDX-License-Identifier: Apache-2.0 + +.PHONY: all clean + +CXXFLAGS := +CXXFLAGS += -std=c++17 + +GEN_DIR = gen-cpp +GENSRC = $(GEN_DIR)/Hello.cpp $(GEN_DIR)/Hello.h $(GEN_DIR)/hello_types.h +GENHDR = $(filter %.h, $(GENSRC)) +GENOBJ = $(filter-out %.h, $(GENSRC:.cpp=.o)) + +THRIFT_FLAGS := +THRIFT_FLAGS += $(shell pkg-config --cflags thrift) +THRIFT_FLAGS += -I$(GEN_DIR) +THRIFT_LIBS = $(shell pkg-config --libs thrift) + +all: hello_client hello_client_compact hello_client_ssl hello_client_py.stamp + +hello_client.stamp: ../hello.thrift + thrift --gen cpp:no_skeleton $< + +$(GENSRC): hello_client.stamp + touch $@ + +%.o: %.cpp $(GENHDR) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(THRIFT_FLAGS) -o $@ -c $< + +hello_client: src/main.cpp $(GENOBJ) $(GENHDR) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(THRIFT_FLAGS) -o $@ $< $(GENOBJ) $(THRIFT_LIBS) + +hello_client_compact: src/main.cpp $(GENOBJ) $(GENHDR) + $(CXX) -DCONFIG_THRIFT_COMPACT_PROTOCOL=1 $(CPPFLAGS) $(CXXFLAGS) $(THRIFT_FLAGS) -o $@ $< $(GENOBJ) $(THRIFT_LIBS) + +hello_client_ssl: src/main.cpp $(GENOBJ) $(GENHDR) + $(CXX) -DCONFIG_THRIFT_SSL_SOCKET=1 $(CPPFLAGS) $(CXXFLAGS) $(THRIFT_FLAGS) -o $@ $< $(GENOBJ) $(THRIFT_LIBS) + +hello_client_py.stamp: ../hello.thrift + thrift --gen py $< + touch $@ + +clean: + rm -Rf hello_client hello_client_compact hello_client_ssl $(GEN_DIR) gen-py *.stamp diff --git a/samples/modules/thrift/hello/client/hello_client.py b/samples/modules/thrift/hello/client/hello_client.py new file mode 100755 index 00000000000000..06422347ff033e --- /dev/null +++ b/samples/modules/thrift/hello/client/hello_client.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023, Meta +# +# SPDX-License-Identifier: Apache-2.0 + +"""Thrift Hello Client Sample + +Connect to a hello service and demonstrate the +ping(), echo(), and counter() Thrift RPC methods. + +Usage: + ./hello_client.py [ip] +""" + +import argparse +import sys +sys.path.append('gen-py') + +from thrift.protocol import TBinaryProtocol +from thrift.transport import TTransport +from thrift.transport import TSocket +from hello import Hello + + +def parse_args(): + parser = argparse.ArgumentParser(allow_abbrev=False) + parser.add_argument('--ip', default='192.0.2.1', + help='IP address of hello server') + + return parser.parse_args() + + +def main(): + args = parse_args() + + transport = TSocket.TSocket(args.ip, 4242) + transport = TTransport.TBufferedTransport(transport) + protocol = TBinaryProtocol.TBinaryProtocol(transport) + client = Hello.Client(protocol) + + transport.open() + + client.ping() + client.echo('Hello, world!') + + # necessary to mitigate unused variable warning with for i in range(5) + i = 0 + while i < 5: + client.counter() + i = i + 1 + + transport.close() + + +if __name__ == '__main__': + main() diff --git a/samples/modules/thrift/hello/client/prj.conf b/samples/modules/thrift/hello/client/prj.conf new file mode 100644 index 00000000000000..83026931ad210c --- /dev/null +++ b/samples/modules/thrift/hello/client/prj.conf @@ -0,0 +1,72 @@ +# CONFIG_LIB_CPLUSPLUS Dependencies +CONFIG_NEWLIB_LIBC=y +CONFIG_NEWLIB_LIBC_NANO=n + +# CONFIG_THRIFT Dependencies +CONFIG_CPP=y +CONFIG_STD_CPP17=y +CONFIG_CPP_EXCEPTIONS=y +CONFIG_EXTERNAL_LIBCPP=y +CONFIG_POSIX_API=y +CONFIG_NETWORKING=y +CONFIG_NET_SOCKETS=y +CONFIG_NET_SOCKETPAIR=y +CONFIG_HEAP_MEM_POOL_SIZE=16384 +CONFIG_EVENTFD=y + +CONFIG_THRIFT=y + +CONFIG_TEST_RANDOM_GENERATOR=y +# pthread_cond_wait() triggers sentinel for some reason +CONFIG_STACK_SENTINEL=n + +# Generic networking options +CONFIG_NETWORKING=y +CONFIG_NET_UDP=y +CONFIG_NET_TCP=y +CONFIG_NET_IPV6=n +CONFIG_NET_IPV4=y +CONFIG_NET_SOCKETS=y +CONFIG_POSIX_MAX_FDS=6 +CONFIG_NET_CONNECTION_MANAGER=y + +# Kernel options +CONFIG_ENTROPY_GENERATOR=y +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_INIT_STACKS=y + +# Logging +CONFIG_NET_LOG=y +CONFIG_LOG=y +CONFIG_NET_STATISTICS=y +CONFIG_PRINTK=y + +# Network buffers +CONFIG_NET_PKT_RX_COUNT=16 +CONFIG_NET_PKT_TX_COUNT=16 +CONFIG_NET_BUF_RX_COUNT=64 +CONFIG_NET_BUF_TX_COUNT=64 +CONFIG_NET_CONTEXT_NET_PKT_POOL=y + +# IP address options +CONFIG_NET_MAX_CONTEXTS=10 + +# Network application options and configuration +CONFIG_NET_CONFIG_SETTINGS=y +CONFIG_NET_CONFIG_NEED_IPV6=n +CONFIG_NET_CONFIG_NEED_IPV4=y +CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" +CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" + +# Number of socket descriptors might need adjusting +# if there are more than 1 handlers defined. +CONFIG_POSIX_MAX_FDS=16 + +# Some platforms require relatively large stack sizes. +# This can be tuned per-board. +CONFIG_MAIN_STACK_SIZE=8192 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=8192 +CONFIG_NET_TCP_WORKQ_STACK_SIZE=4096 +CONFIG_NET_MGMT_EVENT_STACK_SIZE=4096 +CONFIG_IDLE_STACK_SIZE=4096 +CONFIG_NET_RX_STACK_SIZE=8192 diff --git a/samples/modules/thrift/hello/client/sample.yaml b/samples/modules/thrift/hello/client/sample.yaml new file mode 100644 index 00000000000000..abe77def017924 --- /dev/null +++ b/samples/modules/thrift/hello/client/sample.yaml @@ -0,0 +1,16 @@ +sample: + description: Hello Thrift client sample + name: hello thrift client +common: + tags: thrift cpp sample + build_only: true + modules: + - thrift + platform_allow: mps2_an385 qemu_x86_64 +tests: + sample.thrift.hello.server.binaryProtocol: {} + sample.thrift.hello.server.compactProtocol: + extra_configs: + - CONFIG_THRIFT_COMPACT_PROTOCOL=y + sample.thrift.hello.server.tlsTransport: + extra_args: OVERLAY_CONFIG="../overlay-tls.conf" diff --git a/samples/modules/thrift/hello/client/src/main.cpp b/samples/modules/thrift/hello/client/src/main.cpp new file mode 100644 index 00000000000000..bc79c6fbf4031f --- /dev/null +++ b/samples/modules/thrift/hello/client/src/main.cpp @@ -0,0 +1,130 @@ +/* + * Copyright 2022 Young Mei + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifdef __ZEPHYR__ +#include +#endif + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "Hello.h" + +using namespace apache::thrift; +using namespace apache::thrift::protocol; +using namespace apache::thrift::transport; + +#ifndef IS_ENABLED +#define IS_ENABLED(flag) flag +#endif + +#ifndef CONFIG_THRIFT_COMPACT_PROTOCOL +#define CONFIG_THRIFT_COMPACT_PROTOCOL 0 +#endif + +#ifndef CONFIG_THRIFT_SSL_SOCKET +#define CONFIG_THRIFT_SSL_SOCKET 0 +#endif + +#ifdef __ZEPHYR__ +int main(void) +#else +int main(int argc, char **argv) +#endif +{ + std::string my_addr; + +#ifdef __ZEPHYR__ + my_addr = CONFIG_NET_CONFIG_PEER_IPV4_ADDR; +#else + if (IS_ENABLED(CONFIG_THRIFT_SSL_SOCKET)) { + if (argc != 5) { + printf("usage: %s " + "\n", + argv[0]); + return EXIT_FAILURE; + } + } + + if (argc >= 2) { + my_addr = std::string(argv[1]); + } else { + my_addr = "192.0.2.1"; + } +#endif + + int port = 4242; + std::shared_ptr protocol; + std::shared_ptr transport; + std::shared_ptr socketFactory; + std::shared_ptr trans; + + if (IS_ENABLED(CONFIG_THRIFT_SSL_SOCKET)) { + const int port = 4242; + socketFactory = std::make_shared(); + socketFactory->authenticate(true); + +#ifdef __ZEPHYR__ + static const char qemu_cert_pem[] = { +#include "qemu_cert.pem.inc" + }; + + static const char qemu_key_pem[] = { +#include "qemu_key.pem.inc" + }; + + static const char native_cert_pem[] = { +#include "native_cert.pem.inc" + }; + + socketFactory->loadCertificateFromBuffer(qemu_cert_pem); + socketFactory->loadPrivateKeyFromBuffer(qemu_key_pem); + socketFactory->loadTrustedCertificatesFromBuffer(native_cert_pem); +#else + socketFactory->loadCertificate(argv[2]); + socketFactory->loadPrivateKey(argv[3]); + socketFactory->loadTrustedCertificates(argv[4]); +#endif + trans = socketFactory->createSocket(my_addr, port); + } else { + trans = std::make_shared(my_addr, port); + } + + transport = std::make_shared(trans); + + if (IS_ENABLED(CONFIG_THRIFT_COMPACT_PROTOCOL)) { + protocol = std::make_shared(transport); + } else { + protocol = std::make_shared(transport); + } + + HelloClient client(protocol); + + try { + transport->open(); + client.ping(); + std::string s; + client.echo(s, "Hello, world!"); + for (int i = 0; i < 5; ++i) { + client.counter(); + } + + transport->close(); + } catch (std::exception &e) { + printf("caught exception: %s\n", e.what()); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/samples/modules/thrift/hello/doc/index.rst b/samples/modules/thrift/hello/doc/index.rst new file mode 100644 index 00000000000000..84a784e02189f9 --- /dev/null +++ b/samples/modules/thrift/hello/doc/index.rst @@ -0,0 +1,165 @@ +.. _thrift-hello-sample: + +Hello Sample Application +######################## + +Overview +******** + +This sample application includes a client a server implementing the RPC +interface described in ``thrift/hello.thrift``. The purpose of this +example is to demonstrate how components at different layer in thrift can +be combined to build an application with desired features. + + +Requirements +************ + +- QEMU Networking (described in :ref:`networking_with_qemu`) +- Thrift dependencies installed for your host OS e.g. in Ubuntu + +.. code-block:: console + :caption: Install additional dependencies in Ubuntu + + sudo apt install -y libboost-all-dev thrift-compiler libthrift-dev + +Building and Running +******************** + +This application can be run on a Linux host, with either the server or the +client in the QEMU environment, and the peer is built and run natively on +the host. + +Building the Native Client and Server +===================================== + +.. code-block:: console + + $ make -j -C client/ + $ make -j -C server/ + +Under ``client/``, 3 executables will be generated, and components +used in each layer of them are listed below: + ++----------------------+------------+--------------------+------------------+ +| hello_client | TSocket | TBufferedTransport | TBinaryProtocol | ++----------------------+------------+--------------------+------------------+ +| hello_client_compact | TSocket | TBufferedTransport | TCompactProtocol | ++----------------------+------------+--------------------+------------------+ +| hello_client_ssl | TSSLSocket | TBufferedTransport | TBinaryProtocol | ++----------------------+------------+--------------------+------------------+ + +The same applies for the server. Only the client and the server with the +same set of stacks can communicate. + +Additionally, there is a ``hello_client.py`` Python script that can be used +interchangeably with the ``hello_client`` C++ application to illustrate the +cross-language capabilities of Thrift. + ++----------------------+------------+--------------------+------------------+ +| hello_client.py | TSocket | TBufferedTransport | TBinaryProtocol | ++----------------------+------------+--------------------+------------------+ + +Running the Zephyr Server in QEMU +================================= + +Build the Zephyr version of the ``hello/server`` sample application like this: + +.. zephyr-app-commands:: + :zephyr-app: samples/modules/thrift/hello/server + :board: board_name + :goals: build + :compact: + +To enable advanced features, extra arguments should be passed accordingly: + +- TCompactProtocol: ``-DCONFIG_THRIFT_COMPACT_PROTOCOL=y`` +- TSSLSocket: ``-DCONF_FILE="prj.conf ../overlay-tls.conf"`` + +For example, to build for ``qemu_x86_64`` with TSSLSocket support: + +.. zephyr-app-commands:: + :zephyr-app: samples/modules/thrift/hello/server + :host-os: unix + :board: qemu_x86_64 + :conf: "prj.conf ../overlay-tls.conf" + :goals: run + :compact: + +In another terminal, run the ``hello_client`` sample app compiled for the +host OS: + +.. code-block:: console + + $ ./hello_client 192.0.2.1 + $ ./hello_client_compact 192.0.2.1 + $ ./hello_client_ssl 192.0.2.1 ../native-cert.pem ../native-key.pem ../qemu-cert.pem + +You should observe the following in the original ``hello/server`` terminal: + +.. code-block:: console + + ping + echo: Hello, world! + counter: 1 + counter: 2 + counter: 3 + counter: 4 + counter: 5 + +In the client terminal, run ``hello_client.py`` app under the host OS (not +described for compact or ssl variants for brevity): + +.. code-block:: console + + $ ./hello_client.py + +You should observe the following in the original ``hello/server`` terminal. +Note that the server's state is not discarded (the counter continues to +increase). + +.. code-block:: console + + ping + echo: Hello, world! + counter: 6 + counter: 7 + counter: 8 + counter: 9 + counter: 10 + +Running the Zephyr Client in QEMU +================================= + +In another terminal, run the ``hello_server`` sample app compiled for the +host OS: + +.. code-block:: console + + $ ./hello_server 0.0.0.0 + $ ./hello_server_compact 0.0.0.0 + $ ./hello_server_ssl 0.0.0.0 ../native-cert.pem ../native-key.pem ../qemu-cert.pem + + +Then, in annother terminal, run the corresponding ``hello/client`` sample: + +.. zephyr-app-commands:: + :zephyr-app: samples/modules/thrift/hello/client + :board: qemu_x86_64 + :goals: run + :compact: + +The additional arguments for advanced features are the same as +``hello/server``. + +You should observe the following in the original ``hello_server`` terminal: + +.. code-block:: console + + ping + echo: Hello, world! + counter: 1 + counter: 2 + counter: 3 + counter: 4 + counter: 5 diff --git a/samples/modules/thrift/hello/hello.thrift b/samples/modules/thrift/hello/hello.thrift new file mode 100644 index 00000000000000..ba094466d10740 --- /dev/null +++ b/samples/modules/thrift/hello/hello.thrift @@ -0,0 +1,11 @@ +/* + * Copyright 2022 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +service Hello { + void ping(); + string echo(1: string msg); + i32 counter(); +} diff --git a/samples/modules/thrift/hello/native-cert.pem b/samples/modules/thrift/hello/native-cert.pem new file mode 100644 index 00000000000000..3adf82b166c019 --- /dev/null +++ b/samples/modules/thrift/hello/native-cert.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkzCCAnugAwIBAgIUaGlOEAH7p7FyprSNEHTH3Yy3+8owDQYJKoZIhvcNAQEL +BQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJMTkyLjAuMi4yMB4X +DTIyMDgwOTA3NDgzOVoXDTQ5MTIyNTA3NDgzOVowWTELMAkGA1UEBhMCQVUxEzAR +BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5 +IEx0ZDESMBAGA1UEAwwJMTkyLjAuMi4yMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEA4cg88HTUwqufnmbCfsZ/j+lkuRLMRWVuCyZ6d4AapIwHanHhdAhj +jejPbEnSMacxiYUVhuKMjMWw1sUMKTwu9MA2wk6jCvewEhnCymaZY0IHE1SCY8/B +Zik70ds/0D8OtUB53xgR5el/ntUUJgmczW5ZIKmpcW86OR0rzUs9j6I8MF3Tp4qK +PSFBuWMC+nXkPuX0l631dtk76DZabOqST3Hiqi4dDV+TaOO5KmN2k6E/iw7p7X4F +ddt9JJIlErV9DZqaKvymdQXlhymohBQHPE909J9z0HEkVqBHRgiMvUyo2hYOqLya +qe+eWvJIEvF/bpEHcESm1v+txagk+BulyQIDAQABo1MwUTAdBgNVHQ4EFgQU7PKo +jr9k+KBC/hmnAUKqsfpgZSowHwYDVR0jBBgwFoAU7PKojr9k+KBC/hmnAUKqsfpg +ZSowDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAVwUrUMLZbrAi +VAS72zpvedGN912bkzgP3vsDbW/F4jbwq+NcVFoqtgUiJrjbhPa52qig6bzNtllX +fVIAjh/pCB+PYDDXotO3mk79Sofy3W2qNrlFQNJsqJpDkY/yF2Dg8FdKao6oPwSs +ldb6REFy6V7I9pdy4Emq+ObW6btzEBByky5TrwUf44ZwSuhxKB2R+jqZHM7BNsnH +QnGUia/qGF1plSUqFzsdq9AwQ6H9v2SLwPDOqEGLDV1Jvwoe0svp+SaaBxY1aGHD +Mg5Z6Uh5cHYlJLCC7WsfTlH+9HZ9ALg0Gww1twlYXyaMw4R480YtSPZC4Wv0jy35 +Sbw6IAbCTg== +-----END CERTIFICATE----- diff --git a/samples/modules/thrift/hello/native-key.pem b/samples/modules/thrift/hello/native-key.pem new file mode 100644 index 00000000000000..b6c67e03b8445f --- /dev/null +++ b/samples/modules/thrift/hello/native-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDhyDzwdNTCq5+e +ZsJ+xn+P6WS5EsxFZW4LJnp3gBqkjAdqceF0CGON6M9sSdIxpzGJhRWG4oyMxbDW +xQwpPC70wDbCTqMK97ASGcLKZpljQgcTVIJjz8FmKTvR2z/QPw61QHnfGBHl6X+e +1RQmCZzNblkgqalxbzo5HSvNSz2PojwwXdOnioo9IUG5YwL6deQ+5fSXrfV22Tvo +Nlps6pJPceKqLh0NX5No47kqY3aToT+LDuntfgV1230kkiUStX0Nmpoq/KZ1BeWH +KaiEFAc8T3T0n3PQcSRWoEdGCIy9TKjaFg6ovJqp755a8kgS8X9ukQdwRKbW/63F +qCT4G6XJAgMBAAECggEAXbZQQNelJWW5mzP4n0kBUjijs0NvoJAgdCVU6Hu10z1B +qLc6xf/jXlfWnBIp2a0VHQitbi5i+tzk8MeZrBXMQY70S4L7Hka/AExL8tlR6gZS +TH4jnozxL1eG+iv/2Q4LK0TnMKdbamuXqlOziLQtroCSIsH4z9nEN0d50jxcAVyj +/WUFdWztYbrZFT2m16zQcic2/GyGGDTDkcmpu3+FGhbCDz22W/3iXS57Vhtd9Ety +9VnxA0cDC7O2X3GuQyCaCSmepC+hdZlJTiW16jto1IPYXm38cVn8WETcRpazmtfW +0wtMSFinUZpGpbEBPEvhIVE5Yaor+07qzGIuEwKrXwKBgQDx7b6bzxqk6TAt7oH/ +ub6X4u1tarfM9e/T8R4CfEo9sLvZjaiwKIclCueTjdRUJOogMoZCcZRdD0+NCg5h +JR4FmCwpSB1iaiRDYmPJr7hwlqmwah/t90DKdPwY9uQn//TlWoUwDWtBZ7TwB/HN +LTfyO2tTMUeNCp8VYV8z8Fe0dwKBgQDu6hN9opKpqyTm8Aqwiy+LbKCQg9YwI3zV +3B7KP1buaa4WHiWTWd86Ns6wwFRQSr3jAexNQaDvH8MhI696iBaEVLAvYFmGomLR +V3dpudap143AV0wwvniUn78ewyLPg7V5fUcetcX8QlKLp0wGWuYAZqgJ3uA2Kf3v +qgIi7BlHvwKBgCKNYfu+yH9lDoyA0/BCBwaKUn6eD0ImneoXNcIFHlVROIMJyF3g +a+zOceSRDRI3c3jFvoce0aG43hO2q/cT5gXGhggfVJMJtcQp+TaE8kKiQfoALi8+ +cPJ5Ysft+wf7dm6LTxpd0EO3HBBsEgzLuIHQGrP3BdEPA0l6bq5sVRphAoGBAJI8 +MGXsBn1XxiSctM5Ow3FBsh4CtC2O6zAzpZ0BnAIeKXJcTX+duOb2+RhzAKiMtyGl +4a+ABjOXa2ZzY0tK1Q12kMjO3r1r07RzJyJNn7khuSALzxTe4QuHpAH+SuZdpcyR +A+EmPeMj7UaRxhT1umZwb1ZrVy2QEmCJ3PjnLqodAoGBALVLa4X2CHHEACculEcC +wDUdaF8penGVV0HP+4DvxLUtcvPohvdyvcoTzqMqkk2QCKRfnImD3aL014Pgv26C +9kO1C8/K+cvwq2Pc6v2fgTHwSqj1DglNEJOctbStpwTDugG+vsymlTaD6xogFunW +SmtskQUnB2GXxqXMzmMIGUYC +-----END PRIVATE KEY----- diff --git a/samples/modules/thrift/hello/overlay-tls.conf b/samples/modules/thrift/hello/overlay-tls.conf new file mode 100644 index 00000000000000..3524f07558adc4 --- /dev/null +++ b/samples/modules/thrift/hello/overlay-tls.conf @@ -0,0 +1,10 @@ +CONFIG_THRIFT_SSL_SOCKET=y + +# TLS configuration +CONFIG_MBEDTLS=y +CONFIG_MBEDTLS_PEM_CERTIFICATE_FORMAT=y +CONFIG_MBEDTLS_ENABLE_HEAP=y +CONFIG_MBEDTLS_HEAP_SIZE=60000 +CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=2048 +CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=6 +CONFIG_NET_SOCKETS_SOCKOPT_TLS=y diff --git a/samples/modules/thrift/hello/qemu-cert.pem b/samples/modules/thrift/hello/qemu-cert.pem new file mode 100644 index 00000000000000..d89973ebb7a986 --- /dev/null +++ b/samples/modules/thrift/hello/qemu-cert.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkzCCAnugAwIBAgIUImw6a5K1bBeocIiUyvyhQLUWKBYwDQYJKoZIhvcNAQEL +BQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJMTkyLjAuMi4xMB4X +DTIyMDgwOTA3NDgwMVoXDTQ5MTIyNTA3NDgwMVowWTELMAkGA1UEBhMCQVUxEzAR +BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5 +IEx0ZDESMBAGA1UEAwwJMTkyLjAuMi4xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAyXtaqbldQrHL61NcMDhR3MTv8cVCFnsVZEgq621vZ5njCnK557LR +gOKJx6Mn+8d0au1RgjIjyhuW0aGRQnnkX8mBXSqFJ+jQYTBAs4i5Jemn+Rsf17Lj +R11eGNjqItS5JqlrKUfY3CfgFoN/YJITmDgIE0d6NbJbq+LkuBuvdf4+bxDp8w/m +gOr2wvGcAGvtaAWsJVaQvXkLlXKwAOR4/ChFLQJexe4KreMwnvaa/0JXRia+4I+U +PWSJUmqcpwebj8oDgXqiQv+6JXF66ZoULVINiiDk9qtAbksm8Vz/QQ8Ll4ML96fZ +ZXM3sie0OSsEdpzfLayYwc3sX7Y8p1f4SQIDAQABo1MwUTAdBgNVHQ4EFgQU5LRU +s0gUR8AEWND35ZbE3QilH5wwHwYDVR0jBBgwFoAU5LRUs0gUR8AEWND35ZbE3Qil +H5wwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAKQm2tMYeFUqb +ep1Teq+zcsjRf3Zt7CUQoYUKwRbxfG+M8f0KtE0XgJ5jntRHMfiw157qGJY2YRPY +DJ1G8TmF//x4+cudixuZlkD0t7J+YQBLjNtvu68FIb+gNuv/GJSBps1C4Q49P8/c +48ulUCvEUjUwJ99yC/v1BajdUdunqgfwVnD3i5cAm1dStLMxeuUMhU7OaMnylkMY +eF+CXzZ7k2Nmr9SlGZR28kiDJF6TdfkVTxL8A5Xyjh/DvRxVYYE0LzmG99Q1qj5S +Q1U4wCHJDm7/sb7GfXrl6abqECWPWi65/77QSsq8LkRkbbpkCvm9MyxKPSMqqUeF +vH7+Xv7oMw== +-----END CERTIFICATE----- diff --git a/samples/modules/thrift/hello/qemu-key.pem b/samples/modules/thrift/hello/qemu-key.pem new file mode 100644 index 00000000000000..d48b0160423bf9 --- /dev/null +++ b/samples/modules/thrift/hello/qemu-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDJe1qpuV1Cscvr +U1wwOFHcxO/xxUIWexVkSCrrbW9nmeMKcrnnstGA4onHoyf7x3Rq7VGCMiPKG5bR +oZFCeeRfyYFdKoUn6NBhMECziLkl6af5Gx/XsuNHXV4Y2Ooi1LkmqWspR9jcJ+AW +g39gkhOYOAgTR3o1slur4uS4G691/j5vEOnzD+aA6vbC8ZwAa+1oBawlVpC9eQuV +crAA5Hj8KEUtAl7F7gqt4zCe9pr/QldGJr7gj5Q9ZIlSapynB5uPygOBeqJC/7ol +cXrpmhQtUg2KIOT2q0BuSybxXP9BDwuXgwv3p9llczeyJ7Q5KwR2nN8trJjBzexf +tjynV/hJAgMBAAECggEACB/IddgILeiH6bGsjF2KVX3TvrAJcb5y9skfK+uM0VoH +6N5b5ym+H2A4azDwa4tXwyOrGfYbcdU/dVf6Xg/BWOhskN0Q+J0/YRqGPVxZujDh +VEmBn5uyZOiw+Devkd8ke8Mwk5NL/Vfr8KnK5idgZrlPAAytiEKXG4efA9p1Q9YT +N+vBh+S36uP74Y1S/gpZaVo4igd03htqZ87s+h32l4rWM/KznbUCza4tl/Kz4oaZ +SddfQ1IcU4xbU5W+r405XEQcK6UgF5+wOTEyuh5ECVblQFnvLrQELinokj2/Xbvd +zx214mxYxjff9tmt4gZcWHFAaHQfV2e28sGdQzglgQKBgQDmrruc1IOBKSfW5Xw7 +O60zpPa0gCbweh21+amAan0V0u4NLXcEp6BhDdO00Fkuw8hNNLRlGxMtIvLX/RuB +ZKstE/PPyq9O1vJBv3KoTg4uF71ic1LRb77fZrrl9xuuo6beS8agodPqlsxmREa7 +sSfP2Z1t2la8loxz4TefiWW2iQKBgQDfmDJ6uZCB1GKaSYjtIRDldxyjIUZvFbm4 +vQGQS/xJvSmMdCBbBfenHshgCDoPvCslB4aSPzi0ihUwdoWpQ+dVoNJTONxJzJwV +wEAC3GvLQYMTpEGzht8u2ullde76G33GoFSDSF9ErCZUALosjrzlHTwRjYnBo4Mu +pV4eUufDwQKBgCItlWKBIhLK9DokuilUiC70rBDGQ/6xOSGzIegC3xGStO6C4/Vu +mJaIo+tQS0Zgf5bgzjGEt2yilvRlbePX9HyzThZlY1/8/Nu879H77qHppoelqomZ +UuBqqhpUaGeRm7Gn7H/0Oh+xxAsK5qf8cXecOHUEOoGqlJi+r60VgFpxAoGABria +e9nsIBr0Q9MGDKq7yUoFUFoFtf0fMhBsZZwDH2xSPWiYOGQ7h4iDWW+l3yc23MwX +HXpNCBBGhshpSCdEYuyMpffFl2pRHs5CnlNl4hw8BnEfkHfzaYMnFOewoVAGPdw/ +7hpU0smh9VB4SDKaNwDj91sb0vhJTzOlWp//W4ECgYEAt24lSRSlKxh7RzSiXwnu +hcd92nw2fVPwIWMy/X3UY8GD1V9O1qXcBIS2IMoWDChr6yPhfZ5GzWMhAb170tDC +5Xyj6v5b3wkADEFbkd7ioBTNi34og6w16wm1MZgiVRHcAGuOarGH5MzRZQBAEmHQ +CJiEUbFAwcg3RFElByRzIx0= +-----END PRIVATE KEY----- diff --git a/samples/modules/thrift/hello/server/CMakeLists.txt b/samples/modules/thrift/hello/server/CMakeLists.txt new file mode 100644 index 00000000000000..44860f78da4b40 --- /dev/null +++ b/samples/modules/thrift/hello/server/CMakeLists.txt @@ -0,0 +1,61 @@ +# Copyright 2022 Meta +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(thrift_hello_server) + +FILE(GLOB app_sources + src/*.cpp +) + +include(${ZEPHYR_BASE}/modules/thrift/cmake/thrift.cmake) + +set(generated_sources "") +set(gen_dir ${ZEPHYR_BINARY_DIR}/misc/generated/thrift_hello) +list(APPEND generated_sources ${gen_dir}/gen-cpp/hello_types.h) +list(APPEND generated_sources ${gen_dir}/gen-cpp/Hello.cpp) +list(APPEND generated_sources ${gen_dir}/gen-cpp/Hello.h) +list(APPEND app_sources ${generated_sources}) + +thrift( + app + cpp + :no_skeleton + ${gen_dir} + ${ZEPHYR_BASE}/samples/modules/thrift/hello/hello.thrift + "" + ${generated_sources} +) + +target_sources(app PRIVATE ${app_sources}) + +# needed because std::iterator was deprecated with -std=c++17 +target_compile_options(app PRIVATE -Wno-deprecated-declarations) + +# convert .pem files to array data at build time +zephyr_include_directories(${gen_dir}) + +generate_inc_file_for_target( + app + ${ZEPHYR_BASE}/samples/modules/thrift/hello/qemu-cert.pem + ${gen_dir}/qemu_cert.pem.inc + ) + +generate_inc_file_for_target( + app + ${ZEPHYR_BASE}/samples/modules/thrift/hello/qemu-key.pem + ${gen_dir}/qemu_key.pem.inc + ) + +generate_inc_file_for_target( + app + ${ZEPHYR_BASE}/samples/modules/thrift/hello/native-cert.pem + ${gen_dir}/native_cert.pem.inc + ) + +generate_inc_file_for_target( + app + ${ZEPHYR_BASE}/samples/modules/thrift/hello/native-key.pem + ${gen_dir}/native_key.pem.inc + ) diff --git a/samples/modules/thrift/hello/server/Kconfig b/samples/modules/thrift/hello/server/Kconfig new file mode 100644 index 00000000000000..8a15c50347e29d --- /dev/null +++ b/samples/modules/thrift/hello/server/Kconfig @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright (c) 2022 Meta + +source "Kconfig.zephyr" + +config THRIFT_COMPACT_PROTOCOL + bool "Use TCompactProtocol in samples" + depends on THRIFT + help + Enable this option to use TCompactProtocol in samples diff --git a/samples/modules/thrift/hello/server/Makefile b/samples/modules/thrift/hello/server/Makefile new file mode 100644 index 00000000000000..20fc9bf625c3df --- /dev/null +++ b/samples/modules/thrift/hello/server/Makefile @@ -0,0 +1,40 @@ +# Copyright 2022 Meta +# SPDX-License-Identifier: Apache-2.0 + +.PHONY: all clean + +CXXFLAGS := +CXXFLAGS += -std=c++17 + +GEN_DIR = gen-cpp +GENSRC = $(GEN_DIR)/Hello.cpp $(GEN_DIR)/Hello.h $(GEN_DIR)/hello_types.h +GENHDR = $(filter %.h, $(GENSRC)) +GENOBJ = $(filter-out %.h, $(GENSRC:.cpp=.o)) + +THRIFT_FLAGS := +THRIFT_FLAGS += $(shell pkg-config --cflags thrift) +THRIFT_FLAGS += -I$(GEN_DIR) +THRIFT_LIBS := +THRIFT_LIBS = $(shell pkg-config --libs thrift) + +all: hello_server hello_server_compact hello_server_ssl + +hello_server.stamp: ../hello.thrift + thrift --gen cpp:no_skeleton $< + +$(GENSRC): hello_server.stamp + +%.o: %.cpp $(GENHDR) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(THRIFT_FLAGS) -o $@ -c $< + +hello_server: src/main.cpp $(GENOBJ) $(GENHDR) + $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(THRIFT_FLAGS) -o $@ $< $(GENOBJ) $(THRIFT_LIBS) + +hello_server_compact: src/main.cpp $(GENOBJ) $(GENHDR) + $(CXX) -DCONFIG_THRIFT_COMPACT_PROTOCOL=1 $(CPPFLAGS) $(CXXFLAGS) $(THRIFT_FLAGS) -o $@ $< $(GENOBJ) $(THRIFT_LIBS) + +hello_server_ssl: src/main.cpp $(GENOBJ) $(GENHDR) + $(CXX) -DCONFIG_THRIFT_SSL_SOCKET=1 $(CPPFLAGS) $(CXXFLAGS) $(THRIFT_FLAGS) -o $@ $< $(GENOBJ) $(THRIFT_LIBS) + +clean: + rm -Rf hello_server hello_server_compact hello_server_ssl $(GEN_DIR) diff --git a/samples/modules/thrift/hello/server/prj.conf b/samples/modules/thrift/hello/server/prj.conf new file mode 100644 index 00000000000000..20f6631202a0ff --- /dev/null +++ b/samples/modules/thrift/hello/server/prj.conf @@ -0,0 +1,65 @@ +# Need a full libc++ +CONFIG_NEWLIB_LIBC=y +CONFIG_NEWLIB_LIBC_NANO=n + +# CONFIG_THRIFT Dependencies +CONFIG_CPP=y +CONFIG_STD_CPP17=y +CONFIG_CPP_EXCEPTIONS=y +CONFIG_EXTERNAL_LIBCPP=y +CONFIG_POSIX_API=y +CONFIG_NET_SOCKETPAIR=y +CONFIG_HEAP_MEM_POOL_SIZE=16384 +CONFIG_EVENTFD=y + +CONFIG_THRIFT=y + +# Generic networking options +CONFIG_NETWORKING=y +CONFIG_NET_UDP=y +CONFIG_NET_TCP=y +CONFIG_NET_IPV6=n +CONFIG_NET_IPV4=y +CONFIG_NET_SOCKETS=y +CONFIG_NET_CONNECTION_MANAGER=y + +# Kernel options +CONFIG_ENTROPY_GENERATOR=y +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_INIT_STACKS=y + +# Logging +CONFIG_NET_LOG=y +CONFIG_LOG=y +CONFIG_NET_STATISTICS=y +CONFIG_PRINTK=y + +# Network buffers +CONFIG_NET_PKT_RX_COUNT=16 +CONFIG_NET_PKT_TX_COUNT=16 +CONFIG_NET_BUF_RX_COUNT=64 +CONFIG_NET_BUF_TX_COUNT=64 +CONFIG_NET_CONTEXT_NET_PKT_POOL=y + +# IP address options +CONFIG_NET_MAX_CONTEXTS=10 + +# Network application options and configuration +CONFIG_NET_CONFIG_SETTINGS=y +CONFIG_NET_CONFIG_NEED_IPV6=n +CONFIG_NET_CONFIG_NEED_IPV4=y +CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" +CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" + +# Number of socket descriptors might need adjusting +# if there are more than 1 handlers defined. +CONFIG_POSIX_MAX_FDS=16 + +# Some platforms require relatively large stack sizes. +# This can be tuned per-board. +CONFIG_MAIN_STACK_SIZE=8192 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=8192 +CONFIG_NET_TCP_WORKQ_STACK_SIZE=4096 +CONFIG_NET_MGMT_EVENT_STACK_SIZE=4096 +CONFIG_IDLE_STACK_SIZE=4096 +CONFIG_NET_RX_STACK_SIZE=8192 diff --git a/samples/modules/thrift/hello/server/sample.yaml b/samples/modules/thrift/hello/server/sample.yaml new file mode 100644 index 00000000000000..c56bee25560741 --- /dev/null +++ b/samples/modules/thrift/hello/server/sample.yaml @@ -0,0 +1,16 @@ +sample: + description: Hello Thrift server sample + name: hello thrift server +common: + tags: thrift cpp sample + build_only: true + modules: + - thrift + platform_allow: mps2_an385 qemu_x86_64 +tests: + sample.thrift.hello.server.binaryProtocol: {} + sample.thrift.hello.server.compactProtocol: + extra_configs: + - CONFIG_THRIFT_COMPACT_PROTOCOL=y + sample.thrift.hello.server.tlsTransport: + extra_args: OVERLAY_CONFIG="../overlay-tls.conf" diff --git a/samples/modules/thrift/hello/server/src/HelloHandler.h b/samples/modules/thrift/hello/server/src/HelloHandler.h new file mode 100644 index 00000000000000..24c05f668f2fe4 --- /dev/null +++ b/samples/modules/thrift/hello/server/src/HelloHandler.h @@ -0,0 +1,46 @@ +/* + * Copyright 2022 Meta + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __ZEPHYR__ +#include +#else +#define printk printf +#endif + +#include + +#include "Hello.h" + +class HelloHandler : virtual public HelloIf +{ +public: + HelloHandler() : count(0) + { + } + + void ping() + { + printk("%s\n", __func__); + } + + void echo(std::string &_return, const std::string &msg) + { + printk("%s: %s\n", __func__, msg.c_str()); + _return = msg; + } + + int32_t counter() + { + ++count; + printk("%s: %d\n", __func__, count); + return count; + } + +protected: + int count; +}; diff --git a/samples/modules/thrift/hello/server/src/main.cpp b/samples/modules/thrift/hello/server/src/main.cpp new file mode 100644 index 00000000000000..f81db2ad366b08 --- /dev/null +++ b/samples/modules/thrift/hello/server/src/main.cpp @@ -0,0 +1,124 @@ +/* + * Copyright 2022 Young Mei + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifdef __ZEPHYR__ +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "Hello.h" +#include "HelloHandler.h" + +using namespace ::apache::thrift; +using namespace ::apache::thrift::protocol; +using namespace ::apache::thrift::transport; +using namespace ::apache::thrift::server; + +#ifndef IS_ENABLED +#define IS_ENABLED(flag) flag +#endif + +#ifndef CONFIG_THRIFT_COMPACT_PROTOCOL +#define CONFIG_THRIFT_COMPACT_PROTOCOL 0 +#endif + +#ifndef CONFIG_THRIFT_SSL_SOCKET +#define CONFIG_THRIFT_SSL_SOCKET 0 +#endif + +#ifdef __ZEPHYR__ +int main(void) +#else +int main(int argc, char **argv) +#endif +{ + std::string my_addr; + +#ifdef __ZEPHYR__ + my_addr = CONFIG_NET_CONFIG_MY_IPV4_ADDR; +#else + if (IS_ENABLED(CONFIG_THRIFT_SSL_SOCKET)) { + if (argc != 5) { + printf("usage: %s " + "\n", + argv[0]); + return EXIT_FAILURE; + } + } else { + if (argc != 2) { + printf("usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + } + + my_addr = std::string(argv[1]); +#endif + + const int port = 4242; + std::shared_ptr serverTransport; + std::shared_ptr transportFactory; + std::shared_ptr protocolFactory; + std::shared_ptr handler(new HelloHandler()); + std::shared_ptr processor(new HelloProcessor(handler)); + + if (IS_ENABLED(CONFIG_THRIFT_SSL_SOCKET)) { + std::shared_ptr socketFactory(new TSSLSocketFactory()); + socketFactory->server(true); +#ifdef __ZEPHYR__ + static const char qemu_cert_pem[] = { +#include "qemu_cert.pem.inc" + }; + + static const char qemu_key_pem[] = { +#include "qemu_key.pem.inc" + }; + + static const char native_cert_pem[] = { +#include "native_cert.pem.inc" + }; + + socketFactory->loadCertificateFromBuffer(qemu_cert_pem); + socketFactory->loadPrivateKeyFromBuffer(qemu_key_pem); + socketFactory->loadTrustedCertificatesFromBuffer(native_cert_pem); +#else + socketFactory->loadCertificate(argv[2]); + socketFactory->loadPrivateKey(argv[3]); + socketFactory->loadTrustedCertificates(argv[4]); +#endif + serverTransport = + std::make_shared("0.0.0.0", port, socketFactory); + } else { + serverTransport = std::make_shared(my_addr, port); + } + + transportFactory = std::make_shared(); + if (IS_ENABLED(CONFIG_THRIFT_COMPACT_PROTOCOL)) { + protocolFactory = std::make_shared(); + } else { + protocolFactory = std::make_shared(); + } + + TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory); + + try { + server.serve(); + } catch (std::exception &e) { + printf("caught exception: %s\n", e.what()); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +}