fe_tuner_device.h
Go to the documentation of this file.
1 /*
2  * This file is protected by Copyright. Please refer to the COPYRIGHT file
3  * distributed with this source distribution.
4  *
5  * This file is part of REDHAWK frontendInterfaces.
6  *
7  * REDHAWK frontendInterfaces is free software: you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation, either version 3 of the License, or (at your
10  * option) any later version.
11  *
12  * REDHAWK frontendInterfaces is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this program. If not, see http://www.gnu.org/licenses/.
19  */
20 #ifndef FE_TUNER_DEVICE_BASE_H
21 #define FE_TUNER_DEVICE_BASE_H
22 
23 #include <ossie/Device_impl.h>
24 #include <uuid/uuid.h>
25 #include <redhawk/FRONTEND/Frontend.h>
26 
27 #include "ossie/prop_helpers.h"
28 #include "bulkio/bulkio.h"
29 #include "fe_tuner_struct_props.h"
30 #include "fe_tuner_port_impl.h"
31 #include "fe_rfinfo_port_impl.h"
32 #include "fe_rfsource_port_impl.h"
33 
34 /*********************************************************************************************/
35 /************************** FRONTEND **************************/
36 /*********************************************************************************************/
37 namespace frontend {
38 
39  class AllocationAlreadyExists : public CF::Device::InvalidCapacity {
40  public:
41  AllocationAlreadyExists(const char* msg, const CF::Properties& props) :
42  CF::Device::InvalidCapacity(msg, props)
43  {}
44  };
45 
46  inline std::string uuidGenerator() {
47  uuid_t new_random_uuid;
48  uuid_generate_random(new_random_uuid);
49  char new_random_uuid_str[37];
50  uuid_unparse(new_random_uuid, new_random_uuid_str);
51  return std::string(new_random_uuid_str);
52  };
53 
54  /* floatingPointCompare is a helper function to handle floating point comparison
55  * Return values:
56  * if lhs == rhs: 0.0
57  * if lhs > rhs: 1.0 or greater
58  * if lhs < rhs: -1.0 or less
59  * Recommended usage is to convert a comparison such as: (lhs OP rhs)
60  * to (floatingPointCompare(lhs,rhs) OP 0), where OP is a comparison operator
61  * (==, <, >, <=, >=, !=).
62  * "places" is used to specify precision. The default is 1, which
63  * uses a single decimal place of precision.
64  */
65  inline double floatingPointCompare(double lhs, double rhs, size_t places = 1){
66  return round((lhs-rhs)*pow(10,places));
67  /*if(round((lhs-rhs)*(pow(10,places))) == 0)
68  return 0; // equal
69  if(lhs<rhs)
70  return -1; // lhs < rhs
71  return 1; // lhs > rhs*/
72  }
73 
74  /* validateRequest is a helper function to verify a value is within a range, returning
75  * true if the value requested_val falls within the range [available_min:available_max]
76  * False is returned if min > max
77  */
78  inline bool validateRequest(double available_min, double available_max, double requested_val){
79  if(floatingPointCompare(requested_val,available_min) < 0) return false;
80  if(floatingPointCompare(requested_val,available_max) > 0) return false;
81  if(floatingPointCompare(available_min,available_max) > 0) return false;
82  return true;
83  }
84 
85  /* validateRequest is a helper function to compare two ranges, returning true if the range
86  * [requested_min:requested_max] falls within the range [available_min:available_max]
87  * False is returned if min > max for either available for requested values
88  */
89  inline bool validateRequest(double available_min, double available_max, double requested_min, double requested_max){
90  if(floatingPointCompare(requested_min,available_min) < 0) return false;
91  if(floatingPointCompare(requested_max,available_max) > 0) return false;
92  if(floatingPointCompare(available_min,available_max) > 0) return false;
93  if(floatingPointCompare(requested_min,requested_max) > 0) return false;
94  return true;
95  }
96 
97  /* validateRequestVsSRI is a helper function to check that the input data stream can support
98  * the allocation request. The output mode (true if complex output) is used when determining
99  * the necessary sample rate required to satisfy the request. The entire frequency band of the
100  * request must be available for True to be returned, not just the center frequency.
101  * True is returned upon success, otherwise FRONTEND::BadParameterException is thrown.
102  * If the CHAN_RF and FRONTEND::BANDWIDTH keywords are not found in the sri,
103  * FRONTEND::BadParameterException is thrown.
104  */
105  bool validateRequestVsSRI(const frontend_tuner_allocation_struct& request, const BULKIO::StreamSRI& upstream_sri, bool output_mode);
106 
107  /* validateRequestVsDevice is a helper function to check that the input data stream and the
108  * device can support an allocation request. The output mode (true if complex output) is used
109  * when determining the necessary sample rate required to satisfy the request. The entire
110  * frequency band of the request must be available for True to be returned, not just the center
111  * frequency.
112  * True is returned upon success, otherwise FRONTEND::BadParameterException is thrown.
113  * If the CHAN_RF and FRONTEND::BANDWIDTH keywords are not found in the sri,
114  * FRONTEND::BadParameterException is thrown.
115  */
116  bool validateRequestVsDevice(const frontend_tuner_allocation_struct& request, const BULKIO::StreamSRI& upstream_sri,
117  bool output_mode, double min_device_center_freq, double max_device_center_freq, double max_device_bandwidth, double max_device_sample_rate);
118 
119  /* validateRequestVsRFInfo is a helper function to check that the analog capabilities can support
120  * the allocation request. The mode (true if complex) is used when determining the necessary
121  * sample rate required to satisfy the request. The entire frequency band of the request must be
122  * available for True to be returned, not just the center frequency.
123  * True is returned upon success, otherwise FRONTEND::BadParameterException is thrown.
124  */
125  bool validateRequestVsRFInfo(const frontend_tuner_allocation_struct& request, const frontend::RFInfoPkt& rfinfo, bool mode);
126 
127  /* validateRequestVsDevice is a helper function to check that the analog capabilities and the
128  * device can support the allocation request. The mode (true if complex) is used when
129  * determining the necessary sample rate required to satisfy the request. The entire frequency
130  * band of the request must be available for True to be returned, not just the center frequency.
131  * True is returned upon success, otherwise FRONTEND::BadParameterException is thrown.
132  */
133  bool validateRequestVsDevice(const frontend_tuner_allocation_struct& request, const frontend::RFInfoPkt& rfinfo,
134  bool mode, double min_device_center_freq, double max_device_center_freq, double max_device_bandwidth, double max_device_sample_rate);
135 
136  /* Tuner Allocation IDs struct. This structure contains allocation tracking data.
137  *
138  */
139 
142  reset();
143  }
145  std::vector<std::string> listener_allocation_ids;
146 
147  void reset(){
148  control_allocation_id.clear();
149  listener_allocation_ids.clear();
150  }
151  };
152 
153  /*
154  * Frontend tuner class definition
155  */
156  template < typename TunerStatusStructType >
158  {
159  ENABLE_LOGGING
160 
161  public:
162  FrontendTunerDevice(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl);
163  FrontendTunerDevice(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, char *compDev);
164  FrontendTunerDevice(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities);
165  FrontendTunerDevice(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities, char *compDev);
167 
168  // this is implemented in the generated base class once all properties are known
169  virtual void loadProperties();
170 
171  // Device specific allocation handling
172  virtual CF::Device::UsageType updateUsageState();
173  virtual CORBA::Boolean allocateCapacity(const CF::Properties & capacities) throw (CORBA::SystemException, CF::Device::InvalidCapacity, CF::Device::InvalidState);
174  virtual void deallocateCapacity(const CF::Properties & capacities)throw (CORBA::SystemException, CF::Device::InvalidCapacity, CF::Device::InvalidState);
175 
176  protected:
177  typedef std::map<std::string, size_t> string_number_mapping;
178  typedef boost::mutex::scoped_lock exclusive_lock;
179 
180  // Member variables exposed as properties
181  std::string device_kind;
182  std::string device_model;
183  frontend::frontend_tuner_allocation_struct frontend_tuner_allocation;
184  frontend::frontend_listener_allocation_struct frontend_listener_allocation;
185  std::vector<TunerStatusStructType> frontend_tuner_status;
186 
187  // tuner_allocation_ids is exclusively paired with property frontend_tuner_status.
188  // tuner_allocation_ids tracks allocation ids while frontend_tuner_status provides tuner information.
189  std::vector<frontend::tunerAllocationIdsStruct> tuner_allocation_ids;
190 
191  // Provides mapping from unique allocation ID to internal tuner (channel) number
192  string_number_mapping allocation_id_to_tuner_id;
194 
196  // Device specific functions // -- virtual - to be implemented by device developer
198  virtual void deviceEnable(TunerStatusStructType &fts, size_t tuner_id) = 0;
199  virtual void deviceDisable(TunerStatusStructType &fts, size_t tuner_id) = 0;
200  virtual bool deviceSetTuning(const frontend_tuner_allocation_struct &request, TunerStatusStructType &fts, size_t tuner_id) = 0;
201  virtual bool deviceDeleteTuning(TunerStatusStructType &fts, size_t tuner_id) = 0;
202 
204  // Mapping and translation helpers. External string identifiers to internal numerical identifiers
206  virtual std::string getControlAllocationId(size_t tuner_id);
207  virtual std::vector<std::string> getListenerAllocationIds(size_t tuner_id);
208  virtual long getTunerMapping(std::string allocation_id);
209  std::string createAllocationIdCsv(size_t tuner_id);
210  virtual bool removeTunerMapping(size_t tuner_id, std::string allocation_id);
211  virtual bool removeTunerMapping(size_t tuner_id);
212  virtual void assignListener(const std::string& listen_alloc_id, const std::string& alloc_id);
213  virtual void removeListener(const std::string& listen_alloc_id);
214  virtual void removeAllocationIdRouting(const size_t tuner_id) = 0;
215  virtual void setNumChannels(size_t num) = 0;
216 
217  // Configure tuner - gets called during allocation
218  virtual bool enableTuner(size_t tuner_id, bool enable);
219  virtual bool listenerRequestValidation(frontend_tuner_allocation_struct &request, size_t tuner_id);
220 
221 
223  // Other helper functions //
225  BULKIO::StreamSRI create(std::string &stream_id, TunerStatusStructType &frontend_status, double collector_frequency = -1.0) {
226  BULKIO::StreamSRI sri;
227  sri.hversion = 1;
228  sri.xstart = 0.0;
229  if ( frontend_status.sample_rate <= 0.0 )
230  sri.xdelta = 1.0;
231  else
232  sri.xdelta = 1/frontend_status.sample_rate;
233  sri.xunits = BULKIO::UNITS_TIME;
234  sri.subsize = 0;
235  sri.ystart = 0.0;
236  sri.ydelta = 0.0;
237  sri.yunits = BULKIO::UNITS_NONE;
238  sri.mode = 0;
239  sri.blocking=false;
240  sri.streamID = stream_id.c_str();
241  CORBA::Double colFreq;
242  if (collector_frequency < 0)
243  colFreq = frontend_status.center_frequency;
244  else
245  colFreq = CORBA::Double(collector_frequency);
246  this->addModifyKeyword<CORBA::Double > (&sri, "COL_RF", CORBA::Double(colFreq));
247  this->addModifyKeyword<CORBA::Double > (&sri, "CHAN_RF", CORBA::Double(frontend_status.center_frequency));
248  this->addModifyKeyword<std::string> (&sri,"FRONTEND::RF_FLOW_ID",frontend_status.rf_flow_id);
249  this->addModifyKeyword<CORBA::Double> (&sri,"FRONTEND::BANDWIDTH", CORBA::Double(frontend_status.bandwidth));
250  this->addModifyKeyword<std::string> (&sri,"FRONTEND::DEVICE_ID",std::string(identifier()));
251  return sri;
252  }
253 
254  template <typename CORBAXX> bool addModifyKeyword(BULKIO::StreamSRI *sri, CORBA::String_member id, CORBAXX myValue, bool addOnly = false) {
255  CORBA::Any value;
256  value <<= myValue;
257  unsigned long keySize = sri->keywords.length();
258  if (!addOnly) {
259  for (unsigned int i = 0; i < keySize; i++) {
260  if (!strcmp(sri->keywords[i].id, id)) {
261  sri->keywords[i].value = value;
262  return true;
263  }
264  }
265  }
266  sri->keywords.length(keySize + 1);
267  if (sri->keywords.length() != keySize + 1)
268  return false;
269  sri->keywords[keySize].id = CORBA::string_dup(id);
270  sri->keywords[keySize].value = value;
271  return true;
272  }
273 
274  // This is not currently used but is available as a debugging tool
275  void printSRI(BULKIO::StreamSRI *sri, std::string strHeader = "DEBUG SRI"){
276  std::cout << strHeader << ":\n";
277  std::cout << "\thversion: " << sri->hversion<< std::endl;
278  std::cout << "\txstart: " << sri->xstart<< std::endl;
279  std::cout << "\txdelta: " << sri->xdelta<< std::endl;
280  std::cout << "\txunits: " << sri->xunits<< std::endl;
281  std::cout << "\tsubsize: " << sri->subsize<< std::endl;
282  std::cout << "\tystart: " << sri->ystart<< std::endl;
283  std::cout << "\tydelta: " << sri->ydelta<< std::endl;
284  std::cout << "\tyunits: " << sri->yunits<< std::endl;
285  std::cout << "\tmode: " << sri->mode<< std::endl;
286  std::cout << "\tstreamID: " << sri->streamID<< std::endl;
287  unsigned long keySize = sri->keywords.length();
288  for (unsigned int i = 0; i < keySize; i++) {
289  std::cout << "\t KEYWORD KEY/VAL :: " << sri->keywords[i].id << ": " << ossie::any_to_string(sri->keywords[i].value) << std::endl;
290  }
291  std::cout << std::endl;
292  }
293 
294  private:
295  // this will be overridden by the generated base class once all ports are known
296  virtual void construct();
297  };
298 
299 }; // end frontend namespace
300 
301 #endif
void printSRI(BULKIO::StreamSRI *sri, std::string strHeader="DEBUG SRI")
Definition: fe_tuner_device.h:275
virtual long getTunerMapping(std::string allocation_id)
std::string device_model
Definition: fe_tuner_device.h:182
std::string uuidGenerator()
Definition: fe_tuner_device.h:46
virtual CF::Device::UsageType updateUsageState()
Definition: fe_tuner_device.h:37
std::vector< frontend::tunerAllocationIdsStruct > tuner_allocation_ids
Definition: fe_tuner_device.h:189
FrontendTunerDevice(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl)
double floatingPointCompare(double lhs, double rhs, size_t places=1)
Definition: fe_tuner_device.h:65
void reset()
Definition: fe_tuner_device.h:147
virtual bool deviceSetTuning(const frontend_tuner_allocation_struct &request, TunerStatusStructType &fts, size_t tuner_id)=0
Definition: fe_tuner_device.h:39
char * identifier()
virtual bool removeTunerMapping(size_t tuner_id, std::string allocation_id)
frontend::frontend_listener_allocation_struct frontend_listener_allocation
Definition: fe_tuner_device.h:184
double Double
Definition: bulkio_base.h:156
std::vector< TunerStatusStructType > frontend_tuner_status
Definition: fe_tuner_device.h:185
virtual void deviceDisable(TunerStatusStructType &fts, size_t tuner_id)=0
virtual bool deviceDeleteTuning(TunerStatusStructType &fts, size_t tuner_id)=0
virtual void deallocateCapacity(const CF::Properties &capacities)
std::map< std::string, size_t > string_number_mapping
Definition: fe_tuner_device.h:177
string_number_mapping allocation_id_to_tuner_id
Definition: fe_tuner_device.h:192
Definition: fe_tuner_device.h:140
bool validateRequestVsSRI(const frontend_tuner_allocation_struct &request, const BULKIO::StreamSRI &upstream_sri, bool output_mode)
tunerAllocationIdsStruct()
Definition: fe_tuner_device.h:141
boost::mutex allocation_id_mapping_lock
Definition: fe_tuner_device.h:193
bool addModifyKeyword(BULKIO::StreamSRI *sri, CORBA::String_member id, CORBAXX myValue, bool addOnly=false)
Definition: fe_tuner_device.h:254
virtual CORBA::Boolean allocateCapacity(const CF::Properties &capacities)
virtual void deviceEnable(TunerStatusStructType &fts, size_t tuner_id)=0
bool validateRequest(double available_min, double available_max, double requested_val)
Definition: fe_tuner_device.h:78
virtual bool enableTuner(size_t tuner_id, bool enable)
virtual void assignListener(const std::string &listen_alloc_id, const std::string &alloc_id)
AllocationAlreadyExists(const char *msg, const CF::Properties &props)
Definition: fe_tuner_device.h:41
Definition: Device_impl.h:40
std::string control_allocation_id
Definition: fe_tuner_device.h:144
bool validateRequestVsDevice(const frontend_tuner_allocation_struct &request, const BULKIO::StreamSRI &upstream_sri, bool output_mode, double min_device_center_freq, double max_device_center_freq, double max_device_bandwidth, double max_device_sample_rate)
BULKIO::StreamSRI create(std::string &stream_id, TunerStatusStructType &frontend_status, double collector_frequency=-1.0)
Definition: fe_tuner_device.h:225
virtual void setNumChannels(size_t num)=0
std::vector< std::string > listener_allocation_ids
Definition: fe_tuner_device.h:145
Definition: fe_tuner_device.h:157
virtual bool listenerRequestValidation(frontend_tuner_allocation_struct &request, size_t tuner_id)
std::string createAllocationIdCsv(size_t tuner_id)
bool validateRequestVsRFInfo(const frontend_tuner_allocation_struct &request, const frontend::RFInfoPkt &rfinfo, bool mode)
boost::mutex::scoped_lock exclusive_lock
Definition: fe_tuner_device.h:178
virtual std::vector< std::string > getListenerAllocationIds(size_t tuner_id)
virtual std::string getControlAllocationId(size_t tuner_id)
std::string device_kind
Definition: fe_tuner_device.h:181
virtual void removeListener(const std::string &listen_alloc_id)
frontend::frontend_tuner_allocation_struct frontend_tuner_allocation
Definition: fe_tuner_device.h:183
virtual void removeAllocationIdRouting(const size_t tuner_id)=0