lib: renamed SB_DBOP_SET_RECORD to SB_DBOP_ADD_RECORD, and packet API
[barry.git] / src / packet.cc
blob6f78834b88da1055047497b90a968b199c909d81
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-2012, 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 "packet.h"
25 #include "m_desktop.h"
26 #include "protocol.h"
27 #include "protostructs.h"
28 #include "data.h"
29 #include "endian.h"
30 #include "parser.h"
31 #include "builder.h"
32 #include "error.h"
33 #include <string.h>
35 #define __DEBUG_MODE__
36 #include "debug.h"
39 namespace Barry {
41 //////////////////////////////////////////////////////////////////////////////
42 // Packet base class
45 // Command
47 /// Returns the command value of the receive packet. If receive isn't
48 /// large enough, throws Error.
49 ///
50 unsigned int Packet::Command() const
52 Protocol::CheckSize(*m_receive, SB_PACKET_HEADER_SIZE);
53 MAKE_PACKET(rpack, *m_receive);
54 return rpack->command;
58 //////////////////////////////////////////////////////////////////////////////
59 // ZeroPacket class
61 ZeroPacket::ZeroPacket(Data &send, Data &receive)
62 : Packet(send, receive)
66 ZeroPacket::~ZeroPacket()
71 // GetAttribute
73 /// Builds a command packet for the initial socket-0 handshakes
74 /// that fetch certain (some unknown) attributes. The attributes
75 /// appear to exist in an object/attribute sequence, so that's
76 /// how we address them here.
77 ///
78 void ZeroPacket::GetAttribute(unsigned int object, unsigned int attribute)
80 size_t size = SB_SOCKET_PACKET_HEADER_SIZE + ATTRIBUTE_FETCH_COMMAND_SIZE;
81 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(size));
82 Protocol::Packet &packet = *cpack;
84 // socket class sets socket for us
85 packet.size = htobs(size);
86 packet.command = SB_COMMAND_FETCH_ATTRIBUTE;
87 packet.u.socket.socket = htobs(0x00ff); // default non-socket request
88 packet.u.socket.sequence = 0; // filled in by Socket class
89 packet.u.socket.u.fetch.object = htobs(object);
90 packet.u.socket.u.fetch.attribute = htobs(attribute);
92 m_send.ReleaseBuffer(size);
96 // Echo
98 /// Builds command packet for sending echo request. The parameter
99 /// to this command is the number of microseconds elapsed since host
100 /// computer startup.
102 void ZeroPacket::Echo(uint64_t us_ticks)
104 size_t size = SB_SOCKET_PACKET_HEADER_SIZE + ECHO_COMMAND_SIZE;
105 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(size));
106 Protocol::Packet &packet = *cpack;
108 packet.size = htobs(size);
109 packet.command = SB_COMMAND_ECHO;
110 packet.u.socket.socket = htobs(0x00ff); // default non-socket request
111 packet.u.socket.sequence = 0; // filled in by Socket class
112 packet.u.socket.u.echo.ticks = htobl(us_ticks);
114 m_send.ReleaseBuffer(size);
117 void ZeroPacket::Reset()
119 size_t size = SB_SOCKET_PACKET_HEADER_SIZE;
120 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(size));
121 Protocol::Packet &packet = *cpack;
123 packet.size = htobs(size);
124 packet.command = SB_COMMAND_RESET;
125 packet.u.socket.socket = htobs(0x00ff); // default non-socket request
126 packet.u.socket.sequence = 0; // filled in by Socket class
128 m_send.ReleaseBuffer(size);
131 unsigned int ZeroPacket::ObjectID() const
133 Protocol::CheckSize(*m_receive, SB_SOCKET_PACKET_HEADER_SIZE);
134 MAKE_PACKET(rpack, *m_receive);
135 return btohs(rpack->u.socket.u.fetch.object);
138 unsigned int ZeroPacket::AttributeID() const
140 Protocol::CheckSize(*m_receive, SB_SOCKET_PACKET_HEADER_SIZE);
141 MAKE_PACKET(rpack, *m_receive);
142 return btohs(rpack->u.socket.u.fetch.attribute);
145 uint32_t ZeroPacket::ChallengeSeed() const
147 Protocol::CheckSize(*m_receive, SB_SOCKET_PACKET_HEADER_SIZE +
148 PASSWORD_CHALLENGE_SEED_SIZE);
149 MAKE_PACKET(rpack, *m_receive);
150 return btohl(rpack->u.socket.u.password.u.seed);
153 unsigned int ZeroPacket::RemainingTries() const
155 Protocol::CheckSize(*m_receive, SB_SOCKET_PACKET_HEADER_SIZE +
156 PASSWORD_CHALLENGE_HEADER_SIZE);
157 MAKE_PACKET(rpack, *m_receive);
158 // this is a byte, so no byte swapping needed
159 return rpack->u.socket.u.password.remaining_tries;
162 unsigned int ZeroPacket::SocketResponse() const
164 Protocol::CheckSize(*m_receive, SB_SOCKET_PACKET_HEADER_SIZE);
165 MAKE_PACKET(rpack, *m_receive);
166 return btohs(rpack->u.socket.socket);
169 unsigned char ZeroPacket::SocketSequence() const
171 Protocol::CheckSize(*m_receive, SB_SOCKET_PACKET_HEADER_SIZE);
172 MAKE_PACKET(rpack, *m_receive);
173 return rpack->u.socket.sequence; // sequence is a byte
176 uint8_t ZeroPacket::CommandResponse() const
178 Protocol::CheckSize(*m_receive, SB_SOCKET_PACKET_HEADER_SIZE);
179 MAKE_PACKET(rpack, *m_receive);
180 return rpack->command;
185 //////////////////////////////////////////////////////////////////////////////
186 // DBPacket class
188 DBPacket::DBPacket(Mode::Desktop &con, Data &send, Data &receive)
189 : Packet(send, receive)
190 , m_con(con)
191 , m_last_dbop(0)
195 DBPacket::~DBPacket()
200 // ClearDatabase
202 /// Builds a command packet for the CLEAR_DATABASE command code, placing
203 /// the data in the send buffer.
205 void DBPacket::ClearDatabase(unsigned int dbId)
207 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(9));
208 Protocol::Packet &packet = *cpack;
210 // socket class sets socket for us
211 packet.size = htobs(9);
212 packet.command = SB_COMMAND_DB_DATA;
213 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
214 packet.u.db.u.command.operation = SB_DBOP_CLEAR_DATABASE;
215 packet.u.db.u.command.databaseId = htobs(dbId);
217 m_send.ReleaseBuffer(9);
219 m_last_dbop = SB_DBOP_CLEAR_DATABASE;
223 // GetDBDB
225 /// Builds a command packet for the GET_DBDB command code, placing the
226 /// data in m_send.
228 void DBPacket::GetDBDB()
230 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(7));
231 Protocol::Packet &packet = *cpack;
233 // socket class sets socket for us
234 packet.size = htobs(7);
235 packet.command = SB_COMMAND_DB_DATA;
236 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
237 // packet.u.db.u.command.operation = SB_DBOP_GET_DBDB;
238 packet.u.db.u.command.operation = SB_DBOP_OLD_GET_DBDB;
240 m_send.ReleaseBuffer(7);
242 m_last_dbop = SB_DBOP_OLD_GET_DBDB;
246 // GetRecordStateTable
248 /// Builds a command packet in the send buffer for the
249 /// GET_RECORD_STATE_TABLE command.
251 void DBPacket::GetRecordStateTable(unsigned int dbId)
253 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(9));
254 Protocol::Packet &packet = *cpack;
256 // socket class sets socket for us
257 packet.size = htobs(9);
258 packet.command = SB_COMMAND_DB_DATA;
259 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
260 packet.u.db.u.command.operation = SB_DBOP_GET_RECORD_STATE_TABLE;
261 packet.u.db.u.command.databaseId = htobs(dbId);
263 m_send.ReleaseBuffer(9);
265 m_last_dbop = SB_DBOP_GET_RECORD_STATE_TABLE;
269 // SetRecordFlags
271 /// Builds a command packet in the send buffer for the SET_RECORD_FLAGS
272 /// command code.
274 /// FIXME - this API call is incomplete, since there are unknown flags
275 /// in the SetRecordFlags protocol packet. Currently it is only
276 /// used to set all flags to zero.
278 void DBPacket::SetRecordFlags(unsigned int dbId, unsigned int stateTableIndex,
279 uint8_t flag1)
281 size_t size = SB_PACKET_COMMAND_HEADER_SIZE + DBC_RECORD_FLAGS_SIZE;
282 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(size));
283 Protocol::Packet &packet = *cpack;
285 // socket class sets socket for us
286 packet.size = htobs(size);
287 packet.command = SB_COMMAND_DB_DATA;
288 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
289 packet.u.db.u.command.operation = SB_DBOP_SET_RECORD_FLAGS;
290 packet.u.db.u.command.databaseId = htobs(dbId);
291 packet.u.db.u.command.u.flags.unknown = flag1;
292 packet.u.db.u.command.u.flags.index = htobs(stateTableIndex);
293 memset(packet.u.db.u.command.u.flags.unknown2, 0, sizeof(packet.u.db.u.command.u.flags.unknown2));
295 m_send.ReleaseBuffer(size);
297 m_last_dbop = SB_DBOP_SET_RECORD_FLAGS;
301 // DeleteRecordByIndex
303 /// Builds a command packet in the send buffer for the DELETE_RECORD_BY_INDEX
304 /// command code.
306 void DBPacket::DeleteRecordByIndex(unsigned int dbId, unsigned int stateTableIndex)
308 size_t size = SB_PACKET_COMMAND_HEADER_SIZE + DBC_RECORD_HEADER_SIZE;
309 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(size));
310 Protocol::Packet &packet = *cpack;
312 // socket class sets socket for us
313 packet.size = htobs(size);
314 packet.command = SB_COMMAND_DB_DATA;
315 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
316 packet.u.db.u.command.operation = SB_DBOP_DELETE_RECORD_BY_INDEX;
317 packet.u.db.u.command.databaseId = htobs(dbId);
318 packet.u.db.u.command.u.record.recordIndex = htobs(stateTableIndex);
320 m_send.ReleaseBuffer(size);
322 m_last_dbop = SB_DBOP_DELETE_RECORD_BY_INDEX;
326 // GetRecordByIndex
328 /// Builds a command packet in the send buffer for the GET_RECORD_BY_INDEX
329 /// command code.
331 void DBPacket::GetRecordByIndex(unsigned int dbId, unsigned int stateTableIndex)
333 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(11));
334 Protocol::Packet &packet = *cpack;
336 // socket class sets socket for us
337 packet.size = htobs(11);
338 packet.command = SB_COMMAND_DB_DATA;
339 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
340 packet.u.db.u.command.operation = SB_DBOP_GET_RECORD_BY_INDEX;
341 packet.u.db.u.command.databaseId = htobs(dbId);
342 packet.u.db.u.command.u.record.recordIndex = htobs(stateTableIndex);
344 m_send.ReleaseBuffer(11);
346 m_last_dbop = SB_DBOP_GET_RECORD_BY_INDEX;
350 // SetRecordByIndex
352 /// Builds a command packet in the m_send buffer for the SET_RECORD_BY_INDEX
353 /// command code.
355 /// \return bool
356 /// - true means success
357 /// - false means no data available from Builder object
359 bool DBPacket::SetRecordByIndex(unsigned int dbId, unsigned int stateTableIndex,
360 Builder &build, const IConverter *ic)
362 // build packet data
363 DBData send(m_send, false); // send is just a reference to m_send,
364 // so it is safe to use m_send later
366 size_t header_size = SB_PACKET_COMMAND_HEADER_SIZE + DBC_INDEXED_UPLOAD_HEADER_SIZE;
367 if( !build.BuildRecord(send, header_size, ic) )
368 return false; // no data available
369 size_t total_size = m_send.GetSize();
371 // fill in the header values
372 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(total_size));
373 Protocol::Packet &packet = *cpack;
375 // socket class sets socket for us
376 packet.size = htobs(total_size);
377 packet.command = SB_COMMAND_DB_DATA;
378 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
379 packet.u.db.u.command.operation = SB_DBOP_SET_RECORD_BY_INDEX;
380 packet.u.db.u.command.databaseId = htobs(dbId);
381 packet.u.db.u.command.u.index_upload.unknown = 0;
382 packet.u.db.u.command.u.index_upload.index = htobs(stateTableIndex);
384 m_send.ReleaseBuffer(total_size);
386 m_last_dbop = SB_DBOP_SET_RECORD_BY_INDEX;
387 return true;
391 // GetRecords
393 /// Builds a command packet in the send buffer for the GET_RECORDS
394 /// command code.
396 void DBPacket::GetRecords(unsigned int dbId)
398 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(9));
399 Protocol::Packet &packet = *cpack;
401 // socket class sets socket for us
402 packet.size = htobs(9);
403 packet.command = SB_COMMAND_DB_DATA;
404 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
405 packet.u.db.u.command.operation = SB_DBOP_OLD_GET_RECORDS;
406 packet.u.db.u.command.databaseId = htobs(dbId);
408 m_send.ReleaseBuffer(9);
410 m_last_dbop = SB_DBOP_OLD_GET_RECORDS;
414 // AddRecord
416 /// Builds a command packet in the m_send buffer for the ADD_RECORD command
417 /// code.
419 /// \return bool
420 /// - true means success
421 /// - false means no data available from Builder object
423 bool DBPacket::AddRecord(unsigned int dbId, Builder &build, const IConverter *ic)
425 // build packet data
426 DBData send(m_send, false); // send is just a reference to m_send,
427 // so it is safe to use m_send later
429 size_t header_size = SB_PACKET_COMMAND_HEADER_SIZE + DBC_TAGGED_UPLOAD_HEADER_SIZE;
430 if( !build.BuildRecord(send, header_size, ic) )
431 return false; // no data available
432 size_t total_size = m_send.GetSize();
434 // fill in the header values
435 MAKE_PACKETPTR_BUF(cpack, m_send.GetBuffer(total_size));
436 Protocol::Packet &packet = *cpack;
438 // socket class sets socket for us
439 packet.size = htobs(total_size);
440 packet.command = SB_COMMAND_DB_DATA;
441 packet.u.db.tableCmd = m_con.GetDBCommand(Mode::Desktop::DatabaseAccess);
442 packet.u.db.u.command.operation = SB_DBOP_ADD_RECORD;
443 packet.u.db.u.command.databaseId = htobs(dbId);
444 packet.u.db.u.command.u.tag_upload.rectype = send.GetRecType();
445 packet.u.db.u.command.u.tag_upload.uniqueId = htobl(send.GetUniqueId());
446 packet.u.db.u.command.u.tag_upload.unknown2 = 1; // unknown observed value
448 m_send.ReleaseBuffer(total_size);
450 m_last_dbop = SB_DBOP_ADD_RECORD;
451 return true;
455 // throws FIXME if packet doesn't support it
456 unsigned int DBPacket::ReturnCode() const
458 if( Command() == SB_COMMAND_DB_DONE ) {
459 Protocol::CheckSize(*m_receive, SB_PACKET_DBACCESS_HEADER_SIZE + SB_DBACCESS_RETURN_CODE_SIZE);
460 MAKE_PACKET(rpack, *m_receive);
461 return rpack->u.db.u.return_code;
463 else {
464 throw Error("Attempting to extract a return code from the wrong response packet type");
469 // DBOperation
471 /// Returns the database operation code from the receive packet, assuming
472 /// that receive contains a response packet. If receive isn't large
473 /// enough, throws Error.
475 unsigned int DBPacket::DBOperation() const
477 Protocol::CheckSize(*m_receive, SB_PACKET_RESPONSE_HEADER_SIZE);
478 MAKE_PACKET(rpack, *m_receive);
479 return rpack->u.db.u.response.operation;
483 // Parse
485 /// Parses the data in the receive buffer, and attempts to be smart about it,
486 /// using the last send command as guidance for what to expect in the
487 /// response.
489 /// \returns bool true - packet was recognized and parse was attempted
490 /// false - packet was not recognized
492 bool DBPacket::Parse(Parser &parser, const std::string &dbname,
493 const IConverter *ic)
495 size_t offset = 0;
496 MAKE_PACKET(rpack, *m_receive);
498 switch( m_last_dbop )
500 case SB_DBOP_OLD_GET_RECORDS:
501 case SB_DBOP_GET_RECORD_BY_INDEX:
502 offset = SB_PACKET_RESPONSE_HEADER_SIZE + DBR_OLD_TAGGED_RECORD_HEADER_SIZE;
503 Protocol::CheckSize(*m_receive, offset);
505 // FIXME - this may need adjustment for email records... they
506 // don't seem to have uniqueID's
508 DBData block(DBData::REC_VERSION_1, dbname,
509 rpack->u.db.u.response.u.tagged.rectype,
510 btohl(rpack->u.db.u.response.u.tagged.uniqueId),
511 offset, *m_receive, false);
512 parser.ParseRecord(block, ic);
514 return true;
516 default: // unknown command
517 return false;
522 // ParseMeta
524 /// Fills DBData's meta data based on its data block, and the last dbop.
526 bool DBPacket::ParseMeta(DBData &data)
528 size_t offset = 0;
529 MAKE_PACKET(rpack, data.GetData());
531 switch( m_last_dbop )
533 case SB_DBOP_OLD_GET_RECORDS:
534 case SB_DBOP_GET_RECORD_BY_INDEX:
535 data.SetVersion(DBData::REC_VERSION_1);
537 offset = SB_PACKET_RESPONSE_HEADER_SIZE + DBR_OLD_TAGGED_RECORD_HEADER_SIZE;
538 Protocol::CheckSize(data.GetData(), offset);
539 data.SetOffset(offset);
541 // FIXME - this may need adjustment for email records... they
542 // don't seem to have uniqueID's
543 data.SetIds(rpack->u.db.u.response.u.tagged.rectype,
544 btohl(rpack->u.db.u.response.u.tagged.uniqueId));
545 return true;
547 default: // unknown command
548 return false;
554 //////////////////////////////////////////////////////////////////////////////
555 // JLPacket class
557 JLPacket::JLPacket(Data &cmd, Data &send, Data &receive)
558 : Packet(send, receive)
559 , m_cmd(cmd)
560 , m_data(send)
561 , m_last_set_size(0)
565 JLPacket::~JLPacket()
569 unsigned int JLPacket::Size()
571 Protocol::CheckSize(*m_receive, SB_JLPACKET_HEADER_SIZE + SB_JLRESPONSE_HEADER_SIZE);
572 MAKE_JLPACKET(rpack, *m_receive);
573 return btohs(rpack->u.response.expect);
577 // returns 1 or 2 depending on whether cmd or cmd+send are available
578 int JLPacket::SimpleCmd(uint8_t cmd, uint8_t unknown, uint16_t size)
580 MAKE_JLPACKETPTR_BUF(cpack, m_cmd.GetBuffer(8));
581 Protocol::JLPacket &packet = *cpack;
583 // socket class sets socket for us
584 packet.size = htobs(8);
585 packet.u.command.command = cmd;
586 packet.u.command.unknown = unknown;
587 packet.u.command.size = htobs(size);
589 m_cmd.ReleaseBuffer(8);
591 return m_last_set_size = 1;
594 int JLPacket::SimpleData(const void *data, uint16_t size)
596 uint16_t total = size + 4;
598 MAKE_JLPACKETPTR_BUF(dpack, m_data.GetBuffer(total));
600 // socket class sets socket for us
601 dpack->size = htobs(total);
602 memcpy(dpack->u.raw, data, size);
604 m_data.ReleaseBuffer(total);
606 return m_last_set_size = 2;
609 int JLPacket::BigEndianData(uint16_t value)
611 value = be_htobs(value);
612 return SimpleData(&value, sizeof(value));
615 int JLPacket::BigEndianData(uint32_t value)
617 value = be_htobl(value);
618 return SimpleData(&value, sizeof(value));
621 int JLPacket::SetUnknown1()
623 SimpleCmd(SB_COMMAND_JL_SET_UNKNOWN1, 0, 1);
624 uint8_t arg = 0;
625 return SimpleData(&arg, 1);
628 int JLPacket::SetCodFilename(const std::string &filename)
630 SimpleCmd(SB_COMMAND_JL_SET_COD_FILENAME, 0, filename.size());
631 return SimpleData(filename.data(), filename.size());
634 int JLPacket::SetCodSize(off_t size)
636 SimpleCmd(SB_COMMAND_JL_SET_COD_SIZE, 1, 4);
637 return BigEndianData((uint32_t)size);
640 int JLPacket::SetTime(time_t when)
642 SimpleCmd(SB_COMMAND_JL_SET_TIME, 0, 4);
643 return BigEndianData((uint32_t)when);
646 int JLPacket::GetSubDir(uint16_t id)
648 SimpleCmd(SB_COMMAND_JL_GET_SUBDIR, 0, 2);
649 return BigEndianData(id);
652 int JLPacket::GetDirEntry(uint8_t entry_cmd, uint16_t id)
654 SimpleCmd(entry_cmd, 0, 2);
655 return BigEndianData(id);
658 int JLPacket::GetScreenshot()
660 SimpleCmd(SB_COMMAND_JL_GET_SCREENSHOT, 0, 4);
661 return BigEndianData((uint32_t) 0);
664 int JLPacket::Erase(uint16_t cmd, uint16_t id)
666 SimpleCmd(cmd, 0, 2);
667 return BigEndianData(id);
670 int JLPacket::GetEventlogEntry(uint16_t entry_num)
672 SimpleCmd(SB_COMMAND_JL_GET_LOG_ENTRY, 0, 2);
673 return BigEndianData(entry_num);
676 int JLPacket::SaveModule(uint16_t id)
678 SimpleCmd(SB_COMMAND_JL_SAVE_MODULE, 0, 2);
679 return BigEndianData(id);
682 int JLPacket::PutData(const void *data, uint16_t size)
684 SimpleCmd(SB_COMMAND_JL_SEND_DATA, 0, size);
685 return SimpleData(data, size);
689 //////////////////////////////////////////////////////////////////////////////
690 // JVMPacket class
692 JVMPacket::JVMPacket(Data &send, Data &receive)
693 : Packet(send, receive)
694 , m_cmd(send)
698 JVMPacket::~JVMPacket()
703 unsigned int JVMPacket::Size()
705 MAKE_JVMPACKET(rpack, *m_receive);
706 Protocol::CheckSize(*m_receive, SB_JVMPACKET_HEADER_SIZE + sizeof(rpack->u.expect));
707 return be_btohs(rpack->u.expect);
711 // Command format (param is optionnal) :
712 // 00000000: 05 00 07 00 00 01 8a
713 // ^^ : command
714 // ^^^^^ : size of commd + param
715 // ^^^^^ : packet size
716 // ^^^^^ : socket ID
717 void JVMPacket::SimpleCmd(uint8_t cmd)
719 // 4 : socket id field + packet size field
720 // 2 : size field
721 // 1 : command field
722 const uint16_t total = 4 + 2 + 1;
724 MAKE_JVMPACKETPTR_BUF(cpack, m_cmd.GetBuffer(total));
725 Protocol::JVMPacket &packet = *cpack;
727 // socket class sets socket for us
728 packet.size = htobs(total);
729 packet.u.command.size = be_htobs(1);
730 packet.u.command.command = cmd;
732 m_cmd.ReleaseBuffer(total);
735 // Command with parameter format :
736 // 00000000: 05 00 0b 00 00 05 8d 00 00 00 00
737 // ^^^^^^^^^^^ : param
738 // ^^ : command
739 // ^^^^^ : size of commd + param
740 // ^^^^^ : packet size
741 // ^^^^^ : socket ID
742 void JVMPacket::ComplexCmd(uint8_t cmd, const void *param, uint16_t size)
744 // 4 : socket id field + packet size field
745 // 2 : size field
746 // 1 : command field
747 uint16_t total = 4 + 2 + 1 + size;
749 MAKE_JVMPACKETPTR_BUF(cpack, m_cmd.GetBuffer(total));
750 Protocol::JVMPacket &packet = *cpack;
752 // socket class sets socket for us
753 packet.size = htobs(total);
754 packet.u.command.size = be_htobs(1 + size);
755 packet.u.command.command = cmd;
757 if ((size > 0) && (param != NULL))
758 memcpy(cpack->u.command.raw, param, size);
760 m_cmd.ReleaseBuffer(total);
764 void JVMPacket::Unknown01() {
765 SimpleCmd(SB_COMMAND_JVM_UNKNOWN01);
769 void JVMPacket::Unknown02() {
770 SimpleCmd(SB_COMMAND_JVM_UNKNOWN02);
774 void JVMPacket::Unknown03() {
775 SimpleCmd(SB_COMMAND_JVM_UNKNOWN03);
779 void JVMPacket::Unknown04() {
780 SimpleCmd(SB_COMMAND_JVM_UNKNOWN04);
784 void JVMPacket::Unknown05() {
785 SimpleCmd(SB_COMMAND_JVM_UNKNOWN05);
789 void JVMPacket::Unknown06() {
790 uint32_t param = 0;
792 ComplexCmd(SB_COMMAND_JVM_UNKNOWN06, &param, sizeof(param));
796 void JVMPacket::Unknown07() {
797 uint32_t param = 0;
799 ComplexCmd(SB_COMMAND_JVM_UNKNOWN07, &param, sizeof(param));
803 void JVMPacket::Unknown08() {
804 uint32_t param = 0;
806 ComplexCmd(SB_COMMAND_JVM_UNKNOWN08, &param, sizeof(param));
810 void JVMPacket::Unknown09() {
811 uint32_t param = be_htobl(0x09);
813 ComplexCmd(SB_COMMAND_JVM_UNKNOWN09, &param, sizeof(param));
817 void JVMPacket::Unknown10() {
818 uint32_t param = be_htobl(0x01);
820 ComplexCmd(SB_COMMAND_JVM_UNKNOWN10, &param, sizeof(param));
824 void JVMPacket::Unknown11(uint32_t id) {
825 id = be_htobl(id);
827 ComplexCmd(SB_COMMAND_JVM_UNKNOWN11, &id, sizeof(id));
831 void JVMPacket::Unknown12(uint32_t id) {
832 id = be_htobl(id);
834 ComplexCmd(SB_COMMAND_JVM_UNKNOWN12, &id, sizeof(id));
838 void JVMPacket::Unknown13(uint32_t id) {
839 id = be_htobl(id);
841 ComplexCmd(SB_COMMAND_JVM_UNKNOWN13, &id, sizeof(id));
845 void JVMPacket::Unknown14(uint32_t id) {
846 id = be_htobl(id);
848 ComplexCmd(SB_COMMAND_JVM_UNKNOWN14, &id, sizeof(id));
852 void JVMPacket::Unknown15(uint32_t id) {
853 id = be_htobl(id);
855 ComplexCmd(SB_COMMAND_JVM_UNKNOWN15, &id, sizeof(id));
859 void JVMPacket::GetModulesList(uint32_t id) {
860 id = be_htobl(id);
862 ComplexCmd(SB_COMMAND_JVM_GET_MODULES_LIST, &id, sizeof(id));
866 void JVMPacket::GetThreadsList() {
867 SimpleCmd(SB_COMMAND_JVM_GET_THREADS_LIST);
871 void JVMPacket::GetConsoleMessage() {
872 SimpleCmd(SB_COMMAND_JVM_GET_CONSOLE_MSG);
876 void JVMPacket::Go()
878 SimpleCmd(SB_COMMAND_JVM_GO);
882 void JVMPacket::Stop()
884 // 4 : socket id field + packet size field
885 // 2 : value field
886 const uint16_t total = 4 + 2;
888 MAKE_JVMPACKETPTR_BUF(cpack, m_cmd.GetBuffer(total));
889 Protocol::JVMPacket &packet = *cpack;
891 // socket class sets socket for us
892 packet.size = htobs(total);
893 packet.u.value = be_htobs(SB_COMMAND_JVM_STOP);
895 m_cmd.ReleaseBuffer(total);
899 void JVMPacket::GetStatus()
901 SimpleCmd(SB_COMMAND_JVM_GET_STATUS);
904 } // namespace Barry