|
TOBI Interface A
0.1
|
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