Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added internet access detection before version checking is performed #199

Merged
merged 14 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
260 changes: 165 additions & 95 deletions EmotiBitOscilloscope/src/ofApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ void ofApp::setup() {
ofBackground(255, 255, 255);
checkLatestSwVersion();
ofSetLogLevel(OF_LOG_NOTICE);
writeOfxEmotiBitVersionFile();
setTypeTagPlotAttributes();
//saveEmotiBitCommSettings();
loadEmotiBitCommSettings();
Expand Down Expand Up @@ -77,148 +76,219 @@ void ofApp::update() {

void ofApp::checkLatestSwVersion()
{
bool newVersionAvailable = false;
// system call to curl
std::string latestReleaseUrl = "https://github.com/EmotiBit/ofxEmotiBit/releases/latest";
std::string latestReleaseApiRequest = "https://api.github.com/repos/EmotiBit/ofxEmotiBit/releases/latest";
std::string command = "curl " + latestReleaseApiRequest;
std::string response = "";

bool isNetworkAvailable = false;
// -n specifies number of tries. we are going to try to detect internet connection by sending 1 packet
// -w specifies timeout period in mS. We are going to wait for a maximum of 3 seconds for a ping response.
// the IP 8.8.8.8 is google's public DNS. We are using ping with a specific IP as that removes undefined wait periods associated with DNS resolution. More details: https://developers.google.com/speed/public-dns
std::string command = "ping -n 1 -w 3000 8.8.8.8";
std::string pingResponse = "";
char buffer[200];
bool exceptionOccured = false;
ofLogNotice() << "Trying to detect internet access";
try
{
#if defined (TARGET_OSX) || defined (TARGET_LINUX)
FILE* pipe = popen(command.c_str(), "r"); // returns NULL on fail. refer: https://man7.org/linux/man-pages/man3/popen.3.html#RETURN_VALUE
#else
FILE* pipe = _popen(command.c_str(), "r"); // returns NULL on fail. refer: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/popen-wpopen?view=msvc-170#return-value
#endif
#endif
if (pipe != NULL)
{
try
while (fgets(buffer, sizeof buffer, pipe) != NULL)
{
while (fgets(buffer, sizeof buffer, pipe) != NULL)
pingResponse += buffer;
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function has been moved to its own file in ofxEmotiBit/src.
Idea being, we can re-use it in other softwares (parser)

#if defined (TARGET_OSX) || defined (TARGET_LINUX)
pclose(pipe);
#else
_pclose(pipe);
#endif
}
else
{
ofLogNotice() << "Failed to open pipe. ping failed";
}
}
catch (...)
{
ofLogError() << "Ping failed";
}
ofLogNotice() << pingResponse.c_str();

// A successful ping response contains a sumary of round trip times. We are using that do determine if ping was successful
/* A successful ping response
------------------------------
Pinging 8.8.8.8 with 32 bytes of data:
nitin710 marked this conversation as resolved.
Show resolved Hide resolved
Reply from 8.8.8.8: bytes = 32 time = 18ms TTL = 119

Ping statistics for 8.8.8.8 :
Packets : Sent = 1, Received = 1, Lost = 0 (0 % loss),
Approximate round trip times in milli - seconds :
Minimum = 18ms, Maximum = 18ms, Average = 18ms
*/
if (pingResponse.find("Approximate round trip times") != std::string::npos)
{
// substring found!
ofLogNotice() << "internet access detected";
isNetworkAvailable = true;
}
else
{
// failed
ofLogNotice() << "Failed to ping IP";
}

if (isNetworkAvailable)
nitin710 marked this conversation as resolved.
Show resolved Hide resolved
{
bool newVersionAvailable = false;
// system call to curl
std::string latestReleaseUrl = "https://github.com/EmotiBit/ofxEmotiBit/releases/latest";
std::string latestReleaseApiRequest = "https://api.github.com/repos/EmotiBit/ofxEmotiBit/releases/latest";
// Calling curl with a 3 second timeout. Timeout tested working with curl version v8.0.1. Older versions of curl have shown a "disregard" for the timeout.
std::string command = "curl --connect-timeout 3 " + latestReleaseApiRequest;
nitin710 marked this conversation as resolved.
Show resolved Hide resolved
std::string response = "";
char buffer[200];
bool exceptionOccured = false;
try
{
#if defined (TARGET_OSX) || defined (TARGET_LINUX)
FILE* pipe = popen(command.c_str(), "r"); // returns NULL on fail. refer: https://man7.org/linux/man-pages/man3/popen.3.html#RETURN_VALUE
#else
FILE* pipe = _popen(command.c_str(), "r"); // returns NULL on fail. refer: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/popen-wpopen?view=msvc-170#return-value
#endif
if (pipe != NULL)
{
try
{
response += buffer;
while (fgets(buffer, sizeof buffer, pipe) != NULL)
{
response += buffer;
}
}
catch (...) {
try
{
#if defined (TARGET_OSX) || defined (TARGET_LINUX)
pclose(pipe);
#else
_pclose(pipe);
#endif
}
catch (...)
{
ofLogError("Failed to close pipe");
}
ofLog(OF_LOG_ERROR, "An exception occured while executing curl");
exceptionOccured = true;
}
}
catch (...) {
try
{
#if defined (TARGET_OSX) || defined (TARGET_LINUX)
#if defined (TARGET_OSX) || defined (TARGET_LINUX)
pclose(pipe);
#else
#else
_pclose(pipe);
#endif
#endif
}
catch (...)
{
ofLogError("Failed to close pipe");
}
ofLog(OF_LOG_ERROR, "An exception occured while executing curl");
exceptionOccured = true;
}
try
{
#if defined (TARGET_OSX) || defined (TARGET_LINUX)
pclose(pipe);
#else
_pclose(pipe);
#endif
}
catch (...)
else
{
ofLogError("Failed to close pipe");
ofLog(OF_LOG_ERROR, "Failed to check for latest version. Failed to open pipe");
exceptionOccured = true;
}
}
else
catch (...)
{
ofLog(OF_LOG_ERROR, "Failed to check for latest version. Failed to open pipe");
ofLogError("Failed to open pipe");
exceptionOccured = true;
}
}
catch (...)
{
ofLogError("Failed to open pipe");
exceptionOccured = true;
}
try
{
if (!exceptionOccured & response != "")
try
{
ofxJSONElement jsonResponse;
if (jsonResponse.parse(response))
if (!exceptionOccured & response != "")
{
//ofLog(OF_LOG_NOTICE, jsonResponse.getRawString(true)); // uncomment to print curl output
std::string latestAvailableVersion = jsonResponse["tag_name"].asString();
ofLogNotice("Latest version") << latestAvailableVersion;
int swVerPrefixLoc = latestAvailableVersion.find(SOFTWARE_VERSION_PREFIX);
if (swVerPrefixLoc != std::string::npos)
ofxJSONElement jsonResponse;
if (jsonResponse.parse(response))
{
latestAvailableVersion.erase(swVerPrefixLoc, 1); // remove leading version char "v"
}
// compare with ofxEmotiBitVersion
std::vector<std::string> latestVersionSplit = ofSplitString(latestAvailableVersion, ".");
std::vector<std::string> currentVersionSplit = ofSplitString(ofxEmotiBitVersion, ".");
int versionLength = latestVersionSplit.size() < currentVersionSplit.size() ? latestVersionSplit.size() : currentVersionSplit.size();
if (versionLength)
{
for (int i = 0; i < versionLength; i++)
//ofLog(OF_LOG_NOTICE, jsonResponse.getRawString(true)); // uncomment to print curl output
std::string latestAvailableVersion = jsonResponse["tag_name"].asString();
ofLogNotice("Latest version") << latestAvailableVersion;
int swVerPrefixLoc = latestAvailableVersion.find(SOFTWARE_VERSION_PREFIX);
if (swVerPrefixLoc != std::string::npos)
{
int latest = ofToInt(latestVersionSplit.at(i));
int current = ofToInt(currentVersionSplit.at(i));
if (latest == current)
{
// need to check minor version
continue;
}
else if (latest < current)
{
// current version higher than latest available
break;
}
else // latest > current
latestAvailableVersion.erase(swVerPrefixLoc, 1); // remove leading version char "v"
}
// compare with ofxEmotiBitVersion
std::vector<std::string> latestVersionSplit = ofSplitString(latestAvailableVersion, ".");
std::vector<std::string> currentVersionSplit = ofSplitString(ofxEmotiBitVersion, ".");
int versionLength = latestVersionSplit.size() < currentVersionSplit.size() ? latestVersionSplit.size() : currentVersionSplit.size();
if (versionLength)
{
for (int i = 0; i < versionLength; i++)
{
// new version available
newVersionAvailable = true;
break;
int latest = ofToInt(latestVersionSplit.at(i));
int current = ofToInt(currentVersionSplit.at(i));
if (latest == current)
{
// need to check minor version
continue;
}
else if (latest < current)
{
// current version higher than latest available
break;
}
else // latest > current
{
// new version available
newVersionAvailable = true;
break;
}
}
}
else
{
ofLogError("Failed to parse version string");
}
}
else
{
ofLogError("Failed to parse version string");
ofLog(OF_LOG_ERROR, "unexpected curl response");
}
}
else
{
ofLog(OF_LOG_ERROR, "unexpected curl response");
}
// If newer version available, display alert message
if (newVersionAvailable)
{
// create alert dialog box
ofSystemAlertDialog("A new version of EmotiBit Software is available!");
// open browser to latest version
try
// If newer version available, display alert message
if (newVersionAvailable)
{
// create alert dialog box
ofSystemAlertDialog("A new version of EmotiBit Software is available!");
// open browser to latest version
try
{
#ifdef TARGET_WIN32
std::string command = "start " + latestReleaseUrl;
system(command.c_str());
std::string command = "start " + latestReleaseUrl;
system(command.c_str());
#else
std::string command = "open " + latestReleaseUrl;
system(command.c_str());
std::string command = "open " + latestReleaseUrl;
system(command.c_str());
#endif
}
catch (...)
{
ofLogError("Failed to open browser");
}
catch (...)
{
ofLogError("Failed to open browser");
}
}
}
}
catch (...)
{
ofLogError("An exception occured while checking latest version of EmotiBit software");
}
}
catch (...)
else
{
ofLogError("An exception occured while checking latest version of EmotiBit software");
ofLogNotice() << "Internet access not detected. Skipping version check.";
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/ofxEmotiBitVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "ofMain.h"


const std::string ofxEmotiBitVersion = "1.8.1";
const std::string ofxEmotiBitVersion = "1.8.1.fix-swVersionChecker.1";

static const char SOFTWARE_VERSION_PREFIX = 'v';

Expand Down