//============================================================================= // 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 = ""; m_hw_curl = NULL; } // ============================================================================ // TIMIQCurl::~TIMIQCurl // ============================================================================ TIMIQCurl::~TIMIQCurl () { m_hw_curl = NULL; } // ============================================================================ // 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) { 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; return err_num; } // ============================================================================ // TIMIQCurl::write_qValue // ============================================================================ E_timiq_errno_t TIMIQCurl::write_qValue(float& qValue) { 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; 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) { 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)) err_num = timiq_NO_ERROR; 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_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() { E_timiq_errno_t err_num = timiq_internal_ERROR; m_error_string = ""; 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!\n"; m_error_string += "TIMIQCurl::connect()"; } } else { m_error_string = "TIMIQ WebServer access allows only single session!\n"; m_error_string += "TIMIQCurl::connect()"; } } catch (...) { m_error_string = "TIMIQCurl::connect: exception while initialize Webserver..."; m_hw_curl = NULL; } return err_num; } // ============================================================================ // TIMIQCurl::write_i // ============================================================================ bool TIMIQCurl::write_i(std::string& url, std::string& strData) { //- CURL easy return code CURLcode result; m_error_string = ""; #if !defined (_SIMULATION_) //- 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::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 { #else 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"; #endif 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; } #if !defined (_SIMULATION_) } #endif return false; } // ============================================================================ // 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; //- CURL easy return code CURLcode result; m_error_string = ""; #if !defined (_SIMULATION_) //- 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 ) { //- CURL easy return code CURLcode result; m_error_string = ""; #if !defined (_SIMULATION_) //- 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::send_to_webserver_i // ============================================================================ CURLcode TIMIQCurl:: send_to_webserver_i(const std::string& url) { CURLcode result; //- clean the timiq buffer data before perform m_timiq_internal_buff.clear(); /* 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; } }