Skip to main content
Version: 029-rc2

pvwificonnect — WiFi Provisioning Container

pvwificonnect ships as a core container in the starter image (PVROOT_CONTAINERS_CORE in recipes-pv/images/pantavisor-starter.bb). It is a Go network-provisioning service (gitlab.com/pantacor/pvwificonnect) that lets a headless device be joined to a WiFi network without a console: it brings up an access point / captive portal, can tether AP clients to an existing uplink, and watches connectivity so it can re-provision after a drop.

What it brings to the system

FeatureDescription
Access pointBroadcasts a setup SSID (default pvwificonnect / 1234567890) so a phone/laptop can connect to the device.
Captive portalRedirects connecting clients to a web setup page (opt-in via captive_portal).
Internet tetheringShares the device's uplink (eth0, wwan0, …) to AP clients (opt-in via tethering).
Auto modePicks portal vs. tethering automatically based on connectivity (auto_mode, on by default).
Connection watcherBackground loop that re-triggers AP/tethering setup when connectivity is lost (watcher).
Pluggable backendTalks to the network stack over D-Bus (org.pantacor.PvWificonnect); adapts to whichever backend container is present.

It is built three ways in this layer:

RecipeProduces
recipes-containers/pantavisor/pvwificonnect_v1.7.0.bbThe pvrexport container (this doc).
recipes-containers/pantavisor/pvwificonnect-app_v1.7.0.bbThe pvwificonnect + pvwificonnect-cli binaries built from source.
recipes-containers/pantavisor/pv-pvwificonnect_v1.7.0.bbThe prebuilt Docker-image variant.

Network backend dependency

pvwificonnect does not manage WiFi hardware itself — it drives a backend over the host D-Bus (imported via os:/pvrun/dbus:/var/run/dbus, see args.json). The starter image pairs it with the ConnMan backend:

PVROOT_CONTAINERS_CORE ?= "pv-pvr-sdk pv-alpine-connman pvwificonnect pv-avahi"
Backend containerStackAP gateway IP
pv-alpine-connman (default here)ConnMan tethering API + dnsmasq192.168.0.1
Debian / NetworkManagerNM "shared" connection profiles10.42.0.1

If neither backend is running, the service waits at startup up to wait_time_in_sec for D-Bus readiness. The board must also have working WiFi firmware and a wlanN interface — see the board flashing guides (e.g. Verdin iMX8MM, Colibri iMX6ULL) for enabling the WiFi DTB and firmware.

Configuration

Runtime settings live in /var/pvwificonnect/config.json inside the container. The layer ships this overlay (recipes-containers/pantavisor/pvwificonnect/pvwificonnect-config/var/pvwificonnect/config.json):

{
"ap": {
"ssid": "pvwificonnect",
"password": "1234567890"
},
"auto_mode": true,
"wait_time_in_sec": 60,
"watcher": true,
"watcher_interval": "1m"
}

config.json keys

KeyMeaningDefault
ap.ssidSSID broadcast by the access pointpvwificonnect
ap.passwordAP password1234567890
network.ssid / network.passwordPre-seed credentials for an existing network to joinunset
captive_portalRedirect AP clients to a web setup pagefalse
tetheringShare the device uplink to AP clientsfalse
auto_modeAuto-select portal vs. tethering from connectivitytrue
uplink_interfacePreferred uplink (eth0, wwan0, …)auto-detected
wait_time_in_secD-Bus readiness timeout at startup60
watcherBackground connectivity monitorfalse
watcher_intervalWatcher check frequency (Go duration)1m
watcher_max_retriesFailures before the watcher backs off3

Change the default AP SSID/password before shipping a product image — the 1234567890 default is for bring-up only.

Environment variables

Set in the container's Docker config (recipes-containers/pantavisor/pvwificonnect/config.json):

VariableMeaningDefault
PV_WIFI_CONNECT_WATCHEREnable the connection watcherfalse
PV_WIFI_CONNECT_INTERVALWatcher interval (Go duration)1m
PV_WIFI_CONNECT_MAX_RETRIESMax consecutive watcher failures3

Container runtime args

args.json grants the container the capabilities and group it needs:

{
"PV_GROUP": "platform",
"PV_LXC_CAP_KEEP": [
"block_suspend", "wake_alarm", "sys_time",
"net_admin net_raw net_bind_service"
],
"PV_RESTART_POLICY": "system",
"PV_VOLUME_IMPORTS": ["os:/pvrun/dbus:/var/run/dbus"]
}

Using it

  1. Boot a device running the starter image with both pvwificonnect and a network backend (pv-alpine-connman). The service starts in the platform group.
  2. Join the setup AP — from a phone/laptop connect to the ap.ssid (default pvwificonnect, password 1234567890). The backend hands out an address on its gateway subnet (192.168.0.x for ConnMan).
  3. Provision — with captive_portal enabled, opening a browser redirects to the setup page where you select the home network and enter credentials. Alternatively, pre-seed network.ssid/network.password in config.json so the device joins on first boot with no interaction.
  4. Stay connected — with watcher on, the service re-runs AP/tethering setup whenever connectivity drops.

The pvwificonnect-cli binary (installed to /usr/bin by pvwificonnect-app) is available inside the container for inspecting and driving the service over its D-Bus interface.

Building

./kas-container build .github/configs/release/docker-x86_64-scarthgap.yaml \
--target pvwificonnect

Output: build/tmp-scarthgap/deploy/images/<machine>/pvwificonnect.pvrexport.tgz. Because it is in PVROOT_CONTAINERS_CORE, a full pantavisor-starter build already includes it.