From 39a57a6c39afa9276d799be0f8829cdf0805b973 Mon Sep 17 00:00:00 2001
From: Josh Kropf <josh@archlappy.(none)>
Date: Fri, 30 Jan 2009 17:55:07 -0500
Subject: [PATCH 1/2] Preliminary work for eventlog command in javaloader

---
 src/m_javaloader.cc  |   32 ++++++++++++++++++++++++++++++++
 src/m_javaloader.h   |    1 +
 src/packet.cc        |    6 ++++++
 src/packet.h         |    2 ++
 src/protocol.h       |    3 +++
 tools/bjavaloader.cc |    4 ++++
 6 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/src/m_javaloader.cc b/src/m_javaloader.cc
index 672fff9..f394cee 100644
--- a/src/m_javaloader.cc
+++ b/src/m_javaloader.cc
@@ -698,6 +698,38 @@ void JavaLoader::ForceErase(const std::string &cod_name)
 	DoErase(SB_COMMAND_JL_FORCE_ERASE, cod_name);
 }
 
+void JavaLoader::GetEventlog()
+{
+	Data command(-1, 8), data(-1, 8), response;
+	JLPacket packet(command, data, response);
+
+	packet.GetEventlog();
+
+	m_socket->Packet(packet);
+
+	if( packet.Command() != SB_COMMAND_JL_ACK ) {
+		ThrowJLError("JavaLoader::GetEventlog", packet.Command());
+	}
+
+	m_socket->Receive(response);
+	Protocol::CheckSize(response, SB_JLPACKET_HEADER_SIZE + sizeof(uint16_t));
+	MAKE_JLPACKET(jpack, response);
+
+	uint16_t count = jpack->u.response.expect;
+
+//	while( count > 0 ) {
+		packet.GetEventlogEntry();
+
+		m_socket->Packet(packet);
+
+		if( packet.Command() != SB_COMMAND_JL_ACK ) {
+			ThrowJLError("JavaLoader::GetEventlog", packet.Command());
+		}
+
+		m_socket->Receive(response);
+		cout << response << endl;
+//	}
+}
 
 }} // namespace Barry::Mode
 
diff --git a/src/m_javaloader.h b/src/m_javaloader.h
index 80fac98..d76bcb4 100644
--- a/src/m_javaloader.h
+++ b/src/m_javaloader.h
@@ -165,6 +165,7 @@ public:
 	void GetScreenshot(JLScreenInfo &info, Data &image);
 	void Erase(const std::string &cod_name);
 	void ForceErase(const std::string &cod_name);
+	void GetEventlog();
 };
 
 }} // namespace Barry::Mode
diff --git a/src/packet.cc b/src/packet.cc
index 1dca724..16a7a45 100644
--- a/src/packet.cc
+++ b/src/packet.cc
@@ -593,5 +593,11 @@ int JLPacket::Erase(uint16_t cmd, uint16_t id)
 	return BigEndianData(id);
 }
 
+int JLPacket::GetEventlogEntry()
+{
+	SimpleCmd(SB_COMMAND_JL_GET_LOG_ENTRY, 0, 2);
+	return BigEndianData((uint16_t)2);
+}
+
 } // namespace Barry
 
diff --git a/src/packet.h b/src/packet.h
index e0d229c..2cff3e0 100644
--- a/src/packet.h
+++ b/src/packet.h
@@ -224,6 +224,8 @@ public:
 	int GetSubDir(uint16_t id);
 	int GetDirEntry(uint8_t entry_cmd, uint16_t id);
 	int Erase(uint16_t cmd, uint16_t id);
+	int GetEventlog()	{ return SimpleCmd(SB_COMMAND_JL_GET_LOG); }
+	int GetEventlogEntry();
 
 	//////////////////////////////////
 	// response analysis
diff --git a/src/protocol.h b/src/protocol.h
index d330198..c6bc11d 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -59,6 +59,9 @@
 #define SB_COMMAND_JL_ERASE		0x69
 #define SB_COMMAND_JL_FORCE_ERASE	0x7b
 #define SB_COMMAND_JL_UNKNOWN3		0x63
+#define SB_COMMAND_JL_GET_LOG		0x73
+#define SB_COMMAND_JL_GET_LOG_ENTRY	0x74
+
 // JavaLoader response
 #define SB_COMMAND_JL_ACK		0x64
 #define SB_COMMAND_JL_READY		0x01
