|
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 00038 #include <sstream> 00039 #include <stdexcept> 00040 00041 #include "tia/defines.h" 00042 00043 #include "tia-private/datapacket/data_packet_3_impl.h" 00044 #include "tia-private/clock.h" 00045 #include "tia-private/datapacket/raw_mem3.h" 00046 00047 namespace tia 00048 { 00049 00050 using boost::uint16_t; 00051 using boost::uint32_t; 00052 using boost::uint64_t; 00053 using boost::int32_t; 00054 00055 using std::vector; 00056 using std::map; 00057 using std::string; 00058 using std::stringstream; 00059 using std::make_pair; 00060 00061 static const unsigned int CURRENT_DATA_PACKET_VERSION = 3; 00062 00063 //----------------------------------------------------------------------------- 00064 00065 DataPacket3Impl::DataPacket3Impl() 00066 : version_(CURRENT_DATA_PACKET_VERSION), packet_id_(0), 00067 flags_(0), connection_packet_nr_(0), 00068 timestamp_(0), nr_of_signal_types_(0) 00069 { 00070 00071 } 00072 00073 //----------------------------------------------------------------------------- 00074 00075 DataPacket3Impl::DataPacket3Impl(const DataPacket3Impl &src) 00076 { 00077 version_ = src.version_; 00078 packet_id_ = src.packet_id_; 00079 flags_ = src.flags_; 00080 connection_packet_nr_ = src.connection_packet_nr_; 00081 timestamp_ = src.timestamp_; 00082 nr_of_signal_types_ = src.nr_of_signal_types_; 00083 00084 nr_channels_ = src.nr_channels_; 00085 samples_per_channel_ = src.samples_per_channel_; 00086 data_ = src.data_; 00087 00088 std::map<boost::uint32_t, RawMem3*> raw_map_; 00089 } 00090 00091 //----------------------------------------------------------------------------- 00092 00093 DataPacket3Impl& DataPacket3Impl::operator=(const DataPacket3Impl &src) 00094 { 00095 version_ = src.version_; 00096 packet_id_ = src.packet_id_; 00097 flags_ = src.flags_; 00098 connection_packet_nr_ = src.connection_packet_nr_; 00099 timestamp_ = src.timestamp_; 00100 nr_of_signal_types_ = src.nr_of_signal_types_; 00101 00102 nr_channels_ = src.nr_channels_; 00103 samples_per_channel_ = src.samples_per_channel_; 00104 data_ = src.data_; 00105 00106 std::map<boost::uint32_t, RawMem3*> raw_map_; 00107 00108 return *this; 00109 } 00110 00111 //----------------------------------------------------------------------------- 00112 00113 void DataPacket3Impl::reset(void* mem) 00114 { 00115 #ifdef DEBUG 00116 cout << "DataPacket: RAW Constructor" << endl; 00117 #endif 00118 00119 flags_ = 0; 00120 connection_packet_nr_ = 0; 00121 nr_of_signal_types_ = 0; 00122 00123 uint8_t* version_ptr = reinterpret_cast<uint8_t*>(mem); 00124 version_ = *version_ptr; 00125 00126 if(CURRENT_DATA_PACKET_VERSION != version_) 00127 { 00128 string ex_str("DataPacket(void* mem): ERROR -- DataPacket versions don't match!"); 00129 ex_str = ex_str + " - Received packet version: "; 00130 ex_str += version_; 00131 ex_str = ex_str + " - Needed packet version: "; 00132 ex_str += CURRENT_DATA_PACKET_VERSION; 00133 throw(std::runtime_error(ex_str)); 00134 } 00135 00136 uint32_t* ui32_ptr = reinterpret_cast<uint32_t*>(++version_ptr); 00137 ++ui32_ptr; // FIXME ... skip size field 00138 flags_ = *ui32_ptr; 00139 00140 nr_of_signal_types_ = calcNrOfSignalTypes(flags_); 00141 00142 uint64_t* ui64_ptr = reinterpret_cast<uint64_t*>(++ui32_ptr); 00143 packet_id_ = *ui64_ptr; 00144 ui64_ptr++; 00145 connection_packet_nr_ = *ui64_ptr; 00146 00147 uint64_t* time_ptr 00148 = reinterpret_cast<uint64_t*>(++ui64_ptr); 00149 timestamp_ = *time_ptr; 00150 00151 uint16_t* ui16_ptr = reinterpret_cast<uint16_t*>(++time_ptr); 00152 for(unsigned int n = 0; n < nr_of_signal_types_; n++) 00153 { 00154 nr_channels_.push_back(*ui16_ptr); 00155 ui16_ptr++; 00156 } 00157 00158 for(unsigned int n = 0; n < nr_of_signal_types_; n++) 00159 { 00160 samples_per_channel_.push_back(*ui16_ptr); 00161 ui16_ptr++; 00162 } 00163 00164 float* data_ptr = reinterpret_cast<float*>(ui16_ptr); 00165 for(unsigned int j = 0; j < nr_channels_.size(); j++) 00166 for(int32_t k = 0; k < (nr_channels_[j] * samples_per_channel_[j] ) ; k++) 00167 { 00168 data_.push_back(*data_ptr); 00169 data_ptr++; 00170 } 00171 } 00172 00173 //----------------------------------------------------------------------------- 00174 DataPacket3Impl::~DataPacket3Impl() 00175 { 00176 for(std::map<boost::uint32_t, RawMem3*>::iterator it(raw_map_.begin()); 00177 it != raw_map_.end(); it++) 00178 { 00179 delete(it->second); 00180 it->second = 0; 00181 } 00182 } 00183 00184 00185 //----------------------------------------------------------------------------- 00186 00187 void DataPacket3Impl::reset() 00188 { 00189 #ifdef DEBUG 00190 cout << "DataPacket: reset" << endl; 00191 #endif 00192 00193 flags_ = 0; 00194 connection_packet_nr_ = 0; 00195 nr_of_signal_types_ = 0; 00196 samples_per_channel_.clear(); 00197 nr_channels_.clear(); 00198 setTimestamp(); 00199 data_.clear(); 00200 for(map<uint32_t, RawMem3*>::iterator it(raw_map_.begin()); it != raw_map_.end(); it++) 00201 if(it->second) 00202 { 00203 delete(it->second); 00204 it->second = 0; 00205 } 00206 raw_map_.clear(); 00207 } 00208 00209 //----------------------------------------------------------------------------- 00210 00211 void DataPacket3Impl::incPacketID() 00212 { 00213 packet_id_++; 00214 } 00215 00216 //----------------------------------------------------------------------------- 00217 00218 void DataPacket3Impl::setPacketID(boost::uint64_t nr) 00219 { 00220 packet_id_ = nr; 00221 } 00222 00223 //----------------------------------------------------------------------------- 00224 00225 void DataPacket3Impl::insertDataBlock(vector<double> v, uint32_t signal_flag, uint16_t blocks, bool prepend) 00226 { 00227 00228 if(!flagsOK()) 00229 throw(std::logic_error("DataPacket3::insertDataBlock() -- Flags differ from Amount of Signals in DataPacket!")); 00230 00231 if(calcNrOfSignalTypes(signal_flag) != 1) 00232 throw(std::logic_error("DataPacket3::insertDataBlock() -- Trying to insert more or less than 1 signal type at the same time!")); 00233 00234 if(hasFlag(signal_flag)) 00235 { 00236 if(prepend) 00237 prependDataBlock(v, signal_flag, blocks); 00238 else 00239 appendDataBlock(v, signal_flag, blocks); 00240 00241 return; 00242 /* throw(std::logic_error("DataPacket3::insertDataBlock() -- Error ... Flag already defined, \ 00243 equal signal types simultaneously from different sources not supported at the moment!")); */ 00244 } 00245 00246 uint32_t pos = getDataPos(signal_flag); 00247 00248 setFlag(signal_flag); 00249 00250 vector<double>::iterator it_data(data_.begin() + getOffset(pos)); 00251 data_.insert(it_data,v.begin(),v.end()); 00252 00253 vector<uint16_t>::iterator it_nr(samples_per_channel_.begin() + pos ); 00254 samples_per_channel_.insert(it_nr, blocks); 00255 00256 it_nr = nr_channels_.begin() + pos; 00257 nr_channels_.insert(it_nr, v.size()/blocks); 00258 00259 nr_of_signal_types_++; 00260 } 00261 00262 //----------------------------------------------------------------------------- 00263 00264 void DataPacket3Impl::appendDataBlock(vector<double> &v, uint32_t signal_flag, uint16_t blocks) 00265 { 00266 if(getNrSamplesPerChannel(signal_flag) != blocks) 00267 throw(std::logic_error("DataPacket3::appendDataBlock() -- Blocksize of appended signal does not \ 00268 match the stored one -- check your settings!")); 00269 00270 uint32_t pos = getDataPos(signal_flag); 00271 00272 vector<double>::iterator it_data(data_.begin() + getOffset(pos) + 00273 (nr_channels_[pos] * samples_per_channel_[pos] ) ); 00274 data_.insert(it_data,v.begin(),v.end()); 00275 00276 nr_channels_[pos] += v.size()/blocks; 00277 } 00278 00279 //----------------------------------------------------------------------------- 00280 00281 void DataPacket3Impl::prependDataBlock(vector<double> &v, uint32_t signal_flag, uint16_t blocks) 00282 { 00283 if(getNrSamplesPerChannel(signal_flag) != blocks) 00284 throw(std::logic_error("DataPacket3::appendDataBlock() -- Blocksize of appended signal does not \ 00285 match the stored one -- check your settings!")); 00286 00287 uint32_t pos = getDataPos(signal_flag); 00288 00289 vector<double>::iterator it_data(data_.begin() + getOffset(pos)); 00290 data_.insert(it_data,v.begin(),v.end()); 00291 00292 nr_channels_[pos] += v.size()/blocks; 00293 } 00294 00295 //----------------------------------------------------------------------------- 00296 00297 void DataPacket3Impl::setConnectionPacketNr(boost::uint64_t nr) 00298 { 00299 connection_packet_nr_ = nr; 00300 } 00301 00302 //-------------------------------------------------------------------- 00303 00304 uint64_t DataPacket3Impl::getConnectionPacketNr() 00305 { 00306 return(connection_packet_nr_); 00307 } 00308 00309 //------------------------------------------------------------------- 00310 00311 void DataPacket3Impl::setTimestamp() 00312 { 00313 timestamp_ = Clock::instance ().getMicroSeconds (); 00314 } 00315 00316 //----------------------------------------------------------------------------- 00317 00318 bool DataPacket3Impl::hasFlag(boost::uint32_t f) 00319 { 00320 return( (f & flags_) == f); 00321 } 00322 00323 //----------------------------------------------------------------------------- 00324 00325 boost::uint32_t DataPacket3Impl::getFlags() 00326 { 00327 if(!flagsOK()) 00328 throw(std::logic_error("DataPacket3::getFlags() -- Flags differ from Amount of Signals in DataPacket!")); 00329 return(flags_); 00330 } 00331 00332 //----------------------------------------------------------------------------- 00333 00334 boost::uint64_t DataPacket3Impl::getPacketID() 00335 { 00336 return(packet_id_); 00337 } 00338 00339 //----------------------------------------------------------------------------- 00340 00341 boost::uint16_t DataPacket3Impl::getNrOfSignalTypes() 00342 { 00343 if(!flagsOK()) 00344 throw(std::logic_error("DataPacket3::getNrOfSignalTypes() -- Flags differ from Amount of Signals in DataPacket!")); 00345 00346 return(nr_of_signal_types_); 00347 } 00348 00349 //----------------------------------------------------------------------------- 00350 00351 std::vector<boost::uint16_t> DataPacket3Impl::getNrOfSamples() 00352 { 00353 std::vector<boost::uint16_t> vec(samples_per_channel_.size()); 00354 00355 for(unsigned int n = 0; n < samples_per_channel_.size(); n++ ) 00356 vec[n] = samples_per_channel_[n] * nr_channels_[n]; 00357 00358 return(vec); 00359 } 00360 00361 //----------------------------------------------------------------------------- 00362 00363 vector<boost::uint16_t> DataPacket3Impl::getNrSamplesPerChannel() 00364 { 00365 return(samples_per_channel_); 00366 } 00367 00368 //----------------------------------------------------------------------------- 00369 00370 vector<uint16_t> DataPacket3Impl::getNrOfChannels() 00371 { 00372 return(nr_channels_); 00373 } 00374 00375 //----------------------------------------------------------------------------- 00376 00377 const vector<double>& DataPacket3Impl::getData() 00378 { 00379 if(!flagsOK()) 00380 throw(std::logic_error("DataPacket3::getData() -- Flags differ from Amount of Signals in DataPacket!")); 00381 return(data_); 00382 } 00383 00384 //----------------------------------------------------------------------------- 00385 00386 vector<double> DataPacket3Impl::getSingleDataBlock(boost::uint32_t flag) 00387 { 00388 if(!flagsOK()) 00389 throw(std::logic_error("DataPacket3::getSingleDataBlock() -- Flags differ from Amount of Signals in DataPacket!")); 00390 00391 if(!hasFlag(flag)) 00392 throw(std::invalid_argument("DataPacket3::getSingleDataBlock() -- Error ... Flag not set, unable to get Data!")); 00393 00394 uint32_t position = getDataPos(flag); 00395 00396 vector<double> v(data_.begin() + getOffset(position), \ 00397 data_.begin() + getOffset(position) + \ 00398 ( nr_channels_[position] * samples_per_channel_[position] ) ); 00399 return(v); 00400 } 00401 00402 //----------------------------------------------------------------------------- 00403 00404 boost::uint16_t DataPacket3Impl::getNrOfSamples(boost::uint32_t flag) 00405 { 00406 if(!flagsOK()) 00407 throw(std::logic_error("DataPacket3::getNrOfValues() -- Flags differ from Amount of Signals in DataPacket!")); 00408 00409 if(!hasFlag(flag)) 00410 return(0); 00411 00412 return( getNrOfChannels(flag) * getNrSamplesPerChannel(flag) ); 00413 } 00414 00415 //----------------------------------------------------------------------------- 00416 00417 boost::uint16_t DataPacket3Impl::getNrOfChannels(boost::uint32_t flag) 00418 { 00419 if(!flagsOK()) 00420 throw(std::logic_error("DataPacket3::getNrOfChannels() -- Flags differ from Amount of Signals in DataPacket!")); 00421 00422 if(!hasFlag(flag)) 00423 return(0); 00424 // throw(std::invalid_argument("DataPacket3::getNrOfChannels() -- Error ... Flag not set, unable to get Data!")); 00425 00426 return(nr_channels_[getDataPos(flag)]); 00427 } 00428 00429 //----------------------------------------------------------------------------- 00430 00431 boost::uint16_t DataPacket3Impl::getNrSamplesPerChannel(boost::uint32_t flag) 00432 { 00433 if(!flagsOK()) 00434 throw(std::logic_error("DataPacket3::getSamplesPerChannel() -- Flags differ from Amount of Signals in DataPacket!")); 00435 00436 if(!hasFlag(flag)) 00437 return(0); 00438 // throw(std::invalid_argument("DataPacket3::getSamplesPerChannel() -- Error ... Flag not set, unable to get Data!")); 00439 00440 return(samples_per_channel_[getDataPos(flag)]); 00441 } 00442 00443 //----------------------------------------------------------------------------- 00444 00445 boost::uint16_t DataPacket3Impl::calcNrOfSignalTypes(boost::uint32_t f) 00446 { 00447 uint16_t count = 0; 00448 uint32_t shift = 1; 00449 00450 for(unsigned int n = 0; n < sizeof(f) *8; n++) 00451 count += (((shift << n) & f) >= 1) ; 00452 00453 return(count); 00454 } 00455 00456 //----------------------------------------------------------------------------- 00457 00458 bool DataPacket3Impl::flagsOK() 00459 { 00460 if(calcNrOfSignalTypes(flags_) != nr_of_signal_types_) 00461 return(false); 00462 00463 return(true); 00464 } 00465 00466 //----------------------------------------------------------------------------- 00467 00468 void DataPacket3Impl::setFlag(boost::uint32_t f) 00469 { 00470 flags_ |= f; 00471 } 00472 00473 //----------------------------------------------------------------------------- 00474 00475 boost::uint32_t DataPacket3Impl::getDataPos(boost::uint32_t flag) 00476 { 00477 if(flag > flags_) 00478 return(nr_of_signal_types_); 00479 00480 uint32_t pos = 0; 00481 uint32_t shift = 1; 00482 00483 while(shift < flag) 00484 { 00485 if(flags_ & shift) 00486 pos++; 00487 shift <<= 1; 00488 } 00489 00490 return(pos); 00491 } 00492 00493 //----------------------------------------------------------------------------- 00494 00495 boost::uint32_t DataPacket3Impl::getOffset(boost::uint32_t pos) 00496 { 00497 uint32_t offset = 0; 00498 00499 for(uint32_t n = 0; n < pos; n++) 00500 offset += (nr_channels_[n] * samples_per_channel_[n]); 00501 return(offset); 00502 } 00503 00504 //----------------------------------------------------------------------------- 00505 00506 boost::uint32_t DataPacket3Impl::getRawMemorySize() 00507 { 00508 map<uint32_t, RawMem3*>::iterator it(raw_map_.find(flags_)); 00509 00510 if(it == raw_map_.end()) return 0; 00511 00512 return it->second->size(); 00513 } 00514 00515 //----------------------------------------------------------------------------- 00516 00517 void* DataPacket3Impl::getRaw() 00518 { 00519 map<uint32_t, RawMem3*>::iterator it(raw_map_.find(flags_)); 00520 RawMem3* r; 00521 00522 if(it == raw_map_.end()) 00523 { 00524 if(connection_packet_nr_ == 0) 00525 connection_packet_nr_ = packet_id_; 00526 00527 r = new RawMem3(version_, flags_, packet_id_, connection_packet_nr_, \ 00528 timestamp_, nr_channels_, samples_per_channel_, data_); 00529 00530 raw_map_.insert(make_pair(flags_,r)); 00531 } 00532 else 00533 r = it->second; 00534 00535 return(r->getMemPtr()); 00536 } 00537 00538 //----------------------------------------------------------------------------- 00539 00540 boost::uint32_t DataPacket3Impl::getRequiredRawMemorySize() 00541 { 00542 uint32_t size_ = sizeof(version_) + sizeof(size_)\ 00543 + sizeof(flags_) + sizeof(packet_id_) + sizeof(connection_packet_nr_) \ 00544 + sizeof(timestamp_) \ 00545 + samples_per_channel_.size() * sizeof(uint16_t) \ 00546 + nr_channels_.size() * sizeof(uint16_t) \ 00547 + data_.size() * sizeof(float); // FIXME ... hardcoded sizeof() !!!! 00548 return(size_); 00549 } 00550 00551 //----------------------------------------------------------------------------- 00552 00553 boost::uint32_t DataPacket3Impl::getRequiredRawMemorySize(void* mem, boost::uint32_t ba) 00554 { 00555 if(ba < sizeof(uint8_t) + sizeof(uint32_t) ) 00556 return(0); 00557 00558 uint8_t* version_ptr = reinterpret_cast<uint8_t*>(mem); 00559 uint8_t version = *version_ptr; 00560 00561 if(version != CURRENT_DATA_PACKET_VERSION) 00562 throw(std::runtime_error("Error -- DataPacket3Impl::getRequiredRawMemorySize: Wrong packet version!")); 00563 00564 uint32_t* ui32_ptr = reinterpret_cast<uint32_t*>(++version_ptr); 00565 00566 return(*ui32_ptr); 00567 00568 00569 } 00570 00571 } // Namespace tobiss 00572 00573 //-----------------------------------------------------------------------------