| Index: build_tools/debug_server/debug_server/rsp_recorder/rsp_recorder.cc
|
| ===================================================================
|
| --- build_tools/debug_server/debug_server/rsp_recorder/rsp_recorder.cc (revision 0)
|
| +++ build_tools/debug_server/debug_server/rsp_recorder/rsp_recorder.cc (revision 0)
|
| @@ -0,0 +1,169 @@
|
| +#include "rsp_recorder.h"
|
| +
|
| +namespace {
|
| +const int kListenMs = 20;
|
| +const int kReadWaitMs = 20;
|
| +const int kBufferSize = 512;
|
| +}
|
| +
|
| +namespace rsp_recorder {
|
| +Recorder::Recorder()
|
| + : state_(STOPPED),
|
| + host_port_(0),
|
| + target_port_(0) {
|
| + host_packet_consumer_.rec_ = this;
|
| + target_packet_consumer_.rec_ = this;
|
| +}
|
| +
|
| +Recorder::~Recorder() {
|
| + Stop();
|
| + session_log_.Close();
|
| +}
|
| +
|
| +void Recorder::SetSessionLogFileName(const std::string& name) {
|
| + session_log_.OpenToWrite(name);
|
| +}
|
| +
|
| +void Recorder::Start(int host_port,
|
| + const std::string& target_hostname,
|
| + int target_port) {
|
| + Stop();
|
| + host_port_ = host_port;
|
| + target_port_ = target_port;
|
| + target_hostname_ = target_hostname;
|
| + host_listening_socket_.Setup(host_port_);
|
| + host_packetizer_.SetPacketConsumer(&host_packet_consumer_);
|
| + target_packetizer_.SetPacketConsumer(&target_packet_consumer_);
|
| + state_ = CONNECTING;
|
| +}
|
| +void Recorder::Stop() {
|
| + host_listening_socket_.Close();
|
| + host_connection_.Close();
|
| + target_connection_.Close();
|
| + state_ = STOPPED;
|
| +}
|
| +
|
| +bool Recorder::IsRunning() const {
|
| + return (STOPPED != state_);
|
| +}
|
| +
|
| +void Recorder::DoWork() {
|
| + if (STOPPED == state_)
|
| + return;
|
| +
|
| + // Recorder always connects to the target first, then accepts
|
| + // connection from the host (gdb).
|
| + if (CONNECTING == state_) {
|
| + if (!target_connection_.IsConnected()) {
|
| + target_connection_.ConnectTo(target_hostname_, target_port_);
|
| + if (target_connection_.IsConnected())
|
| + printf("Connected to target on [%s:%d]\n",
|
| + target_hostname_.c_str(),
|
| + target_port_);
|
| + } else if (!host_connection_.IsConnected()) {
|
| + host_listening_socket_.Accept(&host_connection_, kListenMs);
|
| + if (host_connection_.IsConnected())
|
| + printf("Got connection from host\n");
|
| + } else {
|
| + state_ = CONNECTED;
|
| + }
|
| + return;
|
| + }
|
| +
|
| + if (CONNECTED == state_) {
|
| + if (!target_connection_.IsConnected() || !host_connection_.IsConnected()) {
|
| + Stop();
|
| + return;
|
| + }
|
| + }
|
| +
|
| + char buff[kBufferSize];
|
| + size_t read_bytes = host_connection_.Read(buff,
|
| + sizeof(buff) - 1,
|
| + kReadWaitMs);
|
| + if (read_bytes > 0) {
|
| + buff[read_bytes] = 0;
|
| + printf("h>%s\n", buff);
|
| + host_packetizer_.OnData(buff, read_bytes);
|
| + target_connection_.WriteAll(buff, read_bytes);
|
| + }
|
| +
|
| + read_bytes = target_connection_.Read(buff, sizeof(buff) - 1, kReadWaitMs);
|
| + if (read_bytes > 0) {
|
| + buff[read_bytes] = 0;
|
| + printf("t>%s\n", buff);
|
| + target_packetizer_.OnData(buff, read_bytes);
|
| + host_connection_.WriteAll(buff, read_bytes);
|
| + }
|
| +}
|
| +
|
| +void Recorder::OnError(const char* error_description) {
|
| + printf("Recorder ERROR!!! : [%s]\n", error_description);
|
| + fflush(stdout);
|
| + Stop();
|
| +}
|
| +
|
| +void HostPacketConsumer::OnPacket(debug::Blob& body, bool valid_checksum) {
|
| + rec_->OnHostPacket(body, valid_checksum);
|
| +}
|
| +
|
| +void HostPacketConsumer::OnUnexpectedChar(char unexpected_char) {
|
| + rec_->OnHostUnexpectedChar(unexpected_char);
|
| +}
|
| +
|
| +void HostPacketConsumer::OnBreak() {
|
| + rec_->OnHostBreak();
|
| +}
|
| +
|
| +void TargetPacketConsumer::OnPacket(debug::Blob& body, bool valid_checksum) {
|
| + rec_->OnTargetPacket(body, valid_checksum);
|
| +}
|
| +
|
| +void TargetPacketConsumer::OnUnexpectedChar(char unexpected_char) {
|
| + rec_->OnTargetUnexpectedChar(unexpected_char);
|
| +}
|
| +
|
| +void TargetPacketConsumer::OnBreak() {
|
| + rec_->OnTargetBreak();
|
| +}
|
| +
|
| +void Recorder::OnHostPacket(debug::Blob& body, bool valid_checksum) {
|
| + if (!valid_checksum)
|
| + OnError("Invalid checksum on message from host.");
|
| + else {
|
| + std::string body_str = body.ToString();
|
| + printf("H>[%s] chk=%s\n",
|
| + body_str.c_str(),
|
| + (valid_checksum ? "ok" : "err"));
|
| + session_log_.Add('H', body);
|
| + }
|
| +}
|
| +
|
| +void Recorder::OnHostUnexpectedChar(char unexpected_char) {
|
| + printf("H>enexpected [%c]\n", unexpected_char);
|
| + OnError("Received unexpected character from host.");
|
| +}
|
| +
|
| +void Recorder::OnHostBreak() {
|
| + printf("H>Brk\n");
|
| + debug::Blob body;
|
| + body.PushBack(0x03); // Ctrl-C
|
| + session_log_.Add('H', body);
|
| +}
|
| +
|
| +void Recorder::OnTargetPacket(debug::Blob& body, bool valid_checksum) {
|
| + std::string body_str = body.ToString();
|
| + printf("T>[%s] chk=%s\n", body_str.c_str(), (valid_checksum ? "ok" : "err"));
|
| + session_log_.Add('T', body);
|
| +}
|
| +
|
| +void Recorder::OnTargetUnexpectedChar(char unexpected_char) {
|
| + printf("T>enexpected [%c]\n", unexpected_char);
|
| + OnError("Received unexpected character from targer.");
|
| +}
|
| +
|
| +void Recorder::OnTargetBreak() {
|
| + printf("T>Brk\n");
|
| + OnError("Received Ctrl-C from targer.");
|
| +}
|
| +} // namespace rsp_recorder
|
|
|