From 273aae5c7bb95e74e5fb383c9ec7feb69e96e73f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20L=C3=B6per?= Date: Tue, 16 Feb 2021 02:02:09 +0100 Subject: [PATCH] feat: aws greengrass integration (#22) --- .github/workflows/build-app-nightly.yaml | 14 ++- .github/workflows/build-aptly.yaml | 1 + .github/workflows/build-deps.yaml | 1 + .github/workflows/build-toolchain.yaml | 1 + .gitignore | 3 +- .vscode/tasks.json | 4 +- README.md | 4 +- .../docker/deps.Dockerfile | 8 +- rpi-scripts/install-all-dependencies.sh | 17 +-- rpi-scripts/install-aws-greengrass-sdk.sh | 4 + src/CMakeLists.txt | 1 + src/greengrass/CMakeLists.txt | 13 +++ src/greengrass/main.cpp | 104 ++++++++++++++++++ 13 files changed, 162 insertions(+), 13 deletions(-) create mode 100755 rpi-scripts/install-aws-greengrass-sdk.sh create mode 100644 src/greengrass/CMakeLists.txt create mode 100644 src/greengrass/main.cpp diff --git a/.github/workflows/build-app-nightly.yaml b/.github/workflows/build-app-nightly.yaml index 78ea722f..cfdc99aa 100644 --- a/.github/workflows/build-app-nightly.yaml +++ b/.github/workflows/build-app-nightly.yaml @@ -88,6 +88,18 @@ jobs: path: | usbproxy/*.deb + - name: Create greengrass deployment package + working-directory: usbproxy/src/build/greengrass/ + run: | + zip usb-mitm.zip usb-mitm-gg + + - name: Upload Release Asset - Greengrass Deployment Package + uses: actions/upload-artifact@v2 + with: + name: greengrass-deployment-package + path: | + usbproxy/src/build/greengrass/usb-mitm.zip + upload-package: name: Upload nesto-usbproxy debian package into nesto repository in S3 runs-on: ubuntu-latest @@ -129,4 +141,4 @@ jobs: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: | - aptly publish repo -batch=true -passphrase-file="./key_passwd" -gpg-key="$GPG_KEY_ID" -component=aws -distribution=nightly nesto-pos-adapter-devel s3:nesto-debian-repo-devel: + aptly publish repo -batch=true -passphrase-file="./key_passwd" -gpg-key="$GPG_KEY_ID" -component=aws -distribution=nightly nesto-pos-adapter-devel s3:nesto-debian-repo-devel: \ No newline at end of file diff --git a/.github/workflows/build-aptly.yaml b/.github/workflows/build-aptly.yaml index 02ea76a1..c2c0a74a 100644 --- a/.github/workflows/build-aptly.yaml +++ b/.github/workflows/build-aptly.yaml @@ -3,6 +3,7 @@ on: paths: - 'aptly/Dockerfile' branches: master + workflow_dispatch: jobs: build-aptly: diff --git a/.github/workflows/build-deps.yaml b/.github/workflows/build-deps.yaml index 4177efa4..7499b815 100644 --- a/.github/workflows/build-deps.yaml +++ b/.github/workflows/build-deps.yaml @@ -3,6 +3,7 @@ on: paths: - 'docker-crosstool-ng-arm/docker/deps.Dockerfile' branches: master + workflow_dispatch: jobs: build-deps: diff --git a/.github/workflows/build-toolchain.yaml b/.github/workflows/build-toolchain.yaml index e7a846ac..41bfaf82 100644 --- a/.github/workflows/build-toolchain.yaml +++ b/.github/workflows/build-toolchain.yaml @@ -3,6 +3,7 @@ on: paths: - 'docker-crosstool-ng-arm/docker/toolchain.Dockerfile' branches: master + workflow_dispatch: jobs: build-toolchain: diff --git a/.gitignore b/.gitignore index 92c40950..6ff8ef21 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,5 @@ obj-x86_64-linux-gnu # nesto-specific src/build cppzmq -usb-mitm.tar \ No newline at end of file +usb-mitm.tar +src/lib/usbproxy.pc \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 705841f4..f1ab951b 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -29,9 +29,9 @@ "label": "cmake", "type": "shell", "options": { - "cwd": "${workspaceRoot}/src" + "cwd": "${workspaceRoot}/src/build" }, - "command": "/usr/bin/cmake --build ${workspaceRoot}/src/build --config Debug --target all -- -j 6", + "command": "/usr/bin/cmake -Daws-greengrass-core-sdk-c_DIR=/usr/local/lib/ --build ${workspaceRoot}/src/build --config Debug --target all -- -j 6 ..", "problemMatcher": [] } ], diff --git a/README.md b/README.md index a51b4196..410f138a 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,8 @@ Please note that you must run the application with root privileges. The launch c If you want to run the script on your own, make sure to run the install task before (i.e. Ctrl+P -> *task install* -> Enter -> Enter). This is needed to copy shared libraries into appropriate system folders. You can run the binary from the repository root by doing: `./src/build/tools/usb-mitm --help`. Do not forget to use **sudo** when running anything other than the help menu view. We need root permissions to access the usb subsystem and read from devices. +> :warning: **Linking Libraries**: If you want to run the globally installed executable, you must make sure that your dynamic linker is up-to-date. Please run `sudo ldconfig` to ensure libraries can be linked correctly at runtime. + Usage --------- ``` @@ -230,4 +232,4 @@ Building a Release (for Maintainers) 4. Create a PR into master and describe the changes; Make sure to squash the commits. Use a commit message like: `chore: prepare release for vx.y.z`. -Use a PR title like: `chore: release vx.y.z`. \ No newline at end of file +Use a PR title like: `chore: release vx.y.z`. diff --git a/docker-crosstool-ng-arm/docker/deps.Dockerfile b/docker-crosstool-ng-arm/docker/deps.Dockerfile index a8324634..c639507f 100644 --- a/docker-crosstool-ng-arm/docker/deps.Dockerfile +++ b/docker-crosstool-ng-arm/docker/deps.Dockerfile @@ -106,4 +106,10 @@ RUN LDFLAGS="-L$STAGING_DIR/usr/lib" make RUN make install DESTDIR=${STAGING_DIR} # install dep for debian build -RUN apt-get install -y dh-make \ No newline at end of file +RUN apt-get install -y dh-make + + +# install aws-greengrass-sdk + +COPY ./rpi-scripts/install-aws-greengrass-sdk.sh ./install-aws-greengrass-sdk.sh +RUN ./install-aws-greengrass-sdk.sh \ No newline at end of file diff --git a/rpi-scripts/install-all-dependencies.sh b/rpi-scripts/install-all-dependencies.sh index 0ef602c5..0dd8050b 100755 --- a/rpi-scripts/install-all-dependencies.sh +++ b/rpi-scripts/install-all-dependencies.sh @@ -5,27 +5,30 @@ set -o pipefail echo -e "[0/7] Updating package list\n" sudo apt-get update -echo -e "[1/7] Installing cmake" +echo -e "[1/8] Installing cmake" sudo apt-get install -y cmake -echo -e "[2/7] Installing libusb\n" +echo -e "[2/8] Installing libusb\n" sudo apt-get install -y libusb-1.0.0-dev -echo -e "[3/7] Installing boost libs: chrono, timer, system\n" +echo -e "[3/8] Installing boost libs: chrono, timer, system\n" sudo apt-get install -y libboost-chrono-dev libboost-timer-dev libboost-system-dev -echo -e "[4/7] Installing libzmq\n" +echo -e "[4/8] Installing libzmq\n" sudo apt-get install -y libzmq3-dev -echo -e "[5/7] Installing cppzmq\n" +echo -e "[5/8] Installing cppzmq\n" git clone https://github.com/zeromq/cppzmq.git /tmp/cppzmq || echo "Skipped clone." (cd /tmp/cppzmq && mkdir -p build && cd build && cmake -DCPPZMQ_BUILD_TESTS=off .. && sudo make -j4 install) -echo -e "[6/7] Installing msgpack\n" +echo -e "[6/8] Installing msgpack\n" git clone https://github.com/msgpack/msgpack-c.git /tmp/msgpack-c || echo "Skipped clone." (cd /tmp/msgpack-c && git checkout cpp_master && cmake -DMSGPACK_CXX17=ON . && sudo make install) -echo -e "[7/7] Put RPi USB into client mode" +echo -e "[7/8] Installing aws-greengrass-sdk\n" +./install-aws-greengrass-sdk.sh + +echo -e "[8/8] Put RPi USB into client mode" set +e set +o pipefail diff --git a/rpi-scripts/install-aws-greengrass-sdk.sh b/rpi-scripts/install-aws-greengrass-sdk.sh new file mode 100755 index 00000000..1d7764df --- /dev/null +++ b/rpi-scripts/install-aws-greengrass-sdk.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +git clone https://github.com/aws/aws-greengrass-core-sdk-c.git /tmp/aws-sdk +(cd /tmp/aws-sdk/aws-greengrass-core-sdk-c && mkdir -p build && cd build && cmake .. && cmake --build . && sudo make install) \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ad707c8e..6ada2d98 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,6 +26,7 @@ set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} $ENV{CPPFLAGS} -std=gnu++11 -pthread -pe add_subdirectory(lib) add_subdirectory(Plugins) add_subdirectory(tools) +add_subdirectory(greengrass) # Create uninstall target configure_file( diff --git a/src/greengrass/CMakeLists.txt b/src/greengrass/CMakeLists.txt new file mode 100644 index 00000000..04601a0f --- /dev/null +++ b/src/greengrass/CMakeLists.txt @@ -0,0 +1,13 @@ +# minimal CMakeLists.txt for the AWS Greengrass SDK for C +cmake_minimum_required(VERSION 2.8) +set(TOOL usb-mitm-gg) +LIST(APPEND TOOLS_LINK_LIBS USBProxy -pthread zmq aws-greengrass-core-sdk-c) + +find_package(aws-greengrass-core-sdk-c REQUIRED) + +include_directories(${libusbproxy_SOURCE_DIR}) +add_executable(${TOOL} main.cpp) +target_link_libraries(${TOOL} ${TOOLS_LINK_LIBS}) +target_compile_options(${TOOL} PRIVATE -Werror -Wall -Wextra -pedantic) + +install(TARGETS ${TOOL} RUNTIME DESTINATION ${INSTALL_DEFAULT_BINDIR}) \ No newline at end of file diff --git a/src/greengrass/main.cpp b/src/greengrass/main.cpp new file mode 100644 index 00000000..8683bf4c --- /dev/null +++ b/src/greengrass/main.cpp @@ -0,0 +1,104 @@ +#include +#include "greengrasssdk.h" + +#include "Manager.h" +#include "ConfigParser.h" +#include +#include + +Manager* manager; +zmq::context_t *ctx = new zmq::context_t(); +zmq::socket_t *frontend = new zmq::socket_t(*ctx, zmq::socket_type::xsub); +zmq::socket_t *backend = new zmq::socket_t(*ctx, zmq::socket_type::xpub); + +void run_proxy(zmq::socket_t *frontend, zmq::socket_t *backend) { + + // proxy until context is destroyed, see: http://api.zeromq.org/3-2:zmq-proxy + zmq::proxy(*frontend, *backend); +} + +void handle_signal(int signum) +{ + struct sigaction action; + switch (signum) { + case SIGTERM: + case SIGINT: + if(signum == SIGTERM) + fprintf(stderr, "Received SIGTERM, stopping relaying...\n"); + else + fprintf(stderr, "Received SIGINT, stopping relaying...\n"); + if (manager) {manager->stop_relaying();} + fprintf(stderr, "Exiting\n"); + memset(&action, 0, sizeof(struct sigaction)); + action.sa_handler = SIG_DFL; + sigaction(SIGINT, &action, NULL); + sigaction(SIGTERM, &action, NULL); + break; + case SIGHUP: + fprintf(stderr, "Received SIGHUP, restarting relaying...\n"); + if (manager) {manager->stop_relaying();} + if (manager) {manager->start_control_relaying();} + break; + } +} + +void handler(const gg_lambda_context *cxt) { + (void)cxt; + return; +} + +int main() { + gg_error err = GGE_SUCCESS; + + err = gg_global_init(0); + if(err) { + gg_log(GG_LOG_ERROR, "gg_global_init failed %d", err); + return -1; + } + + gg_runtime_start(handler, GG_RT_OPT_ASYNC); + + struct sigaction action; + memset(&action, 0, sizeof(struct sigaction)); + action.sa_handler = handle_signal; + sigaction(SIGTERM, &action, NULL); + sigaction(SIGHUP, &action, NULL); + sigaction(SIGINT, &action, NULL); + + ConfigParser *cfg = new ConfigParser(); + cfg->set("vendorId", "045e"); + //cfg->set("productId", ""); + cfg->set("DeviceProxy", "DeviceProxy_LibUSB"); + cfg->set("HostProxy", "HostProxy_GadgetFS"); + cfg->add_to_vector("Plugins", "PacketFilter_ZeroMQ"); + + + (*frontend).bind("tcp://127.0.0.1:9999"); + (*backend).bind("tcp://127.0.0.1:5678"); + std::thread zmq_proxy = std::thread(run_proxy, std::ref(frontend), std::ref(backend)); + + int status; + do { + manager=new Manager(false); + manager->load_plugins(cfg); + cfg->print_config(); + + manager->start_control_relaying(); + while ( ( status = manager->get_status()) == USBM_RELAYING) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + + frontend->close(); + backend->close(); + zmq_proxy.join(); + ctx->close(); + manager->stop_relaying(); + manager->cleanup(); + delete(frontend); + delete(backend); + delete(manager); + delete(ctx); + } while ( status == USBM_RESET); + + return -1; +} \ No newline at end of file