Skip to content

Commit

Permalink
Change to dbus_connection_open_private and don't maintain connection …
Browse files Browse the repository at this point in the history
…more than an 30 minutes.
  • Loading branch information
William C Bonner committed Nov 16, 2024
1 parent 673b360 commit fd2d1a9
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 115 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ if (POLICY CMP0115)
endif()

project (VictronBTLELogger
VERSION 3.20241113.1
VERSION 3.20241115.0
DESCRIPTION "Log Victron Direct Bluetooth LE messages and graph battery states"
HOMEPAGE_URL https://github.com/wcbonner/VictronBTLELogger
)
Expand Down
227 changes: 113 additions & 114 deletions victronbtlelogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2547,141 +2547,140 @@ int main(int argc, char** argv)
exit(EXIT_FAILURE);
}

DBusError dbus_error;
dbus_error_init(&dbus_error); // https://dbus.freedesktop.org/doc/api/html/group__DBusErrors.html#ga8937f0b7cdf8554fa6305158ce453fbe
// Set up CTR-C signal handler
typedef void(*SignalHandlerPointer)(int);
SignalHandlerPointer previousHandlerSIGINT = std::signal(SIGINT, SignalHandlerSIGINT); // Install CTR-C signal handler
SignalHandlerPointer previousHandlerSIGHUP = std::signal(SIGHUP, SignalHandlerSIGHUP); // Install Hangup signal handler

