Index: fact/FADctrl/FAD.cc
===================================================================
--- fact/FADctrl/FAD.cc	(revision 10153)
+++ fact/FADctrl/FAD.cc	(revision 10164)
@@ -1,10 +1,10 @@
 /********************************************************************\
 
-  FAD.cc
-
   Main class of FADCtrl
 
-
- Comment 19/10/2010: It is assumed that boolean access is an atomic operation.
+  If outputting text with PrintMessage(), a '\r' is used on the console automatically
+  if the given text ends with '\n'.
+  
+  Comment 19/10/2010: It is assumed that boolean access is an atomic operation.
      
 \********************************************************************/
@@ -20,5 +20,5 @@
 			  const char *Help;
   } CommandList[] = 
-  {{"board", &FAD::cmd_board, true, 1, "[+|-]<range>" ,"Activate or deactivate boards"},
+  {{"board", &FAD::cmd_board, true, 1, "[+|-]<range>" ,"Activate or deactivate board(s)"},
    {"status", &FAD::cmd_status, false, 0, "[range]", "Show board status information"},
    {"domino", &FAD::cmd_domino, true, 1, "<on|off>", "Switch Domino wave"},
@@ -40,7 +40,7 @@
    {"update", &FAD::cmd_update, false, 1, "<sec>", "Minimum delay between updates to DIM event service"},		  
    {"socketmode", &FAD::cmd_socketmode, true, 1, "<com|daq>", "Choose which Sockets are used for data transmission"},		  
-   {"exit", &FAD::cmd_exit, true, 0, "", "Exit program"},
+   {"reconnect", &FAD::cmd_reconnect, true, 1, "<board range> [init]", "Reconnect to boards (and re-initialise)"},		  
+   {"exit", &FAD::cmd_exit, false, 0, "", "Exit program"},
    {"help", &FAD::cmd_help, false, 0, "", "Print help"}};
-
 
 
@@ -61,6 +61,5 @@
   EventUpdateDelay = atof(GetConfig("EventUpdateDelay", "0.5").c_str());
 
-  // Create pipe for command execution and data exchange
-  if (pipe(CommandPipe) == -1) Message(FATAL, "pipe() failed in FAD::FAD() (%s)", strerror(errno));
+  // Create pipe for data exchange
   if (pipe(Pipe) == -1) Message(FATAL, "pipe() failed in FAD::FAD() (%s)", strerror(errno));
 
@@ -75,12 +74,5 @@
 
   for (unsigned int i=0; i<BoardList.size(); i++) {
-    Boards.push_back(new class FADBoard(BoardList[i], 5000, this, i));
-
-	// Check if initialised OK
-	if (!Boards.back()->InitOK) {
-	  Message(WARN, "Failed to initialize board %s", BoardList[i].c_str());
-	  delete Boards.back();
-	  Boards.pop_back();
-	}
+    Boards.push_back(new class FADBoard(BoardList[i], PORT, this, i));
   }
 
@@ -91,9 +83,13 @@
   }
 
-  // Create command handling thread
-  DimThread::start();
-
   // Install DIM command (after all initialized)
   Command = new DimCommand((char *) SERVER_NAME"/Command", (char *) "C", this);
+  
+  // Initialise boards
+  vector<string> Init = Tokenize(GetConfig("InitSequence", ""), ";");
+
+  for (unsigned int i=0; i<Init.size(); i++) {
+	DimClient::sendCommand(SERVER_NAME"/Command", Init[i].c_str());
+  }
 }
 
@@ -108,8 +104,6 @@
   if (close(Pipe[0]) == -1) Message(ERROR, "close() on Pipe[0] failed in FAD::~FAD() (%s)", strerror(errno));
   if (close(Pipe[1]) == -1) Message(ERROR, "close() on Pipe[1] failed in FAD::~FAD() (%s)", strerror(errno));
-  if (close(CommandPipe[0]) == -1) Message(ERROR, "close() on CommandPipe[0] failed in FAD::~FAD() (%s)", strerror(errno));
-  if (close(CommandPipe[1]) == -1) Message(ERROR, "close() on CommandPipe[1] failed in FAD::~FAD() (%s)", strerror(errno));
-
-  // Wait for command and DIM service thread to quit
+
+  // Wait for DIM service thread to quit
   if ((Ret = pthread_join(Thread, NULL)) != 0) Message(ERROR, "pthread_join() failed in ~FAD() (%s)", strerror(Ret));
 
