-
Sonia Minolli authoredSonia Minolli authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
TIMIQCurl.cpp 20.71 KiB
//=============================================================================
// 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;
m_thr_hw_curl = NULL;
curl_global_init(CURL_GLOBAL_ALL);
}
// ============================================================================
// TIMIQCurl::~TIMIQCurl
// ============================================================================
TIMIQCurl::~TIMIQCurl ()
{
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();
}
// ============================================================================
// 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; // soso traces
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)
{
std::cout << "TIMIQCurl::write_qValue() write qValue = " << qValue << std::endl; // soso traces
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, 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;
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(bool thr)
{
E_timiq_errno_t err_num = timiq_internal_ERROR;
m_error_string = "";
// 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;
}
// ============================================================================
// TIMIQCurl::write_i
// ============================================================================
bool TIMIQCurl::write_i(std::string& url, std::string& strData, bool thr)
{
//- CURL easy return code
CURLcode result;
m_error_string = "";
#if !defined (_SIMULATION_)
//- 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
{
#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, bool thr)
{
std::cout << "TIMIQCurl::send_to_webserver_i() entering... thr? " << thr << " - url = " << url << std::endl; // soso traces
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 rend la main pour url = " << url << std::endl; // soso traces
//- 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;
}
}