void Messenger::StartAcquisition() { fPID = fork(); std::ostringstream os; int ret; try { switch (fPID) { case -1: throw Exception(__PRETTY_FUNCTION__, "Failed to fork the current process!", JustWarning); case 0: PrintInfo("Launching the daughter acquisition process"); ret = execl("ppsFetch", "", (char*)NULL); os.str(""); os << "Failed to launch the daughter process!" << "\n\t" << "Return value: " << ret << "\n\t" << "Errno: " << errno; throw Exception(__PRETTY_FUNCTION__, os.str(), JustWarning); default: break; } SendAll(DAQ, SocketMessage(ACQUISITION_STARTED)); // Send the run number to DQMonitors int last_run = -1; try { last_run = OnlineDBHandler().GetLastRun(); } catch (Exception& e) { last_run = -1; } try { SendAll(DQM, SocketMessage(RUN_NUMBER, last_run)); } catch (Exception& e) { e.Dump(); } throw Exception(__PRETTY_FUNCTION__, "Acquisition started!", Info, 30000); } catch (Exception& e) { e.Dump(); } }
void Client::Announce() { try { // Once connected we send our request for connection SendMessage(SocketMessage(ADD_CLIENT, static_cast<int>(GetType()))); // Then we wait for to the server to send us a connection acknowledgement // + an id SocketMessage ack(FetchMessage()); switch (ack.GetKey()) { case SET_CLIENT_ID: fClientId = ack.GetIntValue(); break; case INVALID_KEY: default: throw Exception(__PRETTY_FUNCTION__, "Received an invalid answer from server", JustWarning); } } catch (Exception& e) { e.Dump(); } std::cout << __PRETTY_FUNCTION__ << " connected to socket at port " << GetPort() << ", received id \"" << fClientId << "\""<< std::endl; }
void VMEReader::NewRun() const { if (!fOnSocket) return; Client::Send(SocketMessage(NEW_RUN)); std::ostringstream os; os << "New run detected: " << GetRunNumber(); Client::Send(Exception(__PRETTY_FUNCTION__, os.str(), JustWarning)); }
void VMEReader::SendOutputFile(uint32_t tdc_address) const { if (!fOnSocket) return; OutputFiles::const_iterator it = fOutputFiles.find(tdc_address); if (it!=fOutputFiles.end()) { std::ostringstream os; os << tdc_address << ":" << it->second; Client::Send(SocketMessage(SET_NEW_FILENAME, os.str())); } }
void Messenger::Disconnect() { if (fPort<0) return; // do not broadcast the death of a secondary messenger! try { Broadcast(SocketMessage(MASTER_DISCONNECT, "")); } catch (Exception& e) { e.Dump(); throw Exception(__PRETTY_FUNCTION__, "Failed to broadcast the server disconnection status!", JustWarning, SOCKET_ERROR(errno)); } Stop(); }
unsigned int VMEReader::GetRunNumber() const { if (!fOnSocket) return 0; SocketMessage msg; try { msg = Client::SendAndReceive(SocketMessage(GET_RUN_NUMBER), RUN_NUMBER); return static_cast<unsigned int>(msg.GetIntValue()); } catch (Exception& e) { e.Dump(); if (fOnSocket) Client::Send(e); } return 0; }
void Messenger::StopAcquisition() { signal(SIGCHLD, SIG_IGN); int ret = kill(fPID, SIGINT); if (ret<0) { std::ostringstream os; os << "Failed to kill the acquisition process with pid=" << fPID << "\n\t" << "Return value: " << ret << " (errno=" << errno << ")"; throw Exception(__PRETTY_FUNCTION__, os.str(), JustWarning); } SendAll(DAQ, SocketMessage(ACQUISITION_STOPPED)); throw Exception(__PRETTY_FUNCTION__, "Acquisition stop signal sent!", Info, 30001); }
void Client::Receive() { SocketMessage msg; try { msg = FetchMessage(); } catch (Exception& e) { if (e.ErrorNumber()==11000) // client has been disconnected throw Exception(__PRETTY_FUNCTION__, "Some other socket asked for this client's disconnection. Obtemperating...", Fatal); } if (msg.GetKey()==MASTER_DISCONNECT) { throw Exception(__PRETTY_FUNCTION__, "Master disconnected!", Fatal); } else if (msg.GetKey()==OTHER_CLIENT_DELETED) { throw Exception(__PRETTY_FUNCTION__, "Some other socket asked for this client's disconnection. Obtemperating...", Fatal); } else if (msg.GetKey()==GET_CLIENT_TYPE) { Send(SocketMessage(CLIENT_TYPE, static_cast<int>(GetType()))); } else if (msg.GetKey()==PING_CLIENT) { std::ostringstream os; os << "Pong. My name is " << GetSocketId() << " and I feel fine, thank you!"; Send(SocketMessage(PING_ANSWER, os.str())); PrintInfo("Got a ping, answering..."); } else if (msg.GetKey()==CLIENTS_LIST) { VectorValue vals = msg.GetVectorValue(); int i = 0; std::ostringstream o; o << "List of members on the socket:\n\t"; for (VectorValue::const_iterator v=vals.begin(); v!=vals.end(); v++, i++) { if (i!=0) o << ", "; o << *v; } PrintInfo(o.str()); } else { ParseMessage(msg); } }
void Messenger::AddClient() { Socket s; try { AcceptConnections(s); Message message = FetchMessage(s.GetSocketId()); SocketMessage m(message); if (m.GetKey()==ADD_CLIENT) { SocketType type = static_cast<SocketType>(m.GetIntValue()); if (type!=CLIENT) SwitchClientType(s.GetSocketId(), type); } // Send the client's unique identifier Send(SocketMessage(SET_CLIENT_ID, s.GetSocketId()), s.GetSocketId()); } catch (Exception& e) { e.Dump(); } }
void Client::Disconnect() { std::cout << "===> Disconnecting the client from socket" << std::endl; if (!fIsConnected) return; try { SendMessage(SocketMessage(REMOVE_CLIENT, fClientId), -1); } catch (Exception& e) { e.Dump(); } try { SocketMessage ack(FetchMessage()); if (ack.GetKey()==THIS_CLIENT_DELETED or ack.GetKey()==OTHER_CLIENT_DELETED) { fIsConnected = false; } } catch (Exception& e) { if (e.ErrorNumber()!=11000) // client has been disconnected e.Dump(); else return; } }
void Messenger::Receive() { Message msg; SocketMessage m; // We start by copying the master file descriptors list to the // temporary list for readout fReadFds = fMaster; try { SelectConnections(); } catch (Exception& e) { e.Dump(); throw Exception(__PRETTY_FUNCTION__, "Impossible to select the connections!", Fatal); } // Looking for something to read! for (SocketCollection::const_iterator s=fSocketsConnected.begin(); s!=fSocketsConnected.end(); s++) { if (!FD_ISSET(s->first, &fReadFds)) continue; // First check if we need to handle new connections if (s->first==GetSocketId()) { AddClient(); return; } // Handle data from a client try { msg = FetchMessage(s->first); } catch (Exception& e) { //std::cout << "exception found..." << e.OneLine() << ", "<< e.ErrorNumber() << std::endl; e.Dump(); if (e.ErrorNumber()==11000) { DisconnectClient(s->first, THIS_CLIENT_DELETED); return; } } m = SocketMessage(msg.GetString()); // Message was successfully decoded fNumAttempts = 0; try { ProcessMessage(m, s->first); } catch (Exception& e) { if (e.ErrorNumber()==11001) break; } } }
void VMEReader::BroadcastHVStatus(unsigned short channel_id, const NIM::HVModuleN470ChannelValues& val) const { std::ostringstream os; os << channel_id << ":" << val.ChannelStatus() << "," << val.Imon() << "," << val.Vmon(); Client::Send(SocketMessage(HV_STATUS, os.str())); }
void VMEReader::BroadcastTriggerRate(unsigned int burst_id, unsigned long num_triggers) const { std::ostringstream os; os << burst_id << ":" << num_triggers; Client::Send(SocketMessage(NUM_TRIGGERS, os.str())); }
// Function responsible of performing the operations of the class. void NetworkOperator::_operate() { std::vector<unsigned int> pending_close_sockets(0,NULL); unsigned int buffer_size_to_use = sizeof(DawnEngine::Network::Message); char buffer[sizeof(DawnEngine::Network::Message)]; DawnEngine::Network::Message message; #ifndef NETWORK_OPERATOR_NO_LOGGING DawnEngine::IO::LogManagerA* log_manager_a = DawnEngine::IO::LogManagerA::get(); DawnEngine::IO::LogManagerW* log_manager_w = DawnEngine::IO::LogManagerW::get(); #endif /* NETWORK_OPERATOR_NO_LOGGING */ unsigned int counter = 0; _socket_lock.acquire_shared(); counter = 0; while ( counter < _pending_connection_sockets.size() ) { if ( _pending_connection_sockets[counter] > 0 ) { std::map<unsigned int,SocketStatus>::iterator socket_iterator(_sockets.find(_pending_connection_sockets[counter])); if ( socket_iterator != _sockets.end() && socket_iterator->second.first != NULL && !socket_iterator->second.second ) { if ( socket_iterator->second.first->connect() ) { std::deque<unsigned int>::iterator pending_socket_iterator(_pending_connection_sockets.begin() + counter); if ( pending_socket_iterator != _pending_connection_sockets.end() ) { #ifndef NETWORK_OPERATOR_NO_LOGGING if ( log_manager_a != NULL ) log_manager_a->log_message("TCP Socket with ID %u connected to %s:%u",_pending_connection_sockets[counter],socket_iterator->second.first->address().c_str(),socket_iterator->second.first->port()); if ( log_manager_w != NULL ) log_manager_w->log_message(L"TCP Socket with ID %u connected.",_pending_connection_sockets[counter]); #endif /* NETWORK_OPERATOR_NO_LOGGING */ _pending_connection_sockets.erase(pending_socket_iterator); socket_iterator->second.second = true; } } else { std::deque<unsigned int>::iterator pending_socket_iterator(_pending_connection_sockets.begin() + counter); int error_code = socket_iterator->second.first->last_error(); bool remove = false; if ( error_code != WSAEWOULDBLOCK && error_code != WSAECONNREFUSED && error_code != WSAEISCONN && error_code != WSAEALREADY ) { #ifndef NETWORK_OPERATOR_NO_LOGGING if ( log_manager_a ) log_manager_a->log_error("TCP Socket with ID %u connect error with code %i.",_pending_connection_sockets[counter],error_code); if ( log_manager_w ) log_manager_w->log_error(L"TCP Socket with ID %u connect error with code %i.",_pending_connection_sockets[counter],error_code); #endif /* NETWORK_OPERATOR_NO_LOGGING */ remove = true; } else if ( error_code == WSAEISCONN ) { #ifndef NETWORK_OPERATOR_NO_LOGGING if ( log_manager_a != NULL ) log_manager_a->log_message("TCP Socket with ID %u connected to %s:%u",_pending_connection_sockets[counter],socket_iterator->second.first->address().c_str(),socket_iterator->second.first->port()); if ( log_manager_w != NULL ) log_manager_w->log_message(L"TCP Socket with ID %u connected.",_pending_connection_sockets[counter]); #endif /* NETWORK_OPERATOR_NO_LOGGING */ socket_iterator->second.second = true; remove = true; } else ++counter; if ( remove && pending_socket_iterator != _pending_connection_sockets.end() ) _pending_connection_sockets.erase(pending_socket_iterator); } } else { std::deque<unsigned int>::iterator pending_socket_iterator(_pending_connection_sockets.begin() + counter); if ( pending_socket_iterator != _pending_connection_sockets.end() ) _pending_connection_sockets.erase(pending_socket_iterator); } } else { std::deque<unsigned int>::iterator pending_socket_iterator(_pending_connection_sockets.begin() + counter); if ( pending_socket_iterator != _pending_connection_sockets.end() ) _pending_connection_sockets.erase(pending_socket_iterator); } } _send_lock.acquire(); counter = 0; while ( counter < _send_queue.size() ) { bool remove = false; if ( _send_queue[counter].first > 0 ) { std::vector<unsigned int>::iterator pending_close_iterator = pending_close_sockets.begin(); std::map<unsigned int,SocketStatus>::iterator socket_iterator(_sockets.find(_send_queue[counter].first)); bool found = false; while ( !found && pending_close_iterator != pending_close_sockets.end() ) { if ( (*pending_close_iterator) == _send_queue[counter].first ) found = true; else ++pending_close_iterator; } if ( !found && socket_iterator != _sockets.end() ) { if ( socket_iterator->first != NULL ) { if ( socket_iterator->second.second ) { unsigned long remaining_bytes = buffer_size_to_use; int exit_code = 0; char* temp_buffer = buffer; memset(buffer,'\0',buffer_size_to_use); memcpy(buffer,&(_send_queue[counter].second),buffer_size_to_use); while ( exit_code != ERROR_CODE && remaining_bytes > 0 ) { exit_code = socket_iterator->second.first->send(temp_buffer,remaining_bytes,NULL); if ( exit_code == ERROR_CODE ) { int error_code = socket_iterator->second.first->last_error(); if ( error_code != WSAEWOULDBLOCK && error_code != WSAETIMEDOUT ) { #ifndef NETWORK_OPERATOR_NO_LOGGING if ( log_manager_a != NULL ) log_manager_a->log_error("Send on socket with ID %u failed with error %u. Socket will be closed.",_send_queue[counter].first,error_code); if ( log_manager_w != NULL ) log_manager_w->log_error(L"Send on socket with ID %u failed with error %u. Socket will be closed.",_send_queue[counter].first,error_code); #endif /* NETWORK_OPERATOR_NO_LOGGING */ pending_close_sockets.push_back(_send_queue[counter].first); } } else { remaining_bytes -= std::min(remaining_bytes,static_cast<unsigned long>(exit_code)); temp_buffer += exit_code; } } remove = true; } } else remove = true; } else remove = true; } else { for ( std::map<unsigned int,SocketStatus>::iterator socket_iterator = _sockets.begin(); socket_iterator != _sockets.end(); ++socket_iterator ) { std::vector<unsigned int>::iterator pending_close_iterator = pending_close_sockets.begin(); bool found = false; while ( !found && pending_close_iterator != pending_close_sockets.end() ) { if ( (*pending_close_iterator) == socket_iterator->first ) found = true; else ++pending_close_iterator; } if ( !found && socket_iterator->second.second && socket_iterator->second.first != NULL ) { unsigned long remaining_bytes = buffer_size_to_use; int exit_code = 0; char* temp_buffer = buffer; memset(buffer,'\0',buffer_size_to_use); memcpy(buffer,&(_send_queue[counter].second),buffer_size_to_use); while ( exit_code != ERROR_CODE && remaining_bytes > 0 ) { exit_code = socket_iterator->second.first->send(temp_buffer,remaining_bytes,NULL); if ( exit_code == ERROR_CODE ) { int error_code = socket_iterator->second.first->last_error(); if ( error_code != WSAEWOULDBLOCK && error_code != WSAETIMEDOUT ) { #ifndef NETWORK_OPERATOR_NO_LOGGING if ( log_manager_a != NULL ) log_manager_a->log_error("Send on socket with ID %u failed with error %u. Socket will be closed.",socket_iterator->first,error_code); if ( log_manager_w != NULL ) log_manager_w->log_error(L"Send on socket with ID %u failed with error %u. Socket will be closed.",socket_iterator->first,error_code); #endif /* NETWORK_OPERATOR_NO_LOGGING */ pending_close_sockets.push_back(socket_iterator->first); } } else { remaining_bytes -= std::min(remaining_bytes,static_cast<unsigned long>(exit_code)); temp_buffer += exit_code; if ( exit_code == 0 ) { exit_code = ERROR_CODE; pending_close_sockets.push_back(socket_iterator->first); } } } } } remove = true; } if ( remove ) { std::deque<SocketMessage>::iterator message_iterator(_send_queue.begin() + counter); if ( message_iterator != _send_queue.end() ) _send_queue.erase(message_iterator); else ++counter; } else ++counter; } _send_lock.release(); _receive_lock.acquire(); for ( std::map<unsigned int,SocketStatus>::iterator socket_iterator = _sockets.begin(); socket_iterator != _sockets.end(); ++socket_iterator ) { std::vector<unsigned int>::iterator pending_close_iterator = pending_close_sockets.begin(); bool found = false; while ( !found && pending_close_iterator != pending_close_sockets.end() ) { if ( (*pending_close_iterator) == socket_iterator->first ) found = true; else ++pending_close_iterator; } if ( !found && socket_iterator->second.second && socket_iterator->second.first != NULL ) { unsigned long remaining_bytes = buffer_size_to_use; int exit_code = 0; char* temp_buffer = buffer; bool closed = false; while ( exit_code != ERROR_CODE ) { memset(buffer,'\0',buffer_size_to_use); temp_buffer = buffer; remaining_bytes = buffer_size_to_use; exit_code = 0; while ( exit_code != ERROR_CODE && remaining_bytes > 0 ) { exit_code = socket_iterator->second.first->receive(buffer,remaining_bytes,NULL); if ( exit_code == ERROR_CODE ) { int error_code = socket_iterator->second.first->last_error(); if ( error_code != WSAEWOULDBLOCK && error_code != WSAETIMEDOUT ) { #ifndef NETWORK_OPERATOR_NO_LOGGING if ( log_manager_a ) log_manager_a->log_error("Receive on socket with ID %u failed. Socket will be closed.",socket_iterator->first); if ( log_manager_w != NULL ) log_manager_w->log_error(L"Receive on socket with ID %u failed. Socket will be closed.",socket_iterator->first); #endif /* NETWORK_OPERATOR_NO_LOGGING */ closed = true; } } else { remaining_bytes -= std::min(remaining_bytes,static_cast<unsigned long>(exit_code)); temp_buffer += exit_code; if ( exit_code == 0 ) { DawnEngine::Network::SocketProtocol type = socket_iterator->second.first->protocol(); if ( type == DawnEngine::Network::SOCKET_TCP_V4 || type == DawnEngine::Network::SOCKET_TCP_V6 ) { exit_code = ERROR_CODE; closed = true; } else exit_code = ERROR_CODE; } } } if ( remaining_bytes == 0 ) { memset(&message,'\0',buffer_size_to_use); memcpy(&message,buffer,buffer_size_to_use); _receive_queue.push_back(SocketMessage(socket_iterator->first,message)); } else if ( closed ) { memset(&message,'\0',buffer_size_to_use); message.message_code = ERROR_CODE; _receive_queue.push_back(SocketMessage(socket_iterator->first,message)); pending_close_sockets.push_back(socket_iterator->first); } } } } _receive_lock.release(); for ( std::vector<unsigned int>::iterator socket_iterator = pending_close_sockets.begin(); socket_iterator != pending_close_sockets.end(); ++socket_iterator ) _close_socket((*socket_iterator)); pending_close_sockets.clear(); _socket_lock.release_shared(); };
void Messenger::ProcessMessage(SocketMessage m, int sid) { if (m.GetKey()==REMOVE_CLIENT) { if (m.GetIntValue()==GetSocketId()) { std::ostringstream o; o << "Some client (id=" << sid << ") asked for this master's disconnection!" << "\n\tIgnoring this request..."; throw Exception(__PRETTY_FUNCTION__, o.str(), JustWarning); return; } const MessageKey key = (sid==m.GetIntValue()) ? THIS_CLIENT_DELETED : OTHER_CLIENT_DELETED; DisconnectClient(m.GetIntValue(), key); throw Exception(__PRETTY_FUNCTION__, "Removing socket client", Info, 11001); } else if (m.GetKey()==PING_CLIENT) { const int toping = m.GetIntValue(); Send(SocketMessage(PING_CLIENT), toping); SocketMessage msg; int i=0; do { msg = FetchMessage(toping); i++; } while (msg.GetKey()!=PING_ANSWER && i<MAX_SOCKET_ATTEMPTS); try { Send(SocketMessage(PING_ANSWER, msg.GetValue()), sid); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==GET_CLIENTS) { int i = 0; std::ostringstream os; for (SocketCollection::const_iterator it=fSocketsConnected.begin(); it!=fSocketsConnected.end(); it++, i++) { if (i!=0) os << ";"; os << it->first << " (type " << static_cast<int>(it->second) << ")"; } try { Send(SocketMessage(CLIENTS_LIST, os.str()), sid); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==WEB_GET_CLIENTS) { int i = 0; SocketType type; std::ostringstream os; for (SocketCollection::const_iterator it=fSocketsConnected.begin(); it!=fSocketsConnected.end(); it++, i++) { type = (it->first==GetSocketId()) ? MASTER : it->second; if (i!=0) os << ";"; os << it->first << ","; if (it->first==GetSocketId()) os << "Master,"; else os << "Client" << it->first << ","; os << static_cast<int>(type) << "\0"; } try { Send(SocketMessage(CLIENTS_LIST, os.str()), sid); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==START_ACQUISITION) { try { StartAcquisition(); } catch (Exception& e) { e.Dump(); SendAll(DAQ, e); } } else if (m.GetKey()==STOP_ACQUISITION) { try { StopAcquisition(); } catch (Exception& e) { e.Dump(); SendAll(DAQ, e); } } else if (m.GetKey()==NEW_RUN) { try { OnlineDBHandler().NewRun(); int last_run = OnlineDBHandler().GetLastRun(); SendAll(DQM, SocketMessage(RUN_NUMBER, last_run)); SendAll(DAQ, SocketMessage(RUN_NUMBER, last_run)); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==GET_RUN_NUMBER) { int last_run = 0; try { last_run = OnlineDBHandler().GetLastRun(); } catch (Exception& e) { last_run = -1; } try { Send(SocketMessage(RUN_NUMBER, last_run), sid); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==SET_NEW_FILENAME) { try { std::cout << "---> " << m.GetValue() << std::endl; SendAll(DQM, SocketMessage(NEW_FILENAME, m.GetValue().c_str())); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==NUM_TRIGGERS or m.GetKey()==HV_STATUS) { try { SendAll(DAQ, m); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==NEW_DQM_PLOT or m.GetKey()==UPDATED_DQM_PLOT) { try { SendAll(DAQ, m); } catch (Exception& e) { e.Dump(); } } else if (m.GetKey()==EXCEPTION) { try { SendAll(DAQ, m); std::cout << "--> " << m.GetValue() << std::endl; } catch (Exception& e) { e.Dump(); } } /*else { try { Send(SocketMessage(INVALID_KEY), sid); } catch (Exception& e) { e.Dump(); } std::ostringstream o; o << "Received an invalid message: " << m.GetString(); throw Exception(__PRETTY_FUNCTION__, o.str(), JustWarning); }*/ }