1 /* 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/base/testclient.h" 12 #include "webrtc/base/thread.h" 13 #include "webrtc/base/timeutils.h" 14 15 namespace rtc { 16 17 // DESIGN: Each packet received is put it into a list of packets. 18 // Callers can retrieve received packets from any thread by calling 19 // NextPacket. 20 21 TestClient::TestClient(AsyncPacketSocket* socket) 22 : socket_(socket), ready_to_send_(false) { 23 packets_ = new std::vector<Packet*>(); 24 socket_->SignalReadPacket.connect(this, &TestClient::OnPacket); 25 socket_->SignalReadyToSend.connect(this, &TestClient::OnReadyToSend); 26 } 27 28 TestClient::~TestClient() { 29 delete socket_; 30 for (unsigned i = 0; i < packets_->size(); i++) 31 delete (*packets_)[i]; 32 delete packets_; 33 } 34 35 bool TestClient::CheckConnState(AsyncPacketSocket::State state) { 36 // Wait for our timeout value until the socket reaches the desired state. 37 uint32_t end = TimeAfter(kTimeoutMs); 38 while (socket_->GetState() != state && TimeUntil(end) > 0) 39 Thread::Current()->ProcessMessages(1); 40 return (socket_->GetState() == state); 41 } 42 43 int TestClient::Send(const char* buf, size_t size) { 44 rtc::PacketOptions options; 45 return socket_->Send(buf, size, options); 46 } 47 48 int TestClient::SendTo(const char* buf, size_t size, 49 const SocketAddress& dest) { 50 rtc::PacketOptions options; 51 return socket_->SendTo(buf, size, dest, options); 52 } 53 54 TestClient::Packet* TestClient::NextPacket(int timeout_ms) { 55 // If no packets are currently available, we go into a get/dispatch loop for 56 // at most timeout_ms. If, during the loop, a packet arrives, then we can 57 // stop early and return it. 58 59 // Note that the case where no packet arrives is important. We often want to 60 // test that a packet does not arrive. 61 62 // Note also that we only try to pump our current thread's message queue. 63 // Pumping another thread's queue could lead to messages being dispatched from 64 // the wrong thread to non-thread-safe objects. 65 66 uint32_t end = TimeAfter(timeout_ms); 67 while (TimeUntil(end) > 0) { 68 { 69 CritScope cs(&crit_); 70 if (packets_->size() != 0) { 71 break; 72 } 73 } 74 Thread::Current()->ProcessMessages(1); 75 } 76 77 // Return the first packet placed in the queue. 78 Packet* packet = NULL; 79 CritScope cs(&crit_); 80 if (packets_->size() > 0) { 81 packet = packets_->front(); 82 packets_->erase(packets_->begin()); 83 } 84 85 return packet; 86 } 87 88 bool TestClient::CheckNextPacket(const char* buf, size_t size, 89 SocketAddress* addr) { 90 bool res = false; 91 Packet* packet = NextPacket(kTimeoutMs); 92 if (packet) { 93 res = (packet->size == size && memcmp(packet->buf, buf, size) == 0); 94 if (addr) 95 *addr = packet->addr; 96 delete packet; 97 } 98 return res; 99 } 100 101 bool TestClient::CheckNoPacket() { 102 bool res; 103 Packet* packet = NextPacket(kNoPacketTimeoutMs); 104 res = (packet == NULL); 105 delete packet; 106 return res; 107 } 108 109 int TestClient::GetError() { 110 return socket_->GetError(); 111 } 112 113 int TestClient::SetOption(Socket::Option opt, int value) { 114 return socket_->SetOption(opt, value); 115 } 116 117 bool TestClient::ready_to_send() const { 118 return ready_to_send_; 119 } 120 121 void TestClient::OnPacket(AsyncPacketSocket* socket, const char* buf, 122 size_t size, const SocketAddress& remote_addr, 123 const PacketTime& packet_time) { 124 CritScope cs(&crit_); 125 packets_->push_back(new Packet(remote_addr, buf, size)); 126 } 127 128 void TestClient::OnReadyToSend(AsyncPacketSocket* socket) { 129 ready_to_send_ = true; 130 } 131 132 TestClient::Packet::Packet(const SocketAddress& a, const char* b, size_t s) 133 : addr(a), buf(0), size(s) { 134 buf = new char[size]; 135 memcpy(buf, b, size); 136 } 137 138 TestClient::Packet::Packet(const Packet& p) 139 : addr(p.addr), buf(0), size(p.size) { 140 buf = new char[size]; 141 memcpy(buf, p.buf, size); 142 } 143 144 TestClient::Packet::~Packet() { 145 delete[] buf; 146 } 147 148 } // namespace rtc 149