diff --git a/tools/bjavaloader.cc b/tools/bjavaloader.cc
index 5d3eab5..cb7a0b6 100644
--- a/tools/bjavaloader.cc
+++ b/tools/bjavaloader.cc
@@ -37,6 +37,7 @@
 #define CMD_LOAD	"load"
 #define CMD_SCREENSHOT	"screenshot"
 #define CMD_SETTIME	"settime"
+#define CMD_EVENTLOG    "eventlog"
 
 // time string format specifier and user friendly description
 #define TIME_FMT         "%Y-%m-%d %H:%M:%S"
@@ -303,6 +304,9 @@ int main(int argc, char *argv[])
 				SetTime(&javaloader, NULL);
 			}
 		}
+		else if( cmd == CMD_EVENTLOG ) {
+			javaloader.GetEventlog();
+		}
 		else {
 			cerr << "invalid command \"" << cmd << "\"" << endl;
 			Usage();
-- 
1.6.1.1


From ad4f667cad512224ce784814ebbaf543f29fb979 Mon Sep 17 00:00:00 2001
From: Josh Kropf <josh@slashdev.ca>
Date: Sat, 31 Jan 2009 16:40:15 -0500
Subject: [PATCH 2/2] Added dump eventlog and clear eventlog commands to javaloader

---
 src/m_javaloader.cc  |   98 ++++++++++++++++++++++++++++++++++++++++++++++----
 src/m_javaloader.h   |   47 +++++++++++++++++++++++-
 src/packet.cc        |    4 +-
 src/packet.h         |    3 +-
 src/protocol.h       |    1 +
 src/protostructs.h   |    9 +++++
 tools/bjavaloader.cc |   14 +++++++-
 7 files changed, 164 insertions(+), 12 deletions(-)

diff --git a/src/m_javaloader.cc b/src/m_javaloader.cc
index f394cee..308486a 100644
--- a/src/m_javaloader.cc
+++ b/src/m_javaloader.cc
@@ -164,6 +164,68 @@ void JLDirectoryEntry::Dump(std::ostream &os) const
 		os << "\n" << SubDir;
 }
 
+void JLEventlog::Dump(std::ostream &os) const
+{
+	const_iterator i = begin(), e = end();
+	for( ; i != e; ++i ) {
+		(*i).Dump(os);
+	}
+}
+
+void JLEventlogEntry::Parse(uint16_t size, const char* buf)
+{
+	// example of a single log entry
+	//guid:92E11214401C3 time:0x11F133E6470 severity:0 type:2 app:UI data:GS-D 2c89868b
+	
+	std::string src = std::string(buf, size);
+	std::istringstream ss(src);
+	
+	ss.ignore(5); // skip "guid:"
+	ss >> guid;
+	if( ss.fail() )
+		throw BadData("JLEventlogEntry:Parse bad guid field");
+	
+	ss.ignore(6); // skip " time:"
+	ss >> hex >> timestamp;
+	if( ss.fail() )
+		throw BadData("JLEventlogEntry:Parse bad time field");
+
+	ss.ignore(10); // skip " severity:"
+	ss >> (unsigned int&)severity;
+	if( ss.fail() )
+		throw BadData("JLEventlogEntry:Parse bad severity field");
+
+	ss.ignore(6); // skip " type:"
+	ss >> (unsigned int&)type;
+	if( ss.fail() )
+		throw BadData("JLEventlogEntry:Parse bad type field");
+
+	ss.ignore(5); // skip " app:"
+	ss >> app;
+	if( ss.fail() )
+		throw BadData("JLEventlogEntry:Parse bad app field");
+
+	ss.ignore(6); // skip " data:"
+	
+	// use stringbuf to extract rest of data from stream
+	stringbuf databuf;
+	ss >> &databuf;
+	if( ss.fail() )
+		throw BadData("JLEventlogEntry:Parse bad data field");
+
+	data = databuf.str();
+}
+
+
+void JLEventlogEntry::Dump(std::ostream &os) const
+{
+	os << "guid:"      << guid;
+	os << " time:"     << hex << timestamp;
+	os << " severity:" << severity; //TODO it might make sense to format
+	os << " type:"     << type;     //severity and type as meaningful names
+	os << " app:"      << app;
+	os << " data:"     << data << endl;
+}
 
 namespace Mode {
 
@@ -698,7 +760,7 @@ void JavaLoader::ForceErase(const std::string &cod_name)
 	DoErase(SB_COMMAND_JL_FORCE_ERASE, cod_name);
 }
 
