diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 493b42b..717d1cd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,7 +28,6 @@ jobs: uses: actions/checkout@v4 with: path: up-zenoh-example-cpp - repository: eclipse-uprotocol/up-zenoh-example-cpp - name: Fetch up-cpp conan recipe uses: actions/checkout@v4 @@ -39,7 +38,7 @@ jobs: - name: Build up-core-api conan recipe shell: bash run: | - conan create --version 1.6.0 up-conan-recipes/up-core-api/release + conan create --version 1.6.0-alpha2 --build=missing up-conan-recipes/up-core-api/release - name: Build up-cpp conan recipe shell: bash @@ -59,8 +58,98 @@ jobs: cmake --preset conan-release -DCMAKE_EXPORT_COMPILE_COMMANDS=yes cd build/Release cmake --build . -- -j + + - name: Upload compile commands + uses: actions/upload-artifact@v4 + with: + name: compile-commands + path: up-zenoh-example-cpp/build/Release/compile_commands.json + + - name: Save conan cache to archive + shell: bash + run: | + conan cache save --file ./conan-cache.tgz '*' + + - name: Upload conan cache for linting + uses: actions/upload-artifact@v4 + with: + name: conan-cache + path: ./conan-cache.tgz - + lint: + name: Lint C++ sources + runs-on: ubuntu-22.04 + needs: build + permissions: + contents: write + pull-requests: read + steps: + - name: Fetch up-zenoh-example-cpp + uses: actions/checkout@v4 + with: + path: up-zenoh-example-cpp + + - name: Get build commands + uses: actions/download-artifact@v4 + with: + name: compile-commands + + - name: Install Conan + id: conan + uses: turtlebrowser/get-conan@main + with: + version: 2.3.2 + + - name: Install conan CI profile + shell: bash + run: | + conan profile detect + cp up-zenoh-example-cpp/.github/workflows/ci_conan_profile "$(conan profile path default)" + conan profile show + + - name: Get conan cache + uses: actions/download-artifact@v4 + with: + name: conan-cache + + - name: Restore conan cache from archive + shell: bash + run: | + conan cache restore conan-cache.tgz + + - name: Run linters on source + id: source-linter + uses: cpp-linter/cpp-linter-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + repo-root: up-zenoh-example-cpp + ignore: 'test' + style: 'file' # read .clang-format for configuration + tidy-checks: '' # Read .clang-tidy for configuration + database: compile_commands.json + version: 13 + + - name: Run linters on tests + id: test-linter + uses: cpp-linter/cpp-linter-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + repo-root: up-zenoh-example-cpp + ignore: 'src|include' + style: 'file' # read .clang-format for configuration + tidy-checks: '' # Read .clang-tidy for configuration + database: compile_commands.json + version: 13 + + - name: Report lint failure + if: + steps.source-linter.outputs.checks-failed > 0 || + steps.test-linter.outputs.checks-failed > 0 + run: | + exit 1 + # NOTE: In GitHub repository settings, the "Require status checks to pass # before merging" branch protection rule ensures that commits are only merged # from branches where specific status checks have passed. These checks are diff --git a/.github/workflows/ci_conan_profile b/.github/workflows/ci_conan_profile new file mode 100644 index 0000000..73fec78 --- /dev/null +++ b/.github/workflows/ci_conan_profile @@ -0,0 +1,8 @@ +[settings] +arch=x86_64 +build_type=Release +compiler=gcc +compiler.cppstd=gnu17 +compiler.libcxx=libstdc++11 +compiler.version=11 +os=Linux diff --git a/README.md b/README.md index 70f09e0..49dedd0 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,8 @@ C++ Example application and service that utilizes up-client-zenoh-cpp Use the up-conan-recipes repo and compile the following recipes: ``` -$ conan create --version 1.6.0 --build=missing up-core-api/developer -$ conan create --version 1.0.1-rc1 --build=missing up-cpp/developer +$ conan create --version 1.6.0-alpha4 --build=missing up-core-api/release +$ conan create --version 1.0.1-rc1 --build=missing up-cpp/release $ conan create --version 1.0.0-dev --build=missing up-transport-socket-cpp/developer ``` diff --git a/conanfile.txt b/conanfile.txt index ec056ee..7d784f0 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -1,7 +1,7 @@ [requires] -up-cpp/[^1.0.1, include_prerelease] +up-cpp/1.0.1-rc1 spdlog/[~1.13] -up-core-api/1.6.0 +up-core-api/1.6.0-alpha2 protobuf/[>=3.21.12] up-transport-socket-cpp/[>=1.0.0, include_prerelease] diff --git a/lint/clang-format.sh b/lint/clang-format.sh new file mode 100755 index 0000000..de7e641 --- /dev/null +++ b/lint/clang-format.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +PROJECT_ROOT="$(realpath "$(dirname "$0")/../")" + +if [ -n "$(which clang-format-13)" ]; then + # NOTE: Using clang-format-13 in CI system, too + FORMATTER=clang-format-13 +elif [ -n "$(which clang-format)" ]; then + echo "Did not find clang-format-13. Trying clang-format. Results may not" + echo "match formatting in GitHub CI process." + FORMATTER=clang-format +else + echo "Could not find clang-format. Please make sure it is installed" 1>&2 + exit 2 +fi + +echo "Running $FORMATTER on all files in '$PROJECT_ROOT'" +shopt -s globstar + +pushd "$PROJECT_ROOT" > /dev/null +for f in **/*.h **/*.cpp; do + if [[ ! ("$f" =~ "build/") ]]; then + echo + echo "Checking file '$f'" + $FORMATTER -i "$f" + fi +done +popd > /dev/null diff --git a/lint/clang-tidy.sh b/lint/clang-tidy.sh new file mode 100755 index 0000000..e5bfea4 --- /dev/null +++ b/lint/clang-tidy.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +PROJECT_ROOT="$(realpath "$(dirname "$0")/../")" + +if [ -n "$(which clang-tidy-13)" ]; then + # NOTE: Using clang-tidy-13 in CI system, too + LINTER=clang-tidy-13 +elif [ -n "$(which clang-tidy)" ]; then + echo "Did not find clang-tidy-13. Trying clang-tidy. Results may not" + echo "match formatting in GitHub CI process." + LINTER=clang-tidy +else + echo "Could not find clang-tidy. Please make sure it is installed" 1>&2 + exit 2 +fi + +usage() { + echo "$(basename "$0") path/to/compile_commands.json [source_to_lint]" 1>&2 + echo 1>&2 + echo " compile_commands.json" 1>&2 + echo " Produced during a cmake build when configured with the" 1>&2 + echo " -DCMAKE_EXPORT_COMPILE_COMMANDS=yes flag" 1>&2 + echo 1>&2 + echo " source_to_lint (optional)" 1>&2 + echo " Source file to run clang-tidy against. If not specified," 1>&2 + echo " all source files in the repo will be scanned." 1>&2 +} + +if [ "$1" == "-h" ] || [ "$1" == "--help" ] || [ "$1" == "/h" ] || [ "$1" == "/?" ]; then + usage + exit +fi + +compile_database="$1" + +if [ -z "$compile_database" ]; then + echo "No compile database specified. Make sure cmake was configured" 1>&2 + echo "with '-DCMAKE_EXPORT_COMPILE_COMMANDS=yes' and re-run the build" 1>&2 + echo 1>&2 + echo "Usage:" 1>&2 + usage + exit 1 +elif [ ! -f "$compile_database" ]; then + echo "Compile database file not found. Make sure cmake was configured" 1>&2 + echo "with '-DCMAKE_EXPORT_COMPILE_COMMANDS=yes' and re-run the build" 1>&2 + echo 1>&2 + echo "Usage:" 1>&2 + usage + exit 1 +fi + +compile_database="$(realpath "$compile_database")" + +target_source="$2" + +if [ -z "$target_source" ]; then + echo "Running $LINTER on all files in '$PROJECT_ROOT'" + shopt -s globstar + + pushd "$PROJECT_ROOT" > /dev/null + for f in **/*.h **/*.cpp; do + if [[ ! ("$f" =~ "build/") ]]; then + echo + echo "Checking file '$f'" + $LINTER -p "$(dirname "$compile_database")" "$f" + fi + done + popd > /dev/null + exit +fi + +if [ ! -f "$target_source" ]; then + echo "Target source file '$target_source' not found." 1>&2 + echo 1>&2 + echo "Usage:" 1>&2 + usage + exit 1 +fi + +echo "Running $LINTER on '$target_source'" +$LINTER -p "$(dirname "$compile_database")" "$target_source" diff --git a/pubsub/src/UTransportDomainSockets.h b/pubsub/include/UTransportDomainSockets.h similarity index 83% rename from pubsub/src/UTransportDomainSockets.h rename to pubsub/include/UTransportDomainSockets.h index eee63ce..957faa0 100644 --- a/pubsub/src/UTransportDomainSockets.h +++ b/pubsub/include/UTransportDomainSockets.h @@ -9,20 +9,20 @@ // // SPDX-License-Identifier: Apache-2.0 -#ifndef UTRANSPORT_DOMAIN_SOCKETS_H -#define UTRANSPORT_DOMAIN_SOCKETS_H +#ifndef UTRANSPORTDOMAINSOCKETS_H +#define UTRANSPORTDOMAINSOCKETS_H #include #include #include -using namespace uprotocol; +namespace uprotocol::transport { -class UTransportDomainSockets : public transport::UTransport { +class UTransportDomainSockets : public UTransport { public: explicit UTransportDomainSockets(const v1::UUri& uuri); - virtual ~UTransportDomainSockets(); + ~UTransportDomainSockets() override; private: int fdSocket_; // socket handle @@ -44,5 +44,6 @@ class UTransportDomainSockets : public transport::UTransport { void listenThread(); // listen for incoming messages (thread) void cleanupListener(CallableConn listener) override {} }; // class UTransportDomainSockets +} // namespace uprotocol::transport -#endif // UTRANSPORT_DOMAIN_SOCKETS_H \ No newline at end of file +#endif // UTRANSPORTDOMAINSOCKETS_H diff --git a/pubsub/include/common.h b/pubsub/include/common.h index 918314f..53125ee 100644 --- a/pubsub/include/common.h +++ b/pubsub/include/common.h @@ -20,33 +20,37 @@ // SPDX-FileCopyrightText: 2024 General Motors GTO LLC // SPDX-License-Identifier: Apache-2.0 -#ifndef PUBSUB_COMMON_H -#define PUBSUB_COMMON_H +#ifndef COMMON_H +#define COMMON_H #include -uprotocol::v1::UUri getUUri(int const resource_id) { +inline uprotocol::v1::UUri getUUri(int const resource_id) { + constexpr uint32_t PUBSUB_UE_ID = 0x18002; uprotocol::v1::UUri uuri; uuri.set_authority_name("test.app"); - uuri.set_ue_id(0x18002); + uuri.set_ue_id(PUBSUB_UE_ID); uuri.set_ue_version_major(1); uuri.set_resource_id(resource_id); return uuri; } -uprotocol::v1::UUri const& getTimeUUri() { - static auto uuri = getUUri(0x8001); - return uuri; +inline uprotocol::v1::UUri const& getTimeUUri() { + constexpr uint32_t TIME_UURI_RESOURCE_ID = 0x8001; + static auto uuri = getUUri(TIME_UURI_RESOURCE_ID); + return uuri; } -uprotocol::v1::UUri const& getRandomUUri() { - static auto uuri = getUUri(0x8002); - return uuri; +inline uprotocol::v1::UUri const& getRandomUUri() { + constexpr uint32_t RANDOM_UURI_RESOURCE_ID = 0x8002; + static auto uuri = getUUri(RANDOM_UURI_RESOURCE_ID); + return uuri; } -uprotocol::v1::UUri const& getCounterUUri() { - static auto uuri = getUUri(0x8003); - return uuri; +inline uprotocol::v1::UUri const& getCounterUUri() { + constexpr uint32_t COUNTER_UURI_RESOURCE_ID = 0x8003; + static auto uuri = getUUri(COUNTER_UURI_RESOURCE_ID); + return uuri; } -#endif // PUBSUB_COMMON_H +#endif // COMMON_H diff --git a/pubsub/src/UTransportDomainSockets.cpp b/pubsub/src/UTransportDomainSockets.cpp index 0aa3881..3d50633 100644 --- a/pubsub/src/UTransportDomainSockets.cpp +++ b/pubsub/src/UTransportDomainSockets.cpp @@ -19,15 +19,18 @@ #include #include +namespace uprotocol::transport { + UTransportDomainSockets::UTransportDomainSockets(const v1::UUri& uuri) : transport::UTransport(uuri), send_count_(0), + fdSocket_(socket(AF_UNIX, SOCK_STREAM, 0)), fdClient_(-1), stopFlag_(false) { socketPath_ = std::filesystem::canonical("/proc/self/exe") .parent_path() .append(uuri.authority_name()); - fdSocket_ = socket(AF_UNIX, SOCK_STREAM, 0); + if (fdSocket_ == -1) { spdlog::error("Error on socket creation\n"); } @@ -57,26 +60,28 @@ v1::UStatus UTransportDomainSockets::sendImpl(const v1::UMessage& message) { if (fdClient_ == -1) { // Bind the socket, and await client connection - int len = 0; - struct sockaddr_un local; - int nIncomingConnections = 1; + std::size_t len = 0; + struct sockaddr_un local {}; + int n_incoming_connections = 1; local.sun_family = AF_UNIX; - strcpy(local.sun_path, socketPath_.c_str()); - unlink(local.sun_path); - len = strlen(local.sun_path) + sizeof(local.sun_family); - if (bind(fdSocket_, (struct sockaddr*)&local, len) != 0) { + strcpy(static_cast(local.sun_path), socketPath_.c_str()); + unlink(static_cast(local.sun_path)); + len = strlen(static_cast(local.sun_path)) + + sizeof(local.sun_family); + if (bind(fdSocket_, reinterpret_cast(&local), len) != + 0) { spdlog::error("Error on binding socket. Errno={}\n", errno); return retval; } - if (listen(fdSocket_, nIncomingConnections) != 0) { + if (listen(fdSocket_, n_incoming_connections) != 0) { spdlog::error("Error on listen call. Errno={}\n", errno); return retval; } spdlog::info("Waiting for client connection\n"); - fdClient_ = accept(fdSocket_, NULL, NULL); + fdClient_ = accept(fdSocket_, nullptr, nullptr); if (fdClient_ == -1) { spdlog::error("Error on accept call. Errno={}\n", errno); return retval; @@ -84,23 +89,24 @@ v1::UStatus UTransportDomainSockets::sendImpl(const v1::UMessage& message) { } // serialize the message - size_t serializedSize = message.ByteSizeLong(); - std::string serializedMessage(serializedSize, 0); - bool success = - message.SerializeToArray(serializedMessage.data(), serializedSize); + size_t serialized_size = message.ByteSizeLong(); + std::string serialized_message(serialized_size, 0); + bool success = message.SerializeToArray(serialized_message.data(), + static_cast(serialized_size)); spdlog::debug("Serialized message size: {} ; Serialized data: {}", - serializedSize, serializedMessage); + serialized_size, serialized_message); // Send the serialized UMessage spdlog::debug("Sending message number {}", send_count_.load()); // send length of serialized message - if (::send(fdClient_, &serializedSize, sizeof(serializedSize), 0) == -1) { + if (::send(fdClient_, &serialized_size, sizeof(serialized_size), 0) == -1) { spdlog::error("Error sending message size. Errno={}\n", errno); return retval; } // send serialized message - if (::send(fdClient_, serializedMessage.data(), serializedSize, 0) == -1) { + if (::send(fdClient_, serialized_message.data(), serialized_size, 0) == + -1) { spdlog::error("Error sending serialized data. Errno={}\n", errno); return retval; } @@ -113,8 +119,8 @@ v1::UStatus UTransportDomainSockets::sendImpl(const v1::UMessage& message) { v1::UStatus UTransportDomainSockets::registerListenerImpl( CallableConn&& listener, const v1::UUri& source_filter /* topic */, std::optional&& sink_filter) { + (void)std::move(sink_filter); v1::UStatus retval; - // Start the listener thread (if not already started) if (!listener_thread_.joinable()) { listener_thread_ = @@ -132,7 +138,7 @@ v1::UStatus UTransportDomainSockets::registerListenerImpl( size_t hash = std::hash{}( uprotocol::datamodel::serializer::uri::AsString::serialize( source_filter)); - cbListeners_[hash] = listener; + cbListeners_[hash] = std::move(listener); retval.set_code(v1::UCode::OK); return retval; @@ -140,18 +146,21 @@ v1::UStatus UTransportDomainSockets::registerListenerImpl( void UTransportDomainSockets::listenThread() { while (!stopFlag_) { - int data_len; - int connected; - struct sockaddr_un addr; - size_t serializedSize; + std::size_t data_len = 0; + int connected = 0; + struct sockaddr_un addr {}; + size_t serialized_size = 0; addr.sun_family = AF_UNIX; - strcpy(addr.sun_path, socketPath_.c_str()); - data_len = strlen(addr.sun_path) + sizeof(addr.sun_family); + strcpy(static_cast(addr.sun_path), socketPath_.c_str()); + data_len = + strlen(static_cast(addr.sun_path)) + sizeof(addr.sun_family); spdlog::info("Client: Trying to connect..."); - if ((connected = - connect(fdSocket_, (struct sockaddr*)&addr, data_len)) == -1) { + + connected = connect( + fdSocket_, reinterpret_cast(&addr), data_len); + if (connected == -1) { spdlog::info("Client: Error on connect call. Errno = {}", errno); sleep(1); } else { @@ -159,10 +168,10 @@ void UTransportDomainSockets::listenThread() { } while (!stopFlag_ && (connected != -1)) { - v1::UMessage receivedMessage; + v1::UMessage received_message; // receive length of serialized message - if (recv(fdSocket_, &serializedSize, sizeof(serializedSize), 0) == + if (recv(fdSocket_, &serialized_size, sizeof(serialized_size), 0) == -1) { spdlog::error("Error receiving message size. Errno={}\n", errno); @@ -170,22 +179,21 @@ void UTransportDomainSockets::listenThread() { } // receive serialized message - std::string serializedMessage(serializedSize, 0); - if (recv(fdSocket_, serializedMessage.data(), serializedSize, 0) == - -1) { + std::string serialized_message(serialized_size, 0); + if (recv(fdSocket_, serialized_message.data(), serialized_size, + 0) == -1) { spdlog::error("Error receiving serialized data. Errno={}\n", errno); break; } - if (!receivedMessage.ParseFromString(serializedMessage)) { + if (!received_message.ParseFromString(serialized_message)) { spdlog::error("Failed to parse received message"); break; - } else { - spdlog::debug("Received message number {}", send_count_.load()); - send_count_++; - notifyListener(receivedMessage); } + spdlog::debug("Received message number {}", send_count_.load()); + send_count_++; + notifyListener(received_message); } } } @@ -206,3 +214,5 @@ void UTransportDomainSockets::notifyListener(const v1::UMessage& message) { message.attributes().source())); } } + +} // namespace uprotocol::transport diff --git a/pubsub/src/main_pub.cpp b/pubsub/src/main_pub.cpp index e4f4a37..e926ff2 100644 --- a/pubsub/src/main_pub.cpp +++ b/pubsub/src/main_pub.cpp @@ -25,41 +25,43 @@ #include #include #include +#include #include #include #include #include #include +#include #include "UTransportDomainSockets.h" #include "common.h" -using namespace uprotocol::datamodel::builder; -using namespace uprotocol::communication; -using namespace uprotocol::v1; +namespace uprotocol::v1 { -bool gTerminate = false; +bool g_terminate = false; void signalHandler(int signal) { if (signal == SIGINT) { std::cout << "Ctrl+C received. Exiting..." << std::endl; - gTerminate = true; + g_terminate = true; } } int64_t getTime() { - auto currentTime = std::chrono::system_clock::now(); - auto duration = currentTime.time_since_epoch(); - int64_t timeMilli = + auto current_time = std::chrono::system_clock::now(); + auto duration = current_time.time_since_epoch(); + int64_t time_milli = std::chrono::duration_cast(duration).count(); - return timeMilli; + return time_milli; } int32_t getRandom() { - int32_t val = std::rand(); - return val; + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution distribution(0, INT32_MAX); + return distribution(gen); } uint8_t getCounter() { @@ -67,7 +69,11 @@ uint8_t getCounter() { ++counter; return counter; } +} // namespace uprotocol::v1 +using UStatus = uprotocol::v1::UStatus; +using UPayloadFormat = uprotocol::v1::UPayloadFormat; +using UCode = uprotocol::v1::UCode; /* The sample pub applications demonstrates how to send data using uTransport - * There are three topics that are published - random number, current time and a * counter */ @@ -75,8 +81,8 @@ int main(int argc, char** argv) { (void)argc; (void)argv; - signal(SIGINT, signalHandler); - signal(SIGPIPE, signalHandler); + (void)signal(SIGINT, uprotocol::v1::signalHandler); + (void)signal(SIGPIPE, uprotocol::v1::signalHandler); UStatus status; @@ -84,40 +90,44 @@ int main(int argc, char** argv) { auto topic_time = getTimeUUri(); auto topic_random = getRandomUUri(); auto topic_counter = getCounterUUri(); - auto transport = std::make_shared(source); - Publisher publish_time(transport, std::move(topic_time), - UPayloadFormat::UPAYLOAD_FORMAT_TEXT); - Publisher publish_random(transport, std::move(topic_random), - UPayloadFormat::UPAYLOAD_FORMAT_TEXT); - Publisher publish_counter(transport, std::move(topic_counter), - UPayloadFormat::UPAYLOAD_FORMAT_TEXT); - - while (!gTerminate) { + auto transport = + std::make_shared(source); + uprotocol::communication::Publisher publish_time( + transport, std::move(topic_time), + uprotocol::v1::UPayloadFormat::UPAYLOAD_FORMAT_TEXT); + uprotocol::communication::Publisher publish_random( + transport, std::move(topic_random), + UPayloadFormat::UPAYLOAD_FORMAT_TEXT); + uprotocol::communication::Publisher publish_counter( + transport, std::move(topic_counter), + UPayloadFormat::UPAYLOAD_FORMAT_TEXT); + + while (!uprotocol::v1::g_terminate) { // send a string with a time value (ie "15665489") - uint64_t time_val = getTime(); + uint64_t time_val = uprotocol::v1::getTime(); spdlog::info("sending time = {}", time_val); - Payload string_time(std::to_string(time_val), - UPayloadFormat::UPAYLOAD_FORMAT_TEXT); + uprotocol::datamodel::builder::Payload string_time( + std::to_string(time_val), UPayloadFormat::UPAYLOAD_FORMAT_TEXT); status = publish_time.publish(std::move(string_time)); if (status.code() != UCode::OK) { spdlog::error("Publish time failed."); break; } - int32_t rand_val = getRandom(); + int32_t rand_val = uprotocol::v1::getRandom(); spdlog::info("sending random = {}", rand_val); - Payload random_payload(std::to_string(rand_val), - UPayloadFormat::UPAYLOAD_FORMAT_TEXT); + uprotocol::datamodel::builder::Payload random_payload( + std::to_string(rand_val), UPayloadFormat::UPAYLOAD_FORMAT_TEXT); status = publish_random.publish(std::move(random_payload)); if (status.code() != UCode::OK) { spdlog::error("Publish random failed."); break; } - uint8_t counter_val = getCounter(); + uint8_t counter_val = uprotocol::v1::getCounter(); spdlog::info("sending counter = {}", counter_val); - Payload counter_payload(std::to_string(counter_val), - UPayloadFormat::UPAYLOAD_FORMAT_TEXT); + uprotocol::datamodel::builder::Payload counter_payload( + std::to_string(counter_val), UPayloadFormat::UPAYLOAD_FORMAT_TEXT); status = publish_counter.publish(std::move(counter_payload)); if (status.code() != UCode::OK) { spdlog::error("Publish counter failed."); diff --git a/pubsub/src/main_sub.cpp b/pubsub/src/main_sub.cpp index a63966b..59c3dce 100644 --- a/pubsub/src/main_sub.cpp +++ b/pubsub/src/main_sub.cpp @@ -33,15 +33,14 @@ #include "UTransportDomainSockets.h" #include "common.h" -using namespace uprotocol::communication; -using namespace uprotocol::v1; +namespace uprotocol::v1 { -bool gTerminate = false; +bool g_terminate = false; void signalHandler(int signal) { if (signal == SIGINT) { std::cout << "Ctrl+C received. Exiting..." << std::endl; - gTerminate = true; + g_terminate = true; } } @@ -71,7 +70,9 @@ void onReceiveCounter(const uprotocol::v1::UMessage& message) { spdlog::info("received counter = {}", payload); } } +} // namespace uprotocol::v1 +using UStatus = uprotocol::v1::UStatus; /* The sample sub applications demonstrates how to consume data using uTransport * - * There are three topics that are received - random number, current time and a @@ -80,24 +81,25 @@ int main(int argc, char** argv) { (void)argc; (void)argv; - signal(SIGINT, signalHandler); - signal(SIGPIPE, signalHandler); + (void)signal(SIGINT, uprotocol::v1::signalHandler); + (void)signal(SIGPIPE, uprotocol::v1::signalHandler); UStatus status; - UUri source = getUUri(0); - auto topic_time = getTimeUUri(); - auto topic_random = getRandomUUri(); - auto topic_counter = getCounterUUri(); - auto transport = std::make_shared(source); - - auto resTime = - Subscriber::subscribe(transport, std::move(topic_time), onReceiveTime); - auto resRandom = Subscriber::subscribe(transport, std::move(topic_random), - onReceiveRandom); - auto resCounter = Subscriber::subscribe(transport, std::move(topic_counter), - onReceiveCounter); - - while (!gTerminate) { + uprotocol::v1::UUri source = getUUri(0); + const auto& topic_time = getTimeUUri(); + const auto& topic_random = getRandomUUri(); + const auto& topic_counter = getCounterUUri(); + auto transport = + std::make_shared(source); + + auto res_time = uprotocol::communication::Subscriber::subscribe( + transport, topic_time, uprotocol::v1::onReceiveTime); + auto res_random = uprotocol::communication::Subscriber::subscribe( + transport, topic_random, uprotocol::v1::onReceiveRandom); + auto res_counter = uprotocol::communication::Subscriber::subscribe( + transport, topic_counter, uprotocol::v1::onReceiveCounter); + + while (!uprotocol::v1::g_terminate) { sleep(1); } diff --git a/rpc/include/common.h b/rpc/include/common.h index bfdead0..9b0f8ce 100644 --- a/rpc/include/common.h +++ b/rpc/include/common.h @@ -20,18 +20,19 @@ // SPDX-FileCopyrightText: 2024 General Motors GTO LLC // SPDX-License-Identifier: Apache-2.0 -#ifndef RPC_COMMON_H -#define RPC_COMMON_H +#ifndef COMMON_H +#define COMMON_H #include -uprotocol::v1::UUri getRpcUUri(const int resource_id) { - uprotocol::v1::UUri uuri; - uuri.set_authority_name("test_rpc.app"); - uuri.set_ue_id(0x10001); - uuri.set_ue_version_major(1); - uuri.set_resource_id(resource_id); - return uuri; +inline uprotocol::v1::UUri getRpcUUri(const int resource_id) { + constexpr uint32_t RPC_UE_ID = 0x10001; + uprotocol::v1::UUri uuri; + uuri.set_authority_name("test_rpc.app"); + uuri.set_ue_id(RPC_UE_ID); + uuri.set_ue_version_major(1); + uuri.set_resource_id(resource_id); + return uuri; } -#endif // RPC_COMMON_H +#endif // COMMON_H diff --git a/rpc/src/main_rpc_client.cpp b/rpc/src/main_rpc_client.cpp index e32c646..cb1e90c 100644 --- a/rpc/src/main_rpc_client.cpp +++ b/rpc/src/main_rpc_client.cpp @@ -32,22 +32,23 @@ #include "SocketUTransport.h" #include "common.h" -using namespace uprotocol::v1; -using namespace uprotocol::communication; -using namespace uprotocol::datamodel::builder; +constexpr uint32_t METHOD_RPC_RESOURCE_ID = 12; +constexpr std::chrono::milliseconds RPCCLIENT_TTL(500); -bool gTerminate = false; +namespace uprotocol::v1 { + +bool g_terminate = false; void signalHandler(int signal) { if (signal == SIGINT) { std::cout << "Ctrl+C received. Exiting..." << std::endl; - gTerminate = true; + g_terminate = true; } } -void OnReceive(RpcClient::MessageOrStatus expected) { +void OnReceive(uprotocol::communication::RpcClient::MessageOrStatus expected) { if (!expected.has_value()) { - UStatus status = expected.error(); + const UStatus& status = expected.error(); spdlog::error("Expected value not found. -- Status: {}", status.DebugString()); return; @@ -72,10 +73,14 @@ void OnReceive(RpcClient::MessageOrStatus expected) { // sequence number, current time, and random value spdlog::debug("(Client) Received message: {}", message.DebugString()); - const uint64_t* pdata = (uint64_t*)message.payload().data(); + std::vector pdata(3); + size_t expected_size = 3 * sizeof(uint64_t); + std::memcpy(pdata.data(), message.payload().data(), expected_size); spdlog::info("Received payload: {} - {}, {}", pdata[0], pdata[1], pdata[2]); } +} // namespace uprotocol::v1 +using UPriority = uprotocol::v1::UPriority; /* The sample RPC client applications demonstrates how to send RPC requests and * wait for the response */ @@ -83,21 +88,19 @@ int main(int argc, char** argv) { (void)argc; (void)argv; - signal(SIGINT, signalHandler); + (void)signal(SIGINT, uprotocol::v1::signalHandler); - UUri source = getRpcUUri(0); - UUri method = getRpcUUri(12); + uprotocol::v1::UUri source = getRpcUUri(0); + uprotocol::v1::UUri method = getRpcUUri(METHOD_RPC_RESOURCE_ID); auto transport = std::make_shared(source); - auto client = - RpcClient(transport, std::move(method), UPriority::UPRIORITY_CS4, - std::chrono::milliseconds(500)); - RpcClient::InvokeHandle handle; + auto client = uprotocol::communication::RpcClient( + transport, std::move(method), UPriority::UPRIORITY_CS4, RPCCLIENT_TTL); + uprotocol::communication::RpcClient::InvokeHandle handle; - while (!gTerminate) { - handle = client.invokeMethod(OnReceive); + while (!uprotocol::v1::g_terminate) { + handle = client.invokeMethod(uprotocol::v1::OnReceive); sleep(1); } return 0; } - diff --git a/rpc/src/main_rpc_server.cpp b/rpc/src/main_rpc_server.cpp index 408854a..da7b0d4 100644 --- a/rpc/src/main_rpc_server.cpp +++ b/rpc/src/main_rpc_server.cpp @@ -27,21 +27,23 @@ #include #include +#include #include +#include #include "SocketUTransport.h" #include "common.h" -using namespace uprotocol::v1; -using namespace uprotocol::communication; -using namespace uprotocol::datamodel::builder; +constexpr uint32_t METHOD_RPC_RESOURCE_ID = 12; -bool gTerminate = false; +namespace uprotocol::v1 { + +bool g_terminate = false; void signalHandler(int signal) { if (signal == SIGINT) { std::cout << "Ctrl+C received. Exiting..." << std::endl; - gTerminate = true; + g_terminate = true; } } @@ -63,22 +65,27 @@ std::optional OnReceive( // Received request with empty payload, generate response with // sequence number, current time, and random value - static uint64_t seqNum = 0; - uint64_t randVal = std::rand(); - uint64_t timeVal = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count(); - std::vector payload_data = {seqNum++, timeVal, randVal}; + static uint64_t seq_num = 0; + std::random_device rd; + std::mt19937_64 gen(rd()); + std::uniform_int_distribution distribution(0, UINT64_MAX); + uint64_t rand_val = distribution(gen); + uint64_t time_val = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count(); + std::vector payload_data = {seq_num++, time_val, rand_val}; spdlog::debug("(Server) Received request:\n{}", message.DebugString()); - Payload payload(reinterpret_cast&>(payload_data), - UPayloadFormat::UPAYLOAD_FORMAT_RAW); + uprotocol::datamodel::builder::Payload payload( + reinterpret_cast&>(payload_data), + UPayloadFormat::UPAYLOAD_FORMAT_RAW); spdlog::info("Sending payload: {} - {}, {}", payload_data[0], payload_data[1], payload_data[2]); return payload; } +} // namespace uprotocol::v1 /* The sample RPC server applications demonstrates how to receive RPC requests * and send a response back to the client - @@ -87,12 +94,13 @@ int main(int argc, char** argv) { (void)argc; (void)argv; - signal(SIGINT, signalHandler); + (void)signal(SIGINT, uprotocol::v1::signalHandler); - UUri source = getRpcUUri(0); - UUri method = getRpcUUri(12); + uprotocol::v1::UUri source = getRpcUUri(0); + uprotocol::v1::UUri method = getRpcUUri(METHOD_RPC_RESOURCE_ID); auto transport = std::make_shared(source); - auto server = RpcServer::create(transport, method, OnReceive); + auto server = uprotocol::communication::RpcServer::create( + transport, method, uprotocol::v1::OnReceive); if (!server.has_value()) { spdlog::error("Failed to create RPC server: {}", @@ -100,10 +108,9 @@ int main(int argc, char** argv) { return 1; } - while (!gTerminate) { + while (!uprotocol::v1::g_terminate) { sleep(1); } return 0; } -