|
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/lexical_cast.hpp> 00043 #include <boost/cstdint.hpp> 00044 00045 // TICPP 00046 #include "ticpp/ticpp.h" 00047 00048 // local 00049 #include "tia/constants.h" 00050 00051 #include "tia-private/config/control_message_decoder.h" 00052 #include "tia/ss_meta_info.h" 00053 00054 namespace tia 00055 { 00056 00057 using boost::lexical_cast; 00058 using boost::uint16_t; 00059 using boost::uint32_t; 00060 00061 using std::cout; 00062 using std::cerr; 00063 using std::endl; 00064 00065 //----------------------------------------------------------------------------- 00066 00067 ControlMsgDecoderXML::ControlMsgDecoderXML() : 00068 tixml_doc_(0), xml_doc_(0), xml_msg_header_(0) 00069 { 00070 tixml_doc_ = new TiXmlDocument(); 00071 xml_doc_ = new ticpp::Document(tixml_doc_); 00072 00073 prototypes_["alive"] = ControlMsgHandle(new KeepAliveMsg()); 00074 prototypes_["getConfig"] = ControlMsgHandle(new GetConfigMsg()); 00075 prototypes_["startTransmission"] = ControlMsgHandle(new StartTransmissionMsg()); 00076 prototypes_["getDataConnection"] = ControlMsgHandle(new GetDataConnectionMsg()); 00077 prototypes_["dataConnection"] = ControlMsgHandle(new DataConnectionMsg()); 00078 prototypes_["stopTransmission"] = ControlMsgHandle(new StopTransmissionMsg()); 00079 prototypes_["config"] = ControlMsgHandle(new ConfigMsg()); 00080 prototypes_["okReply"] = ControlMsgHandle(ReplyMsg::ok().clone()); 00081 prototypes_["errorReply"] = ControlMsgHandle(ReplyMsg::error().clone()); 00082 } 00083 00084 //----------------------------------------------------------------------------- 00085 00086 ControlMsgDecoderXML::~ControlMsgDecoderXML() 00087 { 00088 if(xml_doc_) 00089 delete tixml_doc_; 00090 00091 if(xml_doc_) 00092 delete xml_doc_; 00093 } 00094 00095 //----------------------------------------------------------------------------- 00096 00097 ControlMsg* ControlMsgDecoderXML::decodeMsg() 00098 { 00099 return decodeMsgInternal(); 00100 } 00101 00102 //----------------------------------------------------------------------------- 00103 00104 ControlMsg* ControlMsgDecoderXML::decodeMsgInternal() 00105 { 00106 if (istream_ == 0 || !istream_->good()) return 0; 00107 00108 xml_doc_->Clear(); 00109 xml_msg_header_ = 0; 00110 00111 *istream_ >> *xml_doc_; 00112 00113 if (tixml_doc_->Error()) 00114 { 00115 // TODO: do a proper error handling 00116 cerr << "ControlMsgDecoderXML::decodeMsgInternal: " 00117 << tixml_doc_->ErrorDesc() 00118 << endl; 00119 00120 return 0; 00121 } 00122 00123 #ifdef DEBUG 00124 cout << "ControlMsgDecoderXML::decodeMsgInternal: decoding XML message:" << endl; 00125 cout << "-------------" << endl; 00126 tixml_doc_->Print(); 00127 cout << "-------------" << endl; 00128 #endif 00129 00130 ticpp::Element* message = xml_doc_->FirstChildElement("message", false); 00131 if (message == 0) 00132 { 00133 // TODO: do a proper error handling 00134 cerr << "Missing tag 'message'" << endl; 00135 return 0; 00136 } 00137 00138 std::string msg_version; 00139 msg_version = message->GetAttribute<std::string>("version", true); 00140 00141 if(msg_version != MESSAGE_VERSION) 00142 { 00143 cerr << "Wrong message version " << msg_version << " -- expected: " << MESSAGE_VERSION << endl; 00144 return 0; 00145 } 00146 00147 xml_msg_header_ = message->FirstChildElement("header", false); 00148 if (xml_msg_header_ == 0) 00149 { 00150 // TODO: do a proper error handling 00151 cerr << "Missing tag 'header'" << endl; 00152 return 0; 00153 } 00154 00155 std::string xml_msg_type; 00156 if (!getXmlMsgType(*xml_msg_header_, xml_msg_type)) 00157 { 00158 // TODO: do a proper error handling 00159 return 0; 00160 } 00161 00162 std::map<std::string, ControlMsgHandle>::iterator itPrototypes = 00163 prototypes_.find(xml_msg_type); 00164 00165 if (itPrototypes == prototypes_.end()) 00166 { 00167 // TODO: do a proper error handling 00168 cerr << "Unknown control message type '" << xml_msg_type << "'" << endl; 00169 return 0; 00170 } 00171 00172 ControlMsg* msg = (*itPrototypes).second->clone(); 00173 assert(msg != 0); 00174 msg->readMsg(*this); 00175 00176 return msg; 00177 } 00178 00179 //----------------------------------------------------------------------------- 00180 00181 bool ControlMsgDecoderXML::getXmlMsgType(ticpp::Element& header, std::string& type) const 00182 { 00183 ticpp::Element* element = header.FirstChildElement("type", false); 00184 if (element == 0) 00185 { 00186 // TODO: do a proper error handling 00187 cerr << "Missing tag 'type' in control message header" << endl; 00188 return false; 00189 } 00190 00191 type = element->GetText(); 00192 return true; 00193 } 00194 00195 //----------------------------------------------------------------------------- 00196 00197 bool ControlMsgDecoderXML::decodeHeader(ControlMsg& msg) 00198 { 00199 ticpp::Element* element = xml_msg_header_->FirstChildElement("sender", false); 00200 if (element == 0 || element->Value() != "sender") 00201 { 00202 // TODO: do a proper error handling 00203 cerr << "Missing tag 'sender' in control message header" << endl; 00204 return false; 00205 } 00206 00207 std::string text = element->GetTextOrDefault(""); 00208 msg.setSender(text); 00209 00210 return true; 00211 } 00212 00213 //----------------------------------------------------------------------------- 00214 00215 void ControlMsgDecoderXML::decodeMsg(KeepAliveMsg& msg) 00216 { 00217 #ifdef DEBUG 00218 cout << "ControlMsgDecoderXML::decodeMsg: decoding KeepAliveMsg" << endl; 00219 #endif 00220 00221 if (!decodeHeader(msg)) 00222 { 00223 // TODO: do a proper error handling 00224 cerr << "Error decoding KeepAliveMsg" << endl; 00225 return; 00226 } 00227 // TODO: parse message body 00228 } 00229 00230 //----------------------------------------------------------------------------- 00231 00232 void ControlMsgDecoderXML::decodeMsg(GetConfigMsg& msg) 00233 { 00234 #ifdef DEBUG 00235 cout << "ControlMsgDecoderXML::decodeMsg: decoding GetConfigMsg" << endl; 00236 #endif 00237 00238 if (!decodeHeader(msg)) 00239 { 00240 // TODO: do a proper error handling 00241 cerr << "Error decoding GetConfigMsg" << endl; 00242 return; 00243 } 00244 // TODO: parse message body 00245 } 00246 00247 //----------------------------------------------------------------------------- 00248 00249 void ControlMsgDecoderXML::decodeMsg(StopTransmissionMsg& msg) 00250 { 00251 #ifdef DEBUG 00252 cout << "ControlMsgDecoderXML::decodeMsg: decoding StopTransmissionMsg" << endl; 00253 #endif 00254 00255 if (!decodeHeader(msg)) 00256 { 00257 // TODO: do a proper error handling 00258 cerr << "Error decoding StopTransmissionMsg" << endl; 00259 return; 00260 } 00261 // TODO: parse message body 00262 } 00263 00264 //----------------------------------------------------------------------------- 00265 00266 void ControlMsgDecoderXML::decodeMsg(StartTransmissionMsg& msg) 00267 { 00268 #ifdef DEBUG 00269 cout << "ControlMsgDecoderXML::decodeMsg: decoding StartTransmissionMsg" << endl; 00270 #endif 00271 00272 if (!decodeHeader(msg)) 00273 { 00274 // TODO: do a proper error handling 00275 cerr << "Error decoding StartTransmissionMsg" << endl; 00276 return; 00277 } 00278 00279 ticpp::Element* start_trans_element = xml_msg_header_->NextSiblingElement(); 00280 if (start_trans_element == 0 || start_trans_element->Value() != "startTransmission") 00281 { 00282 // TODO: do a proper error handling 00283 cerr << "Missing element 'startTransmission' in StartTransmissionMsg" << endl; 00284 return; 00285 } 00286 } 00287 00288 //----------------------------------------------------------------------------- 00289 00290 void ControlMsgDecoderXML::decodeMsg(GetDataConnectionMsg& msg) 00291 { 00292 #ifdef DEBUG 00293 cout << "ControlMsgDecoderXML::decodeMsg: decoding GetDataConnectionMsg" << endl; 00294 #endif 00295 00296 if (!decodeHeader(msg)) 00297 { 00298 // TODO: do a proper error handling 00299 cerr << "Error decoding GetDataConnectionMsg" << endl; 00300 return; 00301 } 00302 00303 ticpp::Element* get_data_conn_element = xml_msg_header_->NextSiblingElement(); 00304 if (get_data_conn_element == 0 || get_data_conn_element->Value() != "getDataConnection") 00305 { 00306 // TODO: do a proper error handling 00307 cerr << "Missing element 'getDataConnection' in GetDataConnectionMsg" << endl; 00308 return; 00309 } 00310 00311 std::string element_name = "connectionType"; 00312 ticpp::Element* element = get_data_conn_element->FirstChildElement(element_name, false); 00313 if (element != 0) 00314 { 00315 std::string value = element->GetTextOrDefault(""); 00316 if (value == "tcp") 00317 msg.setConnectionType(GetDataConnectionMsg::Tcp); 00318 else if (value == "udp") 00319 msg.setConnectionType(GetDataConnectionMsg::Udp); 00320 else 00321 cerr << "Invalid value for element '" << element_name << endl; 00322 } 00323 else 00324 cerr << "Missing element '" << element_name << " in element 'getDataConnection'" << endl; 00325 00326 } 00327 00328 //----------------------------------------------------------------------------- 00329 00330 void ControlMsgDecoderXML::decodeMsg(DataConnectionMsg& msg) 00331 { 00332 #ifdef DEBUG 00333 cout << "ControlMsgDecoderXML::decodeMsg: decoding DataConnectionMsg" << endl; 00334 #endif 00335 00336 if (!decodeHeader(msg)) 00337 { 00338 // TODO: do a proper error handling 00339 cerr << "Error decoding GetDataConnectionMsg" << endl; 00340 return; 00341 } 00342 00343 ticpp::Element* data_conn_element = xml_msg_header_->NextSiblingElement(); 00344 if (data_conn_element == 0 || data_conn_element->Value() != "dataConnection") 00345 { 00346 // TODO: do a proper error handling 00347 cerr << "Missing element 'dataConnection' in DataConnectionMsg" << endl; 00348 return; 00349 } 00350 00351 std::string element_name = "address"; 00352 ticpp::Element* element = data_conn_element->FirstChildElement(element_name, false); 00353 if (element != 0) 00354 { 00355 std::string address = element->GetTextOrDefault(""); 00356 msg.setAddress(address); 00357 } 00358 00359 element_name = "port"; 00360 element = data_conn_element->FirstChildElement(element_name, false); 00361 if (element != 0) 00362 { 00363 try { 00364 uint16_t value = 0; 00365 element->GetText(&value); 00366 msg.setPort(value); 00367 } 00368 catch(...) 00369 { 00370 cerr << "Invalid value for element '" << element_name << endl; 00371 } 00372 } 00373 else 00374 cerr << "Missing element '" << element_name << " in element 'dataConnection'" << endl; 00375 } 00376 00377 //----------------------------------------------------------------------------- 00378 00379 void ControlMsgDecoderXML::decodeMsg(ConfigMsg& msg) 00380 { 00381 #ifdef DEBUG 00382 cout << "ControlMsgDecoderXML::decodeMsg: decoding ConfigMsg" << endl; 00383 #endif 00384 00385 if (!decodeHeader(msg)) 00386 { 00387 // TODO: do a proper error handling 00388 cerr << "Error decoding ConfigMsg" << endl; 00389 return; 00390 } 00391 00392 ticpp::Element* config_element = xml_msg_header_->NextSiblingElement(); 00393 if (config_element == 0 || config_element->Value() != "config") 00394 { 00395 // TODO: do a proper error handling 00396 cerr << "Missing element 'config' in ConfigMsg" << endl; 00397 return; 00398 } 00399 00400 ticpp::Element* subject_element = config_element->FirstChildElement("subject", false); 00401 if (subject_element == 0) 00402 { 00403 // TODO: do a proper error handling 00404 cerr << "Missing element 'subject' in ConfigMsg" << endl; 00405 return; 00406 } 00407 00408 std::string element_name; 00409 ticpp::Element* element = 0; 00410 00411 element_name = "id"; 00412 element = subject_element->FirstChildElement(element_name, false); 00413 if (element != 0) 00414 msg.subject_info.setId(element->GetText()); 00415 else 00416 cerr << "Missing element '" << element_name << "' in element 'subject'" << endl; 00417 00418 element_name = "firstName"; 00419 element = subject_element->FirstChildElement(element_name, false); 00420 if (element != 0) 00421 msg.subject_info.setFirstName(element->GetText()); 00422 else 00423 cerr << "Missing element '" << element_name << "' in element 'subject'" << endl; 00424 00425 element_name = "surname"; 00426 element = subject_element->FirstChildElement(element_name, false); 00427 if (element != 0) 00428 msg.subject_info.setSurname(element->GetText()); 00429 else 00430 cerr << "Missing element '" << element_name << "' in element 'subject'" << endl; 00431 00432 element_name = "birthday"; 00433 element = subject_element->FirstChildElement(element_name, false); 00434 if (element != 0) 00435 msg.subject_info.setBirthday(element->GetText()); 00436 else 00437 cerr << "Missing element '" << element_name << "' in element 'subject'" << endl; 00438 00439 element_name = "medication"; 00440 element = subject_element->FirstChildElement(element_name, false); 00441 if (element != 0) 00442 msg.subject_info.setBirthday(element->GetText()); 00443 else 00444 cerr << "Missing element '" << element_name << "' in element 'subject'" << endl; 00445 00446 element_name = "sex"; 00447 element = subject_element->FirstChildElement(element_name, false); 00448 if (element != 0) 00449 { 00450 if (element->GetText() == "m") 00451 msg.subject_info.setSex(SubjectInfo::Male); 00452 else if (element->GetText() == "f") 00453 msg.subject_info.setSex(SubjectInfo::Female); 00454 else 00455 cerr << "Invalid value for element '" << element_name << "' in element 'subject'" << endl; 00456 } 00457 else 00458 cerr << "Missing element '" << element_name << "' in subject" << endl; 00459 00460 element_name = "handedness"; 00461 element = subject_element->FirstChildElement(element_name, false); 00462 if (element != 0) 00463 { 00464 if (element->GetText() == "r") 00465 msg.subject_info.setHandedness(SubjectInfo::RightHanded); 00466 else if (element->GetText() == "l") 00467 msg.subject_info.setHandedness(SubjectInfo::LeftHanded); 00468 else 00469 cerr << "Invalid value for element '" << element_name << "' in element 'subject'" << endl; 00470 } 00471 else 00472 cerr << "Missing element '" << element_name << "' in subject" << endl; 00473 00474 // Optional elements 00475 00476 element_name = "glasses"; 00477 element = subject_element->FirstChildElement(element_name, false); 00478 if (element != 0) 00479 { 00480 if (element->GetText() == "yes") 00481 msg.subject_info.setShortInfo(SubjectInfo::Glasses, SubjectInfo::Yes); 00482 else if (element->GetText() == "no") 00483 msg.subject_info.setShortInfo(SubjectInfo::Glasses, SubjectInfo::No); 00484 else 00485 cerr << "Invalid value for element '" << element_name << "' in element 'subject'" << endl; 00486 } 00487 00488 element_name = "smoker"; 00489 element = subject_element->FirstChildElement(element_name, false); 00490 if (element != 0) 00491 { 00492 if (element->GetText() == "yes") 00493 msg.subject_info.setShortInfo(SubjectInfo::Smoking, SubjectInfo::Yes); 00494 else if (element->GetText() == "no") 00495 msg.subject_info.setShortInfo(SubjectInfo::Smoking, SubjectInfo::No); 00496 else 00497 cerr << "Invalid value for element '" << element_name << "' in element 'subject'" << endl; 00498 } 00499 00500 ticpp::Element* signal_info_element = config_element->FirstChildElement("signalInfo", false); 00501 if (signal_info_element == 0) 00502 { 00503 // TODO: do a proper error handling 00504 cerr << "Missing element 'signalInfo' in ConfigMsg" << endl; 00505 return; 00506 } 00507 00508 ticpp::Element* master_element = signal_info_element->FirstChildElement("master", false); 00509 if (master_element != 0) 00510 { 00511 element_name = "samplingRate"; 00512 element = master_element->FirstChildElement(element_name, false); 00513 if (element != 0) 00514 { 00515 try { 00516 uint16_t value = 0; 00517 element->GetText(&value); 00518 msg.signal_info.setMasterSamplingRate(value); 00519 } 00520 catch(...) 00521 { 00522 cerr << "Invalid value for '" << element_name << "' in element 'master'" << endl; 00523 } 00524 } 00525 else 00526 cerr << "Missing element '" << element_name << "' in element 'master'" << endl; 00527 00528 element_name = "blockSize"; 00529 element = master_element->FirstChildElement(element_name, false); 00530 if (element != 0) 00531 { 00532 try { 00533 uint16_t value = 0; 00534 element->GetText(&value); 00535 msg.signal_info.setMasterBlockSize(value); 00536 } 00537 catch(...) 00538 { 00539 cerr << "Invalid value for '" << element_name << "' in element 'master'" << endl; 00540 } 00541 } 00542 else 00543 cerr << "Missing element '" << element_name << "' in element 'master'" << endl; 00544 } 00545 else 00546 { 00547 cerr << "Missing element 'master' in element 'signalInfo'" << endl; 00548 return; 00549 } 00550 00551 ticpp::Element* signals_element = signal_info_element->FirstChildElement("signals", false); 00552 00553 if (signals_element != 0) 00554 { 00555 ticpp::Element* sig_element = signals_element->FirstChildElement(false); 00556 for (; sig_element != 0; sig_element = sig_element->NextSiblingElement(false)) 00557 { 00558 if (sig_element->Value() != "sig") 00559 { 00560 cerr << "Misplaced element '" << sig_element->Value() << "' in element 'signals'" << endl; 00561 continue; 00562 } 00563 00564 std::string signal_type = sig_element->GetAttributeOrDefault("type", ""); 00565 if (signal_type.empty()) 00566 { 00567 cerr << "Element 'sig' without attribute 'type' in element signals" << endl; 00568 continue; 00569 } 00570 00571 Signal signal; 00572 signal.setType(signal_type); 00573 00574 element_name = "blockSize"; 00575 element = sig_element->FirstChildElement(element_name, false); 00576 if (element != 0) 00577 { 00578 try { 00579 uint16_t value = 0; 00580 element->GetText(&value); 00581 signal.setBlockSize(value); 00582 } 00583 catch(...) 00584 { 00585 cerr << "Invalid value for '" << element_name << "' in element 'sig'" << endl; 00586 } 00587 } 00588 else 00589 cerr << "Missing element '" << element_name << "' in element 'sig'" << endl; 00590 00591 element_name = "samplingRate"; 00592 element = sig_element->FirstChildElement(element_name, false); 00593 if (element != 0) 00594 { 00595 try { 00596 uint16_t value = 0; 00597 element->GetText(&value); 00598 signal.setSamplingRate(value); 00599 } 00600 catch(...) 00601 { 00602 cerr << "Invalid value for '" << element_name << "' in element 'sig'" << endl; 00603 } 00604 } 00605 else 00606 cerr << "Missing element '" << element_name << "' in element 'sig'" << endl; 00607 00608 ticpp::Element* channels_element = sig_element->FirstChildElement("channels", false); 00609 00610 if (channels_element != 0) 00611 { 00612 ticpp::Element* ch_element = channels_element->FirstChildElement(false); 00613 for (; ch_element != 0; ch_element = ch_element->NextSiblingElement(false)) 00614 { 00615 if (ch_element->Value() != "ch") 00616 { 00617 cerr << "Misplaced element '" << ch_element->Value() << "' in element 'signals'" << endl; 00618 continue; 00619 } 00620 00621 Channel ch; 00622 ch.setId(ch_element->GetAttributeOrDefault("id", "")); 00623 signal.channels().push_back(ch); 00624 } 00625 } 00626 else 00627 cerr << "Missing element 'channels' in element 'sig'" << endl; 00628 00629 msg.signal_info.signals().insert(make_pair(signal_type, signal)); 00630 } 00631 } 00632 else 00633 cerr << "Missing element 'signals' in 'signalInfo'" << endl; 00634 } 00635 00636 //----------------------------------------------------------------------------- 00637 00638 void ControlMsgDecoderXML::decodeMsg(ReplyMsg& msg) 00639 { 00640 #ifdef DEBUG 00641 cout << "ControlMsgDecoderXML::decodeMsg: decoding ReplyMsg" << endl; 00642 #endif 00643 00644 if (!decodeHeader(msg)) 00645 { 00646 // TODO: do a proper error handling 00647 cerr << "Error decoding ReplyMsg" << endl; 00648 return; 00649 } 00650 00651 switch (msg.msgType()) 00652 { 00653 case ControlMsg::OkReply: 00654 { 00655 ticpp::Element* reply_element = xml_msg_header_->NextSiblingElement(); 00656 if (reply_element == 0 || reply_element->Value() != "okReply") 00657 { 00658 // TODO: do a proper error handling 00659 cerr << "Missing element 'okReply' in ReplyMsg" << endl; 00660 return; 00661 } 00662 break; 00663 } 00664 case ControlMsg::ErrorReply: 00665 { 00666 ticpp::Element* reply_element = xml_msg_header_->NextSiblingElement(); 00667 if (reply_element == 0 || reply_element->Value() != "errorReply") 00668 { 00669 // TODO: do a proper error handling 00670 cerr << "Missing element 'errorReply' in ReplyMsg" << endl; 00671 return; 00672 } 00673 break; 00674 } 00675 00676 default: 00677 { 00678 // TODO: do a proper error handling 00679 cerr << "Catastrophic error - aborting" << endl; 00680 assert(false); 00681 } 00682 } 00683 } 00684 00685 //----------------------------------------------------------------------------- 00686 00687 } // Namespace tobiss 00688 00689 // End Of File