mirror of
https://github.com/akuker/RASCSI.git
synced 2024-11-25 20:33:35 +00:00
Feature device list (#146)
* Removed all BAREMETAL ifdefs * Cleaned up subfolders * Fixed regression * Re-added underscores * Fixed merge conflicts * Assume RASCSI is always defined * Fixed mege issue * Re-added result message * Added Devices message to protobuf interface * Fixed typo * Fixed include file names * Updated files to be ignored by git * Merge with develop branch * Synchronized output with develop branch * Fixed missing dependency, causing issues when running "make -j1" * Fixed handling of connection errors * Improved protobuf interface upwards compatibility * Use -g instead of -s, this has less conflict potential with future options * Made log level options consistent (rascsi and rasctl used a different option) * Serialization improvements (#142) * Simplified serialization, extracted sending commands * Simplified serialization * Fixed warning * Signature update * Use Pb prefix for protobuf interface messages * Moved ListDevices to rasutil * Log device list * Split initialization * Moved code
This commit is contained in:
parent
845d249d9b
commit
863feed611
@ -13,8 +13,11 @@
|
||||
#define exceptions_h
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
class lunexception : public std::exception {
|
||||
using namespace std;
|
||||
|
||||
class lunexception final : public exception {
|
||||
private:
|
||||
int lun;
|
||||
|
||||
@ -28,16 +31,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class ioexception : public std::exception {
|
||||
class ioexception : public exception {
|
||||
private:
|
||||
const char *msg;
|
||||
string msg;
|
||||
|
||||
public:
|
||||
ioexception(const char *_msg) : msg(_msg) { }
|
||||
ioexception(const string& _msg) : msg(_msg) { }
|
||||
|
||||
~ioexception() { }
|
||||
|
||||
const char *getmsg() const {
|
||||
const string& getmsg() const {
|
||||
return msg;
|
||||
}
|
||||
};
|
||||
|
@ -119,7 +119,8 @@ void Banner(int argc, char* argv[])
|
||||
// Initialization
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
BOOL Init(int port)
|
||||
|
||||
BOOL InitService(int port)
|
||||
{
|
||||
struct sockaddr_in server;
|
||||
int yes, result;
|
||||
@ -165,6 +166,13 @@ BOOL Init(int port)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
running = FALSE;
|
||||
active = FALSE;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InitBusAndDisks() {
|
||||
// GPIOBUS creation
|
||||
bus = new GPIOBUS();
|
||||
|
||||
@ -186,10 +194,6 @@ BOOL Init(int port)
|
||||
disk[i] = NULL;
|
||||
}
|
||||
|
||||
// Other
|
||||
running = FALSE;
|
||||
active = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -253,8 +257,8 @@ void Reset()
|
||||
// Get the list of attached devices
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
Devices GetDevices() {
|
||||
Devices devices;
|
||||
PbDevices GetDevices() {
|
||||
PbDevices devices;
|
||||
|
||||
for (int i = 0; i < CtrlMax * UnitNum; i++) {
|
||||
// skip if unit does not exist or null disk
|
||||
@ -263,7 +267,7 @@ Devices GetDevices() {
|
||||
continue;
|
||||
}
|
||||
|
||||
Device *device = devices.add_devices();
|
||||
PbDevice *device = devices.add_devices();
|
||||
|
||||
// Initialize ID and unit number
|
||||
device->set_id(i / UnitNum);
|
||||
@ -298,45 +302,6 @@ Devices GetDevices() {
|
||||
return devices;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// List and log devices
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
string ListDevices(Devices devices) {
|
||||
ostringstream s;
|
||||
|
||||
if (devices.devices_size()) {
|
||||
s << endl
|
||||
<< "+----+----+------+-------------------------------------" << endl
|
||||
<< "| ID | UN | TYPE | DEVICE STATUS" << endl
|
||||
<< "+----+----+------+-------------------------------------" << endl;
|
||||
|
||||
LOGINFO( "+----+----+------+-------------------------------------");
|
||||
LOGINFO( "| ID | UN | TYPE | DEVICE STATUS");
|
||||
LOGINFO( "+----+----+------+-------------------------------------\n");
|
||||
}
|
||||
else {
|
||||
return "No images currently attached.\n";
|
||||
}
|
||||
|
||||
for (int i = 0; i < devices.devices_size() ; i++) {
|
||||
Device device = devices.devices(i);
|
||||
|
||||
s << "| " << device.id() << " | " << device.un() << " | " << device.type() << " | "
|
||||
<< device.file() << (device.read_only() ? " (WRITEPROTECT)" : "") << endl;
|
||||
|
||||
LOGINFO( "| %d | %d | %s | %s%s", device.id(), device.un(), device.type().c_str(),
|
||||
device.file().c_str(), device.read_only() ? " (WRITEPROTECT)" : "");
|
||||
}
|
||||
|
||||
s << "+----+----+------+-------------------------------------" << endl;
|
||||
|
||||
LOGINFO( "+----+----+------+-------------------------------------");
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Controller Mapping
|
||||
@ -462,13 +427,10 @@ bool ReturnStatus(int fd, bool status = true, const string msg = "") {
|
||||
}
|
||||
}
|
||||
else {
|
||||
Result result;
|
||||
PbResult result;
|
||||
result.set_status(status);
|
||||
result.set_msg(msg + "\n");
|
||||
|
||||
string data;
|
||||
result.SerializeToString(&data);
|
||||
SerializeProtobufData(fd, data);
|
||||
SerializeMessage(fd, result);
|
||||
}
|
||||
|
||||
return status;
|
||||
@ -502,12 +464,22 @@ void SetLogLevel(const string& log_level) {
|
||||
}
|
||||
}
|
||||
|
||||
void LogDeviceList(const string& device_list)
|
||||
{
|
||||
stringstream ss(device_list);
|
||||
string line;
|
||||
|
||||
while (getline(ss, line, '\n')) {
|
||||
LOGINFO("%s", line.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Command Processing
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
bool ProcessCmd(int fd, const Command &command)
|
||||
bool ProcessCmd(int fd, const PbCommand &command)
|
||||
{
|
||||
Disk *map[CtrlMax * UnitNum];
|
||||
Filepath filepath;
|
||||
@ -516,8 +488,8 @@ bool ProcessCmd(int fd, const Command &command)
|
||||
|
||||
int id = command.id();
|
||||
int un = command.un();
|
||||
Operation cmd = command.cmd();
|
||||
DeviceType type = command.type();
|
||||
PbOperation cmd = command.cmd();
|
||||
PbDeviceType type = command.type();
|
||||
string params = command.params().c_str();
|
||||
|
||||
ostringstream s;
|
||||
@ -783,7 +755,7 @@ bool ParseArgument(int argc, char* argv[], int& port)
|
||||
}
|
||||
|
||||
string path = optarg;
|
||||
DeviceType type = SASI_HD;
|
||||
PbDeviceType type = SASI_HD;
|
||||
if (has_suffix(path, ".hdf") || has_suffix(path, ".hds") || has_suffix(path, ".hdn")
|
||||
|| has_suffix(path, ".hdi") || has_suffix(path, ".hda") || has_suffix(path, ".nhd")) {
|
||||
type = SASI_HD;
|
||||
@ -807,7 +779,7 @@ bool ParseArgument(int argc, char* argv[], int& port)
|
||||
}
|
||||
|
||||
// Execute the command
|
||||
Command command;
|
||||
PbCommand command;
|
||||
command.set_id(id);
|
||||
command.set_un(un);
|
||||
command.set_cmd(ATTACH);
|
||||
@ -821,9 +793,11 @@ bool ParseArgument(int argc, char* argv[], int& port)
|
||||
|
||||
SetLogLevel(log_level);
|
||||
|
||||
// Display the device list
|
||||
Devices devices = GetDevices();
|
||||
cout << ListDevices(devices) << endl;
|
||||
// Display and log the device list
|
||||
const PbDevices devices = GetDevices();
|
||||
const string device_list = ListDevices(devices);
|
||||
cout << device_list << endl;
|
||||
LogDeviceList(device_list);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -886,17 +860,14 @@ static void *MonThread(void *param)
|
||||
}
|
||||
|
||||
// Fetch the command
|
||||
Command command;
|
||||
command.ParseFromString(DeserializeProtobufData(fd));
|
||||
PbCommand command;
|
||||
DeserializeMessage(fd, command);
|
||||
|
||||
// List all of the devices
|
||||
// List and log all of the devices
|
||||
if (command.cmd() == LIST) {
|
||||
Devices devices = GetDevices();
|
||||
ListDevices(devices);
|
||||
|
||||
string data;
|
||||
devices.SerializeToString(&data);
|
||||
SerializeProtobufData(fd, data);
|
||||
const PbDevices devices = GetDevices();
|
||||
SerializeMessage(fd, devices);
|
||||
LogDeviceList(ListDevices(devices));
|
||||
}
|
||||
else if (command.cmd() == LOG_LEVEL) {
|
||||
SetLogLevel(command.params());
|
||||
@ -915,7 +886,7 @@ static void *MonThread(void *param)
|
||||
}
|
||||
}
|
||||
catch(const ioexception& e) {
|
||||
LOGERROR("%s", e.getmsg());
|
||||
LOGERROR("%s", e.getmsg().c_str());
|
||||
|
||||
// Fall through
|
||||
}
|
||||
@ -952,16 +923,20 @@ int main(int argc, char* argv[])
|
||||
// Output the Banner
|
||||
Banner(argc, argv);
|
||||
|
||||
// Argument parsing
|
||||
int ret = 0;
|
||||
int port = 6868;
|
||||
|
||||
if (!InitBusAndDisks()) {
|
||||
ret = EPERM;
|
||||
goto init_exit;
|
||||
}
|
||||
|
||||
if (!ParseArgument(argc, argv, port)) {
|
||||
ret = EINVAL;
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
// Initialize
|
||||
if (!Init(port)) {
|
||||
if (!InitService(port)) {
|
||||
ret = EPERM;
|
||||
goto init_exit;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ option optimize_for = LITE_RUNTIME;
|
||||
package rascsi_interface;
|
||||
|
||||
// The supported device types
|
||||
enum DeviceType {
|
||||
enum PbDeviceType {
|
||||
UNDEFINED = 0;
|
||||
SASI_HD = 1;
|
||||
SCSI_HD = 2;
|
||||
@ -17,7 +17,7 @@ enum DeviceType {
|
||||
}
|
||||
|
||||
// rascsi remote operations
|
||||
enum Operation {
|
||||
enum PbOperation {
|
||||
NONE = 0;
|
||||
LIST = 1;
|
||||
ATTACH = 2;
|
||||
@ -29,22 +29,22 @@ enum Operation {
|
||||
}
|
||||
|
||||
// Commands rascsi can execute
|
||||
message Command {
|
||||
Operation cmd = 1;
|
||||
message PbCommand {
|
||||
PbOperation cmd = 1;
|
||||
int32 id = 2;
|
||||
int32 un = 3;
|
||||
DeviceType type = 4;
|
||||
PbDeviceType type = 4;
|
||||
string params = 5;
|
||||
}
|
||||
|
||||
// The result of a command
|
||||
message Result {
|
||||
message PbResult {
|
||||
bool status = 1;
|
||||
string msg = 2;
|
||||
}
|
||||
|
||||
// The device meta data
|
||||
message Device {
|
||||
message PbDevice {
|
||||
int32 id = 1;
|
||||
int32 un = 2;
|
||||
string type = 3;
|
||||
@ -52,6 +52,6 @@ message Device {
|
||||
bool read_only = 5;
|
||||
}
|
||||
|
||||
message Devices {
|
||||
repeated Device devices = 1;
|
||||
message PbDevices {
|
||||
repeated PbDevice devices = 1;
|
||||
}
|
@ -10,6 +10,7 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include <netdb.h>
|
||||
#include "google/protobuf/message_lite.h"
|
||||
#include "os.h"
|
||||
#include "rascsi_version.h"
|
||||
#include "exceptions.h"
|
||||
@ -26,44 +27,45 @@ using namespace rascsi_interface;
|
||||
// Send Command
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
int SendCommand(const char *hostname, int port, const Command& command)
|
||||
int SendCommand(const string& hostname, const PbCommand& command)
|
||||
{
|
||||
// Create a socket to send the command
|
||||
int fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
struct sockaddr_in server;
|
||||
memset(&server, 0, sizeof(server));
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(port);
|
||||
server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
int fd;
|
||||
|
||||
struct hostent *host = gethostbyname(hostname);
|
||||
if(!host) {
|
||||
fprintf(stderr, "Error : Can't resolve hostname '%s'\n", hostname);
|
||||
return false;
|
||||
}
|
||||
memcpy((char *)&server.sin_addr.s_addr, (char *)host->h_addr, host->h_length);
|
||||
try {
|
||||
struct hostent *host = gethostbyname(hostname.c_str());
|
||||
if (!host) {
|
||||
throw ioexception("Can't resolve hostname '" + hostname + "'");
|
||||
}
|
||||
|
||||
// Connect
|
||||
if (connect(fd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0) {
|
||||
cerr << "Error: Can't connect to rascsi process on '" << hostname << ":" << port << "'" << endl;
|
||||
return -1;
|
||||
}
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0) {
|
||||
throw ioexception("Can't create socket");
|
||||
}
|
||||
|
||||
string data;
|
||||
command.SerializeToString(&data);
|
||||
struct sockaddr_in server;
|
||||
memset(&server, 0, sizeof(server));
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(6868);
|
||||
server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
memcpy(&server.sin_addr.s_addr, host->h_addr, host->h_length);
|
||||
|
||||
try {
|
||||
SerializeProtobufData(fd, data);
|
||||
if (connect(fd, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0) {
|
||||
throw ioexception("Can't connect to rascsi process on host '" + hostname + "'");
|
||||
}
|
||||
|
||||
SerializeMessage(fd, command);
|
||||
}
|
||||
catch(const ioexception& e) {
|
||||
cerr << "Error : " << e.getmsg() << endl;
|
||||
cerr << "Error: " << e.getmsg() << endl;
|
||||
|
||||
close(fd);
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
return fd;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@ -73,11 +75,12 @@ int SendCommand(const char *hostname, int port, const Command& command)
|
||||
//---------------------------------------------------------------------------
|
||||
bool ReceiveResult(int fd) {
|
||||
bool status = true;
|
||||
try {
|
||||
Result result;
|
||||
result.ParseFromString(DeserializeProtobufData(fd));
|
||||
|
||||
status = result.status();
|
||||
try {
|
||||
PbResult result;
|
||||
DeserializeMessage(fd, result);
|
||||
|
||||
status = result.status();
|
||||
if (status) {
|
||||
cerr << result.msg();
|
||||
}
|
||||
@ -98,29 +101,53 @@ bool ReceiveResult(int fd) {
|
||||
return status;
|
||||
}
|
||||
|
||||
string ListDevices(const Devices& devices) {
|
||||
ostringstream s;
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Command implementations
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
if (devices.devices_size()) {
|
||||
s << endl
|
||||
<< "+----+----+------+-------------------------------------" << endl
|
||||
<< "| ID | UN | TYPE | DEVICE STATUS" << endl
|
||||
<< "+----+----+------+-------------------------------------" << endl;
|
||||
}
|
||||
else {
|
||||
return "No images currently attached.\n";
|
||||
void CommandList(const string& hostname)
|
||||
{
|
||||
PbCommand command;
|
||||
command.set_cmd(LIST);
|
||||
|
||||
int fd = SendCommand(hostname.c_str(), command);
|
||||
if (fd < 0) {
|
||||
exit(ENOTCONN);
|
||||
}
|
||||
|
||||
for (int i = 0; i < devices.devices_size() ; i++) {
|
||||
Device device = devices.devices(i);
|
||||
PbDevices devices;
|
||||
try {
|
||||
DeserializeMessage(fd, devices);
|
||||
}
|
||||
catch(const ioexception& e) {
|
||||
cerr << "Error: " << e.getmsg() << endl;
|
||||
|
||||
s << "| " << device.id() << " | " << device.un() << " | " << device.type() << " | "
|
||||
<< device.file() << (device.read_only() ? " (WRITEPROTECT)" : "") << endl;
|
||||
close(fd);
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
s << "+----+----+------+-------------------------------------" << endl;
|
||||
close (fd);
|
||||
|
||||
return s.str();
|
||||
cout << ListDevices(devices) << endl;
|
||||
}
|
||||
|
||||
void CommandLogLevel(const string& hostname, const string& log_level)
|
||||
{
|
||||
PbCommand command;
|
||||
command.set_cmd(LOG_LEVEL);
|
||||
command.set_params(log_level);
|
||||
|
||||
int fd = SendCommand(hostname.c_str(), command);
|
||||
if (fd < 0) {
|
||||
exit(ENOTCONN);
|
||||
}
|
||||
|
||||
ReceiveResult(fd);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@ -136,14 +163,13 @@ int main(int argc, char* argv[])
|
||||
if (argc < 2) {
|
||||
cerr << "SCSI Target Emulator RaSCSI Controller" << endl;
|
||||
cerr << "version " << rascsi_get_version_string() << " (" << __DATE__ << ", " << __TIME__ << ")" << endl;
|
||||
cerr << "Usage: " << argv[0] << " -i ID [-u UNIT] [-c CMD] [-t TYPE] [-f FILE] [-h HOSTNAME] [-p PORT] [-g LOG_LEVEL]" << endl;
|
||||
cerr << "Usage: " << argv[0] << " -i ID [-u UNIT] [-c CMD] [-t TYPE] [-f FILE] [-h HOSTNAME] [-g LOG_LEVEL]" << endl;
|
||||
cerr << " where ID := {0|1|2|3|4|5|6|7}" << endl;
|
||||
cerr << " UNIT := {0|1} default setting is 0." << endl;
|
||||
cerr << " CMD := {attach|detach|insert|eject|protect}" << endl;
|
||||
cerr << " TYPE := {hd|mo|cd|bridge|daynaport}" << endl;
|
||||
cerr << " FILE := image file path" << endl;
|
||||
cerr << " HOSTNAME := rascsi host to connect to, default is 'localhost'" << endl;
|
||||
cerr << " PORT := rascsi port to connect to, default is 6868" << endl;
|
||||
cerr << " LOG_LEVEL := log level {trace|debug|info|warn|err|critical|off}, default is 'trace'" << endl;
|
||||
cerr << " If CMD is 'attach' or 'insert' the FILE parameter is required." << endl;
|
||||
cerr << "Usage: " << argv[0] << " -l" << endl;
|
||||
@ -156,13 +182,12 @@ int main(int argc, char* argv[])
|
||||
int opt;
|
||||
int id = -1;
|
||||
int un = 0;
|
||||
Operation cmd = LIST;
|
||||
DeviceType type = UNDEFINED;
|
||||
PbOperation cmd = LIST;
|
||||
PbDeviceType type = UNDEFINED;
|
||||
const char *hostname = "localhost";
|
||||
int port = 6868;
|
||||
string params;
|
||||
opterr = 0;
|
||||
while ((opt = getopt(argc, argv, "i:u:c:t:f:h:p:g:l")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "i:u:c:t:f:h:g:l")) != -1) {
|
||||
switch (opt) {
|
||||
case 'i':
|
||||
id = optarg[0] - '0';
|
||||
@ -240,14 +265,6 @@ int main(int argc, char* argv[])
|
||||
hostname = optarg;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
port = atoi(optarg);
|
||||
if (port <= 0 || port > 65535) {
|
||||
cerr << "Invalid port " << optarg << ", port must be between 1 and 65535" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
cmd = LOG_LEVEL;
|
||||
params = optarg;
|
||||
@ -255,44 +272,16 @@ int main(int argc, char* argv[])
|
||||
}
|
||||
}
|
||||
|
||||
Command command;
|
||||
PbCommand command;
|
||||
|
||||
if (cmd == LOG_LEVEL) {
|
||||
command.set_cmd(LOG_LEVEL);
|
||||
command.set_params(params);
|
||||
int fd = SendCommand(hostname, port, command);
|
||||
if (fd < 0) {
|
||||
exit(ENOTCONN);
|
||||
}
|
||||
|
||||
ReceiveResult(fd);
|
||||
CommandLogLevel(hostname, params);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// List display only
|
||||
if (cmd == LIST || (id < 0 && type == UNDEFINED && params.empty())) {
|
||||
command.set_cmd(LIST);
|
||||
int fd = SendCommand(hostname, port, command);
|
||||
if (fd < 0) {
|
||||
exit(ENOTCONN);
|
||||
}
|
||||
|
||||
Devices devices;
|
||||
try {
|
||||
devices.ParseFromString(DeserializeProtobufData(fd));
|
||||
}
|
||||
catch(const ioexception& e) {
|
||||
cerr << "Error : " << e.getmsg() << endl;
|
||||
|
||||
close(fd);
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
close (fd);
|
||||
|
||||
cout << ListDevices(devices) << endl;
|
||||
|
||||
CommandList(hostname);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -345,8 +334,8 @@ int main(int argc, char* argv[])
|
||||
command.set_params(params);
|
||||
}
|
||||
|
||||
int fd = SendCommand(hostname, port, command);
|
||||
if (fd == -1) {
|
||||
int fd = SendCommand(hostname, command);
|
||||
if (fd < 0) {
|
||||
exit(ENOTCONN);
|
||||
}
|
||||
|
||||
|
@ -9,25 +9,30 @@
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include <cstring>
|
||||
#include <unistd.h>
|
||||
#include <sstream>
|
||||
#include "rascsi_interface.pb.h"
|
||||
#include "exceptions.h"
|
||||
#include "rasutil.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace rascsi_interface;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Serialize/Deserialize protobuf data: Length followed by the actual data
|
||||
// Serialize/Deserialize protobuf message: Length followed by the actual data
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void SerializeProtobufData(int fd, const string& data)
|
||||
void SerializeMessage(int fd, const google::protobuf::MessageLite& message)
|
||||
{
|
||||
string data;
|
||||
message.SerializeToString(&data);
|
||||
|
||||
// Write the size of the protobuf data as a header
|
||||
int32_t size = data.length();
|
||||
if (write(fd, &size, sizeof(size)) != sizeof(size)) {
|
||||
throw ioexception("Cannot write protobuf header");
|
||||
throw ioexception("Can't write protobuf header");
|
||||
}
|
||||
|
||||
// Write the actual protobuf data
|
||||
@ -36,32 +41,59 @@ void SerializeProtobufData(int fd, const string& data)
|
||||
if (write(fd, buf, size) != size) {
|
||||
free(buf);
|
||||
|
||||
throw ioexception("Cannot write protobuf data");
|
||||
throw ioexception("Can't write protobuf data");
|
||||
}
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
string DeserializeProtobufData(int fd)
|
||||
void DeserializeMessage(int fd, google::protobuf::MessageLite& message)
|
||||
{
|
||||
// First read the header with the size of the protobuf data
|
||||
int32_t size;
|
||||
if (read(fd, &size, sizeof(size)) != sizeof(size)) {
|
||||
// No more data
|
||||
return "";
|
||||
}
|
||||
if (read(fd, &size, sizeof(size)) == sizeof(size)) {
|
||||
// Read the actual protobuf data
|
||||
void *buf = malloc(size);
|
||||
if (read(fd, buf, size) != (ssize_t)size) {
|
||||
free(buf);
|
||||
|
||||
// Read the actual protobuf data
|
||||
void *buf = malloc(size);
|
||||
if (read(fd, buf, size) != (ssize_t)size) {
|
||||
throw ioexception("Missing protobuf data");
|
||||
}
|
||||
|
||||
// Read protobuf data into a string, to be converted into a protobuf data structure by the caller
|
||||
string data((const char *)buf, size);
|
||||
free(buf);
|
||||
|
||||
throw ioexception("Missing protobuf data");
|
||||
message.ParseFromString(data);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// List devices
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
string ListDevices(const PbDevices& devices) {
|
||||
ostringstream s;
|
||||
|
||||
if (devices.devices_size()) {
|
||||
s << endl
|
||||
<< "+----+----+------+-------------------------------------" << endl
|
||||
<< "| ID | UN | TYPE | DEVICE STATUS" << endl
|
||||
<< "+----+----+------+-------------------------------------" << endl;
|
||||
}
|
||||
else {
|
||||
return "No images currently attached.\n";
|
||||
}
|
||||
|
||||
// Read protobuf data into a string, to be converted into a protobuf data structure by the caller
|
||||
string data((const char *)buf, size);
|
||||
free(buf);
|
||||
for (int i = 0; i < devices.devices_size() ; i++) {
|
||||
PbDevice device = devices.devices(i);
|
||||
|
||||
return data;
|
||||
s << "| " << device.id() << " | " << device.un() << " | " << device.type() << " | "
|
||||
<< device.file() << (device.read_only() ? " (WRITEPROTECT)" : "") << endl;
|
||||
}
|
||||
|
||||
s << "+----+----+------+-------------------------------------" << endl;
|
||||
|
||||
return s.str();
|
||||
}
|
||||
|
@ -12,10 +12,11 @@
|
||||
#if !defined(rasutil_h)
|
||||
#define rasutil_h
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include "google/protobuf/message_lite.h"
|
||||
#include "rascsi_interface.pb.h"
|
||||
|
||||
void SerializeProtobufData(int fd, const std::string& data);
|
||||
std::string DeserializeProtobufData(int fd);
|
||||
void SerializeMessage(int fd, const google::protobuf::MessageLite&);
|
||||
void DeserializeMessage(int fd, google::protobuf::MessageLite&);
|
||||
string ListDevices(const rascsi_interface::PbDevices&);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user