## Local HTTP/HTTPS Setup with Custom CA This project provides a dual-port Streamlit server setup for local networks: - **HTTP** available on port **8502** - **HTTPS** (trusted with custom CA) available on port **8503** ### How it works - A custom Certificate Authority (CA) is generated for your organization. - Each device/server is issued a certificate signed by this CA. - Customers can import the CA certificate into their OS/browser trust store, so the device's HTTPS connection is fully trusted (no browser warnings). ### Usage 1. **Generate Certificates** - Run `generate_ca_cert.sh` in `src/auracast/server/`. - This creates: - `certs/ca/ca_cert.pem` / `ca_key.pem` (CA cert/key) - **Distribute `ca_cert.pem` or `ca_cert.crt` to customers** for installation in their trust store. - This is a one-time operation for your organization. 2. **Start the Server** - Run `run_http_and_https.sh` in `src/auracast/server/`. - This starts: - HTTP Streamlit on port 8500 - HTTPS Streamlit on port 8501 (using the signed device cert) 3. **Client Trust Setup** - Customers should install `ca_cert.pem` in their operating system or browser trust store to trust the HTTPS connection. - After this, browsers will show a secure HTTPS connection to the device (no warnings). ### Why this setup? - **WebRTC and other browser features require HTTPS for local devices.** - Using a local CA allows trusted HTTPS without needing a public certificate or exposing devices to the internet. - HTTP is also available for compatibility/testing. ### Advertise Hostname with mDNS ```bash cd src/auracast/server sudo ./provision_domain_hostname.sh ``` - Example: ```bash sudo ./provision_domain_hostname.sh box1 auracast.local ``` - The script will: - Validate your input (no dots in hostname) - Set the system hostname - Update `/etc/hosts` - Set the Avahi domain in `/etc/avahi/avahi-daemon.conf` - Restart Avahi - Generate a unique per-device certificate and key signed by your CA, stored in `certs/per_device/./`. - The certificate will have a SAN matching the device's mDNS name (e.g., `box1-summitwave.local`). --- ### Troubleshooting & Tips - **Use .local domain** (e.g., `box1-summitwave.local`) - most clients will not resolve multi-label domains. - **Hostnames must not contain dots** (`.`). Only use single-label names for the system hostname. - **Avahi domain** can be multi-label (e.g., `auracast.local`). - **Clients may need** `libnss-mdns` installed and `/etc/nsswitch.conf` configured with `mdns4_minimal` and `mdns4` for multi-label mDNS names. - If you have issues with mDNS name resolution, check for conflicting mDNS stacks (e.g., systemd-resolved, Bonjour, or other daemons). - Some Linux clients may not resolve multi-label mDNS names via NSS—test with `avahi-resolve-host-name` and try from another device if needed. # record audio and save to file for debugging pw-record --target="AVIOUSB-8f6326 : 2:receive_Left" --rate=48000 --channels=1 --format=s24 /tmp/aes67_test.wav & RECORD_PID=$! sleep 30 kill $RECORD_PID # uart reset over hci does not work: stty -F /dev/ttyAMA3 -hupcl stty -F /dev/ttyAMA3 -a | grep -o 'hupcl' || echo "-hupcl is set" # Audio latency if there is hearable audio error with aes67, tune sess.latency.msec in pipewire-aes67.conf if latency is piling up something may be blocking the event loop in multicast_server.py - the event loop must never block at any time --- After completing these steps, your device will be discoverable as `.` (e.g., `box1.auracast.local`) on the local network via mDNS. --- ## Checking Advertised mDNS Services Once your device is configured, you can verify that its mDNS advertisement is visible on the network: - **List all mDNS services:** ```bash avahi-browse -a ``` Look for your hostname and service (e.g., `box1.auracast.local`). - **Check specific hostname resolution:** ```bash avahi-resolve-host-name box1.auracast.local avahi-resolve-host-name -4 box1.auracast.local # IPv4 only avahi-resolve-host-name -6 box1.auracast.local # IPv6 only ``` ## Run the application with local webui - for microphone streaming via the browser, https is required - poetry run multicast_server.py - sudo -E PATH="$PATH" bash ./start_frontend_https.sh - bash start_mdns.sh ## Managing Auracast systemd Services You can run the backend and frontend as systemd services for easier management and automatic startup on boot. ### 1. Install the service files Copy the provided service files to your systemd directory (requires sudo): ```bash sudo cp auracast-server.service /etc/systemd/system/ sudo cp auracast-frontend.service /etc/systemd/system/ ``` ### 2. Reload systemd ```bash sudo systemctl daemon-reload ``` ### 3. Enable services to start at boot ```bash sudo systemctl enable auracast-server sudo systemctl enable auracast-frontend ``` ### 4. Start the services ```bash sudo systemctl start auracast-server sudo systemctl start auracast-frontend ``` ### 5. Stop the services ```bash sudo systemctl stop auracast-server sudo systemctl stop auracast-frontend ``` ### 6. Disable services to start at boot ```bash sudo systemctl disable auracast-server sudo systemctl disable auracast-frontend ``` ### 7. Check service status ```bash sudo systemctl status auracast-server sudo systemctl status auracast-frontend ``` If you want to run the services as a specific user, edit the `User=` line in the service files accordingly. # Setup the audio system sudo apt update sudo apt remove -y libportaudio2 portaudio19-dev libportaudiocpp0 echo "y" | rpi-update stable sudo apt install -y pipewire wireplumber pipewire-audio-client-libraries rtkit cpufrequtils cp src/service/pipewire/99-lowlatency.conf ~/.config/pipewire/pipewire.conf.d/ sudo cpufreq-set -g performance /etc/modprobe.d/usb-audio-lowlatency.conf option snd_usb_audio nrpacks=1 sudo apt install -y --no-install-recommends \ git build-essential cmake pkg-config \ libasound2-dev libpulse-dev pipewire ethtool linuxptp sudo apt remove -y libportaudio2 portaudio19-dev libportaudiocpp0 git clone https://github.com/PortAudio/portaudio.git cd portaudio git checkout 9abe5fe7db729280080a0bbc1397a528cd3ce658 rm -rf build cmake -S . -B build -G"Unix Makefiles" \ -DBUILD_SHARED_LIBS=ON \ -DPA_USE_ALSA=ON \ -DPA_USE_PULSEAUDIO=ON \ -DPA_USE_JACK=OFF cmake --build build -j$(nproc) sudo cmake --install build # installs to /usr/local/lib sudo ldconfig # refresh linker cache # Device commisioning - generate id_ed25519 keypair - setup hostname - sudo bash src/auracast/server/provision_domain_hostname.sh box7-summitwave local - activate aes67 service - install udev rule for ptp4l - sudo cp src/service/aes67/90-pipewire-aes67-ptp.rules /etc/udev/rules.d/ - sudo udevadm control --log-priority=debug --reload-rules - sudo udevadm trigger - bash src/service/update_and_run_aes67.sh - poetry config virtualenvs.in-project true - poetry install - activate server and frontend - bash srv/service/update_and_run_server_and_frontend.sh - update to latest stable kernel - echo "y" | rpi-update stable - place cert - disable pw login - loginctl enable-linger "$USER" - reboot # Use temperature sensor - uncomment in config.txt: - dtparam=i2c_arm=on - reboot - load drivers - sudo modprobe i2c_bcm2835 - sudo modprobe i2c-dev - echo i2c_bcm2835 | sudo tee -a /etc/modules - echo i2c-dev | sudo tee -a /etc/modules - read temp /src/scripts/temp # configure the pcm1862 i2s interface bash misc/build_pcm1862_dts.sh bash misc/install_asoundconf.sh - configure differential inputs sudo modprobe i2c-dev i2cdetect -y 1 | grep -i 4a || true i2cset -f -y 1 0x4a 0x00 0x00 # Page 0 i2cset -f -y 1 0x4a 0x06 0x10 # Left = VIN1P/M [DIFF] i2cset -f -y 1 0x4a 0x07 0x10 # Right = VIN2P/M [DIFF] # test recording arecord -f cd -c 1 -D record_left left.wav -r48000 arecord -f cd -c 1 -D record_right right.wav -r48000 # Run with realtime priority - for the feedback loop to work right realtime priority is absolutely nececcarry. chrt -f 99 python src/auracast/multicast.py - give the user realtime priority: sudo tee /etc/security/limits.d/99-realtime.conf >/dev/null <<'EOF' caster - rtprio 99 caster - memlock unlimited EOF # Known issues: - When running on a laptop there might be issues switching between usb and browser audio input since they use the same audio device