Skip to content
CARP Docs
Ask AISystemLightDark
On this page

Wi-Fi

The WIFI measure, which reads the name, access point and IP address of the Wi-Fi network that the phone uses.

Copy MarkdownOpen inOpen in GitHubView as MarkdownOpen in Scira AIOpen in ChatGPTOpen in ClaudeOpen in Cursor

dk.cachet.carp.wifi is an event-based measure that runs on the phone on Android and iOS. Add it as Measure(type: ConnectivitySamplingPackage.WIFI). Every 10 minutes by default, it reads the network name (SSID), the MAC address of the access point (BSSID) and the phone's IP address.

Add the measure to a protocol

Start the measure with an ImmediateTrigger. To read the network every 5 minutes, set an IntervalSamplingConfiguration on the measure:

protocol.addTaskControl(
  ImmediateTrigger(),
  BackgroundTask(
    measures: [
      Measure(
        type: ConnectivitySamplingPackage.WIFI,
        samplingConfiguration: IntervalSamplingConfiguration( 
          interval: const Duration(minutes: 5),
        ),
      ),
    ],
  ),
  phone,
);

The measure also needs location access. See Location permission.

Configuration

The measure uses an IntervalSamplingConfiguration:

PropertyTypeDefaultDescription
intervalDuration10 minutesTime between two readings. The first reading comes one interval after the measure starts.

A shorter interval catches network changes sooner and produces more measurements.

Location permission

Android and iOS return the SSID and BSSID only to apps with location access. On Android, the participant must allow precise location, and Location Services must be on.

Known issue

CARP Mobile Sensing (CAMS) does not ask for location for WIFI, because the measure declares no permissions. Unless the app or another measure asks for it, the measurements lack the real SSID and BSSID. Ask for location in the app, as shown below.

Add location to the permissions that CAMS asks for, with a permissionRequester in configure(). Permission comes from permission_handler, which you add with flutter pub add permission_handler:

await SmartPhoneClientManager().configure(
  permissionRequester: (permissions) => requestPermissionsInOrder([
    ...permissions,
    Permission.locationWhenInUse,
  ]),
);

CAMS calls the requester only when a measure in the deployment declares a permission. Measures that declare location, such as BEACON and the location measures of carp_context_package, make CAMS ask for location by themselves. If no measure in the protocol declares a permission, ask for location in the app before you configure the client:

await Permission.locationWhenInUse.request();
await SmartPhoneClientManager().configure();

Platform differences

AndroidiOS
  • The SSID comes in double quotes, for example "MyLab", as Android returns it.
  • The SSID and BSSID need precise location (ACCESS_FINE_LOCATION) and Location Services. The IP address needs neither.
  • On Android 12 or later, ip is the IPv4 address on the phone's active network. That network can also be the mobile network or a VPN.
  • The plugin adds ACCESS_WIFI_STATE and ACCESS_NETWORK_STATE to the merged manifest.
  • The SSID and BSSID need the Access Wi-Fi Information capability and precise location access. Instead of location access, a network that the app configured with NEHotspotConfiguration, or an active VPN or NEDNSSettingsManager configuration of the app, also works.
  • Without these, ssid and bssid are missing. The IP address needs no permission.
  • The simulator returns no Wi-Fi information.

Name hashing

The default privacy schema replaces ssid with its SHA-1 hash, a string of 40 hexadecimal characters. bssid and ip are stored as collected. Turn the schema on with privacySchemaName: PrivacySchema.DEFAULT on the SmartphoneStudyProtocol.

Android includes the quotes in the SSID, so the same network hashes differently on the two platforms:

Platformssid as collectedSHA-1 hash of ssid
Android"MyLab"25dbe51dca333497aadaceb6203d1c59569e86b9
iOSMyLab3593174e7d8fb794f1feef02985266f85596924b

For privacy schemas in general, see Data transformation and privacy.

Data

Each measurement holds a Wifi object with the __type dk.cachet.carp.wifi. Fields that are null are left out of the JSON:

FieldTypeDescription
ssidString?Network name, in double quotes on Android. With the default privacy schema, its SHA-1 hash.
bssidString?MAC address of the access point.
ipString?IPv4 address of the phone.

The measurement's sensorStartTime is the time of the reading. On Android, without the privacy schema, the data looks like this:

{
  "__type": "dk.cachet.carp.wifi",
  "ssid": "\"MyLab\"",
  "bssid": "a4:2b:b0:12:34:56",
  "ip": "192.168.1.43"
}

For the measurement envelope around the data, see Measurements and data.

Quick links

Page · DocumentationCARP DocumentationPage · DocumentationIntroductionPage · DocumentationQuickstartPage · DocumentationTerminologyPage · DocumentationArchitecture