@@ -131,88 +125,54 @@
 void FAD::commandHandler() {
 
+  char *Command = getCommand()->getString(), *Start;
+
   // Ignore empty or illegal strings
-  if (getCommand()->getSize() == 0 || *(getCommand()->getString()+getCommand()->getSize()-1) != '\0' ||
-	  strlen(getCommand()->getString()) == 0) return;
-
-  // Send command to command execution thread
-  if (write(CommandPipe[1], getCommand()->getData(), getCommand()->getSize()) == -1) {
-	Message(ERROR, "write() to CommandPipe[1] failed in class FAD::commandHandler() (%s)", strerror(errno));
-  }
-}
-
-//
-// Command execution thread
-//
-void FAD::threadHandler() {
-
-  char *Command, *Start, Buffer[1000];
-  int Ret;
-  unsigned int n;
-
-  while (!ExitRequest) {
-	if ((Ret=read(CommandPipe[0], Buffer, sizeof(Buffer))) == -1) Message(ERROR, "read() from CommandPipe[0] failed in FAD::threadHandler() (%s)", strerror(errno));
-
-	// Check if pipe closed
-	if (Ret == 0) break;
-
-	// Shell command
-	if (Buffer[0]=='.') {
-      system(&(Buffer[1]));
-      continue;
-	}
-
-	// Parse command into tokens
-	Parameter.clear();
-	Command = Buffer;
-	while(true) {
-      while (isspace(*Command)) Command++; // Ignore initial white spaces
-      if(*Command=='\0') break;
-      if (*Command == '\"') {
-		Start = ++Command;
-    	while(*Command!='\"' && *Command!='\0') Command++;
-      }
-      else {
-		Start = Command;
-    	while(!isspace(*Command) && *Command!='\0') Command++;
-      }
-      if(*Command != '\0') *Command++ = '\0';
-	  Parameter.push_back(Start);
-	}
-
-	// Search for command in command list
-	for(n=0; n<sizeof(CommandList)/sizeof(CL_Struct); n++) {
-      if (Match(Parameter[0], CommandList[n].Name)) break;
-	}
-
-	// Command not found?	
-	if (n == sizeof(CommandList)/sizeof(CL_Struct)) {
-	  PrintMessage("Unknown command '%s'\n", Parameter[0].c_str());
-	  continue;
-	}
-
-	// Check if number of parameters
-    if(Parameter.size()-1 < CommandList[n].MinNumParameter) {
-	  PrintMessage("Usage: %s %s\n", CommandList[n].Name, CommandList[n].Parameters);
-	  continue;
-	}
-
-	// Check if idle mode required
-	if (CommandList[n].NeedIdle && Mode != idle) {
-	  PrintMessage("Current mode is not idle ('stop' will stop current operation)\n");
-	  continue;
-	}
-	
-	// Jump to command function
-	(this->*CommandList[n].CommandPointer)();
-  } // while()
-}
-
-//
-// DIM exit handler (overwriting handler in Evidence class)
-//
-void FAD::exitHandler(int Code) {
-
-  Message(INFO, "Exit handler called (DIM exit code %d)", Code);
-  pthread_kill(MainThread, SIGTERM);
+  if (getCommand()->getSize() == 0) return;
+  if( *(Command+getCommand()->getSize()-1) != '\0' || strlen(Command) == 0) return;
+
+  // Shell command
+  if (*Command == '.') {
+    system(Command+1);
+    return;
+  }
+
+  // Parse command into tokens
+  Parameter.clear();
+  while(true) {
+    while (isspace(*Command)) Command++; // Ignore initial white spaces
+    if(*Command=='\0') break;
+    if (*Command == '\"') {
+	  Start = ++Command;
+      while(*Command!='\"' && *Command!='\0') Command++;
+    }
+    else {
+	  Start = Command;
+      while(!isspace(*Command) && *Command!='\0') Command++;
+    }
+    if(*Command != '\0') *Command++ = '\0';
+	Parameter.push_back(Start);
+  }
+
+  // Search for command in command list
+  for(unsigned int n=0; n<sizeof(CommandList)/sizeof(CL_Struct); n++) {
+    if (Match(Parameter[0], CommandList[n].Name)) {
+	  // Check if number of parameters
+	  if(Parameter.size()-1 < CommandList[n].MinNumParameter) {
+		PrintMessage("Usage: %s %s\n", CommandList[n].Name, CommandList[n].Parameters);
+		return;
+	  }
+	  // Check if idle mode required
+	  if (CommandList[n].NeedIdle && Mode != idle) {
+		PrintMessage("Current mode is not idle ('stop' will stop current operation)\n");
+		return;
+	  }
+	  // Jump to command function
+	  (this->*CommandList[n].CommandPointer)();
+	  return;
+	}
+  }
+
+  // Command not found	
+  PrintMessage("Unknown command '%s'\n", Parameter[0].c_str());
 }
 
