00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00068
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
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
00174 Message *message = messageTypesInitializer.createMessage(type);
00175
00176
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
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
00415
00416 add(static_cast<uint16>(localEvents.size()));
00417
00418
00419 add(static_cast<uint16>(nativeFunctions.size()));
00420
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
00434
00435 localEvents.resize(get<uint16>());
00436
00437
00438 nativeFunctions.resize(get<uint16>());
00439
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
00449
00450 stream << "\nlocal events: " << localEvents.size() << "\n";
00451
00452
00453 stream << "native functions: " << nativeFunctions.size();
00454
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
00557
00558
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 }