diff --git a/.gitattributes b/.gitattributes index f6e3b12b..6313b56c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -*.sh text eol=lf +* text=auto eol=lf diff --git a/.github/workflows/build_image.yml b/.github/workflows/build_image.yml new file mode 100644 index 00000000..02e4d000 --- /dev/null +++ b/.github/workflows/build_image.yml @@ -0,0 +1,63 @@ +# +name: Create and publish a Docker image + +# Configures this workflow to run every time a docker artificat is edited +on: + push: + paths: + - 'odysseus/Dockerfile' + - 'odysseus/docker_scripts/**' + - '.github/workflows/build_image.yml' + workflow_dispatch: + +# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu. +jobs: + build-and-push-image: + runs-on: ubuntu-latest + # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. + permissions: + contents: read + packages: write + # + steps: + - name: Checkout repository + uses: actions/checkout@v4 + # Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + # This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels. + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Encrypt and inject passwords + shell: bash + working-directory: ./odysseus + env: + ODY_BASE_WIFI_PASSWORD: ${{ secrets.ODY_BASE_WIFI_PASSWORD }} + ODY_AP_ROOT_PASSWORD: ${{ secrets.ODY_AP_ROOT_PASSWORD }} + ODY_TPU_ROOT_PASSWORD: ${{ secrets.ODY_TPU_ROOT_PASSWORD }} + ODY_IROH_ROOT_PASSWORD: ${{ secrets.ODY_IROH_ROOT_PASSWORD }} + MASTER_PASSWORD: ${{ secrets.ODY_MASTER_PASSWORD }} + run: for i in ODY_AP_ROOT_PASSWORD ODY_TPU_ROOT_PASSWORD ODY_IROH_ROOT_PASSWORD ODY_BASE_WIFI_PASSWORD; do echo "$i=${!i}" >> SECRETS.env; done && gpg --batch --symmetric --passphrase "$MASTER_PASSWORD" --no-symkey-cache --cipher-algo AES256 SECRETS.env + # This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages. + # It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository. + # It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step. + - name: Build and push Docker image + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: ./odysseus + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.gitignore b/.gitignore index 7a05c46b..7300642a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,14 @@ *.o *.bin - */__pycache__ .DS_Store odysseus/outputs/** + +# for passwords +odysseus/SECRETS.env +odysseus/SECRETS.env-example +# redundant safeguard for all env files named SECRETS.env in case it is renamed wrong +**/*SECRETS.env* +/.idea diff --git a/extra/emqx_base/README.md b/extra/emqx_base/README.md index 0f2bc4b9..1ed591bd 100644 --- a/extra/emqx_base/README.md +++ b/extra/emqx_base/README.md @@ -5,3 +5,6 @@ Clone repo and cd to this directory. run with (note: absolute paths must be used): `docker run -d --restart=always --name emqx -p 18083:18083 -p 1883:1883 -p 14567:14567/udp -v /path/to/emqx.conf:/opt/emqx/etc/emqx.conf -v /path/to/listeners.quic.conf:/opt/emqx/etc/listeners.quic.conf -v /path/to/listeners.tcp.conf:/opt/emqx/etc/listeners.tcp.conf emqx:5.5.0` + +Ex. +`docker run -d --restart=always --name emqx -p 18083:18083 -p 1883:1883 -p 14567:14567/udp -v /opt/Odysseus/extra/emqx_base/emqx.conf:/opt/emqx/etc/emqx.conf -v /opt/Odysseus/extra/emqx_base/listeners.quic.conf:/opt/emqx/etc/listeners.quic.conf -v /opt/Odysseus/extra/emqx_base/listeners.tcp.conf:/opt/emqx/etc/listeners.tcp.conf emqx:5.5.0` diff --git a/extra/mosquitto_base/README.md b/extra/mosquitto_base/README.md index 48946553..096fb108 100644 --- a/extra/mosquitto_base/README.md +++ b/extra/mosquitto_base/README.md @@ -6,7 +6,8 @@ All of the steps should be done in the ssh console of the base station, with IP 3. run the below command. note that the path to the moquitto.conf in this directory **must be absolute**. `docker run --restart=always -it -p 1883:1883 -p 9001:9001 -v /path/to/mosquitto.conf:/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log -d eclipse-mosquitto` - +Ex. +`docker run --restart=always -it -p 1883:1883 -p 9001:9001 -v /opt/Odysseus/extra/mosquitto_base/mosquitto.conf:/mosquitto/config/mosquitto.conf -v /mosquitto/data -v /mosquitto/log -d eclipse-mosquitto` ### Tips and tricks diff --git a/extra/mosquitto_base/mosquitto.conf b/extra/mosquitto_base/mosquitto.conf index 39a35054..92eee86e 100644 --- a/extra/mosquitto_base/mosquitto.conf +++ b/extra/mosquitto_base/mosquitto.conf @@ -172,6 +172,7 @@ address 192.168.100.12 # *** diff from tpu (needed as topic key required) topic reserved out 2 dummy dummyremote + #bridge_bind_address #bridge_attempt_unsubscribe true diff --git a/odysseus/Dockerfile b/odysseus/Dockerfile index 9d39465b..69de7bd0 100644 --- a/odysseus/Dockerfile +++ b/odysseus/Dockerfile @@ -5,7 +5,7 @@ RUN apt-get update && \ apt-get -y install tzdata -RUN apt-get install -y \ +RUN apt-get update && apt-get install -y \ make \ binutils \ build-essential \ @@ -31,18 +31,23 @@ RUN apt-get install -y \ python3-matplotlib \ graphviz \ git-lfs \ - util-linux + util-linux \ + wpasupplicant # just for calypso require ruamel.yaml -RUN apt-get install -y python3-pip && pip install "ruamel.yaml<0.18.0" +RUN apt-get update && apt-get install -y python3-pip && pip install "ruamel.yaml<0.18.0" # add all buildroot files there WORKDIR /home/odysseus/build RUN git clone https://gitlab.com/buildroot.org/buildroot.git && cd ./buildroot && git checkout 2024.02 + WORKDIR /home/odysseus/outputs/ COPY ./docker_scripts /home/odysseus/scripts RUN echo "source /home/odysseus/scripts/setup_env.sh" >> ~/.bashrc +# install password using wildcard so failures arent deadly +COPY ./SECRETS.env.* /home/odysseus/ + ENTRYPOINT "/bin/bash" diff --git a/odysseus/README.md b/odysseus/README.md index d1cb51a4..b92aac84 100644 --- a/odysseus/README.md +++ b/odysseus/README.md @@ -27,19 +27,34 @@ All defconfigs come with (in addition to busybox and util_linux utilities): - iperf3, iw, iputils, and other network configuration utilities ## Quick start -Download and install to PATH git and docker. +Download and install to PATH git and docker. Docker desktop is recommended for macOS and Windows. ``` git clone https://github.com/Northeastern-Electric-Racing/Siren.git git submodule update --init --recursive cd ./odysseus +``` + +For linux (current support includes all build defconfigs): +``` docker compose run --rm --build odysseus # Future launches can omit `--build` for time savings and space savings, but it should be used if the Dockerfile or docker_out_of_tree.sh files change. + ``` + +For mac and windows: (current support includes all _debug defconfigs, on x86_64 host normal defconfigs can work (experimental)): +``` +docker compose -f "compose-compat.yml" run --rm --build odysseus # Future launches can omit `--build` for time savings and space savings, but it should be used if the Dockerfile or docker_out_of_tree.sh files change. +``` + + + Now you are in the docker container. To build cd into the defconfig directory (either ap, or tpu), then run the make command alias: ``` cd ./ make-current ``` -You can view the `output.log` for more info. Now, to deploy just flash the image in `images/ + +**Note: If failure occurs on mac or windows very early in the process, run `make nanomq-source` and try again before reporting the error.** +You can view the `output.log` for more info. ### More on docker configuration The container has a directory structure as so: @@ -49,13 +64,16 @@ The container has a directory structure as so: - `./odysseus_tree`: The odyssues external tree, bound to the same directory in the git repository on your local machine! - `./shared_data`: The download and ccache cache for buildroot, should be persisted as long as space is available, there is usually no reason to enter this. A persistent docker volume with the name `odysseus_shared_data`. - `./outputs/*`: - - **The output folders for odysseus. `cd` into the one named for what defconfig you would like to build, and run the `make` configuration and build commands as described below. It is recommended to save space to run `make clean` in defconfig directories rather than removing this volume all together. This is bound to the `./odysseus/outputs` directory in the repository. *Remember to use `make savedefconfig` when you are done as changes are overriden when you re-open the docker image!* + - **The output folders for odysseus. `cd` into the one named for what defconfig you would like to build, and run the `make` configuration and build commands as described below. It is recommended to save space to run `make clean` in defconfig directories rather than removing this volume all together. For Linux hosts, this is bound to the `./odysseus/outputs` directory in the repository. For Windows users, this is a docker volume. *Remember to use `make savedefconfig` when you are done as changes are overriden when you re-open the docker image!* ### Extra docker tips All paths relative to Siren root. +#### Note for Windows/macOS users +The outputs are stored in a docker volume on these platforms to ensure rsync compatability. Therefore fetching the files requires first running the image, then use `docker cp` to get them to the userspace. Alternatively, docker desktop has a file explorer for docker volumes that may come in handy. + #### Writing the sd card -The image is present in `./odysseus/outputs//images/sdcard.img`. +The image is present in `./odysseus/outputs//images/sdcard.img`. One can flash this with tools like the Raspberry Pi OS Imager. #### Pulling source files for scp, etc. The target binaries are located in `./odysseus/outputs//target`. @@ -66,6 +84,10 @@ The target binaries are located in `./odysseus/outputs//target`. **IMPORTANT**: this WILL wipe all shared cache (don't do this unless you need the space): `docker volume rm odysseus_shared_data` +This will wipe all outputs, not the cache so just requires a full rebuild to recover from. On compose-compat images only: +`docker volume rm odysseus_outputs` + + #### Open another tty `docker ps` Find the container ID of odysseus-odysseus then run: @@ -78,12 +100,20 @@ docker exec -d -w /home/odysseus/outputs/ make-current ``` Be careful with this. -Notes about docker: -- Build time may be slower due to docker isolations (not dramatic, about 5-15%) -- Since odysseus only supports amd64 hosts for non-debug defconfigs, full releases cannot be built on mac +Docker limitations: +- Build time may be slower due to docker isolations (not dramatic, about 5%) - Launch time is longer - Space is used up by rebuilds, prune often or omit `--build` +### Passwords +Root passwords are stored via Github secrets and an encrypted file within a ghcr docker image. Below are the steps to load and decrypt such passwords for use by buildroot. Requirements are you know the team's master password and are running x86_64. + +1. Authenticate with ghcr. First make a [classic PAT](https://github.com/settings/tokens/new) with the permission `read:packages`. Make sure to copy the token, then run `sudo docker login ghcr.io -u -p ` +2. cd into odysseus folder and `docker compose pull` +3. Run `docker compose run odysseus` to enter the docker image. At this point the image should be identical to a locally built one, but it is less preferable for development purposes. +4. Run `load-secrets` and enter the master password. Consult Odysseus lead if you need this info. Now your passwords are loaded (can be viewed with `env | grep ODY`), and will be set when you make the sdcard.img. Note this step must be repeated on each `docker compose run odysseus`, and if the passwords change on Github steps 2 and 3 must be rerun as well. + + See below to learn more about developing, and check confluence for most info. Once in the docker image, all the normal make commands (in an out-of-tree context only) apply. @@ -92,6 +122,13 @@ See below to learn more about developing, and check confluence for most info. O 2. Make any customizations you want in the menu 3. Save changes after you've made them by running ```make savedefconfig```. Ensure you are saving changes to the intended defconfig, it is saved to whatever directory you `cd`ed into! +#### Adding defconfigs + +Checklist when adding a defconfig: +[ ] Add a secret for SSH password in settings, and load it into the workflow env in `.github/workflows/build_image.yml` +[ ] Add the defconfig itself, changing path names, etc. Board folders and overlays can still be shared as needed. +[ ] Add a pretty name to `post-build-os-release.sh` +[ ] Add a load command to `setup_env.sh` target_gpio_in(14)) if str(config['model']) == "7393" or str(config['model']) == "7394": ps_gpio_arg = " power_save_gpio=17,14" @@ -74,8 +69,7 @@ def setModuleParam(config): # module param for bss_max_idle (keep alive) # default: bss_max_idle(0: disabled) if int(config['bss_max_idle_enable']) == 1: - if strSTA() == 'AP' or strSTA() == 'RELAY' or strSTA() == 'STA': - bss_max_idle_arg = " bss_max_idle=" + str(config['bss_max_idle']) + bss_max_idle_arg = " bss_max_idle=" + str(config['bss_max_idle']) # module param for NDP Prboe Request (NDP scan) # default: ndp_preq(0: disabled) @@ -171,7 +165,7 @@ def setModuleParam(config): # module param for supported channel width # default : support 1/2/4MHz (1: 1/2/4Mhz) - if strSTA() == 'STA' and int(config['support_ch_width']) == 0: + if option == 'STA' and int(config['support_ch_width']) == 0: support_ch_width_arg = " support_ch_width=0" module_param += fw_arg + \ @@ -194,15 +188,12 @@ def load_conf(file_path): def run_common(): - ini_path = "" - # if not passed in, use live buildroot default - if len(sys.argv) <= 2: - if strSTA() == 'STA': + ini_path = args.ini_path + if (ini_path is None) : + if option == 'STA': ini_path = "/etc/nrc_opts_sta.ini" else: ini_path = "/etc/nrc_opts_ap.ini" - else: - ini_path = sys.argv[2] items = load_conf(ini_path) @@ -212,13 +203,9 @@ def run_common(): insmod_arg = setModuleParam(items) file_txt = "" - mod_path = "" - # if not passed in, use live buildroot default - if len(sys.argv) <= 3: - mod_path = "/etc/modprobe.d/nrc.conf" - else: - mod_path = sys.argv[3] + mod_path = args.mod_path + with open(mod_path, "w") as mod_file: file_txt = "options nrc" + insmod_arg file_txt = file_txt.strip("\n") diff --git a/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/eglfs.json b/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/eglfs.json index 71d823a6..2b813c4f 100644 --- a/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/eglfs.json +++ b/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/eglfs.json @@ -2,7 +2,7 @@ "device": "/dev/dri/by-path/platform-gpu-card", "outputs": [ { - "name": "HDMI0", + "name": "HDMI1", "mode": "800x480", "primary": true } diff --git a/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/init.d/S01psplash-start b/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/init.d/S01psplash-start new file mode 100755 index 00000000..f37258ba --- /dev/null +++ b/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/init.d/S01psplash-start @@ -0,0 +1,27 @@ +#!/bin/sh + +PIDFILE=/var/run/psplash.pid + +start() { + printf "Starting psplash" + start-stop-daemon -S -m -b -p "$PIDFILE" --exec /usr/bin/psplash +} + +stop () { + printf "Stopping psplash" + start-stop-daemon -K -s SIGINT -p "$PIDFILE" + rm "$PIDFILE" +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + *) + echo "Usage: $0 {start|stop}" + exit 1 + ;; +esac diff --git a/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/modprobe.d/nrc.conf b/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/modprobe.d/nrc.conf deleted file mode 100644 index 755c361f..00000000 --- a/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/modprobe.d/nrc.conf +++ /dev/null @@ -1 +0,0 @@ -options nrc fw_name=nrc7292_cspi.bin bss_max_idle=1800 listen_interval=1000 bd_name=nrc7292_bd.dat ap_rc_mode=2 sta_rc_mode=2 ap_rc_default_mcs=2 sta_rc_default_mcs=2 diff --git a/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/mosquitto/mosquitto.conf b/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/mosquitto/mosquitto.conf index 435a4f64..3a5a956a 100644 --- a/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/mosquitto/mosquitto.conf +++ b/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/mosquitto/mosquitto.conf @@ -167,7 +167,7 @@ connection base_station # *** base station ip address 192.168.100.1 # below is not a comment !!! #*** -topic # out 0 "" "" +topic # both 0 "" "" #bridge_bind_address diff --git a/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/wpa_supplicant_base.conf b/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/wpa_supplicant_base.conf index 3da40e13..2274bb52 100755 --- a/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/wpa_supplicant_base.conf +++ b/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/wpa_supplicant_base.conf @@ -1,10 +1,10 @@ -# base_station_open ctrl_interface=/var/run/wpa_supplicant_base - +ap_scan=1 country=US network={ ssid="H68K" - scan_ssid=1 - key_mgmt=NONE + key_mgmt=WPA-PSK + scan_freq= 2427 + psk="password" } ignore_old_scan_res=1 diff --git a/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/wpa_supplicant_halow.conf b/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/wpa_supplicant_halow.conf index 3d059b8e..f7ec9eb9 100755 --- a/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/wpa_supplicant_halow.conf +++ b/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/etc/wpa_supplicant_halow.conf @@ -4,7 +4,6 @@ ctrl_interface=/var/run/wpa_supplicant_halow country=US network={ ssid="NER_Halow" - scan_ssid=1 key_mgmt=NONE scan_freq= 2412 freq_list= 2412 diff --git a/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/sbin/quicknet b/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/sbin/quicknet index 7abd8b39..0c293bc2 100755 --- a/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/sbin/quicknet +++ b/odysseus/odysseus_tree/overlays/rootfs_overlay_tpu/sbin/quicknet @@ -9,7 +9,7 @@ do_start() { ip link set dev eth0 up # can0 - ip link set dev can0 type can bitrate 1000000 listen-only on + ip link set dev can0 type can bitrate 1000000 listen-only off ip link set dev can0 up # bond0 @@ -17,6 +17,9 @@ do_start() { # add_master ip link add dev bond0 type bond + + # statically define mac addr + ip link set bond0 address 00:c0:ca:b1:9b:09 # setup_master ip link set dev bond0 type bond mode active-backup miimon 100 diff --git a/odysseus/odysseus_tree/package/nero2/Config.in b/odysseus/odysseus_tree/package/nero2/Config.in index 0d9cb00f..991588ad 100644 --- a/odysseus/odysseus_tree/package/nero2/Config.in +++ b/odysseus/odysseus_tree/package/nero2/Config.in @@ -1,6 +1,6 @@ config BR2_PACKAGE_NERO2 bool "nero2" - depends on BR2_PACKAGE_NERQT6 && BR2_PACKAGE_NERQT6BASE_NETWORK && BR2_PACKAGE_NERQT6BASE_WIDGETS && BR2_PACKAGE_NERQT6BASE_PNG + depends on BR2_PACKAGE_NERQT6 && BR2_PACKAGE_NERQT6BASE_NETWORK && BR2_PACKAGE_NERQT6BASE_WIDGETS && BR2_PACKAGE_NERQT6BASE_PNG && BR2_PACKAGE_NERQT6CHARTS depends on BR2_PACKAGE_NERQT6DECLARATIVE && BR2_PACKAGE_NERQT6DECLARATIVE_QUICK depends on BR2_PACKAGE_NERQT6MQTT && BR2_PACKAGE_NERQT6GRPC && BR2_PACKAGE_NERQT6CORE5COMPAT && BR2_PACKAGE_NERQT6SVG help diff --git a/odysseus/odysseus_tree/package/nero2/S99nero2 b/odysseus/odysseus_tree/package/nero2/S99nero2 index 4599b6fb..8e53e827 100755 --- a/odysseus/odysseus_tree/package/nero2/S99nero2 +++ b/odysseus/odysseus_tree/package/nero2/S99nero2 @@ -6,6 +6,8 @@ KMS_EGLFS_CONF_FILE=/etc/eglfs.json case "$1" in start) + echo "Stopping psplash" + /etc/init.d/S*psplash-start stop echo "Starting nero2..." # start (S) executable (x) in background (b), make pid file (m) at p QT_QPA_EGLFS_ALWAYS_SET_MODE=1 QT_QPA_EGLFS_NO_LIBINPUT=1 QT_QPA_EVDEV_KEYBOARD_PARAMETERS=grab=1 QT_QPA_EGLFS_KMS_CONFIG=$KMS_EGLFS_CONF_FILE start-stop-daemon -S -x "$EXECUTABLE" -b -m -p "$PIDFILE" -- --platform eglfs @@ -24,4 +26,3 @@ case "$1" in echo "Usage: {start|stop|restart/reload}" exit 1 esac - diff --git a/odysseus/odysseus_tree/package/nerqt6/Config.in b/odysseus/odysseus_tree/package/nerqt6/Config.in index d8f22eae..5cd7be8a 100644 --- a/odysseus/odysseus_tree/package/nerqt6/Config.in +++ b/odysseus/odysseus_tree/package/nerqt6/Config.in @@ -57,5 +57,6 @@ source "$BR2_EXTERNAL_ODY_TREE_PATH/package/nerqt6/nerqt6svg/Config.in" source "$BR2_EXTERNAL_ODY_TREE_PATH/package/nerqt6/nerqt6declarative/Config.in" source "$BR2_EXTERNAL_ODY_TREE_PATH/package/nerqt6/nerqt6mqtt/Config.in" source "$BR2_EXTERNAL_ODY_TREE_PATH/package/nerqt6/nerqt6grpc/Config.in" +source "$BR2_EXTERNAL_ODY_TREE_PATH/package/nerqt6/nerqt6charts/Config.in" endif diff --git a/odysseus/odysseus_tree/package/nerqt6/nerqt6charts/Config.in b/odysseus/odysseus_tree/package/nerqt6/nerqt6charts/Config.in new file mode 100644 index 00000000..958231c7 --- /dev/null +++ b/odysseus/odysseus_tree/package/nerqt6/nerqt6charts/Config.in @@ -0,0 +1,11 @@ +# NER new package +config BR2_PACKAGE_NERQT6CHARTS + bool "nerqt6charts" + help + Qt is a cross-platform application and UI framework for + developers using C++. + + The Qt Charts module provides a set of easy-to-use chart components. + It uses the Qt Graphics View Framework to integrate charts with modern user interfaces. + + https://doc.qt.io/qt-6/qtcharts-index.html diff --git a/odysseus/odysseus_tree/package/nerqt6/nerqt6charts/nerqt6charts.mk b/odysseus/odysseus_tree/package/nerqt6/nerqt6charts/nerqt6charts.mk new file mode 100644 index 00000000..3fc722d1 --- /dev/null +++ b/odysseus/odysseus_tree/package/nerqt6/nerqt6charts/nerqt6charts.mk @@ -0,0 +1,27 @@ +# NER: new package +NERQT6CHARTS_VERSION = $(NERQT6_VERSION) +NERQT6CHARTS_SITE = $(NERQT6_SITE) +NERQT6CHARTS_SOURCE = qtcharts-$(NERQT6_SOURCE_TARBALL_PREFIX)-$(NERQT6CHARTS_VERSION).tar.xz +NERQT6CHARTS_INSTALL_STAGING = YES +NERQT6CHARTS_SUPPORTS_IN_SOURCE_BUILD = NO + +NERQT6CHARTS_CMAKE_BACKEND = ninja + +NERQT6CHARTS_LICENSE = GPL-3.0 with exception + +NERQT6CHARTS_CONF_OPTS = \ + -DQT_HOST_PATH=$(HOST_DIR) \ + -DBUILD_WITH_PCH=OFF \ + -DQT_BUILD_EXAMPLES=OFF \ + -DQT_BUILD_TESTS=OFF + +NERQT6CHARTS_DEPENDENCIES = \ + host-pkgconf \ + nerqt6base + +# add declarative as a dep for this if it is being used +ifeq ($(BR2_PACKAGE_NERQT6DECLARATIVE),y) +NERQT6CHARTS_DEPENDENCIES += nerqt6declarative +endif + +$(eval $(cmake-package)) diff --git a/odysseus/odysseus_tree/package/nerqt6/nerqt6core5compat/Config.in b/odysseus/odysseus_tree/package/nerqt6/nerqt6core5compat/Config.in index 342d1570..ae6f03c4 100644 --- a/odysseus/odysseus_tree/package/nerqt6/nerqt6core5compat/Config.in +++ b/odysseus/odysseus_tree/package/nerqt6/nerqt6core5compat/Config.in @@ -1,5 +1,5 @@ config BR2_PACKAGE_NERQT6CORE5COMPAT - bool "qt6core5compat" + bool "nerqt6core5compat" select BR2_PACKAGE_NERQT6BASE_XML help Qt is a cross-platform application and UI framework for diff --git a/odysseus/odysseus_tree/package/tpu-telemetry/Config.in b/odysseus/odysseus_tree/package/tpu-telemetry/Config.in index 809fc7d8..09ecf1d6 100644 --- a/odysseus/odysseus_tree/package/tpu-telemetry/Config.in +++ b/odysseus/odysseus_tree/package/tpu-telemetry/Config.in @@ -3,6 +3,7 @@ config BR2_PACKAGE_TPU_TELEMETRY select BR2_PACKAGE_PYTHON_GMQTT select BR2_PACKAGE_PYTHON_PSUTIL select BR2_PACKAGE_PYTHON_PROTOBUF + select BR2_PACKAGE_PYTHON_CAN depends on BR2_PACKAGE_GPSD_PYTHON help Fast script scrape and send diff --git a/odysseus/odysseus_tree/package/tpu-telemetry/tpu-telemetry.mk b/odysseus/odysseus_tree/package/tpu-telemetry/tpu-telemetry.mk index 2d933de4..949f1bb9 100644 --- a/odysseus/odysseus_tree/package/tpu-telemetry/tpu-telemetry.mk +++ b/odysseus/odysseus_tree/package/tpu-telemetry/tpu-telemetry.mk @@ -1,10 +1,15 @@ TPU_TELEMETRY_VERSON = 0.1 TPU_TELEMETRY_SITE = $(BR2_EXTERNAL_ODY_TREE_PATH)/sources/tpu_telemetry TPU_TELEMETRY_SITE_METHOD = local -TPU_TELEMETRY_SETUP_TYPE = setuptools define TPU_TELEMETRY_INSTALL_INIT_SYSV $(INSTALL) -D -m 0755 $(TPU_TELEMETRY_PKGDIR)S98tpu-telemetry $(TARGET_DIR)/etc/init.d/S98tpu-telemetry endef -$(eval $(python-package)) +define TPU_TELEMETRY_INSTALL_TARGET_CMDS + $(INSTALL) -d $(TARGET_DIR)/usr/lib/tpu-telemetry/telemetry + cp -r $(@D)/telemetry/* $(TARGET_DIR)/usr/lib/tpu-telemetry/telemetry + $(INSTALL) -D -m 0755 $(TPU_TELEMETRY_PKGDIR)tpu-telemetry.sh $(TARGET_DIR)/usr/bin/tpu-telemetry +endef + +$(eval $(generic-package)) diff --git a/odysseus/odysseus_tree/package/tpu-telemetry/tpu-telemetry.sh b/odysseus/odysseus_tree/package/tpu-telemetry/tpu-telemetry.sh new file mode 100644 index 00000000..3931cd11 --- /dev/null +++ b/odysseus/odysseus_tree/package/tpu-telemetry/tpu-telemetry.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +cd /usr/lib/tpu-telemetry +python3 -m telemetry.publish diff --git a/odysseus/odysseus_tree/patches/dhcpcd/github.com_NetworkConfiguration_dhcpcd_compare_v10.0.5...v10.0.6.patch b/odysseus/odysseus_tree/patches/dhcpcd/github.com_NetworkConfiguration_dhcpcd_compare_v10.0.5...v10.0.6.patch new file mode 100644 index 00000000..c9c22fe4 --- /dev/null +++ b/odysseus/odysseus_tree/patches/dhcpcd/github.com_NetworkConfiguration_dhcpcd_compare_v10.0.5...v10.0.6.patch @@ -0,0 +1,897 @@ +From 584b52db330a96471ff9301b85ce47ebb065a8a4 Mon Sep 17 00:00:00 2001 +From: Roy Marples +Date: Sun, 12 Nov 2023 11:30:01 +0000 +Subject: [PATCH 01/12] control: Fix hangup for non privsep builds + +Fix related to #262. +--- + src/control.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/control.c b/src/control.c +index 5325ac35..93041f82 100644 +--- a/src/control.c ++++ b/src/control.c +@@ -113,8 +113,9 @@ control_handle_read(struct fd_list *fd) + ssize_t bytes; + + bytes = read(fd->fd, buffer, sizeof(buffer) - 1); +- if (bytes == -1) { ++ if (bytes == -1) + logerr(__func__); ++ if (bytes == -1 || bytes == 0) { + control_hangup(fd); + return; + } + +From 21d020b00e60e71b1300d89815f914145d7372f6 Mon Sep 17 00:00:00 2001 +From: Roy Marples +Date: Sun, 12 Nov 2023 12:16:53 +0000 +Subject: [PATCH 02/12] dhcpcd: Detach from launcher before stopping root + process + +This fixes non privsep builds where the launcher reports dhcpcd +hungup. Unsure why this happens, but it should not be a problem. + +While here, shutdown has no effect on non STREAM sockets and +remove the silly error logging in fork_cb that we read an +error. We already printed the error so this makes no sense. + +Hopefully fixes #262. +--- + src/dhcpcd.c | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +diff --git a/src/dhcpcd.c b/src/dhcpcd.c +index 46c64b42..25ce57c1 100644 +--- a/src/dhcpcd.c ++++ b/src/dhcpcd.c +@@ -395,7 +395,6 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx) + logerr("write"); + ctx->options |= DHCPCD_DAEMONISED; + // dhcpcd_fork_cb will close the socket +- shutdown(ctx->fork_fd, SHUT_RDWR); + #endif + } + +@@ -1877,8 +1876,6 @@ dhcpcd_fork_cb(void *arg, unsigned short events) + if (ctx->options & DHCPCD_FORKED) { + if (exit_code == EXIT_SUCCESS) + logdebugx("forked to background"); +- else +- logerrx("exited with code %d", exit_code); + eloop_exit(ctx->eloop, exit_code); + } else + dhcpcd_signal_cb(exit_code, ctx); +@@ -2738,8 +2735,19 @@ main(int argc, char **argv, char **envp) + if (ps_stopwait(&ctx) != EXIT_SUCCESS) + i = EXIT_FAILURE; + #endif +- if (ctx.options & DHCPCD_STARTED && !(ctx.options & DHCPCD_FORKED)) ++ if (ctx.options & DHCPCD_STARTED && !(ctx.options & DHCPCD_FORKED)) { + loginfox(PACKAGE " exited"); ++#ifdef USE_SIGNALS ++ /* Detach from the launch process. ++ * This *should* happen after we stop the root process, ++ * but for some reason non privsep builds get a zero length ++ * read in dhcpcd_fork_cb(). */ ++ if (ctx.fork_fd != -1) { ++ if (write(ctx.fork_fd, &i, sizeof(i)) == -1) ++ logerr("%s: write", __func__); ++ } ++#endif ++ } + #ifdef PRIVSEP + if (ps_root_stop(&ctx) == -1) + i = EXIT_FAILURE; +@@ -2753,12 +2761,6 @@ main(int argc, char **argv, char **envp) + setproctitle_fini(); + #endif + #ifdef USE_SIGNALS +- if (ctx.options & DHCPCD_STARTED) { +- /* Try to detach from the launch process. */ +- if (ctx.fork_fd != -1 && +- write(ctx.fork_fd, &i, sizeof(i)) == -1) +- logerr("%s: write", __func__); +- } + if (ctx.options & (DHCPCD_FORKED | DHCPCD_PRIVSEP)) + _exit(i); /* so atexit won't remove our pidfile */ + #endif + +From 3b4c71859c45b9405f96a5ee8fce04bd3014b2d0 Mon Sep 17 00:00:00 2001 +From: Roy Marples +Date: Mon, 13 Nov 2023 10:24:15 +0000 +Subject: [PATCH 03/12] control: Abort control recv path on hangup + +This fixes a crash when we try and re-use it in another function. +--- + src/control.c | 30 ++++++++++++++++++------------ + 1 file changed, 18 insertions(+), 12 deletions(-) + +diff --git a/src/control.c b/src/control.c +index 93041f82..17fd13aa 100644 +--- a/src/control.c ++++ b/src/control.c +@@ -106,7 +106,7 @@ control_hangup(struct fd_list *fd) + control_free(fd); + } + +-static void ++static int + control_handle_read(struct fd_list *fd) + { + char buffer[1024]; +@@ -117,7 +117,7 @@ control_handle_read(struct fd_list *fd) + logerr(__func__); + if (bytes == -1 || bytes == 0) { + control_hangup(fd); +- return; ++ return -1; + } + + #ifdef PRIVSEP +@@ -129,21 +129,23 @@ control_handle_read(struct fd_list *fd) + fd->flags &= ~FD_SENDLEN; + if (err == -1) { + logerr(__func__); +- return; ++ return 0; + } + if (err == 1 && + ps_ctl_sendargs(fd, buffer, (size_t)bytes) == -1) { + logerr(__func__); + control_free(fd); ++ return -1; + } +- return; ++ return 0; + } + #endif + + control_recvdata(fd, buffer, (size_t)bytes); ++ return 0; + } + +-static void ++static int + control_handle_write(struct fd_list *fd) + { + struct iovec iov[2]; +@@ -170,7 +172,7 @@ control_handle_write(struct fd_list *fd) + logerr("%s: write", __func__); + } + control_hangup(fd); +- return; ++ return -1; + } + + TAILQ_REMOVE(&fd->queue, data, next); +@@ -183,7 +185,7 @@ control_handle_write(struct fd_list *fd) + #endif + + if (TAILQ_FIRST(&fd->queue) != NULL) +- return; ++ return 0; + + #ifdef PRIVSEP + if (IN_PRIVSEP_SE(fd->ctx) && !(fd->flags & FD_LISTEN)) { +@@ -196,9 +198,9 @@ control_handle_write(struct fd_list *fd) + if (eloop_event_add(fd->ctx->eloop, fd->fd, ELE_READ, + control_handle_data, fd) == -1) + logerr("%s: eloop_event_add", __func__); ++ return 0; + } + +- + static void + control_handle_data(void *arg, unsigned short events) + { +@@ -207,10 +209,14 @@ control_handle_data(void *arg, unsigned short events) + if (!(events & (ELE_READ | ELE_WRITE | ELE_HANGUP))) + logerrx("%s: unexpected event 0x%04x", __func__, events); + +- if (events & ELE_WRITE && !(events & ELE_HANGUP)) +- control_handle_write(fd); +- if (events & ELE_READ) +- control_handle_read(fd); ++ if (events & ELE_WRITE && !(events & ELE_HANGUP)) { ++ if (control_handle_write(fd) == -1) ++ return; ++ } ++ if (events & ELE_READ) { ++ if (control_handle_read(fd) == -1) ++ return; ++ } + if (events & ELE_HANGUP) + control_hangup(fd); + } + +From ea53344a2430736124bf9fa62acb0d3107acd58f Mon Sep 17 00:00:00 2001 +From: Roy Marples +Date: Mon, 13 Nov 2023 10:29:58 +0000 +Subject: [PATCH 04/12] dhcpcd: Remove stdio callback and detach on daemonise + +For some reason, the stdio callback is extremely flaky on +*some* Linux based distributions making it very hard to debug some +things. +Removing it is fine because we now enforce that we have file descriptors +for stdin, stdout and stdrr on launch and dup them to /dev/null on daemonise. + +It's also interesting to see behavioural differences between +some socketpair implementations that emit a HANGUP and some don't. + +As such, we now close the fork socket on daemonise once more AND +in the fork_cb depending on if we hangup or read zero first. + +Fixes #262 +--- + src/dhcpcd.c | 125 +++++++++++++------------------------------------- + src/dhcpcd.h | 4 -- + src/privsep.c | 12 ++--- + 3 files changed, 37 insertions(+), 104 deletions(-) + +diff --git a/src/dhcpcd.c b/src/dhcpcd.c +index 25ce57c1..17af1a05 100644 +--- a/src/dhcpcd.c ++++ b/src/dhcpcd.c +@@ -364,7 +364,7 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx) + errno = ENOSYS; + return; + #else +- int i; ++ int exit_code; + + if (ctx->options & DHCPCD_DAEMONISE && + !(ctx->options & (DHCPCD_DAEMONISED | DHCPCD_NOWAITIP))) +@@ -385,16 +385,19 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx) + return; + + #ifdef PRIVSEP +- ps_daemonised(ctx); ++ if (IN_PRIVSEP(ctx)) ++ ps_daemonised(ctx); ++ else + #else +- dhcpcd_daemonised(ctx); ++ dhcpcd_daemonised(ctx); + #endif + +- i = EXIT_SUCCESS; +- if (write(ctx->fork_fd, &i, sizeof(i)) == -1) +- logerr("write"); +- ctx->options |= DHCPCD_DAEMONISED; +- // dhcpcd_fork_cb will close the socket ++ eloop_event_delete(ctx->eloop, ctx->fork_fd); ++ exit_code = EXIT_SUCCESS; ++ if (write(ctx->fork_fd, &exit_code, sizeof(exit_code)) == -1) ++ logerr(__func__); ++ close(ctx->fork_fd); ++ ctx->fork_fd = -1; + #endif + } + +@@ -1814,30 +1817,6 @@ dhcpcd_readdump(struct dhcpcd_ctx *ctx) + dhcpcd_readdump0, ctx); + } + +-static void +-dhcpcd_stderr_cb(void *arg, unsigned short events) +-{ +- struct dhcpcd_ctx *ctx = arg; +- char log[BUFSIZ]; +- ssize_t len; +- +- if (events & ELE_HANGUP) +- eloop_exit(ctx->eloop, EXIT_SUCCESS); +- +- if (!(events & ELE_READ)) +- return; +- +- len = read(ctx->stderr_fd, log, sizeof(log) - 1); +- if (len == -1) { +- if (errno != ECONNRESET) +- logerr(__func__); +- return; +- } +- +- log[len] = '\0'; +- fprintf(stderr, "%s", log); +-} +- + static void + dhcpcd_fork_cb(void *arg, unsigned short events) + { +@@ -1928,7 +1907,7 @@ main(int argc, char **argv, char **envp) + ssize_t len; + #if defined(USE_SIGNALS) || !defined(THERE_IS_NO_FORK) + pid_t pid; +- int fork_fd[2], stderr_fd[2]; ++ int fork_fd[2]; + #endif + #ifdef USE_SIGNALS + int sig = 0; +@@ -2013,22 +1992,17 @@ main(int argc, char **argv, char **envp) + TAILQ_INIT(&ctx.ps_processes); + #endif + +- /* Check our streams for validity */ +- ctx.stdin_valid = fcntl(STDIN_FILENO, F_GETFD) != -1; +- ctx.stdout_valid = fcntl(STDOUT_FILENO, F_GETFD) != -1; +- ctx.stderr_valid = fcntl(STDERR_FILENO, F_GETFD) != -1; ++ logopts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID; + +- /* Even we if we don't have input/outputs, we need to +- * ensure they are setup for shells. */ +- if (!ctx.stdin_valid) ++ /* Ensure we have stdin, stdout and stderr file descriptors. ++ * This is important as we do run scripts which expect these. */ ++ if (fcntl(STDIN_FILENO, F_GETFD) == -1) + dup_null(STDIN_FILENO); +- if (!ctx.stdout_valid) ++ if (fcntl(STDOUT_FILENO, F_GETFD) == -1) + dup_null(STDOUT_FILENO); +- if (!ctx.stderr_valid) ++ if (fcntl(STDERR_FILENO, F_GETFD) == -1) + dup_null(STDERR_FILENO); +- +- logopts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID; +- if (ctx.stderr_valid) ++ else + logopts |= LOGERR_ERR; + + i = 0; +@@ -2398,17 +2372,13 @@ main(int argc, char **argv, char **envp) + loginfox(PACKAGE "-" VERSION " starting"); + + // We don't need stdin past this point +- if (ctx.stdin_valid) +- dup_null(STDIN_FILENO); ++ dup_null(STDIN_FILENO); + + #if defined(USE_SIGNALS) && !defined(THERE_IS_NO_FORK) + if (!(ctx.options & DHCPCD_DAEMONISE)) + goto start_manager; + +- if (xsocketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CXNB, 0, fork_fd) == -1 || +- (ctx.stderr_valid && +- xsocketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CXNB, 0, stderr_fd) == -1)) +- { ++ if (xsocketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CXNB, 0, fork_fd) == -1) { + logerr("socketpair"); + goto exit_failure; + } +@@ -2429,22 +2399,6 @@ main(int argc, char **argv, char **envp) + dhcpcd_fork_cb, &ctx) == -1) + logerr("%s: eloop_event_add", __func__); + +- /* +- * Redirect stderr to the stderr socketpair. +- * Redirect stdout as well. +- * dhcpcd doesn't output via stdout, but something in +- * a called script might. +- */ +- if (ctx.stderr_valid) { +- if (dup2(stderr_fd[1], STDERR_FILENO) == -1 || +- (ctx.stdout_valid && +- dup2(stderr_fd[1], STDOUT_FILENO) == -1)) +- logerr("dup2"); +- close(stderr_fd[0]); +- close(stderr_fd[1]); +- } else if (ctx.stdout_valid) +- dup_null(STDOUT_FILENO); +- + if (setsid() == -1) { + logerr("%s: setsid", __func__); + goto exit_failure; +@@ -2478,19 +2432,6 @@ main(int argc, char **argv, char **envp) + dhcpcd_fork_cb, &ctx) == -1) + logerr("%s: eloop_event_add", __func__); + +- if (ctx.stderr_valid) { +- ctx.stderr_fd = stderr_fd[0]; +- close(stderr_fd[1]); +-#ifdef PRIVSEP_RIGHTS +- if (ps_rights_limit_fd(ctx.stderr_fd) == 1) { +- logerr("ps_rights_limit_fd"); +- goto exit_failure; +- } +-#endif +- if (eloop_event_add(ctx.eloop, ctx.stderr_fd, ELE_READ, +- dhcpcd_stderr_cb, &ctx) == -1) +- logerr("%s: eloop_event_add", __func__); +- } + #ifdef PRIVSEP + if (IN_PRIVSEP(&ctx) && ps_managersandbox(&ctx, NULL) == -1) + goto exit_failure; +@@ -2602,6 +2543,7 @@ main(int argc, char **argv, char **envp) + if (ifp->active == IF_ACTIVE_USER) + break; + } ++ + if (ifp == NULL) { + if (ctx.ifc == 0) { + int loglevel; +@@ -2735,24 +2677,22 @@ main(int argc, char **argv, char **envp) + if (ps_stopwait(&ctx) != EXIT_SUCCESS) + i = EXIT_FAILURE; + #endif +- if (ctx.options & DHCPCD_STARTED && !(ctx.options & DHCPCD_FORKED)) { ++ if (ctx.options & DHCPCD_STARTED && !(ctx.options & DHCPCD_FORKED)) + loginfox(PACKAGE " exited"); +-#ifdef USE_SIGNALS +- /* Detach from the launch process. +- * This *should* happen after we stop the root process, +- * but for some reason non privsep builds get a zero length +- * read in dhcpcd_fork_cb(). */ +- if (ctx.fork_fd != -1) { +- if (write(ctx.fork_fd, &i, sizeof(i)) == -1) +- logerr("%s: write", __func__); +- } +-#endif +- } + #ifdef PRIVSEP + if (ps_root_stop(&ctx) == -1) + i = EXIT_FAILURE; + eloop_free(ctx.ps_eloop); + #endif ++ ++#ifdef USE_SIGNALS ++ /* If still attached, detach from the launcher */ ++ if (ctx.options & DHCPCD_STARTED && ctx.fork_fd != -1) { ++ if (write(ctx.fork_fd, &i, sizeof(i)) == -1) ++ logerr("%s: write", __func__); ++ } ++#endif ++ + eloop_free(ctx.eloop); + logclose(); + free(ctx.logfile); +@@ -2760,6 +2700,7 @@ main(int argc, char **argv, char **envp) + #ifdef SETPROCTITLE_H + setproctitle_fini(); + #endif ++ + #ifdef USE_SIGNALS + if (ctx.options & (DHCPCD_FORKED | DHCPCD_PRIVSEP)) + _exit(i); /* so atexit won't remove our pidfile */ +diff --git a/src/dhcpcd.h b/src/dhcpcd.h +index 918dc687..7fee0604 100644 +--- a/src/dhcpcd.h ++++ b/src/dhcpcd.h +@@ -116,10 +116,6 @@ struct passwd; + struct dhcpcd_ctx { + char pidfile[sizeof(PIDFILE) + IF_NAMESIZE + 1]; + char vendor[256]; +- bool stdin_valid; /* It's possible stdin, stdout and stderr */ +- bool stdout_valid; /* could be closed when dhcpcd starts. */ +- bool stderr_valid; +- int stderr_fd; /* FD for logging to stderr */ + int fork_fd; /* FD for the fork init signal pipe */ + const char *cffile; + unsigned long long options; +diff --git a/src/privsep.c b/src/privsep.c +index c3aeab8d..2decb8b8 100644 +--- a/src/privsep.c ++++ b/src/privsep.c +@@ -172,8 +172,7 @@ ps_dropprivs(struct dhcpcd_ctx *ctx) + * Obviously this won't work if we are using a logfile + * or redirecting stderr to a file. */ + if ((ctx->options & DHC_NOCHKIO) == DHC_NOCHKIO || +- (ctx->logfile == NULL && +- (!ctx->stderr_valid || isatty(STDERR_FILENO) == 1))) ++ (ctx->logfile == NULL && isatty(STDERR_FILENO) == 1)) + { + if (setrlimit(RLIMIT_FSIZE, &rzero) == -1) + logerr("setrlimit RLIMIT_FSIZE"); +@@ -305,14 +304,11 @@ ps_rights_limit_stdio(struct dhcpcd_ctx *ctx) + const int iebadf = CAPH_IGNORE_EBADF; + int error = 0; + +- if (ctx->stdin_valid && +- caph_limit_stream(STDIN_FILENO, CAPH_READ | iebadf) == -1) ++ if (caph_limit_stream(STDIN_FILENO, CAPH_READ | iebadf) == -1) + error = -1; +- if (ctx->stdout_valid && +- caph_limit_stream(STDOUT_FILENO, CAPH_WRITE | iebadf) == -1) ++ if (caph_limit_stream(STDOUT_FILENO, CAPH_WRITE | iebadf) == -1) + error = -1; +- if (ctx->stderr_valid && +- caph_limit_stream(STDERR_FILENO, CAPH_WRITE | iebadf) == -1) ++ if (caph_limit_stream(STDERR_FILENO, CAPH_WRITE | iebadf) == -1) + error = -1; + + return error; + +From 8d12632c670f02d8a685e80c8abad7049d3dd18f Mon Sep 17 00:00:00 2001 +From: Roy Marples +Date: Mon, 13 Nov 2023 15:54:50 +0000 +Subject: [PATCH 05/12] Fix privsep builds for prior. + +--- + src/dhcpcd.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/dhcpcd.c b/src/dhcpcd.c +index 17af1a05..5f8fc02b 100644 +--- a/src/dhcpcd.c ++++ b/src/dhcpcd.c +@@ -388,9 +388,8 @@ dhcpcd_daemonise(struct dhcpcd_ctx *ctx) + if (IN_PRIVSEP(ctx)) + ps_daemonised(ctx); + else +-#else +- dhcpcd_daemonised(ctx); + #endif ++ dhcpcd_daemonised(ctx); + + eloop_event_delete(ctx->eloop, ctx->fork_fd); + exit_code = EXIT_SUCCESS; + +From 6788608eb0fcd32fd23974100cdd42d3174cb8d1 Mon Sep 17 00:00:00 2001 +From: Roy Marples +Date: Mon, 13 Nov 2023 16:05:04 +0000 +Subject: [PATCH 06/12] Fix an unused var warning for capsicum for prior + +--- + src/privsep.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/privsep.c b/src/privsep.c +index 2decb8b8..4cca12ee 100644 +--- a/src/privsep.c ++++ b/src/privsep.c +@@ -299,7 +299,7 @@ ps_rights_limit_fdpair(int fd[]) + } + + static int +-ps_rights_limit_stdio(struct dhcpcd_ctx *ctx) ++ps_rights_limit_stdio() + { + const int iebadf = CAPH_IGNORE_EBADF; + int error = 0; +@@ -452,7 +452,7 @@ ps_startprocess(struct ps_process *psp, + ctx->ps_log_root_fd = -1; + } + #ifdef PRIVSEP_RIGHTS +- if (ps_rights_limit_stdio(ctx) == -1) { ++ if (ps_rights_limit_stdio() == -1) { + logerr("ps_rights_limit_stdio"); + goto errexit; + } +@@ -666,7 +666,7 @@ ps_managersandbox(struct dhcpcd_ctx *ctx, const char *_pledge) + #ifdef PRIVSEP_RIGHTS + if ((ctx->pf_inet_fd != -1 && + ps_rights_limit_ioctl(ctx->pf_inet_fd) == -1) || +- ps_rights_limit_stdio(ctx) == -1) ++ ps_rights_limit_stdio() == -1) + { + logerr("%s: cap_rights_limit", __func__); + return -1; + +From e337bd7ce4a8a53d0ee6bf8cc0f4fd2b135943a4 Mon Sep 17 00:00:00 2001 +From: Roy Marples +Date: Sun, 10 Dec 2023 08:27:30 +0000 +Subject: [PATCH 07/12] Document that limiting address protocol can affect + signalling dhcpcd + +Fixes #264 +--- + src/dhcpcd.8.in | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/src/dhcpcd.8.in b/src/dhcpcd.8.in +index 4cd092e5..f4508761 100644 +--- a/src/dhcpcd.8.in ++++ b/src/dhcpcd.8.in +@@ -24,7 +24,7 @@ + .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + .\" SUCH DAMAGE. + .\" +-.Dd August 31, 2022 ++.Dd December 10, 2022 + .Dt DHCPCD 8 + .Os + .Sh NAME +@@ -186,13 +186,16 @@ The + .Fl w , Fl Fl waitip + option is enabled in this instance to maintain compatibility with older + versions. +-Using a single interface also affects the ++Using a single interface, ++optionally further limited to an address protocol, ++also affects the + .Fl k , + .Fl N , + .Fl n + and + .Fl x +-options, where the same interface will need to be specified, as a lack of an ++options, where the same interface and any address protocol ++will need to be specified, as a lack of an + interface will imply Manager mode which this is not. + To force starting in Manager mode with only one interface, the + .Fl M , Fl Fl manager + +From 0a0bbfe74eb2dda8a4594a7a3547dd73456a0df0 Mon Sep 17 00:00:00 2001 +From: Roy Marples +Date: Tue, 12 Dec 2023 07:13:29 +0000 +Subject: [PATCH 08/12] Fix year + +--- + src/dhcpcd.8.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/dhcpcd.8.in b/src/dhcpcd.8.in +index f4508761..93232840 100644 +--- a/src/dhcpcd.8.in ++++ b/src/dhcpcd.8.in +@@ -24,7 +24,7 @@ + .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + .\" SUCH DAMAGE. + .\" +-.Dd December 10, 2022 ++.Dd December 10, 2023 + .Dt DHCPCD 8 + .Os + .Sh NAME + +From 411e6539fd242224b320782eac4b4769f13a81fe Mon Sep 17 00:00:00 2001 +From: Roy Marples +Date: Sun, 10 Dec 2023 07:34:19 +0000 +Subject: [PATCH 09/12] Fully configure an interface when being activated. + +We need the full configuration - for example dhcpcd.conf +might have environment options for the hooks for the interface +being activated. + +Because we now guard against starting protocols with IF_ACTIVE_USER +this is safe. + +Fixes #257. +--- + src/dhcpcd.c | 35 ++++++++++++----------------------- + src/if-options.c | 2 +- + src/if-options.h | 1 - + 3 files changed, 13 insertions(+), 25 deletions(-) + +diff --git a/src/dhcpcd.c b/src/dhcpcd.c +index 5f8fc02b..3571aae0 100644 +--- a/src/dhcpcd.c ++++ b/src/dhcpcd.c +@@ -657,20 +657,17 @@ configure_interface(struct interface *ifp, int argc, char **argv, + } + + static void +-dhcpcd_initstate2(struct interface *ifp, unsigned long long options) ++dhcpcd_initstate1(struct interface *ifp, int argc, char **argv, ++ unsigned long long options) + { + struct if_options *ifo; + +- if (options) { +- if ((ifo = default_config(ifp->ctx)) == NULL) { +- logerr(__func__); +- return; +- } +- ifo->options |= options; +- free(ifp->options); +- ifp->options = ifo; +- } else +- ifo = ifp->options; ++ configure_interface(ifp, argc, argv, options); ++ if (!ifp->active) ++ return; ++ ++ ifo = ifp->options; ++ ifo->options |= options; + + #ifdef INET6 + if (ifo->options & DHCPCD_IPV6 && ipv6_init(ifp->ctx) == -1) { +@@ -680,16 +677,6 @@ dhcpcd_initstate2(struct interface *ifp, unsigned long long options) + #endif + } + +-static void +-dhcpcd_initstate1(struct interface *ifp, int argc, char **argv, +- unsigned long long options) +-{ +- +- configure_interface(ifp, argc, argv, options); +- if (ifp->active) +- dhcpcd_initstate2(ifp, 0); +-} +- + static void + dhcpcd_initstate(struct interface *ifp, unsigned long long options) + { +@@ -1033,15 +1020,17 @@ dhcpcd_activateinterface(struct interface *ifp, unsigned long long options) + if (ifp->active) + return; + ++ /* IF_ACTIVE_USER will start protocols when the interface is started. ++ * IF_ACTIVE will ask the protocols for setup, ++ * such as any delegated prefixes. */ + ifp->active = IF_ACTIVE; +- dhcpcd_initstate2(ifp, options); ++ dhcpcd_initstate(ifp, options); + + /* It's possible we might not have been able to load + * a config. */ + if (!ifp->active) + return; + +- configure_interface1(ifp); + run_preinit(ifp); + dhcpcd_prestartinterface(ifp); + } +diff --git a/src/if-options.c b/src/if-options.c +index 9c930f38..b28e4ee2 100644 +--- a/src/if-options.c ++++ b/src/if-options.c +@@ -2407,7 +2407,7 @@ finish_config(struct if_options *ifo) + ~(DHCPCD_IPV6RA_AUTOCONF | DHCPCD_IPV6RA_REQRDNSS); + } + +-struct if_options * ++static struct if_options * + default_config(struct dhcpcd_ctx *ctx) + { + struct if_options *ifo; +diff --git a/src/if-options.h b/src/if-options.h +index b37a08d3..53914655 100644 +--- a/src/if-options.h ++++ b/src/if-options.h +@@ -285,7 +285,6 @@ struct if_options { + struct auth auth; + }; + +-struct if_options *default_config(struct dhcpcd_ctx *); + struct if_options *read_config(struct dhcpcd_ctx *, + const char *, const char *, const char *); + int add_options(struct dhcpcd_ctx *, const char *, + +From c7a142affe8f4ef989e58fb8ef93a6e7a6244fca Mon Sep 17 00:00:00 2001 +From: Roy Marples +Date: Mon, 18 Dec 2023 12:15:10 +0000 +Subject: [PATCH 10/12] DHCP6: Improve logging when changing IA type + +Changing from PD to IA or IA to PD can result in a diagnostic +when there is no address to confirm AND we haven't loaded +a lease. +This improves the check and no more Success errors should +be reported. +--- + src/dhcp6.c | 22 ++++++++++------------ + 1 file changed, 10 insertions(+), 12 deletions(-) + +diff --git a/src/dhcp6.c b/src/dhcp6.c +index 63fe2dc6..6703f5cf 100644 +--- a/src/dhcp6.c ++++ b/src/dhcp6.c +@@ -2589,21 +2589,17 @@ dhcp6_validatelease(struct interface *ifp, + } + state->has_no_binding = false; + nia = dhcp6_findia(ifp, m, len, sfrom, acquired); +- if (nia == 0) { +- if (state->state != DH6S_CONFIRM && ok_errno != 0) { +- logerrx("%s: no useable IA found in lease", ifp->name); +- return -1; +- } +- +- /* We are confirming and have an OK, +- * so look for ia's in our old lease. +- * IA's must have existed here otherwise we would +- * have rejected it earlier. */ +- assert(state->new != NULL && state->new_len != 0); ++ if (nia == 0 && state->state == DH6S_CONFIRM && ok_errno == 0 && ++ state->new && state->new_len) ++ { + state->has_no_binding = false; + nia = dhcp6_findia(ifp, state->new, state->new_len, + sfrom, acquired); + } ++ if (nia == 0) { ++ logerrx("%s: no useable IA found in lease", ifp->name); ++ return -1; ++ } + return nia; + } + +@@ -2657,8 +2653,10 @@ dhcp6_readlease(struct interface *ifp, int validate) + /* Check to see if the lease is still valid */ + fd = dhcp6_validatelease(ifp, &buf.dhcp6, (size_t)bytes, NULL, + &state->acquired); +- if (fd == -1) ++ if (fd == -1) { ++ bytes = 0; /* We have already reported the error */ + goto ex; ++ } + + if (state->expire != ND6_INFINITE_LIFETIME && + (time_t)state->expire < now - mtime && + +From 01de6f23d323236b44d6d952fa0dab183db1d009 Mon Sep 17 00:00:00 2001 +From: Roy Marples +Date: Mon, 18 Dec 2023 12:22:13 +0000 +Subject: [PATCH 11/12] DHCP6: For Prefix Delegation, the - interface means no + assignment + +- is an invalid interface name. +So we take this to mean don't assign the Delegated Prefix to +any interfaces. +The reject route for the Delegated Prefix is still installed. + +Fixes #270 +--- + src/dhcp6.c | 5 +++-- + src/dhcpcd.conf.5.in | 4 +++- + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/src/dhcp6.c b/src/dhcp6.c +index 6703f5cf..bdc3664e 100644 +--- a/src/dhcp6.c ++++ b/src/dhcp6.c +@@ -3871,8 +3871,9 @@ dhcp6_activateinterfaces(struct interface *ifp) + sla = &ia->sla[j]; + ifd = if_find(ifp->ctx->ifaces, sla->ifname); + if (ifd == NULL) { +- logwarn("%s: cannot delegate to %s", +- ifp->name, sla->ifname); ++ if (*sla->ifname != '-') ++ logwarn("%s: cannot delegate to %s", ++ ifp->name, sla->ifname); + continue; + } + if (!ifd->active) { +diff --git a/src/dhcpcd.conf.5.in b/src/dhcpcd.conf.5.in +index 566b3727..878cdb8e 100644 +--- a/src/dhcpcd.conf.5.in ++++ b/src/dhcpcd.conf.5.in +@@ -24,7 +24,7 @@ + .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + .\" SUCH DAMAGE. + .\" +-.Dd October 4, 2023 ++.Dd December 18, 2023 + .Dt DHCPCD.CONF 5 + .Os + .Sh NAME +@@ -359,6 +359,7 @@ Otherwise addresses are only assigned for each + .Ar interface + and + .Ar sla_id . ++To avoid delegating to any interface, use - as the invalid interface name. + Each assigned address will have a + .Ar suffix , + defaulting to 1. +@@ -415,6 +416,7 @@ interface eth0 + ia_na 1 # request an IPv6 address + ia_pd 2 eth1/0 # request a PD and assign it to eth1 + ia_pd 3 eth2/1 eth3/2 # req a PD and assign it to eth2 and eth3 ++ ia_pd 4 - # request a PD but don't assign it + .Ed + .It Ic ipv4only + Only configure IPv4. + +From 1c8ae59836fa87b4c63c598087f0460ec20ed862 Mon Sep 17 00:00:00 2001 +From: Roy Marples +Date: Mon, 18 Dec 2023 15:39:51 +0000 +Subject: [PATCH 12/12] Release dhcpcd-10.0.6 + +--- + src/defs.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/defs.h b/src/defs.h +index a2b1f890..c46b2e54 100644 +--- a/src/defs.h ++++ b/src/defs.h +@@ -29,7 +29,7 @@ + #define DEFS_H + + #define PACKAGE "dhcpcd" +-#define VERSION "10.0.5" ++#define VERSION "10.0.6" + + #ifndef PRIVSEP_USER + # define PRIVSEP_USER "_" PACKAGE diff --git a/odysseus/odysseus_tree/patches/psplash/01config.patch b/odysseus/odysseus_tree/patches/psplash/01config.patch new file mode 100644 index 00000000..609b4006 --- /dev/null +++ b/odysseus/odysseus_tree/patches/psplash/01config.patch @@ -0,0 +1,18 @@ +diff --git a/psplash-config.h b/psplash-config.h +index eb90ef3..e98bdde 100644 +--- a/psplash-config.h ++++ b/psplash-config.h +@@ -23,11 +23,11 @@ + + /* Bool indicated if the progress bar should be disabled */ + #ifndef PSPLASH_DISABLE_PROGRESS_BAR +-#define PSPLASH_SHOW_PROGRESS_BAR 1 ++#define PSPLASH_SHOW_PROGRESS_BAR 0 + #endif + + /* Position of the image split from top edge, numerator of fraction */ +-#define PSPLASH_IMG_SPLIT_NUMERATOR 5 ++#define PSPLASH_IMG_SPLIT_NUMERATOR 6 + + /* Position of the image split from top edge, denominator of fraction */ + #define PSPLASH_IMG_SPLIT_DENOMINATOR 6 diff --git a/odysseus/odysseus_tree/patches/psplash/02colors.patch b/odysseus/odysseus_tree/patches/psplash/02colors.patch new file mode 100644 index 00000000..55189754 --- /dev/null +++ b/odysseus/odysseus_tree/patches/psplash/02colors.patch @@ -0,0 +1,13 @@ +diff --git a/psplash-colors.h b/psplash-colors.h +index 82a9893..14d6eff 100644 +--- a/psplash-colors.h ++++ b/psplash-colors.h +@@ -12,7 +12,7 @@ + #define _HAVE_PSPLASH_COLORS_H + + /* This is the overall background color */ +-#define PSPLASH_BACKGROUND_COLOR 0xec,0xec,0xe1 ++#define PSPLASH_BACKGROUND_COLOR 0x0,0x0,0x0 + + /* This is the color of any text output */ + #define PSPLASH_TEXT_COLOR 0x6d,0x6d,0x70 diff --git a/odysseus/odysseus_tree/post-build-ap.sh b/odysseus/odysseus_tree/post-build-ap.sh new file mode 100755 index 00000000..205923d6 --- /dev/null +++ b/odysseus/odysseus_tree/post-build-ap.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +python3 "$BR2_EXTERNAL_ODY_TREE_PATH"/overlays/rootfs_overlay_nrc_common/usr/bin/build_nrc_params.py AP --ini-path "$BR2_EXTERNAL_ODY_TREE_PATH"/overlays/rootfs_overlay_ap/etc/nrc_opts_ap.ini --mod-path "$TARGET_DIR"/etc/modprobe.d/nrc.conf diff --git a/odysseus/odysseus_tree/post-build-base-connect.sh b/odysseus/odysseus_tree/post-build-base-connect.sh new file mode 100755 index 00000000..7d18d35d --- /dev/null +++ b/odysseus/odysseus_tree/post-build-base-connect.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +# hashes the password so it cannot be read in a dsitributed image (does not secure wifi!) +# this regex extras the part after psk= +hashed_block=$(wpa_passphrase "H68K" "$ODY_BASE_WIFI_PASSWORD" | sed -n -e 's/^.*[[:space:]]psk=//p') + +# this replaces the psk in the target directory with the hashed block found above +sed -i "s/\(psk=\)\(.*\)/\1$hashed_block/" "$TARGET_DIR"/etc/wpa_supplicant_base.conf diff --git a/odysseus/odysseus_tree/post-build-os-release.sh b/odysseus/odysseus_tree/post-build-os-release.sh new file mode 100755 index 00000000..b93e3ce0 --- /dev/null +++ b/odysseus/odysseus_tree/post-build-os-release.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +FILE="$TARGET_DIR/etc/os-release-ody" + +# if file exists, clear it +if test -f "$FILE"; +then + rm "$FILE" +fi + +# ensure file exists +touch "$FILE" || exit + +# push a param to FILE, first arg is name second is value +push_param() { + cat <<< "$1=$2" >> "$FILE" +} + +# change dirs for fetching git info +cd "$BR2_EXTERNAL_ODY_TREE_PATH"/../githistory/ || exit +# hacky way to allow portable git file to work +git config --global --add safe.directory $PWD + +# https://www.freedesktop.org/software/systemd/man/latest/os-release.html#General%20information%20identifying%20the%20operating%20system +push_param "NAME" "NER Odysseus" +push_param "ID" "odysseus" +push_param "ID_LIKE" "buildroot" +push_param "PRETTY_NAME" "NER Odysseus v$(git describe --tags $(git rev-list --tags --max-count=1))" +# 2nd argument into this file is the name of the defconfig +if [[ "$2" == "TPU" ]]; +then + variant="Built for Telemetry Processing Unit" + variantid="tpu" +elif [[ "$2" == "AP" ]]; +then + variant="Built for HaLow Access Point" + variantid="ap" + +elif [[ "$2" == "IROH" ]]; +then + variant="Built for Iroh Charging Scraper" + variant="iroh" +else + variant="UK" + variantid="uk" +fi + +push_param "VARIANT" "$variant" +push_param "VARIANT_ID" "$variantid" + +# https://www.freedesktop.org/software/systemd/man/latest/os-release.html#Information%20about%20the%20version%20of%20the%20operating%20system +push_param "VERSION" "$(git describe --tags $(git rev-list --tags --max-count=1))" # latest tag +push_param "VERSION_ID" "$(git describe --tags $(git rev-list --tags --max-count=1))" +# VERSION_CODENAME unimplemented + +push_param "BUILD_ID" "$(date +"%Y-%m-%dT%H:%M:%S%z")" # time of build finish +push_param "IMAGE_ID" "$(git rev-parse --abbrev-ref HEAD)" # branch name +push_param "IMAGE_VERSION" "$(git rev-parse HEAD)" # current sha + +# https://www.freedesktop.org/software/systemd/man/latest/os-release.html#Presentation%20information%20and%20links +push_param "HOME_URL" "https://github.com/Northeastern-Electric-Racing/Odysseus" +push_param "VENDOR_NAME" "Northeastern Electric Racing" diff --git a/odysseus/odysseus_tree/post-build-sta.sh b/odysseus/odysseus_tree/post-build-sta.sh new file mode 100755 index 00000000..fb8d1c09 --- /dev/null +++ b/odysseus/odysseus_tree/post-build-sta.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +# add nrc modprobe based on ini config +python3 "$BR2_EXTERNAL_ODY_TREE_PATH"/overlays/rootfs_overlay_nrc_common/usr/bin/build_nrc_params.py STA --ini-path "$BR2_EXTERNAL_ODY_TREE_PATH"/overlays/rootfs_overlay_tpu/etc/nrc_opts_sta.ini --mod-path "$TARGET_DIR"/etc/modprobe.d/nrc.conf + diff --git a/odysseus/odysseus_tree/pre-make-ap.sh b/odysseus/odysseus_tree/pre-make-ap.sh deleted file mode 100755 index 88e4cea3..00000000 --- a/odysseus/odysseus_tree/pre-make-ap.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -python3 "$BR2_EXTERNAL_ODY_TREE_PATH"/utils/build_nrc_params.py 1 "$BR2_EXTERNAL_ODY_TREE_PATH"/overlays/rootfs_overlay_ap/etc/nrc_opts_ap.ini "$BR2_EXTERNAL_ODY_TREE_PATH"/overlays/rootfs_overlay_ap/etc/modprobe.d/nrc.conf diff --git a/odysseus/odysseus_tree/pre-make-sta.sh b/odysseus/odysseus_tree/pre-make-sta.sh deleted file mode 100755 index 72779397..00000000 --- a/odysseus/odysseus_tree/pre-make-sta.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -python3 "$BR2_EXTERNAL_ODY_TREE_PATH"/utils/build_nrc_params.py 0 "$BR2_EXTERNAL_ODY_TREE_PATH"/overlays/rootfs_overlay_tpu/etc/nrc_opts_sta.ini "$BR2_EXTERNAL_ODY_TREE_PATH"/overlays/rootfs_overlay_tpu/etc/modprobe.d/nrc.conf diff --git a/odysseus/odysseus_tree/sources/Nero-2.0 b/odysseus/odysseus_tree/sources/Nero-2.0 index 75140253..e892fead 160000 --- a/odysseus/odysseus_tree/sources/Nero-2.0 +++ b/odysseus/odysseus_tree/sources/Nero-2.0 @@ -1 +1 @@ -Subproject commit 7514025389f04a5c98c333bae5e278784521c6d7 +Subproject commit e892fead79028f171f0687a4ae33c525b91791a1 diff --git a/odysseus/odysseus_tree/sources/tpu_telemetry/.gitignore b/odysseus/odysseus_tree/sources/tpu_telemetry/.gitignore index eeb8a6ec..0e974625 100644 --- a/odysseus/odysseus_tree/sources/tpu_telemetry/.gitignore +++ b/odysseus/odysseus_tree/sources/tpu_telemetry/.gitignore @@ -1 +1,2 @@ **/__pycache__ +env/ diff --git a/odysseus/odysseus_tree/sources/tpu_telemetry/README.md b/odysseus/odysseus_tree/sources/tpu_telemetry/README.md new file mode 100644 index 00000000..4fab4144 --- /dev/null +++ b/odysseus/odysseus_tree/sources/tpu_telemetry/README.md @@ -0,0 +1,27 @@ +# TPU Telemetry + +## Setup +In order to run the virtual environment, cd into this directory and run the following commands: + - `python3 -m venv env` + - `activate` + +From Linux: + - `source env/bin/activate` + +Then install the required dependencies: + - `pip install -r requirements.txt` + + +### Code regen +Before you can use the publishing script, you must use Protobuf (must have the compiler downloaded and included in PATH. see tutorial: https://protobuf.dev/getting-started/pythontutorial/, and latest protoc release: https://protobuf.dev/downloads/) to serialize the data. Move into the publishing directory: + - `cd ./telemetry ` + +and run the command + - `protoc --python_out="." "server_data.proto"` + +You're now prepared to work with the telemetry script: + - `python3 -m telemetry.publish` + + +## Edit TPU Install +TPU is installed differently. In order to edit enter the `/usr/lib/tpu-telemetry/` directory and edit the python sources. Ensure the system script is off (`/etc/init.d/S*tpu-telemetry stop`) and then run `tpu-telemetry` to test your edits. diff --git a/odysseus/odysseus_tree/sources/tpu_telemetry/requirements.txt b/odysseus/odysseus_tree/sources/tpu_telemetry/requirements.txt new file mode 100644 index 00000000..6ea8a730 --- /dev/null +++ b/odysseus/odysseus_tree/sources/tpu_telemetry/requirements.txt @@ -0,0 +1,3 @@ +protobuf +psutil +gmqtt \ No newline at end of file diff --git a/odysseus/odysseus_tree/sources/tpu_telemetry/telemetry/poll_data/__init__.py b/odysseus/odysseus_tree/sources/tpu_telemetry/telemetry/poll_data/__init__.py index 139597f9..8b137891 100644 --- a/odysseus/odysseus_tree/sources/tpu_telemetry/telemetry/poll_data/__init__.py +++ b/odysseus/odysseus_tree/sources/tpu_telemetry/telemetry/poll_data/__init__.py @@ -1,2 +1 @@ - diff --git a/odysseus/odysseus_tree/sources/tpu_telemetry/telemetry/poll_data/gps_data.py b/odysseus/odysseus_tree/sources/tpu_telemetry/telemetry/poll_data/gps_data.py new file mode 100644 index 00000000..406207ef --- /dev/null +++ b/odysseus/odysseus_tree/sources/tpu_telemetry/telemetry/poll_data/gps_data.py @@ -0,0 +1,55 @@ +from subprocess import check_output +from .. import measurement +import gps + +session = gps.gps(mode=gps.WATCH_ENABLE) + + +@measurement(1000) +def fetch_data_location(): + try: + if 0 == session.read() and session.valid and gps.isfinite(session.fix.latitude) and gps.isfinite(session.fix.longitude): + tempLat = session.fix.latitude + tempLong = session.fix.longitude + return [("TPU/GPS/Location", [str(tempLat), str(tempLong)], "coordinate")] + else: + return [] + except Exception as e: + print(f"Failed to fetch data: {e}") + return [] + + +@measurement(1000) +def fetch_data_speed(): + try: + if 0 == session.read() and session.valid and gps.isfinite(session.fix.speed): + tempSpeed = session.fix.speed + return [("TPU/GPS/GroundSpeed", [str(tempSpeed)], "knot")] + else: + return [] + except Exception as e: + print(f"Failed to fetch data: {e}") + return [] + + +@measurement(1000) +def fetch_data_mode(): + try: + if 0 == session.read() and session.valid: + tempMode = session.fix.mode + return [("TPU/GPS/Mode", [str(tempMode)], "enum")] + else: + return [] + except Exception as e: + print(f"Failed to fetch data: {e}") + return [] + + +def main(): + print(fetch_data_location()) + print(fetch_data_speed()) + print(fetch_data_mode()) + + +if __name__ == "__main__": + main() diff --git a/odysseus/odysseus_tree/sources/tpu_telemetry/telemetry/server_data_pb2.py b/odysseus/odysseus_tree/sources/tpu_telemetry/telemetry/server_data_pb2.py index f2dc8aa5..4f5e18cb 100644 --- a/odysseus/odysseus_tree/sources/tpu_telemetry/telemetry/server_data_pb2.py +++ b/odysseus/odysseus_tree/sources/tpu_telemetry/telemetry/server_data_pb2.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # Generated by the protocol buffer compiler. DO NOT EDIT! # source: server_data.proto -# Protobuf Python Version: 4.25.3 +# Protobuf Python Version: 5.26.0 """Generated protocol buffer code.""" from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool @@ -19,8 +19,8 @@ _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'server_data_pb2', _globals) -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR._options = None +if not _descriptor._USE_C_DESCRIPTORS: + DESCRIPTOR._loaded_options = None _globals['_SERVERDATA']._serialized_start=36 _globals['_SERVERDATA']._serialized_end=77 # @@protoc_insertion_point(module_scope) diff --git a/odysseus/odysseus_tree/utils/build_nrc_params.py b/odysseus/odysseus_tree/utils/build_nrc_params.py deleted file mode 120000 index 4c21eb76..00000000 --- a/odysseus/odysseus_tree/utils/build_nrc_params.py +++ /dev/null @@ -1 +0,0 @@ -../overlays/rootfs_overlay_nrc_common/usr/bin/build_nrc_params.py \ No newline at end of file