msg.cpp
Go to the documentation of this file.
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 }


aseba
Author(s): Stéphane Magnenat
autogenerated on Sun Oct 5 2014 23:46:38