Index: Evidence/Evidence.cc
===================================================================
--- Evidence/Evidence.cc	(revision 154)
+++ Evidence/Evidence.cc	(revision 159)
@@ -25,4 +25,10 @@
 #include "Evidence.h"
 
+using namespace std;
+
+//////////////////////////
+// EvidenceServer Class //
+//////////////////////////
+
 EvidenceServer *ThisServer;
 
@@ -50,5 +56,4 @@
   start(Name);
   addExitHandler(this);
-
 }
 
@@ -56,4 +61,6 @@
 EvidenceServer::~EvidenceServer() {
 
+  State(INFO, "Server stopped");
+  
   for (unsigned int i=0; i<ConfigList.size(); i++) {
   	delete[] ConfigList[i].Name;
@@ -64,5 +71,5 @@
 // DIM exit handler
 void EvidenceServer::exitHandler(int Code) {
-  State(INFO, "Server stopped (DIM exit code %d)", Code);
+  State(INFO, "Exit handler called (DIM exit code %d)", Code);
   exit(EXIT_SUCCESS);
 }
@@ -104,5 +111,5 @@
   // Send message to console and log file
   printf("%s\n", TBuf);
-  if (Severity != INFO) DimClient::sendCommand("DColl/Log", TBuf);
+  DimClient::sendCommandNB("DColl/Log", TBuf);
 
   // Update DIM status service (including severity encoding)
@@ -188,25 +195,104 @@
 
 // Translates DIMInfo to string (memory has to be freed by caller)
-// No DIM structures are supported (only a single number or string is converted)
+// DIM structures are converted to hexadecimal representation
 // For string conversion, a terminating \0 is enforced.
 char *EvidenceServer::ToString(DimInfo *Item) {
 
   char *Text;
-  int R;
-  
-  if (strlen(Item->getFormat()) != 1) return NULL;
-  
-  switch (*(Item->getFormat())) {
-    case 'I':  R = asprintf(&Text, "%d", Item->getInt());   break;
-    case 'S':  R = asprintf(&Text, "%hd", Item->getShort());   break;
-    case 'F':  R = asprintf(&Text, "%.5f", Item->getFloat());   break;
-    case 'D':  R = asprintf(&Text, "%.5f", Item->getDouble());   break;
-    case 'X':  R = asprintf(&Text, "%lld", Item->getLonglong());   break;
-    case 'C':  *(Item->getString() + Item->getSize()) = '\0'; 
-			   R = asprintf(&Text, "%s", Item->getString());
-			   break;
-    default: return NULL;
-  }
-
+  int R=0;
+  
+  if (strlen(Item->getFormat()) != 1) {
+    if ((Text = (char *) malloc(3*Item->getSize()+1)) != NULL) {
+	  for (int i=0; i<Item->getSize(); i++) sprintf(Text+3*i, "%02x", *((char *) Item->getData() + i)); 
+	}
+  }
+  else {
+	switch (*(Item->getFormat())) {
+      case 'I':  R = asprintf(&Text, "%d", Item->getInt());   break;
+      case 'S':  R = asprintf(&Text, "%hd", Item->getShort());   break;
+      case 'F':  R = asprintf(&Text, "%.5f", Item->getFloat());   break;
+      case 'D':  R = asprintf(&Text, "%.5f", Item->getDouble());   break;
+      case 'X':  R = asprintf(&Text, "%lld", Item->getLonglong());   break;
+      case 'C':  *(Item->getString() + Item->getSize() - 1) = '\0'; 
+				 R = asprintf(&Text, "%s", Item->getString());
+				 break;
+      default: return NULL;
+	}
+  }
+  
   return (R == -1) ? NULL : Text;
 }
+
+// Checks if service contents indicates not available
+bool EvidenceServer::ServiceOK(DimInfo *Item) {
+
+  return !((Item->getSize() == strlen(NO_LINK)+1) &&  
+	  (memcmp(Item->getData(), NO_LINK, Item->getSize()) == 0));
+
+}
+
+
+///////////////////////////
+// EvidenceHistory Class //
+///////////////////////////
+
+// Organisaztion of history buffer
+// F | T S D | T S D | 0 0 ......  | T S D | T S D | 0 -1
+//
+// F: Offset of oldest entry  T: Time  S: Size  D: Data
+// F, T, S: int
+
+// Marker for history buffer
+const int EvidenceHistory::WrapMark[] = {0, -1};
+const int EvidenceHistory::EndMark[] = {0, 0};
+
+// Constructor
+EvidenceHistory::EvidenceHistory() {
+
+  Buffer = NULL;
+}
+
+// Destructor
+EvidenceHistory::~EvidenceHistory() {
+
+  delete[] Buffer;
+}
+
+// Requests service history
+bool EvidenceHistory::GetHistory(char *Name) {
+
+  DimCurrentInfo Info((string(Name)+".hist").c_str(), NO_LINK);
+
+  // Check if service available
+  if (((Info.getSize() == strlen(NO_LINK)+1) &&  
+	  (memcmp(Info.getData(), NO_LINK, Info.getSize()) == 0))) return false;
+
+  delete[] Buffer;
+  BufferSize = Info.getSize();
+  Buffer = new char [BufferSize];
+
+  memcpy(Buffer, Info.getData(), BufferSize);
+  Offset = *(int *) Buffer;
+  
+  return true;
+}
+
+// Returns next item in history buffer
+bool EvidenceHistory::Next(int &Time, int &Size, void *&Data) {
+
+  if (Buffer == NULL) return false;
+
+  // Check for wrap around
+  if (memcmp(Buffer+Offset, WrapMark, sizeof(WrapMark)) == 0) Offset = 4;
+  
+  // Check if at end of ring buffer
+  if (memcmp(Buffer+Offset, EndMark, sizeof(EndMark)) == 0) return false;
+
+  Time = *(int *) (Buffer + Offset);
+  Size = *(int *) (Buffer + Offset + sizeof(int));
+  Data = Buffer + Offset + 2*sizeof(int);
+
+  Offset += *((int *) (Buffer + Offset) + 1) + 2*sizeof(int);
+
+  return true;
+}
