TOBI Interface A  0.1
/home/breidi/Dropbox/libtia/src/tia/tia_server.cpp
Go to the documentation of this file.
00001 /*
00002     This file is part of the TOBI Interface A (TiA) library.
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 Lesser General Public License Usage
00014     Alternatively, this file may be used under the terms of the GNU Lesser
00015     General Public License version 3.0 as published by the Free Software
00016     Foundation and appearing in the file lgpl.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/lgpl.html.
00020 
00021     In case of GNU Lesser General Public License Usage ,the TiA library
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 Lesser General Public License
00028     along with the TiA library. If not, see <http://www.gnu.org/licenses/>.
00029 
00030     Copyright 2010 Graz University of Technology
00031     Contact: TiA@tobi-project.org
00032 */
00033 
00038 // STL
00039 #include <iostream>
00040 #include <sstream>
00041 #include <vector>
00042 #include <algorithm>
00043 
00044 // Boost
00045 #include <boost/date_time/posix_time/posix_time.hpp>
00046 #include <boost/lexical_cast.hpp>
00047 #include <boost/bind.hpp>
00048 #include <boost/asio.hpp>
00049 
00050 // TICPP
00051 #include "ticpp/ticpp.h"
00052 
00053 // local
00054 #include "tia/data_packet_interface.h"
00055 #include "tia/tia_server.h"
00056 
00057 #include "tia-private/network/control_connection_server.h"
00058 #include "tia-private/network/tcp_data_server.h"
00059 #include "tia-private/network/udp_data_server.h"
00060 #include "tia-private/newtia/server_impl/tia_server_state_server_impl.h"
00061 #include "tia-private/newtia/network_impl/boost_tcp_server_socket_impl.h"
00062 #include "tia-private/newtia/server_impl/control_connection_server_2_impl.h"
00063 
00064 #include "tia-private/newtia/server_impl/fusty_data_server_impl.h"
00065 #include "tia-private/newtia/fusty_hardware_interface_impl.h"
00066 
00067 #include "tia-private/datapacket/data_packet_impl.h"
00068 #include "tia-private/datapacket/data_packet_3_impl.h"
00069 
00070 #ifdef TIMING_TEST
00071   #include "LptTools/LptTools.h"
00072   #define LPT1  0
00073   #define LPT2  1
00074 #endif
00075 
00076 namespace tia
00077 {
00078 using boost::uint64_t;
00079 using boost::uint32_t;
00080 using boost::uint16_t;
00081 using boost::int16_t;
00082 using boost::int64_t;
00083 using boost::lexical_cast;
00084 using namespace std;
00085 
00086 //-----------------------------------------------------------------------------
00087 
00088 TiAServer::TiAServer(boost::asio::io_service& io_service, bool new_tia)
00089   : io_service_(io_service),
00090 //  config_(0),
00091   tcp_data_server_(0),
00092   udp_data_server_(0),
00093   control_connection_server_(0),
00094   server_state_server_(0),
00095   new_tia_ (new_tia),
00096   control_connection_server_2_(0),
00097   data_server_(0), hardware_interface_(0)
00098 
00099 {
00100 
00101   data_packet_impl_.reset( new DataPacketImpl );
00102   work_data_packet_impl_ = new DataPacketImpl;
00103 
00104   data_packet_3_impl_.reset( new DataPacket3Impl );
00105   work_data_packet_3_impl_ = new DataPacket3Impl;
00106 
00107   #ifdef TIMING_TEST
00108     timestamp_ = boost::posix_time::microsec_clock::local_time();
00109     counter_ = 0;
00110     t_max_last_ = boost::posix_time::time_duration (0, 0, 0);
00111     t_max_total_ = boost::posix_time::time_duration (0, 0, 0);
00112     t_min_last_ = boost::posix_time::time_duration (10, 0, 0);
00113     t_min_total_ = boost::posix_time::time_duration (10, 0, 0);
00114     t_var_ = 0;
00115     lpt_flag_ = 0;
00116 
00117       if(!LptDriverInstall())
00118       {
00119         cerr << "Installing LptTools lpt driver failed (do you have access rights for the lpt-port?)." << endl;
00120         throw std::runtime_error("Error installing LptTools lpt driver!");
00121       }
00122 
00123       if(!LptInit())
00124       {
00125         cerr << "Initializing lpt driver failed (do you have access rights for the lpt-port?)." << endl;
00126         throw std::runtime_error("Error initializing lpt driver!");
00127       }
00128   #endif
00129 }
00130 
00131 //-----------------------------------------------------------------------------
00132 
00133 TiAServer::~TiAServer()
00134 {
00135   if(tcp_data_server_)
00136     delete tcp_data_server_;
00137 
00138   if(udp_data_server_)
00139     delete udp_data_server_;
00140 
00141   if(control_connection_server_)
00142     delete control_connection_server_;
00143 
00144   if(control_connection_server_2_)
00145     delete control_connection_server_2_;
00146 
00147   if(server_state_server_)
00148     delete server_state_server_;
00149 
00150   if(data_server_)
00151     delete data_server_;
00152 
00153   if(hardware_interface_)
00154     delete hardware_interface_;
00155 
00156   data_packet_ = 0;
00157   if(work_data_packet_impl_)
00158     delete work_data_packet_impl_;
00159   if(work_data_packet_3_impl_)
00160     delete work_data_packet_3_impl_;
00161 
00162   #ifdef TIMING_TEST
00163     LptExit();
00164   #endif
00165 }
00166 
00167 //-----------------------------------------------------------------------------
00168 
00169 void TiAServer::initialize(std::map<std::string,std::string>& subject_info_map,
00170                               std::map<std::string,std::string>& server_settings)
00171 {
00172   server_settings_ = server_settings;
00173 
00174   createSubjectInfo(subject_info_map);
00175   createSignalInfo();
00176 
00177   uint16_t ctl_port = lexical_cast<uint16_t>(server_settings_[Constants::ss_ctl_port]);
00178 
00179   tcp_data_server_ = new TCPDataServer(io_service_);
00180 
00181   uint16_t udp_port = lexical_cast<uint16_t>(server_settings_[Constants::ss_udp_port]);
00182   udp_data_server_ = new UDPDataServer(io_service_);
00183   udp_data_server_->setDestination(server_settings_[Constants::ss_udp_bc_addr], udp_port);
00184 
00185   if (new_tia_)
00186   {
00187     hardware_interface_ = new tia::FustyHardwareInterfaceImpl(subject_info_, signal_info_);
00188 
00189     boost::shared_ptr<tia::TCPServerSocket>
00190         server_state_server_socket(new tia::BoostTCPServerSocketImpl (io_service_));
00191     server_state_server_ = new tia::TiAServerStateServerImpl(server_state_server_socket);
00192 
00193     data_server_ = new tia::FustyDataServerImpl(*tcp_data_server_, *udp_data_server_);
00194 
00195 
00196     boost::shared_ptr<tia::TCPServerSocket>
00197         control_connection_server2_socket(new tia::BoostTCPServerSocketImpl (io_service_));
00198     control_connection_server_2_ =
00199         new tia::ControlConnectionServer2Impl(control_connection_server2_socket, ctl_port,
00200                    data_server_, server_state_server_, hardware_interface_);
00201 
00202     data_packet_ = data_packet_3_impl_.get();
00203     work_data_packet_ = work_data_packet_3_impl_;
00204   }
00205   else
00206   {
00207     control_connection_server_ = new ControlConnectionServer(subject_info_map,
00208                                                              io_service_, *this);
00209     control_connection_server_->bind(ctl_port);
00210     control_connection_server_->listen();
00211 
00212     data_packet_ = data_packet_impl_.get();
00213     work_data_packet_ = work_data_packet_impl_;
00214   }
00215 }
00216 
00217 //-----------------------------------------------------------------------------
00218 
00219 DataPacket* TiAServer::getEmptyDataPacket()
00220 {
00221   return data_packet_;
00222 }
00223 
00224 //-----------------------------------------------------------------------------
00225 
00226 DataPacketImpl  TiAServer::makeDataPacketCopy(DataPacketImpl& packet)
00227 {
00228   DataPacketImpl p(packet);
00229   return p;
00230 }
00231 
00232 //-----------------------------------------------------------------------------
00233 
00234 DataPacket3Impl  TiAServer::makeDataPacketCopy(DataPacket3Impl& packet)
00235 {
00236   DataPacket3Impl p(packet);
00237   return p;
00238 }
00239 
00240 //-----------------------------------------------------------------------------
00241 
00242 void TiAServer::sendDataPacket()
00243 {
00244   if(new_tia_)
00245     *work_data_packet_3_impl_ = *(data_packet_3_impl_.get() );
00246   else
00247     *work_data_packet_impl_ = *(data_packet_impl_.get() );
00248 
00249   tcp_data_server_->sendDataPacket( *work_data_packet_ );
00250   udp_data_server_->sendDataPacket( *work_data_packet_ );
00251 
00252   work_data_packet_->reset();
00253 
00254   #ifdef TIMING_TEST
00255     timestamp_ = boost::posix_time::microsec_clock::local_time();
00256     int port_state = LptPortIn(LPT1,0);
00257     if(!lpt_flag_)
00258     {
00259       lpt_flag_ = 1;
00260       LptPortOut(LPT1, 0, port_state | 0x02);
00261     }
00262     else
00263     {
00264       lpt_flag_ = 0;
00265       LptPortOut(LPT1, 0, port_state & ~0x02);
00266     }
00267     counter_++;
00268 
00269     diff_ = timestamp_ - data_packet_->getTimestamp();
00270     t_diffs_.push_back (diff_);
00271     t_min_total_ = min (t_min_total_, diff_);
00272     t_max_total_ = max (t_max_total_, diff_);
00273     t_min_last_ = min (t_min_last_, diff_);
00274     t_max_last_ = max (t_max_last_, diff_);
00275 
00276     t_mean_ = (t_mean_ + diff_)/2;
00277     t_var_  = (t_var_ +
00278     ( (diff_.total_microseconds() - t_mean_.total_microseconds() )*
00279     (diff_.total_microseconds() - t_mean_.total_microseconds() )  ) )/2;
00280 
00281     if( (master_samplingrate_/master_blocksize_ < 1) ||
00282        (counter_%((master_samplingrate_/master_blocksize_) *2) == 0) )
00283     {
00284       sort (t_diffs_.begin(), t_diffs_.end());
00285 
00286       cout << "Packet Nr.: " << counter_ << ";  ";
00287       cout << "Timing (microsecs) -- mean: " << t_mean_.total_microseconds() << ", ";
00288       cout << "variance: " << t_var_;
00289       cout << ", min: " << t_min_last_.total_microseconds() << " (total: "<<  t_min_total_.total_microseconds() <<"), ";
00290       cout << "max: "<< t_max_last_.total_microseconds() << " (total: "<< t_max_total_.total_microseconds() << "), ";
00291       cout << "median: " << t_diffs_[t_diffs_.size() / 2].total_microseconds () << endl;
00292       t_diffs_.clear();
00293       t_min_last_ = boost::posix_time::time_duration (10, 0, 0);
00294       t_max_last_ = boost::posix_time::time_duration (0, 0, 0);
00295     }
00296 
00297   #endif
00298 
00299 }
00300 
00301 //-----------------------------------------------------------------------------
00302 
00303 void TiAServer::createSubjectInfo(std::map<std::string,std::string> subject_map)
00304 {
00305   subject_info_.setId(subject_map["id"]);
00306   subject_info_.setFirstName(subject_map["first_name"]);
00307   subject_info_.setSurname(subject_map["surname"]);
00308   subject_info_.setBirthday(subject_map["birthday"]);
00309   subject_info_.setMedication(subject_map["medication"]);
00310 
00311   std::string value = subject_map["sex"];
00312   if (value == "m")
00313     subject_info_.setSex(SubjectInfo::Male);
00314   else if (value == "f")
00315     subject_info_.setSex(SubjectInfo::Female);
00316 
00317   value = subject_map["handedness"];
00318   if (value == "r")
00319     subject_info_.setHandedness(SubjectInfo::RightHanded);
00320   else if (value == "l")
00321     subject_info_.setHandedness(SubjectInfo::LeftHanded);
00322 
00323   value = subject_map["glasses"];
00324   if (value == "y")
00325     subject_info_.setShortInfo(SubjectInfo::Glasses, SubjectInfo::Yes);
00326   else if (value == "n")
00327     subject_info_.setShortInfo(SubjectInfo::Glasses, SubjectInfo::No);
00328   else
00329     subject_info_.setShortInfo(SubjectInfo::Glasses, SubjectInfo::Unknown);
00330 
00331   value = subject_map["smoker"];
00332   if (value == "y")
00333     subject_info_.setShortInfo(SubjectInfo::Smoking, SubjectInfo::Yes);
00334   else if (value == "n")
00335     subject_info_.setShortInfo(SubjectInfo::Smoking, SubjectInfo::No);
00336   else
00337     subject_info_.setShortInfo(SubjectInfo::Smoking, SubjectInfo::Unknown);
00338 }
00339 
00340 //-----------------------------------------------------------------------------
00341 
00342 void TiAServer::createSignalInfo()
00343 {
00344   const std::vector<uint32_t>& sig_types       = sig_types_;
00345   const std::vector<uint16_t>& blocksizes      = blocksizes_;
00346   const std::vector<uint32_t>& fs_per_sig_type = fs_per_sig_type_;
00347 
00348   const std::map<uint32_t, std::vector<std::string> >& channel_map = channels_per_sig_type_;
00349 
00350   assert(sig_types.size() == blocksizes.size() && sig_types.size() == fs_per_sig_type.size());
00351 
00352   cout << endl;
00353   cout << " Sent Signal Types: (ordered)" << endl;
00354 
00355   for (vector<uint32_t>::size_type index = 0; index < sig_types.size(); ++index)
00356   {
00357     Signal signal;
00358 
00359     uint32_t sig_num_type = sig_types[index];
00360     std::string sig_str_type = Constants().getSignalName(sig_num_type);
00361     signal.setType(sig_str_type);
00362     cout << "   ... Signal type " << sig_str_type << endl;
00363 
00364     uint16_t block_size = blocksizes[index];
00365     signal.setBlockSize(block_size);
00366 
00367     uint32_t fs = fs_per_sig_type[index];
00368     signal.setSamplingRate(fs);
00369 
00370     std::map<uint32_t, std::vector<std::string> >::const_iterator it_channel_map =
00371       channel_map.find(sig_num_type);
00372 
00373     if (it_channel_map != channel_map.end())
00374     {
00375       const std::vector<std::string>& channel_names = (*it_channel_map).second;
00376       std::vector<std::string>::const_iterator it_channels = channel_names.begin();
00377       std::vector<std::string>::const_iterator end_channels = channel_names.end();
00378       for (; it_channels != end_channels; ++it_channels)
00379       {
00380         Channel channel;
00381         channel.setId(*it_channels);
00382         signal.channels().push_back(channel);
00383       }
00384     }
00385 
00386     signal_info_.signals().insert(make_pair(sig_str_type,signal));
00387   }
00388 
00389   signal_info_.setMasterBlockSize(master_blocksize_);
00390   signal_info_.setMasterSamplingRate(master_samplingrate_);
00391 }
00392 
00393 //-----------------------------------------------------------------------------
00394 
00395 
00396 } // Namespace tobiss
00397 
 All Data Structures Files Functions Variables Typedefs Enumerations