menu: added new Keywords tag to .desktop files
[barry.git] / src / packet.cc
blob60fbf1334d74c306d3c7849a1c1554693fd67943
1 ///
2 /// \file packet.cc
3 /// Low level protocol packet builder class.
4 /// Has knowledge of specific protocol commands in order
5 /// to hide protocol details behind an API.
6 ///
8 /*
9 Copyright (C) 2005-2013, Net Direct Inc. (http://www.netdirect.ca/)
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 See the GNU General Public License in the COPYING file at the
21 root directory of this project for more details.
24 #include "i18n.h"
25 #include "packet.h"
26 #include "m_desktop.h"
27 #include "protocol.h"
28 #include "protostructs.h"
29 #include "data.h"
30 #include "endian.h"
31 #include "parser.h"
32 #include "builder.h"
33 #include "error.h"
34 #include <string.h>
36 #define __DEBUG_MODE__
37 #include "debug.h"
40 namespace Barry {
42 //////////////////////////////////////////////////////////////////////////////
43 // Packet base class
46 // Command
48 /// Returns the command value of the receive packet. If receive isn't
49 /// large enough, throws Error.
50 ///
51 unsigned int Packet::Command() const
53 Protocol::CheckSize(*m_receive, SB_PACKET_HEADER_SIZE);
54 MAKE_PACKET(rpack, *m_receive);
55 return rpack->command;
59 //////////////////////////////////////////////////////////////////////////////
60 // ZeroPacket class
62 ZeroPacket::ZeroPacket(Data &send, Data &receive)
63 : Packet(send, receive)
67 ZeroPacket::~ZeroPacket()
72 // GetAttribute
74 /// Builds a command packet for the initial socket-0 handshakes
75 /// that fetch certain (some unknown) attributes. The attributes
76 /// appear to exist in an object/attribute sequence, so that's
77 /// how we address them here.
78 ///
79 void ZeroPacket::GetAttribute(unsigned int object, unsigned int attribute)
81 size_t size = SB_SOCKET_PACKET_HEADER_SIZE + ATTRIBUTE_FETCH_COMMAND_SIZE;
82 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(size));
83 Protocol::Packet &packet = *cpack;
85 // socket class sets socket for us
86 packet.size = htobs(size);
87 packet.command = SB_COMMAND_FETCH_ATTRIBUTE;
88 packet.u.socket.socket = htobs(0x00ff); // default non-socket request
89 packet.u.socket.sequence = 0; // filled in by Socket class
90 packet.u.socket.u.fetch.object = htobs(object);
91 packet.u.socket.u.fetch.attribute = htobs(attribute);
93 m_send.ReleaseBuffer(size);
97 // Echo
99 /// Builds command packet for sending echo request. The parameter
100 /// to this command is the number of microseconds elapsed since host
101 /// computer startup.
103 void ZeroPacket::Echo(uint64_t us_ticks)
105 size_t size = SB_SOCKET_PACKET_HEADER_SIZE + ECHO_COMMAND_SIZE;
106 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(size));
107 Protocol::Packet &packet = *cpack;
109 packet.size = htobs(size);
110 packet.command = SB_COMMAND_ECHO;
111 packet.u.socket.socket = htobs(0x00ff); // default non-socket request
112 packet.u.socket.sequence = 0; // filled in by Socket class
113 packet.u.socket.u.echo.ticks = htobl(us_ticks);
115 m_send.ReleaseBuffer(size);
118 void ZeroPacket::Reset()
120 size_t size = SB_SOCKET_PACKET_HEADER_SIZE;
121 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(size));
122 Protocol::Packet &packet = *cpack;
124 packet.size = htobs(size);
125 packet.command = SB_COMMAND_RESET;
126 packet.u.socket.socket = htobs(0x00ff); // default non-socket request
127 packet.u.socket.sequence = 0; // filled in by Socket class
129 m_send.ReleaseBuffer(size);
132 unsigned int ZeroPacket::ObjectID() const
134 Protocol::CheckSize(*m_receive, SB_SOCKET_PACKET_HEADER_SIZE);
135 MAKE_PACKET(rpack, *m_receive);
136 return btohs(rpack->u.socket.u.fetch.object);
139 unsigned int ZeroPacket::AttributeID() const
141 Protocol::CheckSize(*m_receive, SB_SOCKET_PACKET_HEADER_SIZE);
142 MAKE_PACKET(rpack, *m_receive);
143 return btohs(rpack->u.socket.u.fetch.attribute);
146 uint32_t ZeroPacket::ChallengeSeed() const
148 Protocol::CheckSize(*m_receive, SB_SOCKET_PACKET_HEADER_SIZE +
149 PASSWORD_CHALLENGE_SEED_SIZE);
150 MAKE_PACKET(rpack, *m_receive);
151 return btohl(rpack->u.socket.u.password.u.seed);
154 unsigned int ZeroPacket::RemainingTries() const
156 Protocol::CheckSize(*m_receive, SB_SOCKET_PACKET_HEADER_SIZE +
157 PASSWORD_CHALLENGE_HEADER_SIZE);
158 MAKE_PACKET(rpack, *m_receive);
159 // this is a byte, so no byte swapping needed
160 return rpack->u.socket.u.password.remaining_tries;
163 unsigned int ZeroPacket::SocketResponse() const
165 Protocol::CheckSize(*m_receive, SB_SOCKET_PACKET_HEADER_SIZE);
166 MAKE_PACKET(rpack, *m_receive);
167 return btohs(rpack->u.socket.socket);
170 unsigned char ZeroPacket::SocketSequence() const
172 Protocol::CheckSize(*m_receive, SB_SOCKET_PACKET_HEADER_SIZE);
173 MAKE_PACKET(rpack, *m_receive);
174 return rpack->u.socket.sequence; // sequence is a byte
177 uint8_t ZeroPacket::CommandResponse() const
179 Protocol::CheckSize(*m_receive, SB_SOCKET_PACKET_HEADER_SIZE);
180 MAKE_PACKET(rpack, *m_receive);
181 return rpack->command;
186 //////////////////////////////////////////////////////////////////////////////
187 // DBPacket class
189 DBPacket::DBPacket(Mode::Desktop &con, Data &send, Data &receive)
190 : Packet(send, receive)
191 , m_con(con)
192 , m_last_dbop(0)
196 DBPacket::~DBPacket()
201 // ClearDatabase
203 /// Builds a command packet for the CLEAR_DATABASE command code, placing
204 /// the data in the send buffer.
206 void DBPacket::ClearDatabase(unsigned int dbId)
208 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(9));
209 Protocol::Packet &packet = *cpack;
211 // socket class sets socket for us
212 packet.size = htobs(9);
213 packet.command = SB_COMMAND_DB_DATA;
214 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
215 packet.u.db.u.command.operation = SB_DBOP_CLEAR_DATABASE;
216 packet.u.db.u.command.databaseId = htobs(dbId);
218 m_send.ReleaseBuffer(9);
220 m_last_dbop = SB_DBOP_CLEAR_DATABASE;
224 // GetDBDB
226 /// Builds a command packet for the GET_DBDB command code, placing the
227 /// data in m_send.
229 void DBPacket::GetDBDB()
231 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(7));
232 Protocol::Packet &packet = *cpack;
234 // socket class sets socket for us
235 packet.size = htobs(7);
236 packet.command = SB_COMMAND_DB_DATA;
237 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
238 // packet.u.db.u.command.operation = SB_DBOP_GET_DBDB;
239 packet.u.db.u.command.operation = SB_DBOP_OLD_GET_DBDB;
241 m_send.ReleaseBuffer(7);
243 m_last_dbop = SB_DBOP_OLD_GET_DBDB;
247 // GetRecordStateTable
249 /// Builds a command packet in the send buffer for the
250 /// GET_RECORD_STATE_TABLE command.
252 void DBPacket::GetRecordStateTable(unsigned int dbId)
254 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(9));
255 Protocol::Packet &packet = *cpack;
257 // socket class sets socket for us
258 packet.size = htobs(9);
259 packet.command = SB_COMMAND_DB_DATA;
260 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
261 packet.u.db.u.command.operation = SB_DBOP_GET_RECORD_STATE_TABLE;
262 packet.u.db.u.command.databaseId = htobs(dbId);
264 m_send.ReleaseBuffer(9);
266 m_last_dbop = SB_DBOP_GET_RECORD_STATE_TABLE;
270 // SetRecordFlags
272 /// Builds a command packet in the send buffer for the SET_RECORD_FLAGS
273 /// command code.
275 /// FIXME - this API call is incomplete, since there are unknown flags
276 /// in the SetRecordFlags protocol packet. Currently it is only
277 /// used to set all flags to zero.
279 void DBPacket::SetRecordFlags(unsigned int dbId, unsigned int stateTableIndex,
280 uint8_t flag1)
282 size_t size = SB_PACKET_COMMAND_HEADER_SIZE + DBC_RECORD_FLAGS_SIZE;
283 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(size));
284 Protocol::Packet &packet = *cpack;
286 // socket class sets socket for us
287 packet.size = htobs(size);
288 packet.command = SB_COMMAND_DB_DATA;
289 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
290 packet.u.db.u.command.operation = SB_DBOP_SET_RECORD_FLAGS;
291 packet.u.db.u.command.databaseId = htobs(dbId);
292 packet.u.db.u.command.u.flags.unknown = flag1;
293 packet.u.db.u.command.u.flags.index = htobs(stateTableIndex);
294 memset(packet.u.db.u.command.u.flags.unknown2, 0, sizeof(packet.u.db.u.command.u.flags.unknown2));
296 m_send.ReleaseBuffer(size);
298 m_last_dbop = SB_DBOP_SET_RECORD_FLAGS;
302 // DeleteRecordByIndex
304 /// Builds a command packet in the send buffer for the DELETE_RECORD_BY_INDEX
305 /// command code.
307 void DBPacket::DeleteRecordByIndex(unsigned int dbId, unsigned int stateTableIndex)
309 size_t size = SB_PACKET_COMMAND_HEADER_SIZE + DBC_RECORD_HEADER_SIZE;
310 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(size));
311 Protocol::Packet &packet = *cpack;
313 // socket class sets socket for us
314 packet.size = htobs(size);
315 packet.command = SB_COMMAND_DB_DATA;
316 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
317 packet.u.db.u.command.operation = SB_DBOP_DELETE_RECORD_BY_INDEX;
318 packet.u.db.u.command.databaseId = htobs(dbId);
319 packet.u.db.u.command.u.record.recordIndex = htobs(stateTableIndex);
321 m_send.ReleaseBuffer(size);
323 m_last_dbop = SB_DBOP_DELETE_RECORD_BY_INDEX;
327 // GetRecordByIndex
329 /// Builds a command packet in the send buffer for the GET_RECORD_BY_INDEX
330 /// command code.
332 void DBPacket::GetRecordByIndex(unsigned int dbId, unsigned int stateTableIndex)
334 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(11));
335 Protocol::Packet &packet = *cpack;
337 // socket class sets socket for us
338 packet.size = htobs(11);
339 packet.command = SB_COMMAND_DB_DATA;
340 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
341 packet.u.db.u.command.operation = SB_DBOP_GET_RECORD_BY_INDEX;
342 packet.u.db.u.command.databaseId = htobs(dbId);
343 packet.u.db.u.command.u.record.recordIndex = htobs(stateTableIndex);
345 m_send.ReleaseBuffer(11);
347 m_last_dbop = SB_DBOP_GET_RECORD_BY_INDEX;
351 // SetRecordByIndex
353 /// Builds a command packet in the m_send buffer for the SET_RECORD_BY_INDEX
354 /// command code.
356 /// \return bool
357 /// - true means success
358 /// - false means no data available from Builder object
360 bool DBPacket::SetRecordByIndex(unsigned int dbId, unsigned int stateTableIndex,
361 Builder &build, const IConverter *ic)
363 // build packet data
364 DBData send(m_send, false); // send is just a reference to m_send,
365 // so it is safe to use m_send later
367 size_t header_size = SB_PACKET_COMMAND_HEADER_SIZE + DBC_INDEXED_UPLOAD_HEADER_SIZE;
368 if( !build.BuildRecord(send, header_size, ic) )
369 return false; // no data available
370 size_t total_size = m_send.GetSize();
372 // fill in the header values
373 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(total_size));
374 Protocol::Packet &packet = *cpack;
376 // socket class sets socket for us
377 packet.size = htobs(total_size);
378 packet.command = SB_COMMAND_DB_DATA;
379 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
380 packet.u.db.u.command.operation = SB_DBOP_SET_RECORD_BY_INDEX;
381 packet.u.db.u.command.databaseId = htobs(dbId);
382 packet.u.db.u.command.u.index_upload.unknown = 0;
383 packet.u.db.u.command.u.index_upload.index = htobs(stateTableIndex);
385 m_send.ReleaseBuffer(total_size);
387 m_last_dbop = SB_DBOP_SET_RECORD_BY_INDEX;
388 return true;
392 // GetRecords
394 /// Builds a command packet in the send buffer for the GET_RECORDS
395 /// command code.
397 void DBPacket::GetRecords(unsigned int dbId)
399 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(9));
400 Protocol::Packet &packet = *cpack;
402 // socket class sets socket for us
403 packet.size = htobs(9);
404 packet.command = SB_COMMAND_DB_DATA;
405 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
406 packet.u.db.u.command.operation = SB_DBOP_OLD_GET_RECORDS;
407 packet.u.db.u.command.databaseId = htobs(dbId);
409 m_send.ReleaseBuffer(9);
411 m_last_dbop = SB_DBOP_OLD_GET_RECORDS;
415 // AddRecord
417 /// Builds a command packet in the m_send buffer for the ADD_RECORD command
418 /// code.
420 /// \return bool
421 /// - true means success
422 /// - false means no data available from Builder object
424 bool DBPacket::AddRecord(unsigned int dbId, Builder &build, const IConverter *ic)
426 // build packet data
427 DBData send(m_send, false); // send is just a reference to m_send,
428 // so it is safe to use m_send later
430 size_t header_size = SB_PACKET_COMMAND_HEADER_SIZE + DBC_TAGGED_UPLOAD_HEADER_SIZE;
431 if( !build.BuildRecord(send, header_size, ic) )
432 return false; // no data available
433 size_t total_size = m_send.GetSize();
435 // fill in the header values
436 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(total_size));
437 Protocol::Packet &packet = *cpack;
439 // socket class sets socket for us
440 packet.size = htobs(total_size);
441 packet.command = SB_COMMAND_DB_DATA;
442 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
443 packet.u.db.u.command.operation = SB_DBOP_ADD_RECORD;
444 packet.u.db.u.command.databaseId = htobs(dbId);
445 packet.u.db.u.command.u.tag_upload.rectype = send.GetRecType();
446 packet.u.db.u.command.u.tag_upload.uniqueId = htobl(send.GetUniqueId());
447 packet.u.db.u.command.u.tag_upload.unknown2 = 1; // unknown observed value
449 m_send.ReleaseBuffer(total_size);
451 m_last_dbop = SB_DBOP_ADD_RECORD;
452 return true;
456 // throws FIXME if packet doesn't support it
457 unsigned int DBPacket::ReturnCode() const
459 if( Command() == SB_COMMAND_DB_DONE ) {
460 Protocol::CheckSize(*m_receive, SB_PACKET_DBACCESS_HEADER_SIZE + SB_DBACCESS_RETURN_CODE_SIZE);
461 MAKE_PACKET(rpack, *m_receive);
462 return rpack->u.db.u.return_code;
464 else {
465 throw Error(_("Attempting to extract a return code from the wrong response packet type"));
470 // DBOperation
472 /// Returns the database operation code from the receive packet, assuming
473 /// that receive contains a response packet. If receive isn't large
474 /// enough, throws Error.
476 unsigned int DBPacket::DBOperation() const
478 Protocol::CheckSize(*m_receive, SB_PACKET_RESPONSE_HEADER_SIZE);
479 MAKE_PACKET(rpack, *m_receive);
480 return rpack->u.db.u.response.operation;
484 // Parse
486 /// Parses the data in the receive buffer, and attempts to be smart about it,
487 /// using the last send command as guidance for what to expect in the
488 /// response.
490 /// \returns bool true - packet was recognized and parse was attempted
491 /// false - packet was not recognized
493 bool DBPacket::Parse(Parser &parser, const std::string &dbname,
494 const IConverter *ic)
496 size_t offset = 0;
497 MAKE_PACKET(rpack, *m_receive);
499 switch( m_last_dbop )
501 case SB_DBOP_OLD_GET_RECORDS:
502 case SB_DBOP_GET_RECORD_BY_INDEX:
503 offset = SB_PACKET_RESPONSE_HEADER_SIZE + DBR_OLD_TAGGED_RECORD_HEADER_SIZE;
504 Protocol::CheckSize(*m_receive, offset);
506 // FIXME - this may need adjustment for email records... they
507 // don't seem to have uniqueID's
509 DBData block(DBData::REC_VERSION_1, dbname,
510 rpack->u.db.u.response.u.tagged.rectype,
511 btohl(rpack->u.db.u.response.u.tagged.uniqueId),
512 offset, *m_receive, false);
513 parser.ParseRecord(block, ic);
515 return true;
517 default: // unknown command
518 return false;
523 // ParseMeta
525 /// Fills DBData's meta data based on its data block, and the last dbop.
527 bool DBPacket::ParseMeta(DBData &data)
529 size_t offset = 0;
530 MAKE_PACKET(rpack, data.GetData());
532 switch( m_last_dbop )
534 case SB_DBOP_OLD_GET_RECORDS:
535 case SB_DBOP_GET_RECORD_BY_INDEX:
536 data.SetVersion(DBData::REC_VERSION_1);
538 offset = SB_PACKET_RESPONSE_HEADER_SIZE + DBR_OLD_TAGGED_RECORD_HEADER_SIZE;
539 Protocol::CheckSize(data.GetData(), offset);
540 data.SetOffset(offset);
542 // FIXME - this may need adjustment for email records... they
543 // don't seem to have uniqueID's
544 data.SetIds(rpack->u.db.u.response.u.tagged.rectype,
545 btohl(rpack->u.db.u.response.u.tagged.uniqueId));
546 return true;
548 default: // unknown command
549 return false;
555 //////////////////////////////////////////////////////////////////////////////
556 // JLPacket class
558 JLPacket::JLPacket(Data &cmd, Data &send, Data &receive)
559 : Packet(send, receive)
560 , m_cmd(cmd)
561 , m_data(send)
562 , m_last_set_size(0)
566 JLPacket::~JLPacket()
570 unsigned int JLPacket::Size()
572 Protocol::CheckSize(*m_receive, SB_JLPACKET_HEADER_SIZE + SB_JLRESPONSE_HEADER_SIZE);
573 MAKE_JLPACKET(rpack, *m_receive);
574 return btohs(rpack->u.response.expect);
578 // returns 1 or 2 depending on whether cmd or cmd+send are available
579 int JLPacket::SimpleCmd(uint8_t cmd, uint8_t unknown, uint16_t size)
581 MAKE_JLPACKETPTR_BUF(cpack, m_cmd.GetBuffer(8));
582 Protocol::JLPacket &packet = *cpack;
584 // socket class sets socket for us
585 packet.size = htobs(8);
586 packet.u.command.command = cmd;
587 packet.u.command.unknown = unknown;
588 packet.u.command.size = htobs(size);
590 m_cmd.ReleaseBuffer(8);
592 return m_last_set_size = 1;
595 int JLPacket::SimpleData(const void *data, uint16_t size)
597 uint16_t total = size + 4;
599 MAKE_JLPACKETPTR_BUF(dpack, m_data.GetBuffer(total));
601 // socket class sets socket for us
602 dpack->size = htobs(total);
603 memcpy(dpack->u.raw, data, size);
605 m_data.ReleaseBuffer(total);
607 return m_last_set_size = 2;
610 int JLPacket::BigEndianData(uint16_t value)
612 value = be_htobs(value);
613 return SimpleData(&value, sizeof(value));
616 int JLPacket::BigEndianData(uint32_t value)
618 value = be_htobl(value);
619 return SimpleData(&value, sizeof(value));
622 int JLPacket::SetUnknown1()
624 SimpleCmd(SB_COMMAND_JL_SET_UNKNOWN1, 0, 1);
625 uint8_t arg = 0;
626 return SimpleData(&arg, 1);
629 int JLPacket::SetCodFilename(const std::string &filename)
631 SimpleCmd(SB_COMMAND_JL_SET_COD_FILENAME, 0, filename.size());
632 return SimpleData(filename.data(), filename.size());
635 int JLPacket::SetCodSize(off_t size)
637 SimpleCmd(SB_COMMAND_JL_SET_COD_SIZE, 1, 4);
638 return BigEndianData((uint32_t)size);
641 int JLPacket::SetTime(time_t when)
643 SimpleCmd(SB_COMMAND_JL_SET_TIME, 0, 4);
644 return BigEndianData((uint32_t)when);
647 int JLPacket::GetSubDir(uint16_t id)
649 SimpleCmd(SB_COMMAND_JL_GET_SUBDIR, 0, 2);
650 return BigEndianData(id);
653 int JLPacket::GetDirEntry(uint8_t entry_cmd, uint16_t id)
655 SimpleCmd(entry_cmd, 0, 2);
656 return BigEndianData(id);
659 int JLPacket::GetScreenshot()
661 SimpleCmd(SB_COMMAND_JL_GET_SCREENSHOT, 0, 4);
662 return BigEndianData((uint32_t) 0);
665 int JLPacket::Erase(uint16_t cmd, uint16_t id)
667 SimpleCmd((uint8_t)cmd, 0, 2);
668 return BigEndianData(id);
671 int JLPacket::GetEventlogEntry(uint16_t entry_num)
673 SimpleCmd(SB_COMMAND_JL_GET_LOG_ENTRY, 0, 2);
674 return BigEndianData(entry_num);
677 int JLPacket::SaveModule(uint16_t id)
679 SimpleCmd(SB_COMMAND_JL_SAVE_MODULE, 0, 2);
680 return BigEndianData(id);
683 int JLPacket::PutData(const void *data, uint16_t size)
685 SimpleCmd(SB_COMMAND_JL_SEND_DATA, 0, size);
686 return SimpleData(data, size);
690 //////////////////////////////////////////////////////////////////////////////
691 // JVMPacket class
693 JVMPacket::JVMPacket(Data &send, Data &receive)
694 : Packet(send, receive)
695 , m_cmd(send)
699 JVMPacket::~JVMPacket()
704 unsigned int JVMPacket::Size()
706 MAKE_JVMPACKET(rpack, *m_receive);
707 Protocol::CheckSize(*m_receive, SB_JVMPACKET_HEADER_SIZE + sizeof(rpack->u.expect));
708 return be_btohs(rpack->u.expect);
712 // Command format (param is optionnal) :
713 // 00000000: 05 00 07 00 00 01 8a
714 // ^^ : command
715 // ^^^^^ : size of commd + param
716 // ^^^^^ : packet size
717 // ^^^^^ : socket ID
718 void JVMPacket::SimpleCmd(uint8_t cmd)
720 // 4 : socket id field + packet size field
721 // 2 : size field
722 // 1 : command field
723 const uint16_t total = 4 + 2 + 1;
725 MAKE_JVMPACKETPTR_BUF(cpack, m_cmd.GetBuffer(total));
726 Protocol::JVMPacket &packet = *cpack;
728 // socket class sets socket for us
729 packet.size = htobs(total);
730 packet.u.command.size = be_htobs(1);
731 packet.u.command.command = cmd;
733 m_cmd.ReleaseBuffer(total);
736 // Command with parameter format :
737 // 00000000: 05 00 0b 00 00 05 8d 00 00 00 00
738 // ^^^^^^^^^^^ : param
739 // ^^ : command
740 // ^^^^^ : size of commd + param
741 // ^^^^^ : packet size
742 // ^^^^^ : socket ID
743 void JVMPacket::ComplexCmd(uint8_t cmd, const void *param, uint16_t size)
745 // 4 : socket id field + packet size field
746 // 2 : size field
747 // 1 : command field
748 uint16_t total = 4 + 2 + 1 + size;
750 MAKE_JVMPACKETPTR_BUF(cpack, m_cmd.GetBuffer(total));
751 Protocol::JVMPacket &packet = *cpack;
753 // socket class sets socket for us
754 packet.size = htobs(total);
755 packet.u.command.size = be_htobs(1 + size);
756 packet.u.command.command = cmd;
758 if ((size > 0) && (param != NULL))
759 memcpy(cpack->u.command.raw, param, size);
761 m_cmd.ReleaseBuffer(total);
765 void JVMPacket::Unknown01() {
766 SimpleCmd(SB_COMMAND_JVM_UNKNOWN01);
770 void JVMPacket::Unknown02() {
771 SimpleCmd(SB_COMMAND_JVM_UNKNOWN02);
775 void JVMPacket::Unknown03() {
776 SimpleCmd(SB_COMMAND_JVM_UNKNOWN03);
780 void JVMPacket::Unknown04() {
781 SimpleCmd(SB_COMMAND_JVM_UNKNOWN04);
785 void JVMPacket::Unknown05() {
786 SimpleCmd(SB_COMMAND_JVM_UNKNOWN05);
790 void JVMPacket::Unknown06() {
791 uint32_t param = 0;
793 ComplexCmd(SB_COMMAND_JVM_UNKNOWN06, &param, sizeof(param));
797 void JVMPacket::Unknown07() {
798 uint32_t param = 0;
800 ComplexCmd(SB_COMMAND_JVM_UNKNOWN07, &param, sizeof(param));
804 void JVMPacket::Unknown08() {
805 uint32_t param = 0;
807 ComplexCmd(SB_COMMAND_JVM_UNKNOWN08, &param, sizeof(param));
811 void JVMPacket::Unknown09() {
812 uint32_t param = be_htobl(0x09);
814 ComplexCmd(SB_COMMAND_JVM_UNKNOWN09, &param, sizeof(param));
818 void JVMPacket::Unknown10() {
819 uint32_t param = be_htobl(0x01);
821 ComplexCmd(SB_COMMAND_JVM_UNKNOWN10, &param, sizeof(param));
825 void JVMPacket::Unknown11(uint32_t id) {
826 id = be_htobl(id);
828 ComplexCmd(SB_COMMAND_JVM_UNKNOWN11, &id, sizeof(id));
832 void JVMPacket::Unknown12(uint32_t id) {
833 id = be_htobl(id);
835 ComplexCmd(SB_COMMAND_JVM_UNKNOWN12, &id, sizeof(id));
839 void JVMPacket::Unknown13(uint32_t id) {
840 id = be_htobl(id);
842 ComplexCmd(SB_COMMAND_JVM_UNKNOWN13, &id, sizeof(id));
846 void JVMPacket::Unknown14(uint32_t id) {
847 id = be_htobl(id);
849 ComplexCmd(SB_COMMAND_JVM_UNKNOWN14, &id, sizeof(id));
853 void JVMPacket::Unknown15(uint32_t id) {
854 id = be_htobl(id);
856 ComplexCmd(SB_COMMAND_JVM_UNKNOWN15, &id, sizeof(id));
860 void JVMPacket::GetModulesList(uint32_t id) {
861 id = be_htobl(id);
863 ComplexCmd(SB_COMMAND_JVM_GET_MODULES_LIST, &id, sizeof(id));
867 void JVMPacket::GetThreadsList() {
868 SimpleCmd(SB_COMMAND_JVM_GET_THREADS_LIST);
872 void JVMPacket::GetConsoleMessage() {
873 SimpleCmd(SB_COMMAND_JVM_GET_CONSOLE_MSG);
877 void JVMPacket::Go()
879 SimpleCmd(SB_COMMAND_JVM_GO);
883 void JVMPacket::Stop()
885 // 4 : socket id field + packet size field
886 // 2 : value field
887 const uint16_t total = 4 + 2;
889 MAKE_JVMPACKETPTR_BUF(cpack, m_cmd.GetBuffer(total));
890 Protocol::JVMPacket &packet = *cpack;
892 // socket class sets socket for us
893 packet.size = htobs(total);
894 packet.u.value = be_htobs(SB_COMMAND_JVM_STOP);
896 m_cmd.ReleaseBuffer(total);
900 void JVMPacket::GetStatus()
902 SimpleCmd(SB_COMMAND_JVM_GET_STATUS);
905 } // namespace Barry