// Connect to the system bus
DBusConnection* dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_error); // https://dbus.freedesktop.org/doc/api/html/group__DBusBus.html#ga77ba5250adb84620f16007e1b023cf26
if (dbus_error_is_set(&dbus_error)) // https://dbus.freedesktop.org/doc/api/html/group__DBusErrors.html#gab0ed62e9fc2685897eb2d41467c89405
time_t TimeStart(0), TimeLog(0), TimeSVG(0);
// Main loop
bRun = true;
while (bRun)
{
std::cout << "[" << getTimeISO8601(true) << "] Error connecting to the D-Bus system bus: " << dbus_error.message << std::endl;
dbus_error_free(&dbus_error); // https://dbus.freedesktop.org/doc/api/html/group__DBusErrors.html#gaac6c14ead14829ee4e090f39de6a7568
}
else
{
if (ConsoleVerbosity > 0)
std::cout << "[" << getTimeISO8601(true) << "] Connected to D-Bus as \"" << dbus_bus_get_unique_name(dbus_conn) << "\"" << std::endl; // https://dbus.freedesktop.org/doc/api/html/group__DBusBus.html#ga8c10339a1e62f6a2e5752d9c2270d37b
else
std::cerr << "Connected to D-Bus as \"" << dbus_bus_get_unique_name(dbus_conn) << "\"" << std::endl; // https://dbus.freedesktop.org/doc/api/html/group__DBusBus.html#ga8c10339a1e62f6a2e5752d9c2270d37b
time(&TimeStart);
DBusError dbus_error;
dbus_error_init(&dbus_error); // https://dbus.freedesktop.org/doc/api/html/group__DBusErrors.html#ga8937f0b7cdf8554fa6305158ce453fbe

std::map<bdaddr_t, std::string> BlueZAdapterMap;
bool bUse_HCI_Interface = !bluez_find_adapters(dbus_conn, BlueZAdapterMap);
if (bUse_HCI_Interface && BlueZAdapterMap.empty())
// Connect to the system bus
DBusConnection* dbus_conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, &dbus_error); // https://dbus.freedesktop.org/doc/api/html/group__DBusBus.html#ga77ba5250adb84620f16007e1b023cf26
if (dbus_error_is_set(&dbus_error)) // https://dbus.freedesktop.org/doc/api/html/group__DBusErrors.html#gab0ed62e9fc2685897eb2d41467c89405
{
if (ConsoleVerbosity > 0)
std::cout << "[" << getTimeISO8601() << "] Could not get list of adapters from BlueZ over DBus. Reverting to HCI interface." << std::endl;
else
std::cerr << "Could not get list of adapters from BlueZ over DBus. Reverting to HCI interface." << std::endl;
std::cout << "[" << getTimeISO8601(true) << "] Error connecting to the D-Bus system bus: " << dbus_error.message << std::endl;
dbus_error_free(&dbus_error); // https://dbus.freedesktop.org/doc/api/html/group__DBusErrors.html#gaac6c14ead14829ee4e090f39de6a7568
}
if (!BlueZAdapterMap.empty())
else
{
std::string BlueZAdapter(BlueZAdapterMap.cbegin()->second);
if (!ControllerAddress.empty())
if (auto search = BlueZAdapterMap.find(string2ba(ControllerAddress)); search != BlueZAdapterMap.end())
BlueZAdapter = search->second;
if (ConsoleVerbosity > 0)
std::cout << "[" << getTimeISO8601(true) << "] D-Bus connection \"" << dbus_bus_get_unique_name(dbus_conn) << "\" Opened" << std::endl; // https://dbus.freedesktop.org/doc/api/html/group__DBusBus.html#ga8c10339a1e62f6a2e5752d9c2270d37b
else
std::cerr << "D-Bus connection \"" << dbus_bus_get_unique_name(dbus_conn) << "\" Opened" << std::endl; // https://dbus.freedesktop.org/doc/api/html/group__DBusBus.html#ga8c10339a1e62f6a2e5752d9c2270d37b

bluez_power_on(dbus_conn, BlueZAdapter.c_str());
bluez_filter_le(dbus_conn, BlueZAdapter.c_str());
bluez_dbus_FindExistingDevices(dbus_conn); // This pulls data from BlueZ on devices that BlueZ is already keeping track of
if (bluez_discovery(dbus_conn, BlueZAdapter.c_str(), true))
std::map<bdaddr_t, std::string> BlueZAdapterMap;
bool bUse_HCI_Interface = !bluez_find_adapters(dbus_conn, BlueZAdapterMap);
if (bUse_HCI_Interface && BlueZAdapterMap.empty())
{
dbus_connection_flush(dbus_conn); // https://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#ga10e68d9d2f41d655a4151ddeb807ff54
std::vector<std::string> MatchRules;
MatchRules.push_back("type='signal',sender='org.bluez',member='InterfacesAdded'");
MatchRules.push_back("type='signal',sender='org.bluez',member='PropertiesChanged'");
for (auto& MatchRule : MatchRules)
{
dbus_error_init(&dbus_error); // https://dbus.freedesktop.org/doc/api/html/group__DBusErrors.html#ga8937f0b7cdf8554fa6305158ce453fbe
dbus_bus_add_match(dbus_conn, MatchRule.c_str(), &dbus_error); // https://dbus.freedesktop.org/doc/api/html/group__DBusBus.html#ga4eb6401ba014da3dbe3dc4e2a8e5b3ef
if (dbus_error_is_set(&dbus_error))
{
std::cout << "Error adding a match rule on the D-Bus system bus: " << dbus_error.message << std::endl;
dbus_error_free(&dbus_error);
}
}
// Set up CTR-C signal handler
typedef void(*SignalHandlerPointer)(int);
SignalHandlerPointer previousHandlerSIGINT = std::signal(SIGINT, SignalHandlerSIGINT); // Install CTR-C signal handler
SignalHandlerPointer previousHandlerSIGHUP = std::signal(SIGHUP, SignalHandlerSIGHUP); // Install Hangup signal handler
if (ConsoleVerbosity > 0)
std::cout << "[" << getTimeISO8601() << "] Could not get list of adapters from BlueZ over DBus. Reverting to HCI interface." << std::endl;
else
std::cerr << "Could not get list of adapters from BlueZ over DBus. Reverting to HCI interface." << std::endl;
}
if (!BlueZAdapterMap.empty())
{
std::string BlueZAdapter(BlueZAdapterMap.cbegin()->second);
if (!ControllerAddress.empty())
if (auto search = BlueZAdapterMap.find(string2ba(ControllerAddress)); search != BlueZAdapterMap.end())
BlueZAdapter = search->second;

// Main loop
bRun = true;
time_t TimeStart(0), TimeSVG(0), TimeAdvertisment(0);
time(&TimeStart);
time_t TimeLog(TimeStart);
while (bRun)
bluez_power_on(dbus_conn, BlueZAdapter.c_str());
bluez_filter_le(dbus_conn, BlueZAdapter.c_str());
bluez_dbus_FindExistingDevices(dbus_conn); // This pulls data from BlueZ on devices that BlueZ is already keeping track of
if (bluez_discovery(dbus_conn, BlueZAdapter.c_str(), true))
{
// Wait for access to the D-Bus
if (!dbus_connection_read_write(dbus_conn, 1000)) // https://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#ga371163b4955a6e0bf0f1f70f38390c14
dbus_connection_flush(dbus_conn); // https://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#ga10e68d9d2f41d655a4151ddeb807ff54
std::vector<std::string> MatchRules;
MatchRules.push_back("type='signal',sender='org.bluez',member='InterfacesAdded'");
MatchRules.push_back("type='signal',sender='org.bluez',member='PropertiesChanged'");
for (auto& MatchRule : MatchRules)
{
if (ConsoleVerbosity > 0)
std::cout << "[" << getTimeISO8601() << "] D-Bus connection was closed" << std::endl;
else
std::cerr << "D-Bus connection was closed" << std::endl;
bRun = false;
dbus_error_init(&dbus_error); // https://dbus.freedesktop.org/doc/api/html/group__DBusErrors.html#ga8937f0b7cdf8554fa6305158ce453fbe
dbus_bus_add_match(dbus_conn, MatchRule.c_str(), &dbus_error); // https://dbus.freedesktop.org/doc/api/html/group__DBusBus.html#ga4eb6401ba014da3dbe3dc4e2a8e5b3ef
if (dbus_error_is_set(&dbus_error))
{
std::cout << "Error adding a match rule on the D-Bus system bus: " << dbus_error.message << std::endl;
dbus_error_free(&dbus_error);
}
}
else
time_t TimeNow(0);
do
{
// Pop first message on D-Bus connection
DBusMessage* dbus_msg = dbus_connection_pop_message(dbus_conn); // https://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#ga1e40d994ea162ce767e78de1c4988566

// If there is nothing to receive we get a NULL
if (dbus_msg != nullptr)
// Wait for access to the D-Bus
if (!dbus_connection_read_write(dbus_conn, 1000)) // https://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#ga371163b4955a6e0bf0f1f70f38390c14
{
if (DBUS_MESSAGE_TYPE_SIGNAL == dbus_message_get_type(dbus_msg))
time(&TimeNow);
if (ConsoleVerbosity > 0)
std::cout << "[" << timeToISO8601(TimeNow, true) << "] D-Bus connection Closed" << std::endl;
else
std::cerr << "D-Bus connection Closed" << std::endl;
bRun = false;
}
else
{
time(&TimeNow);
// Pop first message on D-Bus connection
DBusMessage* dbus_msg = dbus_connection_pop_message(dbus_conn); // https://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#ga1e40d994ea162ce767e78de1c4988566

// If there is nothing to receive we get a NULL
if (dbus_msg != nullptr)
{
const std::string dbus_msg_Member(dbus_message_get_member(dbus_msg)); // https://dbus.freedesktop.org/doc/api/html/group__DBusMessage.html#gaf5c6b705c53db07a5ae2c6b76f230cf9
bdaddr_t localBTAddress({ 0 });
if (!dbus_msg_Member.compare("InterfacesAdded"))
bluez_dbus_msg_InterfacesAdded(dbus_msg, localBTAddress);
else if (!dbus_msg_Member.compare("PropertiesChanged"))
bluez_dbus_msg_PropertiesChanged(dbus_msg, localBTAddress);
if (DBUS_MESSAGE_TYPE_SIGNAL == dbus_message_get_type(dbus_msg))
{
const std::string dbus_msg_Member(dbus_message_get_member(dbus_msg)); // https://dbus.freedesktop.org/doc/api/html/group__DBusMessage.html#gaf5c6b705c53db07a5ae2c6b76f230cf9
bdaddr_t localBTAddress({ 0 });
if (!dbus_msg_Member.compare("InterfacesAdded"))
bluez_dbus_msg_InterfacesAdded(dbus_msg, localBTAddress);
else if (!dbus_msg_Member.compare("PropertiesChanged"))
bluez_dbus_msg_PropertiesChanged(dbus_msg, localBTAddress);
}
dbus_message_unref(dbus_msg); // Free the message
}
dbus_message_unref(dbus_msg); // Free the message
}
}
time_t TimeNow;
time(&TimeNow);
if ((!SVGDirectory.empty()) && (difftime(TimeNow, TimeSVG) > DAY_SAMPLE))
{
if (ConsoleVerbosity > 0)
std::cout << "[" << getTimeISO8601(true) << "] " << std::dec << DAY_SAMPLE << " seconds or more have passed. Writing SVG Files" << std::endl;
TimeSVG = (TimeNow / DAY_SAMPLE) * DAY_SAMPLE; // hack to try to line up TimeSVG to be on a five minute period
WriteAllSVG();
}
const int LogFileTime(60);
if (difftime(TimeNow, TimeLog) > LogFileTime)
{
if (ConsoleVerbosity > 0)
std::cout << "[" << getTimeISO8601(true) << "] " << std::dec << LogFileTime << " seconds or more have passed. Writing LOG Files" << std::endl;
TimeLog = TimeNow;
GenerateLogFile(VictronVirtualLog);
GenerateCacheFile(VictronSmartLithiumMRTGLogs); // flush FakeMRTG data to cache files
}
if (difftime(TimeNow, TimeStart) > 60 * 30) // Issue StartDiscovery command every 30 minutes to make sure it's not been turned off by another bluetooth process
{
if (ConsoleVerbosity > 1)
std::cout << "[" << getTimeISO8601(true) << "] " << "Restarting Scanning" << std::endl;
bluez_discovery(dbus_conn, BlueZAdapter.c_str(), false);
bluez_dbus_RemoveKnownDevices(dbus_conn, BlueZAdapter.c_str(), VictronEncryptionKeys);
bRun = bluez_discovery(dbus_conn, BlueZAdapter.c_str(), true);
TimeStart = TimeNow;
}
if ((!SVGDirectory.empty()) && (difftime(TimeNow, TimeSVG) > DAY_SAMPLE))
{
if (ConsoleVerbosity > 0)
std::cout << "[" << getTimeISO8601(true) << "] " << std::dec << DAY_SAMPLE << " seconds or more have passed. Writing SVG Files" << std::endl;
TimeSVG = (TimeNow / DAY_SAMPLE) * DAY_SAMPLE; // hack to try to line up TimeSVG to be on a five minute period
WriteAllSVG();
}
const int LogFileTime(60);
if (difftime(TimeNow, TimeLog) > LogFileTime)
{
if (ConsoleVerbosity > 0)
std::cout << "[" << getTimeISO8601(true) << "] " << std::dec << LogFileTime << " seconds or more have passed. Writing LOG Files" << std::endl;
TimeLog = TimeNow;
GenerateLogFile(VictronVirtualLog);
GenerateCacheFile(VictronSmartLithiumMRTGLogs); // flush FakeMRTG data to cache files
}
#ifdef DEBUG
} while (bRun && difftime(TimeNow, TimeStart) < 30); // Maintain DBus connection for no more than 30 seconds
#else
} while (bRun && difftime(TimeNow, TimeStart) < (60 * 30)); // Maintain DBus connection for no more than 30 minutes
#endif // DEBUG
bluez_discovery(dbus_conn, BlueZAdapter.c_str(), false);
bluez_dbus_RemoveKnownDevices(dbus_conn, BlueZAdapter.c_str(), VictronEncryptionKeys);
//bluez_filter_le(dbus_conn, BlueZAdapter.c_str(), false, false); // remove discovery filter
}
bluez_discovery(dbus_conn, BlueZAdapter.c_str(), false);

