diff --git a/src/raspberrypi/Makefile b/src/raspberrypi/Makefile index 2a069f24..1b097987 100644 --- a/src/raspberrypi/Makefile +++ b/src/raspberrypi/Makefile @@ -161,10 +161,10 @@ ALL: all docs: $(DOC_DIR)/rascsi_man_page.txt $(DOC_DIR)/rasctl_man_page.txt $(DOC_DIR)/scsimon_man_page.txt $(BINDIR)/$(RASCSI): $(SRC_PROTOBUF) $(OBJ_RASCSI) | $(BINDIR) - $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI) -lpthread -lz -lpcap -lprotobuf-lite + $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCSI) -lpthread -lz -lpcap -lprotobuf $(BINDIR)/$(RASCTL): $(SRC_PROTOBUF) $(OBJ_RASCTL) | $(BINDIR) - $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCTL) -lprotobuf-lite + $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASCTL) -lprotobuf $(BINDIR)/$(RASDUMP): $(OBJ_RASDUMP) | $(BINDIR) $(CXX) $(CXXFLAGS) -o $@ $(OBJ_RASDUMP) diff --git a/src/raspberrypi/rascsi_interface.proto b/src/raspberrypi/rascsi_interface.proto index 28832cbd..0ca3611d 100644 --- a/src/raspberrypi/rascsi_interface.proto +++ b/src/raspberrypi/rascsi_interface.proto @@ -1,7 +1,5 @@ syntax = "proto3"; -option optimize_for = LITE_RUNTIME; - package rascsi_interface; // The supported device types diff --git a/src/raspberrypi/rasutil.cpp b/src/raspberrypi/rasutil.cpp index 41fa6adf..8f6336f6 100644 --- a/src/raspberrypi/rasutil.cpp +++ b/src/raspberrypi/rasutil.cpp @@ -20,7 +20,8 @@ using namespace rascsi_interface; //--------------------------------------------------------------------------- // -// Serialize/Deserialize protobuf message: Length followed by the actual data +// Serialize/Deserialize protobuf message: Length followed by the actual data. +// Little endian is assumed. // //--------------------------------------------------------------------------- @@ -36,36 +37,48 @@ void SerializeMessage(int fd, const google::protobuf::MessageLite& message) } // Write the actual protobuf data - void *buf = malloc(size); + uint8_t buf[size]; memcpy(buf, data.data(), size); if (write(fd, buf, size) != size) { - free(buf); - throw ioexception("Can't write protobuf data"); } - - free(buf); } 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)) { - // Read the actual protobuf data - void *buf = malloc(size); - if (read(fd, buf, size) != (ssize_t)size) { - free(buf); + // Read the header with the size of the protobuf data + uint8_t header_buf[4]; + int bytes_read = ReadNBytes(fd, header_buf, 4); + if (bytes_read < 4) { + return; + } + int32_t size = (header_buf[3] << 24) + (header_buf[2] << 16) + (header_buf[1] << 8) + header_buf[0]; - throw ioexception("Missing protobuf data"); + // Read the binary protobuf data + uint8_t data_buf[size]; + bytes_read = ReadNBytes(fd, data_buf, size); + if (bytes_read < size) { + throw ioexception("Missing protobuf data"); + } + + // Create protobuf message + string data((const char *)data_buf, size); + message.ParseFromString(data); +} + +int ReadNBytes(int fd, uint8_t *buf, int n) +{ + int offset = 0; + while (offset < n) { + ssize_t len = read(fd, buf + offset, n - offset); + if (!len) { + break; } - // 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); - - message.ParseFromString(data); + offset += len; } + + return offset; } //--------------------------------------------------------------------------- diff --git a/src/raspberrypi/rasutil.h b/src/raspberrypi/rasutil.h index 42b760a4..9d974321 100644 --- a/src/raspberrypi/rasutil.h +++ b/src/raspberrypi/rasutil.h @@ -15,8 +15,9 @@ #include "google/protobuf/message_lite.h" #include "rascsi_interface.pb.h" -void SerializeMessage(int fd, const google::protobuf::MessageLite&); -void DeserializeMessage(int fd, google::protobuf::MessageLite&); +void SerializeMessage(int, const google::protobuf::MessageLite&); +void DeserializeMessage(int, google::protobuf::MessageLite&); +int ReadNBytes(int, uint8_t *, int); string ListDevices(const rascsi_interface::PbDevices&); #endif