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