syntax = "proto3";

package P4wnP1_grpc;

service P4WNP1 {
    //Bluetooth
    rpc GetBluetoothControllerInformation (Empty) returns (BluetoothControllerInformation) {}
    rpc DeployBluetoothControllerInformation (BluetoothControllerInformation) returns (BluetoothControllerInformation) {}
    rpc GetBluetoothAgentSettings (Empty) returns (BluetoothAgentSettings) {}
    rpc DeployBluetoothAgentSettings (BluetoothAgentSettings) returns (BluetoothAgentSettings) {}
    rpc SetBluetoothNetworkService (BluetoothNetworkService) returns (Empty) {}
    rpc DeployBluetoothSettings (BluetoothSettings) returns (BluetoothSettings) {}

    rpc StoreBluetoothSettings(BluetoothRequestSettingsStorage) returns (Empty) {}
    rpc GetStoredBluetoothSettings(StringMessage) returns (BluetoothSettings) {}
    rpc DeployStoredBluetoothSettings(StringMessage) returns (BluetoothSettings) {}
    rpc DeleteStoredBluetoothSettings(StringMessage) returns (Empty) {}
    rpc StoreDeployedBluetoothSettings(StringMessage) returns (Empty) {}
    rpc ListStoredBluetoothSettings(Empty) returns (StringMessageArray) {}


    //USB gadget
    rpc GetDeployedGadgetSetting (Empty) returns (GadgetSettings) {    }
    rpc DeployGadgetSetting (GadgetSettings) returns (GadgetSettings) {    }

    rpc GetLEDSettings (Empty) returns (LEDSettings) {    }
    rpc SetLEDSettings (LEDSettings) returns (Empty) {    }
    rpc MountUMSFile (GadgetSettingsUMS) returns (Empty) {    }

    rpc StoreUSBSettings(USBRequestSettingsStorage) returns (Empty) {}
    rpc GetStoredUSBSettings(StringMessage) returns (GadgetSettings) {}
    rpc DeployStoredUSBSettings(StringMessage) returns (GadgetSettings) {}
    rpc DeleteStoredUSBSettings(StringMessage) returns (Empty) {}
    rpc StoreDeployedUSBSettings(StringMessage) returns (Empty) {}
    rpc ListStoredUSBSettings(Empty) returns (StringMessageArray) {}

    rpc ListUmsImageCdrom(Empty) returns (StringMessageArray) {}
    rpc ListUmsImageFlashdrive(Empty) returns (StringMessageArray) {}

    //HIDScript / job management
    rpc HIDRunScript (HIDScriptRequest) returns (HIDScriptResult) {    }
    rpc HIDRunScriptJob (HIDScriptRequest) returns (HIDScriptJob) {    }
    rpc HIDGetScriptJobResult (HIDScriptJob) returns (HIDScriptResult) {    }
    rpc HIDCancelScriptJob (HIDScriptJob) returns (Empty) {    }
    rpc HIDGetRunningScriptJobs (Empty) returns (HIDScriptJobList) {    }
    rpc HIDCancelAllScriptJobs (Empty) returns (Empty) {    }
    rpc HIDGetRunningJobState (HIDScriptJob) returns (HIDRunningJobStateResult) {    }

    //FileSystem
    rpc FSWriteFile (WriteFileRequest) returns (Empty) {}
    rpc FSReadFile (ReadFileRequest) returns (ReadFileResponse) {}
    rpc FSGetFileInfo (FileInfoRequest) returns (FileInfoResponse) {    }
    rpc FSCreateTempDirOrFile (TempDirOrFileRequest) returns (TempDirOrFileResponse) {    }

    //Events
    rpc EventListen (EventRequest) returns (stream Event) {    }

    //Alive check
    rpc EchoRequest (StringMessage) returns (StringMessage) {    }

    // WiFi
    rpc DeployWiFiSettings (WiFiSettings) returns (WiFiState) {}
    rpc GetWiFiState (Empty) returns (WiFiState) {}
    rpc ListenWiFiStateChanges (Empty) returns (WiFiState) {} //ToDo: Check usage

    rpc StoreWifiSettings(WifiRequestSettingsStorage) returns (Empty) {}
    rpc GetStoredWifiSettings(StringMessage) returns (WiFiSettings) {}
    rpc DeployStoredWifiSettings(StringMessage) returns (WiFiState) {}
    rpc DeleteStoredWifiSettings(StringMessage) returns (Empty) {}
    rpc StoreDeployedWifiSettings(StringMessage) returns (Empty) {}
    rpc ListStoredWifiSettings(Empty) returns (StringMessageArray) {}

    //Ethernet
    rpc DeployEthernetInterfaceSettings (EthernetInterfaceSettings) returns (Empty) {    }
    rpc GetAllDeployedEthernetInterfaceSettings (Empty) returns (DeployedEthernetInterfaceSettings) {    }
    rpc GetDeployedEthernetInterfaceSettings (StringMessage) returns (EthernetInterfaceSettings) {    } //StringMessage has to contain the interface name

    rpc StoreEthernetInterfaceSettings(EthernetRequestSettingsStorage) returns (Empty) {}
    rpc GetStoredEthernetInterfaceSettings(StringMessage) returns (EthernetInterfaceSettings) {}
    rpc DeployStoredEthernetInterfaceSettings(StringMessage) returns (Empty) {}
    rpc DeleteStoredEthernetInterfaceSettings(StringMessage) returns (Empty) {}
    rpc ListStoredEthernetInterfaceSettings(Empty) returns (StringMessageArray) {}
    //ToDo: Store&Load for EthernetInterfaceSettingsList (multiple interfaces)



    // TriggerActions
    rpc GetDeployedTriggerActionSet(Empty) returns (TriggerActionSet) {}
    rpc DeployTriggerActionSetReplace(TriggerActionSet) returns (TriggerActionSet) {} // Replaces registered TriggerActions with given set, returns a set ONLY OF ADDED TriggerActions (with assigned IDs)
    rpc DeployTriggerActionSetAdd(TriggerActionSet) returns (TriggerActionSet) {} //  Adds a set of additional TriggerActions, returns a set of all Triggeractions registered afterwards
    rpc DeployTriggerActionSetRemove(TriggerActionSet) returns (TriggerActionSet) {} // Removes registered TriggerActions from given set, returns a set ONLY OF REMOVED TriggerActions (with assigned IDs)
    rpc DeployTriggerActionSetUpdate(TriggerActionSet) returns (TriggerActionSet) {} // Updates already registered TriggerActions from given set, returns aall regitered TriggerActions

    rpc ListStoredTriggerActionSets(Empty) returns (StringMessageArray) {}
    rpc StoreTriggerActionSet(TriggerActionSet) returns (Empty) {}
    rpc DeployStoredTriggerActionSetReplace(StringMessage) returns (TriggerActionSet) {} // Adds a set of additional TriggerActions, returns a set of all Triggeractions registered afterwards
    rpc DeployStoredTriggerActionSetAdd(StringMessage) returns (TriggerActionSet) {} // Replaces registered TriggerActions with given set, returns a set ONLY OF ADDED TriggerActions (with assigned IDs)
    rpc DeleteStoredTriggerActionSet(StringMessage) returns (Empty) {}

    //TriggerAction for cli (trigger group send and wait for group receive)
    rpc WaitTriggerGroupReceive(TriggerGroupReceive) returns (Empty) {}
    rpc FireActionGroupSend(ActionGroupSend) returns (Empty) {}


    //MasterTemplates
    rpc DeployMasterTemplate(MasterTemplate) returns (Empty) {}

    rpc StoreMasterTemplate(RequestMasterTemplateStorage) returns (Empty) {}
    rpc GetStoredMasterTemplate(StringMessage) returns (MasterTemplate) {}
    rpc DeployStoredMasterTemplate(StringMessage) returns (MasterTemplate) {}
    rpc DeleteStoredMasterTemplate(StringMessage) returns (Empty) {}
    rpc ListStoredMasterTemplate(Empty) returns (StringMessageArray) {}

    // Startup Master Template
    rpc GetStartupMasterTemplate(Empty) returns (StringMessage) {}
    rpc SetStartupMasterTemplate(StringMessage) returns (Empty) {}


    // DB backup&restore
    rpc DBBackup(StringMessage) returns(Empty) {}
    rpc DBRestore(StringMessage) returns(Empty) {}

    rpc ListStoredHIDScripts(Empty) returns (StringMessageArray) {}
    rpc ListStoredBashScripts(Empty) returns (StringMessageArray) {}
    rpc ListStoredDBBackups(Empty) returns (StringMessageArray) {}

    /* GPIO */
    rpc GetAvailableGpios(Empty) returns (StringMessageArray) {}

    /* System */
    rpc Shutdown(Empty) returns (Empty) {}
    rpc Reboot(Empty) returns (Empty) {}
}

