blob: e797c6fa5947cc261dc1c14d06465e76624e661a [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
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
15namespace 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
21TestClient::TestClient(AsyncPacketSocket* socket)
Taylor Brandstettere7536412016-09-09 13:16:15 -070022 : socket_(socket), prev_packet_timestamp_(-1) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000023 packets_ = new std::vector<Packet*>();
24 socket_->SignalReadPacket.connect(this, &TestClient::OnPacket);
25 socket_->SignalReadyToSend.connect(this, &TestClient::OnReadyToSend);
26}
27
28TestClient::~TestClient() {
29 delete socket_;
30 for (unsigned i = 0; i < packets_->size(); i++)
31 delete (*packets_)[i];
32 delete packets_;
33}
34
35bool TestClient::CheckConnState(AsyncPacketSocket::State state) {
36 // Wait for our timeout value until the socket reaches the desired state.
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070037 int64_t end = TimeAfter(kTimeoutMs);
38 while (socket_->GetState() != state && TimeUntil(end) > 0) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000039 Thread::Current()->ProcessMessages(1);
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070040 }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000041 return (socket_->GetState() == state);
42}
43
44int TestClient::Send(const char* buf, size_t size) {
45 rtc::PacketOptions options;
46 return socket_->Send(buf, size, options);
47}
48
49int TestClient::SendTo(const char* buf, size_t size,
50 const SocketAddress& dest) {
51 rtc::PacketOptions options;
52 return socket_->SendTo(buf, size, dest, options);
53}
54
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +000055TestClient::Packet* TestClient::NextPacket(int timeout_ms) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000056 // If no packets are currently available, we go into a get/dispatch loop for
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +000057 // at most timeout_ms. If, during the loop, a packet arrives, then we can
58 // stop early and return it.
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000059
60 // Note that the case where no packet arrives is important. We often want to
61 // test that a packet does not arrive.
62
63 // Note also that we only try to pump our current thread's message queue.
64 // Pumping another thread's queue could lead to messages being dispatched from
65 // the wrong thread to non-thread-safe objects.
66
Taylor Brandstetter2b3bf6b2016-05-19 14:57:31 -070067 int64_t end = TimeAfter(timeout_ms);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000068 while (TimeUntil(end) > 0) {
69 {
70 CritScope cs(&crit_);
71 if (packets_->size() != 0) {
72 break;
73 }
74 }
75 Thread::Current()->ProcessMessages(1);
76 }
77
78 // Return the first packet placed in the queue.
deadbeef37f5ecf2017-02-27 14:06:41 -080079 Packet* packet = nullptr;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000080 CritScope cs(&crit_);
81 if (packets_->size() > 0) {
82 packet = packets_->front();
83 packets_->erase(packets_->begin());
84 }
85
86 return packet;
87}
88
89bool TestClient::CheckNextPacket(const char* buf, size_t size,
90 SocketAddress* addr) {
91 bool res = false;
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +000092 Packet* packet = NextPacket(kTimeoutMs);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000093 if (packet) {
Stefan Holmer9131efd2016-05-23 18:19:26 +020094 res = (packet->size == size && memcmp(packet->buf, buf, size) == 0 &&
95 CheckTimestamp(packet->packet_time.timestamp));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000096 if (addr)
97 *addr = packet->addr;
98 delete packet;
99 }
100 return res;
101}
102
Stefan Holmer9131efd2016-05-23 18:19:26 +0200103bool TestClient::CheckTimestamp(int64_t packet_timestamp) {
104 bool res = true;
105 if (packet_timestamp == -1) {
106 res = false;
107 }
Stefan Holmer9131efd2016-05-23 18:19:26 +0200108 if (prev_packet_timestamp_ != -1) {
109 if (packet_timestamp < prev_packet_timestamp_) {
110 res = false;
111 }
Stefan Holmer9131efd2016-05-23 18:19:26 +0200112 }
113 prev_packet_timestamp_ = packet_timestamp;
Stefan Holmer9131efd2016-05-23 18:19:26 +0200114 return res;
115}
116
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000117bool TestClient::CheckNoPacket() {
118 bool res;
jlmiller@webrtc.orgec499be2015-02-07 22:37:59 +0000119 Packet* packet = NextPacket(kNoPacketTimeoutMs);
deadbeef37f5ecf2017-02-27 14:06:41 -0800120 res = (packet == nullptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000121 delete packet;
122 return res;
123}
124
125int TestClient::GetError() {
126 return socket_->GetError();
127}
128
129int TestClient::SetOption(Socket::Option opt, int value) {
130 return socket_->SetOption(opt, value);
131}
132
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000133void TestClient::OnPacket(AsyncPacketSocket* socket, const char* buf,
134 size_t size, const SocketAddress& remote_addr,
135 const PacketTime& packet_time) {
136 CritScope cs(&crit_);
Stefan Holmer9131efd2016-05-23 18:19:26 +0200137 packets_->push_back(new Packet(remote_addr, buf, size, packet_time));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000138}
139
140void TestClient::OnReadyToSend(AsyncPacketSocket* socket) {
Taylor Brandstettere7536412016-09-09 13:16:15 -0700141 ++ready_to_send_count_;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000142}
143
Stefan Holmer9131efd2016-05-23 18:19:26 +0200144TestClient::Packet::Packet(const SocketAddress& a,
145 const char* b,
146 size_t s,
147 const PacketTime& packet_time)
148 : addr(a), buf(0), size(s), packet_time(packet_time) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000149 buf = new char[size];
150 memcpy(buf, b, size);
151}
152
153TestClient::Packet::Packet(const Packet& p)
Stefan Holmer9131efd2016-05-23 18:19:26 +0200154 : addr(p.addr), buf(0), size(p.size), packet_time(p.packet_time) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000155 buf = new char[size];
156 memcpy(buf, p.buf, size);
157}
158
159TestClient::Packet::~Packet() {
160 delete[] buf;
161}
162
163} // namespace rtc