//============================================================================= // TIMIQCurl.cpp //============================================================================= // abstraction.......TIMIQCurl Low level access to TIMIQ hardware // class.............TIMIQCurl // original author...J. GOUNO - NEXEYA-FRANCE //============================================================================= // ============================================================================ // DEPENDENCIES // ============================================================================ #include "TIMIQCurl.h" #include <iostream> #include <string.h> #include <yat/utils/StringTokenizer.h> #include <yat/utils/XString.h> namespace TIMIQLib_ns { // ============================================================================ // static variables & functions // ============================================================================ //- timiq internal web buffer static std::string m_timiq_internal_buff; // ---------------------------------------------------------------------------- // write callback functions // @param buffer data , size*nmemb buffer size, void userp // @return size*nmemb buffer size // ---------------------------------------------------------------------------- static size_t write_callback( char *buffer, size_t size, size_t nmemb, void* ) { // std::cout<<"static size_t write_callback <"<<size<<"> nmemb<"<<nmemb<<">"<<std::endl; for (size_t idx = 0; idx < size*nmemb; idx++ ) m_timiq_internal_buff.push_back(buffer[idx]); return size*nmemb; } // ============================================================================ // TIMIQCurl::TIMIQCurl // ============================================================================ TIMIQCurl::TIMIQCurl(const std::string& ip_address, const std::string& num_port) { //std::cout << "TIMIQCurl constructor" << std::endl; m_base_addr = kHTTP_WEB_PROTOCOL + ip_address + ":"+ num_port; m_error_string = ""; #if !defined (_SIMULATION_) m_hw_curl = NULL; m_thr_hw_curl = NULL; curl_global_init(CURL_GLOBAL_ALL); #endif #if defined (_SIMULATION_) m_sim_ival = 0.0; m_sim_qval = 0.0; #endif } // ============================================================================ // TIMIQCurl::~TIMIQCurl // ============================================================================ TIMIQCurl::~TIMIQCurl () { #if !defined (_SIMULATION_) if (m_hw_curl) { //- clean up curl_easy_cleanup(m_hw_curl); m_hw_curl = NULL; } if (m_thr_hw_curl) { //- clean up curl_easy_cleanup(m_thr_hw_curl); m_thr_hw_curl = NULL; } curl_global_cleanup(); #endif } // ============================================================================ // TIMIQCurl::write_data // ============================================================================ E_timiq_errno_t TIMIQCurl::write_data(float& data) { E_timiq_errno_t err_num = timiq_internal_ERROR; char buff[kMAX_DATA_SIZE]; memset(buff, 0, sizeof(buff)); sprintf(buff, "%s=%2.3f", (char*)kTIMIQ_DATA_KEY.c_str(), data); std::string strbuff(buff); //- request to the web page // http://address/set_data std::string str_url = m_base_addr + kTIMIQ_DATA_PAGE+ "?" + strbuff; if (this->write_i(str_url, strbuff)) err_num = timiq_NO_ERROR; return err_num; } // ============================================================================ // TIMIQCurl::write_iValue // ============================================================================ E_timiq_errno_t TIMIQCurl::write_iValue(float& iValue) { // std::cout << "TIMIQCurl::write_iValue() write iValue = " << iValue << std::endl; E_timiq_errno_t err_num = timiq_internal_ERROR; char buff[kMAX_DATA_SIZE]; memset(buff, 0, sizeof(buff)); sprintf(buff, "%s=%1.6f", kTIMIQ_IVALUE_KEY.c_str() , iValue); std::string strbuff(buff); //- request to the web page // http://address/set_iValue std::string str_url = m_base_addr + kTIMIQ_IVALUE_PAGE + "?" + strbuff; if (this->write_i(str_url, strbuff)) err_num = timiq_NO_ERROR; #if defined (_SIMULATION_) m_sim_ival = iValue; #endif return err_num; } // ============================================================================ // TIMIQCurl::write_qValue // ============================================================================ E_timiq_errno_t TIMIQCurl::write_qValue(float& qValue) { //std::cout << "TIMIQCurl::write_qValue() write qValue = " << qValue << std::endl; E_timiq_errno_t err_num = timiq_internal_ERROR; char buff[kMAX_DATA_SIZE]; memset(buff, 0, sizeof (buff)); sprintf(buff, "%s=%1.6f", kTIMIQ_QVALUE_KEY.c_str(), qValue); std::string strbuff(buff); //- request to the web page // http://address/set_qValue std::string str_url = m_base_addr + kTIMIQ_QVALUE_PAGE + "?" + strbuff; if (this->write_i(str_url, strbuff)) err_num = timiq_NO_ERROR; #if defined (_SIMULATION_) m_sim_qval = qValue; #endif return err_num; } // ============================================================================ // TIMIQCurl::write_boardTemperature // ============================================================================ E_timiq_errno_t TIMIQCurl::write_boardTemperature(float& boardTemperature) { E_timiq_errno_t err_num = timiq_internal_ERROR; char buff[kMAX_DATA_SIZE]; memset(buff, 0, sizeof (buff)); sprintf(buff, "%s=%2.3f", kTIMIQ_BOARD_TEMPERATURE_KEY.c_str(), boardTemperature); std::string strbuff(buff); //- request to the web page // http://address/set_boardTemperature.wsgi std::string str_url = m_base_addr + kTIMIQ_BOARD_TEMPERATURE_PAGE + "?" + strbuff; if (this->write_i(str_url, strbuff)) err_num = timiq_NO_ERROR; return err_num; } // ============================================================================ // TIMIQCurl::write_command // ============================================================================ E_timiq_errno_t TIMIQCurl::write_command(E_timiq_cmd_t& cmd, bool thr) { E_timiq_errno_t err_num = timiq_internal_ERROR; char buff[kMAX_DATA_SIZE]; memset(buff, 0, sizeof(buff)); sprintf(buff, "%s=%d", kTIMIQ_COMMAND_KEY.c_str(), (unsigned short)cmd); std::string strbuff(buff); //- request to the web page // http://address/set_command std::string str_url = m_base_addr + kTIMIQ_COMMAND_PAGE + "?" + strbuff; if (this->write_i(str_url, strbuff, thr)) err_num = timiq_NO_ERROR; #if defined (_SIMULATION_) m_sim_ival = 0.0; m_sim_qval = 0.0; #endif return err_num; } // ============================================================================ // TIMIQCurl::read_data // ============================================================================ E_timiq_errno_t TIMIQCurl::read_data(float& data) { E_timiq_errno_t err_num = timiq_internal_ERROR; //- request to the web page // http://address/get_data.wsgi std::string str_url = m_base_addr + kTIMIQ_DATA_PAGE; if (this->read_float_i(str_url, kTIMIQ_DATA_KEY, data)) err_num = timiq_NO_ERROR; return err_num; } // ============================================================================ // TIMIQCurl::read_iValue // ============================================================================ E_timiq_errno_t TIMIQCurl::read_iValue(float& iValue) { E_timiq_errno_t err_num = timiq_internal_ERROR; //- request to the web page // http://address/get_feedback.wsgi std::string str_url = m_base_addr + kTIMIQ_FEEDBACK_PAGE; if (this->read_float_i(str_url, kTIMIQ_IVALUE_KEY, iValue)) err_num = timiq_NO_ERROR; return err_num; } // ============================================================================ // TIMIQCurl::read_qValue // ============================================================================ E_timiq_errno_t TIMIQCurl::read_qValue(float& qValue) { E_timiq_errno_t err_num = timiq_internal_ERROR; //- request to the web page // http://address/get_feedback.wsgi std::string str_url = m_base_addr + kTIMIQ_FEEDBACK_PAGE; if (this->read_float_i(str_url, kTIMIQ_QVALUE_KEY, qValue)) err_num = timiq_NO_ERROR; return err_num; } // ============================================================================ // TIMIQCurl::read_mixerCosOutput // ============================================================================ E_timiq_errno_t TIMIQCurl::read_mixerCosOutput(float& mixerCosOutput) { E_timiq_errno_t err_num = timiq_internal_ERROR; //- request to the web page //- http://address/get_feedback.wsgi std::string str_url = m_base_addr + kTIMIQ_FEEDBACK_PAGE; if (this->read_float_i(str_url, kTIMIQ_MIXER_COS_OUTPUT_KEY, mixerCosOutput)) err_num = timiq_NO_ERROR; return err_num; } // ============================================================================ // TIMIQCurl::read_mixerSinOutput // ============================================================================ E_timiq_errno_t TIMIQCurl::read_mixerSinOutput(float& mixerSinOutput) { E_timiq_errno_t err_num = timiq_internal_ERROR; //- request to the web page //- http://address/get_feedback.wsgi std::string str_url = m_base_addr + kTIMIQ_FEEDBACK_PAGE; if (this->read_float_i(str_url, kTIMIQ_MIXER_SIN_OUTPUT_KEY, mixerSinOutput)) err_num = timiq_NO_ERROR; return err_num; } // ============================================================================ // TIMIQCurl::read_boardTemperature // ============================================================================ E_timiq_errno_t TIMIQCurl::read_boardTemperature(float& boardTemperature) { E_timiq_errno_t err_num = timiq_internal_ERROR; //- request to the web page //- http://address/get_feedback.wsgi std::string str_url = m_base_addr + kTIMIQ_FEEDBACK_PAGE; if (this->read_float_i(str_url, kTIMIQ_BOARD_TEMPERATURE_KEY, boardTemperature)) err_num = timiq_NO_ERROR; return err_num; } // ============================================================================ // TIMIQCurl::read_all // ============================================================================ E_timiq_errno_t TIMIQCurl::read_all(timIQval_t& val) { E_timiq_errno_t err_num = timiq_internal_ERROR; //- request to the web page //- http://address/get_feedback.wsgi std::string str_url = m_base_addr + kTIMIQ_FEEDBACK_PAGE; if (this->read_all_i(str_url, val)) err_num = timiq_NO_ERROR; return err_num; } // ============================================================================ // TIMIQCurl::read_state_and_status // ============================================================================ E_timiq_errno_t TIMIQCurl::read_state_and_status(std::string& status, E_timiq_code_t& codeRet) { E_timiq_errno_t err_num = timiq_internal_ERROR; //- request to the web page //- http://address/get_state.wsgi std::string str_url = m_base_addr + kTIMIQ_STATE_PAGE; if (this->read_state_and_status_i(str_url, status, codeRet)) err_num = timiq_NO_ERROR; return err_num; } // ============================================================================ // TIMIQCurl::connect_i // ============================================================================ E_timiq_errno_t TIMIQCurl::connect_i(bool thr) { E_timiq_errno_t err_num = timiq_internal_ERROR; m_error_string = ""; #if !defined (_SIMULATION_) // according to flag, initialize "standard" or "threaded" curl reference if (thr) { // use threaded reference try { if (!m_thr_hw_curl) { m_thr_hw_curl = curl_easy_init(); if (m_thr_hw_curl) { err_num = timiq_NO_ERROR; } else { m_error_string = "INTERNAL_ERROR\n"; m_error_string += "TIMIQ WebServer access is not available, null pointer detected for threaded ref!\n"; m_error_string += "TIMIQCurl::connect()"; } } else { m_error_string = "TIMIQ WebServer access allows only single session for threaded ref!\n"; m_error_string += "TIMIQCurl::connect()"; } } catch (...) { m_error_string = "TIMIQCurl::connect: exception while initializing Webserver for threaded ref..."; m_thr_hw_curl = NULL; } } else { // use non threaded reference try { if (!m_hw_curl) { m_hw_curl = curl_easy_init(); if (m_hw_curl) { err_num = timiq_NO_ERROR; } else { m_error_string = "INTERNAL_ERROR\n"; m_error_string += "TIMIQ WebServer access is not available, null pointer detected for standard ref!\n"; m_error_string += "TIMIQCurl::connect()"; } } else { m_error_string = "TIMIQ WebServer access allows only single session for standard ref!\n"; m_error_string += "TIMIQCurl::connect()"; } } catch (...) { m_error_string = "TIMIQCurl::connect: exception while initializing Webserver for standard ref..."; m_hw_curl = NULL; } } return err_num; #else return timiq_NO_ERROR; #endif } // ============================================================================ // TIMIQCurl::write_i // ============================================================================ bool TIMIQCurl::write_i(std::string& url, std::string& strData, bool thr) { #if !defined (_SIMULATION_) //- CURL easy return code CURLcode result; m_error_string = ""; //- no connection is possible if (this->connect_i(thr) != timiq_NO_ERROR) return false; try { result = send_to_webserver_i(url, thr); } catch (...) { m_error_string = "TIMIQCurl::write_i: exception while writing data on" + url; return false; } //- check the result //---------------------------- if (result != CURLE_OK) { //- HTTP error m_error_string = m_timiq_internal_buff; return false; } else //- check the data returned { std::size_t found = m_timiq_internal_buff.find(strData); if (found != std::string::npos) { m_error_string = "OK"; return true; } else { //- otherwise error m_error_string = m_timiq_internal_buff; } } return false; #else m_error_string = "OK"; m_timiq_internal_buff = "\ncommand=1\n"; m_timiq_internal_buff += "command=2\n"; m_timiq_internal_buff += "command=3\n"; m_timiq_internal_buff += "iValue=-0.000001\n"; m_timiq_internal_buff += "qValue=-0.000002"; return true; #endif } // ============================================================================ // TIMIQCurl::read_float_i // ============================================================================ bool TIMIQCurl::read_float_i(const std::string& url, const std::string& strData, float& value) { // std::cout <<"TIMIQCurl::read_float_i"<<std::endl; #if !defined (_SIMULATION_) //- CURL easy return code CURLcode result; m_error_string = ""; //- no connection is possible if (this->connect_i() != timiq_NO_ERROR) return false; try { result = send_to_webserver_i(url); } catch (...) { m_error_string = "TIMIQCurl::read_float_i: exception while reading data on " + url; return false; } //- check the result //---------------------------- if (result != CURLE_OK) { //- HTTP error char buff[kMAX_DATA_SIZE]; memset(buff, 0, sizeof(buff)); sprintf (buff, "TIMIQCurl::read_float_i - CURL code error <%d>",result); m_error_string = buff; return false; } else //- check the data returned { #else m_timiq_internal_buff = "\niValue=-0.000001\n"; m_timiq_internal_buff += "qValue=0.000002\n"; m_timiq_internal_buff += "mixerSinOutput=3.100000\n"; m_timiq_internal_buff += "mixerCosOutput=0.154600\n"; m_timiq_internal_buff += "boardTemperature=20.154"; #endif std::size_t index = m_timiq_internal_buff.find(strData); if (index != std::string::npos) { //- extract substring from index std::string l_subStr = m_timiq_internal_buff.substr(index); //- parse "=" yat::StringTokenizer tokfloatStr (l_subStr, "="); try { //- field std::string fieldStr = tokfloatStr.next_token(); //- value std::string floatStr = tokfloatStr.next_token(); //- convert data to float value = (float)yat::XString<float>::to_num(floatStr); } catch(...) { m_error_string = "TIMIQCurl::read_float_i: exception while converting data from " + url; m_error_string += m_timiq_internal_buff; return false; } //- success m_error_string = "OK"; return true; } //- otherwise error m_error_string = m_timiq_internal_buff; #if !defined (_SIMULATION_) } #endif return false; } // ============================================================================ // TIMIQCurl::read_state_and_status_i // ============================================================================ bool TIMIQCurl::read_state_and_status_i(const std::string& url, std::string& status, E_timiq_code_t& codeRet) { #if !defined (_SIMULATION_) //- CURL easy return code CURLcode result; m_error_string = ""; //- no connection is possible if (this->connect_i() != timiq_NO_ERROR) return false; try { result = send_to_webserver_i(url); } catch (...) { m_error_string = "TIMIQCurl::read_status_i: exception while reading TimIQ status on " + url; return false; } //- check the result //---------------------------- if (result != CURLE_OK) { //- HTTP error char buff[kMAX_DATA_SIZE]; memset(buff, 0, sizeof(buff)); sprintf (buff, "TIMIQCurl::read_state_and_status_i - CURL code error <%d>",result); m_error_string = buff; return false; } else //- check the data returned { #else m_timiq_internal_buff="message=System up and running\n"; m_timiq_internal_buff+="state=OK\n"; m_timiq_internal_buff+="code=1\n"; #endif bool b_found = true; //- key word: message std::size_t found = m_timiq_internal_buff.find(kTIMIQ_MESSAGE_KEY); b_found = (found != std::string::npos); //- key word: state found = m_timiq_internal_buff.find(kTIMIQ_STATE_KEY); b_found &=(found != std::string::npos); //- key word: code found = m_timiq_internal_buff.find(kTIMIQ_CODE_KEY); b_found &=(found != std::string::npos); if (b_found) { //- extract the code value std::string strCode = m_timiq_internal_buff.substr(found); //- parse "=" yat::StringTokenizer tokKeyword (strCode, "="); try { //- field std::string fieldStr = tokKeyword.next_token(); //- value codeRet = (E_timiq_code_t) tokKeyword.next_int_token(); } catch(...) { m_error_string = "TIMIQCurl::read_state_and_status_i: exception while converting code from " + url; m_error_string += m_timiq_internal_buff; return false; } status = m_timiq_internal_buff; m_error_string = "OK"; return true; } //- otherwise error m_error_string = m_timiq_internal_buff; #if !defined (_SIMULATION_) } #endif return false; } // ============================================================================ // TIMIQCurl::read_all_i // ============================================================================ bool TIMIQCurl::read_all_i(const std::string& url, timIQval_t& values) { #if !defined (_SIMULATION_) //- CURL easy return code CURLcode result; m_error_string = ""; // time logs //struct timeval begin, inter, depouil, end; //gettimeofday(&begin, NULL); //- no connection is possible if (this->connect_i() != timiq_NO_ERROR) return false; // time logs //gettimeofday(&inter, NULL); try { result = send_to_webserver_i(url); } catch (...) { m_error_string = "TIMIQCurl::read_all_i: exception while reading data on " + url; return false; } // time logs //gettimeofday(&depouil, NULL); //- check the result //---------------------------- if (result != CURLE_OK) { //- HTTP error char buff[kMAX_DATA_SIZE]; memset(buff, 0, sizeof(buff)); sprintf (buff, "TIMIQCurl::read_all_i - CURL code error <%d>",result); m_error_string = buff; return false; } //- check the returned data std::string strData = ""; std::size_t index = 0; // extract i value //***************** strData = kTIMIQ_IVALUE_KEY; index = m_timiq_internal_buff.find(strData); if (index != std::string::npos) { //- extract substring from index std::string l_subStr = m_timiq_internal_buff.substr(index); //- parse "=" yat::StringTokenizer tokfloatStr (l_subStr, "="); try { //- field std::string fieldStr = tokfloatStr.next_token(); //- value std::string floatStr = tokfloatStr.next_token(); //- convert data to float values.iVal = (float)yat::XString<float>::to_num(floatStr); } catch(...) { m_error_string = "TIMIQCurl::read_all_i: exception while converting data for i value from " + url; m_error_string += m_timiq_internal_buff; return false; } } else { //- otherwise error m_error_string = m_timiq_internal_buff; return false; } // extract q value //***************** strData = kTIMIQ_QVALUE_KEY; index = m_timiq_internal_buff.find(strData); if (index != std::string::npos) { //- extract substring from index std::string l_subStr = m_timiq_internal_buff.substr(index); //- parse "=" yat::StringTokenizer tokfloatStr (l_subStr, "="); try { //- field std::string fieldStr = tokfloatStr.next_token(); //- value std::string floatStr = tokfloatStr.next_token(); //- convert data to float values.qVal = (float)yat::XString<float>::to_num(floatStr); } catch(...) { m_error_string = "TIMIQCurl::read_all_i: exception while converting data for q value from " + url; m_error_string += m_timiq_internal_buff; return false; } } else { //- otherwise error m_error_string = m_timiq_internal_buff; return false; } // extract mixer cos value //************************* strData = kTIMIQ_MIXER_COS_OUTPUT_KEY; index = m_timiq_internal_buff.find(strData); if (index != std::string::npos) { //- extract substring from index std::string l_subStr = m_timiq_internal_buff.substr(index); //- parse "=" yat::StringTokenizer tokfloatStr (l_subStr, "="); try { //- field std::string fieldStr = tokfloatStr.next_token(); //- value std::string floatStr = tokfloatStr.next_token(); //- convert data to float values.mixerCos = (float)yat::XString<float>::to_num(floatStr); } catch(...) { m_error_string = "TIMIQCurl::read_all_i: exception while converting data for mixer cos value from " + url; m_error_string += m_timiq_internal_buff; return false; } } else { //- otherwise error m_error_string = m_timiq_internal_buff; return false; } // extract mixer sin value //************************* strData = kTIMIQ_MIXER_SIN_OUTPUT_KEY; index = m_timiq_internal_buff.find(strData); if (index != std::string::npos) { //- extract substring from index std::string l_subStr = m_timiq_internal_buff.substr(index); //- parse "=" yat::StringTokenizer tokfloatStr (l_subStr, "="); try { //- field std::string fieldStr = tokfloatStr.next_token(); //- value std::string floatStr = tokfloatStr.next_token(); //- convert data to float values.mixerSin = (float)yat::XString<float>::to_num(floatStr); } catch(...) { m_error_string = "TIMIQCurl::read_all_i: exception while converting data for mixer sin value from " + url; m_error_string += m_timiq_internal_buff; return false; } } else { //- otherwise error m_error_string = m_timiq_internal_buff; return false; } // extract temperature value //**************************** strData = kTIMIQ_BOARD_TEMPERATURE_KEY; index = m_timiq_internal_buff.find(strData); if (index != std::string::npos) { //- extract substring from index std::string l_subStr = m_timiq_internal_buff.substr(index); //- parse "=" yat::StringTokenizer tokfloatStr (l_subStr, "="); try { //- field std::string fieldStr = tokfloatStr.next_token(); //- value std::string floatStr = tokfloatStr.next_token(); //- convert data to float values.temperature = (float)yat::XString<float>::to_num(floatStr); } catch(...) { m_error_string = "TIMIQCurl::read_all_i: exception while converting data for temperature from " + url; m_error_string += m_timiq_internal_buff; return false; } } else { //- otherwise error m_error_string = m_timiq_internal_buff; return false; } #else values.iVal = m_sim_ival; values.qVal = m_sim_qval; values.temperature = 37.2 + values.iVal + values.qVal; values.mixerSin = values.iVal + values.qVal; values.mixerCos = values.iVal - values.qVal; #endif // time logs /*gettimeofday(&end, NULL); std::cout << "INSTRU - TIMIQCurl::read_all_i function took " << (end.tv_sec * 1000.0 + end.tv_usec / 1000.0) - (begin.tv_sec * 1000.0 + begin.tv_usec / 1000.0) << " ms - connect took: " << (inter.tv_sec * 1000.0 + inter.tv_usec / 1000.0) - (begin.tv_sec * 1000.0 + begin.tv_usec / 1000.0) << " ms - get took: " << (depouil.tv_sec * 1000.0 + depouil.tv_usec / 1000.0) - (inter.tv_sec * 1000.0 + inter.tv_usec / 1000.0) << std::endl; */ //- success m_error_string = "OK"; return true; } #if !defined (_SIMULATION_) // ============================================================================ // TIMIQCurl::send_to_webserver_i // ============================================================================ CURLcode TIMIQCurl::send_to_webserver_i(const std::string& url, bool thr) { //std::cout << "TIMIQCurl::send_to_webserver_i() entering... thr? " << thr << " - url = " << url << std::endl; CURLcode result; //- clean the timiq buffer data before perform m_timiq_internal_buff.clear(); // according to flag, use "standard" or "threaded" curl reference if (thr) { // use threaded reference /* ask libcurl to set options */ curl_easy_setopt(m_thr_hw_curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(m_thr_hw_curl, CURLOPT_PROXY, ""); curl_easy_setopt(m_thr_hw_curl, CURLOPT_WRITEFUNCTION, &write_callback); /* complete within 1500 ms */ curl_easy_setopt(m_thr_hw_curl, CURLOPT_TIMEOUT_MS, 30000L); // High timeout for threaded actions /* ask libcurl to show us the verbose output */ // curl_easy_setopt(hm_thr_hw_curl, CURLOPT_VERBOSE, 1L); //- perform the query result = curl_easy_perform(m_thr_hw_curl); // std::cout << "TIMIQCurl::send_to_webserver_i() curl_easy_perform terminates for url = " << url << std::endl; //- clean up curl_easy_cleanup(m_thr_hw_curl); m_thr_hw_curl = NULL; } else { // use non threaded reference /* ask libcurl to set options */ curl_easy_setopt(m_hw_curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(m_hw_curl, CURLOPT_PROXY, ""); curl_easy_setopt(m_hw_curl, CURLOPT_WRITEFUNCTION, &write_callback); /* complete within 1500 ms */ curl_easy_setopt(m_hw_curl, CURLOPT_TIMEOUT_MS, 1500L); /* ask libcurl to show us the verbose output */ // curl_easy_setopt(m_hw_curl, CURLOPT_VERBOSE, 1L); //- perform the query result = curl_easy_perform(m_hw_curl); //- clean up curl_easy_cleanup(m_hw_curl); m_hw_curl = NULL; } return result; } #endif }