libcyberradio 22.01.24
VitaIqSource.cpp
1/* -*- c++ -*- */
2/***************************************************************************
3 * \file VitaIqSource.cpp
4 *
5 * \brief Implementation of a generic VITA 49-compatible I/Q data source
6 * block.
7 *
8 * \author DA
9 * \copyright 2015 CyberRadio Solutions, Inc.
10 */
11
12#ifdef HAVE_CONFIG_H
13#include "config.h"
14#endif
15
16#include "LibCyberRadio/Common/VitaIqSource.h"
17#include <iostream>
18
19namespace LibCyberRadio
20{
21 VitaIqSource::VitaIqSource(const std::string& name,
22 int vita_type,
23 size_t payload_size,
24 size_t vita_header_size,
25 size_t vita_tail_size,
26 bool byte_swapped,
27 bool iq_swapped,
28 const std::string& host,
29 unsigned short port,
30 bool debug) :
31 Debuggable(debug, name),
32 d_name(name),
33 d_vita_type(vita_type),
34 d_payload_size(payload_size),
35 d_vita_header_size(vita_header_size),
36 d_vita_tail_size(vita_tail_size),
37 d_byte_swapped(byte_swapped),
38 d_iq_swapped(iq_swapped),
39 d_host(host),
40 d_port(port),
41 d_packet_size(0)
42 {
43 this->debug("construction\n");
44 // Determine packet size
45 d_packet_size = (vita_type == 0 ? payload_size : vita_header_size + payload_size + vita_tail_size);
46 // Create UDP port for collecting data
47 this->debug(" -- Packet Size: %d\n", d_packet_size);
48 connect_udp_port();
49 }
50
51 /*
52 * Our virtual destructor.
53 */
55 {
56 this->debug("destruction\n");
57 // Destroy/disconnect UDP port for collecting data
58 disconnect_udp_port();
59 }
60
61 int VitaIqSource::getPackets(int noutput_items, Vita49PacketVector& output_items)
62 {
63 int noutput_items_processed = 0;
64 bool got_data_on_loop = false;
65 // Check to see if the UDP port is available for reading
66 if ( d_udp_port_mtx.try_lock() )
67 {
68 // Get as many packets as we can, up to the maximum number requested.
69 do
70 {
71 got_data_on_loop = false;
72 // Get data from UDP port if it's available
73 d_udp_port->read_data();
74 if ( d_udp_port->is_packet_ready() )
75 {
76 // Handle disposition of the new packet object depending on whether or not
77 // the output vector has been pre-allocated
78 if ( noutput_items_processed < (int)output_items.size() )
79 {
80 output_items[noutput_items_processed] = Vita49Packet(
81 d_vita_type,
82 d_payload_size,
83 d_vita_header_size,
84 d_vita_tail_size,
85 d_byte_swapped,
86 d_iq_swapped,
87 (unsigned char*)(d_udp_port->recv_buffer),
88 d_packet_size);
89 }
90 else
91 {
92 output_items.push_back( Vita49Packet(
93 d_vita_type,
94 d_payload_size,
95 d_vita_header_size,
96 d_vita_tail_size,
97 d_byte_swapped,
98 d_iq_swapped,
99 (unsigned char*)(d_udp_port->recv_buffer),
100 d_packet_size) );
101 }
102 // Increment the items processed counter
103 noutput_items_processed++;
104 // Reset the UDP port buffer
105 d_udp_port->clear_buffer();
106 // Set the got data on loop flag
107 got_data_on_loop = true;
108 }
109 } while ( got_data_on_loop && (noutput_items_processed < noutput_items) );
110 d_udp_port_mtx.unlock();
111 }
112 return noutput_items_processed;
113 }
114
115 int VitaIqSource::getPacketsPayloadData(int noutput_items, void * buffer)
116 {
117 int noutput_items_processed = 0;
118 bool got_data_on_loop = false;
119 // Check to see if the UDP port is available for reading
120 if ( d_udp_port_mtx.try_lock() )
121 {
122 // Get as many packets as we can, up to the maximum number requested.
123 do
124 {
125 got_data_on_loop = false;
126 // Get data from UDP port if it's available
127 d_udp_port->read_data();
128 if ( d_udp_port->is_packet_ready() )
129 {
131 d_vita_type,
132 d_payload_size,
133 d_vita_header_size,
134 d_vita_tail_size,
135 d_byte_swapped,
136 d_iq_swapped,
137 (unsigned char*)(d_udp_port->recv_buffer),
138 d_packet_size);
139 //std::cout << temp.timestampFrac << std::endl;
140 std::memcpy(buffer, temp.sampleData, d_payload_size);
141 // Increment the items processed counter
142 noutput_items_processed++;
143 // Reset the UDP port buffer
144 d_udp_port->clear_buffer();
145 // Set the got data on loop flag
146 got_data_on_loop = true;
147 }
148 } while ( got_data_on_loop && (noutput_items_processed < noutput_items) );
149 d_udp_port_mtx.unlock();
150 }
151 return noutput_items_processed;
152 }
153
155 {
156 return d_packet_size;
157 }
158
160 {
161 return d_byte_swapped;
162 }
163
165 {
166 return d_iq_swapped;
167 }
168
170 {
171 return d_payload_size;
172 }
173
175 {
176 return d_vita_header_size;
177 }
178
180 {
181 return d_vita_tail_size;
182 }
183
185 {
186 return d_vita_type;
187 }
188
189 void VitaIqSource::recalc_packet_size()
190 {
191 // Determine packet size
192 d_packet_size = (d_vita_type == 0 ? d_payload_size :
193 d_vita_header_size + d_payload_size + d_vita_tail_size);
194 // Reconnect the UDP port
195 disconnect_udp_port();
196 connect_udp_port();
197 }
198
199 void VitaIqSource::connect_udp_port()
200 {
201 d_udp_port_mtx.lock();
202 // Create UDP port for collecting data
203 this->debug("connect udp %s/%d\n", d_host.c_str(), d_port);
204 d_udp_port = new VitaIqUdpPort(d_host, d_port, d_packet_size, isDebug());
205 this->debug("-- connect result: %d\n", d_udp_port->connected);
206 d_udp_port_mtx.unlock();
207 }
208
209 void VitaIqSource::disconnect_udp_port()
210 {
211 d_udp_port_mtx.lock();
212 // Destroy UDP port for collecting data
213 this->debug("disconnect udp %s/%d\n", d_host.c_str(), d_port);
214 delete d_udp_port;
215 d_udp_port = NULL;
216 d_udp_port_mtx.unlock();
217 }
218
219
220} /* namespace LibCyberRadio */
221
virtual bool isDebug() const
Gets whether this object produces debug output.
virtual int debug(const char *format,...)
Outputs debug information.
Debuggable(bool debug=false, const std::string &debug_name="", FILE *debug_fp=DEBUG_FP, const std::string &debug_timefmt=DEBUG_TIME_FMT)
Constructs a Debuggable object.
Decodes a VITA 49 or I/Q data packet.
size_t getPayloadSize() const
Gets the payload size.
virtual ~VitaIqSource()
Destroys a vita_iq_source object.
size_t getVitaHeaderSize() const
Gets the VITA 49 frame header size.
bool isIqSwapped() const
Gets the I/Q-swapping state.
virtual int getPacketsPayloadData(int noutput_items, void *buff)
Gets VITA 49 or I/Q data packets.
virtual int getPackets(int noutput_items, Vita49PacketVector &output_items)
Gets VITA 49 or I/Q data packets.
VitaIqSource(const std::string &name="VitaIqSource", int vita_type=0, size_t payload_size=8192, size_t vita_header_size=0, size_t vita_tail_size=0, bool byte_swapped=false, bool iq_swapped=false, const std::string &host="0.0.0.0", unsigned short port=0, bool debug=false)
Creates a VitaIqSource object.
virtual int getPacketSize() const
Gets the VITA 49 or I/Q packet size.
size_t getVitaTailSize() const
Gets the VITA 49 frame trailer size.
int getVitaType() const
Gets the VITA type.
bool isByteSwapped() const
Gets the byte-swapping state.
Defines functionality for LibCyberRadio applications.
Definition App.h:24