Complete documentation / fix bug
[barry/progweb.git] / src / m_javadebug.cc
blob58070fb36ab8a0a31eb6b136a792f52394b2c656
1 ///
2 /// \file m_javadebug.cc
3 /// Mode class for the JavaDebug mode
4 ///
6 /*
7 Copyright (C) 2005-2009, Net Direct Inc. (http://www.netdirect.ca/)
8 Copyright (C) 2008-2009, Nicolas VIVIEN
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19 See the GNU General Public License in the COPYING file at the
20 root directory of this project for more details.
23 #include "m_javadebug.h"
24 #include "data.h"
25 #include "protocol.h"
26 #include "protostructs.h"
27 #include "packet.h"
28 #include "endian.h"
29 #include "error.h"
30 #include "usbwrap.h"
31 #include "controller.h"
32 #include "cod.h"
33 #include <stdexcept>
34 #include <sstream>
35 #include <iomanip>
36 #include <vector>
37 #include <string.h>
38 #include <time.h>
39 #include <stdio.h>
41 #include "debug.h"
43 using namespace std;
45 namespace Barry {
47 ///////////////////////////////////////////////////////////////////////////////
48 // JDModulesList class
50 void JDModulesList::Parse(const Data &entry_packet)
52 uint16_t count = 0;
54 size_t size = entry_packet.GetSize();
56 while (count < size) {
57 uint16_t len = 0;
59 const unsigned char *ptr = (entry_packet.GetData() + count);
60 Protocol::JDModulesEntry *e = (Protocol::JDModulesEntry *) ptr;
62 len = SB_JDMODULES_ENTRY_HEADER_SIZE + be_btohs(e->sizename);
64 JDModulesEntry entry;
66 entry.Id = be_btohl(e->id);
67 entry.Address = be_btohl(e->address);
68 (entry.Name).assign((char *) (ptr + SB_JDMODULES_ENTRY_HEADER_SIZE), be_btohs(e->sizename));
70 push_back(entry);
72 count += len;
77 void JDModulesList::Dump(std::ostream &os) const
79 const_iterator i = begin(), e = end();
81 os << " ID " << "|";
82 os << " Address " << "|";
83 os << " Module Name" << endl;
85 os << "------------+";
86 os << "------------+";
87 os << "-------------";
88 os << endl;
90 for( ; i != e; ++i ) {
91 (*i).Dump(os);
96 ///////////////////////////////////////////////////////////////////////////////
97 // JDModulesEntry class
99 void JDModulesEntry::Dump(std::ostream &os) const
101 os << " 0x" << setfill('0') << setw(8) << hex << Id << " |";
102 os << " 0x" << setfill('0') << setw(8) << hex << Address << " |";
103 os << " " << Name << endl;
107 ///////////////////////////////////////////////////////////////////////////////
108 // JDThreadsList class
110 void JDThreadsList::Parse(const Data &entry_packet)
112 uint16_t count = 0;
114 size_t size = entry_packet.GetSize();
116 while (count < size) {
117 uint16_t len = 0;
119 const unsigned char *ptr = (entry_packet.GetData() + count);
120 uint32_t *e = (uint32_t *) ptr;
122 len = sizeof(uint32_t);
124 JDThreadsEntry entry;
126 entry.Id = be_btohl(*e);
128 push_back(entry);
130 count += len;
135 void JDThreadsList::Dump(std::ostream &os) const
137 const_iterator i = begin(), e = end();
139 os << " Thread " << "|";
140 os << " Byte " << "|";
141 os << " Address " << "|";
142 os << " Unknown01 " << "|";
143 os << " Unknown02 " << "|";
144 os << " Unknown03 " << "|";
145 os << " Unknown04 " << "|";
146 os << " Unknown05 " << "|";
147 os << " Unknown06 " << "|";
149 os << "------------+";
150 os << "------+";
151 os << "------------+";
152 os << "------------+";
153 os << "------------+";
154 os << "------------+";
155 os << "------------+";
156 os << "------------+";
157 os << "-------------";
158 os << endl;
160 for(int k=0 ; i != e; ++i, k++ ) {
161 (*i).Dump(os, k);
166 void JDThreadsEntry::Dump(std::ostream &os, int num) const
168 os << " " << setfill(' ') << setw(8) << dec << num << " |";
169 os << " 0x" << setfill('0') << setw(8) << hex << (Id) << " |";
170 os << " 0x" << setfill('0') << setw(2) << hex << (Byte) << " |";
171 os << " 0x" << setfill('0') << setw(8) << hex << (Address) << " |";
172 os << " 0x" << setfill('0') << setw(8) << hex << (Unknown01) << " |";
173 os << " 0x" << setfill('0') << setw(8) << hex << (Unknown02) << " |";
174 os << " 0x" << setfill('0') << setw(8) << hex << (Unknown03) << " |";
175 os << " 0x" << setfill('0') << setw(8) << hex << (Unknown04) << " |";
176 os << " 0x" << setfill('0') << setw(8) << hex << (Unknown05) << " |";
177 os << " 0x" << setfill('0') << setw(8) << hex << (Unknown06) << endl;
181 namespace Mode {
183 ///////////////////////////////////////////////////////////////////////////////
184 // JavaDebug Mode class
186 JavaDebug::JavaDebug(Controller &con)
187 : Mode(con, Controller::JavaDebug)
188 , m_Attached(false)
192 JavaDebug::~JavaDebug()
194 if( m_Attached )
195 Detach();
198 ///////////////////////////////////////////////////////////////////////////////
199 // protected members
202 ///////////////////////////////////////////////////////////////////////////////
203 // public API
205 void JavaDebug::OnOpen()
207 m_socket->InitSequence();
211 // Attach
213 /// These commands are sent to prepare the debug communication.
214 /// Must be called at the start of a JavaDebug session.
216 void JavaDebug::Attach()
221 // Detach
223 /// Must be called at the end of a JavaDebug session. The JD_GOODBYE
224 /// command is sent to the device.
226 void JavaDebug::Detach()
231 void JavaDebug::ThrowJDError(const std::string &msg, uint8_t cmd)
233 std::ostringstream oss;
234 oss << msg << ": unexpected packet command code: 0x"
235 << std::hex << (unsigned int) cmd;
236 throw Error(oss.str());
241 // Unknown 01 ???
243 void JavaDebug::Unknown01()
245 uint16_t expect = 0;
247 Data command(-1, 8), response;
248 JDPacket packet(command, response);
250 // Send the command packet
251 packet.Unknown01();
252 m_socket->Packet(packet);
253 expect = packet.Size();
255 if (expect == 0)
256 return;
258 // Read the data stream
259 m_socket->ReceiveData(response);
261 size_t bytereceived = response.GetSize() - 4;
263 // Check the size read into the previous packet
264 if( expect != bytereceived ) {
265 ThrowJDError("JavaDebug::Attach expect", expect);
271 // Unknown 02 ???
273 void JavaDebug::Unknown02()
275 uint16_t expect = 0;
277 Data command(-1, 8), response;
278 JDPacket packet(command, response);
280 // Send the command packet
281 packet.Unknown02();
282 m_socket->Packet(packet);
283 expect = packet.Size();
285 if (expect == 0)
286 return;
288 // Read the data stream
289 m_socket->ReceiveData(response);
291 size_t bytereceived = response.GetSize() - 4;
293 // Check the size read into the previous packet
294 if( expect != bytereceived ) {
295 ThrowJDError("JavaDebug::Attach expect", expect);
301 // Unknown 03 ???
303 void JavaDebug::Unknown03()
305 uint16_t expect = 0;
307 Data command(-1, 8), response;
308 JDPacket packet(command, response);
310 // Send the command packet
311 packet.Unknown03();
312 m_socket->Packet(packet);
313 expect = packet.Size();
315 if (expect == 0)
316 return;
318 // Read the data stream
319 m_socket->ReceiveData(response);
321 size_t bytereceived = response.GetSize() - 4;
323 // Check the size read into the previous packet
324 if( expect != bytereceived ) {
325 ThrowJDError("JavaDebug::Attach expect", expect);
331 // Unknown 04 ???
333 void JavaDebug::Unknown04()
335 uint16_t expect = 0;
337 Data command(-1, 8), response;
338 JDPacket packet(command, response);
340 // Send the command packet
341 packet.Unknown04();
342 m_socket->Packet(packet);
343 expect = packet.Size();
345 if (expect == 0)
346 return;
348 // Read the data stream
349 m_socket->ReceiveData(response);
351 size_t bytereceived = response.GetSize() - 4;
353 // Check the size read into the previous packet
354 if( expect != bytereceived ) {
355 ThrowJDError("JavaDebug::Attach expect", expect);
361 // Unknown 05 ???
363 void JavaDebug::Unknown05()
365 uint16_t expect = 0;
367 Data command(-1, 8), response;
368 JDPacket packet(command, response);
370 // Send the command packet
371 packet.Unknown05();
372 m_socket->Packet(packet);
373 expect = packet.Size();
375 if (expect == 0)
376 return;
378 // Read the data stream
379 m_socket->ReceiveData(response);
381 size_t bytereceived = response.GetSize() - 4;
383 // Check the size read into the previous packet
384 if( expect != bytereceived ) {
385 ThrowJDError("JavaDebug::Attach expect", expect);
391 // Unknown 06 ???
393 void JavaDebug::Unknown06()
395 uint16_t expect = 0;
397 Data command(-1, 8), response;
398 JDPacket packet(command, response);
400 // Send the command packet
401 packet.Unknown06();
402 m_socket->Packet(packet);
403 expect = packet.Size();
405 if (expect == 0)
406 return;
408 // Read the data stream
409 m_socket->ReceiveData(response);
411 size_t bytereceived = response.GetSize() - 4;
413 // Check the size read into the previous packet
414 if( expect != bytereceived ) {
415 ThrowJDError("JavaDebug::Attach expect", expect);
421 // Unknown 07 ???
423 void JavaDebug::Unknown07()
425 uint16_t expect = 0;
427 Data command(-1, 8), response;
428 JDPacket packet(command, response);
430 // Send the command packet
431 packet.Unknown07();
432 m_socket->Packet(packet);
433 expect = packet.Size();
435 if (expect == 0)
436 return;
438 // Read the data stream
439 m_socket->ReceiveData(response);
441 size_t bytereceived = response.GetSize() - 4;
443 // Check the size read into the previous packet
444 if( expect != bytereceived ) {
445 ThrowJDError("JavaDebug::Attach expect", expect);
451 // Unknown 08 ???
453 void JavaDebug::Unknown08()
455 uint16_t expect = 0;
457 Data command(-1, 8), response;
458 JDPacket packet(command, response);
460 // Send the command packet
461 packet.Unknown08();
462 m_socket->Packet(packet);
463 expect = packet.Size();
465 if (expect == 0)
466 return;
468 // Read the data stream
469 m_socket->ReceiveData(response);
471 size_t bytereceived = response.GetSize() - 4;
473 // Check the size read into the previous packet
474 if( expect != bytereceived ) {
475 ThrowJDError("JavaDebug::Attach expect", expect);
481 // Unknown 09 ???
483 void JavaDebug::Unknown09()
485 uint16_t expect = 0;
487 Data command(-1, 8), response;
488 JDPacket packet(command, response);
490 // Send the command packet
491 packet.Unknown09();
492 m_socket->Packet(packet);
493 expect = packet.Size();
495 if (expect == 0)
496 return;
498 // Read the data stream
499 m_socket->ReceiveData(response);
501 size_t bytereceived = response.GetSize() - 4;
503 // Check the size read into the previous packet
504 if( expect != bytereceived ) {
505 ThrowJDError("JavaDebug::Attach expect", expect);
511 // Unknown 10 ???
513 void JavaDebug::Unknown10()
515 uint16_t expect = 0;
517 Data command(-1, 8), response;
518 JDPacket packet(command, response);
520 // Send the command packet
521 packet.Unknown10();
522 m_socket->Packet(packet);
523 expect = packet.Size();
525 if (expect == 0)
526 return;
528 // Read the data stream
529 m_socket->ReceiveData(response);
531 size_t bytereceived = response.GetSize() - 4;
533 // Check the size read into the previous packet
534 if( expect != bytereceived ) {
535 ThrowJDError("JavaDebug::Attach expect", expect);
541 // Get Status
543 bool JavaDebug::GetStatus(int &status)
545 uint16_t expect = 0;
547 Data command(-1, 8), response;
548 JDPacket packet(command, response);
550 // Send the command packet
551 packet.GetStatus();
553 m_socket->Packet(packet);
555 expect = packet.Size();
557 if (expect == 0)
558 return false;
560 // Read the data stream
561 m_socket->ReceiveData(response);
563 MAKE_JDPACKET(dpack, response);
565 size_t bytereceived = response.GetSize() - 4;
567 // Check the size read into the previous packet
568 if( expect != bytereceived ) {
569 ThrowJDError("JavaDebug::GetModulesList expect", expect);
572 // Return status
573 status = dpack->u.status;
575 return true;
580 // Wait Status
582 bool JavaDebug::WaitStatus(int &status)
584 uint16_t expect = 0;
586 Data command(-1, 8), response;
587 JDPacket packet(command, response);
589 // Prepare the command packet
590 packet.GetStatus();
592 try {
593 m_socket->Receive(packet.GetReceive(), 100);
594 } catch (Usb::Timeout &to ) {
595 return false;
598 expect = packet.Size();
600 if (expect == 0)
601 return false;
603 // Read the data stream
604 m_socket->ReceiveData(response);
606 MAKE_JDPACKET(dpack, response);
608 size_t bytereceived = response.GetSize() - 4;
610 // Check the size read into the previous packet
611 if( expect != bytereceived ) {
612 ThrowJDError("JavaDebug::GetModulesList expect", expect);
615 // Return status
616 status = dpack->u.status;
618 return true;
623 // Get Console Message
624 // Sample, display the output of System.out.println(...) and all JVM messages output
626 // Return the length message or -1 if message doesn't exit or is empty
628 int JavaDebug::GetConsoleMessage(std::string &message)
630 uint16_t expect = 0;
632 Data command(-1, 8), response;
633 JDPacket packet(command, response);
635 // Send the command packet
636 packet.GetConsoleMessage();
638 m_socket->Packet(packet);
640 expect = packet.Size();
642 if (expect == 0)
643 return -1;
645 // Read the data stream
646 m_socket->ReceiveData(response);
648 MAKE_JDPACKET(dpack, response);
650 size_t bytereceived = response.GetSize() - 4;
652 // Check the size read into the previous packet
653 if( expect != bytereceived ) {
654 ThrowJDError("JavaDebug::GetModulesList expect", expect);
657 // Length of message
658 uint16_t length = be_btohs(dpack->u.msglength);
660 if (length == 0)
661 return -1;
663 // Parse the ID of nextmodules
664 const unsigned char *ptr = (response.GetData() + SB_JDPACKET_HEADER_SIZE + sizeof(uint16_t));
666 message.assign((char *) ptr, length);
668 return length;
673 // Get list of Java modules
675 void JavaDebug::GetModulesList(JDModulesList &mylist)
677 uint32_t size = 0;
678 uint32_t count = 0;
679 uint32_t offset = 0;
680 uint16_t expect = 0;
682 Data command(-1, 8), response;
683 JDPacket packet(command, response);
685 do {
686 // Send the command packet
687 packet.GetModulesList(offset);
689 m_socket->Packet(packet);
691 expect = packet.Size();
693 if (expect == 0)
694 break;
696 // Read the data stream
697 m_socket->ReceiveData(response);
699 MAKE_JDPACKET(dpack, response);
701 size_t bytereceived = response.GetSize() - 4;
703 // Check the size read into the previous packet
704 if( expect != bytereceived ) {
705 ThrowJDError("JavaDebug::GetModulesList expect", expect);
708 // Number of modules entries in the list
709 count = be_btohl(dpack->u.moduleslist.nbr);
711 // Size of modules list
712 // I remove the header of packet (contains the field 'number of modules')
713 // and 4 bytes (contains the field 'ID of next modules')
714 size = bytereceived - SB_JDMODULES_LIST_HEADER_SIZE - 4;
716 // Parse the modules list
717 mylist.Parse(Data(response.GetData() + SB_JDPACKET_HEADER_SIZE + SB_JDMODULES_LIST_HEADER_SIZE, size));
719 // Parse the ID of nextmodules
720 const unsigned char *ptr = (response.GetData() + SB_JDPACKET_HEADER_SIZE + SB_JDMODULES_LIST_HEADER_SIZE + size);
721 uint32_t *poffset = (uint32_t *) ptr;
723 offset = be_btohl(*poffset);
724 } while (offset != 0); // When the offset != 0, there is some modules
729 // Get list of Java threads
731 void JavaDebug::GetThreadsList(JDThreadsList &mylist)
733 uint32_t size = 0;
734 uint32_t count = 0;
735 uint16_t expect = 0;
737 Data command(-1, 8), response;
738 JDPacket packet(command, response);
740 // Send the command packet
741 packet.GetThreadsList();
743 m_socket->Packet(packet);
745 expect = packet.Size();
747 if (expect == 0)
748 return;
750 // Read the data stream
751 m_socket->ReceiveData(response);
753 MAKE_JDPACKET(dpack, response);
755 size_t bytereceived = response.GetSize() - 4;
757 // Check the size read into the previous packet
758 if( expect != bytereceived ) {
759 ThrowJDError("JavaDebug::GetThreadsList expect", expect);
762 // Number of threads entries in the list
763 count = be_btohl(dpack->u.threadslist.nbr);
765 // Size of threads list
766 // I remove the header of packet (contains the field 'number of threads')
767 size = bytereceived - SB_JDTHREADS_LIST_HEADER_SIZE;
769 // Parse the threads list
770 mylist.Parse(Data(response.GetData() + SB_JDPACKET_HEADER_SIZE + SB_JDTHREADS_LIST_HEADER_SIZE, size));
772 // Complete threads list
773 vector<JDThreadsEntry>::iterator b = mylist.begin();
774 for( ; b != mylist.end(); b++ ) {
775 JDThreadsEntry entry = (*b);
777 // 1°/
778 // Send the command packet
779 packet.Unknown11(entry.Id);
781 m_socket->Packet(packet);
783 expect = packet.Size();
785 if (expect == 0)
786 return;
788 // Read the data stream
789 m_socket->ReceiveData(response);
791 dpack = (const Protocol::JDPacket *) response.GetData();
793 bytereceived = response.GetSize() - 4;
795 // Check the size read into the previous packet
796 if( expect != bytereceived ) {
797 ThrowJDError("JavaDebug::GetThreadsList (1) expect", expect);
800 // Save values
801 entry.Byte = dpack->u.unknown01.byte;
802 entry.Address = be_btohl(dpack->u.unknown01.address);
804 // 2°/
805 if (entry.Address != 0) {
806 // Send the command packet
807 packet.Unknown12(entry.Address);
809 m_socket->Packet(packet);
811 expect = packet.Size();
813 if (expect == 0)
814 return;
816 // Read the data stream
817 m_socket->ReceiveData(response);
819 dpack = (const Protocol::JDPacket *) response.GetData();
821 bytereceived = response.GetSize() - 4;
823 // Check the size read into the previous packet
824 if( expect != bytereceived ) {
825 ThrowJDError("JavaDebug::GetThreadsList (2) expect", expect);
828 // Save values
829 entry.Unknown01 = be_btohl(dpack->u.address);
831 else
832 entry.Unknown01 = 0;
834 // 3°/
835 // Send the command packet
836 packet.Unknown13(entry.Id);
838 m_socket->Packet(packet);
840 expect = packet.Size();
842 if (expect == 0)
843 return;
845 // Read the data stream
846 m_socket->ReceiveData(response);
848 dpack = (const Protocol::JDPacket *) response.GetData();
850 bytereceived = response.GetSize() - 4;
852 // Check the size read into the previous packet
853 if( expect != bytereceived ) {
854 ThrowJDError("JavaDebug::GetThreadsList (2) expect", expect);
857 // Save values
858 entry.Unknown02 = be_btohl(dpack->u.address);
860 // 4°/
861 // Send the command packet
862 packet.Unknown14(entry.Id);
864 m_socket->Packet(packet);
866 expect = packet.Size();
868 if (expect == 0)
869 return;
871 // Read the data stream
872 m_socket->ReceiveData(response);
874 dpack = (const Protocol::JDPacket *) response.GetData();
876 bytereceived = response.GetSize() - 4;
878 // Check the size read into the previous packet
879 if( expect != bytereceived ) {
880 ThrowJDError("JavaDebug::GetThreadsList (2) expect", expect);
883 // Save values
884 entry.Unknown03 = be_btohl(dpack->u.unknown02.address1);
885 entry.Unknown04 = be_btohl(dpack->u.unknown02.address2);
887 // 5°/
888 // Send the command packet
889 packet.Unknown15(entry.Id);
891 m_socket->Packet(packet);
893 expect = packet.Size();
895 if (expect == 0)
896 return;
898 // Read the data stream
899 m_socket->ReceiveData(response);
901 dpack = (const Protocol::JDPacket *) response.GetData();
903 bytereceived = response.GetSize() - 4;
905 // Check the size read into the previous packet
906 if( expect != bytereceived ) {
907 ThrowJDError("JavaDebug::GetThreadsList (2) expect", expect);
910 // Save values
911 entry.Unknown05 = be_btohl(dpack->u.unknown02.address1);
912 entry.Unknown06 = be_btohl(dpack->u.unknown02.address2);
918 // Go
920 void JavaDebug::Go()
922 uint16_t expect = 0;
924 Data command(-1, 8), response;
925 JDPacket packet(command, response);
927 // Send the command packet
928 packet.Go();
929 m_socket->Packet(packet);
930 expect = packet.Size();
932 while (expect == 0) {
933 m_socket->Receive(packet.GetReceive());
935 expect = packet.Size();
938 // Read the data stream
939 m_socket->ReceiveData(response);
941 size_t bytereceived = response.GetSize() - 4;
943 // Check the size read into the previous packet
944 if( expect != bytereceived ) {
945 ThrowJDError("JavaDebug::Attach expect", expect);
951 // Stop
953 void JavaDebug::Stop()
955 uint16_t expect = 0;
957 Data command(-1, 8), response;
958 JDPacket packet(command, response);
960 // Send the command packet
961 packet.Stop();
962 m_socket->Packet(packet);
963 expect = packet.Size();
965 while (expect == 0) {
966 m_socket->Receive(packet.GetReceive());
968 expect = packet.Size();
971 // Read the data stream
972 m_socket->ReceiveData(response);
974 size_t bytereceived = response.GetSize() - 4;
976 // Check the size read into the previous packet
977 if( expect != bytereceived ) {
978 ThrowJDError("JavaDebug::Attach expect", expect);
983 }} // namespace Barry::Mode