summaryrefslogtreecommitdiffstats
path: root/components/pairing
diff options
context:
space:
mode:
authorzork@chromium.org <zork@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-12 22:50:03 +0000
committerzork@chromium.org <zork@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-12 22:51:43 +0000
commitf33c86757fd0a786005189f10a8d2675d0bfe4a7 (patch)
tree81b36fb6b13c56d6aa6c5d9d5a9a29cb1d2b8478 /components/pairing
parentf34acc690bbeb3d0ebd3cb8be1b254dd9f8d86ee (diff)
downloadchromium_src-f33c86757fd0a786005189f10a8d2675d0bfe4a7.zip
chromium_src-f33c86757fd0a786005189f10a8d2675d0bfe4a7.tar.gz
chromium_src-f33c86757fd0a786005189f10a8d2675d0bfe4a7.tar.bz2
Add ProtoDecoder for sending messages between Host and Controller when pairing
BUG=380961, 380962 Review URL: https://codereview.chromium.org/448273002 Cr-Commit-Position: refs/heads/master@{#289097} git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289097 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components/pairing')
-rw-r--r--components/pairing/BUILD.gn2
-rw-r--r--components/pairing/proto_decoder.cc201
-rw-r--r--components/pairing/proto_decoder.h91
3 files changed, 294 insertions, 0 deletions
diff --git a/components/pairing/BUILD.gn b/components/pairing/BUILD.gn
index 55f29ed..d017ec4 100644
--- a/components/pairing/BUILD.gn
+++ b/components/pairing/BUILD.gn
@@ -16,6 +16,8 @@ source_set("pairing") {
"pairing/host_pairing_controller.h",
"pairing/message_buffer.cc",
"pairing/message_buffer.h",
+ "pairing/proto_decoder.cc",
+ "pairing/proto_decoder.h",
]
deps = [
diff --git a/components/pairing/proto_decoder.cc b/components/pairing/proto_decoder.cc
new file mode 100644
index 0000000..96b3c24
--- /dev/null
+++ b/components/pairing/proto_decoder.cc
@@ -0,0 +1,201 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/pairing/proto_decoder.h"
+
+#include "components/pairing/pairing_api.pb.h"
+#include "net/base/io_buffer.h"
+
+namespace {
+enum {
+ MESSAGE_NONE,
+ MESSAGE_HOST_STATUS,
+ MESSAGE_CONFIGURE_HOST,
+ MESSAGE_PAIR_DEVICES,
+ MESSAGE_COMPLETE_SETUP,
+ MESSAGE_ERROR,
+ NUM_MESSAGES,
+};
+}
+
+namespace pairing_chromeos {
+
+ProtoDecoder::ProtoDecoder(Observer* observer)
+ : observer_(observer),
+ next_message_type_(MESSAGE_NONE),
+ next_message_size_(0) {
+ DCHECK(observer_);
+}
+
+ProtoDecoder::~ProtoDecoder() {}
+
+bool ProtoDecoder::DecodeIOBuffer(int size,
+ ProtoDecoder::IOBufferRefPtr io_buffer) {
+ // Update the message buffer.
+ message_buffer_.AddIOBuffer(io_buffer, size);
+
+ // If there is no current message, the next byte is the message type.
+ if (next_message_type_ == MESSAGE_NONE) {
+ if (message_buffer_.AvailableBytes() < static_cast<int>(sizeof(uint8_t)))
+ return true;
+
+ uint8_t message_type = MESSAGE_NONE;
+ message_buffer_.ReadBytes(reinterpret_cast<char*>(&message_type),
+ sizeof(message_type));
+
+ if (message_type == MESSAGE_NONE || message_type >= NUM_MESSAGES) {
+ LOG(ERROR) << "Unknown message type received: " << message_type;
+ return false;
+ }
+ next_message_type_ = message_type;
+ }
+
+ // If the message size isn't set, the next two bytes are the message size.
+ if (next_message_size_ == 0) {
+ if (message_buffer_.AvailableBytes() < static_cast<int>(sizeof(uint16_t)))
+ return true;
+
+ // The size is sent in network byte order.
+ uint8_t high_byte = 0;
+ message_buffer_.ReadBytes(reinterpret_cast<char*>(&high_byte),
+ sizeof(high_byte));
+ uint8_t low_byte = 0;
+ message_buffer_.ReadBytes(reinterpret_cast<char*>(&low_byte),
+ sizeof(low_byte));
+
+ next_message_size_ = (high_byte << 8) + low_byte;
+ }
+
+ // If the whole proto buffer is not yet available, return early.
+ if (message_buffer_.AvailableBytes() < next_message_size_)
+ return true;
+
+ std::vector<char> buffer(next_message_size_);
+ message_buffer_.ReadBytes(&buffer[0], next_message_size_);
+
+ switch (next_message_type_) {
+ case MESSAGE_HOST_STATUS: {
+ pairing_api::HostStatus message;
+ message.ParseFromArray(&buffer[0], buffer.size());
+ observer_->OnHostStatusMessage(message);
+ }
+ break;
+ case MESSAGE_CONFIGURE_HOST: {
+ pairing_api::ConfigureHost message;
+ message.ParseFromArray(&buffer[0], buffer.size());
+ observer_->OnConfigureHostMessage(message);
+ }
+ break;
+ case MESSAGE_PAIR_DEVICES: {
+ pairing_api::PairDevices message;
+ message.ParseFromArray(&buffer[0], buffer.size());
+ observer_->OnPairDevicesMessage(message);
+ }
+ break;
+ case MESSAGE_COMPLETE_SETUP: {
+ pairing_api::CompleteSetup message;
+ message.ParseFromArray(&buffer[0], buffer.size());
+ observer_->OnCompleteSetupMessage(message);
+ }
+ break;
+ case MESSAGE_ERROR: {
+ pairing_api::Error message;
+ message.ParseFromArray(&buffer[0], buffer.size());
+ observer_->OnErrorMessage(message);
+ }
+ break;
+
+ default:
+ NOTREACHED();
+ break;
+ }
+
+ // Reset the message data.
+ next_message_type_ = MESSAGE_NONE;
+ next_message_size_ = 0;
+
+ return true;
+}
+
+ProtoDecoder::IOBufferRefPtr ProtoDecoder::SendHostStatus(
+ const pairing_api::HostStatus& message, int* size) {
+ std::string serialized_proto;
+ if (!message.SerializeToString(&serialized_proto)) {
+ NOTREACHED();
+ }
+
+ return SendMessage(MESSAGE_HOST_STATUS, serialized_proto, size);
+}
+
+ProtoDecoder::IOBufferRefPtr ProtoDecoder::SendConfigureHost(
+ const pairing_api::ConfigureHost& message, int* size) {
+ std::string serialized_proto;
+ if (!message.SerializeToString(&serialized_proto)) {
+ NOTREACHED();
+ }
+
+ return SendMessage(MESSAGE_CONFIGURE_HOST, serialized_proto, size);
+}
+
+ProtoDecoder::IOBufferRefPtr ProtoDecoder::SendPairDevices(
+ const pairing_api::PairDevices& message, int* size) {
+ std::string serialized_proto;
+ if (!message.SerializeToString(&serialized_proto)) {
+ NOTREACHED();
+ }
+
+ return SendMessage(MESSAGE_PAIR_DEVICES, serialized_proto, size);
+}
+
+ProtoDecoder::IOBufferRefPtr ProtoDecoder::SendCompleteSetup(
+ const pairing_api::CompleteSetup& message, int* size) {
+ std::string serialized_proto;
+ if (!message.SerializeToString(&serialized_proto)) {
+ NOTREACHED();
+ }
+
+ return SendMessage(MESSAGE_COMPLETE_SETUP, serialized_proto, size);
+}
+
+ProtoDecoder::IOBufferRefPtr ProtoDecoder::SendError(
+ const pairing_api::Error& message, int* size) {
+ std::string serialized_proto;
+ if (!message.SerializeToString(&serialized_proto)) {
+ NOTREACHED();
+ }
+
+ return SendMessage(MESSAGE_ERROR, serialized_proto, size);
+}
+
+ProtoDecoder::IOBufferRefPtr ProtoDecoder::SendMessage(
+ uint8_t message_type,
+ const std::string& message,
+ int* size) {
+ uint16_t message_size = message.size();
+
+ *size = sizeof(message_type) + sizeof(message_size) + message.size();
+ IOBufferRefPtr io_buffer(new net::IOBuffer(*size));
+
+ // Write the message type.
+ int offset = 0;
+ memcpy(&io_buffer->data()[offset], &message_type, sizeof(message_type));
+ offset += sizeof(message_type);
+
+ // Network byte order.
+ // Write the high byte of the size.
+ uint8_t data = (message_size >> 8) & 0xFF;
+ memcpy(&io_buffer->data()[offset], &data, sizeof(data));
+ offset += sizeof(data);
+ // Write the low byte of the size.
+ data = message_size & 0xFF;
+ memcpy(&io_buffer->data()[offset], &data, sizeof(data));
+ offset += sizeof(data);
+
+ // Write the actual message.
+ memcpy(&io_buffer->data()[offset], message.data(), message.size());
+
+ return io_buffer;
+}
+
+} // namespace pairing_chromeos
diff --git a/components/pairing/proto_decoder.h b/components/pairing/proto_decoder.h
new file mode 100644
index 0000000..e36eb7f
--- /dev/null
+++ b/components/pairing/proto_decoder.h
@@ -0,0 +1,91 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PAIRING_PROTO_DECODER_H_
+#define COMPONENTS_PAIRING_PROTO_DECODER_H_
+
+#include <deque>
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "components/pairing/message_buffer.h"
+
+namespace net {
+class IOBuffer;
+}
+
+namespace pairing_api {
+class CompleteSetup;
+class ConfigureHost;
+class Error;
+class HostStatus;
+class PairDevices;
+} // namespace pairing_api
+
+namespace pairing_chromeos {
+
+// A ProtoDecoder collects data from a series of IOBuffers and decodes Proto
+// buffers from the data. The decoded messages are then forwarded to an
+// observer.
+class ProtoDecoder {
+ public:
+ typedef scoped_refptr<net::IOBuffer> IOBufferRefPtr;
+ class Observer {
+ public:
+ virtual ~Observer() {}
+
+ virtual void OnHostStatusMessage(
+ const pairing_api::HostStatus& message) = 0;
+ virtual void OnConfigureHostMessage(
+ const pairing_api::ConfigureHost& message) = 0;
+ virtual void OnPairDevicesMessage(
+ const pairing_api::PairDevices& message) = 0;
+ virtual void OnCompleteSetupMessage(
+ const pairing_api::CompleteSetup& message) = 0;
+ virtual void OnErrorMessage(
+ const pairing_api::Error& message) = 0;
+
+ protected:
+ Observer() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Observer);
+ };
+
+ explicit ProtoDecoder(Observer* observer);
+ ~ProtoDecoder();
+
+ // Decodes the data from an io_buffer, and sends out events for any complete
+ // messages.
+ bool DecodeIOBuffer(int size, IOBufferRefPtr io_buffer);
+
+ // Convenience functions for serializing messages into an IOBuffer.
+ static IOBufferRefPtr SendHostStatus(const pairing_api::HostStatus& message,
+ int* size);
+ static IOBufferRefPtr SendConfigureHost(
+ const pairing_api::ConfigureHost& message, int* size);
+ static IOBufferRefPtr SendPairDevices(const pairing_api::PairDevices& message,
+ int* size);
+ static IOBufferRefPtr SendCompleteSetup(
+ const pairing_api::CompleteSetup& message, int* size);
+ static IOBufferRefPtr SendError(const pairing_api::Error& message, int* size);
+
+ private:
+ static IOBufferRefPtr SendMessage(uint8_t message_type,
+ const std::string& message,
+ int* size);
+
+ Observer* observer_;
+ MessageBuffer message_buffer_;
+ int next_message_type_;
+ int next_message_size_;
+
+ DISALLOW_COPY_AND_ASSIGN(ProtoDecoder);
+};
+
+} // namespace pairing_chromeos
+
+#endif // COMPONENTS_PAIRING_PROTO_DECODER_H_