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 00039 // STL 00040 #include <iostream> 00041 #include <algorithm> 00042 00043 // Boost 00044 #include <boost/asio.hpp> 00045 #include <boost/bind.hpp> 00046 #include <boost/thread.hpp> 00047 #include <boost/cstdint.hpp> 00048 00049 // local 00050 #include "tia/data_packet_interface.h" 00051 #include "tia/tia_client.h" 00052 #include "tia/ssconfig.h" 00053 #include "tia/defines.h" 00054 00055 using namespace std; 00056 00057 //----------------------------------------------------------------------------- 00058 00059 class TiAClientDataReader 00060 { 00061 public: 00062 TiAClientDataReader(tia::TiAClient& client, boost::mutex& mutex, boost::condition_variable& cond) : 00063 client_(client), packet_(0), mutex_(mutex), cond_(cond), 00064 running_(1), 00065 timestamp_(boost::posix_time::microsec_clock::local_time()), 00066 t_min_total_ (10, 0, 0), 00067 t_max_total_ (0, 0, 0), 00068 t_min_last_ (10, 0, 0), 00069 t_max_last_ (0, 0, 0), 00070 t_var_(0) 00071 { 00072 packet_ = client_.getEmptyDataPacket(); 00073 } 00074 00075 void stop() 00076 { 00077 running_ = 0; 00078 } 00079 00080 void readData() 00081 { 00082 unsigned int counter = 0; 00083 00084 boost::uint64_t sample_nr = 0; 00085 boost::uint64_t packet_nr = 0; 00086 00087 boost::uint64_t sample_nr_old = 0; 00088 boost::uint64_t packet_nr_old = 0; 00089 00090 while(running_) 00091 { 00092 { 00093 00094 boost::unique_lock<boost::mutex> lock(mutex_); 00095 00096 vector<double> v; 00097 00098 if (!client_.receiving()) 00099 { 00100 cond_.wait(lock); 00101 } 00102 00103 if(running_ && client_.receiving()) 00104 { 00105 try { 00106 client_.getDataPacket(*packet_); 00107 00108 if(packet_->hasFlag(SIG_MOUSE)) 00109 { 00110 v = packet_->getSingleDataBlock(SIG_MOUSE); 00111 cout << "mousepos: "<< packet_->getSingleDataBlock(SIG_MOUSE)[1]<<","<<packet_->getSingleDataBlock(SIG_MOUSE)[2]; 00112 } 00113 00114 if(packet_->hasFlag(SIG_MBUTTON)) 00115 { 00116 v = packet_->getSingleDataBlock(SIG_MBUTTON); 00117 cout<<" ... buttons: "<<packet_->getSingleDataBlock(SIG_MBUTTON)[1]<<packet_->getSingleDataBlock(SIG_MBUTTON)[2]<<packet_->getSingleDataBlock(SIG_MBUTTON)[3]<<endl; 00118 } 00119 if( ((client_.config().signal_info.masterSamplingRate()/client_.config().signal_info.masterBlockSize()) < 1) || 00120 (counter%( 00121 (client_.config().signal_info.masterSamplingRate()/client_.config().signal_info.masterBlockSize()) *2 ) == 0) ) 00122 { 00123 std::cout << " -- Nr:" << packet_->getPacketID() << std::endl; 00124 client_.requestConfig(); 00125 cerr << " -- got config ... " << endl; 00126 } 00127 00128 sample_nr_old = sample_nr; 00129 packet_nr_old = packet_nr; 00130 00131 sample_nr = packet_->getPacketID(); 00132 packet_nr = packet_->getConnectionPacketNr(); 00133 00134 if( (sample_nr - sample_nr_old) > 1) 00135 { 00136 cerr << "SampleNr difference: " << (sample_nr - sample_nr_old); 00137 cerr << " -- @Sample: " << sample_nr << endl; 00138 } 00139 00140 if( (packet_nr - packet_nr_old) > 1) 00141 { 00142 cerr << "PacketNr difference: " << (packet_nr - packet_nr_old); 00143 cerr << " -- @Packet: " << packet_nr << endl; 00144 } 00145 00146 } 00147 catch (std::exception& e) 00148 { 00149 00150 cerr << "*** " << e.what() << endl; 00151 break; 00152 } 00153 00154 #ifdef TIMING_TEST 00155 timestamp_ = boost::posix_time::microsec_clock::local_time(); 00156 diff_ = timestamp_ - packet_->getTimestamp(); 00157 00158 t_diffs_.push_back (diff_); 00159 t_min_total_ = min (t_min_total_, diff_); 00160 t_max_total_ = max (t_max_total_, diff_); 00161 t_min_last_ = min (t_min_last_, diff_); 00162 t_max_last_ = max (t_max_last_, diff_); 00163 00164 t_mean_ = (t_mean_ + diff_)/2; 00165 t_var_ = (t_var_ + 00166 ( (diff_.total_microseconds() - t_mean_.total_microseconds() )* 00167 (diff_.total_microseconds() - t_mean_.total_microseconds() ) ) )/2; 00168 #endif 00169 } 00170 else 00171 break; 00172 00173 counter++; 00174 #ifdef TIMING_TEST 00175 if( ((client_.config().signal_info.masterSamplingRate()/client_.config().signal_info.masterBlockSize()) < 1) || 00176 (counter%( 00177 (client_.config().signal_info.masterSamplingRate()/client_.config().signal_info.masterBlockSize()) *2 ) == 0) ) 00178 { 00179 sort (t_diffs_.begin(), t_diffs_.end()); 00180 cout << "Packet Nr.: " << counter << "; "; 00181 cout << "Timing (microsecs) -- mean: " << t_mean_.total_microseconds() << ", "; 00182 cout << "variance: " << t_var_; 00183 cout << ", min: " << t_min_last_.total_microseconds() << " (total: "<< t_min_total_.total_microseconds() <<"), "; 00184 cout << "max: "<< t_max_last_.total_microseconds() << " (total: "<< t_max_total_.total_microseconds() << "), "; 00185 cout << "median: " << t_diffs_[t_diffs_.size() / 2].total_microseconds () << endl; 00186 t_diffs_.clear(); 00187 t_min_last_ = boost::posix_time::time_duration (10, 0, 0); 00188 t_max_last_ = boost::posix_time::time_duration (0, 0, 0); 00189 } 00190 #endif 00191 } 00192 } 00193 } 00194 private: 00195 tia::TiAClient& client_; 00196 tia::DataPacket* packet_; 00197 boost::mutex& mutex_; 00198 boost::condition_variable& cond_; 00199 bool running_; 00200 boost::posix_time::ptime timestamp_; 00201 boost::posix_time::time_duration diff_; 00202 boost::posix_time::time_duration t_mean_; 00203 boost::posix_time::time_duration t_min_total_; 00204 boost::posix_time::time_duration t_max_total_; 00205 boost::posix_time::time_duration t_min_last_; 00206 boost::posix_time::time_duration t_max_last_; 00207 vector<boost::posix_time::time_duration> t_diffs_; 00208 boost::int64_t t_var_; 00209 // boost::posix_time::time_duration t_var_; 00210 }; 00211 00212 00213 //----------------------------------------------------------------------------- 00214 00215 int main(int argc, const char* argv[]) 00216 { 00217 string srv_addr = "127.0.0.1"; 00218 boost::uint16_t srv_port = 9000; 00219 00220 bool use_new_tia = true; 00221 00222 if(argc == 1) 00223 { 00224 cout << "Using default server " << srv_addr << ":" << srv_port << endl; 00225 } 00226 else if(argc == 2) 00227 { 00228 string param (argv[1]); 00229 if (param == "-o") 00230 use_new_tia = false; 00231 } 00232 else if(argc == 3) 00233 { 00234 srv_addr = argv[1]; 00235 stringstream conv(argv[2]); 00236 conv >> srv_port; 00237 cout << "Using server " << srv_addr << ":" << srv_port << endl; 00238 } 00239 else if(argc == 4) 00240 { 00241 string param (argv[1]); 00242 if (param == "-o") 00243 use_new_tia = false; 00244 00245 srv_addr = argv[2]; 00246 stringstream conv(argv[3]); 00247 conv >> srv_port; 00248 cout << "Using server " << srv_addr << ":" << srv_port << endl; 00249 } 00250 else 00251 { 00252 cout << "Wrong number of arguments given: " << argc-1 << endl; 00253 cout << " - Usage: " << argv[0] << " signalserver-ip port" << endl; 00254 return(-1); 00255 } 00256 00257 tia::TiAClient client(use_new_tia); 00258 00259 try 00260 { 00261 client.connect(srv_addr, srv_port); 00262 client.requestConfig(); 00263 } 00264 catch(std::exception& e) 00265 { 00266 cerr << e.what() << endl; 00267 return 1; 00268 } 00269 00270 boost::mutex mutex; 00271 boost::condition_variable cond; 00272 00273 TiAClientDataReader reader(client, mutex, cond); 00274 boost::thread reader_thread(boost::bind(&TiAClientDataReader::readData, &reader)); 00275 00276 #ifdef WIN32 00277 SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); 00278 SetPriorityClass(reader_thread.native_handle(), REALTIME_PRIORITY_CLASS); 00279 SetThreadPriority(reader_thread.native_handle(), THREAD_PRIORITY_TIME_CRITICAL ); 00280 #endif 00281 00282 map<string, string> known_commands; 00283 known_commands.insert(make_pair("config", "Requests the config from server.")); 00284 known_commands.insert(make_pair("starttcp", "Starts the data transmission using tcp")); 00285 known_commands.insert(make_pair("startudp", "Starts the data transmission using udp broadcast")); 00286 known_commands.insert(make_pair("stop", "Stops the data transmission")); 00287 known_commands.insert(make_pair("q", "Quits the client.")); 00288 known_commands.insert(make_pair("help", "Prints this help text.")); 00289 known_commands.insert(make_pair("state", "Get the data receiving state of the client")); 00290 00291 string command; 00292 cout << endl << ">>"; 00293 00294 while(cin >> command) 00295 { 00296 { 00297 map<string, string>::const_iterator it = known_commands.find(command); 00298 if (it == known_commands.end()) 00299 { 00300 cout << "Type 'help' to get description of supported commands" << endl; 00301 cout << endl << ">>"; 00302 continue; 00303 } 00304 } 00305 00306 // boost::unique_lock<boost::mutex> lock(mutex); 00307 00308 if(command == "q") 00309 { 00310 break; 00311 } 00312 00313 if (command == "config") 00314 { 00315 try { 00316 client.requestConfig(); 00317 } 00318 catch (std::exception& e) 00319 { 00320 cerr << "Requesting config failed -- Error:" 00321 << "--> " << e.what() << endl; 00322 } 00323 } 00324 else if (command == "state") 00325 { 00326 cout << "Client state: "; 00327 if (client.receiving()) 00328 cout << "receiving data" << endl; 00329 else 00330 cout << "not receiving data" << endl; 00331 } 00332 else if (command == "starttcp" || command == "startudp") 00333 { 00334 bool udp = command == "startudp"; 00335 00336 cout << "Start Receiving ..." << endl; 00337 00338 try { 00339 client.startReceiving(udp); 00340 if (!client.receiving()) 00341 cerr << "Client did not block until data receiving..." << endl; 00342 } 00343 catch (std::exception& e) 00344 { 00345 cerr << "Start Receiving failed -- Error:" << endl 00346 << "--> " << e.what() << endl; 00347 } 00348 00349 cond.notify_one(); 00350 } 00351 else if (command == "stop") 00352 { 00353 cout << "Stop Receiving ..." << endl; 00354 00355 //boost::unique_lock<boost::mutex> lock(mutex); 00356 00357 try { 00358 client.stopReceiving(); 00359 } 00360 catch (std::exception& e) 00361 { 00362 cerr << "Stop Receiving failed -- Error:" << endl 00363 << "--> " << e.what() << endl; 00364 } 00365 } 00366 else if (command == "help") 00367 { 00368 map<string, string>::const_iterator it = known_commands.begin(); 00369 map<string, string>::const_iterator end = known_commands.end(); 00370 for (; it != end; ++it) 00371 { 00372 const string& command_name = (*it).first; 00373 string spacing; 00374 spacing.assign(20 - command_name.size(), '.'); 00375 cout << (*it).first << spacing << (*it).second << endl; 00376 } 00377 } 00378 00379 cond.notify_one(); 00380 cout << endl << ">>"; 00381 } 00382 00383 cout << "Terminating ..." << endl; 00384 reader.stop(); 00385 cond.notify_all(); 00386 reader_thread.join(); 00387 00388 try { 00389 client.stopReceiving(); 00390 } 00391 catch (std::exception& e) 00392 { 00393 cerr << "Stop Receiving failed -- Error:" 00394 << "--> " << e.what() << endl; 00395 } 00396 00397 return(0); 00398 } 00399 00400 //-----------------------------------------------------------------------------