$search
00001 /* 00002 Aseba - an event-based framework for distributed robot control 00003 Copyright (C) 2007--2012: 00004 Stephane Magnenat <stephane at magnenat dot net> 00005 (http://stephane.magnenat.net) 00006 and other contributors, see authors.txt for details 00007 00008 This program is free software: you can redistribute it and/or modify 00009 it under the terms of the GNU Lesser General Public License as published 00010 by the Free Software Foundation, version 3 of the License. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 #include "msg.h" 00022 #include "endian.h" 00023 #include "../utils/utils.h" 00024 #include <typeinfo> 00025 #include <iostream> 00026 #include <iomanip> 00027 #include <map> 00028 #include <dashel/dashel.h> 00029 00030 using namespace std; 00031 00032 namespace Aseba 00033 { 00034 using namespace Dashel; 00035 00037 class MessageTypesInitializer 00038 { 00039 public: 00041 MessageTypesInitializer() 00042 { 00043 registerMessageType<BootloaderDescription>(ASEBA_MESSAGE_BOOTLOADER_DESCRIPTION); 00044 registerMessageType<BootloaderDataRead>(ASEBA_MESSAGE_BOOTLOADER_PAGE_DATA_READ); 00045 registerMessageType<BootloaderAck>(ASEBA_MESSAGE_BOOTLOADER_ACK); 00046 00047 registerMessageType<Description>(ASEBA_MESSAGE_DESCRIPTION); 00048 registerMessageType<NamedVariableDescription>(ASEBA_MESSAGE_NAMED_VARIABLE_DESCRIPTION); 00049 registerMessageType<LocalEventDescription>(ASEBA_MESSAGE_LOCAL_EVENT_DESCRIPTION); 00050 registerMessageType<NativeFunctionDescription>(ASEBA_MESSAGE_NATIVE_FUNCTION_DESCRIPTION); 00051 registerMessageType<Disconnected>(ASEBA_MESSAGE_DISCONNECTED); 00052 registerMessageType<Variables>(ASEBA_MESSAGE_VARIABLES); 00053 registerMessageType<ArrayAccessOutOfBounds>(ASEBA_MESSAGE_ARRAY_ACCESS_OUT_OF_BOUNDS); 00054 registerMessageType<DivisionByZero>(ASEBA_MESSAGE_DIVISION_BY_ZERO); 00055 registerMessageType<EventExecutionKilled>(ASEBA_MESSAGE_EVENT_EXECUTION_KILLED); 00056 registerMessageType<NodeSpecificError>(ASEBA_MESSAGE_NODE_SPECIFIC_ERROR); 00057 registerMessageType<ExecutionStateChanged>(ASEBA_MESSAGE_EXECUTION_STATE_CHANGED); 00058 registerMessageType<BreakpointSetResult>(ASEBA_MESSAGE_BREAKPOINT_SET_RESULT); 00059 00060 registerMessageType<GetDescription>(ASEBA_MESSAGE_GET_DESCRIPTION); 00061 00062 registerMessageType<BootloaderReset>(ASEBA_MESSAGE_BOOTLOADER_RESET); 00063 registerMessageType<BootloaderReadPage>(ASEBA_MESSAGE_BOOTLOADER_READ_PAGE); 00064 registerMessageType<BootloaderWritePage>(ASEBA_MESSAGE_BOOTLOADER_WRITE_PAGE); 00065 registerMessageType<BootloaderPageDataWrite>(ASEBA_MESSAGE_BOOTLOADER_PAGE_DATA_WRITE); 00066 00067 //registerMessageType<AttachDebugger>(ASEBA_MESSAGE_ATTACH_DEBUGGER); 00068 //registerMessageType<DetachDebugger>(ASEBA_MESSAGE_DETACH_DEBUGGER); 00069 registerMessageType<SetBytecode>(ASEBA_MESSAGE_SET_BYTECODE); 00070 registerMessageType<Reset>(ASEBA_MESSAGE_RESET); 00071 registerMessageType<Run>(ASEBA_MESSAGE_RUN); 00072 registerMessageType<Pause>(ASEBA_MESSAGE_PAUSE); 00073 registerMessageType<Step>(ASEBA_MESSAGE_STEP); 00074 registerMessageType<Stop>(ASEBA_MESSAGE_STOP); 00075 registerMessageType<GetExecutionState>(ASEBA_MESSAGE_GET_EXECUTION_STATE); 00076 registerMessageType<BreakpointSet>(ASEBA_MESSAGE_BREAKPOINT_SET); 00077 registerMessageType<BreakpointClear>(ASEBA_MESSAGE_BREAKPOINT_CLEAR); 00078 registerMessageType<BreakpointClearAll>(ASEBA_MESSAGE_BREAKPOINT_CLEAR_ALL); 00079 registerMessageType<GetVariables>(ASEBA_MESSAGE_GET_VARIABLES); 00080 registerMessageType<SetVariables>(ASEBA_MESSAGE_SET_VARIABLES); 00081 registerMessageType<WriteBytecode>(ASEBA_MESSAGE_WRITE_BYTECODE); 00082 registerMessageType<Reboot>(ASEBA_MESSAGE_REBOOT); 00083 registerMessageType<Sleep>(ASEBA_MESSAGE_SUSPEND_TO_RAM); 00084 } 00085 00087 template<typename Sub> 00088 void registerMessageType(uint16 type) 00089 { 00090 messagesTypes[type] = &Creator<Sub>; 00091 } 00092 00094 Message *createMessage(uint16 type) 00095 { 00096 if (messagesTypes.find(type) == messagesTypes.end()) 00097 return new UserMessage; 00098 else 00099 return messagesTypes[type](); 00100 } 00101 00103 void dumpKnownMessagesTypes(wostream &stream) const 00104 { 00105 stream << hex << showbase; 00106 for (map<uint16, CreatorFunc>::const_iterator it = messagesTypes.begin(); it != messagesTypes.end(); ++it) 00107 stream << "\t" << setw(4) << it->first << "\n"; 00108 stream << dec << noshowbase; 00109 } 00110 00111 protected: 00113 typedef Message* (*CreatorFunc)(); 00114 map<uint16, CreatorFunc> messagesTypes; 00115 00117 template<typename Sub> 00118 static Message* Creator() 00119 { 00120 return new Sub(); 00121 } 00122 } messageTypesInitializer; 00123 00124 // 00125 00126 Message::Message(uint16 type) : 00127 source(ASEBA_DEST_DEBUG), 00128 type(type), 00129 readPos(0) 00130 { 00131 } 00132 00133 Message::~Message() 00134 { 00135 00136 } 00137 00138 void Message::serialize(Stream* stream) 00139 { 00140 rawData.resize(0); 00141 serializeSpecific(); 00142 uint16 len = static_cast<uint16>(rawData.size()); 00143 00144 if (len > ASEBA_MAX_EVENT_ARG_SIZE) 00145 { 00146 cerr << "Message::serialize() : fatal error: message size exceed maximum packet size.\n"; 00147 cerr << "message payload size: " << len << ", maximum packet payload size (excluding type): " << ASEBA_MAX_EVENT_ARG_SIZE << ", message type: " << hex << showbase << type << dec << noshowbase; 00148 cerr << endl; 00149 abort(); 00150 } 00151 uint16 t; 00152 swapEndian(len); 00153 stream->write(&len, 2); 00154 t = swapEndianCopy(source); 00155 stream->write(&t, 2); 00156 t = swapEndianCopy(type); 00157 stream->write(&t, 2); 00158 if(rawData.size()) 00159 stream->write(&rawData[0], rawData.size()); 00160 } 00161 00162 Message *Message::receive(Stream* stream) 00163 { 00164 // read header 00165 uint16 len, source, type; 00166 stream->read(&len, 2); 00167 swapEndian(len); 00168 stream->read(&source, 2); 00169 swapEndian(source); 00170 stream->read(&type, 2); 00171 swapEndian(type); 00172 00173 // create message 00174 Message *message = messageTypesInitializer.createMessage(type); 00175 00176 // preapare message 00177 message->source = source; 00178 message->type = type; 00179 message->rawData.resize(len); 00180 if (len) 00181 stream->read(&message->rawData[0], len); 00182 message->readPos = 0; 00183 00184 // deserialize it 00185 message->deserializeSpecific(); 00186 00187 if (message->readPos != message->rawData.size()) 00188 { 00189 cerr << "Message::receive() : fatal error: message not fully read.\n"; 00190 cerr << "type: " << type << ", readPos: " << message->readPos << ", rawData size: " << message->rawData.size() << endl; 00191 message->dumpBuffer(wcerr); 00192 abort(); 00193 } 00194 00195 return message; 00196 } 00197 00198 void Message::dump(wostream &stream) const 00199 { 00200 stream << hex << showbase << setw(4) << type << " "; 00201 stream << dec << noshowbase << *this << " from "; 00202 stream << source << " : "; 00203 dumpSpecific(stream); 00204 } 00205 00206 void Message::dumpBuffer(std::wostream &stream) const 00207 { 00208 for (size_t i = 0; i < rawData.size(); ++i) 00209 stream << (unsigned)(rawData[i]) << " (" << rawData[i] << "), "; 00210 stream << endl; 00211 } 00212 00213 template<typename T> 00214 void Message::add(const T& val) 00215 { 00216 size_t pos = rawData.size(); 00217 rawData.reserve(pos + sizeof(T)); 00218 00219 const T swappedVal(swapEndianCopy(val)); 00220 const uint8 *ptr = reinterpret_cast<const uint8 *>(&swappedVal); 00221 00222 copy(ptr, ptr + sizeof(T), back_inserter(rawData)); 00223 } 00224 00225 template<> 00226 void Message::add(const string& val) 00227 { 00228 if (val.length() > 255) 00229 { 00230 cerr << "Message::add<string>() : fatal error, string length exceeds 255 characters.\n"; 00231 cerr << "string size: " << val.length(); 00232 cerr << endl; 00233 dumpBuffer(wcerr); 00234 abort(); 00235 } 00236 00237 add(static_cast<uint8>(val.length())); 00238 for (size_t i = 0; i < val.length(); i++) 00239 add(val[i]); 00240 } 00241 00242 template<typename T> 00243 T Message::get() 00244 { 00245 if (readPos + sizeof(T) > rawData.size()) 00246 { 00247 cerr << "Message<" << typeid(T).name() << ">::get() : fatal error: attempt to overread.\n"; 00248 cerr << "type: " << type << ", readPos: " << readPos << ", rawData size: " << rawData.size() << ", element size: " << sizeof(T); 00249 cerr << endl; 00250 dumpBuffer(wcerr); 00251 abort(); 00252 } 00253 00254 size_t pos = readPos; 00255 readPos += sizeof(T); 00256 T val; 00257 uint8 *ptr = reinterpret_cast<uint8 *>(&val); 00258 copy(rawData.begin() + pos, rawData.begin() + pos + sizeof(T), ptr); 00259 swapEndian(val); 00260 return val; 00261 } 00262 00263 template<> 00264 string Message::get() 00265 { 00266 string s; 00267 size_t len = get<uint8>(); 00268 s.resize(len); 00269 for (size_t i = 0; i < len; i++) 00270 s[i] = get<uint8>(); 00271 return s; 00272 } 00273 00274 // 00275 00276 UserMessage::UserMessage(uint16 type, const sint16* data, const size_t length): 00277 Message(type) 00278 { 00279 this->data.resize(length); 00280 copy(data, data+length, this->data.begin()); 00281 } 00282 00283 void UserMessage::serializeSpecific() 00284 { 00285 for (size_t i = 0; i < data.size(); i++) 00286 add(data[i]); 00287 } 00288 00289 void UserMessage::deserializeSpecific() 00290 { 00291 if (rawData.size() % 2 != 0) 00292 { 00293 cerr << "UserMessage::deserializeSpecific() : fatal error: odd size.\n"; 00294 cerr << "message size: " << rawData.size() << ", message type: " << type; 00295 cerr << endl; 00296 abort(); 00297 } 00298 data.resize(rawData.size() / 2); 00299 00300 for (size_t i = 0; i < data.size(); i++) 00301 data[i] = get<sint16>(); 00302 } 00303 00304 void UserMessage::dumpSpecific(wostream &stream) const 00305 { 00306 stream << dec << "user message of size " << data.size() << " : "; 00307 for (size_t i = 0 ; i < data.size(); i++) 00308 stream << setw(4) << data[i] << " "; 00309 stream << dec << setfill(wchar_t(' ')); 00310 } 00311 00312 // 00313 00314 void BootloaderDescription::serializeSpecific() 00315 { 00316 add(pageSize); 00317 add(pagesStart); 00318 add(pagesCount); 00319 } 00320 00321 void BootloaderDescription::deserializeSpecific() 00322 { 00323 pageSize = get<uint16>(); 00324 pagesStart = get<uint16>(); 00325 pagesCount = get<uint16>(); 00326 } 00327 00328 void BootloaderDescription::dumpSpecific(wostream &stream) const 00329 { 00330 stream << pagesCount << " pages of size " << pageSize << " starting at page " << pagesStart; 00331 } 00332 00333 00334 // 00335 00336 void BootloaderDataRead::serializeSpecific() 00337 { 00338 for (size_t i = 0 ; i < sizeof(data); i++) 00339 add(data[i]); 00340 } 00341 00342 void BootloaderDataRead::deserializeSpecific() 00343 { 00344 for (size_t i = 0 ; i < sizeof(data); i++) 00345 data[i] = get<uint8>(); 00346 } 00347 00348 void BootloaderDataRead::dumpSpecific(wostream &stream) const 00349 { 00350 stream << hex << setfill(wchar_t('0')); 00351 for (size_t i = 0 ; i < sizeof(data); i++) 00352 stream << setw(2) << (unsigned)data[i] << " "; 00353 stream << dec << setfill(wchar_t(' ')); 00354 } 00355 00356 // 00357 00358 void BootloaderAck::serializeSpecific() 00359 { 00360 add(errorCode); 00361 if (errorCode == 2) 00362 add(errorAddress); 00363 } 00364 00365 void BootloaderAck::deserializeSpecific() 00366 { 00367 errorCode = get<uint16>(); 00368 if (errorCode == 2) 00369 errorAddress = get<uint16>(); 00370 } 00371 00372 void BootloaderAck::dumpSpecific(wostream &stream) const 00373 { 00374 switch (errorCode) 00375 { 00376 case SUCCESS: stream << "success"; break; 00377 case ERROR_INVALID_FRAME_SIZE: stream << "error, invalid frame size"; break; 00378 case ERROR_PROGRAMMING_FAILED: stream << "error, programming failed at low address " << hex << showbase << errorAddress; break; 00379 case ERROR_NOT_PROGRAMMING: stream << "error, not programming"; break; 00380 default: stream << "unknown error"; break; 00381 } 00382 stream << dec << noshowbase; 00383 } 00384 00385 // 00386 00387 void GetDescription::serializeSpecific() 00388 { 00389 add(version); 00390 } 00391 00392 void GetDescription::deserializeSpecific() 00393 { 00394 version = get<uint16>(); 00395 } 00396 00397 void GetDescription::dumpSpecific(std::wostream &stream) const 00398 { 00399 stream << "protocol version " << version; 00400 } 00401 00402 // 00403 00404 void Description::serializeSpecific() 00405 { 00406 add(WStringToUTF8(name)); 00407 add(static_cast<uint16>(protocolVersion)); 00408 00409 add(static_cast<uint16>(bytecodeSize)); 00410 add(static_cast<uint16>(stackSize)); 00411 add(static_cast<uint16>(variablesSize)); 00412 00413 add(static_cast<uint16>(namedVariables.size())); 00414 // named variables are sent separately 00415 00416 add(static_cast<uint16>(localEvents.size())); 00417 // local events are sent separately 00418 00419 add(static_cast<uint16>(nativeFunctions.size())); 00420 // native functions are sent separately 00421 } 00422 00423 void Description::deserializeSpecific() 00424 { 00425 name = UTF8ToWString(get<string>()); 00426 protocolVersion = get<uint16>(); 00427 00428 bytecodeSize = get<uint16>(); 00429 stackSize = get<uint16>(); 00430 variablesSize = get<uint16>(); 00431 00432 namedVariables.resize(get<uint16>()); 00433 // named variables are received separately 00434 00435 localEvents.resize(get<uint16>()); 00436 // local events are received separately 00437 00438 nativeFunctions.resize(get<uint16>()); 00439 // native functions are received separately 00440 } 00441 00442 void Description::dumpSpecific(wostream &stream) const 00443 { 00444 stream << "Node " << name << " using protocol version " << protocolVersion << "\n"; 00445 stream << "bytecode: " << bytecodeSize << ", stack: " << stackSize << ", variables: " << variablesSize; 00446 00447 stream << "\nnamed variables: " << namedVariables.size() << "\n"; 00448 // named variables are available separately 00449 00450 stream << "\nlocal events: " << localEvents.size() << "\n"; 00451 // local events are available separately 00452 00453 stream << "native functions: " << nativeFunctions.size(); 00454 // native functions are available separately 00455 } 00456 00457 // 00458 00459 void NamedVariableDescription::serializeSpecific() 00460 { 00461 add(static_cast<sint16>(size)); 00462 add(WStringToUTF8(name)); 00463 } 00464 00465 void NamedVariableDescription::deserializeSpecific() 00466 { 00467 size = get<uint16>(); 00468 name = UTF8ToWString(get<string>()); 00469 } 00470 00471 void NamedVariableDescription::dumpSpecific(std::wostream &stream) const 00472 { 00473 stream << name << " of size " << size; 00474 } 00475 00476 // 00477 00478 void LocalEventDescription::serializeSpecific() 00479 { 00480 add(WStringToUTF8(name)); 00481 add(WStringToUTF8(description)); 00482 } 00483 00484 void LocalEventDescription::deserializeSpecific() 00485 { 00486 name = UTF8ToWString(get<string>()); 00487 description = UTF8ToWString(get<string>()); 00488 } 00489 00490 void LocalEventDescription::dumpSpecific(std::wostream &stream) const 00491 { 00492 stream << name << " : " << description; 00493 } 00494 00495 // 00496 00497 void NativeFunctionDescription::serializeSpecific() 00498 { 00499 add(WStringToUTF8(name)); 00500 add(WStringToUTF8(description)); 00501 00502 add(static_cast<uint16>(parameters.size())); 00503 for (size_t j = 0; j < parameters.size(); j++) 00504 { 00505 add(static_cast<sint16>(parameters[j].size)); 00506 add(WStringToUTF8(parameters[j].name)); 00507 } 00508 } 00509 00510 void NativeFunctionDescription::deserializeSpecific() 00511 { 00512 name = UTF8ToWString(get<string>()); 00513 description = UTF8ToWString(get<string>()); 00514 00515 parameters.resize(get<uint16>()); 00516 for (size_t j = 0; j < parameters.size(); j++) 00517 { 00518 parameters[j].size = get<sint16>(); 00519 parameters[j].name = UTF8ToWString(get<string>()); 00520 } 00521 } 00522 00523 void NativeFunctionDescription::dumpSpecific(std::wostream &stream) const 00524 { 00525 stream << name << " ("; 00526 for (size_t j = 0; j < parameters.size(); j++) 00527 { 00528 stream << parameters[j].name; 00529 stream << "<" << parameters[j].size << ">"; 00530 if (j + 1 < parameters.size()) 00531 stream << ", "; 00532 } 00533 stream << ") : " << description; 00534 } 00535 00536 // 00537 00538 void Variables::serializeSpecific() 00539 { 00540 add(start); 00541 for (size_t i = 0; i < variables.size(); i++) 00542 add(variables[i]); 00543 } 00544 00545 void Variables::deserializeSpecific() 00546 { 00547 start = get<uint16>(); 00548 variables.resize((rawData.size() - readPos) / 2); 00549 for (size_t i = 0; i < variables.size(); i++) 00550 variables[i] = get<sint16>(); 00551 } 00552 00553 void Variables::dumpSpecific(wostream &stream) const 00554 { 00555 stream << "start " << start << ", variables vector of size " << variables.size(); 00556 /*for (size_t i = 0; i < variables.size(); i++) 00557 stream << "\n " << i << " : " << variables[i]; 00558 stream << "\n";*/ 00559 } 00560 00561 // 00562 00563 void ArrayAccessOutOfBounds::serializeSpecific() 00564 { 00565 add(pc); 00566 add(size); 00567 add(index); 00568 } 00569 00570 void ArrayAccessOutOfBounds::deserializeSpecific() 00571 { 00572 pc = get<uint16>(); 00573 size = get<uint16>(); 00574 index = get<uint16>(); 00575 } 00576 00577 void ArrayAccessOutOfBounds::dumpSpecific(wostream &stream) const 00578 { 00579 stream << "pc " << pc << ", size " << size << ", index " << index ; 00580 } 00581 00582 // 00583 00584 void DivisionByZero::serializeSpecific() 00585 { 00586 add(pc); 00587 } 00588 00589 void DivisionByZero::deserializeSpecific() 00590 { 00591 pc = get<uint16>(); 00592 } 00593 00594 void DivisionByZero::dumpSpecific(wostream &stream) const 00595 { 00596 stream << "pc " << pc; 00597 } 00598 00599 // 00600 00601 void EventExecutionKilled::serializeSpecific() 00602 { 00603 add(pc); 00604 } 00605 00606 void EventExecutionKilled::deserializeSpecific() 00607 { 00608 pc = get<uint16>(); 00609 } 00610 00611 void EventExecutionKilled::dumpSpecific(wostream &stream) const 00612 { 00613 stream << "pc " << pc; 00614 } 00615 00616 // 00617 00618 void NodeSpecificError::serializeSpecific() 00619 { 00620 add(pc); 00621 add(WStringToUTF8(message)); 00622 } 00623 00624 void NodeSpecificError::deserializeSpecific() 00625 { 00626 pc = get<uint16>(); 00627 message = UTF8ToWString(get<std::string>()); 00628 } 00629 00630 void NodeSpecificError::dumpSpecific(wostream &stream) const 00631 { 00632 stream << "pc " << pc << " " << message; 00633 } 00634 00635 // 00636 00637 void ExecutionStateChanged::serializeSpecific() 00638 { 00639 add(pc); 00640 add(flags); 00641 } 00642 00643 void ExecutionStateChanged::deserializeSpecific() 00644 { 00645 pc = get<uint16>(); 00646 flags = get<uint16>(); 00647 } 00648 00649 void ExecutionStateChanged::dumpSpecific(wostream &stream) const 00650 { 00651 stream << "pc " << pc << ", flags "; 00652 stream << hex << showbase << setw(4) << flags; 00653 stream << dec << noshowbase; 00654 } 00655 00656 // 00657 00658 void BreakpointSetResult::serializeSpecific() 00659 { 00660 add(pc); 00661 add(success); 00662 } 00663 00664 void BreakpointSetResult::deserializeSpecific() 00665 { 00666 pc = get<uint16>(); 00667 success = get<uint16>(); 00668 } 00669 00670 void BreakpointSetResult::dumpSpecific(wostream &stream) const 00671 { 00672 stream << "pc " << pc << ", success " << success; 00673 } 00674 00675 // 00676 00677 void CmdMessage::serializeSpecific() 00678 { 00679 add(dest); 00680 } 00681 00682 void CmdMessage::deserializeSpecific() 00683 { 00684 dest = get<uint16>(); 00685 } 00686 00687 void CmdMessage::dumpSpecific(wostream &stream) const 00688 { 00689 stream << "dest " << dest << " "; 00690 } 00691 00692 // 00693 00694 void BootloaderReadPage::serializeSpecific() 00695 { 00696 CmdMessage::serializeSpecific(); 00697 00698 add(pageNumber); 00699 } 00700 00701 void BootloaderReadPage::deserializeSpecific() 00702 { 00703 CmdMessage::deserializeSpecific(); 00704 00705 pageNumber = get<uint16>(); 00706 } 00707 00708 void BootloaderReadPage::dumpSpecific(wostream &stream) const 00709 { 00710 CmdMessage::dumpSpecific(stream); 00711 00712 stream << "page " << pageNumber; 00713 } 00714 00715 // 00716 00717 void BootloaderWritePage::serializeSpecific() 00718 { 00719 CmdMessage::serializeSpecific(); 00720 00721 add(pageNumber); 00722 } 00723 00724 void BootloaderWritePage::deserializeSpecific() 00725 { 00726 CmdMessage::deserializeSpecific(); 00727 00728 pageNumber = get<uint16>(); 00729 } 00730 00731 void BootloaderWritePage::dumpSpecific(wostream &stream) const 00732 { 00733 CmdMessage::dumpSpecific(stream); 00734 00735 stream << "page " << pageNumber; 00736 } 00737 00738 // 00739 00740 void BootloaderPageDataWrite::serializeSpecific() 00741 { 00742 CmdMessage::serializeSpecific(); 00743 00744 for (size_t i = 0 ; i < sizeof(data); i++) 00745 add(data[i]); 00746 } 00747 00748 void BootloaderPageDataWrite::deserializeSpecific() 00749 { 00750 CmdMessage::deserializeSpecific(); 00751 00752 for (size_t i = 0 ; i < sizeof(data); i++) 00753 data[i] = get<uint8>(); 00754 } 00755 00756 void BootloaderPageDataWrite::dumpSpecific(wostream &stream) const 00757 { 00758 CmdMessage::dumpSpecific(stream); 00759 00760 stream << hex << setfill(wchar_t('0')); 00761 for (size_t i = 0 ; i < sizeof(data); i++) 00762 stream << setw(2) << (unsigned)data[i] << " "; 00763 stream << dec << setfill(wchar_t(' ')); 00764 } 00765 00766 // 00767 00768 void SetBytecode::serializeSpecific() 00769 { 00770 CmdMessage::serializeSpecific(); 00771 00772 add(start); 00773 for (size_t i = 0; i < bytecode.size(); i++) 00774 add(bytecode[i]); 00775 } 00776 00777 void SetBytecode::deserializeSpecific() 00778 { 00779 CmdMessage::deserializeSpecific(); 00780 00781 start = get<uint16>(); 00782 bytecode.resize((rawData.size() - readPos) / 2); 00783 for (size_t i = 0; i < bytecode.size(); i++) 00784 bytecode[i] = get<uint16>(); 00785 } 00786 00787 void SetBytecode::dumpSpecific(wostream &stream) const 00788 { 00789 CmdMessage::dumpSpecific(stream); 00790 00791 stream << bytecode.size() << " words of bytecode of starting at " << start; 00792 } 00793 00794 void sendBytecode(Dashel::Stream* stream, uint16 dest, const std::vector<uint16>& bytecode) 00795 { 00796 unsigned bytecodePayloadSize = ASEBA_MAX_EVENT_ARG_COUNT-2; 00797 unsigned bytecodeStart = 0; 00798 unsigned bytecodeCount = bytecode.size(); 00799 00800 while (bytecodeCount > bytecodePayloadSize) 00801 { 00802 SetBytecode setBytecodeMessage(dest, bytecodeStart); 00803 setBytecodeMessage.bytecode.resize(bytecodePayloadSize); 00804 copy(bytecode.begin()+bytecodeStart, bytecode.begin()+bytecodeStart+bytecodePayloadSize, setBytecodeMessage.bytecode.begin()); 00805 setBytecodeMessage.serialize(stream); 00806 00807 bytecodeStart += bytecodePayloadSize; 00808 bytecodeCount -= bytecodePayloadSize; 00809 } 00810 00811 { 00812 SetBytecode setBytecodeMessage(dest, bytecodeStart); 00813 setBytecodeMessage.bytecode.resize(bytecodeCount); 00814 copy(bytecode.begin()+bytecodeStart, bytecode.end(), setBytecodeMessage.bytecode.begin()); 00815 setBytecodeMessage.serialize(stream); 00816 } 00817 } 00818 00819 void sendBytecode(std::vector<Message*>& messagesVector, uint16 dest, const std::vector<uint16>& bytecode) 00820 { 00821 unsigned bytecodePayloadSize = ASEBA_MAX_EVENT_ARG_COUNT-2; 00822 unsigned bytecodeStart = 0; 00823 unsigned bytecodeCount = bytecode.size(); 00824 00825 while (bytecodeCount > bytecodePayloadSize) 00826 { 00827 SetBytecode* setBytecodeMessage = new SetBytecode(dest, bytecodeStart); 00828 setBytecodeMessage->bytecode.resize(bytecodePayloadSize); 00829 copy(bytecode.begin()+bytecodeStart, bytecode.begin()+bytecodeStart+bytecodePayloadSize, setBytecodeMessage->bytecode.begin()); 00830 messagesVector.push_back(setBytecodeMessage); 00831 00832 bytecodeStart += bytecodePayloadSize; 00833 bytecodeCount -= bytecodePayloadSize; 00834 } 00835 00836 { 00837 SetBytecode* setBytecodeMessage = new SetBytecode(dest, bytecodeStart); 00838 setBytecodeMessage->bytecode.resize(bytecodeCount); 00839 copy(bytecode.begin()+bytecodeStart, bytecode.end(), setBytecodeMessage->bytecode.begin()); 00840 messagesVector.push_back(setBytecodeMessage); 00841 } 00842 } 00843 00844 // 00845 00846 void BreakpointSet::serializeSpecific() 00847 { 00848 CmdMessage::serializeSpecific(); 00849 00850 add(pc); 00851 } 00852 00853 void BreakpointSet::deserializeSpecific() 00854 { 00855 CmdMessage::deserializeSpecific(); 00856 00857 pc = get<uint16>(); 00858 } 00859 00860 void BreakpointSet::dumpSpecific(wostream &stream) const 00861 { 00862 CmdMessage::dumpSpecific(stream); 00863 00864 stream << "pc " << pc; 00865 } 00866 00867 // 00868 00869 void BreakpointClear::serializeSpecific() 00870 { 00871 CmdMessage::serializeSpecific(); 00872 00873 add(pc); 00874 } 00875 00876 void BreakpointClear::deserializeSpecific() 00877 { 00878 CmdMessage::deserializeSpecific(); 00879 00880 pc = get<uint16>(); 00881 } 00882 00883 void BreakpointClear::dumpSpecific(wostream &stream) const 00884 { 00885 CmdMessage::dumpSpecific(stream); 00886 00887 stream << "pc " << pc; 00888 } 00889 00890 // 00891 00892 GetVariables::GetVariables(uint16 dest, uint16 start, uint16 length) : 00893 CmdMessage(ASEBA_MESSAGE_GET_VARIABLES, dest), 00894 start(start), 00895 length(length) 00896 { 00897 } 00898 00899 void GetVariables::serializeSpecific() 00900 { 00901 CmdMessage::serializeSpecific(); 00902 00903 add(start); 00904 add(length); 00905 } 00906 00907 void GetVariables::deserializeSpecific() 00908 { 00909 CmdMessage::deserializeSpecific(); 00910 00911 start = get<uint16>(); 00912 length = get<uint16>(); 00913 } 00914 00915 void GetVariables::dumpSpecific(wostream &stream) const 00916 { 00917 CmdMessage::dumpSpecific(stream); 00918 00919 stream << "start " << start << ", length " << length; 00920 } 00921 00922 // 00923 00924 SetVariables::SetVariables(uint16 dest, uint16 start, const VariablesVector& variables) : 00925 CmdMessage(ASEBA_MESSAGE_SET_VARIABLES, dest), 00926 start(start), 00927 variables(variables) 00928 { 00929 } 00930 00931 void SetVariables::serializeSpecific() 00932 { 00933 CmdMessage::serializeSpecific(); 00934 00935 add(start); 00936 for (size_t i = 0; i < variables.size(); i++) 00937 add(variables[i]); 00938 } 00939 00940 void SetVariables::deserializeSpecific() 00941 { 00942 CmdMessage::deserializeSpecific(); 00943 00944 start = get<uint16>(); 00945 variables.resize((rawData.size() - readPos) / 2); 00946 for (size_t i = 0; i < variables.size(); i++) 00947 variables[i] = get<sint16>(); 00948 } 00949 00950 void SetVariables::dumpSpecific(wostream &stream) const 00951 { 00952 CmdMessage::dumpSpecific(stream); 00953 00954 stream << "start " << start << ", variables vector of size " << variables.size(); 00955 } 00956 }