-void JavaLoader::GetEventlog()
+void JavaLoader::GetEventlog(JLEventlog &log)
 {
 	Data command(-1, 8), data(-1, 8), response;
 	JLPacket packet(command, data, response);
@@ -713,12 +775,13 @@ void JavaLoader::GetEventlog()
 
 	m_socket->Receive(response);
 	Protocol::CheckSize(response, SB_JLPACKET_HEADER_SIZE + sizeof(uint16_t));
+	
+	// number of eventlog entries
 	MAKE_JLPACKET(jpack, response);
+	uint16_t count = be_btohs(jpack->u.response.expect);
 
-	uint16_t count = jpack->u.response.expect;
-
-//	while( count > 0 ) {
-		packet.GetEventlogEntry();
+	for( uint16_t i = 0; i < count; ++ i ) {
+		packet.GetEventlogEntry(i);
 
 		m_socket->Packet(packet);
 
@@ -727,8 +790,29 @@ void JavaLoader::GetEventlog()
 		}
 
 		m_socket->Receive(response);
-		cout << response << endl;
-//	}
+		Protocol::CheckSize(response, SB_JLPACKET_HEADER_SIZE + SB_JLEVENTLOG_ENTRY_SIZE);
+		
+		MAKE_JLPACKET(jpack, response);
+		uint16_t size = be_btohs(jpack->u.logentry.size);
+		
+		JLEventlogEntry entry;
+		entry.Parse(size, (const char *)(response.GetData() + 6));
+		
+		log.push_back(entry);
+	}
+}
+
+void JavaLoader::ClearEventlog()
+{
+	Data command(-1, 8), data(-1, 8), response;
+	JLPacket packet(command, data, response);
+
+	packet.ClearEventlog();
+	m_socket->Packet(packet);
+
+	if( packet.Command() != SB_COMMAND_JL_ACK ) {
+		ThrowJLError("JavaLoader::ClearEventlog", packet.Command());
+	}
 }
 
 }} // namespace Barry::Mode
diff --git a/src/m_javaloader.h b/src/m_javaloader.h
index d76bcb4..d0a4656 100644
--- a/src/m_javaloader.h
+++ b/src/m_javaloader.h
@@ -39,6 +39,8 @@ class CodFile;
 
 class JLDirectoryEntry;
 
+class JLEventlogEntry;
+
 class BXEXPORT JLDirectory : public std::vector<JLDirectoryEntry>
 {
 public:
@@ -107,6 +109,48 @@ public:
 };
 
 
+class BXEXPORT JLEventlog : public std::vector<JLEventlogEntry>
+{
+public:
+	void Dump(std::ostream &os) const;
+};
+BXEXPORT inline std::ostream& operator<<(std::ostream &os, const JLEventlog &log) {
+	log.Dump(os);
+	return os;
+}
+
+
+class BXEXPORT JLEventlogEntry
+{
+public:
+	typedef enum {
+		ALWAYS_LOG,
+		SEVERE_ERROR,
+		ERROR,
+		WARNING,
+		INFORMATION,
+		DEBUG_INFO
+	} Severity_t;
+
+	typedef enum {
+		NUMBER = 1,
+		STRING,
+		EXCEPTION
+	} ViewerType_t;
+
+	std::string  guid;
+	uint64_t     timestamp; //FIXME what is this? time since epoch? eg: 0x11F133E6470
+	Severity_t   severity;
+	ViewerType_t type;
+	std::string  app;
+	std::string  data;
+
+	void Parse(uint16_t size, const char* str);
+	
+	void Dump(std::ostream &os) const;
+};
+
+
 namespace Mode {
 
 //
@@ -165,7 +209,8 @@ public:
 	void GetScreenshot(JLScreenInfo &info, Data &image);
 	void Erase(const std::string &cod_name);
 	void ForceErase(const std::string &cod_name);
-	void GetEventlog();
+	void GetEventlog(JLEventlog &log);
+	void ClearEventlog();
 };
 
 }} // namespace Barry::Mode
diff --git a/src/packet.cc b/src/packet.cc
index 16a7a45..aa70d8d 100644
--- a/src/packet.cc
+++ b/src/packet.cc
@@ -593,10 +593,10 @@ int JLPacket::Erase(uint16_t cmd, uint16_t id)
 	return BigEndianData(id);
 }
 
