//
// Copyright (C) 2018 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

syntax = "proto2";

package com_android_server_wifi;

option java_package = "com.android.server.wifi.proto";
option java_outer_classname = "WifiScoreCardProto";

message NetworkList {
  optional int64 start_time_millis = 1; // Start of collection period
  optional int64 end_time_millis = 2;   // End of collection period
  // A collection of network descriptions
  repeated Network networks = 3;
};

// Describes a network, consisting of a collection of access points that share
// the same SSID, the same security type, and (hopefully) the same L3 subnet.
// This message is not stored in the MemoryStore. It is used to package
// the access points of a network together in dumpsys output or similar.
// For this purpose, the network_config_id and network_agent_id may be useful
// for cross-referencing with other parts of the bug report. Neither of these
// are meaningful across reboots.
message Network {
  optional string ssid = 1;                // The SSID (not stored)
  optional SecurityType security_type = 2; // Wireless security type
  repeated AccessPoint access_points = 3;  // The list of related APs
  optional int32 network_config_id = 4;    // The networkId of WifiConfiguration
  optional int32 network_agent_id = 5;     // Latest NetworkAgent netId
  optional NetworkStats network_stats = 6; // Network stats of current SSID
};

// Describes an access point (single BSSID)
//
// Beyond the BSSID, a concise id is assigned to track references
// among APs. These ids are local to the device, but unique among all APs
// known to the device. The BSSID itself is not stored in persistent storage.
message AccessPoint {
  optional int32 id = 1;               // Concise id
  optional bytes bssid = 2;            // BSSID of the access point (not stored)
  optional SecurityType security_type = 6; // Wireless security type
  reserved 3;
  repeated Signal event_stats = 4;     // Statistics taken at specific events
  reserved 5;
  // Link bandwidth stats of all bands, links and signal levels
  optional BandwidthStatsAll bandwidth_stats_all = 7;
};

// Describes the IEEE 802.11 security type
enum SecurityType {
    OPEN = 0;         // Open - no encryption
    WEP = 1;          // Should not be used
    PSK = 2;          // WPA2
    EAP = 3;          // Extensible Authentication Protocol
    SAE = 4;          // WPA3
    EAP_SUITE_B = 5;
    OWE = 6;          // Opportunistic Wireless Encryption
};

// Records statistics gathered at various points in the life-cycle of
// a connection, e.g., at disconnections of various flavors. May be
// further split out by frequency.
//
message Signal {
  optional Event event = 1;                   // Type of the event
  optional int32 frequency = 2;               // Frequency (MHz)
  optional UnivariateStatistic rssi = 3;      // Signal strength (dBm) of beacons
  optional UnivariateStatistic linkspeed = 4; // Link speed (Mbits/sec)
  optional UnivariateStatistic elapsed_ms = 5; // Milliseconds since connection attempt
};

// Statistics about a real value
message UnivariateStatistic {
  // Short-term statistics (for current collection period)
  optional int64 count = 1;           // Number of events
  optional double sum = 2;            // Sum of values
  optional double sum_of_squares = 3; // Sum of squares of values
  optional double min_value = 4;      // Minimum value during period
  optional double max_value = 5;      // Maximum value during period

  // Long-term statistics
  // These are accumulated over a longer time span, and are aged so that
  // more recent measurements get a higher weight.
  optional double historical_mean = 6;     // Long-term average
  optional double historical_variance = 7; // Long-term variance

  // Arranged by increasing value
  repeated HistogramBucket buckets = 8;
};

message HistogramBucket {
  // Lower bound (inclusive) for values falling in this bucket.
  // Compact signed encoding used here, because rssi values are negative.
  // The upper bound is not stored explicitly.
  optional sint64 low = 1;
  // Number of occurrences for this value or bucket.
  optional int64 number = 2;
}

message BandwidthStatsAll {
  // Stats of 2g band
  optional BandwidthStatsAllLink stats_2g = 1;
  // Stats of above-2g band
  optional BandwidthStatsAllLink stats_above_2g = 2;
}

