Roof Unit (MV2402)

Hardware Description

Roof Unit API - Unlocking the Control Interface

  • Initial Observation: Direct web access to the roof unit’s root IP (http://192.168.10.254/) is unsuccessful.

  • Discovery Method: Analysis of JavaScript files served by the Indoor Unit (RV2458) web interface.

  • These calls, and many more, are handled by a binary called webmgnt implementing fastcgi.

  • webmgnt listens for http requests on 127.0.0.1:9002.

  • The nginx web server on the device proxies any traffic incoming to /cgi-bin/ to webmgnt.

  • This is why you get 502 errors when trying random section= parameters that the webmgnt binary doesn’t recognize.

  • Authentication Endpoint:

    • Path: /cgi-bin/login
    • Method: POST
    • Payload (JSON): {"username": "admin", "password": "admin"}
    • Successful Response: Sets a COMFAST_SESSIONID cookie.
    • Notes & Challenges:
      • Initial attempts with curl resulted in 400 errors.
      • Switching to Python requests library with session management resolved this.
      • A login retry mechanism may be needed if the first cookie received is DELETED or expired.
  • Main Configuration Endpoint:

    • Path: /cgi-bin/mbox-config
    • Method: POST (used for both fetching and setting data).
    • Parameters: method (e.g., GET, SET) and section (e.g., wifi_scan) are passed as URL query parameters.
  • Key API Calls Identified (Roof Unit - 192.168.10.254):

    • GET wifi_scan
      • URL Params: method=GET, section=wifi_scan
      • POST Payload: {"ifname":"radio0"}
      • Function: Scans for available Wi-Fi networks.
    • SET motorhome_config_set
      • URL Params: method=SET, section=motorhome_config_set
      • POST Payload: {"motorhome": {"ssid": "...", "bssid": "...", "encryption": "...", "key": "..."}}
      • Function: Connects the roof unit to a specified Wi-Fi Access Point.
    • GET firmware_version_get
      • URL Params: method=GET, section=firmware_version_get
      • Function: Retrieves firmware details.
    • GET guide_config
      • URL Params: method=GET, section=guide_config
      • Function: Gets overall status, including current WAN connection details.
    • GET get_ec20_status_info
      • URL Params: method=GET, section=get_ec20_status_info
      • Function: Retrieves LTE status (if an LTE modem like Quectel EC20 is present/active).
    • SET system_reboot
      • URL Params: method=SET, section=system_reboot
      • Function: Reboots the roof unit.

The “Commit” Conundrum & The Orchestration Reversion Mechanism

  • Observed Problem: When attempting to change the Wi-Fi connection directly on the Roof Unit (MV2402) using the motorhome_config_set API call:

    • The API call would initially report success (e.g., HTTP 200 OK).
    • However, the roof unit’s Wi-Fi configuration would frequently revert to its previous state shortly thereafter.
  • Initial Investigation & Clue from Indoor Unit Workflow:

    • Analysis of the indoor unit’s (RV2458) web UI operations revealed a critical step in its standard configuration process.
    • After the roof unit acknowledges a Wi-Fi change request (e.g., through its internal JavaScript redirecting to a confirmation page like set_ok_m.html), the roof unit’s confirmation page was observed to trigger an immediate HTTP request back to the Indoor Unit (RV2458) at the endpoint: http://192.168.10.1/data/set_setting.html.
  • Refined Hypothesis (Incorporating wtpd & heart_beat Knowledge):

    • The configuration reversion is strongly linked to the custom wtpd (Wireless Termination Point Daemon) suite (wtpd, wtpd_server, wtpd_ubus, wtpd_udp) and the heart_beat process operating on the roof unit.
    • These services appear to maintain a connection and synchronization with an Access Controller (AC), which is highly likely the indoor unit (RV2458). The wtpd process handles registration, heartbeats (ap_heart_beat), status updates, and configuration synchronization (sync_config, recv_msg_from_ac) with this AC.
    • The call to http://192.168.10.1/data/set_setting.html by the indoor unit’s UI flow is believed to be the mechanism that informs its own AC logic (and subsequently the roof unit’s wtpd client) that the configuration change is authorized and persistent.
    • Therefore, the reversion likely occurs because: When the roof unit is configured directly via its API (bypassing the indoor unit’s UI), the wtpd service on the roof unit fails its heartbeat or synchronization check with the AC (indoor unit), as the AC was not “notified” of a legitimate change via the /data/set_setting.html pathway. This failure then likely triggers the wtpd_server on the roof unit to revert the configuration to its last known “authorized” state.
  • Implication for Independent Control: This dependency on an “authorization” signal, seemingly managed by the indoor unit and enforced by the roof unit’s wtpd/heart_beat services, presents the primary obstacle to achieving fully independent and persistent configuration of the roof unit solely through its API. Bypassing this reversion mechanism is key to autonomous operation.

Wesley Ray · blog · git · resume