Switched json to proto

Former-commit-id: 1a1c70b93c9b4efe17f1c1d2da246c949affa1f0
This commit is contained in:
johan 2014-01-25 21:00:48 +01:00
parent 6723c7bf2b
commit 4f7997bbfe
3 changed files with 73 additions and 82 deletions

View File

@ -42,7 +42,6 @@ add_executable(hyperion-v4l2
target_link_libraries(hyperion-v4l2 target_link_libraries(hyperion-v4l2
getoptPlusPlus getoptPlusPlus
jsoncpp
hyperion-utils hyperion-utils
${PROTOBUF_LIBRARIES} ${PROTOBUF_LIBRARIES}
pthread pthread

View File

@ -38,26 +38,17 @@ ProtoConnection::~ProtoConnection()
_socket.close(); _socket.close();
} }
void ProtoConnection::setColor(std::vector<QColor> colors, int priority, int duration) void ProtoConnection::setColor(const ColorRgb & color, int priority, int duration)
{ {
// create command proto::HyperionRequest request;
Json::Value command; request.set_command(proto::HyperionRequest::COLOR);
command["command"] = "color"; proto::ColorRequest * colorRequest = request.MutableExtension(proto::ColorRequest::colorRequest);
command["priority"] = priority; colorRequest->set_rgbcolor((color.red << 16) | (color.green << 8) | color.blue);
Json::Value & rgbValue = command["color"]; colorRequest->set_priority(priority);
for (const QColor & color : colors) colorRequest->set_duration(duration);
{
rgbValue.append(color.red());
rgbValue.append(color.green());
rgbValue.append(color.blue());
}
if (duration > 0)
{
command["duration"] = duration;
}
// send command message // send command message
Json::Value reply = sendMessage(command); proto::HyperionReply reply = sendMessage(request);
// parse reply message // parse reply message
parseReply(reply); parseReply(reply);
@ -65,40 +56,31 @@ void ProtoConnection::setColor(std::vector<QColor> colors, int priority, int dur
void ProtoConnection::setImage(const Image<ColorRgb> &image, int priority, int duration) void ProtoConnection::setImage(const Image<ColorRgb> &image, int priority, int duration)
{ {
// ensure the image has RGB888 format proto::HyperionRequest request;
QByteArray binaryImage = QByteArray::fromRawData(reinterpret_cast<const char *>(image.memptr()), image.width() * image.height() * 3); request.set_command(proto::HyperionRequest::IMAGE);
const QByteArray base64Image = binaryImage.toBase64(); proto::ImageRequest * imageRequest = request.MutableExtension(proto::ImageRequest::imageRequest);
imageRequest->set_imagedata(image.memptr(), image.width() * image.height() * 3);
// create command imageRequest->set_imagewidth(image.width());
Json::Value command; imageRequest->set_imageheight(image.height());
command["command"] = "image"; imageRequest->set_priority(priority);
command["priority"] = priority; imageRequest->set_duration(duration);
command["imagewidth"] = image.width();
command["imageheight"] = image.height();
command["imagedata"] = std::string(base64Image.data(), base64Image.size());
if (duration > 0)
{
command["duration"] = duration;
}
// send command message // send command message
Json::Value reply = sendMessage(command); proto::HyperionReply reply = sendMessage(request);
// parse reply message // parse reply message
parseReply(reply); // parseReply(reply);
} }
void ProtoConnection::clear(int priority) void ProtoConnection::clear(int priority)
{ {
std::cout << "Clear priority channel " << priority << std::endl; proto::HyperionRequest request;
request.set_command(proto::HyperionRequest::CLEAR);
// create command proto::ClearRequest * clearRequest = request.MutableExtension(proto::ClearRequest::clearRequest);
Json::Value command; clearRequest->set_priority(priority);
command["command"] = "clear";
command["priority"] = priority;
// send command message // send command message
Json::Value reply = sendMessage(command); proto::HyperionReply reply = sendMessage(request);
// parse reply message // parse reply message
parseReply(reply); parseReply(reply);
@ -106,35 +88,44 @@ void ProtoConnection::clear(int priority)
void ProtoConnection::clearAll() void ProtoConnection::clearAll()
{ {
std::cout << "Clear all priority channels" << std::endl; proto::HyperionRequest request;
request.set_command(proto::HyperionRequest::CLEARALL);
// create command
Json::Value command;
command["command"] = "clearall";
// send command message // send command message
Json::Value reply = sendMessage(command); proto::HyperionReply reply = sendMessage(request);
// parse reply message // parse reply message
parseReply(reply); parseReply(reply);
} }
Json::Value ProtoConnection::sendMessage(const Json::Value & message) proto::HyperionReply ProtoConnection::sendMessage(const proto::HyperionRequest &message)
{ {
// serialize message (FastWriter already appends a newline) // serialize message (FastWriter already appends a newline)
std::string serializedMessage = Json::FastWriter().write(message); std::string serializedMessage = message.SerializeAsString();
int length = serializedMessage.size();
const uint8_t header[] = {
uint8_t((length >> 24) & 0xFF),
uint8_t((length >> 16) & 0xFF),
uint8_t((length >> 8) & 0xFF),
uint8_t((length ) & 0xFF)};
// write message // write message
_socket.write(serializedMessage.c_str()); int count = 0;
count += _socket.write(reinterpret_cast<const char *>(header), 4);
count += _socket.write(reinterpret_cast<const char *>(serializedMessage.data()), length);
if (!_socket.waitForBytesWritten()) if (!_socket.waitForBytesWritten())
{ {
throw std::runtime_error("Error while writing data to host"); throw std::runtime_error("Error while writing data to host");
} }
/*
// read reply data // read reply data
QByteArray serializedReply; QByteArray serializedReply;
while (!serializedReply.contains('\n')) length = -1;
while (serializedReply.size() != length)
{ {
std::cout << length << std::endl;
// receive reply // receive reply
if (!_socket.waitForReadyRead()) if (!_socket.waitForReadyRead())
{ {
@ -142,39 +133,40 @@ Json::Value ProtoConnection::sendMessage(const Json::Value & message)
} }
serializedReply += _socket.readAll(); serializedReply += _socket.readAll();
}
int bytes = serializedReply.indexOf('\n') + 1; // Find the end of message
if (length < 0 && serializedReply.size() >= 4)
{
std::cout << (int) serializedReply[3] << std::endl;
std::cout << (int) serializedReply[2] << std::endl;
std::cout << (int) serializedReply[1] << std::endl;
std::cout << (int) serializedReply[0] << std::endl;
length = (uint8_t(serializedReply[0]) << 24) | (uint8_t(serializedReply[1]) << 16) | (uint8_t(serializedReply[2]) << 8) | uint8_t(serializedReply[3]) ;
}
}
std::cout << length << std::endl;
*/
// parse reply data // parse reply data
Json::Reader jsonReader; proto::HyperionReply reply;
Json::Value reply; // reply.ParseFromArray(serializedReply.constData()+4, length);
if (!jsonReader.parse(serializedReply.constData(), serializedReply.constData() + bytes, reply))
{
throw std::runtime_error("Error while parsing reply: invalid json");
}
return reply; return reply;
} }
bool ProtoConnection::parseReply(const Json::Value &reply) bool ProtoConnection::parseReply(const proto::HyperionReply &reply)
{ {
bool success = false; bool success = false;
std::string reason = "No error info";
try if (!reply.success())
{ {
success = reply.get("success", false).asBool(); if (reply.has_error())
if (!success) {
reason = reply.get("error", reason).asString(); throw std::runtime_error("Error: " + reply.error());
} }
catch (const std::runtime_error &) else
{ {
// Some json parsing error: ignore and set parsing error throw std::runtime_error("Error: No error info");
} }
if (!success)
{
throw std::runtime_error("Error: " + reason);
} }
return success; return success;

View File

@ -14,7 +14,7 @@
#include <utils/ColorRgb.h> #include <utils/ColorRgb.h>
// jsoncpp includes // jsoncpp includes
#include <json/json.h> #include <message.pb.h>
/// ///
/// Connection class to setup an connection to the hyperion server and execute commands /// Connection class to setup an connection to the hyperion server and execute commands
@ -41,7 +41,7 @@ public:
/// @param priority The priority /// @param priority The priority
/// @param duration The duration in milliseconds /// @param duration The duration in milliseconds
/// ///
void setColor(std::vector<QColor> color, int priority, int duration); void setColor(const ColorRgb & color, int priority, int duration = 1);
/// ///
/// Set the leds according to the given image (assume the image is stretched to the display size) /// Set the leds according to the given image (assume the image is stretched to the display size)
@ -50,7 +50,7 @@ public:
/// @param priority The priority /// @param priority The priority
/// @param duration The duration in milliseconds /// @param duration The duration in milliseconds
/// ///
void setImage(const Image<ColorRgb> & image, int priority, int duration); void setImage(const Image<ColorRgb> & image, int priority, int duration = -1);
/// ///
/// Clear the given priority channel /// Clear the given priority channel
@ -66,13 +66,13 @@ public:
private: private:
/// ///
/// Send a json command message and receive its reply /// Send a command message and receive its reply
/// ///
/// @param message The message to send /// @param message The message to send
/// ///
/// @return The returned reply /// @return The returned reply
/// ///
Json::Value sendMessage(const Json::Value & message); proto::HyperionReply sendMessage(const proto::HyperionRequest & message);
/// ///
/// Parse a reply message /// Parse a reply message
@ -81,7 +81,7 @@ private:
/// ///
/// @return true if the reply indicates success /// @return true if the reply indicates success
/// ///
bool parseReply(const Json::Value & reply); bool parseReply(const proto::HyperionReply & reply);
private: private:
/// The TCP-Socket with the connection to the server /// The TCP-Socket with the connection to the server