TOBI Interface A  0.1
/home/breidi/Dropbox/libtia/src/tia/network/control_connection_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 
00041 // Boost
00042 #include <boost/thread.hpp>
00043 #include <boost/bind.hpp>
00044 #include <boost/iostreams/stream.hpp>
00045 
00046 // local
00047 #include "tia/constants.h"
00048 #include "tia/tia_server.h"
00049 
00050 #include "tia-private/network/control_connection.h"
00051 #include "tia-private/network/control_connection_server.h"
00052 #include "tia-private/network/tcp_data_server.h"
00053 #include "tia-private/network/udp_data_server.h"
00054 
00055 //#include "tia-private/newtia/network_impl/boost_tcp_socket_impl.h"
00056 //#include "tia-private/newtia/server_impl/control_connection_2.h"
00057 //#include "tia-private/newtia/server_impl/fusty_data_server_impl.h"
00058 //#include "tia-private/newtia/fusty_hardware_interface_impl.h"
00059 
00060 namespace tia
00061 {
00062 
00063 using std::vector;
00064 using std::string;
00065 using std::map;
00066 using std::cout;
00067 using std::endl;
00068 
00069 using boost::uint16_t;
00070 using boost::uint32_t;
00071 
00072 static const int SECONDS_TO_RE_CHECK_CONNECTIONS = 1;
00073 
00074 //-----------------------------------------------------------------------------
00075 
00076 ControlConnectionServer::ControlConnectionServer(std::map<std::string,std::string> subject_info,
00077                                                  boost::asio::io_service& io_service,
00078                                                  TiAServer& server)
00079   : TCPServer(io_service),
00080   server_(server),
00081   subject_info_(0),
00082   signal_info_(0)
00083 //  data_server_ (0),
00084 //  hardware_interface_ (0),
00085 //  check_connections_timer_ (io_service)
00086 {
00087   signal_info_ = new SignalInfo;
00088   subject_info_ = new SubjectInfo;
00089 //  hardware_interface_ = new tia::FustyHardwareInterfaceImpl (*this);
00090 
00091   createSubjectInfo(subject_info);
00092   createSignalInfo();
00093 }
00094 
00095 //-----------------------------------------------------------------------------
00096 
00097 ControlConnectionServer::~ControlConnectionServer()
00098 {
00099   delete signal_info_;
00100   delete subject_info_;
00101 //  delete hardware_interface_;
00102 //  delete data_server_;
00103 //  for (std::map<unsigned, tia::ControlConnection2*>::iterator iter = new_connections_.begin();
00104 //       iter != new_connections_.end(); ++iter)
00105 //  {
00106 //    delete iter->second;
00107 //  }
00108 //  for (std::map<unsigned, tia::Socket*>::iterator iter = new_sockets_.begin();
00109 //       iter != new_sockets_.end(); ++iter)
00110 //  {
00111 //    delete iter->second;
00112 //  }
00113 }
00114 
00116 
00117 TCPDataServer* ControlConnectionServer::tcpDataServer() const
00118 {
00119   return server_.tcp_data_server_;
00120 }
00121 
00122 //-----------------------------------------------------------------------------
00123 
00124 UDPDataServer* ControlConnectionServer::udpDataServer() const
00125 {
00126   return server_.udp_data_server_;
00127 }
00128 
00129 //-----------------------------------------------------------------------------
00130 
00131 void ControlConnectionServer::getConfig(ConfigMsg& config)
00132 {
00133   config.subject_info = *subject_info_;
00134   config.signal_info  = *signal_info_;
00135 }
00136 
00137 //-----------------------------------------------------------------------------
00138 
00139 void ControlConnectionServer::createSubjectInfo(std::map<std::string,std::string> subject_map)
00140 {
00141 //  map<string,string> subject_map = server_.config_->parseSubject();
00142 
00143   subject_info_->setId(subject_map["id"]);
00144   subject_info_->setFirstName(subject_map["first_name"]);
00145   subject_info_->setSurname(subject_map["surname"]);
00146   subject_info_->setBirthday(subject_map["birthday"]);
00147   subject_info_->setMedication(subject_map["medication"]);
00148 
00149   std::string value = subject_map["sex"];
00150   if (value == "m")
00151     subject_info_->setSex(SubjectInfo::Male);
00152   else if (value == "f")
00153     subject_info_->setSex(SubjectInfo::Female);
00154 
00155   value = subject_map["handedness"];
00156   if (value == "r")
00157     subject_info_->setHandedness(SubjectInfo::RightHanded);
00158   else if (value == "l")
00159     subject_info_->setHandedness(SubjectInfo::LeftHanded);
00160 
00161   value = subject_map["glasses"];
00162   if (value == "y")
00163     subject_info_->setShortInfo(SubjectInfo::Glasses, SubjectInfo::Yes);
00164   else if (value == "n")
00165     subject_info_->setShortInfo(SubjectInfo::Glasses, SubjectInfo::No);
00166   else
00167     subject_info_->setShortInfo(SubjectInfo::Glasses, SubjectInfo::Unknown);
00168 
00169   value = subject_map["smoker"];
00170   if (value == "y")
00171     subject_info_->setShortInfo(SubjectInfo::Smoking, SubjectInfo::Yes);
00172   else if (value == "n")
00173     subject_info_->setShortInfo(SubjectInfo::Smoking, SubjectInfo::No);
00174   else
00175     subject_info_->setShortInfo(SubjectInfo::Smoking, SubjectInfo::Unknown);
00176 }
00177 
00178 //-----------------------------------------------------------------------------
00179 
00180 void ControlConnectionServer::createSignalInfo()
00181 {
00182   const std::vector<uint32_t>& sig_types       = server_.sig_types_;
00183   const std::vector<uint16_t>& blocksizes      = server_.blocksizes_;
00184   const std::vector<uint32_t>& fs_per_sig_type = server_.fs_per_sig_type_;
00185 
00186   const std::map<uint32_t, std::vector<std::string> >& channel_map = server_.channels_per_sig_type_;
00187 
00188   assert(sig_types.size() == blocksizes.size() && sig_types.size() == fs_per_sig_type.size());
00189 
00190   //cout << endl;
00191   //cout << " Sent Signal Types: (ordered)" << endl;
00192 
00193   for (vector<uint32_t>::size_type index = 0; index < sig_types.size(); ++index)
00194   {
00195     Signal signal;
00196 
00197     uint32_t sig_num_type = sig_types[index];
00198     std::string sig_str_type = Constants().getSignalName(sig_num_type);
00199     signal.setType(sig_str_type);
00200     cout << "   ... Signal type " << sig_str_type << endl;
00201 
00202     uint16_t block_size = blocksizes[index];
00203     signal.setBlockSize(block_size);
00204 
00205     uint32_t fs = fs_per_sig_type[index];
00206     signal.setSamplingRate(fs);
00207 
00208     std::map<uint32_t, std::vector<std::string> >::const_iterator it_channel_map =
00209       channel_map.find(sig_num_type);
00210 
00211     if (it_channel_map != channel_map.end())
00212     {
00213       const std::vector<std::string>& channel_names = (*it_channel_map).second;
00214       std::vector<std::string>::const_iterator it_channels = channel_names.begin();
00215       std::vector<std::string>::const_iterator end_channels = channel_names.end();
00216       for (; it_channels != end_channels; ++it_channels)
00217       {
00218         Channel channel;
00219         channel.setId(*it_channels);
00220         signal.channels().push_back(channel);
00221       }
00222     }
00223 
00224     signal_info_->signals().insert(make_pair(sig_str_type, signal));
00225   }
00226 
00227   signal_info_->setMasterBlockSize(server_.master_blocksize_);
00228   signal_info_->setMasterSamplingRate(server_.master_samplingrate_);
00229 }
00230 
00231 
00232 //-----------------------------------------------------------------------------
00233 
00234 void ControlConnectionServer::handleAccept(const TCPConnection::pointer& new_connection,
00235       const boost::system::error_code& error)
00236 {
00237   if (error)
00238   {
00239     // TODO: error handling
00240     return;
00241   }
00242 
00243 //  if (!data_server_)
00244 //    data_server_ = new tia::FustyDataServerImpl (*(server_.tcp_data_server_), *(server_.udp_data_server_));
00245 
00246 //  {
00247 //    boost::system::error_code err;
00248 //    checkConnections (err);
00249 //  }
00250 
00251   // lock the connection list
00252   boost::unique_lock<boost::mutex> lock(mutex_);
00253 
00254   unsigned short local_port = new_connection->socket().local_endpoint().port();
00255 
00256 //  if (server_.new_tia_)
00257 //  {
00258 //    tia::Socket* new_socket = new tia::BoostTCPSocketImpl (new_connection);
00259 //    tia::ControlConnection2* new_control_connection = new tia::ControlConnection2 (*new_socket, *data_server_, *hardware_interface_, *(server_.server_state_server_));
00260 //    unsigned id = new_control_connection->getId();
00261 //    new_connections_[id] = new_control_connection;
00262 //    new_sockets_[id] = new_socket;
00263 //    cout << " Client " << id <<" @" << new_connection->socket().remote_endpoint() << " has connected. (local: "  << new_connection->socket().local_endpoint() << ")"<< endl;
00264 //    cout << " # Connected clients: " << new_connections_.size () << endl;
00265 //    new_control_connection->asyncStart ();
00266 //  }
00267 //  else
00268 //  {
00269     ControlConnection::ConnectionID id = make_pair(local_port, TCPConnection::endpointToString(
00270                                 new_connection->socket().remote_endpoint()));
00271 
00272     ControlConnection::pointer connection = ControlConnection::create(io_service_, id,
00273                                                                     *this, new_connection);
00274 
00275     cout << " Client @" << id.second << " has connected." <<  endl;
00276 
00277 
00278     connections_.insert(make_pair(id, connection)).first;
00279 
00280     cout << " # Connected clients: " << connections_.size() << endl;
00281 
00282     connection->start();
00283 //  }
00284   startAccept ();
00285 }
00286 
00287 //-----------------------------------------------------------------------------
00288 
00289 void ControlConnectionServer::clientHasDisconnected(const ControlConnection::ConnectionID& id)
00290 {
00291   boost::unique_lock<boost::mutex> lock(mutex_);
00292 
00293   cout << " Connection to client @" << id.second << " has been closed." << endl;
00294   connections_.erase(id);
00295 
00296   cout << " # Connected clients: " << connections_.size() << endl;
00297 }
00298 
00299 //-----------------------------------------------------------------------------
00300 //void ControlConnectionServer::checkConnections (boost::system::error_code error)
00301 //{
00302 //  if (error)
00303 //      return;
00304 //  boost::unique_lock<boost::mutex> lock(mutex_);
00305 //  #ifdef DEBUG
00306 //    static unsigned call_counter = 0;
00307 //    cout << " <- check connection "<< ++call_counter <<" -> " << endl;
00308 //  #endif
00309 //  std::list<unsigned> to_be_removed;
00310 //  for (std::map<unsigned, tia::ControlConnection2*>::iterator iter = new_connections_.begin();
00311 //       iter != new_connections_.end(); ++iter)
00312 //  {
00313 //    if (!(iter->second->isRunning()))
00314 //      to_be_removed.push_back (iter->first);
00315 //  }
00316 
00317 //  for (std::list<unsigned>::iterator iter = to_be_removed.begin();
00318 //       iter != to_be_removed.end(); ++iter)
00319 //  {
00320 //    cout << "  -- Removing connection to: " << new_sockets_[*iter]->getRemoteEndPointAsString() << endl;
00321 //    delete new_connections_[*iter];
00322 //    delete new_sockets_[*iter];
00323 //    new_connections_.erase (*iter);
00324 //    new_sockets_.erase (*iter);
00325 //  }
00326 //  if (to_be_removed.size())
00327 //      cout << " # Connected clients: " << new_connections_.size() << endl;
00328 
00329 //  check_connections_timer_.cancel ();
00330 //  check_connections_timer_.expires_from_now (boost::posix_time::seconds (SECONDS_TO_RE_CHECK_CONNECTIONS));
00331 //  check_connections_timer_.async_wait(boost::bind(&ControlConnectionServer::checkConnections, this, boost::asio::placeholders::error));
00332 //}
00333 
00334 
00335 //-----------------------------------------------------------------------------
00336 
00337 } // Namespace tobiss
00338 
00339 // End Of File
 All Data Structures Files Functions Variables Typedefs Enumerations