message BandwidthStatsAllLink {
  // Tx bandwidth stats
  optional BandwidthStatsAllLevel tx = 1;
  // Rx bandwidth stats
  optional BandwidthStatsAllLevel rx = 2;
}

// Bandwidth of all signal levels
// The number of entries will match WifiScoreCard.NUM_SIGNAL_LEVEL
message BandwidthStatsAllLevel {
  repeated BandwidthStats level = 1;
}

message BandwidthStats {
  // Accumulated bandwidth sample value
  optional uint64 value = 1;
  // Accumulated bandwidth sample count
  optional uint32 count = 2;
}

// Events where statistics may be collected
enum Event {
  SIGNAL_POLL = 1;
  SCAN_BEFORE_SUCCESSFUL_CONNECTION = 2;
  FIRST_POLL_AFTER_CONNECTION = 3;
  IP_CONFIGURATION_SUCCESS = 4;
  SCAN_BEFORE_FAILED_CONNECTION = 5;
  CONNECTION_FAILURE = 6;
  IP_REACHABILITY_LOST = 7;
  LAST_POLL_BEFORE_ROAM = 8;
  ROAM_SUCCESS = 9;
  WIFI_DISABLED = 10;
  ROAM_FAILURE = 11;
  LAST_POLL_BEFORE_SWITCH = 12;
  VALIDATION_SUCCESS = 13;
  DISCONNECTION = 14;
  CONNECTION_ATTEMPT = 15;
  VALIDATION_FAILURE = 16;
};

message SystemInfoStats {
  // Current software build information
  optional SoftwareBuildInfo curr_software_build_info = 1;
  // Previous software build information
  optional SoftwareBuildInfo prev_software_build_info = 2;
  // Most recent WiFi scan time
  optional int64 last_scan_time_ms = 3;
  // Number of access points found in most recent WiFi scan at 2G
  optional int32 num_bssid_last_scan_2g = 4;
  // Number of access points found in most recent WiFi scan above 2G
  optional int32 num_bssid_last_scan_above_2g = 5;
}

message SoftwareBuildInfo {
  // Android OS build version
  optional string os_build_version = 1;
  // WiFi stack APK version, 0 means not available.
  optional int64 wifi_stack_version = 2;
  // WiFi driver version
  optional string wifi_driver_version = 3;
  // WiFi firmware version
  optional string wifi_firmware_version = 4;
}

message NetworkStats {
  optional int32 id = 1;    // Concise id
  // The most recent connection stats with current SW build that may be collected over days
  optional ConnectionStats recent_stats = 2;
  // Accumulated connection stats with current SW build
  optional ConnectionStats stats_curr_build = 3;
  // Accumulated connection stats with previous SW build
  optional ConnectionStats stats_prev_build = 4;
  // List of frequencies observed for this network from scan results, sorted by most recent first.
  repeated int32 frequencies = 5;
  // Link bandwidth stats of all bands, links and signal levels
  optional BandwidthStatsAll bandwidth_stats_all = 6;
};

message ConnectionStats {
  // Number of connection attempts at high RSSI
  optional int32 num_connection_attempt = 1;
  // Number of connection failures at high RSSI
  // Does not include wrong password but does include DHCP
  optional int32 num_connection_failure = 2;
  // Total connection duration in seconds
  optional int32 connection_duration_sec = 3;
  // Number of association rejections at high RSSI
  optional int32 num_association_rejection = 4;
  // Number of association timeouts at high RSSI
  optional int32 num_association_timeout = 5;
  // Number of authentication failures (excluding wrong password) at high RSSI
  optional int32 num_authentication_failure = 6;
  // Number of short connections caused by nonlocal disconnection at high RSSI
  // or at high Tx speed with a recent RSSI poll
  optional int32 num_short_connection_nonlocal = 7;
  // Number of non-local disconnections after L3 connection at high RSSI
  // or Tx speed with a recent RSSI poll
  optional int32 num_disconnection_nonlocal = 8;
  // Number of disconnections after L3 connection with a recent RSSI poll
  optional int32 num_disconnection = 9;
  // Number of non-local disconnections during the connecting state at high RSSI
  optional int32 num_disconnection_nonlocal_connecting = 10;
}