/* MasterTemplates */
message MasterTemplate {
    string template_name_bluetooth = 1;
    string template_name_usb = 2;
    string template_name_wifi = 3;
    string template_name_trigger_actions = 4;
    repeated string template_names_network = 5;
}

message RequestMasterTemplateStorage {
    string TemplateName = 1;
    MasterTemplate template = 2;
}


/* Bluetooth */
message BluetoothRequestSettingsStorage {
    string TemplateName = 1;
    BluetoothSettings settings = 2;
}

message BluetoothSettings {
    BluetoothControllerInformation ci = 1; //Parts interpreted as settings: current_settings, name, service_network_server_nap, service_network_server_panu, service_network_server_gn
    BluetoothAgentSettings as = 2;
}

message BluetoothAgentSettings {
    string pin = 1;
}

enum BluetoothNetworkServiceType {
    NAP = 0;
    PANU = 1;
    GN = 2;
}

message BluetoothNetworkService {
    bool register_or_unregister = 1; //true = register, false = unregister
    bool server_or_connect = 2; //if true, try to connect to network service of remoter device given by name_mac, else open service
    BluetoothNetworkServiceType type = 3;
    string mac_or_name = 4;
    string bridge_name = 5; //
}

message BluetoothControllerSettings {
    bool powered = 1;
    bool connectable = 2;
    bool fast_connectable = 3;
    bool discoverable = 4;
    bool bondable = 5;
    bool link_level_security = 6;
    bool secure_simple_pairing = 7;
    bool br_edr = 8;
    bool high_speed = 9;
    bool low_energy = 10;
    bool advertising = 11;
    bool secure_connections = 12;
    bool debug_keys = 13;
    bool privacy = 14;
    bool controller_configuration = 15;
    bool static_address = 16;
}

message BluetoothControllerInformation {
    bytes address = 1;
    uint32 bluetooth_version = 2;
    uint32 manufacturer = 3;
    BluetoothControllerSettings supported_settings = 4;
    BluetoothControllerSettings current_settings = 5;
    bytes class_of_device = 6;
    string name = 7;
    string short_name = 8;
    bool is_available = 9;

    bool service_network_server_nap = 10;
    bool service_network_server_panu = 11;
    bool service_network_server_gn = 12;
}

/* Triggers, Actions and resulting TriggerActions */
message TriggerActionSet {
    repeated TriggerAction TriggerActions = 1;
    string Name = 2;
}



message TriggerAction {
    uint32 id = 1; // assigned by service, used as identifier to allow deletion of trigger actions
    bool oneShot = 2;
    bool isActive = 3;
    bool immutable = 4;
    oneof Trigger {
        TriggerServiceStarted serviceStarted = 5;
        TriggerUSBGadgetConnected usbGadgetConnected = 6;
        TriggerUSBGadgetDisconnected usbGadgetDisconnected = 7;
        TriggerWifiAPStarted wifiAPStarted = 8;
        TriggerWifiConnectedAsSta wifiConnectedAsSta = 9;
        TriggerSSHLogin sshLogin = 10;
        TriggerDHCPLeaseGranted dhcpLeaseGranted = 11;
        TriggerGroupReceive groupReceive = 12;
        TriggerGroupReceiveMulti groupReceiveMulti = 13;
        TriggerGPIOIn gpioIn = 14;
    }

    oneof Action {
        ActionStartBashScript bashScript = 15;
        ActionStartHIDScript hidScript = 16;
        ActionDeploySettingsTemplate deploySettingsTemplate = 17;
        ActionLog log = 18;
        ActionGPIOOut gpioOut = 19;
        ActionGroupSend groupSend = 20;
    }
}

message TriggerServiceStarted {} //no fields
message TriggerUSBGadgetConnected{}
message TriggerUSBGadgetDisconnected{}
message TriggerWifiAPStarted{} // fired when an Access Point is running
message TriggerWifiConnectedAsSta{} // fired when successfully connected to an existing AP
message TriggerSSHLogin{  // fired when a user logs in
    string loginUser = 1;
}
message TriggerDHCPLeaseGranted {} // fired when a client receives a lease
message TriggerGroupReceive{  // fired when the correct value is received on the group channel
    string groupName = 1;
    int32 value = 2;
}

enum GroupReceiveMultiType {
    SEQUENCE = 0; // values have to occur in order (other values allowed in between)
    AND = 1; //logical and ("all" values have to occur, could be unordered)
    OR = 2; //logical or ("one of" the values has to occur)
    EXACT_SEQUENCE = 3; // values have to occur in order (other values are NOT allowed in between)

}

message TriggerGroupReceiveMulti{
    string groupName = 1;
    repeated int32 values = 3;
    GroupReceiveMultiType type = 4;
}
enum GPIOInPullUpDown {
    UP = 0;
    DOWN = 1;
    OFF = 2;
}
enum GPIOInEdge {
    RISING = 0;
    FALLING = 1;
    BOTH = 2;
}
message TriggerGPIOIn {
    string gpio_name = 1;
    GPIOInPullUpDown pullUpDown = 2;
    GPIOInEdge gpioInEdge = 3;
    int64 debounce_millis = 4;
}



message ActionStartBashScript {
    string scriptName = 1;
}
message ActionStartHIDScript {
    string scriptName = 1; //could be combined into oneof with script path, to allow starting scripts from arbitrary filepath (avoids storing scripts in DB or fixed folder)
}
message ActionDeploySettingsTemplate {
    string templateName = 1;
    enum TemplateType {
        FULL_SETTINGS = 0;
        NETWORK = 1;
        WIFI = 2;
        USB = 3;
        BLUETOOTH = 4;
        TRIGGER_ACTIONS = 5;
    }
    TemplateType type = 2;
}
message ActionLog {}
enum GPIOOutValue {
    LOW = 0;
    HIGH = 1;
    TOGGLE = 2;
}

message ActionGPIOOut {
    string gpio_name = 1;
    GPIOOutValue value = 2;
}
message ActionGroupSend {
    string groupName = 1;
    int32 value = 2;
}

message WifiRequestSettingsStorage {
    string TemplateName = 1;
    WiFiSettings settings = 2;
}

/* WiFi2 (distinguish state and settings) */
enum WiFiWorkingMode {
    UNKNOWN = 0;
    AP = 1; //acts as access point
    STA = 2; //acts as station for an existing access point
    STA_FAILOVER_AP = 3; //acts as station, if connection to the given AP isn't possible spawns an own AP
}

enum WiFiStateMode {
    STA_NOT_CONNECTED = 0;
    AP_UP = 1; //acts as access point
    STA_CONNECTED = 2; //acts as station for an existing access point
}

enum WiFiAuthMode {
    WPA2_PSK = 0; //AP uses WPA2 pre-shared key
    OPEN = 1; //Open System Authentication (no authentication)
}

message WiFiSettings {
    /* Generic */
    string name = 1; //for template storage
    bool disabled = 2; //disabled means neither hostapd, nor wpa_supplicant are running, the interface could still be enabled
    string regulatory = 3; //Regulatory domain per ISO/IEC 3166-1 alpha2
    WiFiWorkingMode working_mode = 4;
    WiFiAuthMode auth_mode = 5;
    uint32 channel = 6;


    WiFiBSSCfg ap_BSS = 7; //SSID of AP to spawn + PSK if needed
    repeated WiFiBSSCfg client_BSS_list = 8; //SSID of Infra to join + PSK if needed
    bool hide_ssid = 9; //if true, SSID gets hidden for spawned AP

    bool nexmon = 13;
}

message WiFiState {
    WiFiStateMode mode = 1;
    uint32 channel = 2;
    string ssid = 3; //SSID currently connected (STA) or spawned (AP)
    WiFiSettings currentSettings = 4;
}

message WiFiBSSCfg {
    string SSID = 1;
    string PSK = 2;
}

/* Alive check  */
message StringMessage {
    string msg = 1;
}

message StringMessageArray {
    repeated string msgArray = 1;
}

/* Events */
message EventRequest {
    int64 listenType = 1;
}

message EventValue {
    oneof val {
        string tstring = 1;
        bool tbool = 2;
        int64 tint64 = 3;
    }
}

message Event {
    int64 type = 1;
    repeated EventValue values = 2;
}

/* File System */
message TempDirOrFileRequest {
    string dir = 1;
    string prefix = 2;
    bool onlyFolder = 3;
}

message TempDirOrFileResponse {
    string resultPath = 1;
}

enum AccessibleFolder {
    TMP = 0;
    BASH_SCRIPTS = 1;
    HID_SCRIPTS = 2;
}

message ReadFileRequest {
    AccessibleFolder folder = 1;
    string filename = 2;
    int64 start = 3;
    int64 len = 4;
}

message ReadFileResponse {
    int64 readCount = 1;
    bytes data = 2;
}

message WriteFileRequest {
    AccessibleFolder folder = 1;
    string filename = 2;
    bool append = 3;
    bool mustNotExist = 4;
    bytes data = 5;
}

message FileInfoRequest {
    string path = 1;
}

message FileInfoResponse {
    string name = 1;
    int64 size = 2;
    uint32 mode = 3;
    int64 modTime = 4; //unused
    bool isDir = 5;
}

/* HID */
message HIDScriptRequest {
    string scriptPath = 1;
    uint32 timeoutSeconds = 2; //a timeout > 0 interrupts the HIDScript when reached, meassurement in seconds
}

message HIDScriptJob {
    uint32 id = 1;
}

message HIDScriptJobList {
    repeated uint32 ids = 1;
}

message HIDRunningJobStateResult {
    int64 id = 1;
    int64 vmId = 2;
    string source = 3;
}

message HIDScriptResult {
    HIDScriptJob job = 1;
    bool isFinished = 2;
    string resultJson = 3;
    //string logOutput = 4; //will be used to retrieve log output of unfinished scripts, better implemented in dedicated method with stream
}

/* LED */
message LEDSettings {
    uint32 blink_count = 1;
}
/* End LED */

/* USB Gadget */
message USBRequestSettingsStorage {
    string TemplateName = 1;
    GadgetSettings settings = 2;
}


message GadgetSettings {
    bool enabled = 1;
    string vid = 2;
    string pid = 3;
    string manufacturer = 4;
    string product = 5;
    string serial = 6;
    bool use_CDC_ECM = 7;
    bool use_RNDIS = 8;
    bool use_HID_KEYBOARD = 9;
    bool use_HID_MOUSE = 10;
    bool use_HID_RAW = 11;
    bool use_UMS = 12;
    bool use_SERIAL = 13;
    GadgetSettingsEthernet rndis_settings = 14; //Only applicable if RNDIS on
    GadgetSettingsEthernet cdc_ecm_settings = 15; //Only applicable if CDC ECM on
    GadgetSettingsUMS ums_settings = 16;
    //EthernetInterfaceSettings ethernet_settings = 17; //only applicable if RNDIS or CDC ECM on
    string dev_path_hid_keyboard = 18;
    string dev_path_hid_mouse = 19;
    string dev_path_hid_raw = 20;
}

message GadgetSettingsEthernet {
    string host_addr = 1;
    string dev_addr = 2;
}

message GadgetSettingsUMS {
    bool cdrom = 1;
    string file = 2;
}
/* End USB Gadget */

/* Ethernet Interface Settings */
message EthernetRequestSettingsStorage {
    string TemplateName = 1;
    EthernetInterfaceSettings settings = 2;
}


message DeployedEthernetInterfaceSettings {
    repeated EthernetInterfaceSettings list = 1;
}

message EthernetInterfaceSettings {
    string name = 1;
    enum Mode {
        MANUAL = 0;
        DHCP_CLIENT = 1;
        DHCP_SERVER = 2;
        UNMANAGED = 3; // Indicates that the settings aren't known, as they aren't managed by the service
    }
    Mode mode = 2;
    string ipAddress4 = 3;
    string netmask4 = 4;
    bool enabled = 5;
    DHCPServerSettings dhcpServerSettings = 6;
    bool settingsInUse = 7; //indicates if the given settings are applied to the interface
}

/* DHCP */
message DHCPServerSettings {
    uint32 listenPort = 1; //if a port other thaan 0 is provided, a DNS server is bound to this port in addition to DHCP
    string listenInterface = 2;
    string leaseFile = 3;
    bool notAuthoritative = 4;
    bool doNotBindInterface = 5; //if true, DHCP server binds to 0.0.0.0, no matter which interface is given (no restart needed on interface up/down)
    string callbackScript = 6; //Script executes when lease is added/deleted `scriptname <add|del> <MAC> <IP> <HOSTNAME>`

    repeated DHCPServerRange ranges = 7;
    //repeated DHCPServerOption options = 8;
    map<uint32, string> options = 8; //Replaced by map (dealing with key duplicates is ONLY PARTIALY handled by proto3), See RFC 2132 for details of available options
    repeated DHCPServerStaticHost staticHosts = 9;
}

//Could be used for IPv4 or IPv6 (refer dnsmasq docs), nor field for prefix length (default is 64)
message DHCPServerRange {
    string rangeLower = 1; //Lowest IP of DHCP range
    string rangeUpper = 2; //Highest IP of DHCP range
    string leaseTime = 3;
}

//Used for static leases
message DHCPServerStaticHost {
    string mac = 1;
    string ip = 2;
}


message Empty {
}
