Haiku BNetworkRoster: Saved Wi-Fi Profiles and Iterator Boundaries
Use Haiku's BNetworkRoster for saved Wi-Fi profiles, and verify iterator and error-reporting behavior against the exact target build.
A wireless scan result and the networks currently associated with a wireless device belong to BNetworkDevice; a saved network profile belongs to BNetworkRoster. BNetworkInterface is a distinct interface-configuration and state API for properties such as flags, link presence, addresses, and routes. It is not the wireless scan/join API. Keeping those layers separate prevents a settings view from presenting a saved SSID as proof that the link is connected or has working DHCP and DNS.
This guide concentrates on the public BNetworkRoster contract and a source-level iterator discrepancy in the Haiku tree snapshot cited below. Check the headers and implementation shipped with the Haiku release you target before relying on implementation details.
Use the roster for saved-profile operations
Obtain the default roster with BNetworkRoster::Default(). Its public API provides CountPersistentNetworks(), GetNextPersistentNetwork(), AddPersistentNetwork(), and RemovePersistentNetwork(). The Haiku API guide describes these as operations on saved persistent wireless networks; they are not a replacement for scanning with a wireless device or checking the current interface state.
The wireless_network record in NetworkDevice.h contains a fixed-size name, a BNetworkAddress, signal and noise values, flags, authentication and cipher fields, and a key mode. It has no password member, and AddPersistentNetwork() accepts only that record. Treat credential entry and storage as a separate concern: this roster call does not take a passphrase, and its public signature does not document where credentials are stored. Never print a passphrase or infer that a successful profile operation proves authentication will succeed.
An explicit user action can remove a selected profile and report the returned status:
if (userConfirmedRemoval) {
status_t status = BNetworkRoster::Default()
.RemovePersistentNetwork(selectedName.String());
if (status != B_OK)
ShowProfileRemovalError(status);
}
The API removes by name, so present the exact selected profile and require confirmation before calling it. B_OK means that the operation returned success; it does not mean the adapter joined that network. Re-query live wireless and interface state when the UI needs to report a connection.
Do not treat a zero count as conclusive
CountPersistentNetworks() returns an int32, not a status plus an output count. In the cited NetworkRoster.cpp implementation, a failed message to the network server or a reply without a count field is converted to zero. Therefore zero can mean “no profiles” or “the roster could not retrieve the count.” A settings UI should keep that ambiguity visible instead of translating zero into a confident empty-list message.
The iterator contract also needs a release-specific check. The public NetworkRoster.dox says to initialize the cookie to zero and pass it to each later call so the iteration advances. In the implementation at the pinned source revision below, GetNextPersistentNetwork() sends the value pointed to by the cookie as an index, but does not update the cookie after a successful result. NetServer.cpp passes that index to the settings object. By contrast, the same revision’s GetNextInterface() increments its cookie. This is a concrete documentation/implementation mismatch in that snapshot, not a reason to assume every Haiku build behaves identically.
Before shipping an enumerator, test it on the exact target build with zero, one, and multiple saved profiles. Assert that each successful call returns the expected distinct entry, that iteration terminates, and that server or decoding errors remain distinguishable from an empty list. Keep the test bounded; do not ship a loop that depends on a cookie advancing until the installed implementation has demonstrated that behavior. If documentation and the target binary disagree, capture the Haiku revision and report the mismatch rather than silently inventing a workaround.
Keep profile data and connectivity evidence apart
A persisted entry answers a configuration question. It does not establish that the adapter is present, the access point is in range, authentication is accepted, a DHCP lease was obtained, or a route and resolver are usable. A reliable workflow refreshes each layer independently and labels the data with its source and observation time.
AddPersistentNetwork() and RemovePersistentNetwork() return status_t; check and preserve that result. If profile enumeration fails, offer a retry or a diagnostic state rather than writing a replacement profile list from incomplete data. In particular, avoid “cleanup” routines that remove profiles merely because they were absent from one scan: a scan is a time-bounded observation, not an authoritative inventory of saved configuration.
For a reproducible report, record the Haiku revision, adapter/interface name where relevant, operation, returned status, and whether the profile was independently observed after the operation. Redact SSIDs when they identify a private location, and never attach wireless secrets. The current source snapshot was inspected directly, but this article’s example was not run on a Haiku target; perform the bounded acceptance test on each supported Haiku release.
Related:
- Haiku Network Interfaces: Enumerating State Without Guessing
- Haiku Network Notifications: Watchers and State Reconciliation
Sources:
- Haiku
BNetworkRosterpublic API header at pinned revision - Haiku
BNetworkRosterAPI guide at pinned revision - Haiku
BNetworkRosterimplementation at pinned revision - Haiku network-server profile dispatch at pinned revision
- Haiku
wireless_networkdefinition at pinned revision - Haiku
BNetworkInterfacepublic API header at pinned revision