示例#1
0
bool CommunicationKDP::SendRequestPacketNoLock(
    const PacketStreamType &request_packet) {
  if (IsConnected()) {
    const char *packet_data = request_packet.GetData();
    const size_t packet_size = request_packet.GetSize();

    Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));
    if (log) {
      PacketStreamType log_strm;
      DumpPacket(log_strm, packet_data, packet_size);
      log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
    }
    ConnectionStatus status = eConnectionStatusSuccess;

    size_t bytes_written = Write(packet_data, packet_size, status, NULL);

    if (bytes_written == packet_size)
      return true;

    if (log)
      log->Printf("error: failed to send packet entire packet %" PRIu64
                  " of %" PRIu64 " bytes sent",
                  (uint64_t)bytes_written, (uint64_t)packet_size);
  }
  return false;
}
示例#2
0
void CommunicationKDP::MakeRequestPacketHeader(CommandType request_type,
                                               PacketStreamType &request_packet,
                                               uint16_t request_length) {
  request_packet.Clear();
  request_packet.PutHex8(request_type |
                         ePacketTypeRequest);      // Set the request type
  request_packet.PutHex8(m_request_sequence_id++); // Sequence number
  request_packet.PutHex16(
      request_length); // Length of the packet including this header
  request_packet.PutHex32(m_session_key); // Session key
}
示例#3
0
bool
CommunicationKDP::SendRequestAndGetReply (const CommandType command,
        const uint8_t request_sequence_id,
        const PacketStreamType &request_packet,
        DataExtractor &reply_packet)
{
    if (IsRunning())
    {
        LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
        if (log)
        {
            PacketStreamType log_strm;
            DumpPacket (log_strm, request_packet.GetData(), request_packet.GetSize());
            log->Printf("error: kdp running, not sending packet: %.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
        }
        return false;
    }

    Mutex::Locker locker(m_sequence_mutex);
#ifdef LLDB_CONFIGURATION_DEBUG
    // NOTE: this only works for packets that are in native endian byte order
    assert (request_packet.GetSize() == *((uint16_t *)(request_packet.GetData() + 2)));
#endif
    if (SendRequestPacketNoLock(request_packet))
    {
        if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, GetPacketTimeoutInMicroSeconds ()))
        {
            uint32_t offset = 0;
            const uint8_t reply_command = reply_packet.GetU8 (&offset);
            const uint8_t reply_sequence_id = reply_packet.GetU8 (&offset);
            if ((reply_command & eCommandTypeMask) == command)
            {
                if (request_sequence_id == reply_sequence_id)
                {
                    if (command == KDP_RESUMECPUS)
                        m_is_running.SetValue(true, eBroadcastAlways);
                    return true;
                }
            }
        }
    }
    reply_packet.Clear();
    return false;
}
示例#4
0
bool CommunicationKDP::SendRequestAndGetReply(
    const CommandType command, const PacketStreamType &request_packet,
    DataExtractor &reply_packet) {
  if (IsRunning()) {
    Log *log(ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PACKETS));
    if (log) {
      PacketStreamType log_strm;
      DumpPacket(log_strm, request_packet.GetData(), request_packet.GetSize());
      log->Printf("error: kdp running, not sending packet: %.*s",
                  (uint32_t)log_strm.GetSize(), log_strm.GetData());
    }
    return false;
  }

  std::lock_guard<std::recursive_mutex> guard(m_sequence_mutex);
#ifdef LLDB_CONFIGURATION_DEBUG
  // NOTE: this only works for packets that are in native endian byte order
  assert(request_packet.GetSize() ==
         *((const uint16_t *)(request_packet.GetData() + 2)));
#endif
  lldb::offset_t offset = 1;
  const uint32_t num_retries = 3;
  for (uint32_t i = 0; i < num_retries; ++i) {
    if (SendRequestPacketNoLock(request_packet)) {
      const uint8_t request_sequence_id = (uint8_t)request_packet.GetData()[1];
      while (1) {
        if (WaitForPacketWithTimeoutMicroSecondsNoLock(
                reply_packet,
                std::chrono::microseconds(GetPacketTimeout()).count())) {
          offset = 0;
          const uint8_t reply_command = reply_packet.GetU8(&offset);
          const uint8_t reply_sequence_id = reply_packet.GetU8(&offset);
          if (request_sequence_id == reply_sequence_id) {
            // The sequent ID was correct, now verify we got the response we
            // were looking for
            if ((reply_command & eCommandTypeMask) == command) {
              // Success
              if (command == KDP_RESUMECPUS)
                m_is_running.SetValue(true, eBroadcastAlways);
              return true;
            } else {
              // Failed to get the correct response, bail
              reply_packet.Clear();
              return false;
            }
          } else if (reply_sequence_id > request_sequence_id) {
            // Sequence ID was greater than the sequence ID of the packet we
            // sent, something is really wrong...
            reply_packet.Clear();
            return false;
          } else {
            // The reply sequence ID was less than our current packet's
            // sequence ID so we should keep trying to get a response because
            // this was a response for a previous packet that we must have
            // retried.
          }
        } else {
          // Break and retry sending the packet as we didn't get a response due
          // to timeout
          break;
        }
      }
    }
  }
  reply_packet.Clear();
  return false;
}