Skip to content

Add ESP32/ESP-IDF platform support for mUPnP#23

Draft
Copilot wants to merge 9 commits intomasterfrom
copilot/add-upnp-support-for-esp32
Draft

Add ESP32/ESP-IDF platform support for mUPnP#23
Copilot wants to merge 9 commits intomasterfrom
copilot/add-upnp-support-for-esp32

Conversation

Copy link
Contributor

Copilot AI commented Dec 1, 2025

Enables mUPnP to run on ESP32 microcontrollers using ESP-IDF with FreeRTOS, supporting both UPnP control point and device functionality including SSDP discovery, HTTP control, and device/service descriptions.

Platform Abstraction

Threading & Synchronization (src/mupnp/util/)

  • FreeRTOS tasks for thread abstraction with configurable stack sizes (min 2048B, default 4096B)
  • Mutexes via xSemaphoreCreateMutex() with standard lock/unlock semantics
  • Condition variables using binary semaphores with waiter tracking and overflow-safe timeout calculation

Timing & Logging (src/mupnp/util/)

  • Task delays via vTaskDelay() with tick conversion
  • ESP-IDF logging (ESP_LOG*) integrated, mapping mUPnP severity levels to ESP log levels

Networking (src/mupnp/net/)

  • lwIP POSIX-compatible sockets with IGMP multicast support
  • Standard getifaddrs() for interface enumeration

All ESP32 code conditionally compiled via #if defined(ESP32) || defined(ESP_PLATFORM).

ESP-IDF Component

Structure (components/mupnp/)

  • CMakeLists.txt: Recursive source collection with Expat dependency
  • Kconfig: WiFi credentials, stack sizes, logging levels, SSDP intervals, multicast TTL
  • idf_component.yml: Component manifest requiring ESP-IDF ≥5.0

Configuration Requirements

CONFIG_LWIP_IGMP=y                    # SSDP multicast
CONFIG_LWIP_SO_REUSE=y                # Socket binding
CONFIG_LWIP_MULTICAST_TX_OPTIONS=y    # TTL control

Examples

Control Point (examples/esp32/control_point/)

mUpnpControlPoint* cp = mupnp_controlpoint_new();
mupnp_controlpoint_start(cp);
mupnp_controlpoint_search(cp, MUPNP_ST_ROOT_DEVICE);
// Discovers devices via SSDP, displays name/type/location

Device Server (examples/esp32/device/)

mUpnpDevice* dev = mupnp_device_new();
mupnp_device_parsedescription(dev, xml, strlen(xml));
mupnp_device_setactionlistener(dev, action_handler);
mupnp_device_start(dev);
// Advertises via SSDP, serves description over HTTP

Both include WiFi station setup and sdkconfig.defaults with required LWIP options.

Memory Footprint

  • Base library: ~80KB Flash, ~15KB RAM
  • Control point: +30KB RAM (device caching)
  • Device server: +20KB RAM per connection
  • Suitable for ESP32 (520KB), ESP32-S3 (512KB), ESP32-C3 (400KB)

Compatibility

  • ESP-IDF v5.0+ (v5.1+ recommended)
  • ESP32, ESP32-S2, ESP32-S3, ESP32-C3
  • Zero impact on other platforms (WIN32, Unix, ITRON, etc.)

Documentation

  • ESP32_BUILD_GUIDE.md: Installation, build steps, configuration, troubleshooting
  • ESP32_IMPLEMENTATION_NOTES.md: Architecture, design decisions, limitations
  • ESP32_TESTING_CHECKLIST.md: Comprehensive validation procedures
  • Updated README.md with ESP32 quick start

Requires ESP-IDF toolchain and hardware for validation.

Original prompt

Goal
Enable cybergarage/mupnp to build and run on ESP32 using ESP-IDF with FreeRTOS, supporting both UPnP client and server functionality (SSDP discovery, HTTP control, device/service descriptions, and eventing where feasible).

Scope

  • Build system: Add ESP-IDF-compatible CMake and component configuration to compile mupnp as an ESP-IDF component or static library. Provide example app(s).
  • Platform abstraction: Implement or adapt platform-dependent layers (network sockets, threading, timers, filesystem/flash-friendly I/O, logging) using ESP-IDF APIs (lwIP for sockets, FreeRTOS for threading/synchronization, esp_timer for timers, etc.).
  • Networking:
    • SSDP (UDP multicast on 239.255.255.250:1900) using lwIP sockets and IGMP/MCAST joins.
    • HTTP (TCP) for control point and device hosting (simple HTTP server/client using ESP-IDF or lightweight internal implementation).
  • UPnP stack: Ensure core UPnP client/server flows operate on ESP32 (M-SEARCH, NOTIFY, GET/POST for control actions, device/service XML parsing). Keep memory footprint small.
  • Examples:
    • Control point example that performs SSDP discovery and prints discovered devices/services.
    • Minimal device example that advertises a basic UPnP device and serves description over HTTP.
  • Documentation: Add README section for ESP32 build/run steps.

