TOBI SignalServer  0.1
/home/breidi/Dropbox/signalserver/src/hardware/hw_thread.cpp
Go to the documentation of this file.
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
 All Data Structures Files Functions Variables