147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/*
247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *
447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */
1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/testclient.h"
1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/thread.h"
1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/timeutils.h"
1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc {
1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// DESIGN: Each packet received is put it into a list of packets.
1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//         Callers can retrieve received packets from any thread by calling
1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//         NextPacket.
2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTestClient::TestClient(AsyncPacketSocket* socket)
2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    : socket_(socket), ready_to_send_(false) {
2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  packets_ = new std::vector<Packet*>();
2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  socket_->SignalReadPacket.connect(this, &TestClient::OnPacket);
2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  socket_->SignalReadyToSend.connect(this, &TestClient::OnReadyToSend);
2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTestClient::~TestClient() {
2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete socket_;
3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (unsigned i = 0; i < packets_->size(); i++)
3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    delete (*packets_)[i];
3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete packets_;
3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool TestClient::CheckConnState(AsyncPacketSocket::State state) {
3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Wait for our timeout value until the socket reaches the desired state.
3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  uint32 end = TimeAfter(kTimeout);
3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  while (socket_->GetState() != state && TimeUntil(end) > 0)
3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Thread::Current()->ProcessMessages(1);
4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return (socket_->GetState() == state);
4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint TestClient::Send(const char* buf, size_t size) {
4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  rtc::PacketOptions options;
4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return socket_->Send(buf, size, options);
4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint TestClient::SendTo(const char* buf, size_t size,
4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                       const SocketAddress& dest) {
5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  rtc::PacketOptions options;
5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return socket_->SendTo(buf, size, dest, options);
5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTestClient::Packet* TestClient::NextPacket() {
5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // If no packets are currently available, we go into a get/dispatch loop for
5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // at most 1 second.  If, during the loop, a packet arrives, then we can stop
5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // early and return it.
5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Note that the case where no packet arrives is important.  We often want to
6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // test that a packet does not arrive.
6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Note also that we only try to pump our current thread's message queue.
6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Pumping another thread's queue could lead to messages being dispatched from
6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // the wrong thread to non-thread-safe objects.
6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  uint32 end = TimeAfter(kTimeout);
6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  while (TimeUntil(end) > 0) {
6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    {
6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      CritScope cs(&crit_);
7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (packets_->size() != 0) {
7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        break;
7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Thread::Current()->ProcessMessages(1);
7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Return the first packet placed in the queue.
7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Packet* packet = NULL;
7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_);
8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (packets_->size() > 0) {
8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    packet = packets_->front();
8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    packets_->erase(packets_->begin());
8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return packet;
8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool TestClient::CheckNextPacket(const char* buf, size_t size,
8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                 SocketAddress* addr) {
9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool res = false;
9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Packet* packet = NextPacket();
9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (packet) {
9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    res = (packet->size == size && memcmp(packet->buf, buf, size) == 0);
9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (addr)
9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      *addr = packet->addr;
9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    delete packet;
9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return res;
9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool TestClient::CheckNoPacket() {
10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool res;
10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Packet* packet = NextPacket();
10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  res = (packet == NULL);
10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete packet;
10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return res;
10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint TestClient::GetError() {
11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return socket_->GetError();
11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint TestClient::SetOption(Socket::Option opt, int value) {
11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return socket_->SetOption(opt, value);
11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool TestClient::ready_to_send() const {
11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return ready_to_send_;
11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid TestClient::OnPacket(AsyncPacketSocket* socket, const char* buf,
12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                          size_t size, const SocketAddress& remote_addr,
12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                          const PacketTime& packet_time) {
12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&crit_);
12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  packets_->push_back(new Packet(remote_addr, buf, size));
12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid TestClient::OnReadyToSend(AsyncPacketSocket* socket) {
12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ready_to_send_ = true;
13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTestClient::Packet::Packet(const SocketAddress& a, const char* b, size_t s)
13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    : addr(a), buf(0), size(s) {
13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  buf = new char[size];
13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  memcpy(buf, b, size);
13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTestClient::Packet::Packet(const Packet& p)
13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    : addr(p.addr), buf(0), size(p.size) {
14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  buf = new char[size];
14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  memcpy(buf, p.buf, size);
14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTestClient::Packet::~Packet() {
14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete[] buf;
14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}  // namespace rtc
149