diff --git a/CHANGES b/CHANGES index 7e2c892..0c7c320 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,8 @@ +Improved verbose logging to show if you are not in the dialout +group when trying to find dongles. Install now adds the current +user to the dialout group as well. + Added support for the Hydrocal-M3 heating/cooling meter. Added support for the Apator uniSMART gas meter. diff --git a/README.md b/README.md index 6821023..085944d 100644 --- a/README.md +++ b/README.md @@ -656,14 +656,17 @@ and adds the user `wmbusmeters` with no login account. # Common problems +If wmbusmeters detects no device, but you know you have plugged in your wmbus dongle, then +run with `--verbose` to get more information on why the devices are not detected. +Typically this is because you are not in the dialout (for usb-serial dongles) or plugdev (for rtlsdr) group. + +Run `sudo make install` to add the current user to the dialout group and the wmbusmeters group. + If the daemon has started then the wmbus device will be taken and you cannot start wmbusmeters manually. -To run manually, first make sure the daemon is stopped `sudo stop wmbusmeters@-dev-im871a_0.server` +To run manually, first make sure the daemon is stopped `sudo systemctl stop wmbusmeters` if this hangs, then do `sudo killall -9 wmbusmetersd` and/or `sudo killall -9 wmbusmeters`. -If you are using rtl_sdr/rtl_wmbus and you want to stop the daemon, do -`sudo stop wmbusmeters@-dev-rtlsdr_3.server` followed by `sudo killall -9 rtl_sdr`. - ## How to receive telegrams over longer distances I only have personal experience of the im871a,amb8465 and an rtlsdr diff --git a/install.sh b/install.sh index 76336e0..9df9822 100755 --- a/install.sh +++ b/install.sh @@ -58,3 +58,5 @@ ROOT=$ROOT /bin/sh ./scripts/prepare_logfiles.sh ROOT=$ROOT /bin/sh ./scripts/install_default_configuration.sh ROOT=$ROOT /bin/sh ./scripts/install_systemd_service.sh + +ROOT=$ROOT /bin/sh ./scripts/add_myself_to_dialout.sh diff --git a/scripts/add_myself_to_dialout.sh b/scripts/add_myself_to_dialout.sh new file mode 100755 index 0000000..0c09b19 --- /dev/null +++ b/scripts/add_myself_to_dialout.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +if [ ! -z "$SUDO_USER" ] +then + if [ "$(getent group dialout | grep $SUDO_USER)" = "" ] + then + usermod -a -G dialout $SUDO_USER + echo "group: added $SUDO_USER to group dialout" + else + echo "group: $SUDO_USER already member of dialout" + fi + + if [ "$(groups $SUDO_USER | grep -o wmbusmeters)" = "" ] + then + usermod -a -G wmbusmeters $SUDO_USER + echo "group: added $SUDO_USER to group wmbusmeters" + else + echo "group: user $SUDO_USER already member of wmbusmeters" + fi +fi diff --git a/src/admin.cc b/src/admin.cc index e6e263f..6c40c5b 100644 --- a/src/admin.cc +++ b/src/admin.cc @@ -24,6 +24,7 @@ #include"serial.h" #include"shell.h" #include"ui.h" +#include"util.h" #include"wmbus.h" bool running_as_root_ = false; @@ -99,6 +100,9 @@ int main(int argc, char **argv) enableSyslog(); } + // Handle exit on signals... + onExit(exitUI); + initUI(); clear(); @@ -160,6 +164,8 @@ int main(int argc, char **argv) break; } } while (running); + + exitUI(); } void alwaysOnScreen() @@ -289,7 +295,7 @@ void resetWMBUSReceiver() } } -void probeFor(string type, AccessCheck (*check)(Detected*,shared_ptr)) +void probeFor(string type, AccessCheck (*probe)(Detected*,shared_ptr)) { Detected detected {}; vector devices = handler->listSerialTTYs(); @@ -297,24 +303,33 @@ void probeFor(string type, AccessCheck (*check)(Detected*,shared_ptr m){ detected.specified_device.file=d; return check(&detected, m);}, - type, - device); + AccessCheck ac = handler->checkAccess(device, + handler, + type, + [&](string d, shared_ptr m){ + detected.found_file=d; + detected.specified_device.file=d; return probe(&detected, m);}); if (ac == AccessCheck::AccessOK) { tty = device+" DETECTED "+type; } - else if (ac == AccessCheck::NotThere) + else if (ac == AccessCheck::NoSuchDevice) { - tty = device+" nothing there"; + tty = device+" no such device"; + } + else if (ac == AccessCheck::NoProperResponse) + { + tty = device+" no response"; } else if (ac == AccessCheck::NotSameGroup) { tty = device+" not same group"; } + else if (ac == AccessCheck::NoPermission) + { + tty = device+" same group but wrong permissions"; + } entries.push_back(tty); } if (entries.size() == 0) diff --git a/src/mbus_rawtty.cc b/src/mbus_rawtty.cc index 8b33350..f1e28bb 100644 --- a/src/mbus_rawtty.cc +++ b/src/mbus_rawtty.cc @@ -197,8 +197,8 @@ AccessCheck detectMBUS(Detected *detected, shared_ptrcreateSerialDeviceTTY(tty.c_str(), bps, PARITY::EVEN, "detect mbus"); - AccessCheck rc = serial->open(false); - if (rc != AccessCheck::AccessOK) return AccessCheck::NotThere; + bool ok = serial->open(false); + if (!ok) return AccessCheck::NoSuchDevice; serial->close(); diff --git a/src/rtlsdr.cc b/src/rtlsdr.cc index 2a6f2bd..fe94967 100644 --- a/src/rtlsdr.cc +++ b/src/rtlsdr.cc @@ -106,7 +106,7 @@ AccessCheck detectRTLSDR(string serialnr, Detected *detected) if (detected->specified_device.type != WMBusDeviceType::DEVICE_RTLWMBUS && detected->specified_device.type != WMBusDeviceType::DEVICE_RTL433) { - return AccessCheck::NotThere; + return AccessCheck::NoSuchDevice; } uint32_t n = rtlsdr_get_device_count(); @@ -129,7 +129,7 @@ AccessCheck detectRTLSDR(string serialnr, Detected *detected) } // Something is wrong. - return AccessCheck::NotThere; + return AccessCheck::NoSuchDevice; } /* diff --git a/src/serial.cc b/src/serial.cc index 93d81c0..bbde11b 100644 --- a/src/serial.cc +++ b/src/serial.cc @@ -44,6 +44,8 @@ #include #endif +// return a positive integer (file descriptor) on success. +// return -1 for failure to open. return -2 for already locked. static int openSerialTTY(const char *tty, int baud_rate, PARITY parity); static string showTTYSettings(int fd); @@ -94,6 +96,11 @@ struct SerialCommunicationManagerImp : public SerialCommunicationManager int startRegularCallback(string name, int seconds, function callback); void stopRegularCallback(int id); + AccessCheck checkAccess(string device, + shared_ptr manager, + string extra_info, + function)> extra_probe); + vector listSerialTTYs(); shared_ptr lookup(std::string device); bool removeNonWorking(std::string device); @@ -285,7 +292,7 @@ struct SerialDeviceTTY : public SerialDeviceImp SerialDeviceTTY(string device, int baud_rate, PARITY parity, SerialCommunicationManagerImp * manager, string purpose); ~SerialDeviceTTY(); - AccessCheck open(bool fail_if_not_ok); + bool open(bool fail_if_not_ok); void close(); bool send(vector &data); bool working(); @@ -313,39 +320,26 @@ SerialDeviceTTY::~SerialDeviceTTY() close(); } -AccessCheck SerialDeviceTTY::open(bool fail_if_not_ok) +bool SerialDeviceTTY::open(bool fail_if_not_ok) { assert(device_ != ""); bool ok = checkCharacterDeviceExists(device_.c_str(), fail_if_not_ok); - if (!ok) return AccessCheck::NotThere; + if (!ok) return false; fd_ = openSerialTTY(device_.c_str(), baud_rate_, parity_); - if (fd_ < 0) + if (fd_ == -1) { - if (fail_if_not_ok) - { - if (fd_ == -1) - { - error("Could not open %s with %d baud N81\n", device_.c_str(), baud_rate_); - } - else if (fd_ == -2) - { - error("Device %s is already in use and locked.\n", device_.c_str()); - } - } - else - { - if (fd_ == -1) - { - return AccessCheck::NotThere; - } - else if (fd_ == -2) - { - return AccessCheck::NotSameGroup; - } - } + if (fail_if_not_ok) error("Could not open %s with %d baud N81\n", device_.c_str(), baud_rate_); + verbose("(serialtty) could not open %s with %d baud N81\n", device_.c_str(), baud_rate_); + return false; + } + if (fd_ == -2) + { + if (fail_if_not_ok) error("Device %s is already in use and locked.\n", device_.c_str()); + verbose("(serialtty) device %s is already in use and locked.\n", device_.c_str()); + return false; } verbose("(serialtty) opened %s fd %d (%s)\n", device_.c_str(), fd_, purpose_.c_str()); - return AccessCheck::AccessOK; + return true; } void SerialDeviceTTY::close() @@ -426,7 +420,7 @@ struct SerialDeviceCommand : public SerialDeviceImp string purpose); ~SerialDeviceCommand(); - AccessCheck open(bool fail_if_not_ok); + bool open(bool fail_if_not_ok); void close(); bool send(vector &data); int available(); @@ -466,15 +460,15 @@ SerialDeviceCommand::~SerialDeviceCommand() close(); } -AccessCheck SerialDeviceCommand::open(bool fail_if_not_ok) +bool SerialDeviceCommand::open(bool fail_if_not_ok) { expectAscii(); bool ok = invokeBackgroundShell("/bin/sh", args_, envs_, &fd_, &pid_); assert(fd_ >= 0); - if (!ok) return AccessCheck::NotThere; + if (!ok) return false; setIsStdin(); verbose("(serialcmd) opened %s pid %d fd %d (%s)\n", command_.c_str(), pid_, fd_, purpose_.c_str()); - return AccessCheck::AccessOK; + return true; } void SerialDeviceCommand::close() @@ -553,7 +547,7 @@ struct SerialDeviceFile : public SerialDeviceImp SerialDeviceFile(string file, SerialCommunicationManagerImp *manager, string purpose); ~SerialDeviceFile(); - AccessCheck open(bool fail_if_not_ok); + bool open(bool fail_if_not_ok); void close(); bool working(); bool send(vector &data); @@ -578,7 +572,7 @@ SerialDeviceFile::~SerialDeviceFile() close(); } -AccessCheck SerialDeviceFile::open(bool fail_if_not_ok) +bool SerialDeviceFile::open(bool fail_if_not_ok) { if (file_ == "stdin") { @@ -592,25 +586,20 @@ AccessCheck SerialDeviceFile::open(bool fail_if_not_ok) else { bool ok = checkFileExists(file_.c_str()); - if (!ok) return AccessCheck::NotThere; + if (!ok) return false; fd_ = ::open(file_.c_str(), O_RDONLY | O_NONBLOCK); if (fd_ == -1) { - if (fail_if_not_ok) - { - error("Could not open file %s for reading.\n", file_.c_str()); - } - else - { - return AccessCheck::NotThere; - } + if (fail_if_not_ok) error("Could not open file %s for reading.\n", file_.c_str()); + verbose("(serialdevicefile) could not open file %s for reading.\n", file_.c_str()); + return false; } setIsFile(); verbose("(serialfile) reading from file %s (%s)\n", file_.c_str(), purpose_.c_str()); } manager_->tickleEventLoop(); - return AccessCheck::AccessOK; + return true; } void SerialDeviceFile::close() @@ -656,7 +645,7 @@ struct SerialDeviceSimulator : public SerialDeviceImp }; ~SerialDeviceSimulator() { }; - AccessCheck open(bool fail_if_not_ok) { return AccessCheck::AccessOK; }; + bool open(bool fail_if_not_ok) { return true; }; void close() { }; bool readonly() { return true; } bool send(vector &data) { return true; }; @@ -1602,3 +1591,52 @@ err: return "error"; } + +AccessCheck SerialCommunicationManagerImp::checkAccess(string device, + shared_ptr manager, + string extra_info, + function)> extra_probe) +{ + assert(device != ""); + + if (extra_info == "") + { + extra_info = "serial"; + } + + debug("(%s) check if %s can be accessed\n", extra_info.c_str(), device.c_str()); + + AccessCheck ac = checkIfExistsAndHasAccess(device); + + if (ac == AccessCheck::AccessOK) + { + if (!extra_probe) + { + verbose("(%s) tty %s can be accessed\n", extra_info.c_str(), device.c_str()); + return AccessCheck::AccessOK; + } + verbose("(%s) tty %s can be accessed now probing...\n", extra_info.c_str(), device.c_str()); + ac = extra_probe(device, manager); + verbose("(%s) probe returns %s\n", extra_info.c_str(), toString(ac)); + return ac; + } + + if (ac == AccessCheck::NoPermission) + { + verbose("(serial) you do not have the correct permissions to open the tty %s, but at least you share the same access group.\n", + device.c_str()); + return AccessCheck::NoPermission; + } + + if (ac == AccessCheck::NotSameGroup) + { + verbose("(serial) you do not have the correct permissions to open the tty %s and you do not share the same access group.\n", + device.c_str()); + return AccessCheck::NotSameGroup; + } + + verbose("(serial) cannot open/find tty %s.\n", + device.c_str()); + + return AccessCheck::NoSuchDevice; +} diff --git a/src/serial.h b/src/serial.h index cd5c7da..9655f33 100644 --- a/src/serial.h +++ b/src/serial.h @@ -39,7 +39,7 @@ enum class PARITY { NONE, EVEN, ODD }; struct SerialDevice { // If fail_if_not_ok then forcefully exit the program if cannot be opened. - virtual AccessCheck open(bool fail_if_not_ok) = 0; + virtual bool open(bool fail_if_not_ok) = 0; virtual void close() = 0; // Explicitly closed fd == -1 virtual bool isClosed() = 0; @@ -106,6 +106,11 @@ struct SerialCommunicationManager virtual int startRegularCallback(std::string name, int seconds, function callback) = 0; virtual void stopRegularCallback(int id) = 0; + // Verify if the device can be accessed and verbose any failures. + virtual AccessCheck checkAccess(std::string device, + shared_ptr manager, // Silly but for now, needs shared pointer to itself.... + std::string extra_info = "", + function)> extra_probe = NULL) = 0; // List all real serial devices (avoid pseudo ttys) virtual std::vector listSerialTTYs() = 0; // Return a serial device for the given device, if it exists! Otherwise NULL. diff --git a/src/ui.cc b/src/ui.cc index 4953e25..7c0c2a6 100644 --- a/src/ui.cc +++ b/src/ui.cc @@ -42,6 +42,11 @@ void initUI() wbkgd(stdscr, COLOR_PAIR(BG_PAIR)); } +void exitUI() +{ + endwin(); +} + void registerUpdateCB(std::function cb) { update_cb_ = cb; diff --git a/src/ui.h b/src/ui.h index ae547e9..3005db5 100644 --- a/src/ui.h +++ b/src/ui.h @@ -36,6 +36,7 @@ #define HILIGHT_PAIR 4 void initUI(); +void exitUI(); void registerUpdateCB(std::function cb); diff --git a/src/util.cc b/src/util.cc index 0dc9035..201ffe8 100644 --- a/src/util.cc +++ b/src/util.cc @@ -1373,36 +1373,70 @@ void addMonths(struct tm *date, int months) date->tm_mday = day; } -AccessCheck checkIfExistsAndSameGroup(string device) +const char* toString(AccessCheck ac) { - struct stat sb; + switch (ac) + { + case AccessCheck::NoSuchDevice: return "NoSuchDevice"; + case AccessCheck::NoProperResponse: return "NoProperResponse"; + case AccessCheck::NoPermission: return "NoPermission"; + case AccessCheck::NotSameGroup: return "NotSameGroup"; + case AccessCheck::AccessOK: return "AccessOK"; + } + return "?"; +} - int ok = stat(device.c_str(), &sb); +AccessCheck checkIfExistsAndHasAccess(string device) +{ + struct stat device_sb; + + int ok = stat(device.c_str(), &device_sb); // The file did not exist. - if (ok) return AccessCheck::NotThere; + if (ok) return AccessCheck::NoSuchDevice; + + int r = access(device.c_str(), R_OK); + int w = access(device.c_str(), W_OK); + if (r == 0 && w == 0) + { + // We have read and write access! + return AccessCheck::AccessOK; + } + + // We are not permitted to read and write to this tty. Why? + // Lets check the group settings. #if defined(__APPLE__) && defined(__MACH__) - int groups[256]; + int my_groups[256]; #else - gid_t groups[256]; + gid_t my_groups[256]; #endif int ngroups = 256; struct passwd *p = getpwuid(getuid()); - int rc = getgrouplist(p->pw_name, p->pw_gid, groups, &ngroups); + // What are the groups I am member of? + int rc = getgrouplist(p->pw_name, p->pw_gid, my_groups, &ngroups); if (rc < 0) { error("(wmbusmeters) cannot handle users with more than 256 groups\n"); } - struct group *g = getgrgid(sb.st_gid); - for (int i=0; igr_gid) { - return AccessCheck::AccessOK; + // What is the group of the tty? + struct group *device_group = getgrgid(device_sb.st_gid); + + // Go through my groups to see if the device's group is in there. + for (int i=0; igr_gid) + { + // We belong to the same group as the tty. Typically dialout. + // Then there is some other reason for the lack of access. + return AccessCheck::NoPermission; } } - + // We have examined all the groups that we belong to and yet not + // found the device's group. We can at least conclude that we + // being in the device's group would help, ie dialout. return AccessCheck::NotSameGroup; } diff --git a/src/util.h b/src/util.h index a1b74b5..5f49712 100644 --- a/src/util.h +++ b/src/util.h @@ -174,10 +174,15 @@ void eatWhitespace(std::vector &v, std::vector::iterator &i, bool *e std::string eatToSkipWhitespace(std::vector &v, std::vector::iterator &i, int c, size_t max, bool *eof, bool *err); // Remove leading and trailing white space void trimWhitespace(std::string *s); -// Returns true if device exists and this programs user, belongs -// to the same group that the device belongs to. -enum class AccessCheck { NotThere, NotSameGroup, Locked, AccessOK }; -AccessCheck checkIfExistsAndSameGroup(std::string device); +// Returns AccessOK if device exists and is accessible. +// NotSameGroup means that there is no permission and the groups do not match. +// NoPermission means some other reason for no access. (missing rw etc) +// Locked means that some other process has locked the tty. +// NoSuchDevice means the tty does not exist. +// NoProperResponse means that we talked to something, but we do not know what it is. +enum class AccessCheck { NoSuchDevice, NoProperResponse, NoPermission, NotSameGroup, AccessOK }; +const char* toString(AccessCheck ac); +AccessCheck checkIfExistsAndHasAccess(std::string device); // Count the number of 1:s in the binary number v. int countSetBits(int v); diff --git a/src/wmbus.cc b/src/wmbus.cc index a5458db..94382d7 100644 --- a/src/wmbus.cc +++ b/src/wmbus.cc @@ -3693,9 +3693,9 @@ bool WMBusCommonImplementation::reset() usleep(3000*1000); } - AccessCheck rc = serial()->open(false); + bool ok = serial()->open(false); - if (rc != AccessCheck::AccessOK) + if (!ok) { // Ouch.... return false; @@ -4008,61 +4008,6 @@ LIST_OF_AFL_AUTH_TYPES return AFLAuthenticationType::Reserved1; } -AccessCheck findAndDetect(shared_ptr manager, - string *out_device, - function)> check, - string dongle_name, - string device_root) -{ - string dev = device_root; - debug("(%s) exists? %s\n", dongle_name.c_str(), dev.c_str()); - AccessCheck ac = checkIfExistsAndSameGroup(dev); - *out_device = dev; - if (ac == AccessCheck::AccessOK) - { - debug("(%s) checking %s\n", dongle_name.c_str(), dev.c_str()); - AccessCheck rc = check(dev, manager); - if (rc == AccessCheck::AccessOK) return AccessCheck::AccessOK; - } - - if (ac == AccessCheck::NotSameGroup) - { - // Device exists, but you do not belong to its group! - // This will short circuit testing for other devices. - // But not being in the same group is such a problematic - // situation, that we can stop early. - return AccessCheck::NotSameGroup; - } - - *out_device = ""; - // No device found! - return AccessCheck::NotThere; -} - -AccessCheck checkAccessAndDetect(shared_ptr manager, - function)> check, - string dongle_name, - string device) -{ - debug("(%s) exists? %s\n", dongle_name.c_str(), device.c_str()); - AccessCheck ac = checkIfExistsAndSameGroup(device); - if (ac == AccessCheck::AccessOK) - { - debug("(%s) checking %s\n", dongle_name.c_str(), device.c_str()); - AccessCheck rc = check(device, manager); - if (rc == AccessCheck::AccessOK) return AccessCheck::AccessOK; - return AccessCheck::NotThere; - } - if (ac == AccessCheck::NotSameGroup) - { - // Device exists, but you do not belong to its group! - return AccessCheck::NotSameGroup; - } - - // No device found! - return AccessCheck::NotThere; -} - bool trimCRCsFrameFormatA(std::vector &payload) { if (payload.size() < 12) { @@ -4750,6 +4695,14 @@ Detected detectWMBusDeviceOnTTY(string tty, detected.specified_device.is_tty = true; detected.specified_device.linkmodes = desired_linkmodes; + AccessCheck ac = handler->checkAccess(tty, handler); + if (ac != AccessCheck::AccessOK) + { + // Oups, some low level problem (permissions/groups etc) that means that we will not + // be able to talk to the device. Lets stop here. + return detected; + } + // If im87a is tested first, a delay of 1s must be inserted // before amb8465 is tested, lest it will not respond properly. // It really should not matter, but perhaps is the uart of the amber @@ -4790,8 +4743,8 @@ Detected detectWMBusDeviceOnTTY(string tty, } Detected detectWMBusDeviceWithFileOrHex(SpecifiedDevice &specified_device, - LinkModeSet default_linkmodes, - shared_ptr handler) + LinkModeSet default_linkmodes, + shared_ptr handler) { assert(specified_device.file != "" || specified_device.hex != ""); assert(specified_device.command == ""); @@ -4901,23 +4854,23 @@ Detected detectWMBusDeviceWithCommand(SpecifiedDevice &specified_device, AccessCheck detectUNKNOWN(Detected *detected, shared_ptr handler) { - return AccessCheck::NotThere; + return AccessCheck::NoSuchDevice; } AccessCheck detectSKIP(Detected *detected, shared_ptr handler) { - return AccessCheck::NotThere; + return AccessCheck::NoSuchDevice; } AccessCheck detectSIMULATION(Detected *detected, shared_ptr handler) { - return AccessCheck::NotThere; + return AccessCheck::NoSuchDevice; } AccessCheck detectAUTO(Detected *detected, shared_ptr handler) { // Detection of auto is currently not implemented here, but elsewhere. - return AccessCheck::NotThere; + return AccessCheck::NoSuchDevice; } AccessCheck reDetectDevice(Detected *detected, shared_ptr handler) @@ -4929,7 +4882,7 @@ LIST_OF_MBUS_DEVICES #undef X assert(0); - return AccessCheck::NotThere; + return AccessCheck::NoSuchDevice; } bool usesRTLSDR(WMBusDeviceType t) diff --git a/src/wmbus.h b/src/wmbus.h index acb07ca..d020d9c 100644 --- a/src/wmbus.h +++ b/src/wmbus.h @@ -688,17 +688,6 @@ MeasurementType difMeasurementType(int dif); string linkModeName(LinkMode link_mode); string measurementTypeName(MeasurementType mt); -AccessCheck findAndDetect(shared_ptr manager, - string *out_device, - function)> check, - string dongle_name, - string device_root); - -AccessCheck checkAccessAndDetect(shared_ptr manager, - function)> check, - string dongle_name, - string device); - enum FrameStatus { PartialFrame, FullFrame, ErrorInFrame, TextAndNotFrame }; diff --git a/src/wmbus_amb8465.cc b/src/wmbus_amb8465.cc index d99d42b..4842686 100644 --- a/src/wmbus_amb8465.cc +++ b/src/wmbus_amb8465.cc @@ -587,14 +587,16 @@ void WMBusAmber::handleMessage(int msgid, vector &frame, int rssi_dbm) AccessCheck detectAMB8465(Detected *detected, shared_ptr manager) { + assert(detected->found_file != ""); + // Talk to the device and expect a very specific answer. auto serial = manager->createSerialDeviceTTY(detected->found_file.c_str(), 9600, PARITY::NONE, "detect amb8465"); serial->disableCallbacks(); - AccessCheck rc = serial->open(false); - if (rc != AccessCheck::AccessOK) + bool ok = serial->open(false); + if (!ok) { - debug("(amb8465) could not open tty for detection\n"); - return AccessCheck::NotThere; + verbose("(amb8465) could not open tty %s for detection\n", detected->found_file.c_str()); + return AccessCheck::NoSuchDevice; } vector response; @@ -659,7 +661,7 @@ AccessCheck detectAMB8465(Detected *detected, shared_ptrclose(); - return AccessCheck::NotThere; + return AccessCheck::NoProperResponse; } } } while (sent == false && count < 4); @@ -676,7 +678,7 @@ AccessCheck detectAMB8465(Detected *detected, shared_ptrclose(); - return AccessCheck::NotThere; + return AccessCheck::NoProperResponse; } debug("(amb8465) reading response... %d\n", count); @@ -725,10 +727,11 @@ static AccessCheck tryFactoryResetAMB8465(string device, shared_ptrcreateSerialDeviceTTY(device.c_str(), baud, PARITY::NONE, "reset amb8465"); - AccessCheck rc = serial->open(false); - if (rc != AccessCheck::AccessOK) { - verbose("(amb8465) could not open device %s using baud %d\n", device.c_str(), baud); - return AccessCheck::NotThere; + bool ok = serial->open(false); + if (!ok) + { + verbose("(amb8465) could not open device %s using baud %d for reset\n", device.c_str(), baud); + return AccessCheck::NoSuchDevice; } vector data; @@ -776,7 +779,7 @@ static AccessCheck tryFactoryResetAMB8465(string device, shared_ptr manager, int *was_baud) { - AccessCheck rc = AccessCheck::NotThere; + AccessCheck rc = AccessCheck::NoSuchDevice; for (int i=0; bauds[i] != 0; ++i) { @@ -798,5 +801,5 @@ AccessCheck factoryResetAMB8465(string device, shared_ptr // Talk to the device and expect a very specific answer. auto serial = manager->createSerialDeviceTTY(detected->found_file.c_str(), 38400, PARITY::NONE, "detect cul"); serial->disableCallbacks(); - AccessCheck rc = serial->open(false); - if (rc != AccessCheck::AccessOK) return AccessCheck::NotThere; + bool ok = serial->open(false); + if (!ok) return AccessCheck::NoSuchDevice; bool found = false; for (int i=0; i<3; ++i) @@ -401,7 +401,7 @@ AccessCheck detectCUL(Detected *detected, shared_ptr if (!ok) { verbose("(cul) are you there? no\n"); - return AccessCheck::NotThere; + return AccessCheck::NoSuchDevice; } // Wait for 200ms so that the USB stick have time to prepare a response. @@ -422,7 +422,7 @@ AccessCheck detectCUL(Detected *detected, shared_ptr if (!found) { verbose("(cul) are you there? no\n"); - return AccessCheck::NotThere; + return AccessCheck::NoProperResponse; } detected->setAsFound("", WMBusDeviceType::DEVICE_CUL, 38400, false, detected->specified_device.linkmodes); diff --git a/src/wmbus_im871a.cc b/src/wmbus_im871a.cc index c53fbeb..6cc88f8 100644 --- a/src/wmbus_im871a.cc +++ b/src/wmbus_im871a.cc @@ -966,11 +966,17 @@ bool WMBusIM871aIM170A::sendTelegram(ContentStartsWith starts_with, vector manager) { + assert(detected->found_file != ""); + // Talk to the device and expect a very specific answer. auto serial = manager->createSerialDeviceTTY(detected->found_file.c_str(), 57600, PARITY::NONE, "detect im871a"); serial->disableCallbacks(); - AccessCheck rc = serial->open(false); - if (rc != AccessCheck::AccessOK) return AccessCheck::NotThere; + bool ok = serial->open(false); + if (!ok) + { + verbose("(im871a) could not open tty %s for detection\n", detected->found_file.c_str()); + return AccessCheck::NoSuchDevice; + } vector response; // First clear out any data in the queue. @@ -1000,7 +1006,7 @@ AccessCheck detectIM871AIM170A(Detected *detected, shared_ptrclose(); - return AccessCheck::NotThere; + return AccessCheck::NoProperResponse; } vector payload; @@ -1047,7 +1053,7 @@ AccessCheck detectIM871AIM170A(Detected *detected, shared_ptrclose(); - return AccessCheck::NotThere; + return AccessCheck::NoProperResponse; } serial->close(); diff --git a/src/wmbus_rawtty.cc b/src/wmbus_rawtty.cc index 11973da..3a3de76 100644 --- a/src/wmbus_rawtty.cc +++ b/src/wmbus_rawtty.cc @@ -235,8 +235,8 @@ AccessCheck detectRAWTTY(Detected *detected, shared_ptrcreateSerialDeviceTTY(tty.c_str(), bps, PARITY::NONE, "detect rawtty"); - AccessCheck rc = serial->open(false); - if (rc != AccessCheck::AccessOK) return AccessCheck::NotThere; + bool ok = serial->open(false); + if (!ok) return AccessCheck::NoSuchDevice; serial->close(); diff --git a/src/wmbus_rc1180.cc b/src/wmbus_rc1180.cc index b9d6b78..cb767c4 100644 --- a/src/wmbus_rc1180.cc +++ b/src/wmbus_rc1180.cc @@ -163,6 +163,8 @@ private: shared_ptr openRC1180(Detected detected, shared_ptr manager, shared_ptr serial_override) { + assert(detected.found_file != ""); + string bus_alias = detected.specified_device.bus_alias; string device = detected.found_file; assert(device != ""); @@ -341,8 +343,8 @@ AccessCheck detectRC1180(Detected *detected, shared_ptrcreateSerialDeviceTTY(detected->found_file.c_str(), 19200, PARITY::NONE, "detect rc1180"); serial->disableCallbacks(); - AccessCheck rc = serial->open(false); - if (rc != AccessCheck::AccessOK) return AccessCheck::NotThere; + bool ok = serial->open(false); + if (!ok) return AccessCheck::NoSuchDevice; vector data; vector msg(1); @@ -360,7 +362,7 @@ AccessCheck detectRC1180(Detected *detected, shared_ptrclose(); verbose("(rc1180) are you there? no.\n"); - return AccessCheck::NotThere; + return AccessCheck::NoProperResponse; } data.clear(); @@ -375,7 +377,7 @@ AccessCheck detectRC1180(Detected *detected, shared_ptrreceive(&data); ConfigRC1180 co; - bool ok = co.decode(data); + ok = co.decode(data); if (!ok || co.uart_bps != 5) { // Decode must be ok and the uart bps must be 5, @@ -383,7 +385,7 @@ AccessCheck detectRC1180(Detected *detected, shared_ptrclose(); verbose("(rc1180) are you there? no.\n"); - return AccessCheck::NotThere; + return AccessCheck::NoProperResponse; } debug("(rc1180) config: %s\n", co.str().c_str()); diff --git a/src/wmbus_rtl433.cc b/src/wmbus_rtl433.cc index 50dbb8e..b883b0c 100644 --- a/src/wmbus_rtl433.cc +++ b/src/wmbus_rtl433.cc @@ -367,5 +367,5 @@ FrameStatus WMBusRTL433::checkRTL433Frame(vector &data, AccessCheck detectRTL433(Detected *detected, shared_ptr handler) { assert(0); - return AccessCheck::NotThere; + return AccessCheck::NoSuchDevice; } diff --git a/src/wmbus_rtlwmbus.cc b/src/wmbus_rtlwmbus.cc index 8d35954..171b61f 100644 --- a/src/wmbus_rtlwmbus.cc +++ b/src/wmbus_rtlwmbus.cc @@ -420,5 +420,5 @@ FrameStatus WMBusRTLWMBUS::checkRTLWMBUSFrame(vector &data, AccessCheck detectRTLWMBUS(Detected *detected, shared_ptr handler) { assert(0); - return AccessCheck::NotThere; + return AccessCheck::NoSuchDevice; }