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