std::signal(SIGHUP, previousHandlerSIGHUP); // Restore original Hangup signal handler
std::signal(SIGINT, previousHandlerSIGINT); // Restore original Ctrl-C signal handler

GenerateLogFile(VictronVirtualLog); // flush contents of accumulated map to logfiles
//GenerateCacheFile(GoveeMRTGLogs); // flush FakeMRTG data to cache files
}
bluez_filter_le(dbus_conn, BlueZAdapter.c_str(), false, false); // remove discovery filter
if (ConsoleVerbosity > 0)
std::cout << "[" << getTimeISO8601(true) << "] D-Bus connection \"" << dbus_bus_get_unique_name(dbus_conn) << "\" Closed" << std::endl; // https://dbus.freedesktop.org/doc/api/html/group__DBusBus.html#ga8c10339a1e62f6a2e5752d9c2270d37b
else
std::cerr << "D-Bus connection \"" << dbus_bus_get_unique_name(dbus_conn) << "\" Closed" << std::endl; // https://dbus.freedesktop.org/doc/api/html/group__DBusBus.html#ga8c10339a1e62f6a2e5752d9c2270d37b
dbus_connection_close(dbus_conn); // https://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#ga2522ac5075dfe0a1535471f6e045e1ee
dbus_connection_unref(dbus_conn); // https://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#ga6385ff09bc108238c4429e7c195dab25
}

// Close the connection. When using the System Bus, unreference the connection instead of closing it
dbus_connection_unref(dbus_conn);
}
GenerateLogFile(VictronVirtualLog); // flush contents of accumulated map to logfiles
std::signal(SIGHUP, previousHandlerSIGHUP); // Restore original Hangup signal handler
std::signal(SIGINT, previousHandlerSIGINT); // Restore original Ctrl-C signal handler
std::cerr << ProgramVersionString << " (exiting)" << std::endl;
return(EXIT_SUCCESS);
}

0 comments on commit fd2d1a9

Please sign in to comment.