1 //
2 // Copyright 2011-2012,2015 Ettus Research LLC
3 // Copyright 2018 Ettus Research, a National Instruments Company
4 //
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7
8 #include "../common/mock_zero_copy.hpp"
9 #include "../lib/transport/super_send_packet_handler.hpp"
10 #include <boost/shared_array.hpp>
11 #include <boost/test/unit_test.hpp>
12 #include <complex>
13 #include <functional>
14 #include <list>
15 #include <vector>
16
17 using namespace uhd::transport;
18
19 #define BOOST_CHECK_TS_CLOSE(a, b) \
20 BOOST_CHECK_CLOSE((a).get_real_secs(), (b).get_real_secs(), 0.001)
21
22 ////////////////////////////////////////////////////////////////////////
BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_one_packet_mode)23 BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_one_packet_mode)
24 {
25 ////////////////////////////////////////////////////////////////////////
26 uhd::convert::id_type id;
27 id.input_format = "fc32";
28 id.num_inputs = 1;
29 id.output_format = "sc16_item32_be";
30 id.num_outputs = 1;
31
32 mock_zero_copy xport(vrt::if_packet_info_t::LINK_TYPE_VRLP);
33
34 static const double TICK_RATE = 100e6;
35 static const double SAMP_RATE = 10e6;
36 static const size_t NUM_PKTS_TO_TEST = 30;
37
38 // create the super send packet handler
39 sph::send_packet_handler handler(1);
40 handler.set_vrt_packer(&vrt::if_hdr_pack_be);
41 handler.set_tick_rate(TICK_RATE);
42 handler.set_samp_rate(SAMP_RATE);
43 handler.set_xport_chan_get_buff(
44 0, [&xport](double timeout) { return xport.get_send_buff(timeout); });
45 handler.set_converter(id);
46 handler.set_max_samples_per_packet(20);
47
48 // allocate metadata and buffer
49 std::vector<std::complex<float>> buff(20);
50 uhd::tx_metadata_t metadata;
51 metadata.has_time_spec = true;
52 metadata.time_spec = uhd::time_spec_t(0.0);
53
54 // generate the test data
55 for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) {
56 metadata.start_of_burst = (i == 0);
57 metadata.end_of_burst = (i == NUM_PKTS_TO_TEST - 1);
58 const size_t num_sent = handler.send(&buff.front(), 10 + i % 10, metadata, 1.0);
59 BOOST_CHECK_EQUAL(num_sent, 10 + i % 10);
60 metadata.time_spec += uhd::time_spec_t(0, num_sent, SAMP_RATE);
61 }
62
63 // check the sent packets
64 size_t num_accum_samps = 0;
65 vrt::if_packet_info_t ifpi;
66 for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) {
67 std::cout << "data check " << i << std::endl;
68 xport.pop_send_packet(ifpi);
69 BOOST_CHECK_EQUAL(ifpi.num_payload_words32, 10 + i % 10);
70 BOOST_CHECK(ifpi.has_tsf);
71 BOOST_CHECK_EQUAL(ifpi.tsf, num_accum_samps * TICK_RATE / SAMP_RATE);
72 BOOST_CHECK_EQUAL(ifpi.sob, i == 0);
73 BOOST_CHECK_EQUAL(ifpi.eob, i == NUM_PKTS_TO_TEST - 1);
74 num_accum_samps += ifpi.num_payload_words32;
75 }
76 }
77
78 ////////////////////////////////////////////////////////////////////////
BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_full_buffer_mode)79 BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_full_buffer_mode)
80 {
81 ////////////////////////////////////////////////////////////////////////
82 uhd::convert::id_type id;
83 id.input_format = "fc32";
84 id.num_inputs = 1;
85 id.output_format = "sc16_item32_be";
86 id.num_outputs = 1;
87
88 mock_zero_copy xport(vrt::if_packet_info_t::LINK_TYPE_VRLP);
89
90 static const double TICK_RATE = 100e6;
91 static const double SAMP_RATE = 10e6;
92 static const size_t NUM_PKTS_TO_TEST = 30;
93
94 // create the super send packet handler
95 sph::send_packet_handler handler(1);
96 handler.set_vrt_packer(&vrt::if_hdr_pack_be);
97 handler.set_tick_rate(TICK_RATE);
98 handler.set_samp_rate(SAMP_RATE);
99 handler.set_xport_chan_get_buff(
100 0, [&xport](double timeout) { return xport.get_send_buff(timeout); });
101 handler.set_converter(id);
102 handler.set_max_samples_per_packet(20);
103
104 // allocate metadata and buffer
105 std::vector<std::complex<float>> buff(20 * NUM_PKTS_TO_TEST);
106 uhd::tx_metadata_t metadata;
107 metadata.start_of_burst = true;
108 metadata.end_of_burst = true;
109 metadata.has_time_spec = true;
110 metadata.time_spec = uhd::time_spec_t(0.0);
111
112 // generate the test data
113 const size_t num_sent = handler.send(&buff.front(), buff.size(), metadata, 1.0);
114 BOOST_CHECK_EQUAL(num_sent, buff.size());
115
116 // check the sent packets
117 size_t num_accum_samps = 0;
118 vrt::if_packet_info_t ifpi;
119 for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++) {
120 std::cout << "data check " << i << std::endl;
121 xport.pop_send_packet(ifpi);
122 BOOST_CHECK_EQUAL(ifpi.num_payload_words32, 20UL);
123 BOOST_CHECK(ifpi.has_tsf);
124 BOOST_CHECK_EQUAL(ifpi.tsf, num_accum_samps * TICK_RATE / SAMP_RATE);
125 BOOST_CHECK_EQUAL(ifpi.sob, i == 0);
126 BOOST_CHECK_EQUAL(ifpi.eob, i == NUM_PKTS_TO_TEST - 1);
127 num_accum_samps += ifpi.num_payload_words32;
128 }
129 }
130