@@ -225,9 +185,9 @@
 	if (Match(Parameter[1],"on")) Boards[i]->Send(CMD_SRCLK_ON);
 	else if (Match(Parameter[1],"off")) Boards[i]->Send(CMD_SRCLK_OFF);
-  }
-
-  if (Match(Parameter[1],"on")) PrintMessage("SRCLK switched on for all active boards\n");
-  else if (Match(Parameter[1],"off")) PrintMessage("SRCLK switched off for all active boards\n");
-  else PrintUsage();
+	else {
+	  PrintUsage();
+	  return;
+	}
+  }
 } 
 
@@ -244,9 +204,9 @@
 	if (Match(Parameter[1],"com")) Boards[i]->Send(CMD_Stop);
 	else if (Match(Parameter[1],"daq")) Boards[i]->Send(CMD_Start);
-  }
-
-  if (Match(Parameter[1],"com")) PrintMessage("All active boards switched to command mode - socket 0\n");
-  else if (Match(Parameter[1],"daq")) PrintMessage("All active boards switched to DAQ mode - socket 1..7\n");
-  else PrintUsage();
+	else {
+	  PrintUsage();
+	  return;
+	}
+  }
 } 
 
@@ -259,9 +219,9 @@
 	if (Match(Parameter[1],"on")) Boards[i]->Send(CMD_SCLK_ON);
 	else if (Match(Parameter[1],"off")) Boards[i]->Send(CMD_SCLK_OFF);
-  }
-
-  if (Match(Parameter[1],"on")) PrintMessage("SCLK switched on for all active boards\n");
-  else if (Match(Parameter[1],"off")) PrintMessage("SCLK switched off for all active boards\n");
-  else PrintUsage();
+	else {
+	  PrintUsage();
+	  return;
+	}
+  }
 } 
 
@@ -274,9 +234,9 @@
 	if (Match(Parameter[1],"on")) Boards[i]->Send(CMD_DENABLE);
 	else if (Match(Parameter[1],"off")) Boards[i]->Send(CMD_DDISABLE);
-  }
-  
-  if (Match(Parameter[1],"on")) PrintMessage("Domino wave switched on for all active boards\n");
-  else if (Match(Parameter[1],"off")) PrintMessage("Domino wave switched off for all active boards\n");
-  else PrintUsage();
+	else {
+	  PrintUsage();
+	  return;
+	}
+  }
 } 
 
@@ -289,9 +249,9 @@
 	if (Match(Parameter[1],"on")) Boards[i]->Send(CMD_DWRITE_RUN);
 	else if (Match(Parameter[1],"off")) Boards[i]->Send(CMD_DWRITE_STOP);
-  }
-
-  if (Match(Parameter[1],"on")) PrintMessage("DWRITE set high for all active boards\n");
-  else if (Match(Parameter[1],"off")) PrintMessage("DWRITE set low for all active boards\n");
-  else PrintUsage();
+	else {
+	  PrintUsage();
+	  return;
+	}
+  }
 } 
 
@@ -544,5 +504,4 @@
 
   // Read calibration data from file?