Deliverables

  1. New component directory (e.g., components/mupnp) with CMakeLists.txt to build under ESP-IDF, plus Kconfig if needed.
  2. Platform shim code under src/platform/esp32 (or similar) providing implementations for:
    • Net: UDP multicast (SSDP) and TCP sockets (HTTP)
    • Threading: FreeRTOS tasks, mutexes, condition variables/semaphores
    • Timers: esp_timer or FreeRTOS timers
    • Time: gettimeofday or esp_timer based time utilities
    • Logging: use ESP_LOG* macros behind existing logging interface
  3. Build configurations for examples under examples/esp32/control_point and examples/esp32/device with separate CMakeLists.txt + main/ sources.
  4. README updates with setup, sdkconfig notes (Wi-Fi, IGMP, mDNS if used, heap settings), build and flash instructions.

Implementation Notes

  • Use ESP-IDF v5.x APIs (confirm minimal supported version and avoid deprecated ones); ensure compatibility with lwIP sockets (POSIX-style) available in ESP-IDF.
  • SSDP multicast:
    • Enable LWIP_MULTICAST/IGMP in sdkconfig; join 239.255.255.250 on the active netif; set TTL=2; handle interface binding (IP_MULTICAST_IF) if necessary.
    • Send NOTIFY and M-SEARCH messages; listen on UDP 1900.
  • HTTP server/client:
    • For small footprint, use esp_http_server for device description hosting.
    • For client, use esp_http_client or retain mupnp’s internal HTTP client adapted to lwIP sockets.
  • Threading:
    • Map existing thread abstractions to FreeRTOS tasks; ensure stack sizes are configurable via Kconfig.
    • Replace pthread primitives with FreeRTOS equivalents; wrap in portable API to minimize changes to core code.
  • Timers:
    • Replace POSIX timers with esp_timer or FreeRTOS timers for periodic tasks (SSDP announcements, cache expiration).
  • Memory/IO:
    • Avoid file I/O where not available; allow device/service XML to be embedded as strings or served from SPIFFS/LittleFS if enabled.
  • Config:
    • Provide Kconfig options for Wi-Fi SSID/password, multicast enable, HTTP server port, stack sizes, SSDP announce interval.

Testing

  • On ESP32-DevKitC or similar:
    • Build examples, flash, connect to Wi-Fi, verify SSDP discovery via a desktop UPnP control point (e.g., CyberLink for Java or VLC) and that the device advertises and serves description XML.
    • Run control point example to list devices discovered on the network.

Tasks

  • Create ESP-IDF component structure and CMake.
  • Implement platform shims (net/thread/timer/logging) under src/platform/esp32.
  • Integrate shims with core UPnP modules.
  • Add example apps and CMake build files.
  • Write README instructions.

Acceptance Criteria

  • Successful build under ESP-IDF toolchain for both examples.
  • Control point discovers devices via SSDP; device example announces NOTIFY and responds to M-SEARCH; device description accessible via HTTP.
  • CI or manual instructions provided for building with ESP-IDF.

This pull request was created as a result of the following prompt from Copilot chat.

Goal
Enable cybergarage/mupnp to build and run on ESP32 using ESP-IDF with FreeRTOS, supporting both UPnP client and server functionality (SSDP discovery, HTTP control, device/service descriptions, and eventing where feasible).

Scope

  • Build system: Add ESP-IDF-compatible CMake and component configuration to compile mupnp as an ESP-IDF component or static library. Provide example app(s).
  • Platform abstraction: Implement or adapt platform-dependent layers (network sockets, threading, timers, filesystem/flash-friendly I/O, logging) using ESP-IDF APIs (lwIP for sockets, FreeRTOS for threading/synchronization, esp_timer for timers, etc.).
  • Networking:
    • SSDP (UDP multicast on 239.255.255.250:1900) using lwIP sockets and IGMP/MCAST joins.
    • HTTP (TCP) for control point and device hosting (simple HTTP server/client using ESP-IDF or lightweight internal implementation).
  • UPnP stack: Ensure core UPnP client/server flows operate on ESP32 (M-SEARCH, NOTIFY, GET/POST for control actions, device/service XML parsing). Keep memory footprint small.
  • Examples:
    • Control point example that performs SSDP discovery and prints discovered devices/services.
    • Minimal device example that advertises a basic UPnP device and serves description over HTTP.
  • Documentation: Add README section for ESP32 build/run steps.

