TOBI SignalServer
0.1
|
00001 /* 00002 This file is part of the TOBI SignalServer. 00003 00004 Commercial Usage 00005 Licensees holding valid Graz University of Technology Commercial 00006 licenses may use this file in accordance with the Graz University 00007 of Technology Commercial License Agreement provided with the 00008 Software or, alternatively, in accordance with the terms contained in 00009 a written agreement between you and Graz University of Technology. 00010 00011 -------------------------------------------------- 00012 00013 GNU General Public License Usage 00014 Alternatively, this file may be used under the terms of the GNU 00015 General Public License version 3.0 as published by the Free Software 00016 Foundation and appearing in the file gpl.txt included in the 00017 packaging of this file. Please review the following information to 00018 ensure the GNU General Public License version 3.0 requirements will be 00019 met: http://www.gnu.org/copyleft/gpl.html. 00020 00021 In case of GNU General Public License Usage ,the TOBI SignalServer 00022 is distributed in the hope that it will be useful, 00023 but WITHOUT ANY WARRANTY; without even the implied warranty of 00024 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00025 GNU General Public License for more details. 00026 00027 You should have received a copy of the GNU General Public License 00028 along with the TOBI SignalServer. If not, see <http://www.gnu.org/licenses/>. 00029 00030 Copyright 2010 Graz University of Technology 00031 Contact: SignalServer@tobi-project.org 00032 */ 00033 00038 #include "hardware/hw_thread.h" 00039 #include "tia/constants.h" 00040 #include <boost/algorithm/string.hpp> 00041 00042 #include <boost/lexical_cast.hpp> 00043 00044 namespace tobiss 00045 { 00046 00047 using boost::lexical_cast; 00048 using boost::bad_lexical_cast; 00049 00050 using boost::uint16_t; 00051 using boost::uint32_t; 00052 00053 using boost::algorithm::to_lower_copy; 00054 00055 using std::map; 00056 using std::pair; 00057 using std::vector; 00058 using std::string; 00059 using std::cout; 00060 using std::endl; 00061 using std::dec; 00062 using std::hex; 00063 00064 //----------------------------------------------------------------------------- 00065 00066 //const string HWThread::hardware_("hardware"); 00067 //const string HWThread::hardware_name_("name"); 00068 const string HWThread::hardware_version_("version"); 00069 const string HWThread::hardware_serial_("serial"); 00070 00071 const string HWThread::hw_mode_("mode"); 00072 const string HWThread::hw_devset_("device_settings"); 00073 const string HWThread::hw_fs_("sampling_rate"); 00074 00075 const string HWThread::hw_channels_("measurement_channels"); 00076 const string HWThread::hw_ch_nr_("nr"); 00077 const string HWThread::hw_ch_names_("names"); 00078 const string HWThread::hw_ch_type_("type"); 00079 00080 const string HWThread::hw_blocksize_("blocksize"); 00081 00082 const string HWThread::hw_chset_("channel_settings"); 00083 const string HWThread::hw_chset_sel_("selection"); 00084 const string HWThread::hw_chset_ch_("ch"); 00085 const string HWThread::hw_chset_nr_("nr"); 00086 const string HWThread::hw_chset_name_("name"); 00087 00088 //----------------------------------------------------------------------------- 00089 00090 void HWThread::checkMandatoryHardwareTags(ticpp::Iterator<ticpp::Element> hw) 00091 { 00092 #ifdef DEBUG 00093 cout << "HWThread: checkMandatoryHardwareTags" << endl; 00094 #endif 00095 00096 ticpp::Iterator<ticpp::Element> elem(hw); 00097 ticpp::Iterator< ticpp::Attribute > attribute; 00098 00099 try 00100 { 00101 checkMandatoryHardwareTagsXML(hw); 00102 } 00103 catch(ticpp::Exception& e) 00104 { 00105 string ex_str(type_ + " -- "); 00106 throw(std::invalid_argument(ex_str + e.what())); 00107 } 00108 00109 elem = hw->FirstChildElement(hw_mode_, true); 00110 if(equalsMaster(elem->GetText(false))) 00111 mode_ = MASTER; 00112 if(equalsSlave(elem->GetText(false))) 00113 mode_ = SLAVE; 00114 if(equalsAperiodic(elem->GetText(false))) 00115 mode_ = APERIODIC; 00116 } 00117 00118 //----------------------------------------------------------------------------- 00119 00120 bool HWThread::samplesAvailable() 00121 { 00122 #ifdef DEBUG 00123 cout << "HWThread: samplesAvailable" << endl; 00124 #endif 00125 00126 boost::shared_lock<boost::shared_mutex> lock(rw_); 00127 bool tmp(samples_available_); 00128 lock.unlock(); 00129 return(tmp); 00130 } 00131 00132 //----------------------------------------------------------------------------- 00133 00134 void HWThread::setSamplingRate(ticpp::Iterator<ticpp::Element>const &elem) 00135 { 00136 #ifdef DEBUG 00137 cout << "HWThread: setSamplingRate" << endl; 00138 #endif 00139 00141 try 00142 { 00143 fs_ = lexical_cast<double>(elem->GetText(true)); 00144 } 00145 catch(bad_lexical_cast &) 00146 { 00147 string ex_str(type_ + " -- Sampling Rate is not a number!"); 00148 throw(std::invalid_argument(ex_str)); 00149 } 00150 if(fs_ == 0) 00151 { 00152 string ex_str(type_ + " -- Sampling Rate is 0!"); 00153 throw(std::invalid_argument(ex_str)); 00154 } 00155 } 00156 00157 //--------------------------------------------------------------------------------------- 00158 void HWThread::setDeviceChannels(ticpp::Iterator<ticpp::Element>const &elem) 00159 { 00160 #ifdef DEBUG 00161 cout << "HWThread: setDeviceChannels" << endl; 00162 #endif 00163 00164 string naming; 00165 string type; 00166 00167 try 00168 { 00169 parseDeviceChannels(elem, nr_ch_, naming, type); 00170 } 00171 catch(ticpp::Exception& e) 00172 { 00173 string ex_str(type_ + " -- "); 00174 throw(std::invalid_argument(ex_str + e.what())); 00175 } 00176 00177 tia::Constants cst; 00178 for(uint16_t n = 1; n <= nr_ch_; n++) 00179 channel_info_.insert( 00180 pair<uint16_t, pair<string, uint32_t> >(n, pair<string, uint32_t>(naming, 00181 cst.getSignalFlag(type)))); 00182 homogenous_signal_type_ = 1; 00183 00184 setChannelTypes(); 00185 } 00186 00187 //--------------------------------------------------------------------------------------- 00188 void HWThread::setBlocks(ticpp::Iterator<ticpp::Element>const &elem) 00189 { 00190 #ifdef DEBUG 00191 cout << "HWThread: setBlocks" << endl; 00192 #endif 00193 00194 boost::int16_t blocks = 0; 00195 00196 try 00197 { 00198 blocks = lexical_cast<boost::int16_t>(elem->GetText(true)); 00199 } 00200 catch(bad_lexical_cast &) 00201 { 00202 string ex_str(type_ + " -- Blocksize: value is not a number!"); 00203 throw(std::invalid_argument(ex_str)); 00204 } 00205 if(blocks <= 0) 00206 { 00207 string ex_str(type_ + " -- Blocksize: value is <= 0!"); 00208 throw(std::invalid_argument(ex_str)); 00209 } 00210 00211 blocks_ = blocks; 00212 } 00213 00214 //--------------------------------------------------------------------------------------- 00215 void HWThread::setChannelSelection(ticpp::Iterator<ticpp::Element>const &father) 00216 { 00217 #ifdef DEBUG 00218 cout << "HWThread: setChannelSelection" << endl; 00219 #endif 00220 00221 bool nr_ch_dirty = 0; 00222 ticpp::Iterator<ticpp::Element> elem; 00223 if(nr_ch_ == 0) 00224 elem = father->FirstChildElement(hw_chset_ch_,true); 00225 else 00226 elem = father->FirstChildElement(hw_chset_ch_,false); 00227 00228 tia::Constants cst; 00229 if (elem != elem.end()) 00230 { 00231 if(channel_info_.size() != 0) 00232 nr_ch_dirty = 1; 00233 00234 channel_info_.clear(); 00235 00236 for(ticpp::Iterator<ticpp::Element> it(elem); it != it.end(); it++) 00237 if(it->Value() == hw_chset_ch_) 00238 { 00239 string name; 00240 string type; 00241 uint16_t ch = 0; 00242 try 00243 { 00244 parseChannelSelection(it, ch, name, type); 00245 } 00246 catch(ticpp::Exception& e) 00247 { 00248 string ex_str(type_ + " -- "); 00249 throw(std::invalid_argument(ex_str + e.what())); 00250 } 00251 channel_info_.insert( 00252 pair<uint16_t, pair<string, uint32_t> >(ch, pair<string, uint32_t>(name, 00253 cst.getSignalFlag(type)))); 00254 } 00255 nr_ch_ = channel_info_.size(); 00256 } 00257 00258 if(nr_ch_dirty) 00259 { 00260 cout << " *** Danger ***" << endl; 00261 cout << " -- Global setting \"Nr. Of Channels\" and naming overridden by individual channel setting!" << endl; 00262 map<uint16_t, pair<string, uint32_t> >::iterator m_it; 00263 for ( m_it=channel_info_.begin() ; m_it != channel_info_.end(); m_it++ ) 00264 { 00265 cout << " Channel: " << dec << (*m_it).first; 00266 cout << " ... Name: " << (*m_it).second.first; 00267 cout << " ... Type: " << cst.getSignalName((*m_it).second.second) << " (0x" << hex << (*m_it).second.second << ")" << endl; 00268 } 00269 cout << dec << endl; 00270 } 00271 00272 map<uint16_t, pair<string, uint32_t> >::iterator m_it = channel_info_.begin(); 00273 uint32_t sig_type = (*m_it).second.second; 00274 for (m_it++; m_it != channel_info_.end(); m_it++ ) 00275 if(sig_type != (*m_it).second.second) 00276 homogenous_signal_type_ = 0; 00277 00278 setChannelTypes(); 00279 } 00280 00281 //----------------------------------------------------------------------------- 00282 00283 void HWThread::setChannelTypes() 00284 { 00285 #ifdef DEBUG 00286 cout << "HWThread: setChannelTypes" << endl; 00287 #endif 00288 00289 channel_types_.clear(); 00290 for(map<uint16_t, pair<string, uint32_t> >::iterator it = channel_info_.begin(); 00291 it != channel_info_.end(); it++ ) 00292 channel_types_.push_back((*it).second.second); 00293 } 00294 00295 //--------------------------------------------------------------------------------------- 00296 00297 bool HWThread::equalsOnOrOff(const std::string& s) 00298 { 00299 if(to_lower_copy(s) == "on" || s == "1") 00300 return(true); 00301 if(to_lower_copy(s) == "off" || s == "0") 00302 return(false); 00303 else 00304 { 00305 string e = s + " -- Value equals neiter \"on, off, 0 or 1\"!"; 00306 throw std::invalid_argument(e); 00307 } 00308 } 00309 00310 //----------------------------------------------------------------------------- 00311 00312 bool HWThread::equalsYesOrNo(const std::string& s) 00313 { 00314 if(to_lower_copy(s) == "yes" || s == "1") 00315 return(true); 00316 if(to_lower_copy(s) == "no" || s == "0") 00317 return(false); 00318 else 00319 { 00320 string e = s + " -- Value equals neiter \"yes, no, 0 or 1\"!"; 00321 throw std::invalid_argument(e); 00322 } 00323 } 00324 00325 //----------------------------------------------------------------------------- 00326 00327 bool HWThread::equalsMaster(const std::string& s) 00328 { 00329 return(to_lower_copy(s) == "master"); 00330 } 00331 00332 //----------------------------------------------------------------------------- 00333 00334 bool HWThread::equalsSlave(const std::string& s) 00335 { 00336 return(to_lower_copy(s) == "slave"); 00337 } 00338 00339 //----------------------------------------------------------------------------- 00340 00341 bool HWThread::equalsAperiodic(const std::string& s) 00342 { 00343 return(to_lower_copy(s) == "aperiodic"); 00344 } 00345 00346 //--------------------------------------------------------------------------------------- 00347 00348 void HWThread::parseDeviceChannels(ticpp::Iterator<ticpp::Element>const &elem, boost::uint16_t& nr_ch, 00349 std::string& naming, std::string& type) 00350 { 00351 string nr_channels; 00352 00353 if(!elem.Get()->HasAttribute(hw_ch_nr_)) 00354 { 00355 string ex_str(type_ + " -- "); 00356 ex_str += "Tag <" + hw_channels_ +"> given, number of channels ("+hw_ch_nr_+") not given!"; 00357 throw(std::invalid_argument(ex_str)); 00358 } 00359 if(!elem.Get()->HasAttribute(hw_ch_names_)) 00360 { 00361 string ex_str(type_ + " -- "); 00362 ex_str += "Tag <"+ hw_channels_ +"> given, channel names ("+hw_ch_names_ +") not given!"; 00363 throw(std::invalid_argument(ex_str)); 00364 } 00365 if(!elem.Get()->HasAttribute(hw_ch_type_)) 00366 { 00367 string ex_str(type_ + " -- "); 00368 ex_str += "Tag <"+hw_channels_+"> given, channels type ("+hw_ch_type_+") not given!"; 00369 throw(std::invalid_argument(ex_str)); 00370 } 00371 00372 nr_channels = elem.Get()->GetAttribute(hw_ch_nr_); 00373 naming = elem.Get()->GetAttribute(hw_ch_names_); 00374 type = elem.Get()->GetAttribute(hw_ch_type_); 00375 00376 try 00377 { 00378 nr_ch = lexical_cast<int>(nr_channels); 00379 } 00380 catch(bad_lexical_cast &) 00381 { 00382 string ex_str(type_ + " -- "); 00383 ex_str += "Tag <"+hw_channels_+"> given, but number of channels is not a number!"; 00384 throw(std::invalid_argument(ex_str)); 00385 } 00386 if(nr_ch == 0) 00387 { 00388 string ex_str(type_ + " -- "); 00389 ex_str += "Tag <"+hw_channels_+"> given, but number of channels (nr) is 0!"; 00390 throw(std::invalid_argument(ex_str)); 00391 } 00392 } 00393 00394 //--------------------------------------------------------------------------------------- 00395 00396 void HWThread::parseChannelSelection(ticpp::Iterator<ticpp::Element>const &elem, boost::uint16_t& ch, 00397 std::string& name, std::string& type) 00398 { 00399 string channel; 00400 00401 if(!elem.Get()->HasAttribute(hw_chset_nr_)) 00402 { 00403 string ex_str(type_ + " -- "); 00404 ex_str += "Tag <"+hw_channels_+"> given, channel number ("+hw_ch_nr_+") not given!"; 00405 throw(std::invalid_argument(ex_str)); 00406 } 00407 if(!elem.Get()->HasAttribute(hw_chset_name_)) 00408 { 00409 string ex_str(type_ + " -- "); 00410 ex_str += "Tag <"+hw_channels_+"> given, channel name ("+hw_ch_names_+") not given!"; 00411 throw(std::invalid_argument(ex_str)); 00412 } 00413 if(!elem.Get()->HasAttribute(hw_ch_type_)) 00414 { 00415 string ex_str(type_ + " -- "); 00416 ex_str += "Tag <"+hw_channels_+"> given, channel type ("+hw_ch_type_+") not given!"; 00417 throw(std::invalid_argument(ex_str)); 00418 } 00419 00420 channel = elem.Get()->GetAttribute(hw_chset_nr_); 00421 name = elem.Get()->GetAttribute(hw_chset_name_); 00422 type = elem.Get()->GetAttribute(hw_ch_type_); 00423 00424 try 00425 { 00426 ch = lexical_cast<int>(channel); 00427 } 00428 catch(bad_lexical_cast &) 00429 { 00430 string ex_str(type_ + " -- "); 00431 ex_str += "Tag <"+ hw_chset_ + "> - "+ hw_chset_sel_ +": Channel is not a number!"; 00432 throw(std::invalid_argument(ex_str)); 00433 } 00434 if(ch == 0) 00435 { 00436 string ex_str(type_ + " -- "); 00437 ex_str += "Tag <"+ hw_chset_ + "> - "+ hw_chset_sel_ +": Channel is 0 --> First channel-nr is 1!"; 00438 throw(std::invalid_argument(ex_str)); 00439 } 00440 } 00441 00442 //--------------------------------------------------------------------------------------- 00443 00444 void HWThread::checkMandatoryHardwareTagsXML(ticpp::Iterator<ticpp::Element> hw) 00445 { 00446 #ifdef DEBUG 00447 cout << "HWThread: checkMandatoryHardwareTags" << endl; 00448 #endif 00449 00450 ticpp::Iterator<ticpp::Element> elem; 00451 00452 elem = hw->FirstChildElement(hw_mode_, true); 00453 if( !(equalsMaster(elem->GetText(true)) || equalsSlave(elem->GetText(true)) 00454 || equalsAperiodic(elem->GetText(true)))) 00455 { 00456 string ex_str(type_ + " -- "); 00457 ex_str += "Mode is neither master, slave or aperiodic!"; 00458 throw(std::invalid_argument(ex_str)); 00459 } 00460 00461 elem = hw->FirstChildElement(hw_devset_, true); 00462 for(ticpp::Iterator<ticpp::Element> it(elem); ++it != it.end(); ) 00463 if(it->Value() == hw_devset_) 00464 { 00465 string ex_str(type_ + " -- "); 00466 ex_str += "Multiple device_settings found!"; 00467 throw(std::invalid_argument(ex_str)); 00468 } 00469 } 00470 00471 //----------------------------------------------------------------------------- 00472 00473 } // Namespace tobiss