-  //if (Parameter.size() == 2 && !ConvertToInt(Parameter[1], &NumCalibEvents)) {
   if (Parameter.size() == 2 && !ConvertToInt(Parameter[1], &NumEventsRequested)) {
     // Open file
@@ -618,14 +577,14 @@
 	for (unsigned int i=0; i<Boards.size(); i++) {
 	  if (Boards[i]->Active) Count++;
-	  if (Boards[i]->CommError) Error++;
+	  if (!Boards[i]->CommOK) Error++;
 	}	  
 
-	PrintMessage("Total boards: %d    (%d communication errors)     Active boards: ", Boards.size(), Error);
+	PrintMessage("\rTotal boards: %d    (%d communication errors)     Active boards: %d\n", Boards.size(), Error, Count);
 
 	// Print list of active boards
-	if (Count == 0) PrintMessage("none\n");
-	else if (Count == Boards.size()) PrintMessage("all\n");
-	else for (unsigned int i=0; i<Boards.size(); i++) {
-	  if (Boards[i]->Active) PrintMessage(" %d", i);
+	if (Count != 0) {
+	  PrintMessage("Active are ");
+	  for (unsigned int i=0; i<Boards.size(); i++) if (Boards[i]->Active) PrintMessage(" %d", i);
+	  PrintMessage("\n");
 	}
 
@@ -649,5 +608,5 @@
 	if (i<R.Min || i > R.Max) continue;
 
-	PrintMessage("BOARD #%d (%sactive)   IP %s   Communication %s\n", i, Boards[i]->Active ? "":"in", Boards[i]->Name, Boards[i]->CommError ? "ERROR":"OK");
+	PrintMessage("BOARD #%d (%sactive)   IP %s   Communication %s\n", i, Boards[i]->Active ? "":"in", Boards[i]->Name, Boards[i]->CommOK ? "OK":"ERROR");
 
 	// Calibration information
@@ -688,5 +647,4 @@
 }
 
-
 //
 // Adress FAD boards
@@ -721,4 +679,39 @@
 
 //
+// Reconnect to boards
+//
+void FAD::cmd_reconnect() {
+
+  struct Range R = {0, Boards.size()};
+
+  // Check ranges  
+  if (!ConvertToRange(Parameter[1], R)) {
+	PrintMessage("Error, board number(s) out of range\n");
+	return;
+  }
+  PrintMessage("Note: Currently not protection against concurrent access in EventThread\n");
+  
+  // Reinstantiate boards
+  for (int i=0; i<(int) Boards.size(); i++) if (i >= R.Min && i <= R.Max) {
+	if (pthread_kill(Boards[i]->Thread, 0) != ESRCH) {
+	  PrintMessage("Event thread of board %d still running, cannot reconnect\n", i);
+	  continue;
+	}
+
+	delete Boards[i];
+    Boards[i] = new class FADBoard(BoardList[i], PORT, this, i);
+  }
+  
+  // Initialise boards if requested (use sendCommandNB() to avoid dead lock) 
+  if (Parameter.size() != 3 || !Match(Parameter[2], "init")) return;
+   
+  vector<string> Init = Tokenize(GetConfig("InitSequence"), ";");
+
+  for (unsigned int i=0; i<Init.size(); i++) {
+	DimClient::sendCommandNB(SERVER_NAME"/Command", (char *) Init[i].c_str());
+  }
+} 
+
+//
 // Set DIM event update delay
 //
@@ -749,5 +742,5 @@
 	free(Buffer);
   }
-  PrintMessage(".<command>                  Execute shell command\n\n"
+  PrintMessage(".<command>               Execute shell command\n\n"
    "Items in <> are mandatory, in [] optional, | indicates mutual exclusive.\n"
    "Strings containing spaces have to be enclosed in \"double quotes\".\n"
@@ -756,5 +749,5 @@
 
 //
-// Cancel current operation
+// Stop current operation
 //
 void FAD::cmd_stop() {
@@ -784,7 +777,10 @@
 //
 // Exit programm
-// SIGTERM sets ExitRequest flag, and also makes readline() return (if command from DimCommand thread)
+// SIGTERM sets ExitRequest flag, and also makes
+// readline() return (in case command came over network)
 //
 void FAD::cmd_exit() {
+
+  if (Mode != idle) cmd_stop();
 
   pthread_kill(MainThread, SIGTERM);
@@ -795,4 +791,13 @@
 // *****  Other functions  *****
 // -----------------------------
+
+//
+// DIM exit handler (overwriting handler in Evidence class)
+//
+void FAD::exitHandler(int Code) {
+
+  Message(INFO, "Exit handler called (DIM exit code %d)", Code);
+  cmd_exit();
+}
 
 //
@@ -810,5 +815,5 @@
   // Generate filename
   TimeInfo = localtime(&Time);
-  if (strftime(Buffer, sizeof(Buffer), "/FADcalib_%y-%m-%jT%X.txt", TimeInfo) == 0) {
+  if (strftime(Buffer, sizeof(Buffer), "/FADcalib_%y-%m-%dT%X.txt", TimeInfo) == 0) {
 	PrintMessage("Could not generate calibration data file name, strftime() failed\n");
 	return;
@@ -917,5 +922,5 @@
 	  for (unsigned int i=0; i<Boards.size(); i++) {
 		if (IDString.find(string("ACALIBDONE")+Boards[i]->Name) != string::npos) AcalibDone[i] = true;
-		if (!AcalibDone[i]) Done = false;
+		if (!AcalibDone[i] && Boards[i]->Active && Boards[i]->CommOK) Done = false;
 	  }
 	  // Amplitude calibration finished?
@@ -1129,8 +1134,11 @@
   va_end(ArgumentPointer);
   
+  if (strlen(Text) == 0) return;
+  
   // Print to console
+  if (Text[strlen(Text)-1] == '\n') printf("\r");		// Overwrite prompt
   printf("%s", Text);
   fflush(stdout);
-  if (strlen(Text)>0 && Text[strlen(Text)-1]=='\n') rl_on_new_line(); // New prompt
+  if (Text[strlen(Text)-1]=='\n') rl_on_new_line();		// New prompt
 
   // Send to DIM text service
Index: fact/FADctrl/FAD.h
===================================================================
--- fact/FADctrl/FAD.h	(revision 10153)
+++ fact/FADctrl/FAD.h	(revision 10164)
@@ -21,9 +21,10 @@
 #include "FADBoard.h"
 
+const unsigned int PORT = 5000;
 const int DEFAULT_NUM_CALIB_EVENTS = 100;
 const char CALIB_DIRECTORY[] = "~/";
 
 
-class FAD: public EvidenceServer, public DimThread {
+class FAD: public EvidenceServer {
 
   public:
@@ -39,5 +40,4 @@
     void PrintUsage();
 	void commandHandler();
-	void threadHandler();
 	virtual void exitHandler(int);
 	bool Match(std::string, const char *);
@@ -77,5 +77,5 @@
 	void cmd_phase();		void cmd_send();
 	void cmd_stop();		void cmd_update();
-	void cmd_take();
+	void cmd_take();		void cmd_reconnect();
 
     void EnableDomino();
@@ -89,5 +89,4 @@
 	
 	int Pipe[2];
-	int CommandPipe[2];
     int NumEventsRequested;	// Number of events requested
 	std::vector<std::string> BoardList;
Index: fact/FADctrl/FADBoard.cc
===================================================================
--- fact/FADctrl/FADBoard.cc	(revision 10153)
+++ fact/FADctrl/FADBoard.cc	(revision 10164)
@@ -11,5 +11,5 @@
 // Constructor
 // 
-FADBoard::FADBoard(string Server, unsigned short Port, class FAD *Parent, unsigned int Num) {
+FADBoard::FADBoard(string Server, unsigned short ServerPort, class FAD *Parent, unsigned int Num) {
 
   int Ret;
@@ -17,10 +17,10 @@
   // Initialization
   m = Parent;
-  InitOK = false;
   Active = true;
   Continue = true;
-  CommError = false;
+  CommOK = false;
   ACalibTime = -1;
   Status.Update.tv_sec = -1;
+  Port = ServerPort;
 
   Name = new char [Server.size()+1]; // Name in permanent memory for DIM service
@@ -42,28 +42,4 @@
   }
 
-  // Resolve hostname
-  struct hostent *Host = gethostbyname(Server.c_str());
-  if (Host == 0) {
-    m->PrintMessage("Could not resolve host name for %s\n", Server.c_str());
-    return;
-  }
-
-  // Open socket descriptor
-  if ((Socket = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
-    m->Message(m->ERROR, "Could not open socket for %s (%s)\n", Server.c_str(), strerror(errno));
-    return;
-  }
-    
-  // Connect to server
-  struct sockaddr_in SocketAddress;
-  SocketAddress.sin_family = PF_INET;
-  SocketAddress.sin_port = htons(Port);
-  SocketAddress.sin_addr = *(struct in_addr*) Host->h_addr;
-  
-  if (connect(Socket, (struct sockaddr *) &SocketAddress, sizeof(SocketAddress)) == -1) {
-    m->PrintMessage("Could not connect to %s at port %d (%s)\n", Server.c_str(), Port, strerror(errno));
-    return;
-  }
-  
   // Construct DIM service name prefix
   stringstream ID;
@@ -76,15 +52,11 @@
   DIM_ROI = new DimService((ID.str()+"ROI").c_str(), (char *) "S", NULL, 0);
 
-  // Create thread that receives data
+  // Create thread that connects and receives data
   if ((Ret = pthread_create(&Thread, NULL, (void * (*)(void *)) LaunchThread,(void *) this)) != 0) {
     m->Message(m->FATAL, "pthread_create() failed in FADBoard() (%s)", strerror(Ret));
   }
 
-  // Create thread to connect to other sockets
-  if ((Ret = pthread_create(&OtherThread, NULL, (void * (*)(void *)) OpenOtherSockets, (void *) Name)) != 0) {
-    m->Message(m->FATAL, "pthread_create() failed for OpenOtherSockets (%s)", strerror(Ret));
-  }
-
-  InitOK = true;
+  // Start thread to connect to other sockets
+  DimThread::start();
 }
 
@@ -96,35 +68,18 @@
   int Ret;
 
-  // Avoid segmentation faults by chekcing for InitOK
-  if (InitOK) {
-	// Terminate thread for other sockets  
-	if ((Ret = pthread_cancel(OtherThread)) != 0) {
-	  m->Message(m->ERROR, "pthread_cancel() failed in ~FADBoard() for OtherThread (%s)", strerror(Ret));
-	}
-	if ((Ret = pthread_join(OtherThread, NULL)) != 0) {
-	  m->Message(m->ERROR, "pthread_join() failed in ~FADBoard for OtherThread (%s)", strerror(Ret));
-	}
-
-	// Cancel thread (if it did not quit already) and wait for it to quit
-	if ((Ret = pthread_cancel(Thread)) != 0 && Ret != ESRCH) {
-	  m->Message(m->ERROR, "pthread_cancel() failed in ~FADBoard() (%s)", strerror(Ret));
-	}
-	if ((Ret = pthread_join(Thread, NULL)) != 0) {
-	  m->Message(m->ERROR, "pthread_join() failed in ~FADBoard (%s)", strerror(Ret));
-	}
-
-	delete DIM_Name;
-	delete DIM_ID;
-	delete DIM_Temp;
-	delete DIM_DAC;
-	delete DIM_ROI;
-  }
-  
+  // Cancel thread (if it did not quit already) and wait for it to quit
+  if ((Ret = pthread_cancel(Thread)) != 0 && Ret != ESRCH) {
+	m->Message(m->ERROR, "pthread_cancel() failed in ~FADBoard() (%s)", strerror(Ret));
+  }
+  if ((Ret = pthread_join(Thread, NULL)) != 0) {
+	m->Message(m->ERROR, "pthread_join() failed in ~FADBoard (%s)", strerror(Ret));
+  }
+
+  delete DIM_Name;
+  delete DIM_ID;
+  delete DIM_Temp;
+  delete DIM_DAC;
+  delete DIM_ROI;  
   delete[] Name;
-
-  // Close socket descriptor
-  if ((Socket != -1) && (close(Socket) == -1)) {
-	m->PrintMessage("Could not close socket descriptor (%s)", strerror(errno));  
-  }
 
   // Delete condition variable 
@@ -145,6 +100,6 @@
 void FADBoard::Send(const void *Data, size_t Bytes) {
 
-  // Do not send if not active
-  if (!Active) return;
+  // Do not send if not active or communication problem
+  if (!Active || !CommOK) return;
 
   // Write data
@@ -357,5 +312,5 @@
   
 //
-// Read data from board
+// Connect to board and read data
 //
 void FADBoard::ReadLoop() {
@@ -365,10 +320,34 @@
   const PEVNT_HEADER *Header = (PEVNT_HEADER *) Buffer;
   ssize_t Result;
+  struct sockaddr_in SocketAddress;
   struct BoardStatus PrevStatus;
   int Ret;
 
+  // Resolve hostname
+  struct hostent *Host = gethostbyname(Name);
+  if (Host == 0) {
+    m->Message(m->WARN, "Could not resolve host name for %s", Name);
+    return;
+  }
+
+  SocketAddress.sin_family = PF_INET;
+  SocketAddress.sin_port = htons(Port);
+  SocketAddress.sin_addr = *(struct in_addr*) Host->h_addr;
+
+  // Open socket descriptor
+  if ((Socket = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
+    m->Message(m->ERROR, "Could not open socket for %s (%s)\n", Name, strerror(errno));
+    return;
+  }
+    
+  // Connect to server
+  if (connect(Socket, (struct sockaddr *) &SocketAddress, sizeof(SocketAddress)) == -1) {
+    m->PrintMessage("Could not connect to %s at port %d (%s)\n", Name, Port, strerror(errno));
+  }
+  else CommOK = true;
   memset(&PrevStatus, 0, sizeof(PrevStatus));
 
-  while (!m->ExitRequest) {
+  // Leave loop if program termination requested or board communication not OK
+  while (!m->ExitRequest && CommOK) {
     // Read data from socket
     Result = read(Socket, Buffer + Pos, sizeof(Buffer)-Pos);
@@ -377,10 +356,10 @@
 	if (Result == -1) {
 	  m->PrintMessage("Error: Could not read from socket, exiting read loop (%s)\n", strerror(errno));
-	  CommError = true;
+	  CommOK = false;
 	  break;
 	}
 	else if (Result == 0) {
 	  m->PrintMessage("Server not existing anymore, exiting read loop\n");
-	  CommError = true;
+	  CommOK = false;
 	  break;
 	}
@@ -490,5 +469,5 @@
 	  }  
 	}
-	else printf("End package flag incorrect, removing corrupt event\n");
+	else m->PrintMessage("End package flag incorrect, removing corrupt event\n");
 
 	// Inform event thread of new data
@@ -503,4 +482,10 @@
 	Pos = Pos-Length;	
   } // while()
+  
+  // Close socket descriptor
+  if (close(Socket) == -1) {
+	m->PrintMessage("Could not close socket descriptor for board %s (%s)", Name, strerror(errno));  
+  }
+
 }
 
@@ -538,17 +523,17 @@
 
 //
-// OpenOtherSockets()
-//
-void FADBoard::OpenOtherSockets(char *Hostname) {
+// Open other sockets
+//
+void FADBoard::threadHandler() {
 
   int List[] = {5001, 5002, 5003, 5004, 5005, 5006, 5007};
-  int Socket[sizeof(List)/sizeof(int)], MaxSocketNum=0, Ret;
+  int Socket[sizeof(List)/sizeof(int)], MaxSocketNum, Ret;
   fd_set DescriptorList;
   char Buffer[1000000];
-
+  
   // Resolve hostname
-  struct hostent *Host = gethostbyname(Hostname);
+  struct hostent *Host = gethostbyname(Name);
   if (Host == 0) {
-    printf("OtherSockets: Could not resolve host name for %s\n", Hostname);
+    m->PrintMessage("OtherSockets: Could not resolve host name for %s\n", Name);
     return;
   }
@@ -562,15 +547,13 @@
 	// Open socket descriptor
 	if ((Socket[i] = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
-      printf("OtherSockets: Could not open socket for port %d (%s)\n", List[i], strerror(errno));
+      m->PrintMessage("OtherSockets: Could not open socket for port %d (%s)\n", List[i], strerror(errno));
       return;
 	}
-
-	// Determine highest socket number for select()
-	if (Socket[i] > MaxSocketNum) MaxSocketNum = Socket[i];
+	MaxSocketNum = *max_element(Socket, Socket+sizeof(List)/sizeof(int));
 	 
 	// Connect to server
     SocketAddress.sin_port = htons((unsigned short) List[i]);
 	if (connect(Socket[i], (struct sockaddr *) &SocketAddress, sizeof(SocketAddress)) == -1) {
-      printf("OtherSockets: Could not connect to port %d (%s)\n", List[i], strerror(errno));
+      m->PrintMessage("OtherSockets: Could not connect to port %d (%s)\n", List[i], strerror(errno));
       return;
 	}
@@ -578,9 +561,9 @@
   
   while(true) {
-    // Wait for data from terminal (stdin) or from sockets
+    // Wait for data from sockets
     FD_ZERO(&DescriptorList);   
     for (unsigned int i=0; i<sizeof(List)/sizeof(int); i++) FD_SET(Socket[i], &DescriptorList);
     if (select(MaxSocketNum+1, &DescriptorList, NULL, NULL, NULL) == -1) {
-      perror("OtherSockets: Error with select()");
+      m->PrintMessage("OtherSockets: Error with select() (%s)\n", strerror(errno));
       break;
     }
@@ -589,7 +572,6 @@
 	for (unsigned int i=0; i<sizeof(List)/sizeof(int); i++) if (FD_ISSET(Socket[i], &DescriptorList)) {
 	  Ret = read(Socket[i], Buffer, sizeof(Buffer));
-      if(Ret == 0) printf("OtherSockets: Connection to port %d not existing anymore\n", List[i]);
-      else if (Ret == -1) printf("OtherSockets: Error reading from port %d (%s)\n", List[i], strerror(errno));
-      else ;//printf("OtherSockets: Read %d bytes from port %d\n", Ret, List[i]);
+      if(Ret == 0) m->PrintMessage("OtherSockets: Connection to port %d not existing anymore\n", List[i]);
+      else if (Ret == -1) m->PrintMessage("OtherSockets: Error reading from port %d (%s)\n", List[i], strerror(errno));
     }
   }
@@ -598,6 +580,6 @@
   for (unsigned int i=0; i<sizeof(List)/sizeof(int); i++) {
 	if ((Socket[i] != -1) && (close(Socket[i]) == -1)) {
-	  printf("OtherSockets: Could not close socket of port %d (%s)", List[i], strerror(errno));  
-	}
-  }
-}
+	  m->PrintMessage("OtherSockets: Could not close socket of port %d (%s)", List[i], strerror(errno));  
+	}
+  }
+}
Index: fact/FADctrl/FADBoard.h
===================================================================
--- fact/FADctrl/FADBoard.h	(revision 10153)
+++ fact/FADctrl/FADBoard.h	(revision 10164)
@@ -13,4 +13,5 @@
 #include <string.h>
 #include <iostream>
+#include <algorithm>
 #include <sys/socket.h>
 #include <netdb.h>
@@ -21,9 +22,8 @@
 const unsigned int READ_BUFFER_SIZE = 1000000;
 
-class FADBoard {
+class FADBoard: public DimThread {
 
 	class FAD *m;
 	int Socket;
-	pthread_t Thread, OtherThread;
 	pthread_mutex_t Mutex;
 	DimService *DIM_Name, *DIM_ID, *DIM_Temp, *DIM_ROI, *DIM_DAC;
@@ -31,5 +31,5 @@
 	void ReadLoop();
 	static void LaunchThread(class FADBoard *);
-	static void OpenOtherSockets(char *);
+	void threadHandler();
 
   public: 
@@ -65,9 +65,10 @@
 	void Unlock();
 
+	unsigned short Port;
 	char *Name;
-	bool InitOK;
-	bool CommError;
+	bool CommOK;
 	bool Active;
 	bool Continue;
+	pthread_t Thread;
 	pthread_cond_t CondVar;
 };
Index: fact/FADctrl/FADctrl.cc
===================================================================
--- fact/FADctrl/FADctrl.cc	(revision 10153)
+++ fact/FADctrl/FADctrl.cc	(revision 10164)
@@ -32,16 +32,4 @@
   signal(SIGPIPE, SIG_IGN);
 
-  // Initialise all boards
-  DimClient::sendCommand(SERVER_NAME"/Command", "dwrite off");
-  DimClient::sendCommand(SERVER_NAME"/Command", "domino off");
-  DimClient::sendCommand(SERVER_NAME"/Command", "dac 0 25000");
-  DimClient::sendCommand(SERVER_NAME"/Command", "dac 1-3 0");
-  DimClient::sendCommand(SERVER_NAME"/Command", "dac 4-7 28800");
-  DimClient::sendCommand(SERVER_NAME"/Command", "domino on");
-  DimClient::sendCommand(SERVER_NAME"/Command", "dwrite on");
-  DimClient::sendCommand(SERVER_NAME"/Command", "roi all 1024");
-  DimClient::sendCommand(SERVER_NAME"/Command", "trigger enable");
-  M.PrintMessage("Finished initalizing all boards\n");
-
   // Command loop
   char *Command;
@@ -49,5 +37,5 @@
 
   while (!M.ExitRequest) {
-    Command = readline("\rFADctrl>");
+    Command = readline("\rFADctrl> ");
 
 	// Check for interruption by signal
@@ -60,6 +48,6 @@
 	}
 
-    // Process command
-	DimClient::sendCommand(SERVER_NAME"/Command", Command);
+    // Process command (use SendCommandNB(), see mail from C. Gaspar 18/2/2011)
+	DimClient::sendCommandNB(SERVER_NAME"/Command", Command);
     free(Command);
   }
Index: fact/FADctrl/History.txt
===================================================================
--- fact/FADctrl/History.txt	(revision 10153)
+++ fact/FADctrl/History.txt	(revision 10164)
@@ -11,2 +11,5 @@
 2/2/2011	Warning if amplitude calibration missing for data taking
 4/2/2011	Fixed exitHandler() being stuck at pthread_join()
+11/2/2011	Moved connect() call to thread of FADBoard class
+14/2/2011	Moved initialisation commands to Evidence configuration file
+18/2/2011   Added 'reconnect' command
