DVBConfigParser.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
14 #include "DVBConfigParser.hh"
15 
16 // Custom includes
17 #include <boost/assign/std/map.hpp>
18 #include <senf/Utils/Exception.hh>
19 #include <senf/Utils/Logger.hh>
20 
21 #define prefix_
22 //-/////////////////////////////////////////////////////////////////////////////////////////////////
23 
24 senf::DVBConfigParser::DVBParams const senf::DVBConfigParser::params;
25 
26 prefix_ senf::DVBConfigParser::DVBParams::DVBParams()
27 {
28 
29  boost::assign::insert(inversion)
30  ( "INVERSION_OFF", INVERSION_OFF )
31  ( "INVERSION_ON", INVERSION_ON )
32  ( "INVERSION_AUTO", INVERSION_AUTO );
33  boost::assign::insert(bandwidth)
34  ( "BANDWIDTH_6_MHZ", BANDWIDTH_6_MHZ)
35  ( "BANDWIDTH_7_MHZ", BANDWIDTH_7_MHZ)
36  ( "BANDWIDTH_8_MHZ", BANDWIDTH_8_MHZ);
37  boost::assign::insert(code_rate)
38  ( "FEC_1_2", FEC_1_2)
39  ( "FEC_2_3", FEC_2_3)
40  ( "FEC_3_4", FEC_3_4)
41  ( "FEC_4_5", FEC_4_5)
42  ( "FEC_5_6", FEC_5_6)
43  ( "FEC_6_7", FEC_6_7)
44  ( "FEC_7_8", FEC_7_8)
45  ( "FEC_8_9", FEC_8_9)
46  ( "FEC_AUTO", FEC_AUTO)
47  ( "FEC_NONE", FEC_NONE);
48  boost::assign::insert(guard_interval)
49  ( "GUARD_INTERVAL_1_16", GUARD_INTERVAL_1_16)
50  ( "GUARD_INTERVAL_1_32", GUARD_INTERVAL_1_32)
51  ( "GUARD_INTERVAL_1_4", GUARD_INTERVAL_1_4)
52  ( "GUARD_INTERVAL_1_8", GUARD_INTERVAL_1_8);
53  boost::assign::insert(hierarchy)
54  ( "HIERARCHY_1", HIERARCHY_1)
55  ( "HIERARCHY_2", HIERARCHY_2)
56  ( "HIERARCHY_4", HIERARCHY_4)
57  ( "HIERARCHY_NONE", HIERARCHY_NONE);
58  boost::assign::insert(modulation)
59  ( "QPSK", QPSK)
60  ( "QAM_128", QAM_128)
61  ( "QAM_16", QAM_16)
62  ( "QAM_256", QAM_256)
63  ( "QAM_32", QAM_32)
64  ( "QAM_64", QAM_64);
65  boost::assign::insert(transmit_mode)
66  ( "TRANSMISSION_MODE_2K", TRANSMISSION_MODE_2K)
67  ( "TRANSMISSION_MODE_8K", TRANSMISSION_MODE_8K);
68 }
69 
70 prefix_ senf::DVBConfigParser::DVBConfigParser(fe_type_t type_, std::string const & configFilePath_) :
71  type(type_),
72  configFile()
73 {
74  initConfigFile(configFilePath_);
75 }
76 
78 {
79  configFile.close();
80 }
81 
82 prefix_ void senf::DVBConfigParser::initConfigFile(std::string configFilePath_)
83 {
84  if (configFilePath_.size() == 0) {
85  if ( !(::getenv ("HOME")) )
86  SENF_THROW_SYSTEM_EXCEPTION("$HOME not set! You need it to use default configfile.");
87  std::string configPath (::getenv ("HOME"));
88  switch(type) {
89  case FE_QPSK :
90  configPath += "/.szap/channels.conf";
91  break;
92  case FE_QAM :
93  configPath += "/.czap/channels.conf";
94  break;
95  case FE_OFDM :
96  configPath += "/.tzap/channels.conf";
97  break;
98  default:
99  SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
100  }
101  configFilePath_ = configPath;
102  }
103  configFilePath = configFilePath_;
104  configFile.open( configFilePath.c_str(), std::ios_base::in);
105  if (configFile.bad())
106  SENF_LOG((senf::log::IMPORTANT) ("Could not open channels file"<< configFilePath << "." ));
107  configFile.close();
108 }
109 
110 prefix_ std::string senf::DVBConfigParser::getConfigLine(std::string channel)
111 {
112  std::string configLine;
113  size_t pos;
114  transform(channel.begin(), channel.end(), channel.begin(), ::toupper);
115 
116  configFile.open( configFilePath.c_str(), std::ios_base::in);
117  if (configFile.bad())
118  SENF_THROW_SYSTEM_EXCEPTION("Could not read channels file: ") << configFilePath << ".";
119 
120  while (configFile.good()) {
121  getline( configFile, configLine );
122  SENF_LOG((senf::log::NOTICE)("configLine: " << configLine ));
123  transform(configLine.begin(), configLine.end(), configLine.begin(), ::toupper);
124  pos = configLine.find(channel);
125 
126  if (pos != std::string::npos && pos == 0) { // only first matching number should be interpreted as channel number
127  configFile.close();
128  return configLine; // Line found!
129  }
130  }
131  configFile.close();
132  SENF_THROW_SYSTEM_EXCEPTION("Channel \"")<< channel << "\" not found!";
133  return channel;
134 }
135 
136 prefix_ dvb_frontend_parameters senf::DVBConfigParser::getFrontendParam(std::string configLine)
137 {
138  struct dvb_frontend_parameters frontend;
139  transform(configLine.begin(), configLine.end(), configLine.begin(), ::toupper);
140  boost::char_separator<char> sep(":");
141  tokenizer tokens(configLine, sep);
142  switch (type) {
143  case FE_QPSK:
144  frontend = getFrontendParamDVB_S(tokens);
145  break;
146  case FE_QAM:
147  frontend = getFrontendParamDVB_C(tokens);
148  break;
149  case FE_OFDM:
150  frontend = getFrontendParamDVB_T(tokens);
151  break;
152  default:
153  SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
154  }
155  return frontend;
156 }
157 
158 prefix_ dvb_frontend_parameters
159 senf::DVBConfigParser::getFrontendParamDVB_T(const tokenizer & tokens)
160 {
161  struct dvb_frontend_parameters frontend;
162  std::istringstream isst;
163  int number;
164  enum { p_Frequency=1, p_Inversion, p_Bandwidth, p_hp_code_rate, p_lp_code_rate, p_Mudualtion, p_Transmission, p_guard, p_hierarchy};
165  std::vector<std::string> words (tokens.begin(), tokens.end());
166 
167  ::memset(&frontend, 0, sizeof(struct dvb_frontend_parameters));
168 
169  /*if (words.size() < 10)
170  SENF_THROW_SYSTEM_EXCEPTION("Too few arguments! There must be at least 10, but there are only: ") << words.size();*/
171 
172  isst.str(words[p_Frequency]);
173  isst >> number;
174  if (isst.fail())
175  SENF_THROW_SYSTEM_EXCEPTION("Can't parse frequency");
176  frontend.frequency = number;
177 
178  if (params.inversion.find(words[p_Inversion]) == params.inversion.end())
179  SENF_THROW_SYSTEM_EXCEPTION("Can't parse inversion");
180  frontend.inversion = params.inversion.find(words[p_Inversion])->second;
181 
182  if (params.bandwidth.find(words[p_Bandwidth]) == params.bandwidth.end())
183  SENF_THROW_SYSTEM_EXCEPTION("Can't parse bandwidth");
184  frontend.u.ofdm.bandwidth = params.bandwidth.find(words[p_Bandwidth])->second;
185 
186  if (params.code_rate.find(words[p_hp_code_rate]) == params.code_rate.end())
187  SENF_THROW_SYSTEM_EXCEPTION("Can't parse high priority stream code rate");
188  frontend.u.ofdm.code_rate_HP = params.code_rate.find(words[p_hp_code_rate])->second;
189 
190  if (params.code_rate.find(words[p_lp_code_rate]) == params.code_rate.end())
191  SENF_THROW_SYSTEM_EXCEPTION("Can't parse low priority stream code rate");
192  frontend.u.ofdm.code_rate_LP = params.code_rate.find(words[p_lp_code_rate])->second;
193 
194  if (params.modulation.find(words[p_Mudualtion]) == params.modulation.end())
195  SENF_THROW_SYSTEM_EXCEPTION("Can't parse modulation");
196  frontend.u.ofdm.constellation = params.modulation.find(words[p_Mudualtion])->second;
197 
198  if (params.transmit_mode.find(words[p_Transmission]) == params.transmit_mode.end())
199  SENF_THROW_SYSTEM_EXCEPTION("Can't parse transmission mode");
200  frontend.u.ofdm.transmission_mode = params.transmit_mode.find(words[p_Transmission])->second;
201 
202  if (params.guard_interval.find(words[p_guard]) == params.guard_interval.end())
203  SENF_THROW_SYSTEM_EXCEPTION("Can't parse guard interval");
204  frontend.u.ofdm.guard_interval = params.guard_interval.find(words[p_guard])->second;
205 
206  if (params.hierarchy.find(words[p_hierarchy]) == params.hierarchy.end())
207  SENF_THROW_SYSTEM_EXCEPTION("Can't parse hierarchy");
208  frontend.u.ofdm.hierarchy_information = params.hierarchy.find(words[p_hierarchy])->second;
209 
210  return frontend;
211 }
212 
213 prefix_ dvb_frontend_parameters
214 senf::DVBConfigParser::getFrontendParamDVB_S(const tokenizer & tokens)
215 {
216  struct dvb_frontend_parameters frontend;
217  std::istringstream isst;
218  int number;
219  enum { p_Frequency=1, p_Inversion, p_Symbole, p_code_rate};
220  std::vector<std::string> words (tokens.begin(), tokens.end());
221 
222  ::memset(&frontend, 0, sizeof(struct dvb_frontend_parameters));
223 
224  if (words.size() < 5)
225  SENF_THROW_SYSTEM_EXCEPTION("Too few arguments! There must be at least 5, but there are only: ") << words.size();
226 
227  isst.str(words[p_Frequency]);
228  isst >> number;
229  if (isst.fail())
230  SENF_THROW_SYSTEM_EXCEPTION("Can't parse frequency");
231  frontend.frequency = number;
232 
233  if (params.inversion.find(words[p_Inversion]) == params.inversion.end())
234  SENF_THROW_SYSTEM_EXCEPTION("Can't parse inversion");
235  frontend.inversion = params.inversion.find(words[p_Inversion])->second;
236 
237  isst.str(words[p_Symbole]);
238  isst >> number;
239  if (isst.fail())
240  SENF_THROW_SYSTEM_EXCEPTION("Can't parse symbole rate");
241  frontend.u.qpsk.symbol_rate = number;
242 
243  if (params.code_rate.find(words[p_code_rate]) == params.code_rate.end())
244  SENF_THROW_SYSTEM_EXCEPTION("Can't parse code rate");
245  frontend.u.qpsk.fec_inner = params.code_rate.find(words[p_code_rate])->second;
246 
247  return frontend;
248 }
249 
250 prefix_ dvb_frontend_parameters
251 senf::DVBConfigParser::getFrontendParamDVB_C(const tokenizer & tokens)
252 {
253  struct dvb_frontend_parameters frontend;
254  std::istringstream isst;
255  int number;
256  enum { p_Frequency=1, p_Inversion, p_Symbole, p_code_rate, p_modulation};
257  std::vector<std::string> words (++tokens.begin(), tokens.end());
258 
259  ::memset(&frontend, 0, sizeof(struct dvb_frontend_parameters));
260 
261  if (words.size() < 6)
262  SENF_THROW_SYSTEM_EXCEPTION("Too few arguments! There must be at least 6, but there are only: ") << words.size();
263 
264  isst.str(words[p_Frequency]);
265  isst >> number;
266  if (isst.fail())
267  SENF_THROW_SYSTEM_EXCEPTION("Can't parse frequency");
268  frontend.frequency = number;
269 
270  if (params.inversion.find(words[p_Inversion]) == params.inversion.end())
271  SENF_THROW_SYSTEM_EXCEPTION("Can't parse inversion");
272  frontend.inversion = params.inversion.find(words[p_Inversion])->second;
273 
274  isst.str(words[p_Symbole]);
275  isst >> number;
276  if (isst.fail())
277  SENF_THROW_SYSTEM_EXCEPTION("Can't parse symbole rate");
278  frontend.u.qam.symbol_rate = number;
279 
280  if (params.code_rate.find(words[p_code_rate]) == params.code_rate.end())
281  SENF_THROW_SYSTEM_EXCEPTION("Can't parse code rate");
282  frontend.u.qam.fec_inner = params.code_rate.find(words[p_code_rate])->second;
283 
284  if (params.modulation.find(words[p_modulation]) == params.modulation.end())
285  SENF_THROW_SYSTEM_EXCEPTION("Can't parse modulation");
286  frontend.u.qam.modulation = params.modulation.find(words[p_modulation])->second;
287 
288  return frontend;
289 }
290 
291 //-/////////////////////////////////////////////////////////////////////////////////////////////////
292 #undef prefix_
#define prefix_
#define SENF_THROW_SYSTEM_EXCEPTION(desc)
u8 type
DVBConfigParser(fe_type_t type_, const std::string &configFilePath="")
DVBDemuxHandles public header.
dvb_frontend_parameters getFrontendParam(std::string configLine)
std::string getConfigLine(std::string channel)
#define SENF_LOG(args)