1 // Copyright (c) 2012 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.
5 #include "tools/android/forwarder2/command.h"
12 #include "base/logging.h"
13 #include "base/safe_strerror_posix.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_piece.h"
16 #include "tools/android/forwarder2/socket.h"
18 using base::StringPiece
;
27 // <port> is a 5-chars zero-padded ASCII decimal integer
28 // matching the target port for the command (e.g.
29 // '08080' for port 8080)
30 // <type> is a 3-char zero-padded ASCII decimal integer
31 // matching a command::Type value (e.g. 002 for
33 // The column (:) is used as a separator for easier reading.
34 const int kPortStringSize
= 5;
35 const int kCommandTypeStringSize
= 2;
36 // Command string size also includes the ':' separator char.
37 const int kCommandStringSize
= kPortStringSize
+ kCommandTypeStringSize
+ 1;
41 namespace forwarder2
{
43 bool ReadCommand(Socket
* socket
,
45 command::Type
* command_type_out
) {
46 char command_buffer
[kCommandStringSize
+ 1];
47 // To make logging easier.
48 command_buffer
[kCommandStringSize
] = '\0';
50 int bytes_read
= socket
->ReadNumBytes(command_buffer
, kCommandStringSize
);
51 if (bytes_read
!= kCommandStringSize
) {
53 LOG(ERROR
) << "Read() error: " << safe_strerror(errno
);
55 LOG(ERROR
) << "Read() error, endpoint was unexpectedly closed.";
57 LOG(ERROR
) << "Read() error, not enough data received from the socket.";
61 StringPiece
port_str(command_buffer
, kPortStringSize
);
62 if (!StringToInt(port_str
, port_out
)) {
63 LOG(ERROR
) << "Could not parse the command port string: "
68 StringPiece
command_type_str(
69 &command_buffer
[kPortStringSize
+ 1], kCommandTypeStringSize
);
71 if (!StringToInt(command_type_str
, &command_type
)) {
72 LOG(ERROR
) << "Could not parse the command type string: "
76 *command_type_out
= static_cast<command::Type
>(command_type
);
80 bool SendCommand(command::Type command
, int port
, Socket
* socket
) {
81 char buffer
[kCommandStringSize
+ 1];
82 int len
= snprintf(buffer
, sizeof(buffer
), "%05d:%02d", port
, command
);
83 CHECK_EQ(len
, kCommandStringSize
);
84 // Write the full command minus the leading \0 char.
85 return socket
->WriteNumBytes(buffer
, len
) == len
;
88 bool ReceivedCommand(command::Type command
, Socket
* socket
) {
90 command::Type received_command
;
91 if (!ReadCommand(socket
, &port
, &received_command
))
93 return received_command
== command
;
96 } // namespace forwarder