-int JLPacket::GetEventlogEntry()
+int JLPacket::GetEventlogEntry(uint16_t entry_num)
 {
 	SimpleCmd(SB_COMMAND_JL_GET_LOG_ENTRY, 0, 2);
-	return BigEndianData((uint16_t)2);
+	return BigEndianData(entry_num);
 }
 
 } // namespace Barry
diff --git a/src/packet.h b/src/packet.h
index 2cff3e0..4725f12 100644
--- a/src/packet.h
+++ b/src/packet.h
@@ -225,7 +225,8 @@ public:
 	int GetDirEntry(uint8_t entry_cmd, uint16_t id);
 	int Erase(uint16_t cmd, uint16_t id);
 	int GetEventlog()	{ return SimpleCmd(SB_COMMAND_JL_GET_LOG); }
-	int GetEventlogEntry();
+	int GetEventlogEntry(uint16_t entry_num);
+	int ClearEventlog()	{ return SimpleCmd(SB_COMMAND_JL_CLEAR_LOG); }
 
 	//////////////////////////////////
 	// response analysis
diff --git a/src/protocol.h b/src/protocol.h
index c6bc11d..57f4d97 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -61,6 +61,7 @@
 #define SB_COMMAND_JL_UNKNOWN3		0x63
 #define SB_COMMAND_JL_GET_LOG		0x73
 #define SB_COMMAND_JL_GET_LOG_ENTRY	0x74
+#define SB_COMMAND_JL_CLEAR_LOG		0x88
 
 // JavaLoader response
 #define SB_COMMAND_JL_ACK		0x64
diff --git a/src/protostructs.h b/src/protostructs.h
index 9164dac..7a5c25e 100644
--- a/src/protostructs.h
+++ b/src/protostructs.h
@@ -579,6 +579,14 @@ struct JLScreenInfo
 } __attribute__ ((packed));
 #define SB_JLSCREENINFO_SIZE			(sizeof(Barry::Protocol::JLScreenInfo))
 
+struct JLEventlogEntry
+{
+	uint16_t	size;
+	// remainder of packet is variable
+	// it contains the log data as an ASCII (UTF-8?) string
+} __attribute__ ((packed));
+#define SB_JLEVENTLOG_ENTRY_SIZE		(sizeof(Barry::Protocol::JLEventlogEntry))
+
 struct JLPacket
 {
 	uint16_t	socket;
@@ -589,6 +597,7 @@ struct JLPacket
 		JLCommand		command;
 		JLResponse		response;
 		JLScreenInfo		screeninfo;
+		JLEventlogEntry		logentry;
 		uint8_t			raw[1];
 		char			filename[1];
 		uint32_t		cod_size;
diff --git a/tools/bjavaloader.cc b/tools/bjavaloader.cc
index cb7a0b6..df6f232 100644
--- a/tools/bjavaloader.cc
+++ b/tools/bjavaloader.cc
@@ -38,6 +38,7 @@
 #define CMD_SCREENSHOT	"screenshot"
 #define CMD_SETTIME	"settime"
 #define CMD_EVENTLOG    "eventlog"
+#define CMD_CLEAR_LOG   "cleareventlog"
 
 // time string format specifier and user friendly description
 #define TIME_FMT         "%Y-%m-%d %H:%M:%S"
@@ -76,6 +77,12 @@ void Usage()
    << "   " << CMD_ERASE << " [-f] <module name> ...\n"
    << "      Erase module from handheld\n"
    << "\n"
+   << "   " << CMD_EVENTLOG << "\n"
+   << "      Retrives the handheld event log\n"
+   << "\n"
+   << "   " << CMD_CLEAR_LOG << "\n"
+   << "      Clears the handheld event log\n"
+   << "\n"
    << "   " << CMD_SCREENSHOT << " <.bmp file> ...\n"
    << "      Make a screenshot of handheld\n"
    << "\n"
@@ -305,7 +312,12 @@ int main(int argc, char *argv[])
 			}
 		}
 		else if( cmd == CMD_EVENTLOG ) {
-			javaloader.GetEventlog();
+			JLEventlog log;
+			javaloader.GetEventlog(log);
+			cout << log;
+		}
+		else if( cmd == CMD_CLEAR_LOG ) {
+			javaloader.ClearEventlog();
 		}
 		else {
 			cerr << "invalid command \"" << cmd << "\"" << endl;
-- 
1.6.1.1

