LCOV - code coverage report
Current view: directory - src/trusted/debug_stub - session.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 106 84 79.2 %
Date: 2014-09-25 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2010 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : #include <assert.h>
       8                 : #include <string.h>
       9                 : #include <stdlib.h>
      10                 : 
      11                 : #include <string>
      12                 : #include <sstream>
      13                 : 
      14                 : #include "native_client/src/shared/platform/nacl_log.h"
      15                 : #include "native_client/src/trusted/debug_stub/packet.h"
      16                 : #include "native_client/src/trusted/debug_stub/platform.h"
      17                 : #include "native_client/src/trusted/debug_stub/session.h"
      18                 : #include "native_client/src/trusted/debug_stub/transport.h"
      19                 : #include "native_client/src/trusted/debug_stub/util.h"
      20                 : 
      21                 : using port::IPlatform;
      22                 : using port::ITransport;
      23                 : 
      24                 : namespace gdb_rsp {
      25                 : 
      26                 : Session::Session(ITransport *transport)
      27                 :   : io_(transport),
      28                 :     flags_(0),
      29                 :     seq_(0),
      30               1 :     connected_(true) {
      31               1 : }
      32                 : 
      33               1 : Session::~Session() {
      34               1 : }
      35                 : 
      36               1 : void Session::SetFlags(uint32_t flags) {
      37               1 :   flags_ |= flags;
      38               1 : }
      39                 : 
      40               1 : void Session::ClearFlags(uint32_t flags) {
      41               1 :   flags_ &= ~flags;
      42               1 : }
      43                 : 
      44               1 : uint32_t Session::GetFlags() {
      45               1 :   return flags_;
      46               1 : }
      47                 : 
      48               0 : bool Session::IsDataAvailable() {
      49               0 :   return io_->IsDataAvailable();
      50               0 : }
      51                 : 
      52               1 : bool Session::Connected() {
      53               1 :   return connected_;
      54               1 : }
      55                 : 
      56               1 : void Session::Disconnect() {
      57               1 :   io_->Disconnect();
      58               1 :   connected_ = false;
      59               1 : }
      60                 : 
      61               1 : bool Session::GetChar(char *ch) {
      62               1 :   if (!io_->Read(ch, 1)) {
      63               1 :     Disconnect();
      64               1 :     return false;
      65                 :   }
      66                 : 
      67               1 :   return true;
      68               1 : }
      69                 : 
      70                 : 
      71               1 : bool Session::SendPacket(Packet *pkt) {
      72                 :   char ch;
      73                 : 
      74                 :   do {
      75               1 :     if (!SendPacketOnly(pkt)) return false;
      76                 : 
      77                 :     // If ACKs are off, we are done.
      78               1 :     if (GetFlags() & IGNORE_ACK) break;
      79                 : 
      80                 :     // Otherwise, poll for '+'
      81               1 :     if (!GetChar(&ch)) return false;
      82                 : 
      83                 :     // Retry if we didn't get a '+'
      84               1 :   } while (ch != '+');
      85                 : 
      86               1 :   return true;
      87               1 : }
      88                 : 
      89                 : 
      90               1 : bool Session::SendPacketOnly(Packet *pkt) {
      91                 :   const char *ptr;
      92                 :   char ch;
      93               1 :   std::stringstream outstr;
      94                 : 
      95               1 :   char run_xsum = 0;
      96                 :   int32_t seq;
      97                 : 
      98               1 :   ptr = pkt->GetPayload();
      99               1 :   size_t size = pkt->GetPayloadSize();
     100                 : 
     101               1 :   if (!pkt->GetSequence(&seq) && (GetFlags() & USE_SEQ)) {
     102               0 :     pkt->SetSequence(seq_++);
     103                 :   }
     104                 : 
     105                 :   // Signal start of response
     106               1 :   outstr << '$';
     107                 : 
     108                 :   // If there is a sequence, send as two nibble 8bit value + ':'
     109               1 :   if (pkt->GetSequence(&seq)) {
     110               0 :     IntToNibble((seq & 0xFF) >> 4, &ch);
     111               0 :     outstr << ch;
     112               0 :     run_xsum += ch;
     113                 : 
     114               0 :     IntToNibble(seq & 0xF, &ch);
     115               0 :     outstr << ch;
     116               0 :     run_xsum += ch;
     117                 : 
     118               0 :     ch = ':';
     119               0 :     outstr << ch;
     120               0 :     run_xsum += ch;
     121                 :   }
     122                 : 
     123                 :   // Send the main payload
     124               1 :   for (size_t offs = 0; offs < size; ++offs) {
     125               1 :     ch = ptr[offs];
     126               1 :     outstr << ch;
     127               1 :     run_xsum += ch;
     128               1 :   }
     129                 : 
     130               1 :   if (GetFlags() & DEBUG_SEND) {
     131               0 :     NaClLog(1, "TX %s\n", outstr.str().c_str());
     132                 :   }
     133                 : 
     134                 :   // Send XSUM as two nible 8bit value preceeded by '#'
     135               1 :   outstr << '#';
     136               1 :   IntToNibble((run_xsum >> 4) & 0xF, &ch);
     137               1 :   outstr << ch;
     138               1 :   IntToNibble(run_xsum & 0xF, &ch);
     139               1 :   outstr << ch;
     140                 : 
     141                 :   return io_->Write(outstr.str().data(),
     142               1 :                     static_cast<int32_t>(outstr.str().length()));
     143               1 : }
     144                 : 
     145                 : // Attempt to receive a packet
     146               1 : bool Session::GetPacket(Packet *pkt) {
     147                 :   char run_xsum, fin_xsum, ch;
     148               1 :   std::string in;
     149                 : 
     150                 :   // Toss characters until we see a start of command
     151                 :   do {
     152               1 :     if (!GetChar(&ch)) return false;
     153               1 :     in += ch;
     154               1 :   } while (ch != '$');
     155                 : 
     156                 :  retry:
     157                 :   // Clear the stream
     158               1 :   pkt->Clear();
     159                 : 
     160                 :   // Prepare XSUM calc
     161               1 :   run_xsum = 0;
     162               1 :   fin_xsum = 0;
     163                 : 
     164                 :   // Stream in the characters
     165               1 :   while (1) {
     166               1 :     if (!GetChar(&ch)) return false;
     167                 : 
     168                 :     // If we see a '#' we must be done with the data
     169               1 :     if (ch == '#') break;
     170                 : 
     171               1 :     in += ch;
     172                 : 
     173                 :     // If we see a '$' we must have missed the last cmd
     174               1 :     if (ch == '$') {
     175               0 :       NaClLog(LOG_INFO, "RX Missing $, retry.\n");
     176               0 :       goto retry;
     177                 :     }
     178                 :     // Keep a running XSUM
     179               1 :     run_xsum += ch;
     180               1 :     pkt->AddRawChar(ch);
     181               1 :   }
     182                 : 
     183                 : 
     184                 :   // Get two Nibble XSUM
     185               1 :   if (!GetChar(&ch)) return false;
     186                 : 
     187                 :   int val;
     188               1 :   NibbleToInt(ch, & val);
     189               1 :   fin_xsum = val << 4;
     190                 : 
     191               1 :   if (!GetChar(&ch)) return false;
     192               1 :   NibbleToInt(ch, &val);
     193               1 :   fin_xsum |= val;
     194                 : 
     195               1 :   if (GetFlags() & DEBUG_RECV) NaClLog(1, "RX %s\n", in.c_str());
     196                 : 
     197               1 :   pkt->ParseSequence();
     198                 : 
     199                 :   // If ACKs are off, we are done.
     200               1 :   if (GetFlags() & IGNORE_ACK) return true;
     201                 : 
     202                 :   // If the XSUMs don't match, signal bad packet
     203               1 :   if (fin_xsum == run_xsum) {
     204               1 :     char out[3] = { '+', 0, 0 };
     205                 :     int32_t seq;
     206                 : 
     207                 :     // If we have a sequence number
     208               1 :     if (pkt->GetSequence(&seq)) {
     209                 :       // Respond with Sequence number
     210               0 :       IntToNibble(seq >> 4, &out[1]);
     211               0 :       IntToNibble(seq & 0xF, &out[2]);
     212               0 :       return io_->Write(out, 3);
     213                 :     }
     214               1 :     return io_->Write(out, 1);
     215                 :   } else {
     216                 :     // Resend a bad XSUM and look for retransmit
     217               0 :     io_->Write("-", 1);
     218                 : 
     219               0 :     NaClLog(LOG_INFO, "RX Bad XSUM, retry\n");
     220               0 :     goto retry;
     221                 :   }
     222                 : 
     223                 :   return true;
     224               1 : }
     225                 : 
     226                 : }  // End of namespace gdb_rsp
     227                 : 

Generated by: LCOV version 1.7