Changeset 10164
- Timestamp:
- 02/18/11 17:01:25 (14 years ago)
- Location:
- fact/FADctrl
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
fact/FADctrl/FAD.cc
r10128 r10164 1 1 /********************************************************************\ 2 2 3 FAD.cc4 5 3 Main class of FADCtrl 6 4 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. 9 9 10 10 \********************************************************************/ … … 20 20 const char *Help; 21 21 } CommandList[] = 22 {{"board", &FAD::cmd_board, true, 1, "[+|-]<range>" ,"Activate or deactivate board s"},22 {{"board", &FAD::cmd_board, true, 1, "[+|-]<range>" ,"Activate or deactivate board(s)"}, 23 23 {"status", &FAD::cmd_status, false, 0, "[range]", "Show board status information"}, 24 24 {"domino", &FAD::cmd_domino, true, 1, "<on|off>", "Switch Domino wave"}, … … 40 40 {"update", &FAD::cmd_update, false, 1, "<sec>", "Minimum delay between updates to DIM event service"}, 41 41 {"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"}, 43 44 {"help", &FAD::cmd_help, false, 0, "", "Print help"}}; 44 45 45 46 46 … … 61 61 EventUpdateDelay = atof(GetConfig("EventUpdateDelay", "0.5").c_str()); 62 62 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 65 64 if (pipe(Pipe) == -1) Message(FATAL, "pipe() failed in FAD::FAD() (%s)", strerror(errno)); 66 65 … … 75 74 76 75 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)); 85 77 } 86 78 … … 91 83 } 92 84 93 // Create command handling thread94 DimThread::start();95 96 85 // Install DIM command (after all initialized) 97 86 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 } 98 94 } 99 95 … … 108 104 if (close(Pipe[0]) == -1) Message(ERROR, "close() on Pipe[0] failed in FAD::~FAD() (%s)", strerror(errno)); 109 105 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 114 108 if ((Ret = pthread_join(Thread, NULL)) != 0) Message(ERROR, "pthread_join() failed in ~FAD() (%s)", strerror(Ret)); 115 109 … … 131 125 void FAD::commandHandler() { 132 126 127 char *Command = getCommand()->getString(), *Start; 128 133 129 // 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()); 217 177 } 218 178 … … 225 185 if (Match(Parameter[1],"on")) Boards[i]->Send(CMD_SRCLK_ON); 226 186 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 } 232 192 } 233 193 … … 244 204 if (Match(Parameter[1],"com")) Boards[i]->Send(CMD_Stop); 245 205 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 } 251 211 } 252 212 … … 259 219 if (Match(Parameter[1],"on")) Boards[i]->Send(CMD_SCLK_ON); 260 220 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 } 266 226 } 267 227 … … 274 234 if (Match(Parameter[1],"on")) Boards[i]->Send(CMD_DENABLE); 275 235 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 } 281 241 } 282 242 … … 289 249 if (Match(Parameter[1],"on")) Boards[i]->Send(CMD_DWRITE_RUN); 290 250 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 } 296 256 } 297 257 … … 544 504 545 505 // Read calibration data from file? 546 //if (Parameter.size() == 2 && !ConvertToInt(Parameter[1], &NumCalibEvents)) {547 506 if (Parameter.size() == 2 && !ConvertToInt(Parameter[1], &NumEventsRequested)) { 548 507 // Open file … … 618 577 for (unsigned int i=0; i<Boards.size(); i++) { 619 578 if (Boards[i]->Active) Count++; 620 if ( Boards[i]->CommError) Error++;579 if (!Boards[i]->CommOK) Error++; 621 580 } 622 581 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); 624 583 625 584 // 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"); 630 589 } 631 590 … … 649 608 if (i<R.Min || i > R.Max) continue; 650 609 651 PrintMessage("BOARD #%d (%sactive) IP %s Communication %s\n", i, Boards[i]->Active ? "":"in", Boards[i]->Name, Boards[i]->Comm Error ? "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"); 652 611 653 612 // Calibration information … … 688 647 } 689 648 690 691 649 // 692 650 // Adress FAD boards … … 721 679 722 680 // 681 // Reconnect to boards 682 // 683 void 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 // 723 716 // Set DIM event update delay 724 717 // … … 749 742 free(Buffer); 750 743 } 751 PrintMessage(".<command> 744 PrintMessage(".<command> Execute shell command\n\n" 752 745 "Items in <> are mandatory, in [] optional, | indicates mutual exclusive.\n" 753 746 "Strings containing spaces have to be enclosed in \"double quotes\".\n" … … 756 749 757 750 // 758 // Cancelcurrent operation751 // Stop current operation 759 752 // 760 753 void FAD::cmd_stop() { … … 784 777 // 785 778 // 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) 787 781 // 788 782 void FAD::cmd_exit() { 783 784 if (Mode != idle) cmd_stop(); 789 785 790 786 pthread_kill(MainThread, SIGTERM); … … 795 791 // ***** Other functions ***** 796 792 // ----------------------------- 793 794 // 795 // DIM exit handler (overwriting handler in Evidence class) 796 // 797 void FAD::exitHandler(int Code) { 798 799 Message(INFO, "Exit handler called (DIM exit code %d)", Code); 800 cmd_exit(); 801 } 797 802 798 803 // … … 810 815 // Generate filename 811 816 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) { 813 818 PrintMessage("Could not generate calibration data file name, strftime() failed\n"); 814 819 return; … … 917 922 for (unsigned int i=0; i<Boards.size(); i++) { 918 923 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; 920 925 } 921 926 // Amplitude calibration finished? … … 1129 1134 va_end(ArgumentPointer); 1130 1135 1136 if (strlen(Text) == 0) return; 1137 1131 1138 // Print to console 1139 if (Text[strlen(Text)-1] == '\n') printf("\r"); // Overwrite prompt 1132 1140 printf("%s", Text); 1133 1141 fflush(stdout); 1134 if ( strlen(Text)>0 && Text[strlen(Text)-1]=='\n') rl_on_new_line();// New prompt1142 if (Text[strlen(Text)-1]=='\n') rl_on_new_line(); // New prompt 1135 1143 1136 1144 // Send to DIM text service -
fact/FADctrl/FAD.h
r10128 r10164 21 21 #include "FADBoard.h" 22 22 23 const unsigned int PORT = 5000; 23 24 const int DEFAULT_NUM_CALIB_EVENTS = 100; 24 25 const char CALIB_DIRECTORY[] = "~/"; 25 26 26 27 27 class FAD: public EvidenceServer , public DimThread{28 class FAD: public EvidenceServer { 28 29 29 30 public: … … 39 40 void PrintUsage(); 40 41 void commandHandler(); 41 void threadHandler();42 42 virtual void exitHandler(int); 43 43 bool Match(std::string, const char *); … … 77 77 void cmd_phase(); void cmd_send(); 78 78 void cmd_stop(); void cmd_update(); 79 void cmd_take(); 79 void cmd_take(); void cmd_reconnect(); 80 80 81 81 void EnableDomino(); … … 89 89 90 90 int Pipe[2]; 91 int CommandPipe[2];92 91 int NumEventsRequested; // Number of events requested 93 92 std::vector<std::string> BoardList; -
fact/FADctrl/FADBoard.cc
r10128 r10164 11 11 // Constructor 12 12 // 13 FADBoard::FADBoard(string Server, unsigned short Port, class FAD *Parent, unsigned int Num) {13 FADBoard::FADBoard(string Server, unsigned short ServerPort, class FAD *Parent, unsigned int Num) { 14 14 15 15 int Ret; … … 17 17 // Initialization 18 18 m = Parent; 19 InitOK = false;20 19 Active = true; 21 20 Continue = true; 22 Comm Error= false;21 CommOK = false; 23 22 ACalibTime = -1; 24 23 Status.Update.tv_sec = -1; 24 Port = ServerPort; 25 25 26 26 Name = new char [Server.size()+1]; // Name in permanent memory for DIM service … … 42 42 } 43 43 44 // Resolve hostname45 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 descriptor52 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 server58 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 68 44 // Construct DIM service name prefix 69 45 stringstream ID; … … 76 52 DIM_ROI = new DimService((ID.str()+"ROI").c_str(), (char *) "S", NULL, 0); 77 53 78 // Create thread that receives data54 // Create thread that connects and receives data 79 55 if ((Ret = pthread_create(&Thread, NULL, (void * (*)(void *)) LaunchThread,(void *) this)) != 0) { 80 56 m->Message(m->FATAL, "pthread_create() failed in FADBoard() (%s)", strerror(Ret)); 81 57 } 82 58 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(); 89 61 } 90 62 … … 96 68 int Ret; 97 69 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; 123 83 delete[] Name; 124 125 // Close socket descriptor126 if ((Socket != -1) && (close(Socket) == -1)) {127 m->PrintMessage("Could not close socket descriptor (%s)", strerror(errno));128 }129 84 130 85 // Delete condition variable … … 145 100 void FADBoard::Send(const void *Data, size_t Bytes) { 146 101 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; 149 104 150 105 // Write data … … 357 312 358 313 // 359 // Read data from board314 // Connect to board and read data 360 315 // 361 316 void FADBoard::ReadLoop() { … … 365 320 const PEVNT_HEADER *Header = (PEVNT_HEADER *) Buffer; 366 321 ssize_t Result; 322 struct sockaddr_in SocketAddress; 367 323 struct BoardStatus PrevStatus; 368 324 int Ret; 369 325 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; 370 348 memset(&PrevStatus, 0, sizeof(PrevStatus)); 371 349 372 while (!m->ExitRequest) { 350 // Leave loop if program termination requested or board communication not OK 351 while (!m->ExitRequest && CommOK) { 373 352 // Read data from socket 374 353 Result = read(Socket, Buffer + Pos, sizeof(Buffer)-Pos); … … 377 356 if (Result == -1) { 378 357 m->PrintMessage("Error: Could not read from socket, exiting read loop (%s)\n", strerror(errno)); 379 Comm Error = true;358 CommOK = false; 380 359 break; 381 360 } 382 361 else if (Result == 0) { 383 362 m->PrintMessage("Server not existing anymore, exiting read loop\n"); 384 Comm Error = true;363 CommOK = false; 385 364 break; 386 365 } … … 490 469 } 491 470 } 492 else printf("End package flag incorrect, removing corrupt event\n");471 else m->PrintMessage("End package flag incorrect, removing corrupt event\n"); 493 472 494 473 // Inform event thread of new data … … 503 482 Pos = Pos-Length; 504 483 } // 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 505 490 } 506 491 … … 538 523 539 524 // 540 // Open OtherSockets()541 // 542 void FADBoard:: OpenOtherSockets(char *Hostname) {525 // Open other sockets 526 // 527 void FADBoard::threadHandler() { 543 528 544 529 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; 546 531 fd_set DescriptorList; 547 532 char Buffer[1000000]; 548 533 549 534 // Resolve hostname 550 struct hostent *Host = gethostbyname( Hostname);535 struct hostent *Host = gethostbyname(Name); 551 536 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); 553 538 return; 554 539 } … … 562 547 // Open socket descriptor 563 548 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)); 565 550 return; 566 551 } 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)); 570 553 571 554 // Connect to server 572 555 SocketAddress.sin_port = htons((unsigned short) List[i]); 573 556 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)); 575 558 return; 576 559 } … … 578 561 579 562 while(true) { 580 // Wait for data from terminal (stdin) or fromsockets563 // Wait for data from sockets 581 564 FD_ZERO(&DescriptorList); 582 565 for (unsigned int i=0; i<sizeof(List)/sizeof(int); i++) FD_SET(Socket[i], &DescriptorList); 583 566 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)); 585 568 break; 586 569 } … … 589 572 for (unsigned int i=0; i<sizeof(List)/sizeof(int); i++) if (FD_ISSET(Socket[i], &DescriptorList)) { 590 573 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)); 594 576 } 595 577 } … … 598 580 for (unsigned int i=0; i<sizeof(List)/sizeof(int); i++) { 599 581 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 13 13 #include <string.h> 14 14 #include <iostream> 15 #include <algorithm> 15 16 #include <sys/socket.h> 16 17 #include <netdb.h> … … 21 22 const unsigned int READ_BUFFER_SIZE = 1000000; 22 23 23 class FADBoard {24 class FADBoard: public DimThread { 24 25 25 26 class FAD *m; 26 27 int Socket; 27 pthread_t Thread, OtherThread;28 28 pthread_mutex_t Mutex; 29 29 DimService *DIM_Name, *DIM_ID, *DIM_Temp, *DIM_ROI, *DIM_DAC; … … 31 31 void ReadLoop(); 32 32 static void LaunchThread(class FADBoard *); 33 static void OpenOtherSockets(char *);33 void threadHandler(); 34 34 35 35 public: … … 65 65 void Unlock(); 66 66 67 unsigned short Port; 67 68 char *Name; 68 bool InitOK; 69 bool CommError; 69 bool CommOK; 70 70 bool Active; 71 71 bool Continue; 72 pthread_t Thread; 72 73 pthread_cond_t CondVar; 73 74 }; -
fact/FADctrl/FADctrl.cc
r10128 r10164 32 32 signal(SIGPIPE, SIG_IGN); 33 33 34 // Initialise all boards35 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 46 34 // Command loop 47 35 char *Command; … … 49 37 50 38 while (!M.ExitRequest) { 51 Command = readline("\rFADctrl> ");39 Command = readline("\rFADctrl> "); 52 40 53 41 // Check for interruption by signal … … 60 48 } 61 49 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); 64 52 free(Command); 65 53 } -
fact/FADctrl/History.txt
r10128 r10164 11 11 2/2/2011 Warning if amplitude calibration missing for data taking 12 12 4/2/2011 Fixed exitHandler() being stuck at pthread_join() 13 11/2/2011 Moved connect() call to thread of FADBoard class 14 14/2/2011 Moved initialisation commands to Evidence configuration file 15 18/2/2011 Added 'reconnect' command
Note:
See TracChangeset
for help on using the changeset viewer.