packet.cc

Go to the documentation of this file.
00001 ///
00002 /// \file       packet.cc
00003 ///             Low level protocol packet builder class.
00004 ///             Has knowledge of specific protocol commands in order
00005 ///             to hide protocol details behind an API.
00006 ///
00007 
00008 /*
00009     Copyright (C) 2005-2010, Net Direct Inc. (http://www.netdirect.ca/)
00010 
00011     This program is free software; you can redistribute it and/or modify
00012     it under the terms of the GNU General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or
00014     (at your option) any later version.
00015 
00016     This program is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00019 
00020     See the GNU General Public License in the COPYING file at the
00021     root directory of this project for more details.
00022 */
00023 
00024 #include "packet.h"
00025 #include "m_desktop.h"
00026 #include "protocol.h"
00027 #include "protostructs.h"
00028 #include "data.h"
00029 #include "endian.h"
00030 #include "parser.h"
00031 #include "builder.h"
00032 #include "error.h"
00033 #include <string.h>
00034 
00035 #define __DEBUG_MODE__
00036 #include "debug.h"
00037 
00038 
00039 namespace Barry {
00040 
00041 //////////////////////////////////////////////////////////////////////////////
00042 // Packet base class
00043 
00044 //
00045 // Command
00046 //
00047 /// Returns the command value of the receive packet.  If receive isn't
00048 /// large enough, throws Error.
00049 ///
00050 unsigned int Packet::Command() const
00051 {
00052         Protocol::CheckSize(m_receive, SB_PACKET_HEADER_SIZE);
00053         MAKE_PACKET(rpack, m_receive);
00054         return rpack->command;
00055 }
00056 
00057 
00058 //////////////////////////////////////////////////////////////////////////////
00059 // ZeroPacket class
00060 
00061 ZeroPacket::ZeroPacket(Data &send, Data &receive)
00062         : Packet(send, receive)
00063 {
00064 }
00065 
00066 ZeroPacket::~ZeroPacket()
00067 {
00068 }
00069 
00070 //
00071 // GetAttribute
00072 //
00073 /// Builds a command packet for the initial socket-0 handshakes
00074 /// that fetch certain (some unknown) attributes.  The attributes
00075 /// appear to exist in an object/attribute sequence, so that's
00076 /// how we address them here.
00077 ///
00078 void ZeroPacket::GetAttribute(unsigned int object, unsigned int attribute)
00079 {
00080         size_t size = SB_SOCKET_PACKET_HEADER_SIZE + ATTRIBUTE_FETCH_COMMAND_SIZE;
00081         MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(size));
00082         Protocol::Packet &packet = *cpack;
00083 
00084         // socket class sets socket for us
00085         packet.size = htobs(size);
00086         packet.command = SB_COMMAND_FETCH_ATTRIBUTE;
00087         packet.u.socket.socket = htobs(0x00ff); // default non-socket request
00088         packet.u.socket.sequence = 0;           // filled in by Socket class
00089         packet.u.socket.u.fetch.object = htobs(object);
00090         packet.u.socket.u.fetch.attribute = htobs(attribute);
00091 
00092         m_send.ReleaseBuffer(size);
00093 }
00094 
00095 //
00096 // Echo
00097 //
00098 /// Builds command packet for sending echo request.  The parameter
00099 /// to this command is the number of microseconds elapsed since host
00100 /// computer startup.
00101 ///
00102 void ZeroPacket::Echo(uint64_t us_ticks)
00103 {
00104         size_t size = SB_SOCKET_PACKET_HEADER_SIZE + ECHO_COMMAND_SIZE;
00105         MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(size));
00106         Protocol::Packet &packet = *cpack;
00107 
00108         packet.size = htobs(size);
00109         packet.command = SB_COMMAND_ECHO;
00110         packet.u.socket.socket = htobs(0x00ff); // default non-socket request
00111         packet.u.socket.sequence = 0;           // filled in by Socket class
00112         packet.u.socket.u.echo.ticks = htobl(us_ticks);
00113 
00114         m_send.ReleaseBuffer(size);
00115 }
00116 
00117 void ZeroPacket::Reset()
00118 {
00119         size_t size = SB_SOCKET_PACKET_HEADER_SIZE;
00120         MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(size));
00121         Protocol::Packet &packet = *cpack;
00122 
00123         packet.size = htobs(size);
00124         packet.command = SB_COMMAND_RESET;
00125         packet.u.socket.socket = htobs(0x00ff); // default non-socket request
00126         packet.u.socket.sequence = 0;           // filled in by Socket class
00127 
00128         m_send.ReleaseBuffer(size);
00129 }
00130 
00131 unsigned int ZeroPacket::ObjectID() const
00132 {
00133         Protocol::CheckSize(m_receive, SB_SOCKET_PACKET_HEADER_SIZE);
00134         MAKE_PACKET(rpack, m_receive);
00135         return btohs(rpack->u.socket.u.fetch.object);
00136 }
00137 
00138 unsigned int ZeroPacket::AttributeID() const
00139 {
00140         Protocol::CheckSize(m_receive, SB_SOCKET_PACKET_HEADER_SIZE);
00141         MAKE_PACKET(rpack, m_receive);
00142         return btohs(rpack->u.socket.u.fetch.attribute);
00143 }
00144 
00145 uint32_t ZeroPacket::ChallengeSeed() const
00146 {
00147         Protocol::CheckSize(m_receive, SB_SOCKET_PACKET_HEADER_SIZE +
00148                 PASSWORD_CHALLENGE_SEED_SIZE);
00149         MAKE_PACKET(rpack, m_receive);
00150         return btohl(rpack->u.socket.u.password.u.seed);
00151 }
00152 
00153 unsigned int ZeroPacket::RemainingTries() const
00154 {
00155         Protocol::CheckSize(m_receive, SB_SOCKET_PACKET_HEADER_SIZE +
00156                 PASSWORD_CHALLENGE_HEADER_SIZE);
00157         MAKE_PACKET(rpack, m_receive);
00158         // this is a byte, so no byte swapping needed
00159         return rpack->u.socket.u.password.remaining_tries;
00160 }
00161 
00162 unsigned int ZeroPacket::SocketResponse() const
00163 {
00164         Protocol::CheckSize(m_receive, SB_SOCKET_PACKET_HEADER_SIZE);
00165         MAKE_PACKET(rpack, m_receive);
00166         return btohs(rpack->u.socket.socket);
00167 }
00168 
00169 unsigned char ZeroPacket::SocketSequence() const
00170 {
00171         Protocol::CheckSize(m_receive, SB_SOCKET_PACKET_HEADER_SIZE);
00172         MAKE_PACKET(rpack, m_receive);
00173         return rpack->u.socket.sequence;        // sequence is a byte
00174 }
00175 
00176 uint8_t ZeroPacket::CommandResponse() const
00177 {
00178         Protocol::CheckSize(m_receive, SB_SOCKET_PACKET_HEADER_SIZE);
00179         MAKE_PACKET(rpack, m_receive);
00180         return rpack->command;
00181 }
00182 
00183 
00184 
00185 //////////////////////////////////////////////////////////////////////////////
00186 // DBPacket class
00187 
00188 DBPacket::DBPacket(Mode::Desktop &con, Data &send, Data &receive)
00189         : Packet(send, receive)
00190         , m_con(con)
00191         , m_last_dbop(0)
00192 {
00193 }
00194 
00195 DBPacket::~DBPacket()
00196 {
00197 }
00198 
00199 //
00200 // ClearDatabase
00201 //
00202 /// Builds a command packet for the CLEAR_DATABASE command code, placing
00203 /// the data in the send buffer.
00204 ///
00205 void DBPacket::ClearDatabase(unsigned int dbId)
00206 {
00207         MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(9));
00208         Protocol::Packet &packet = *cpack;
00209 
00210         // socket class sets socket for us
00211         packet.size = htobs(9);
00212         packet.command = SB_COMMAND_DB_DATA;
00213         packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
00214         packet.u.db.u.command.operation = SB_DBOP_CLEAR_DATABASE;
00215         packet.u.db.u.command.databaseId = htobs(dbId);
00216 
00217         m_send.ReleaseBuffer(9);
00218 
00219         m_last_dbop = SB_DBOP_CLEAR_DATABASE;
00220 }
00221 
00222 //
00223 // GetDBDB
00224 //
00225 /// Builds a command packet for the GET_DBDB command code, placing the
00226 /// data in m_send.
00227 ///
00228 void DBPacket::GetDBDB()
00229 {
00230         MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(7));
00231         Protocol::Packet &packet = *cpack;
00232 
00233         // socket class sets socket for us
00234         packet.size = htobs(7);
00235         packet.command = SB_COMMAND_DB_DATA;
00236         packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
00237 //      packet.u.db.u.command.operation = SB_DBOP_GET_DBDB;
00238         packet.u.db.u.command.operation = SB_DBOP_OLD_GET_DBDB;
00239 
00240         m_send.ReleaseBuffer(7);
00241 
00242         m_last_dbop = SB_DBOP_OLD_GET_DBDB;
00243 }
00244 
00245 //
00246 // GetRecordStateTable
00247 //
00248 /// Builds a command packet in the send buffer for the
00249 /// GET_RECORD_STATE_TABLE command.
00250 ///
00251 void DBPacket::GetRecordStateTable(unsigned int dbId)
00252 {
00253         MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(9));
00254         Protocol::Packet &packet = *cpack;
00255 
00256         // socket class sets socket for us
00257         packet.size = htobs(9);
00258         packet.command = SB_COMMAND_DB_DATA;
00259         packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
00260         packet.u.db.u.command.operation = SB_DBOP_GET_RECORD_STATE_TABLE;
00261         packet.u.db.u.command.databaseId = htobs(dbId);
00262 
00263         m_send.ReleaseBuffer(9);
00264 
00265         m_last_dbop = SB_DBOP_GET_RECORD_STATE_TABLE;
00266 }
00267 
00268 //
00269 // SetRecordFlags
00270 //
00271 /// Builds a command packet in the send buffer for the SET_RECORD_FLAGS
00272 /// command code.
00273 ///
00274 /// FIXME - this API call is incomplete, since there are unknown flags
00275 ///         in the SetRecordFlags protocol packet.  Currently it is only
00276 ///         used to set all flags to zero.
00277 ///
00278 void DBPacket::SetRecordFlags(unsigned int dbId, unsigned int stateTableIndex,
00279                             uint8_t flag1)
00280 {
00281         size_t size = SB_PACKET_COMMAND_HEADER_SIZE + DBC_RECORD_FLAGS_SIZE;
00282         MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(size));
00283         Protocol::Packet &packet = *cpack;
00284 
00285         // socket class sets socket for us
00286         packet.size = htobs(size);
00287         packet.command = SB_COMMAND_DB_DATA;
00288         packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
00289         packet.u.db.u.command.operation = SB_DBOP_SET_RECORD_FLAGS;
00290         packet.u.db.u.command.databaseId = htobs(dbId);
00291         packet.u.db.u.command.u.flags.unknown = flag1;
00292         packet.u.db.u.command.u.flags.index = htobs(stateTableIndex);
00293         memset(packet.u.db.u.command.u.flags.unknown2, 0, sizeof(packet.u.db.u.command.u.flags.unknown2));
00294 
00295         m_send.ReleaseBuffer(size);
00296 
00297         m_last_dbop = SB_DBOP_SET_RECORD_FLAGS;
00298 }
00299 
00300 //
00301 // DeleteRecordByIndex
00302 //
00303 /// Builds a command packet in the send buffer for the DELETE_RECORD_BY_INDEX
00304 /// command code.
00305 ///
00306 void DBPacket::DeleteRecordByIndex(unsigned int dbId, unsigned int stateTableIndex)
00307 {
00308         size_t size = SB_PACKET_COMMAND_HEADER_SIZE + DBC_RECORD_HEADER_SIZE;
00309         MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(size));
00310         Protocol::Packet &packet = *cpack;
00311 
00312         // socket class sets socket for us
00313         packet.size = htobs(size);
00314         packet.command = SB_COMMAND_DB_DATA;
00315         packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
00316         packet.u.db.u.command.operation = SB_DBOP_DELETE_RECORD_BY_INDEX;
00317         packet.u.db.u.command.databaseId = htobs(dbId);
00318         packet.u.db.u.command.u.record.recordIndex = htobs(stateTableIndex);
00319 
00320         m_send.ReleaseBuffer(size);
00321 
00322         m_last_dbop = SB_DBOP_DELETE_RECORD_BY_INDEX;
00323 }
00324 
00325 //
00326 // GetRecordByIndex
00327 //
00328 /// Builds a command packet in the send buffer for the GET_RECORD_BY_INDEX
00329 /// command code.
00330 ///
00331 void DBPacket::GetRecordByIndex(unsigned int dbId, unsigned int stateTableIndex)
00332 {
00333         MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(11));
00334         Protocol::Packet &packet = *cpack;
00335 
00336         // socket class sets socket for us
00337         packet.size = htobs(11);
00338         packet.command = SB_COMMAND_DB_DATA;
00339         packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
00340         packet.u.db.u.command.operation = SB_DBOP_GET_RECORD_BY_INDEX;
00341         packet.u.db.u.command.databaseId = htobs(dbId);
00342         packet.u.db.u.command.u.record.recordIndex = htobs(stateTableIndex);
00343 
00344         m_send.ReleaseBuffer(11);
00345 
00346         m_last_dbop = SB_DBOP_GET_RECORD_BY_INDEX;
00347 }
00348 
00349 //
00350 // SetRecordByIndex
00351 //
00352 /// Builds a command packet in the m_send buffer for the SET_RECORD_BY_INDEX
00353 /// command code.
00354 ///
00355 /// \return     bool
00356 ///             - true means success
00357 ///             - false means no data available from Builder object
00358 ///
00359 bool DBPacket::SetRecordByIndex(unsigned int dbId, unsigned int stateTableIndex,
00360                               Builder &build, const IConverter *ic)
00361 {
00362         // get new data if available
00363         if( !build.Retrieve(dbId) )
00364                 return false;
00365 
00366         // build packet data
00367         size_t header_size = SB_PACKET_COMMAND_HEADER_SIZE + DBC_INDEXED_UPLOAD_HEADER_SIZE;
00368         build.BuildFields(m_send, header_size, ic);
00369         size_t total_size = m_send.GetSize();
00370 
00371         // fill in the header values
00372         MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(total_size));
00373         Protocol::Packet &packet = *cpack;
00374 
00375         // socket class sets socket for us
00376         packet.size = htobs(total_size);
00377         packet.command = SB_COMMAND_DB_DATA;
00378         packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
00379         packet.u.db.u.command.operation = SB_DBOP_SET_RECORD_BY_INDEX;
00380         packet.u.db.u.command.databaseId = htobs(dbId);
00381         packet.u.db.u.command.u.index_upload.unknown = 0;
00382         packet.u.db.u.command.u.index_upload.index = htobs(stateTableIndex);
00383 
00384         m_send.ReleaseBuffer(total_size);
00385 
00386         m_last_dbop = SB_DBOP_SET_RECORD_BY_INDEX;
00387         return true;
00388 }
00389 
00390 //
00391 // GetRecords
00392 //
00393 /// Builds a command packet in the send buffer for the GET_RECORDS
00394 /// command code.
00395 ///
00396 void DBPacket::GetRecords(unsigned int dbId)
00397 {
00398         MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(9));
00399         Protocol::Packet &packet = *cpack;
00400 
00401         // socket class sets socket for us
00402         packet.size = htobs(9);
00403         packet.command = SB_COMMAND_DB_DATA;
00404         packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
00405         packet.u.db.u.command.operation = SB_DBOP_OLD_GET_RECORDS;
00406         packet.u.db.u.command.databaseId = htobs(dbId);
00407 
00408         m_send.ReleaseBuffer(9);
00409 
00410         m_last_dbop = SB_DBOP_OLD_GET_RECORDS;
00411 }
00412 
00413 //
00414 // SetRecord
00415 //
00416 /// Builds a command packet in the m_send buffer for the SET_RECORD command
00417 /// code.
00418 ///
00419 /// \return     bool
00420 ///             - true means success
00421 ///             - false means no data available from Builder object
00422 ///
00423 bool DBPacket::SetRecord(unsigned int dbId, Builder &build, const IConverter *ic)
00424 {
00425         // get new data if available
00426         if( !build.Retrieve(dbId) )
00427                 return false;
00428 
00429         // build packet data
00430         size_t header_size = SB_PACKET_COMMAND_HEADER_SIZE + DBC_TAGGED_UPLOAD_HEADER_SIZE;
00431         build.BuildHeader(m_send, header_size);
00432         build.BuildFields(m_send, header_size, ic);
00433         size_t total_size = m_send.GetSize();
00434 
00435         // fill in the header values
00436         MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(total_size));
00437         Protocol::Packet &packet = *cpack;
00438 
00439         // socket class sets socket for us
00440         packet.size = htobs(total_size);
00441         packet.command = SB_COMMAND_DB_DATA;
00442         packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
00443         packet.u.db.u.command.operation = SB_DBOP_SET_RECORD;
00444         packet.u.db.u.command.databaseId = htobs(dbId);
00445         packet.u.db.u.command.u.tag_upload.rectype = build.GetRecType();
00446         packet.u.db.u.command.u.tag_upload.uniqueId = htobl(build.GetUniqueId());
00447         packet.u.db.u.command.u.tag_upload.unknown2 = 1;        // unknown observed value
00448 
00449         m_send.ReleaseBuffer(total_size);
00450 
00451         m_last_dbop = SB_DBOP_SET_RECORD;
00452         return true;
00453 }
00454 
00455 
00456 // throws FIXME if packet doesn't support it
00457 unsigned int DBPacket::ReturnCode() const
00458 {
00459         if( Command() == SB_COMMAND_DB_DONE ) {
00460                 Protocol::CheckSize(m_receive, SB_PACKET_DBACCESS_HEADER_SIZE + SB_DBACCESS_RETURN_CODE_SIZE);
00461                 MAKE_PACKET(rpack, m_receive);
00462                 return rpack->u.db.u.return_code;
00463         }
00464         else {
00465                 throw Error("Attempting to extract a return code from the wrong response packet type");
00466         }
00467 }
00468 
00469 //
00470 // DBOperation
00471 //
00472 /// Returns the database operation code from the receive packet, assuming
00473 /// that receive contains a response packet.  If receive isn't large
00474 /// enough, throws Error.
00475 ///
00476 unsigned int DBPacket::DBOperation() const
00477 {
00478         Protocol::CheckSize(m_receive, SB_PACKET_RESPONSE_HEADER_SIZE);
00479         MAKE_PACKET(rpack, m_receive);
00480         return rpack->u.db.u.response.operation;
00481 }
00482 
00483 //
00484 // Parse
00485 //
00486 /// Parses the data in the receive buffer, and attempts to be smart about it,
00487 /// using the last send command as guidance for what to expect in the
00488 /// response.
00489 ///
00490 /// \returns    bool    true - packet was recognized and parse was attempted
00491 ///                     false - packet was not recognized
00492 ///
00493 bool DBPacket::Parse(Parser &parser, const IConverter *ic)
00494 {
00495         size_t offset = 0;
00496         MAKE_PACKET(rpack, m_receive);
00497 
00498         switch( m_last_dbop )
00499         {
00500         case SB_DBOP_OLD_GET_RECORDS:
00501         case SB_DBOP_GET_RECORD_BY_INDEX:
00502                 parser.Clear();
00503 
00504                 offset = SB_PACKET_RESPONSE_HEADER_SIZE + DBR_OLD_TAGGED_RECORD_HEADER_SIZE;
00505                 Protocol::CheckSize(m_receive, offset);
00506                 // FIXME - this may need adjustment for email records... they
00507                 // don't seem to have uniqueID's
00508                 parser.SetIds(rpack->u.db.u.response.u.tagged.rectype,
00509                         btohl(rpack->u.db.u.response.u.tagged.uniqueId));
00510 
00511                 parser.ParseHeader(m_receive, offset);
00512                 parser.ParseFields(m_receive, offset, ic);
00513                 parser.Store();
00514                 return true;
00515 
00516         default:        // unknown command
00517                 return false;
00518         }
00519 }
00520 
00521 
00522 
00523 //////////////////////////////////////////////////////////////////////////////
00524 // JLPacket class
00525 
00526 JLPacket::JLPacket(Data &cmd, Data &send, Data &receive)
00527         : Packet(send, receive)
00528         , m_cmd(cmd)
00529         , m_data(send)
00530         , m_last_set_size(0)
00531 {
00532 }
00533 
00534 JLPacket::~JLPacket()
00535 {
00536 }
00537 
00538 unsigned int JLPacket::Size()
00539 {
00540         Protocol::CheckSize(m_receive, SB_JLPACKET_HEADER_SIZE + SB_JLRESPONSE_HEADER_SIZE);
00541         MAKE_JLPACKET(rpack, m_receive);
00542         return btohs(rpack->u.response.expect);
00543 }
00544 
00545 
00546 // returns 1 or 2 depending on whether cmd or cmd+send are available
00547 int JLPacket::SimpleCmd(uint8_t cmd, uint8_t unknown, uint16_t size)
00548 {
00549         MAKE_JLPACKETPTR_BUF(cpack, m_cmd.GetBuffer(8));
00550         Protocol::JLPacket &packet = *cpack;
00551 
00552         // socket class sets socket for us
00553         packet.size = htobs(8);
00554         packet.u.command.command = cmd;
00555         packet.u.command.unknown = unknown;
00556         packet.u.command.size = htobs(size);
00557 
00558         m_cmd.ReleaseBuffer(8);
00559 
00560         return m_last_set_size = 1;
00561 }
00562 
00563 int JLPacket::SimpleData(const void *data, uint16_t size)
00564 {
00565         uint16_t total = size + 4;
00566 
00567         MAKE_JLPACKETPTR_BUF(dpack, m_data.GetBuffer(total));
00568 
00569         // socket class sets socket for us
00570         dpack->size = htobs(total);
00571         memcpy(dpack->u.raw, data, size);
00572 
00573         m_data.ReleaseBuffer(total);
00574 
00575         return m_last_set_size = 2;
00576 }
00577 
00578 int JLPacket::BigEndianData(uint16_t value)
00579 {
00580         value = be_htobs(value);
00581         return SimpleData(&value, sizeof(value));
00582 }
00583 
00584 int JLPacket::BigEndianData(uint32_t value)
00585 {
00586         value = be_htobl(value);
00587         return SimpleData(&value, sizeof(value));
00588 }
00589 
00590 int JLPacket::SetUnknown1()
00591 {
00592         SimpleCmd(SB_COMMAND_JL_SET_UNKNOWN1, 0, 1);
00593         uint8_t arg = 0;
00594         return SimpleData(&arg, 1);
00595 }
00596 
00597 int JLPacket::SetCodFilename(const std::string &filename)
00598 {
00599         SimpleCmd(SB_COMMAND_JL_SET_COD_FILENAME, 0, filename.size());
00600         return SimpleData(filename.data(), filename.size());
00601 }
00602 
00603 int JLPacket::SetCodSize(off_t size)
00604 {
00605         SimpleCmd(SB_COMMAND_JL_SET_COD_SIZE, 1, 4);
00606         return BigEndianData((uint32_t)size);
00607 }
00608 
00609 int JLPacket::SetTime(time_t when)
00610 {
00611         SimpleCmd(SB_COMMAND_JL_SET_TIME, 0, 4);
00612         return BigEndianData((uint32_t)when);
00613 }
00614 
00615 int JLPacket::GetSubDir(uint16_t id)
00616 {
00617         SimpleCmd(SB_COMMAND_JL_GET_SUBDIR, 0, 2);
00618         return BigEndianData(id);
00619 }
00620 
00621 int JLPacket::GetDirEntry(uint8_t entry_cmd, uint16_t id)
00622 {
00623         SimpleCmd(entry_cmd, 0, 2);
00624         return BigEndianData(id);
00625 }
00626 
00627 int JLPacket::GetScreenshot()
00628 {
00629         SimpleCmd(SB_COMMAND_JL_GET_SCREENSHOT, 0, 4);
00630         return BigEndianData((uint32_t) 0);
00631 }
00632 
00633 int JLPacket::Erase(uint16_t cmd, uint16_t id)
00634 {
00635         SimpleCmd(cmd, 0, 2);
00636         return BigEndianData(id);
00637 }
00638 
00639 int JLPacket::GetEventlogEntry(uint16_t entry_num)
00640 {
00641         SimpleCmd(SB_COMMAND_JL_GET_LOG_ENTRY, 0, 2);
00642         return BigEndianData(entry_num);
00643 }
00644 
00645 int JLPacket::SaveModule(uint16_t id)
00646 {
00647         SimpleCmd(SB_COMMAND_JL_SAVE_MODULE, 0, 2);
00648         return BigEndianData(id);
00649 }
00650 
00651 int JLPacket::PutData(const void *data, uint16_t size)
00652 {
00653         SimpleCmd(SB_COMMAND_JL_SEND_DATA, 0, size);
00654         return SimpleData(data, size);
00655 }
00656 
00657 
00658 //////////////////////////////////////////////////////////////////////////////
00659 // JVMPacket class
00660 
00661 JVMPacket::JVMPacket(Data &send, Data &receive)
00662         : Packet(send, receive)
00663         , m_cmd(send)
00664 {
00665 }
00666 
00667 JVMPacket::~JVMPacket()
00668 {
00669 }
00670 
00671 
00672 unsigned int JVMPacket::Size()
00673 {
00674         MAKE_JVMPACKET(rpack, m_receive);
00675         Protocol::CheckSize(m_receive, SB_JVMPACKET_HEADER_SIZE + sizeof(rpack->u.expect));
00676         return be_btohs(rpack->u.expect);
00677 }
00678 
00679 
00680 // Command format (param is optionnal) :
00681 // 00000000: 05 00 07 00 00 01 8a
00682 //                             ^^ : command
00683 //                       ^^^^^ : size of commd + param
00684 //                 ^^^^^ : packet size
00685 //           ^^^^^ : socket ID
00686 void JVMPacket::SimpleCmd(uint8_t cmd)
00687 {
00688         // 4 : socket id field + packet size field
00689         // 2 : size field
00690         // 1 : command field
00691         const uint16_t total = 4 + 2 + 1;
00692 
00693         MAKE_JVMPACKETPTR_BUF(cpack, m_cmd.GetBuffer(total));
00694         Protocol::JVMPacket &packet = *cpack;
00695 
00696         // socket class sets socket for us
00697         packet.size = htobs(total);
00698         packet.u.command.size = be_htobs(1);
00699         packet.u.command.command = cmd;
00700 
00701         m_cmd.ReleaseBuffer(total);
00702 }
00703 
00704 // Command with parameter format :
00705 // 00000000: 05 00 0b 00 00 05 8d 00 00 00 00
00706 //                                ^^^^^^^^^^^ : param
00707 //                             ^^ : command
00708 //                       ^^^^^ : size of commd + param
00709 //                 ^^^^^ : packet size
00710 //           ^^^^^ : socket ID
00711 void JVMPacket::ComplexCmd(uint8_t cmd, const void *param, uint16_t size)
00712 {
00713         // 4 : socket id field + packet size field
00714         // 2 : size field
00715         // 1 : command field
00716         uint16_t total = 4 + 2 + 1 + size;
00717 
00718         MAKE_JVMPACKETPTR_BUF(cpack, m_cmd.GetBuffer(total));
00719         Protocol::JVMPacket &packet = *cpack;
00720 
00721         // socket class sets socket for us
00722         packet.size = htobs(total);
00723         packet.u.command.size = be_htobs(1 + size);
00724         packet.u.command.command = cmd;
00725 
00726         if ((size > 0) && (param != NULL))
00727                 memcpy(cpack->u.command.raw, param, size);
00728 
00729         m_cmd.ReleaseBuffer(total);
00730 }
00731 
00732 
00733 void JVMPacket::Unknown01() {
00734         SimpleCmd(SB_COMMAND_JVM_UNKNOWN01);
00735 }
00736 
00737 
00738 void JVMPacket::Unknown02() {
00739         SimpleCmd(SB_COMMAND_JVM_UNKNOWN02);
00740 }
00741 
00742 
00743 void JVMPacket::Unknown03() {
00744         SimpleCmd(SB_COMMAND_JVM_UNKNOWN03);
00745 }
00746 
00747 
00748 void JVMPacket::Unknown04() {
00749         SimpleCmd(SB_COMMAND_JVM_UNKNOWN04);
00750 }
00751 
00752 
00753 void JVMPacket::Unknown05() {
00754         SimpleCmd(SB_COMMAND_JVM_UNKNOWN05);
00755 }
00756 
00757 
00758 void JVMPacket::Unknown06() {
00759         uint32_t param = 0;
00760 
00761         ComplexCmd(SB_COMMAND_JVM_UNKNOWN06, &param, sizeof(param));
00762 }
00763 
00764 
00765 void JVMPacket::Unknown07() {
00766         uint32_t param = 0;
00767 
00768         ComplexCmd(SB_COMMAND_JVM_UNKNOWN07, &param, sizeof(param));
00769 }
00770 
00771 
00772 void JVMPacket::Unknown08() {
00773         uint32_t param = 0;
00774 
00775         ComplexCmd(SB_COMMAND_JVM_UNKNOWN08, &param, sizeof(param));
00776 }
00777 
00778 
00779 void JVMPacket::Unknown09() {
00780         uint32_t param = be_htobl(0x09);
00781 
00782         ComplexCmd(SB_COMMAND_JVM_UNKNOWN09, &param, sizeof(param));
00783 }
00784 
00785 
00786 void JVMPacket::Unknown10() {
00787         uint32_t param = be_htobl(0x01);
00788 
00789         ComplexCmd(SB_COMMAND_JVM_UNKNOWN10, &param, sizeof(param));
00790 }
00791 
00792 
00793 void JVMPacket::Unknown11(uint32_t id) {
00794         id = be_htobl(id);
00795 
00796         ComplexCmd(SB_COMMAND_JVM_UNKNOWN11, &id, sizeof(id));
00797 }
00798 
00799 
00800 void JVMPacket::Unknown12(uint32_t id) {
00801         id = be_htobl(id);
00802 
00803         ComplexCmd(SB_COMMAND_JVM_UNKNOWN12, &id, sizeof(id));
00804 }
00805 
00806 
00807 void JVMPacket::Unknown13(uint32_t id) {
00808         id = be_htobl(id);
00809 
00810         ComplexCmd(SB_COMMAND_JVM_UNKNOWN13, &id, sizeof(id));
00811 }
00812 
00813 
00814 void JVMPacket::Unknown14(uint32_t id) {
00815         id = be_htobl(id);
00816 
00817         ComplexCmd(SB_COMMAND_JVM_UNKNOWN14, &id, sizeof(id));
00818 }
00819 
00820 
00821 void JVMPacket::Unknown15(uint32_t id) {
00822         id = be_htobl(id);
00823 
00824         ComplexCmd(SB_COMMAND_JVM_UNKNOWN15, &id, sizeof(id));
00825 }
00826 
00827 
00828 void JVMPacket::GetModulesList(uint32_t id) {
00829         id = be_htobl(id);
00830 
00831         ComplexCmd(SB_COMMAND_JVM_GET_MODULES_LIST, &id, sizeof(id));
00832 }
00833 
00834 
00835 void JVMPacket::GetThreadsList() {
00836         SimpleCmd(SB_COMMAND_JVM_GET_THREADS_LIST);
00837 }
00838 
00839 
00840 void JVMPacket::GetConsoleMessage() {
00841         SimpleCmd(SB_COMMAND_JVM_GET_CONSOLE_MSG);
00842 }
00843 
00844 
00845 void JVMPacket::Go()
00846 {
00847         SimpleCmd(SB_COMMAND_JVM_GO);
00848 }
00849 
00850 
00851 void JVMPacket::Stop()
00852 {
00853         // 4 : socket id field + packet size field
00854         // 2 : value field
00855         const uint16_t total = 4 + 2;
00856 
00857         MAKE_JVMPACKETPTR_BUF(cpack, m_cmd.GetBuffer(total));
00858         Protocol::JVMPacket &packet = *cpack;
00859 
00860         // socket class sets socket for us
00861         packet.size = htobs(total);
00862         packet.u.value = be_htobs(SB_COMMAND_JVM_STOP);
00863 
00864         m_cmd.ReleaseBuffer(total);
00865 }
00866 
00867 
00868 void JVMPacket::GetStatus()
00869 {
00870         SimpleCmd(SB_COMMAND_JVM_GET_STATUS);
00871 }
00872 
00873 } // namespace Barry
00874 

Generated on 29 Mar 2010 for Barry by  doxygen 1.6.1