// Copyright 2021 Google LLC
//
// 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.
//
// RPC proto API for wifi capabilities, these roughly map to GDM's wifi
// capabilities.

syntax = "proto3";

package chip.rpc;

import 'pw_protobuf_protos/common.proto';

message Channel {
  uint32 channel = 1;
}

message Ssid {
  bytes ssid = 1;
}

message State {
  bool connected = 1;
}

message MacAddress {
  string mac_address = 1;
}

message WiFiInterface {
  string interface = 1;
}

message IP4Address {
  string address = 1;
}

message IP6Address {
  string address = 1;
}

message ScanConfig {
  repeated bytes ssid = 1; // if not null only that SSID is scanned for
  repeated bytes bssid = 2; // if not null only that BSSID is scanned for
  uint32 channel = 3; // if 0 then all channels are scanned
  bool show_hidden = 4; // if false then hidden SSIDs are not returned
  bool active_scan = 5;

  // These fields are used to control how long the scan dwells
  // on each channel.
  // For passive scans, scan_time_min_ms designates
  // the dwell time for each channel.
  // For active scans, dwell times for each channel are listed
  // in the table below. Here, min is short for scan_time_min_ms
  // and max is short for scan_time_max_ms.
  //
  // min>=0, max=0: scan dwells on each channel for the default
  //                length of time.
  // min=0, max>0: scan dwells on each channel for max ms.
  // min>0, max>0: the minimum time the scan dwells on each
  //               channel is min ms. If no AP is found during
  //               this time frame, the scan switches to the
  //               next channel. Otherwise, the scan dwells on
  //               the channel for max ms.
  uint32 scan_time_min_ms = 6;
  uint32 scan_time_max_ms = 7;
}

enum WIFI_SECURITY_TYPE {
    WIFI_AUTH_OPEN = 0;
    WIFI_AUTH_WEP = 1;
    WIFI_AUTH_WPA_PSK = 2;
    WIFI_AUTH_WPA2_PSK = 3;
    WIFI_AUTH_WPA_WPA2_PSK = 4;
    WIFI_AUTH_WPA2_ENTERPRISE = 5;
    WIFI_AUTH_WPA3_PSK = 6;
    WIFI_AUTH_WPA2_WPA3_PSK = 7;
    WIFI_AUTH_WAPI_PSK = 8;
}

message ScanResult {
  bytes ssid = 1; // empty SSID means there are no more results
  bytes bssid = 2;
  WIFI_SECURITY_TYPE security_type = 3;
  uint32 frequency = 4;
  uint32 channel = 5;
  int32 signal = 6;
}

message ScanResults {
  repeated ScanResult aps = 1;
}

message ConnectionData {
  bytes ssid = 1;
  WIFI_SECURITY_TYPE security_type = 2;
  bytes secret = 3; // e.g. passphrase or psk
}

enum CONNECTION_ERROR {
  OK = 0;
  UNSPECIFIED = 1;
  AUTH_EXPIRE = 2;
  AUTH_LEAVE = 3;
  ASSOC_EXPIRE = 4;
  ASSOC_TOOMANY = 5;
  NOT_AUTHED = 6;
  NOT_ASSOCED = 7;
  ASSOC_LEAVE = 8;
  ASSOC_NOT_AUTHED = 9;
  DISASSOC_PWRCAP_BAD = 10;
  DISASSOC_SUPCHAN_BAD = 11;
  IE_INVALID = 13;
  MIC_FAILURE = 14;
  FOURWAY_HANDSHAKE_TIMEOUT = 15;
  GROUP_KEY_UPDATE_TIMEOUT = 16;
  IE_IN_4WAY_DIFFERS = 17;
  GROUP_CIPHER_INVALID = 18;
  PAIRWISE_CIPHER_INVALID = 19;
  AKMP_INVALID = 20;
  UNSUPP_RSN_IE_VERSION = 21;
  INVALID_RSN_IE_CAP = 22;
  IEEE802_1X_AUTH_FAILED = 23;
  CIPHER_SUITE_REJECTED = 24;
  INVALID_PMKID = 53;
  BEACON_TIMEOUT = 200;
  NO_AP_FOUND = 201;
  AUTH_FAIL = 202;
  ASSOC_FAIL = 203;
  HANDSHAKE_TIMEOUT = 204;
  CONNECTION_FAIL = 205;
  AP_TSF_RESET = 206;
  ROAMING = 207;
}

message ConnectionResult {
  CONNECTION_ERROR error = 1;
}

// The WiFi service provides the common RPC interface for interacting
// with a WIFI capable CHIP device.
// The current state can be retrieved using the various 'Get' RPCs.
// A device can be connected to an AP using the StartScan, and Connect RPCs.
service WiFi {
  rpc GetChannel(pw.protobuf.Empty) returns (Channel) {}
  rpc GetSsid(pw.protobuf.Empty) returns (Ssid) {}
  rpc GetState(pw.protobuf.Empty) returns (State) {}
  rpc GetMacAddress(pw.protobuf.Empty) returns (MacAddress) {}

  rpc GetWiFiInterface(pw.protobuf.Empty) returns (WiFiInterface) {}
  rpc GetIP4Address(pw.protobuf.Empty) returns (IP4Address) {}
  rpc GetIP6Address(pw.protobuf.Empty) returns (IP6Address) {}

  rpc StartScan(ScanConfig) returns (stream ScanResults) {}
  rpc StopScan(pw.protobuf.Empty) returns (pw.protobuf.Empty) {}
  rpc Connect(ConnectionData) returns (ConnectionResult) {}
  rpc Disconnect(pw.protobuf.Empty) returns (pw.protobuf.Empty) {}
}