1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
/* -*- c++ -*- */
/*
* Copyright 2019 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "selector_impl.h"
#include <gnuradio/io_signature.h>
#include <string.h>
#include <stdexcept>
namespace gr {
namespace blocks {
selector::sptr
selector::make(size_t itemsize, unsigned int input_index, unsigned int output_index)
{
return gnuradio::get_initial_sptr(
new selector_impl(itemsize, input_index, output_index));
}
selector_impl::selector_impl(size_t itemsize,
unsigned int input_index,
unsigned int output_index)
: block("selector",
io_signature::make(1, -1, itemsize),
io_signature::make(1, -1, itemsize)),
d_itemsize(itemsize),
d_enabled(true),
d_input_index(input_index),
d_output_index(output_index),
d_num_inputs(0),
d_num_outputs(0)
{
message_port_register_in(pmt::mp("en"));
set_msg_handler(pmt::mp("en"), [this](pmt::pmt_t msg) { this->handle_enable(msg); });
message_port_register_in(pmt::mp("iindex"));
set_msg_handler(pmt::mp("iindex"),
[this](pmt::pmt_t msg) { this->handle_msg_input_index(msg); });
message_port_register_in(pmt::mp("oindex"));
set_msg_handler(pmt::mp("oindex"),
[this](pmt::pmt_t msg) { this->handle_msg_output_index(msg); });
}
selector_impl::~selector_impl() {}
void selector_impl::set_input_index(unsigned int input_index)
{
gr::thread::scoped_lock l(d_mutex);
if (input_index < d_num_inputs)
d_input_index = input_index;
else
throw std::out_of_range("input_index must be < ninputs");
}
void selector_impl::set_output_index(unsigned int output_index)
{
gr::thread::scoped_lock l(d_mutex);
if (output_index < d_num_outputs)
d_output_index = output_index;
else
throw std::out_of_range("output_index must be < noutputs");
}
void selector_impl::handle_msg_input_index(pmt::pmt_t msg)
{
pmt::pmt_t data = pmt::cdr(msg);
if (pmt::is_integer(data)) {
const unsigned int new_port = pmt::to_long(data);
if (new_port < d_num_inputs)
set_input_index(new_port);
else
GR_LOG_WARN(
d_logger,
"handle_msg_input_index: port index greater than available ports.");
} else
GR_LOG_WARN(
d_logger,
"handle_msg_input_index: Non-PMT type received, expecting integer PMT");
}
void selector_impl::handle_msg_output_index(pmt::pmt_t msg)
{
pmt::pmt_t data = pmt::cdr(msg);
if (pmt::is_integer(data)) {
const unsigned int new_port = pmt::to_long(data);
if (new_port < d_num_outputs)
set_output_index(new_port);
else
GR_LOG_WARN(
d_logger,
"handle_msg_output_index: port index greater than available ports.");
} else
GR_LOG_WARN(
d_logger,
"handle_msg_output_index: Non-PMT type received, expecting integer PMT");
}
void selector_impl::handle_enable(pmt::pmt_t msg)
{
if (pmt::is_bool(msg)) {
bool en = pmt::to_bool(msg);
gr::thread::scoped_lock l(d_mutex);
d_enabled = en;
} else {
GR_LOG_WARN(d_logger,
"handle_enable: Non-PMT type received, expecting Boolean PMT");
}
}
void selector_impl::forecast(int noutput_items, gr_vector_int& ninput_items_required)
{
unsigned ninputs = ninput_items_required.size();
for (unsigned i = 0; i < ninputs; i++) {
ninput_items_required[i] = noutput_items;
}
}
bool selector_impl::check_topology(int ninputs, int noutputs)
{
if ((int)d_input_index < ninputs && (int)d_output_index < noutputs) {
d_num_inputs = (unsigned int)ninputs;
d_num_outputs = (unsigned int)noutputs;
return true;
} else {
GR_LOG_WARN(d_logger,
"check_topology: Input or Output index greater than number of ports");
return false;
}
}
int selector_impl::general_work(int noutput_items,
gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items)
{
const uint8_t** in = (const uint8_t**)&input_items[0];
uint8_t** out = (uint8_t**)&output_items[0];
gr::thread::scoped_lock l(d_mutex);
if (d_enabled) {
std::copy(in[d_input_index],
in[d_input_index] + noutput_items * d_itemsize,
out[d_output_index]);
produce(d_output_index, noutput_items);
}
consume_each(noutput_items);
return WORK_CALLED_PRODUCE;
}
void selector_impl::setup_rpc()
{
#ifdef GR_CTRLPORT
add_rpc_variable(rpcbasic_sptr(new rpcbasic_register_handler<selector>(
alias(), "en", "", "Enable", RPC_PRIVLVL_MIN, DISPNULL)));
#endif /* GR_CTRLPORT */
}
} /* namespace blocks */
} /* namespace gr */
|