Deliverables

  1. New component directory (e.g., components/mupnp) with CMakeLists.txt to build under ESP-IDF, plus Kconfig if needed.
  2. Platform shim code under src/platform/esp32 (or similar) providing implementations for:
    • Net: UDP multicast (SSDP) and TCP sockets (HTTP)
    • Threading: FreeRTOS tasks, mutexes, condition variables/semaphores
    • Timers: esp_timer or FreeRTOS timers
    • Time: gettimeofday or esp_timer based time utilities
    • Logging: use ESP_LOG* macros behind existing logging interface
  3. Build configurations for examples under examples/esp32/control_point and examples/esp32/device with separate CMakeLists.txt + main/ sources.
  4. README updates with setup, sdkconfig notes (Wi-Fi, IGMP, mDNS if used, heap settings), build and flash instructions.

Implementation Notes

  • Use ESP-IDF v5.x APIs (confirm minimal supported version and avoid deprecated ones); ensure compatibility with lwIP sockets (POSIX-style) available in ESP-IDF.
  • SSDP multicast:
    • Enable LWIP_MULTICAST/IGMP in sdkconfig; join 239.255.255.250 on the active netif; set TTL=2; handle interface binding (IP_MULTICAST_IF) if necessary.
    • Send NOTIFY and M-SEARCH messages; listen on UDP 1900.
  • HTTP server/client:
    • For small footprint, use esp_http_server for device description hosting.
    • For client, use esp_http_client or retain mupnp’s internal HTTP client adapted to lwIP sockets.
  • Threading:
    • Map existing thread abstractions to FreeRTOS tasks; ensure stack sizes are configurable via Kconfig.
    • Replace pthread primitives with FreeRTOS equivalents; wrap in portable API to minimize changes to core code.
  • Timers:
    • Replace POSIX timers with esp_timer or FreeRTOS timers for periodic tasks (SSDP announcements, cache expiration).
  • Memory/IO:
    • Avoid file I/O where not available; allow device/service XML to be embedded as strings or served from SPIFFS/LittleFS if enabled.
  • Config:
    • Provide Kconfig options for Wi-Fi SSID/password, multicast enable, HTTP server port, stack sizes, SSDP announce interval.

Testing

  • On ESP32-DevKitC or similar:
    • Build examples, flash, connect to Wi-Fi, verify SSDP discovery via a desktop UPnP control point (e.g., CyberLink for Java or VLC) and that the device advertises and serves description XML.
    • Run control point example to list devices discovered on the network.

Tasks

  • Create ESP-IDF component structure and CMake.
  • Implement platform shims (net/thread/timer/logging) under src/platform/esp32.
  • Integrate shims with core UPnP modules.
  • Add example apps and CMake build files.
  • Write README instructions.

Acceptance Criteria

  • Successful build under ESP-IDF toolchain for both examples.
  • Control point discovers devices via SSDP; device example announces NOTIFY and responds to M-SEARCH; device description accessible via HTTP.
  • CI or manual instructions provided for building with ESP-IDF.

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI self-assigned this Dec 1, 2025
Copilot AI and others added 3 commits December 1, 2025 06:42
Co-authored-by: cybergarage <586639+cybergarage@users.noreply.github.com>
Co-authored-by: cybergarage <586639+cybergarage@users.noreply.github.com>
Co-authored-by: cybergarage <586639+cybergarage@users.noreply.github.com>
@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 1, 2025

Quality Gate Failed Quality Gate failed

Failed conditions
1 Security Hotspot
22.9% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Copilot AI and others added 5 commits December 1, 2025 06:55
Co-authored-by: cybergarage <586639+cybergarage@users.noreply.github.com>
Co-authored-by: cybergarage <586639+cybergarage@users.noreply.github.com>
Co-authored-by: cybergarage <586639+cybergarage@users.noreply.github.com>
…and security

Co-authored-by: cybergarage <586639+cybergarage@users.noreply.github.com>
Co-authored-by: cybergarage <586639+cybergarage@users.noreply.github.com>
@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 1, 2025

Quality Gate Failed Quality Gate failed

Failed conditions
1 Security Hotspot
20.4% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Copilot AI changed the title [WIP] Enable UPnP functionalities on ESP32 using ESP-IDF Add ESP32/ESP-IDF platform support for mUPnP Dec 1, 2025
Copilot AI requested a review from cybergarage December 1, 2025 07:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants