diff --git a/src/raspberrypi/rascsi.cpp b/src/raspberrypi/rascsi.cpp index 804548a3..339a7071 100644 --- a/src/raspberrypi/rascsi.cpp +++ b/src/raspberrypi/rascsi.cpp @@ -1500,6 +1500,15 @@ static void *MonThread(void *param) break; } + case OPERATION_INFO: { + LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str()); + + PbResult result; + result.set_allocated_operation_info(rascsi_response.GetOperationInfo(result)); + SerializeMessage(fd, result); + break; + } + case RESERVED_IDS_INFO: { LOGTRACE("Received %s command", PbOperation_Name(command.operation()).c_str()); diff --git a/src/raspberrypi/rascsi_interface.proto b/src/raspberrypi/rascsi_interface.proto index 1fad7395..7d59c0fd 100644 --- a/src/raspberrypi/rascsi_interface.proto +++ b/src/raspberrypi/rascsi_interface.proto @@ -162,17 +162,21 @@ enum PbOperation { // The operation parameter meta data message PbOperationParameter { string name = 1; + // Optional description + string description = 2; // "int" or "string" - string type = 2; - // Any value of the specified type is permitted if empty - repeated string values = 3; - bool is_mandatory = 4; + string type = 3; + // There is no specific set of values if empty + repeated string values = 4; + bool is_mandatory = 5; } // The list of parameters supported by an operation message PbOperationParameters { - PbOperation operation = 1; - repeated PbOperationParameter parameters = 2; + string operation = 1; + // Optional description + string description = 2; + repeated PbOperationParameter parameters = 3; } message PbOperationInfo { diff --git a/src/raspberrypi/rascsi_response.cpp b/src/raspberrypi/rascsi_response.cpp index 7636447f..5173902b 100644 --- a/src/raspberrypi/rascsi_response.cpp +++ b/src/raspberrypi/rascsi_response.cpp @@ -334,3 +334,30 @@ PbMappingInfo *RascsiResponse::GetMappingInfo(PbResult& result) return mapping_info; } + +PbOperationInfo *RascsiResponse::GetOperationInfo(PbResult& result) +{ + PbOperationInfo *operation_info = new PbOperationInfo(); + + PbOperationParameters *parameters; + PbOperationParameter *parameter; + + parameters = operation_info->add_operations(); + parameters->set_operation(PbOperation_Name(ATTACH)); + parameters->set_description("Attach device, one of the parameters below is required"); + parameter = parameters->add_parameters(); + parameter->set_name("name"); + parameter->set_description("Image file name"); + parameter->set_type("string"); + parameter = parameters->add_parameters(); + parameter->set_name("interfaces"); + parameter->set_description("Comma-separated list of network interfaces"); + parameter->set_type("string"); + + parameters = operation_info->add_operations(); + parameters->set_operation(PbOperation_Name(OPERATION_INFO)); + + result.set_status(true); + + return operation_info; +} diff --git a/src/raspberrypi/rascsi_response.h b/src/raspberrypi/rascsi_response.h index a4c7893a..e8ea0ee9 100644 --- a/src/raspberrypi/rascsi_response.h +++ b/src/raspberrypi/rascsi_response.h @@ -30,15 +30,16 @@ public: bool GetImageFile(PbImageFile *, const string&); PbImageFilesInfo *GetAvailableImages(PbResult&); - PbReservedIdsInfo *GetReservedIds(PbResult&, const set&); void GetDevices(PbServerInfo&, const vector&); void GetDevicesInfo(PbResult&, const PbCommand&, const vector&, int); PbDeviceTypesInfo *GetDeviceTypesInfo(PbResult&, const PbCommand&); PbVersionInfo *GetVersionInfo(PbResult&); PbServerInfo *GetServerInfo(PbResult&, const vector&, const set&, const string&); PbNetworkInterfacesInfo *GetNetworkInterfacesInfo(PbResult&); - PbMappingInfo *GetMappingInfo(PbResult&); PbLogLevelInfo *GetLogLevelInfo(PbResult&, const string&); + PbReservedIdsInfo *GetReservedIds(PbResult&, const set&); + PbMappingInfo *GetMappingInfo(PbResult&); + PbOperationInfo *GetOperationInfo(PbResult&); private: diff --git a/src/raspberrypi/rasctl.cpp b/src/raspberrypi/rasctl.cpp index f89e0835..94ed5cad 100644 --- a/src/raspberrypi/rasctl.cpp +++ b/src/raspberrypi/rasctl.cpp @@ -102,7 +102,7 @@ int main(int argc, char* argv[]) cerr << "Usage: " << argv[0] << " -i ID [-u UNIT] [-c CMD] [-C FILE] [-t TYPE] [-b BLOCK_SIZE] [-n NAME] [-f FILE|PARAM] "; cerr << "[-F IMAGE_FOLDER] [-L LOG_LEVEL] [-h HOST] [-p PORT] [-r RESERVED_IDS] "; cerr << "[-C FILENAME:FILESIZE] [-d FILENAME] [-w FILENAME] [-R CURRENT_NAME:NEW_NAME] [-x CURRENT_NAME:NEW_NAME] "; - cerr << "[-e] [-E FILENAME] [-D] [-I] [-l] [-L] [-m] [-O] [-s] [-v] [-V] [-y] [-X]" << endl; + cerr << "[-e] [-E FILENAME] [-D] [-I] [-l] [-L] [-m] [o] [-O] [-s] [-v] [-V] [-y] [-X]" << endl; cerr << " where ID := {0-7}" << endl; cerr << " UNIT := {0-31}, default is 0" << endl; cerr << " CMD := {attach|detach|insert|eject|protect|unprotect|show}" << endl; @@ -138,7 +138,7 @@ int main(int argc, char* argv[]) opterr = 1; int opt; - while ((opt = getopt(argc, argv, "elmsvDINOTVXa:b:c:d:f:h:i:n:p:r:t:u:x:C:E:F:L:R:")) != -1) { + while ((opt = getopt(argc, argv, "elmosvDINOTVXa:b:c:d:f:h:i:n:p:r:t:u:x:C:E:F:L:R:")) != -1) { switch (opt) { case 'i': { int id; @@ -238,6 +238,10 @@ int main(int argc, char* argv[]) command.set_operation(LOG_LEVEL_INFO); break; + case 'o': + command.set_operation(OPERATION_INFO); + break; + case 't': device->set_type(ParseType(optarg)); if (device->type() == UNDEFINED) { @@ -411,6 +415,10 @@ int main(int argc, char* argv[]) rasctl_commands.CommandMappingInfo(); break; + case OPERATION_INFO: + rasctl_commands.CommandOperationInfo(); + break; + default: rasctl_commands.SendCommand(); break; diff --git a/src/raspberrypi/rasctl_commands.cpp b/src/raspberrypi/rasctl_commands.cpp index 0302520b..185c1f5a 100644 --- a/src/raspberrypi/rasctl_commands.cpp +++ b/src/raspberrypi/rasctl_commands.cpp @@ -273,3 +273,10 @@ void RasctlCommands::CommandMappingInfo() rasctl_display.DisplayMappingInfo(result.mapping_info()); } + +void RasctlCommands::CommandOperationInfo() +{ + SendCommand(); + + rasctl_display.DisplayOperationInfo(result.operation_info()); +} diff --git a/src/raspberrypi/rasctl_commands.h b/src/raspberrypi/rasctl_commands.h index 0704191c..d1b88347 100644 --- a/src/raspberrypi/rasctl_commands.h +++ b/src/raspberrypi/rasctl_commands.h @@ -42,6 +42,7 @@ public: void CommandLogLevelInfo(); void CommandReservedIdsInfo(); void CommandMappingInfo(); + void CommandOperationInfo(); private: diff --git a/src/raspberrypi/rasctl_display.cpp b/src/raspberrypi/rasctl_display.cpp index 6d3e2da3..5a5d1df1 100644 --- a/src/raspberrypi/rasctl_display.cpp +++ b/src/raspberrypi/rasctl_display.cpp @@ -273,3 +273,24 @@ void RasctlDisplay::DisplayMappingInfo(const PbMappingInfo& mapping_info) cout << " " << mapping.first << "->" << PbDeviceType_Name(mapping.second) << endl; } } + +void RasctlDisplay::DisplayOperationInfo(const PbOperationInfo& operation_info) +{ + cout << "Remote operations supported by rascsi and their parameters:" << endl; + for (const auto& operation : operation_info.operations()) { + cout << " " << operation.operation(); + if (!operation.description().empty()) { + cout << " (" << operation.description() << ")"; + } + cout << endl; + + for (const auto& parameter : operation.parameters()) { + cout << " " << parameter.name() << ": " << parameter.type() + << (parameter.is_mandatory() ? ", mandatory" : ", optional"); + if (!parameter.description().empty()) { + cout << " (" << parameter.description() << ")"; + } + cout << endl; + } + } +} diff --git a/src/raspberrypi/rasctl_display.h b/src/raspberrypi/rasctl_display.h index 9957e5fa..864027a4 100644 --- a/src/raspberrypi/rasctl_display.h +++ b/src/raspberrypi/rasctl_display.h @@ -30,4 +30,5 @@ public: void DisplayImageFiles(const PbImageFilesInfo&); void DisplayNetworkInterfaces(const PbNetworkInterfacesInfo&); void DisplayMappingInfo(const PbMappingInfo&); + void DisplayOperationInfo(const PbOperationInfo&); };