From 30c292648972213bfb175bc642dfbfbd01882c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20=C3=96hrstr=C3=B6m?= Date: Sat, 6 Mar 2021 14:16:47 +0100 Subject: [PATCH] When looking for rtl_sdr/rtl_wmbus first look in the same dir as wmbusmeters was found. --- README.md | 7 +++--- src/cmdline.cc | 8 ++++-- src/config.h | 3 +++ src/main.cc | 11 +++----- src/mbus_rawtty.cc | 9 ++++--- src/rtlsdr.cc | 2 +- src/testinternals.cc | 8 +++--- src/util.cc | 58 +++++++++++++++++++++++++++++++++++++++++++ src/util.h | 7 ++++++ src/wmbus.cc | 13 +++++----- src/wmbus.h | 21 ++++++++-------- src/wmbus_amb8465.cc | 5 ++-- src/wmbus_cul.cc | 2 +- src/wmbus_im871a.cc | 9 ++++--- src/wmbus_rawtty.cc | 2 +- src/wmbus_rc1180.cc | 2 +- src/wmbus_rtl433.cc | 2 +- src/wmbus_rtlwmbus.cc | 50 +++++++++++++++++++++++++------------ 18 files changed, 156 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 0e56663..2599157 100644 --- a/README.md +++ b/README.md @@ -89,9 +89,10 @@ key=00112233445566778899AABBCCDDEEFF Now plugin your wmbus dongle. Wmbusmeters should start automatically, check with `tail -f /var/log/syslog` and `tail -f /var/log/wmbusmeters/wmbusmeters.log` -(If you are using an rtlsdr dongle, then make sure the binaries /usr/bin/rtl_sdr and -/usr/bin/rtl_wmbus exists and are executable. If not you will see the -error message `(rtlwmbus) error: when starting as daemon, wmbusmeters expects /usr/bin/rtl_sdr to exist!` +(If you are using an rtlsdr dongle, then make sure that either the binaries /usr/bin/rtl_sdr and +/usr/bin/rtl_wmbus exists and are executable. Or rtl_sdr/rtl_wmbus exists inside the same directory +as the wmbusmeters directory is located. If not you will see the +error message `(rtlwmbus) error: when starting as daemon, wmbusmeters looked for .../rtl_wmbus and /usr/bin/rtl_wmbus, but found neither!` and the daemon will refuse to start.) The latest reading of the meter can also be found here: /var/log/wmbusmeters/meter_readings/MyTapWater diff --git a/src/cmdline.cc b/src/cmdline.cc index 81ab0dc..db20666 100644 --- a/src/cmdline.cc +++ b/src/cmdline.cc @@ -29,11 +29,15 @@ shared_ptr parseCommandLine(int argc, char **argv) { int i=1; const char *filename = strrchr(argv[0], '/'); - if (filename) { + if (filename) + { filename++; - } else { + } + else + { filename = argv[0]; } + c->bin_dir = dirname(currentProcessExe()); if (!strcmp(filename, "wmbusmetersd")) { c->daemon = true; diff --git a/src/config.h b/src/config.h index a03a957..ed695ec 100644 --- a/src/config.h +++ b/src/config.h @@ -44,6 +44,9 @@ enum class MeterFileTimestamp struct Configuration { + string bin_dir {}; // The wmbusmeters binary executed is located here. + // Use this directory to look for other tools such as rtl_wmbus/rtl_sdr + // inside the same directory. bool daemon {}; std::string pid_file; std::string device_override; diff --git a/src/main.cc b/src/main.cc index e0b315b..abfe4e6 100644 --- a/src/main.cc +++ b/src/main.cc @@ -325,15 +325,15 @@ shared_ptr create_wmbus_object(Detected *detected, Configuration *config, break; case DEVICE_MBUS: verbose("(mbus) on %s\n", detected->found_file.c_str()); - wmbus = openMBUS(detected->found_file, detected->found_bps, manager, serial_override); + wmbus = openMBUS(*detected, manager, serial_override); break; case DEVICE_IM871A: verbose("(im871a) on %s\n", detected->found_file.c_str()); - wmbus = openIM871A(detected->found_file, manager, serial_override); + wmbus = openIM871A(*detected, manager, serial_override); break; case DEVICE_AMB8465: verbose("(amb8465) on %s\n", detected->found_file.c_str()); - wmbus = openAMB8465(detected->found_file, manager, serial_override); + wmbus = openAMB8465(*detected, manager, serial_override); break; case DEVICE_SIMULATION: verbose("(simulation) in %s\n", detected->found_file.c_str()); @@ -344,11 +344,8 @@ shared_ptr create_wmbus_object(Detected *detected, Configuration *config, wmbus = openRawTTY(detected->found_file, detected->found_bps, manager, serial_override); break; case DEVICE_RTLWMBUS: - { - string identifier = detected->found_device_id; - wmbus = openRTLWMBUS(identifier, detected->specified_device, config->daemon, manager, serial_override); + wmbus = openRTLWMBUS(*detected, config->bin_dir, config->daemon, manager, serial_override); break; - } case DEVICE_RTL433: { string command; diff --git a/src/mbus_rawtty.cc b/src/mbus_rawtty.cc index f97a9f1..0c9866d 100644 --- a/src/mbus_rawtty.cc +++ b/src/mbus_rawtty.cc @@ -53,8 +53,11 @@ private: vector received_payload_; }; -shared_ptr openMBUS(string device, int baudrate, shared_ptr manager, shared_ptr serial_override) +shared_ptr openMBUS(Detected detected, shared_ptr manager, shared_ptr serial_override) { + string device = detected.found_file; + int bps = detected.found_bps; + assert(device != ""); if (serial_override) @@ -63,7 +66,7 @@ shared_ptr openMBUS(string device, int baudrate, shared_ptrmarkAsNoLongerSerial(); return shared_ptr(imp); } - auto serial = manager->createSerialDeviceTTY(device.c_str(), baudrate, PARITY::EVEN, "mbus"); + auto serial = manager->createSerialDeviceTTY(device.c_str(), bps, PARITY::EVEN, "mbus"); MBusRawTTY *imp = new MBusRawTTY(serial, manager); return shared_ptr(imp); } @@ -159,7 +162,7 @@ AccessCheck detectMBUS(Detected *detected, shared_ptrclose(); - detected->setAsFound("", WMBusDeviceType::DEVICE_MBUS, bps, false, false, + detected->setAsFound("", WMBusDeviceType::DEVICE_MBUS, bps, false, detected->specified_device.linkmodes); return AccessCheck::AccessOK; diff --git a/src/rtlsdr.cc b/src/rtlsdr.cc index a50e7b1..2a6f2bd 100644 --- a/src/rtlsdr.cc +++ b/src/rtlsdr.cc @@ -123,7 +123,7 @@ AccessCheck detectRTLSDR(string serialnr, Detected *detected) LinkModeSet lms; lms.addLinkMode(LinkMode::C1); lms.addLinkMode(LinkMode::T1); - detected->setAsFound(serialnr, detected->specified_device.type, 0, false, false, lms); + detected->setAsFound(serialnr, detected->specified_device.type, 0, false, lms); return AccessCheck::AccessOK; } } diff --git a/src/testinternals.cc b/src/testinternals.cc index b0b32cf..0450601 100644 --- a/src/testinternals.cc +++ b/src/testinternals.cc @@ -238,11 +238,11 @@ int test_linkmodes() auto serial4 = manager->createSerialDeviceSimulator(); vector no_meter_shells, no_meter_jsons; - - shared_ptr wmbus_im871a = openIM871A("", manager, serial1); - shared_ptr wmbus_amb8465 = openAMB8465("", manager, serial2); + Detected de; SpecifiedDevice sd; - shared_ptr wmbus_rtlwmbus = openRTLWMBUS("", sd, false, manager, serial3); + shared_ptr wmbus_im871a = openIM871A(de, manager, serial1); + shared_ptr wmbus_amb8465 = openAMB8465(de, manager, serial2); + shared_ptr wmbus_rtlwmbus = openRTLWMBUS(de, "", false, manager, serial3); shared_ptr wmbus_rawtty = openRawTTY("", 0, manager, serial4); Configuration nometers_config; diff --git a/src/util.cc b/src/util.cc index 39092c2..868b1d8 100644 --- a/src/util.cc +++ b/src/util.cc @@ -39,6 +39,10 @@ #include #include +#if defined(__APPLE__) && defined(__MACH__) +#include +#endif + using namespace std; // Sigint, sigterm will call the exit handler. @@ -1796,3 +1800,57 @@ bool check_if_rtlsdr_exists_in_path() } return found; } + +std::string currentProcessExe() +{ + char buf[1024]; + memset(buf, 0, 1024); + +#if defined(__APPLE__) && defined(__MACH__) + uint32_t size = sizeof(buf); + + int rs = _NSGetExecutablePath(buf,&size); + if (rs != 0) + { + // Buf not big enough. + return ""; + } + return buf; + } + +#else +# if (defined(__FreeBSD__)) + const char *self = "/proc/curproc/file"; + #else + const char *self = "/proc/self/exe"; + #endif + + ssize_t s = readlink(self, buf, 1023); + + if (s == 1023) return ""; + if (s <= 0) return ""; + return buf; +#endif +} + +string dirname(string p) +{ + size_t s = p.rfind('/'); + if (s == string::npos) return ""; + return p.substr(0, s); +} + +string lookForExecutable(string prog, string bin_dir, string default_dir) +{ + string tmp = bin_dir+"/"+prog; + if (checkFileExists(tmp.c_str())) + { + return tmp; + } + tmp = default_dir+"/"+prog; + if (checkFileExists(tmp.c_str())) + { + return tmp; + } + return ""; +} diff --git a/src/util.h b/src/util.h index 8728a31..5e27668 100644 --- a/src/util.h +++ b/src/util.h @@ -195,4 +195,11 @@ uint32_t indexFromRtlSdrName(std::string &s); bool check_if_rtlwmbus_exists_in_path(); bool check_if_rtlsdr_exists_in_path(); +// Return the actual executable binary that is running. +std::string currentProcessExe(); + +std::string dirname(std::string p); + +std::string lookForExecutable(std::string prog, std::string bin_dir, std::string default_dir); + #endif diff --git a/src/wmbus.cc b/src/wmbus.cc index bee4aee..feac731 100644 --- a/src/wmbus.cc +++ b/src/wmbus.cc @@ -4672,7 +4672,7 @@ Detected detectWMBusDeviceWithFile(SpecifiedDevice &specified_device, debug("(lookup) driver: simulation file\n"); // A simulation file has a lms of all by default, eg no simulation_foo.txt:t1 nor --t1 if (specified_device.linkmodes.empty()) lms.setAll(); - detected.setAsFound("", DEVICE_SIMULATION, 0 , false, false, lms); + detected.setAsFound("", DEVICE_SIMULATION, 0 , false, lms); return detected; } @@ -4682,7 +4682,7 @@ Detected detectWMBusDeviceWithFile(SpecifiedDevice &specified_device, debug("(lookup) driver: rawtty\n"); // A rawtty has a lms of all by default, eg no simulation_foo.txt:t1 nor --t1 if (specified_device.linkmodes.empty()) lms.setAll(); - detected.setAsFound("", DEVICE_RAWTTY, atoi(specified_device.bps.c_str()), false, false, lms); + detected.setAsFound("", DEVICE_RAWTTY, atoi(specified_device.bps.c_str()), false, lms); return detected; } @@ -4696,7 +4696,7 @@ Detected detectWMBusDeviceWithFile(SpecifiedDevice &specified_device, // Default to 2400. This will be adjusted every time the meters are probed. bps = 2400; } - detected.setAsFound("", DEVICE_MBUS, bps, false, false, lms); + detected.setAsFound("", DEVICE_MBUS, bps, false, lms); return detected; } @@ -4706,7 +4706,7 @@ Detected detectWMBusDeviceWithFile(SpecifiedDevice &specified_device, debug("(lookup) driver: raw file\n"); // A rawtty has a lms of all by default, eg no simulation_foo.txt:t1 nor --t1 if (specified_device.linkmodes.empty()) lms.setAll(); - detected.setAsFound("", DEVICE_RAWTTY, 0, true, false, lms); + detected.setAsFound("", DEVICE_RAWTTY, 0, true, lms); return detected; } @@ -4717,8 +4717,7 @@ Detected detectWMBusDeviceWithFile(SpecifiedDevice &specified_device, { debug("(lookup) driver: %s\n", toString(specified_device.type)); assert(!lms.empty()); - detected.setAsFound("", specified_device.type, 0, specified_device.is_file || specified_device.is_stdin, - false, lms); + detected.setAsFound("", specified_device.type, 0, specified_device.is_file || specified_device.is_stdin, lms); return detected; } // Ok, we are left with a single /dev/ttyUSB0 lets talk to it @@ -4751,7 +4750,7 @@ Detected detectWMBusDeviceWithCommand(SpecifiedDevice &specified_device, LinkModeSet lms = specified_device.linkmodes; // If the specified device did not set any linkmodes fall back on the default linkmodes. if (lms.empty()) lms = default_linkmodes; - detected.setAsFound("", specified_device.type, 0, false, true, lms); + detected.setAsFound("", specified_device.type, 0, false, lms); return detected; } diff --git a/src/wmbus.h b/src/wmbus.h index 7a3f112..1a198b4 100644 --- a/src/wmbus.h +++ b/src/wmbus.h @@ -178,22 +178,20 @@ struct Detected string found_file; // The device file to use. string found_device_id; // An "unique" identifier, typically the id used by the dongle as its own wmbus id, if it transmits. WMBusDeviceType found_type {}; // IM871A, AMB8465 etc. - int found_bps {}; // Serial speed of tty, overrides - bool found_tty_override {}; // override tty - bool found_cmd_override {}; // override cmd + int found_bps {}; // Serial speed of tty. + bool found_tty_override {}; void setSpecifiedDevice(SpecifiedDevice sd) { specified_device = sd; } - void setAsFound(string id, WMBusDeviceType t, int b, bool to, bool co, LinkModeSet clm) + void setAsFound(string id, WMBusDeviceType t, int b, bool to, LinkModeSet clm) { found_device_id = id; found_type = t; found_bps = b; found_tty_override = to; - found_cmd_override = co; } std::string str() @@ -589,18 +587,21 @@ Detected detectWMBusDeviceWithCommand(SpecifiedDevice &specified_device, shared_ptr handler); -shared_ptr openIM871A(string device, shared_ptr manager, +shared_ptr openIM871A(Detected detected, shared_ptr manager, shared_ptr serial_override); -shared_ptr openAMB8465(string device, shared_ptr manager, +shared_ptr openAMB8465(Detected detected, shared_ptr manager, shared_ptr serial_override); shared_ptr openRawTTY(string device, int baudrate, shared_ptr manager, shared_ptr serial_override); -shared_ptr openMBUS(string device, int baudrate, shared_ptr manager, +shared_ptr openMBUS(Detected detected, shared_ptr manager, shared_ptr serial_override); shared_ptr openRC1180(string device, shared_ptr manager, shared_ptr serial_override); -shared_ptr openRTLWMBUS(string identifier, SpecifiedDevice device, bool daemon, - shared_ptr manager, shared_ptr serial_override); +shared_ptr openRTLWMBUS(Detected detected, + string bin_dir, + bool daemon, + shared_ptr manager, + shared_ptr serial_override); shared_ptr openRTL433(string identifier, string command, shared_ptr manager, shared_ptr serial_override); shared_ptr openCUL(string device, shared_ptr manager, diff --git a/src/wmbus_amb8465.cc b/src/wmbus_amb8465.cc index e223dd8..3d956d4 100644 --- a/src/wmbus_amb8465.cc +++ b/src/wmbus_amb8465.cc @@ -139,8 +139,9 @@ private: void handleMessage(int msgid, vector &frame, int rssi_dbm); }; -shared_ptr openAMB8465(string device, shared_ptr manager, shared_ptr serial_override) +shared_ptr openAMB8465(Detected detected, shared_ptr manager, shared_ptr serial_override) { + string device = detected.found_file; assert(device != ""); if (serial_override) @@ -605,7 +606,7 @@ AccessCheck detectAMB8465(Detected *detected, shared_ptrsetAsFound(config.dongleId(), WMBusDeviceType::DEVICE_AMB8465, 9600, false, false, + detected->setAsFound(config.dongleId(), WMBusDeviceType::DEVICE_AMB8465, 9600, false, detected->specified_device.linkmodes); verbose("(amb8465) detect %s\n", config.str().c_str()); diff --git a/src/wmbus_cul.cc b/src/wmbus_cul.cc index 9d648c7..8095ed0 100644 --- a/src/wmbus_cul.cc +++ b/src/wmbus_cul.cc @@ -423,7 +423,7 @@ AccessCheck detectCUL(Detected *detected, shared_ptr return AccessCheck::NotThere; } - detected->setAsFound("", WMBusDeviceType::DEVICE_CUL, 38400, false, false, detected->specified_device.linkmodes); + detected->setAsFound("", WMBusDeviceType::DEVICE_CUL, 38400, false, detected->specified_device.linkmodes); verbose("(cul) are you there? yes\n"); diff --git a/src/wmbus_im871a.cc b/src/wmbus_im871a.cc index efe8010..b708812 100644 --- a/src/wmbus_im871a.cc +++ b/src/wmbus_im871a.cc @@ -228,9 +228,10 @@ int toDBM(int rssi) return dbm; } -shared_ptr openIM871A(string device, shared_ptr manager, shared_ptr serial_override) +shared_ptr openIM871A(Detected detected, shared_ptr manager, shared_ptr serial_override) { - assert(device != ""); + string device_file = detected.found_file; + assert(device_file != ""); if (serial_override) { WMBusIM871A *imp = new WMBusIM871A(serial_override, manager); @@ -238,7 +239,7 @@ shared_ptr openIM871A(string device, shared_ptr(imp); } - auto serial = manager->createSerialDeviceTTY(device.c_str(), 57600, PARITY::NONE, "im871a"); + auto serial = manager->createSerialDeviceTTY(device_file.c_str(), 57600, PARITY::NONE, "im871a"); WMBusIM871A *imp = new WMBusIM871A(serial, manager); return shared_ptr(imp); } @@ -911,7 +912,7 @@ AccessCheck detectIM871A(Detected *detected, shared_ptrsetAsFound(co.dongleId(), WMBusDeviceType::DEVICE_IM871A, 57600, false, false, + detected->setAsFound(co.dongleId(), WMBusDeviceType::DEVICE_IM871A, 57600, false, detected->specified_device.linkmodes); verbose("(im871a) are you there? yes %s\n", co.dongleId().c_str()); diff --git a/src/wmbus_rawtty.cc b/src/wmbus_rawtty.cc index 1d76e25..e1d9df3 100644 --- a/src/wmbus_rawtty.cc +++ b/src/wmbus_rawtty.cc @@ -159,7 +159,7 @@ AccessCheck detectRAWTTY(Detected *detected, shared_ptrclose(); - detected->setAsFound("", WMBusDeviceType::DEVICE_RAWTTY, bps, false, false, + detected->setAsFound("", WMBusDeviceType::DEVICE_RAWTTY, false, bps, detected->specified_device.linkmodes); return AccessCheck::AccessOK; diff --git a/src/wmbus_rc1180.cc b/src/wmbus_rc1180.cc index e5ec727..fb13c58 100644 --- a/src/wmbus_rc1180.cc +++ b/src/wmbus_rc1180.cc @@ -410,7 +410,7 @@ AccessCheck detectRC1180(Detected *detected, shared_ptrclose(); - detected->setAsFound(co.dongleId(), WMBusDeviceType::DEVICE_RC1180, 19200, false, false, + detected->setAsFound(co.dongleId(), WMBusDeviceType::DEVICE_RC1180, 19200, false, detected->specified_device.linkmodes); verbose("(rc1180) are you there? yes %s\n", co.dongleId().c_str()); diff --git a/src/wmbus_rtl433.cc b/src/wmbus_rtl433.cc index e0a3872..530a60a 100644 --- a/src/wmbus_rtl433.cc +++ b/src/wmbus_rtl433.cc @@ -305,7 +305,7 @@ FrameStatus WMBusRTL433::checkRTL433Frame(vector &data, AccessCheck detectRTL433(Detected *detected, shared_ptr handler) { - detected->setAsFound("", WMBusDeviceType::DEVICE_RTL433, 0, false, false, + detected->setAsFound("", WMBusDeviceType::DEVICE_RTL433, 0, false, detected->specified_device.linkmodes); return AccessCheck::AccessOK; diff --git a/src/wmbus_rtlwmbus.cc b/src/wmbus_rtlwmbus.cc index 6ff2006..1109a90 100644 --- a/src/wmbus_rtlwmbus.cc +++ b/src/wmbus_rtlwmbus.cc @@ -80,10 +80,14 @@ private: string setup_; }; -shared_ptr openRTLWMBUS(string identifier, SpecifiedDevice device, bool daemon, +shared_ptr openRTLWMBUS(Detected detected, + string bin_dir, + bool daemon, shared_ptr manager, shared_ptr serial_override) { + string identifier = detected.found_device_id; + SpecifiedDevice &device = detected.specified_device; string command; int id = 0; @@ -102,25 +106,39 @@ shared_ptr openRTLWMBUS(string identifier, SpecifiedDevice device, bool d { freq = device.fq; } - string prefix = ""; - if (daemon) + string rtl_sdr; + string rtl_wmbus; + rtl_sdr = lookForExecutable("rtl_sdr", bin_dir, "/usr/bin"); + if (rtl_sdr == "") { - prefix = "/usr/bin/"; - if (command == "") + if (daemon) { - // Default command is used, check that the binaries are in place. - if (!checkFileExists("/usr/bin/rtl_sdr")) - { - error("(rtlwmbus) error: when starting as daemon, wmbusmeters expects /usr/bin/rtl_sdr to exist!\n"); - } - if (!checkFileExists("/usr/bin/rtl_wmbus")) - { - error("(rtlwmbus) error: when starting as daemon, wmbusmeters expects /usr/bin/rtl_wmbus to exist!\n"); - } + error("(rtlwmbus) error: when starting as daemon, wmbusmeters looked for %s/rtl_sdr and %s/rtl_sdr, but found neither!\n", + bin_dir.c_str(), "/usr/bin"); + } + else + { + // Look for it in the PATH + rtl_sdr = "rtl_sdr"; } } - if (command == "") { - command = prefix+"rtl_sdr -d "+to_string(id)+" -f "+freq+" -s 1.6e6 - 2>/dev/null | "+prefix+"rtl_wmbus"; + rtl_wmbus = lookForExecutable("rtl_wmbus", bin_dir, "/usr/bin"); + if (rtl_wmbus == "") + { + if (daemon) + { + error("(rtlwmbus) error: when starting as daemon, wmbusmeters looked for %s/rtl_wmbus and %s/rtl_wmbus, but found neither!\n", + bin_dir.c_str(), "/usr/bin"); + } + else + { + // Look for it in the PATH + rtl_wmbus = "rtl_wmbus"; + } + } + if (command == "") + { + command = rtl_sdr+" -d "+to_string(id)+" -f "+freq+" -s 1.6e6 - 2>/dev/null | "+rtl_wmbus; } verbose("(rtlwmbus) using command: %s\n", command.c_str()); }