Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1112)

Side by Side Diff: components/pairing/proto_decoder.cc

Issue 448273002: Add ProtoDecoder for sending messages between Host and Controller when pairing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/pairing/proto_decoder.h"
6
7 #include "components/pairing/message_buffer.h"
8 #include "components/pairing/pairing_api.pb.h"
9 #include "net/base/io_buffer.h"
10
11 namespace {
12 enum {
13 MESSAGE_NONE,
14 MESSAGE_HOST_STATUS,
15 MESSAGE_CONFIGURE_HOST,
16 MESSAGE_PAIR_DEVICES,
17 MESSAGE_COMPLETE_SETUP,
18 MESSAGE_ERROR,
19 NUM_MESSAGES,
20 };
21 }
22
23 namespace pairing_chromeos {
24
25 ProtoDecoder::ProtoDecoder(Observer* observer)
26 : observer_(observer),
27 message_buffer_(new MessageBuffer),
28 next_message_type_(MESSAGE_NONE),
29 next_message_size_(0) {}
achuithb 2014/08/11 22:04:31 DCHECK(observer);
Zachary Kuznia 2014/08/11 23:40:29 Done.
30
31 ProtoDecoder::~ProtoDecoder() {}
32
33 bool ProtoDecoder::DecodeIOBuffer(int size,
34 scoped_refptr<net::IOBuffer> io_buffer) {
35 // Update the message buffer.
36 message_buffer_->AddIOBuffer(io_buffer, size);
37
38 // If there is no current message, the next byte is the message type.
39 if (next_message_type_ == MESSAGE_NONE) {
40 if (message_buffer_->AvailableBytes() < (int)sizeof(uint8_t)) {
achuithb 2014/08/11 22:04:31 Don't need curly braces. You should use reinterpr
Zachary Kuznia 2014/08/11 23:40:29 I went back and forth on that as well, but this mi
41 return true;
42 }
43
44 uint8_t message_type = MESSAGE_NONE;
achuithb 2014/08/11 22:04:31 Why not char instead of uint8_t?
Zachary Kuznia 2014/08/11 23:40:29 Unsigned types have less undefined behavior with t
45 message_buffer_->ReadBytes(reinterpret_cast<char*>(&message_type),
46 sizeof(message_type));
47
48 if (message_type == MESSAGE_NONE || message_type >= NUM_MESSAGES) {
49 LOG(ERROR) << "Unknown message type received: " << message_type;
50 return false;
51 }
52 next_message_type_ = message_type;
53 }
54
55 // If the message size isn't set, the next two bytes are the message size.
56 if (next_message_size_ == 0) {
57 if (message_buffer_->AvailableBytes() < (int)sizeof(uint16_t)) {
achuithb 2014/08/11 22:04:30 reinterpret cast, no curly braces, consider changi
Zachary Kuznia 2014/08/11 23:40:29 Changed to static_cast, removed braces. I conside
58 return true;
59 }
60
61 // The size is sent in network byte order.
62 uint8_t high_byte = 0;
63 message_buffer_->ReadBytes(reinterpret_cast<char*>(&high_byte),
64 sizeof(high_byte));
65 uint8_t low_byte = 0;
66 message_buffer_->ReadBytes(reinterpret_cast<char*>(&low_byte),
67 sizeof(low_byte));
68
69 next_message_size_ = (high_byte << 8) + low_byte;
achuithb 2014/08/11 22:04:31 It feels like hte proto libraries should help us w
Zachary Kuznia 2014/08/11 23:40:29 See comment at line 190
70 }
71
72 // If the whole proto buffer is not yet available, return early.
73 if (message_buffer_->AvailableBytes() < next_message_size_) {
achuithb 2014/08/11 22:04:30 No curly braces.
Zachary Kuznia 2014/08/11 23:40:29 Done.
74 return true;
75 }
76
77 std::vector<char> buffer(next_message_size_);
78 message_buffer_->ReadBytes(&buffer[0], next_message_size_);
79
80 switch (next_message_type_) {
81 case MESSAGE_HOST_STATUS: {
82 pairing_api::HostStatus message;
83 message.ParseFromArray(&buffer[0], buffer.size());
84 observer_->OnHostStatusMessage(message);
85 }
86 break;
87 case MESSAGE_CONFIGURE_HOST: {
88 pairing_api::ConfigureHost message;
89 message.ParseFromArray(&buffer[0], buffer.size());
90 observer_->OnConfigureHostMessage(message);
91 }
92 break;
93 case MESSAGE_PAIR_DEVICES: {
94 pairing_api::PairDevices message;
95 message.ParseFromArray(&buffer[0], buffer.size());
96 observer_->OnPairDevicesMessage(message);
97 }
98 break;
99 case MESSAGE_COMPLETE_SETUP: {
100 pairing_api::CompleteSetup message;
101 message.ParseFromArray(&buffer[0], buffer.size());
102 observer_->OnCompleteSetupMessage(message);
103 }
104 break;
105 case MESSAGE_ERROR: {
106 pairing_api::Error message;
107 message.ParseFromArray(&buffer[0], buffer.size());
108 observer_->OnErrorMessage(message);
109 }
110 break;
111
112 default:
113 NOTREACHED();
114 break;
115 }
116
117 // Reset the message data.
118 next_message_type_ = MESSAGE_NONE;
119 next_message_size_ = 0;
120
121 return true;
122 }
123
124 scoped_refptr<net::IOBuffer> ProtoDecoder::SendHostStatus(
125 const pairing_api::HostStatus& message, int* size) {
126 std::string serialized_proto;
127 if (!message.SerializeToString(&serialized_proto)) {
achuithb 2014/08/11 22:04:31 Shouldn't this be a DCHECK? Here and everywhere b
Zachary Kuznia 2014/08/11 23:40:29 I avoid putting a function call in any kind of ass
128 NOTREACHED();
129 }
130
131 return SendMessage(MESSAGE_HOST_STATUS, serialized_proto, size);
132 }
133
134 scoped_refptr<net::IOBuffer> ProtoDecoder::SendConfigureHost(
135 const pairing_api::ConfigureHost& message, int* size) {
136 std::string serialized_proto;
137 if (!message.SerializeToString(&serialized_proto)) {
138 NOTREACHED();
139 }
140
141 return SendMessage(MESSAGE_CONFIGURE_HOST, serialized_proto, size);
142 }
143
144 scoped_refptr<net::IOBuffer> ProtoDecoder::SendPairDevices(
145 const pairing_api::PairDevices& message, int* size) {
146 std::string serialized_proto;
147 if (!message.SerializeToString(&serialized_proto)) {
148 NOTREACHED();
149 }
150
151 return SendMessage(MESSAGE_PAIR_DEVICES, serialized_proto, size);
152 }
153
154 scoped_refptr<net::IOBuffer> ProtoDecoder::SendCompleteSetup(
155 const pairing_api::CompleteSetup& message, int* size) {
156 std::string serialized_proto;
157 if (!message.SerializeToString(&serialized_proto)) {
158 NOTREACHED();
159 }
160
161 return SendMessage(MESSAGE_COMPLETE_SETUP, serialized_proto, size);
162 }
163
164 scoped_refptr<net::IOBuffer> ProtoDecoder::SendError(
165 const pairing_api::Error& message, int* size) {
166 std::string serialized_proto;
167 if (!message.SerializeToString(&serialized_proto)) {
168 NOTREACHED();
169 }
170
171 return SendMessage(MESSAGE_ERROR, serialized_proto, size);
172 }
173
174 scoped_refptr<net::IOBuffer> ProtoDecoder::SendMessage(
175 uint8_t message_type,
176 const std::string& message,
177 int* size) {
achuithb 2014/08/11 22:04:31 Should this be size_t? You're doing an implicit co
Zachary Kuznia 2014/08/11 23:40:29 The BluetoothSocket function deals in IOBuffer and
178 uint16_t message_size = message.size();
179
180 *size = sizeof(message_type) + sizeof(message_size) + message.size();
181 scoped_refptr<net::IOBuffer> io_buffer(new net::IOBuffer(*size));
182
183 // Write the message type.
184 int offset = 0;
185 memcpy(&io_buffer->data()[offset], &message_type, sizeof(message_type));
186 offset += sizeof(message_type);
187
188 // Network byte order.
189 // Write the high byte of the size.
190 uint8_t data = (message_size >> 8) & 0xFF;
achuithb 2014/08/11 22:04:31 Is there no way of getting protobufs to do this wo
Zachary Kuznia 2014/08/11 23:40:29 The other call sites I've seen in Chrome serialize
191 memcpy(&io_buffer->data()[offset], &data, sizeof(data));
192 offset += sizeof(data);
193 // Write the low byte of the size.
194 data = message_size & 0xFF;
195 memcpy(&io_buffer->data()[offset], &data, sizeof(data));
196 offset += sizeof(data);
197
198 // Write the actual message.
199 memcpy(&io_buffer->data()[offset], message.data(), message.size());
200
201 return io_buffer;
202 }
203
204 } // namespace pairing_chromeos
OLDNEW
« components/pairing/proto_decoder.h ('K') | « components/pairing/proto_decoder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698