DASH CLI supports new options to enable developers to send request query in JSON format to DASH systems and get the output in JSON format. The output can be interpreted by any programming language supporting JSON format. The output JSON is modeled like Redfish Schema published by DMTF.
In typical usage, DASH CLI is launched with request JSON, DASH CLI processes the request and forms the response in JSON format. This response is sent back to the launching application.
JSON is supported by almost all modern programming languages. Hence it will be easier to add DASH capability into any application or tool with few simple steps. Since the application will be launching DASH CLI, the integration with the application is therefore ‘loosely coupled’. DASH communication, DASH standards compliance, DASH security & stability are encapsulated within DASH CLI. The calling application does not require to know anything about DASH standard.
There are two new options in DASH CLI:
jdo option is faster since it does not involve in any file operation.
dashcli -jdo
When this command is run, DASH CLI waits for input in JSON format. Once the input is provided, it will be executed by DASH CLI and output of which is written back in JSON format, as shown in the screenshot below.
Create a sample C++ Console application by following the steps below:
Step 1: Create a new project in Visual Studio by selecting from the Menu “File” > “New” > “Project”
Step 2: Select “Visual C++” -> “Console App”. Name the application “JDOApp” and click “OK” button.
Step 3: Add the two constant variables in main function which contains path to DASHCLI and arguments to it
const char szArgs[] = (" -jdo ");
const char szAppPath[] = ("C:\\Program Files (x86)\\DASH CLI 3.0\\bin\\dashcli.exe");
Step 4: Include windows, fstream and iostream header files as these will be referenced in the upcoming code.
#include <windows.h>
#include <fstream>
#include <iostream>
Step 5: Define the below functions
int RunDashCLIWithJDO(const char szAppPath[], const char szArgs[], const char szCommands[])
{
int iRetVal = 0;
// Create PIPE for sending commands and reading output from DASHCLI process.
SECURITY_ATTRIBUTES seAttr;
// Set the bInheritHandle flag true so pipe handles are inherited.
seAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
seAttr.bInheritHandle = true;
seAttr.lpSecurityDescriptor = NULL;
// Create a pipe for the DASHCli process's STDOUT.
if (!CreatePipe(&ghDashCmdOUTRd, &ghDashCmdOUTWr, &seAttr, 0))
{
cout << "Stdout CreatePipe failed." << endl;
iRetVal = -1;
}
// Ensure the read handle to the pipe for STDOUT is not inherited.
if (!SetHandleInformation(ghDashCmdOUTRd, HANDLE_FLAG_INHERIT, 0))
{
cout << "Stdout SetHandleInformation failed." << endl;
iRetVal = -1;
}
// Create a pipe for the DASHCli process's STDIN.
if (!CreatePipe(&ghDashCmdINRd, &ghDashCmdINWr, &seAttr, 0))
{
cout << "Stdin CreatePipe failed." << endl;
iRetVal = -1;
}
// Ensure the write handle to the pipe for STDIN is not inherited.
if (!SetHandleInformation(ghDashCmdINWr, HANDLE_FLAG_INHERIT, 0))
{
cout << "Stdin SetHandleInformation failed." << endl;
iRetVal = -1;
}
PROCESS_INFORMATION piProcInfo;
STARTUPINFOA siStartInfo;
// Set up members of the PROCESS_INFORMATION structure.
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
// Set up members of the STARTUPINFO structure.
// This structure specifies the STDIN and STDOUT handles for redirection.
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = ghDashCmdOUTWr;
siStartInfo.hStdOutput = ghDashCmdOUTWr;
siStartInfo.hStdInput = ghDashCmdINRd;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
// Create process with application path of DASHCLI and required arguments list.
// If an error occurs, return -1
if (iRetVal != 0 || !CreateProcessA(szAppPath, const_cast<LPSTR>(szArgs), NULL, NULL, true, 0, NULL, NULL, &siStartInfo, &piProcInfo))
{
std::cout << "Process/Pipe creation failed to execute DashCLI" << std::endl;
iRetVal = -1;
}
else
{
// Sending commands to DashCLI
std::cout << szCommands;
unsigned long dwRead = strlen(szCommands), dwWritten;
WriteFile(ghDashCmdINWr, szCommands, dwRead, &dwWritten, NULL);
// Wait for the process to complete execution.
WaitForSingleObject(piProcInfo.hProcess, INFINITE);
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
}
return iRetVal;
}
void ReadFromDashCLIProcess(void)
{
unsigned long dwRead, dwWritten;
char chBuf[BUFSIZE];
bool bSuccess = false;
void * hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
bSuccess = ReadFile(ghDashCmdOUTRd, chBuf, BUFSIZE, &dwRead, NULL);
if (bSuccess && dwRead > 0)
{
WriteFile(hParentStdOut, chBuf, dwRead, &dwWritten, NULL);
}
}
Step 6: Call “RunDashCLIWithJDO” and “ReadFromDashCLIProcess” function in “main” function by reading input from input_json.txt file.
char szCommands[BUFSIZE];
// Read input commands to DashCLI from json file
std::ifstream infile;
infile.open("input_json.txt");
infile >> szCommands;
strcat_s(szCommands, "\r\n"); // Append carriage return and new line characters to input.
cout << "Running DashCLI with JDO" << endl;
if (0 == RunDashCLIWithJDO(szAppPath, szArgs, szCommands))
{
ReadFromDashCLIProcess();
}
The entire code at this stage should look like as below:
#include <windows.h>
#include <fstream>
#include <iostream>
using namespace std;
#define BUFSIZE 4096
void * ghDashCmdINRd = NULL;
void * ghDashCmdINWr = NULL;
void * ghDashCmdOUTRd = NULL;
void * ghDashCmdOUTWr = NULL;
// Create a child process to run DashCLI and redirect STDIN/STDOUT through pipes.
// Returns: -1 if process creation is failed.
// 0 if process creation is successful.
int RunDashCLIWithJDO(const char szAppPath[], const char szArgs[], const char szCommands[])
{
int iRetVal = 0;
// Create PIPE for sending commands and reading output from DASHCLI process.
SECURITY_ATTRIBUTES seAttr;
// Set the bInheritHandle flag true so pipe handles are inherited.
seAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
seAttr.bInheritHandle = true;
seAttr.lpSecurityDescriptor = NULL;
// Create a pipe for the DASHCli process's STDOUT.
if (!CreatePipe(&ghDashCmdOUTRd, &ghDashCmdOUTWr, &seAttr, 0))
{
cout << "Stdout CreatePipe failed." << endl;
iRetVal = -1;
}
// Ensure the read handle to the pipe for STDOUT is not inherited.
if (!SetHandleInformation(ghDashCmdOUTRd, HANDLE_FLAG_INHERIT, 0))
{
cout << "Stdout SetHandleInformation failed." << endl;
iRetVal = -1;
}
// Create a pipe for the DASHCli process's STDIN.
if (!CreatePipe(&ghDashCmdINRd, &ghDashCmdINWr, &seAttr, 0))
{
cout << "Stdin CreatePipe failed." << endl;
iRetVal = -1;
}
// Ensure the write handle to the pipe for STDIN is not inherited.
if (!SetHandleInformation(ghDashCmdINWr, HANDLE_FLAG_INHERIT, 0))
{
cout << "Stdin SetHandleInformation failed." << endl;
iRetVal = -1;
}
PROCESS_INFORMATION piProcInfo;
STARTUPINFOA siStartInfo;
// Set up members of the PROCESS_INFORMATION structure.
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
// Set up members of the STARTUPINFO structure.
// This structure specifies the STDIN and STDOUT handles for redirection.
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = ghDashCmdOUTWr;
siStartInfo.hStdOutput = ghDashCmdOUTWr;
siStartInfo.hStdInput = ghDashCmdINRd;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
// Create process with application path of DASHCLI and required arguments list.
// If an error occurs, return -1
if (iRetVal != 0 || !CreateProcessA(szAppPath, const_cast<LPSTR>(szArgs), NULL, NULL, true, 0, NULL, NULL, &siStartInfo, &piProcInfo))
{
std::cout << "Process/Pipe creation failed to execute DashCLI" << std::endl;
iRetVal = -1;
}
else
{
// Sending commands to DashCLI
std::cout << szCommands;
unsigned long dwRead = strlen(szCommands), dwWritten;
WriteFile(ghDashCmdINWr, szCommands, dwRead, &dwWritten, NULL);
// Wait for the process to complete execution.
WaitForSingleObject(piProcInfo.hProcess, INFINITE);
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
}
return iRetVal;
}
// Read output from the DashCLI process
// and write to the parent STDOUT.
void ReadFromDashCLIProcess(void)
{
unsigned long dwRead, dwWritten;
char chBuf[BUFSIZE];
bool bSuccess = false;
void * hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
bSuccess = ReadFile(ghDashCmdOUTRd, chBuf, BUFSIZE, &dwRead, NULL);
if (bSuccess && dwRead > 0)
{
WriteFile(hParentStdOut, chBuf, dwRead, &dwWritten, NULL);
}
}
int main(int argc, char* argv[])
{
const char szArgs[] = (" -jdo ");
// Path to DashCLI application.
const char szAppPath[] = ("C:\\Program Files (x86)\\DASH CLI 3.0\\bin\\dashcli.exe");
char szCommands[BUFSIZE];
// Read input commands to DashCLI from json file
std::ifstream infile;
infile.open("input_json.txt");
infile >> szCommands;
strcat_s(szCommands, "\r\n"); // Append carriage return and new line characters to input.
cout << "Running DashCLI with JDO" << endl;
if (0 == RunDashCLIWithJDO(szAppPath, szArgs, szCommands))
{
ReadFromDashCLIProcess();
}
cout << "DashCLI execution with JDO is complete." << endl;
return 0;
}
Step 7: In step 6, main function reads input for JDO from a JSON File (input_json.txt). It assumes that input_json.txt is present in the working directory of the project if the application is running through Visual Studio or it should be present in the exe application path.
Step 8: Contents of JSON text file can be any of the input from Developer guide like a discover command as shown below.
{"h":"HP705G1","u":"adminUserName","P":"adminPassword","Commands":["discover"]}
Step 9: Run the JDOApp.exe application from the console.
Other Commands:
Discover Info through DashCLI JDO
This is to discover the given host and get the list of security profiles supported by the dash target system.
Update the input_json.txt with discover and info commands as below
{"h":"HP705G1","u":"adminUserName","P":"adminPassword","Commands":["discover","info"]}
Repeat Step 9. Output will contain the discovery information under info tag and security profiles under SecurityProfile tag.
Power Status through DashCLI JDO
This is to get the current power status of a dash target system.
Update the input_json.txt with power status commands as below
{"h":"HP705G1","u":"adminUserName","t":"computersystem[0]","P":"adminPassword","Commands":["power","status"]}
Output will contain the current power status of the dash system. Power status will be in shown in the PowerState tag.
Change Power Status through DashCLI JDO
This is to change the power status of a dash target system.
Update the input_json.txt with power and available state commands as below
{"h":"HP705G1","u":"adminUserName","P":"adminPassword","Commands":["power","sleep"]}
Output will contain the power change status of the dash system. ErrorCode tag will contain the status of the power operation 0 if power operation is successful. ErrorMessage will contain more information on the status of the operation as shown below
dashcli -ji input_json.txt -jo output_json.txt
Here, the file ‘input_json.txt’ has the DASH command in JSON format. DASH CLI executes this command and writes the output in JSON format to file specified by -jo option, which is output_json.txt. Usage is shown in the screenshot below.
Create a sample C++ console application by following the steps below:
Step 1: Create a new project in Visual Studio by selecting from the Menu “File” > “New” > “Project”
Step 2: Select “Visual C++” -> “Console App”. Name the application “JiJoApp” and click “OK” button.
Step 3: Add the two constant members which stores DashCLI application path and DashCLI arguments in main function.
const char szArgs[] = (" -ji input_json.txt -jo output_json.txt");
const char szAppPath[] = ("C:\\Program Files (x86)\\DASH CLI 3.0\\bin\\dashcli.exe");
Step 4: Include required header files like windows.h and iostream
#include <windows.h>
#include <iostream>
Step 5: Define a function “RunDashCLIWithJiJO” which creates a process and executes DASHCLI application with JIJO parameters as shown below:
void RunDashCLIWithJiJO(const char szAppPath[], const char szArgs[])
{
PROCESS_INFORMATION piProcInfo;
STARTUPINFOA siStartInfo;
// Set up members of the PROCESS_INFORMATION structure.
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
// Set up members of the STARTUPINFO structure.
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
// Create process with application path of DASHCLI and required arguments list.
if (!CreateProcessA(szAppPath, (LPSTR)szArgs, NULL, NULL, true, 0, NULL, NULL, &siStartInfo, &piProcInfo))
{
cout << "Process creation failed to execute DashCLI" << std::endl;
}
else
{
// Wait for the process to complete execution.
WaitForSingleObject(piProcInfo.hProcess, INFINITE);
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
cout << "DashCLI execution complete." << endl;
}
}
Step 6: Call “RunDashCLIWithJiJO” function in the “main” function
RunDashCLIWithJiJO(szAppPath, szArgs);
The entire code at this stage should look like so:
#include <windows.h>
#include <iostream>
using namespace std;
// Create a child process to run DashCLI and redirect STDIN/STDOUT through pipes.
void RunDashCLIWithJiJO(const char szAppPath[], const char szArgs[])
{
PROCESS_INFORMATION piProcInfo;
STARTUPINFOA siStartInfo;
// Set up members of the PROCESS_INFORMATION structure.
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
// Set up members of the STARTUPINFO structure.
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
// Create process with application path of DASHCLI and required arguments list.
if (!CreateProcessA(szAppPath, (LPSTR)szArgs, NULL, NULL, true, 0, NULL, NULL, &siStartInfo, &piProcInfo))
{
cout << "Process creation failed to execute DashCLI" << std::endl;
}
else
{
// Wait for the process to complete execution.
WaitForSingleObject(piProcInfo.hProcess, INFINITE);
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
cout << "DashCLI execution complete." << endl;
}
}
int main(int argc, char* argv[])
{
const char szArgs[] = (" -ji input_json.txt -jo output_json.txt");
// Path to DashCLI application.
const char szAppPath[] = ("C:\\Program Files (x86)\\DASH CLI 3.0\\bin\\dashcli.exe");
cout << "Running DashCLI with JIJO" << endl;
RunDashCLIWithJiJO(szAppPath, szArgs);
return 0;
}
Step 7: In step 6, to call function “RunDashCLIWithJiJO”, DASHCLI argument expects the input JSON file which is input_json.txt to be present in the working directory if the sample application is running from Visual Studio or to be present in the exe path if the application is running from the command line.
Step 8: Put the following JSON test in input_json.txt file:
{"h":"HP705G1","u":"AdminUserName","P":"AdminPassword","Commands":["discover"]}
Step 9: Run the “JiJoApp.exe” application from the console.
Step 10: Check the content of the “output_json.txt” file using “type” command on the console as shown in the above command. Output_json.txt file will contain the output of DASHCLI for the commands in input_json.txt.
Other Commands:
Discover Info through DashCLI JiJO
This is to discover the given host and get the list of security profiles supported by the dash target system.
Update the input_json.txt with discover and info commands as below
{"h":"HP705G1","u":"adminUserName","P":"adminPassword","Commands":["discover","info"]}
Repeat Step 9 & 10. Output will be stored in json format in output_json.txt. This contains the discovery information under info tag and security profiles under SecurityProfile tag as show in the below snapshot.
Power Status through DashCLI JiJO
This is to get the current power status of a dash target system.
Update the input_json.txt with power status commands as below
{"h":"HP705G1","u":"adminUserName","P":"adminPassword","t":"computersystem[0]","Commands":["power","status"]}
Repeat above steps 9 & 10, output will be stored in the output_json.txt which contains the current power status of the dash system. Power status will be in shown in the PowerState tag.
Change Power Status through DashCLI JDO
This is to change the power status of a dash target system.
Update the input_json.txt with power and available state commands as below
{"h":"HP705G1","u":"adminUserName","P":"adminPassword","Commands":["power","sleep"]}
Output will contain the power change status of the dash system. ErrorCode tag will contain the status of the power operation 0 if power operation is successful. ErrorMessage will contain more information on the status of the operation as shown below
In this blog, DASH Discovery is illustrated. Similarly, other DASH profiles can be accessed by the application by framing the required JSON request. See the ‘DASH CLI Developer Guide’ for JSON format for other supported DASH profiles.
Attachments:
For any further query, drop a note below or contact via mail dashsupport@amd.com
Reference:
Useful links:
Related Blogs: