Changeset 10164


Ignore:
Timestamp:
Feb 18, 2011, 5:01:25 PM (9 years ago)
Author:
ogrimm
Message:
Moved board initalisation to thread, added 'reconnect' command
Location:
fact/FADctrl
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • fact/FADctrl/FAD.cc

    r10128 r10164  
    11/********************************************************************\
    22
    3   FAD.cc
    4 
    53  Main class of FADCtrl
    64
    7 
    8  Comment 19/10/2010: It is assumed that boolean access is an atomic operation.
     5  If outputting text with PrintMessage(), a '\r' is used on the console automatically
     6  if the given text ends with '\n'.
     7 
     8  Comment 19/10/2010: It is assumed that boolean access is an atomic operation.
    99     
    1010\********************************************************************/
     
    2020                          const char *Help;
    2121  } CommandList[] =
    22   {{"board", &FAD::cmd_board, true, 1, "[+|-]<range>" ,"Activate or deactivate boards"},
     22  {{"board", &FAD::cmd_board, true, 1, "[+|-]<range>" ,"Activate or deactivate board(s)"},
    2323   {"status", &FAD::cmd_status, false, 0, "[range]", "Show board status information"},
    2424   {"domino", &FAD::cmd_domino, true, 1, "<on|off>", "Switch Domino wave"},
     
    4040   {"update", &FAD::cmd_update, false, 1, "<sec>", "Minimum delay between updates to DIM event service"},                 
    4141   {"socketmode", &FAD::cmd_socketmode, true, 1, "<com|daq>", "Choose which Sockets are used for data transmission"},             
    42    {"exit", &FAD::cmd_exit, true, 0, "", "Exit program"},
     42   {"reconnect", &FAD::cmd_reconnect, true, 1, "<board range> [init]", "Reconnect to boards (and re-initialise)"},               
     43   {"exit", &FAD::cmd_exit, false, 0, "", "Exit program"},
    4344   {"help", &FAD::cmd_help, false, 0, "", "Print help"}};
    44 
    4545
    4646
     
    6161  EventUpdateDelay = atof(GetConfig("EventUpdateDelay", "0.5").c_str());
    6262
    63   // Create pipe for command execution and data exchange
    64   if (pipe(CommandPipe) == -1) Message(FATAL, "pipe() failed in FAD::FAD() (%s)", strerror(errno));
     63  // Create pipe for data exchange
    6564  if (pipe(Pipe) == -1) Message(FATAL, "pipe() failed in FAD::FAD() (%s)", strerror(errno));
    6665
     
    7574
    7675  for (unsigned int i=0; i<BoardList.size(); i++) {
    77     Boards.push_back(new class FADBoard(BoardList[i], 5000, this, i));
    78 
    79         // Check if initialised OK
    80         if (!Boards.back()->InitOK) {
    81           Message(WARN, "Failed to initialize board %s", BoardList[i].c_str());
    82           delete Boards.back();
    83           Boards.pop_back();
    84         }
     76    Boards.push_back(new class FADBoard(BoardList[i], PORT, this, i));
    8577  }
    8678
     
    9183  }
    9284
    93   // Create command handling thread
    94   DimThread::start();
    95 
    9685  // Install DIM command (after all initialized)
    9786  Command = new DimCommand((char *) SERVER_NAME"/Command", (char *) "C", this);
     87 
     88  // Initialise boards
     89  vector<string> Init = Tokenize(GetConfig("InitSequence", ""), ";");
     90
     91  for (unsigned int i=0; i<Init.size(); i++) {
     92        DimClient::sendCommand(SERVER_NAME"/Command", Init[i].c_str());
     93  }
    9894}
    9995
     
    108104  if (close(Pipe[0]) == -1) Message(ERROR, "close() on Pipe[0] failed in FAD::~FAD() (%s)", strerror(errno));
    109105  if (close(Pipe[1]) == -1) Message(ERROR, "close() on Pipe[1] failed in FAD::~FAD() (%s)", strerror(errno));
    110   if (close(CommandPipe[0]) == -1) Message(ERROR, "close() on CommandPipe[0] failed in FAD::~FAD() (%s)", strerror(errno));
    111   if (close(CommandPipe[1]) == -1) Message(ERROR, "close() on CommandPipe[1] failed in FAD::~FAD() (%s)", strerror(errno));
    112 
    113   // Wait for command and DIM service thread to quit
     106
     107  // Wait for DIM service thread to quit
    114108  if ((Ret = pthread_join(Thread, NULL)) != 0) Message(ERROR, "pthread_join() failed in ~FAD() (%s)", strerror(Ret));
    115109
     
    131125void FAD::commandHandler() {
    132126
     127  char *Command = getCommand()->getString(), *Start;
     128
    133129  // Ignore empty or illegal strings
    134   if (getCommand()->getSize() == 0 || *(getCommand()->getString()+getCommand()->getSize()-1) != '\0' ||
    135           strlen(getCommand()->getString()) == 0) return;
    136 
    137   // Send command to command execution thread
    138   if (write(CommandPipe[1], getCommand()->getData(), getCommand()->getSize()) == -1) {
    139         Message(ERROR, "write() to CommandPipe[1] failed in class FAD::commandHandler() (%s)", strerror(errno));
    140   }
    141 }
    142 
    143 //
    144 // Command execution thread
    145 //
    146 void FAD::threadHandler() {
    147 
    148   char *Command, *Start, Buffer[1000];
    149   int Ret;
    150   unsigned int n;
    151 
    152   while (!ExitRequest) {
    153         if ((Ret=read(CommandPipe[0], Buffer, sizeof(Buffer))) == -1) Message(ERROR, "read() from CommandPipe[0] failed in FAD::threadHandler() (%s)", strerror(errno));
    154 
    155         // Check if pipe closed
    156         if (Ret == 0) break;
    157 
    158         // Shell command
    159         if (Buffer[0]=='.') {
    160       system(&(Buffer[1]));
    161       continue;
    162         }
    163 
    164         // Parse command into tokens
    165         Parameter.clear();
    166         Command = Buffer;
    167         while(true) {
    168       while (isspace(*Command)) Command++; // Ignore initial white spaces
    169       if(*Command=='\0') break;
    170       if (*Command == '\"') {
    171                 Start = ++Command;
    172         while(*Command!='\"' && *Command!='\0') Command++;
    173       }
    174       else {
    175                 Start = Command;
    176         while(!isspace(*Command) && *Command!='\0') Command++;
    177       }
    178       if(*Command != '\0') *Command++ = '\0';
    179           Parameter.push_back(Start);
    180         }
    181 
    182         // Search for command in command list
    183         for(n=0; n<sizeof(CommandList)/sizeof(CL_Struct); n++) {
    184       if (Match(Parameter[0], CommandList[n].Name)) break;
    185         }
    186 
    187         // Command not found?   
    188         if (n == sizeof(CommandList)/sizeof(CL_Struct)) {
    189           PrintMessage("Unknown command '%s'\n", Parameter[0].c_str());
    190           continue;
    191         }
    192 
    193         // Check if number of parameters
    194     if(Parameter.size()-1 < CommandList[n].MinNumParameter) {
    195           PrintMessage("Usage: %s %s\n", CommandList[n].Name, CommandList[n].Parameters);
    196           continue;
    197         }
    198 
    199         // Check if idle mode required
    200         if (CommandList[n].NeedIdle && Mode != idle) {
    201           PrintMessage("Current mode is not idle ('stop' will stop current operation)\n");
    202           continue;
    203         }
    204        
    205         // Jump to command function
    206         (this->*CommandList[n].CommandPointer)();
    207   } // while()
    208 }
    209 
    210 //
    211 // DIM exit handler (overwriting handler in Evidence class)
    212 //
    213 void FAD::exitHandler(int Code) {
    214 
    215   Message(INFO, "Exit handler called (DIM exit code %d)", Code);
    216   pthread_kill(MainThread, SIGTERM);
     130  if (getCommand()->getSize() == 0) return;
     131  if( *(Command+getCommand()->getSize()-1) != '\0' || strlen(Command) == 0) return;
     132
     133  // Shell command
     134  if (*Command == '.') {
     135    system(Command+1);
     136    return;
     137  }
     138
     139  // Parse command into tokens
     140  Parameter.clear();
     141  while(true) {
     142    while (isspace(*Command)) Command++; // Ignore initial white spaces
     143    if(*Command=='\0') break;
     144    if (*Command == '\"') {
     145          Start = ++Command;
     146      while(*Command!='\"' && *Command!='\0') Command++;
     147    }
     148    else {
     149          Start = Command;
     150      while(!isspace(*Command) && *Command!='\0') Command++;
     151    }
     152    if(*Command != '\0') *Command++ = '\0';
     153        Parameter.push_back(Start);
     154  }
     155
     156  // Search for command in command list
     157  for(unsigned int n=0; n<sizeof(CommandList)/sizeof(CL_Struct); n++) {
     158    if (Match(Parameter[0], CommandList[n].Name)) {
     159          // Check if number of parameters
     160          if(Parameter.size()-1 < CommandList[n].MinNumParameter) {
     161                PrintMessage("Usage: %s %s\n", CommandList[n].Name, CommandList[n].Parameters);
     162                return;
     163          }
     164          // Check if idle mode required
     165          if (CommandList[n].NeedIdle && Mode != idle) {
     166                PrintMessage("Current mode is not idle ('stop' will stop current operation)\n");
     167                return;
     168          }
     169          // Jump to command function
     170          (this->*CommandList[n].CommandPointer)();
     171          return;
     172        }
     173  }
     174
     175  // Command not found 
     176  PrintMessage("Unknown command '%s'\n", Parameter[0].c_str());
    217177}
    218178
     
    225185        if (Match(Parameter[1],"on")) Boards[i]->Send(CMD_SRCLK_ON);
    226186        else if (Match(Parameter[1],"off")) Boards[i]->Send(CMD_SRCLK_OFF);
    227   }
    228 
    229   if (Match(Parameter[1],"on")) PrintMessage("SRCLK switched on for all active boards\n");
    230   else if (Match(Parameter[1],"off")) PrintMessage("SRCLK switched off for all active boards\n");
    231   else PrintUsage();
     187        else {
     188          PrintUsage();
     189          return;
     190        }
     191  }
    232192}
    233193
     
    244204        if (Match(Parameter[1],"com")) Boards[i]->Send(CMD_Stop);
    245205        else if (Match(Parameter[1],"daq")) Boards[i]->Send(CMD_Start);
    246   }
    247 
    248   if (Match(Parameter[1],"com")) PrintMessage("All active boards switched to command mode - socket 0\n");
    249   else if (Match(Parameter[1],"daq")) PrintMessage("All active boards switched to DAQ mode - socket 1..7\n");
    250   else PrintUsage();
     206        else {
     207          PrintUsage();
     208          return;
     209        }
     210  }
    251211}
    252212
     
    259219        if (Match(Parameter[1],"on")) Boards[i]->Send(CMD_SCLK_ON);
    260220        else if (Match(Parameter[1],"off")) Boards[i]->Send(CMD_SCLK_OFF);
    261   }
    262 
    263   if (Match(Parameter[1],"on")) PrintMessage("SCLK switched on for all active boards\n");
    264   else if (Match(Parameter[1],"off")) PrintMessage("SCLK switched off for all active boards\n");
    265   else PrintUsage();
     221        else {
     222          PrintUsage();
     223          return;
     224        }
     225  }
    266226}
    267227
     
    274234        if (Match(Parameter[1],"on")) Boards[i]->Send(CMD_DENABLE);
    275235        else if (Match(Parameter[1],"off")) Boards[i]->Send(CMD_DDISABLE);
    276   }
    277  
    278   if (Match(Parameter[1],"on")) PrintMessage("Domino wave switched on for all active boards\n");
    279   else if (Match(Parameter[1],"off")) PrintMessage("Domino wave switched off for all active boards\n");
    280   else PrintUsage();
     236        else {
     237          PrintUsage();
     238          return;
     239        }
     240  }
    281241}
    282242
     
    289249        if (Match(Parameter[1],"on")) Boards[i]->Send(CMD_DWRITE_RUN);
    290250        else if (Match(Parameter[1],"off")) Boards[i]->Send(CMD_DWRITE_STOP);
    291   }
    292 
    293   if (Match(Parameter[1],"on")) PrintMessage("DWRITE set high for all active boards\n");
    294   else if (Match(Parameter[1],"off")) PrintMessage("DWRITE set low for all active boards\n");
    295   else PrintUsage();
     251        else {
     252          PrintUsage();
     253          return;
     254        }
     255  }
    296256}
    297257
     
    544504
    545505  // Read calibration data from file?
    546   //if (Parameter.size() == 2 && !ConvertToInt(Parameter[1], &NumCalibEvents)) {
    547506  if (Parameter.size() == 2 && !ConvertToInt(Parameter[1], &NumEventsRequested)) {
    548507    // Open file
     
    618577        for (unsigned int i=0; i<Boards.size(); i++) {
    619578          if (Boards[i]->Active) Count++;
    620           if (Boards[i]->CommError) Error++;
     579          if (!Boards[i]->CommOK) Error++;
    621580        }         
    622581
    623         PrintMessage("Total boards: %d    (%d communication errors)     Active boards: ", Boards.size(), Error);
     582        PrintMessage("\rTotal boards: %d    (%d communication errors)     Active boards: %d\n", Boards.size(), Error, Count);
    624583
    625584        // Print list of active boards
    626         if (Count == 0) PrintMessage("none\n");
    627         else if (Count == Boards.size()) PrintMessage("all\n");
    628         else for (unsigned int i=0; i<Boards.size(); i++) {
    629           if (Boards[i]->Active) PrintMessage(" %d", i);
     585        if (Count != 0) {
     586          PrintMessage("Active are ");
     587          for (unsigned int i=0; i<Boards.size(); i++) if (Boards[i]->Active) PrintMessage(" %d", i);
     588          PrintMessage("\n");
    630589        }
    631590
     
    649608        if (i<R.Min || i > R.Max) continue;
    650609
    651         PrintMessage("BOARD #%d (%sactive)   IP %s   Communication %s\n", i, Boards[i]->Active ? "":"in", Boards[i]->Name, Boards[i]->CommError ? "ERROR":"OK");
     610        PrintMessage("BOARD #%d (%sactive)   IP %s   Communication %s\n", i, Boards[i]->Active ? "":"in", Boards[i]->Name, Boards[i]->CommOK ? "OK":"ERROR");
    652611
    653612        // Calibration information
     
    688647}
    689648
    690 
    691649//
    692650// Adress FAD boards
     
    721679
    722680//
     681// Reconnect to boards
     682//
     683void FAD::cmd_reconnect() {
     684
     685  struct Range R = {0, Boards.size()};
     686
     687  // Check ranges 
     688  if (!ConvertToRange(Parameter[1], R)) {
     689        PrintMessage("Error, board number(s) out of range\n");
     690        return;
     691  }
     692  PrintMessage("Note: Currently not protection against concurrent access in EventThread\n");
     693 
     694  // Reinstantiate boards
     695  for (int i=0; i<(int) Boards.size(); i++) if (i >= R.Min && i <= R.Max) {
     696        if (pthread_kill(Boards[i]->Thread, 0) != ESRCH) {
     697          PrintMessage("Event thread of board %d still running, cannot reconnect\n", i);
     698          continue;
     699        }
     700
     701        delete Boards[i];
     702    Boards[i] = new class FADBoard(BoardList[i], PORT, this, i);
     703  }
     704 
     705  // Initialise boards if requested (use sendCommandNB() to avoid dead lock)
     706  if (Parameter.size() != 3 || !Match(Parameter[2], "init")) return;
     707   
     708  vector<string> Init = Tokenize(GetConfig("InitSequence"), ";");
     709
     710  for (unsigned int i=0; i<Init.size(); i++) {
     711        DimClient::sendCommandNB(SERVER_NAME"/Command", (char *) Init[i].c_str());
     712  }
     713}
     714
     715//
    723716// Set DIM event update delay
    724717//
     
    749742        free(Buffer);
    750743  }
    751   PrintMessage(".<command>                  Execute shell command\n\n"
     744  PrintMessage(".<command>               Execute shell command\n\n"
    752745   "Items in <> are mandatory, in [] optional, | indicates mutual exclusive.\n"
    753746   "Strings containing spaces have to be enclosed in \"double quotes\".\n"
     
    756749
    757750//
    758 // Cancel current operation
     751// Stop current operation
    759752//
    760753void FAD::cmd_stop() {
     
    784777//
    785778// Exit programm
    786 // SIGTERM sets ExitRequest flag, and also makes readline() return (if command from DimCommand thread)
     779// SIGTERM sets ExitRequest flag, and also makes
     780// readline() return (in case command came over network)
    787781//
    788782void FAD::cmd_exit() {
     783
     784  if (Mode != idle) cmd_stop();
    789785
    790786  pthread_kill(MainThread, SIGTERM);
     
    795791// *****  Other functions  *****
    796792// -----------------------------
     793
     794//
     795// DIM exit handler (overwriting handler in Evidence class)
     796//
     797void FAD::exitHandler(int Code) {
     798
     799  Message(INFO, "Exit handler called (DIM exit code %d)", Code);
     800  cmd_exit();
     801}
    797802
    798803//
     
    810815  // Generate filename
    811816  TimeInfo = localtime(&Time);
    812   if (strftime(Buffer, sizeof(Buffer), "/FADcalib_%y-%m-%jT%X.txt", TimeInfo) == 0) {
     817  if (strftime(Buffer, sizeof(Buffer), "/FADcalib_%y-%m-%dT%X.txt", TimeInfo) == 0) {
    813818        PrintMessage("Could not generate calibration data file name, strftime() failed\n");
    814819        return;
     
    917922          for (unsigned int i=0; i<Boards.size(); i++) {
    918923                if (IDString.find(string("ACALIBDONE")+Boards[i]->Name) != string::npos) AcalibDone[i] = true;
    919                 if (!AcalibDone[i]) Done = false;
     924                if (!AcalibDone[i] && Boards[i]->Active && Boards[i]->CommOK) Done = false;
    920925          }
    921926          // Amplitude calibration finished?
     
    11291134  va_end(ArgumentPointer);
    11301135 
     1136  if (strlen(Text) == 0) return;
     1137 
    11311138  // Print to console
     1139  if (Text[strlen(Text)-1] == '\n') printf("\r");               // Overwrite prompt
    11321140  printf("%s", Text);
    11331141  fflush(stdout);
    1134   if (strlen(Text)>0 && Text[strlen(Text)-1]=='\n') rl_on_new_line(); // New prompt
     1142  if (Text[strlen(Text)-1]=='\n') rl_on_new_line();             // New prompt
    11351143
    11361144  // Send to DIM text service
  • fact/FADctrl/FAD.h

    r10128 r10164  
    2121#include "FADBoard.h"
    2222
     23const unsigned int PORT = 5000;
    2324const int DEFAULT_NUM_CALIB_EVENTS = 100;
    2425const char CALIB_DIRECTORY[] = "~/";
    2526
    2627
    27 class FAD: public EvidenceServer, public DimThread {
     28class FAD: public EvidenceServer {
    2829
    2930  public:
     
    3940    void PrintUsage();
    4041        void commandHandler();
    41         void threadHandler();
    4242        virtual void exitHandler(int);
    4343        bool Match(std::string, const char *);
     
    7777        void cmd_phase();               void cmd_send();
    7878        void cmd_stop();                void cmd_update();
    79         void cmd_take();
     79        void cmd_take();                void cmd_reconnect();
    8080
    8181    void EnableDomino();
     
    8989       
    9090        int Pipe[2];
    91         int CommandPipe[2];
    9291    int NumEventsRequested;     // Number of events requested
    9392        std::vector<std::string> BoardList;
  • fact/FADctrl/FADBoard.cc

    r10128 r10164  
    1111// Constructor
    1212//
    13 FADBoard::FADBoard(string Server, unsigned short Port, class FAD *Parent, unsigned int Num) {
     13FADBoard::FADBoard(string Server, unsigned short ServerPort, class FAD *Parent, unsigned int Num) {
    1414
    1515  int Ret;
     
    1717  // Initialization
    1818  m = Parent;
    19   InitOK = false;
    2019  Active = true;
    2120  Continue = true;
    22   CommError = false;
     21  CommOK = false;
    2322  ACalibTime = -1;
    2423  Status.Update.tv_sec = -1;
     24  Port = ServerPort;
    2525
    2626  Name = new char [Server.size()+1]; // Name in permanent memory for DIM service
     
    4242  }
    4343
    44   // Resolve hostname
    45   struct hostent *Host = gethostbyname(Server.c_str());
    46   if (Host == 0) {
    47     m->PrintMessage("Could not resolve host name for %s\n", Server.c_str());
    48     return;
    49   }
    50 
    51   // Open socket descriptor
    52   if ((Socket = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
    53     m->Message(m->ERROR, "Could not open socket for %s (%s)\n", Server.c_str(), strerror(errno));
    54     return;
    55   }
    56    
    57   // Connect to server
    58   struct sockaddr_in SocketAddress;
    59   SocketAddress.sin_family = PF_INET;
    60   SocketAddress.sin_port = htons(Port);
    61   SocketAddress.sin_addr = *(struct in_addr*) Host->h_addr;
    62  
    63   if (connect(Socket, (struct sockaddr *) &SocketAddress, sizeof(SocketAddress)) == -1) {
    64     m->PrintMessage("Could not connect to %s at port %d (%s)\n", Server.c_str(), Port, strerror(errno));
    65     return;
    66   }
    67  
    6844  // Construct DIM service name prefix
    6945  stringstream ID;
     
    7652  DIM_ROI = new DimService((ID.str()+"ROI").c_str(), (char *) "S", NULL, 0);
    7753
    78   // Create thread that receives data
     54  // Create thread that connects and receives data
    7955  if ((Ret = pthread_create(&Thread, NULL, (void * (*)(void *)) LaunchThread,(void *) this)) != 0) {
    8056    m->Message(m->FATAL, "pthread_create() failed in FADBoard() (%s)", strerror(Ret));
    8157  }
    8258
    83   // Create thread to connect to other sockets
    84   if ((Ret = pthread_create(&OtherThread, NULL, (void * (*)(void *)) OpenOtherSockets, (void *) Name)) != 0) {
    85     m->Message(m->FATAL, "pthread_create() failed for OpenOtherSockets (%s)", strerror(Ret));
    86   }
    87 
    88   InitOK = true;
     59  // Start thread to connect to other sockets
     60  DimThread::start();
    8961}
    9062
     
    9668  int Ret;
    9769
    98   // Avoid segmentation faults by chekcing for InitOK
    99   if (InitOK) {
    100         // Terminate thread for other sockets 
    101         if ((Ret = pthread_cancel(OtherThread)) != 0) {
    102           m->Message(m->ERROR, "pthread_cancel() failed in ~FADBoard() for OtherThread (%s)", strerror(Ret));
    103         }
    104         if ((Ret = pthread_join(OtherThread, NULL)) != 0) {
    105           m->Message(m->ERROR, "pthread_join() failed in ~FADBoard for OtherThread (%s)", strerror(Ret));
    106         }
    107 
    108         // Cancel thread (if it did not quit already) and wait for it to quit
    109         if ((Ret = pthread_cancel(Thread)) != 0 && Ret != ESRCH) {
    110           m->Message(m->ERROR, "pthread_cancel() failed in ~FADBoard() (%s)", strerror(Ret));
    111         }
    112         if ((Ret = pthread_join(Thread, NULL)) != 0) {
    113           m->Message(m->ERROR, "pthread_join() failed in ~FADBoard (%s)", strerror(Ret));
    114         }
    115 
    116         delete DIM_Name;
    117         delete DIM_ID;
    118         delete DIM_Temp;
    119         delete DIM_DAC;
    120         delete DIM_ROI;
    121   }
    122  
     70  // Cancel thread (if it did not quit already) and wait for it to quit
     71  if ((Ret = pthread_cancel(Thread)) != 0 && Ret != ESRCH) {
     72        m->Message(m->ERROR, "pthread_cancel() failed in ~FADBoard() (%s)", strerror(Ret));
     73  }
     74  if ((Ret = pthread_join(Thread, NULL)) != 0) {
     75        m->Message(m->ERROR, "pthread_join() failed in ~FADBoard (%s)", strerror(Ret));
     76  }
     77
     78  delete DIM_Name;
     79  delete DIM_ID;
     80  delete DIM_Temp;
     81  delete DIM_DAC;
     82  delete DIM_ROI; 
    12383  delete[] Name;
    124 
    125   // Close socket descriptor
    126   if ((Socket != -1) && (close(Socket) == -1)) {
    127         m->PrintMessage("Could not close socket descriptor (%s)", strerror(errno)); 
    128   }
    12984
    13085  // Delete condition variable
     
    145100void FADBoard::Send(const void *Data, size_t Bytes) {
    146101
    147   // Do not send if not active
    148   if (!Active) return;
     102  // Do not send if not active or communication problem
     103  if (!Active || !CommOK) return;
    149104
    150105  // Write data
     
    357312 
    358313//
    359 // Read data from board
     314// Connect to board and read data
    360315//
    361316void FADBoard::ReadLoop() {
     
    365320  const PEVNT_HEADER *Header = (PEVNT_HEADER *) Buffer;
    366321  ssize_t Result;
     322  struct sockaddr_in SocketAddress;
    367323  struct BoardStatus PrevStatus;
    368324  int Ret;
    369325
     326  // Resolve hostname
     327  struct hostent *Host = gethostbyname(Name);
     328  if (Host == 0) {
     329    m->Message(m->WARN, "Could not resolve host name for %s", Name);
     330    return;
     331  }
     332
     333  SocketAddress.sin_family = PF_INET;
     334  SocketAddress.sin_port = htons(Port);
     335  SocketAddress.sin_addr = *(struct in_addr*) Host->h_addr;
     336
     337  // Open socket descriptor
     338  if ((Socket = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
     339    m->Message(m->ERROR, "Could not open socket for %s (%s)\n", Name, strerror(errno));
     340    return;
     341  }
     342   
     343  // Connect to server
     344  if (connect(Socket, (struct sockaddr *) &SocketAddress, sizeof(SocketAddress)) == -1) {
     345    m->PrintMessage("Could not connect to %s at port %d (%s)\n", Name, Port, strerror(errno));
     346  }
     347  else CommOK = true;
    370348  memset(&PrevStatus, 0, sizeof(PrevStatus));
    371349
    372   while (!m->ExitRequest) {
     350  // Leave loop if program termination requested or board communication not OK
     351  while (!m->ExitRequest && CommOK) {
    373352    // Read data from socket
    374353    Result = read(Socket, Buffer + Pos, sizeof(Buffer)-Pos);
     
    377356        if (Result == -1) {
    378357          m->PrintMessage("Error: Could not read from socket, exiting read loop (%s)\n", strerror(errno));
    379           CommError = true;
     358          CommOK = false;
    380359          break;
    381360        }
    382361        else if (Result == 0) {
    383362          m->PrintMessage("Server not existing anymore, exiting read loop\n");
    384           CommError = true;
     363          CommOK = false;
    385364          break;
    386365        }
     
    490469          } 
    491470        }
    492         else printf("End package flag incorrect, removing corrupt event\n");
     471        else m->PrintMessage("End package flag incorrect, removing corrupt event\n");
    493472
    494473        // Inform event thread of new data
     
    503482        Pos = Pos-Length;       
    504483  } // while()
     484 
     485  // Close socket descriptor
     486  if (close(Socket) == -1) {
     487        m->PrintMessage("Could not close socket descriptor for board %s (%s)", Name, strerror(errno)); 
     488  }
     489
    505490}
    506491
     
    538523
    539524//
    540 // OpenOtherSockets()
    541 //
    542 void FADBoard::OpenOtherSockets(char *Hostname) {
     525// Open other sockets
     526//
     527void FADBoard::threadHandler() {
    543528
    544529  int List[] = {5001, 5002, 5003, 5004, 5005, 5006, 5007};
    545   int Socket[sizeof(List)/sizeof(int)], MaxSocketNum=0, Ret;
     530  int Socket[sizeof(List)/sizeof(int)], MaxSocketNum, Ret;
    546531  fd_set DescriptorList;
    547532  char Buffer[1000000];
    548 
     533 
    549534  // Resolve hostname
    550   struct hostent *Host = gethostbyname(Hostname);
     535  struct hostent *Host = gethostbyname(Name);
    551536  if (Host == 0) {
    552     printf("OtherSockets: Could not resolve host name for %s\n", Hostname);
     537    m->PrintMessage("OtherSockets: Could not resolve host name for %s\n", Name);
    553538    return;
    554539  }
     
    562547        // Open socket descriptor
    563548        if ((Socket[i] = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
    564       printf("OtherSockets: Could not open socket for port %d (%s)\n", List[i], strerror(errno));
     549      m->PrintMessage("OtherSockets: Could not open socket for port %d (%s)\n", List[i], strerror(errno));
    565550      return;
    566551        }
    567 
    568         // Determine highest socket number for select()
    569         if (Socket[i] > MaxSocketNum) MaxSocketNum = Socket[i];
     552        MaxSocketNum = *max_element(Socket, Socket+sizeof(List)/sizeof(int));
    570553         
    571554        // Connect to server
    572555    SocketAddress.sin_port = htons((unsigned short) List[i]);
    573556        if (connect(Socket[i], (struct sockaddr *) &SocketAddress, sizeof(SocketAddress)) == -1) {
    574       printf("OtherSockets: Could not connect to port %d (%s)\n", List[i], strerror(errno));
     557      m->PrintMessage("OtherSockets: Could not connect to port %d (%s)\n", List[i], strerror(errno));
    575558      return;
    576559        }
     
    578561 
    579562  while(true) {
    580     // Wait for data from terminal (stdin) or from sockets
     563    // Wait for data from sockets
    581564    FD_ZERO(&DescriptorList);   
    582565    for (unsigned int i=0; i<sizeof(List)/sizeof(int); i++) FD_SET(Socket[i], &DescriptorList);
    583566    if (select(MaxSocketNum+1, &DescriptorList, NULL, NULL, NULL) == -1) {
    584       perror("OtherSockets: Error with select()");
     567      m->PrintMessage("OtherSockets: Error with select() (%s)\n", strerror(errno));
    585568      break;
    586569    }
     
    589572        for (unsigned int i=0; i<sizeof(List)/sizeof(int); i++) if (FD_ISSET(Socket[i], &DescriptorList)) {
    590573          Ret = read(Socket[i], Buffer, sizeof(Buffer));
    591       if(Ret == 0) printf("OtherSockets: Connection to port %d not existing anymore\n", List[i]);
    592       else if (Ret == -1) printf("OtherSockets: Error reading from port %d (%s)\n", List[i], strerror(errno));
    593       else ;//printf("OtherSockets: Read %d bytes from port %d\n", Ret, List[i]);
     574      if(Ret == 0) m->PrintMessage("OtherSockets: Connection to port %d not existing anymore\n", List[i]);
     575      else if (Ret == -1) m->PrintMessage("OtherSockets: Error reading from port %d (%s)\n", List[i], strerror(errno));
    594576    }
    595577  }
     
    598580  for (unsigned int i=0; i<sizeof(List)/sizeof(int); i++) {
    599581        if ((Socket[i] != -1) && (close(Socket[i]) == -1)) {
    600           printf("OtherSockets: Could not close socket of port %d (%s)", List[i], strerror(errno)); 
    601         }
    602   }
    603 }
     582          m->PrintMessage("OtherSockets: Could not close socket of port %d (%s)", List[i], strerror(errno)); 
     583        }
     584  }
     585}
  • fact/FADctrl/FADBoard.h

    r10120 r10164  
    1313#include <string.h>
    1414#include <iostream>
     15#include <algorithm>
    1516#include <sys/socket.h>
    1617#include <netdb.h>
     
    2122const unsigned int READ_BUFFER_SIZE = 1000000;
    2223
    23 class FADBoard {
     24class FADBoard: public DimThread {
    2425
    2526        class FAD *m;
    2627        int Socket;
    27         pthread_t Thread, OtherThread;
    2828        pthread_mutex_t Mutex;
    2929        DimService *DIM_Name, *DIM_ID, *DIM_Temp, *DIM_ROI, *DIM_DAC;
     
    3131        void ReadLoop();
    3232        static void LaunchThread(class FADBoard *);
    33         static void OpenOtherSockets(char *);
     33        void threadHandler();
    3434
    3535  public:
     
    6565        void Unlock();
    6666
     67        unsigned short Port;
    6768        char *Name;
    68         bool InitOK;
    69         bool CommError;
     69        bool CommOK;
    7070        bool Active;
    7171        bool Continue;
     72        pthread_t Thread;
    7273        pthread_cond_t CondVar;
    7374};
  • fact/FADctrl/FADctrl.cc

    r10128 r10164  
    3232  signal(SIGPIPE, SIG_IGN);
    3333
    34   // Initialise all boards
    35   DimClient::sendCommand(SERVER_NAME"/Command", "dwrite off");
    36   DimClient::sendCommand(SERVER_NAME"/Command", "domino off");
    37   DimClient::sendCommand(SERVER_NAME"/Command", "dac 0 25000");
    38   DimClient::sendCommand(SERVER_NAME"/Command", "dac 1-3 0");
    39   DimClient::sendCommand(SERVER_NAME"/Command", "dac 4-7 28800");
    40   DimClient::sendCommand(SERVER_NAME"/Command", "domino on");
    41   DimClient::sendCommand(SERVER_NAME"/Command", "dwrite on");
    42   DimClient::sendCommand(SERVER_NAME"/Command", "roi all 1024");
    43   DimClient::sendCommand(SERVER_NAME"/Command", "trigger enable");
    44   M.PrintMessage("Finished initalizing all boards\n");
    45 
    4634  // Command loop
    4735  char *Command;
     
    4937
    5038  while (!M.ExitRequest) {
    51     Command = readline("\rFADctrl>");
     39    Command = readline("\rFADctrl> ");
    5240
    5341        // Check for interruption by signal
     
    6048        }
    6149
    62     // Process command
    63         DimClient::sendCommand(SERVER_NAME"/Command", Command);
     50    // Process command (use SendCommandNB(), see mail from C. Gaspar 18/2/2011)
     51        DimClient::sendCommandNB(SERVER_NAME"/Command", Command);
    6452    free(Command);
    6553  }
  • fact/FADctrl/History.txt

    r10128 r10164  
    11112/2/2011        Warning if amplitude calibration missing for data taking
    12124/2/2011        Fixed exitHandler() being stuck at pthread_join()
     1311/2/2011       Moved connect() call to thread of FADBoard class
     1414/2/2011       Moved initialisation commands to Evidence configuration file
     1518/2/2011   Added 'reconnect' command
Note: See TracChangeset for help on using the changeset viewer.