#ifdef SLS_RECEIVER_UDP_FUNCTIONS /********************************************//** * @file UDPRESTImplementation.cpp * @short does all the functions for a receiver, set/get parameters, start/stop etc. ***********************************************/ #include "UDPRESTImplementation.h" #include // exit() #include // set precision #include // map #include #include #include #include #include "logger.h" //#include "utilities.h" using namespace std; /* TODO + filePath != getFilePath + better state handling. Now it is only IDLE - RUNNING - IDLE */ UDPRESTImplementation::UDPRESTImplementation(){ FILE_LOG(logINFO) << "PID: " + __AT__ + " called"; //TODO I do not really know what to do with bottom... // Default values isInitialized = true; rest = NULL; rest_hostname = "localhost"; rest_port = 8080; is_main_receiver = false; } UDPRESTImplementation::~UDPRESTImplementation(){ delete rest; } void UDPRESTImplementation::configure(map config_map){ // am I ever getting there? FILE_LOG(logINFO) << __AT__ << "configure called"; map::const_iterator pos; pos = config_map.find("rest_hostname"); if (pos != config_map.end() ){ rest_hostname = config_map["rest_hostname"]; /* string host_port_str = pos->second; std::size_t pos = host_port_str.find(":"); // position of "live" in str if(pos != string::npos){ istringstream (host_port_str.substr (pos)) >> rest_port; rest_hostname = host_port_str.substr(0, pos); std::cout << "YEEEEEEEEEEEEEEEE" << rest_hostname << " " << rest_port << std::endl; } */ FILE_LOG(logINFO) << "REST hostname " << rest_hostname << std::endl; } //initialize_REST(); /* for(map::const_iterator i=config_map.begin(); i != config_map.end(); i++){ std::cout << i->first << " " << i->second<< std::endl; } */ } string UDPRESTImplementation::get_rest_state(RestHelper * rest/*, string *rest_state*/){ JsonBox::Value answer; string rest_state = ""; int code = rest->get_json("api/v1/state", &answer); if ( code != -1 ){ //rest_state = answer["global_state"].getString(); rest_state = answer["state"]["status"].getString(); } //rest_state = *prs; std::cout << "REST STATE " << rest_state << std::endl; return rest_state; } void UDPRESTImplementation::initialize_REST(){ FILE_LOG(logDEBUG1) << __AT__ << " called"; FILE_LOG(logINFO) << __AT__ << " REST status is initialized: " + std::string(isInitialized ? "True" : "False"); string rest_state = ""; std::string answer = ""; /* * HORRIBLE FIX to get the main receiver * TODO: use detID (from baseclass) * it i set by the client before calling initialize() */ string filename = getFileName(); int code; //if (filename.substr(filename.length() - 2) == "d0"){ if(detID == 0){ is_main_receiver = true; } if (rest_hostname.empty()) { FILE_LOG(logWARNING) << __AT__ << "can't initialize with empty string or NULL for detectorHostname"; throw; } rest = new RestHelper() ; //std::cout << rest_hostname << " - " << rest_port << std::endl; rest->init(rest_hostname); rest->set_connection_params(1, 3); FILE_LOG(logINFO) << "REST init called"; if (!is_main_receiver){ isInitialized = true; status = slsReceiverDefs::IDLE; return; } if (isInitialized == true) { FILE_LOG(logWARNING) << "already initialized, can't initialize several times"; } else { FILE_LOG(logINFO) << "with receiverHostName=" << rest_hostname; try{ rest_state = get_rest_state(rest); if (rest_state == ""){ FILE_LOG(logERROR) << " REST state returned: " << rest_state; throw; } else{ isInitialized = true; status = slsReceiverDefs::IDLE; } FILE_LOG(logDEBUG1) << "Answer: " << answer; } catch(std::string e){ FILE_LOG(logERROR) << __AT__ << ": " << e; throw; } // HORRIBLE FIX to get the main receiver string filename = getFileName(); int code; //JsonBox::Object json_object; //json_object["configfile"] = JsonBox::Value("FILENAME"); JsonBox::Value json_request; //json_request["configfile"] = "config.py"; json_request["path"] = filePath; stringstream ss; string test; //std::cout << "GetSTring: " << json_request << std::endl; json_request.writeToStream(ss, false); //ss << json_request; ss >> test; rest_state = get_rest_state(rest); //code = rest->get_json("api/v1/state", &answer); //FILE_LOG(logDEBUG1, __AT__ << " state got " + std::string(code) << " " + answer + "\n"; if (rest_state != "INITIALIZED"){ test = "{\"path\":\"" + string( getFilePath() ) + "\", \"n_frames\":10}"; code = rest->post_json("api/v1/initialize", &answer, test); } else{ test = "{\"path\":\"" + string( getFilePath() ) + "\"}"; test = "{\"path\":\"" + string( getFilePath() ) + "\", \"n_frames\":10}"; code = rest->post_json("api/v1/configure", &answer, test); } //FILE_LOG(logDEBUG1) << " state/configure got " + std::string(code); rest_state = get_rest_state(rest); FILE_LOG(logINFO) << " state got " + std::string(rest_state) << "\n"; /* std::std::cout << string << std::endl; << "---- REST test 3: true, json object "<< std::endl; JsonBox::Value json_value; code = rest.get_json("status", &json_value); std::cout << "JSON " << json_value["status"] << std::endl; */ } FILE_LOG(logDEBUG1) << ": configure() done"; } /** acquisition functions */ int UDPRESTImplementation::startReceiver(char message[]){ int i; FILE_LOG(logINFO) << __AT__ << " starting"; initialize_REST(); FILE_LOG(logINFO) << __AT__ << " initialized"; std::string answer; int code; //char *intStr = itoa(a); //string str = string(intStr); // TODO: remove hardcode!!! stringstream ss; ss << getDynamicRange(); string str_dr = ss.str(); stringstream ss2; ss2 << getNumberOfFrames(); string str_n = ss2.str(); stringstream ss3; ss3 << acquisitionPeriod; string sAP = ss3.str(); string rest_state = ""; std::string request_body = "{\"settings\": {\"bit_depth\": " + str_dr + ", \"n_frames\": " + str_n + ", \"period\": " + sAP + "}}"; //std::string request_body = "{\"settings\": {\"nimages\":1, \"scanid\":999, \"bit_depth\":16}}"; if(is_main_receiver){ FILE_LOG(logDEBUG1) << " sending this configuration body: " << request_body; code = rest->post_json("api/v1/configure", &answer, request_body); code = rest->get_json("api/v1/state", &answer); FILE_LOG(logDEBUG1) << " got: " << answer; rest_state = get_rest_state(rest); code = rest->post_json("api/v1/open", &answer); } status = RUNNING; return OK; } void UDPRESTImplementation::stopReceiver(){ FILE_LOG(logINFO) << "called"; if(status == RUNNING) startReadout(); /** * while(status == TRANSMITTING) * usleep(5000); * This has been changed, you check if all the threads are done processing * and set the final status */ //change status status = IDLE; FILE_LOG(logDEBUG1) << "exited, status IDLE"; } void UDPRESTImplementation::startReadout(){ FILE_LOG(logINFO) << " starting"; status = TRANSMITTING; //kill udp socket to tell the listening thread to push last packet shutDownUDPSockets(); FILE_LOG(logDEBUG1) << " done"; } /* FIXME * Its also called by TCP in case of illegal shut down such as Ctrl + c. * Upto you what you want to do with it. */ void UDPRESTImplementation::shutDownUDPSockets(){ FILE_LOG(logDEBUG1) << "called"; // this is just to be sure, it could be removed /* for(int i=0;iShutDownSocket(); delete udpSocket[i]; udpSocket[i] = NULL; } } */ JsonBox::Value answer; int code; string rest_state = ""; //FILE_LOG(logDEBUG1) << __AT__ << " numListeningThreads=" << numListeningThreads; if (rest == NULL){ FILE_LOG(logWARNING) << "No REST object initialized, closing..."; //return OK; } // getting the state if (is_main_receiver){ FILE_LOG(logWARNING) << "PLEASE WAIT WHILE CHECKING AND SHUTTING DOWN ALL CONNECTIONS!"; rest_state = get_rest_state(rest); std::cout << rest_state << std::endl; while (rest_state != "OPEN"){ rest_state = get_rest_state(rest); std::cout << rest_state << std::endl; usleep(1000000); } //while (rest_state != "TRANSIENT"){ // rest_state = get_rest_state(rest); // usleep(10000); //} code = rest->post_json("api/v1/close", &answer); rest_state = get_rest_state(rest); std::cout << rest_state << std::endl; while (rest_state != "CLOSED"){ rest_state = get_rest_state(rest); std::cout << rest_state << std::endl; usleep(1000000); } std::cout << "After close" << rest_state << std::endl; code = rest->post_json("api/v1/reset", &answer); //rest_state = get_rest_state(rest); std::cout << rest_state << std::endl; std::cout << "After reset" << rest_state << std::endl; } status = slsReceiverDefs::RUN_FINISHED; //LEO: not sure it's needed //delete rest; FILE_LOG(logDEBUG1) << "finished"; // Leo: how state is handled now? //return OK; } /* FIXME * do you really need this, this is called if registerDataCallback() is activated * in your gui to get data from receiver. you probably have a different way * of reconstructing complete data set from all receivers */ /* void UDPRESTImplementation::readFrame(char* c,char** raw, uint64_t &startAcq, uint64_t &startFrame){ FILE_LOG(logDEBUG1) << " called"; strcpy(c,""); *raw = NULL; } */ /* FIXME * Its called by TCP in case of illegal shut down such as Ctrl + c. * Upto you what you want to do with it. */ // Leo: not in the base class /* void UDPRESTImplementation::closeFiles(){ FILE_LOG(logDEBUG1) << "called for thread "; FILE_LOG(logDEBUG1) << "exited for thread "; } */ uint64_t UDPRESTImplementation::getTotalFramesCaught() const{ FILE_LOG(logDEBUG1) << " starting"; return (0); } #endif