kopia lustrzana https://github.com/weetmuts/wmbusmeters
				
				
				
			Improve verbose messages when user is not member of dialout.
							rodzic
							
								
									ba5b37ab7a
								
							
						
					
					
						commit
						678a3a8a0a
					
				
							
								
								
									
										4
									
								
								CHANGES
								
								
								
								
							
							
						
						
									
										4
									
								
								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.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										11
									
								
								README.md
								
								
								
								
							
							
						
						
									
										11
									
								
								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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
							
								
								
									
										27
									
								
								src/admin.cc
								
								
								
								
							
							
						
						
									
										27
									
								
								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<SerialCommunicationManager>))
 | 
			
		||||
void probeFor(string type, AccessCheck (*probe)(Detected*,shared_ptr<SerialCommunicationManager>))
 | 
			
		||||
{
 | 
			
		||||
    Detected detected {};
 | 
			
		||||
    vector<string> devices = handler->listSerialTTYs();
 | 
			
		||||
| 
						 | 
				
			
			@ -297,24 +303,33 @@ void probeFor(string type, AccessCheck (*check)(Detected*,shared_ptr<SerialCommu
 | 
			
		|||
    for (string& device : devices)
 | 
			
		||||
    {
 | 
			
		||||
        string tty = "?";
 | 
			
		||||
        AccessCheck ac = checkAccessAndDetect(
 | 
			
		||||
        AccessCheck ac = handler->checkAccess(device,
 | 
			
		||||
                                              handler,
 | 
			
		||||
            [&](string d, shared_ptr<SerialCommunicationManager> m){ detected.specified_device.file=d; return check(&detected, m);},
 | 
			
		||||
                                              type,
 | 
			
		||||
            device);
 | 
			
		||||
                                              [&](string d, shared_ptr<SerialCommunicationManager> 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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -197,8 +197,8 @@ AccessCheck detectMBUS(Detected *detected, shared_ptr<SerialCommunicationManager
 | 
			
		|||
    // Since we do not know how to talk to the other end, it might not
 | 
			
		||||
    // even respond. The only thing we can do is to try to open the serial device.
 | 
			
		||||
    auto serial = manager->createSerialDeviceTTY(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();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										120
									
								
								src/serial.cc
								
								
								
								
							
							
						
						
									
										120
									
								
								src/serial.cc
								
								
								
								
							| 
						 | 
				
			
			@ -44,6 +44,8 @@
 | 
			
		|||
#include <linux/serial.h>
 | 
			
		||||
#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<void()> callback);
 | 
			
		||||
    void stopRegularCallback(int id);
 | 
			
		||||
 | 
			
		||||
    AccessCheck checkAccess(string device,
 | 
			
		||||
                            shared_ptr<SerialCommunicationManager> manager,
 | 
			
		||||
                            string extra_info,
 | 
			
		||||
                            function<AccessCheck(string,shared_ptr<SerialCommunicationManager>)> extra_probe);
 | 
			
		||||
 | 
			
		||||
    vector<string> listSerialTTYs();
 | 
			
		||||
    shared_ptr<SerialDevice> 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<uchar> &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 (fail_if_not_ok)
 | 
			
		||||
        {
 | 
			
		||||
    if (fd_ == -1)
 | 
			
		||||
    {
 | 
			
		||||
                error("Could not open %s with %d baud N81\n", device_.c_str(), baud_rate_);
 | 
			
		||||
        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;
 | 
			
		||||
    }
 | 
			
		||||
            else if (fd_ == -2)
 | 
			
		||||
    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("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<uchar> &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<uchar> &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<uchar> &data) { return true; };
 | 
			
		||||
| 
						 | 
				
			
			@ -1602,3 +1591,52 @@ err:
 | 
			
		|||
 | 
			
		||||
    return "error";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AccessCheck SerialCommunicationManagerImp::checkAccess(string device,
 | 
			
		||||
                                                       shared_ptr<SerialCommunicationManager> manager,
 | 
			
		||||
                                                       string extra_info,
 | 
			
		||||
                                                       function<AccessCheck(string,shared_ptr<SerialCommunicationManager>)> 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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<void()> 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<SerialCommunicationManager> manager, // Silly but for now, needs shared pointer to itself....
 | 
			
		||||
                                    std::string extra_info = "",
 | 
			
		||||
                                    function<AccessCheck(string,shared_ptr<SerialCommunicationManager>)> extra_probe = NULL) = 0;
 | 
			
		||||
    // List all real serial devices (avoid pseudo ttys)
 | 
			
		||||
    virtual std::vector<std::string> listSerialTTYs() = 0;
 | 
			
		||||
    // Return a serial device for the given device, if it exists! Otherwise NULL.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,6 +42,11 @@ void initUI()
 | 
			
		|||
    wbkgd(stdscr, COLOR_PAIR(BG_PAIR));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void exitUI()
 | 
			
		||||
{
 | 
			
		||||
    endwin();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void registerUpdateCB(std::function<void()> cb)
 | 
			
		||||
{
 | 
			
		||||
    update_cb_ = cb;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								src/ui.h
								
								
								
								
							
							
						
						
									
										1
									
								
								src/ui.h
								
								
								
								
							| 
						 | 
				
			
			@ -36,6 +36,7 @@
 | 
			
		|||
#define HILIGHT_PAIR 4
 | 
			
		||||
 | 
			
		||||
void initUI();
 | 
			
		||||
void exitUI();
 | 
			
		||||
 | 
			
		||||
void registerUpdateCB(std::function<void()> cb);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										58
									
								
								src/util.cc
								
								
								
								
							
							
						
						
									
										58
									
								
								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; i<ngroups; ++i) {
 | 
			
		||||
        if (groups[i] == g->gr_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; i<ngroups; ++i)
 | 
			
		||||
    {
 | 
			
		||||
        if (my_groups[i] == device_group->gr_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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										13
									
								
								src/util.h
								
								
								
								
							
							
						
						
									
										13
									
								
								src/util.h
								
								
								
								
							| 
						 | 
				
			
			@ -174,10 +174,15 @@ void eatWhitespace(std::vector<char> &v, std::vector<char>::iterator &i, bool *e
 | 
			
		|||
std::string eatToSkipWhitespace(std::vector<char> &v, std::vector<char>::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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										77
									
								
								src/wmbus.cc
								
								
								
								
							
							
						
						
									
										77
									
								
								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<SerialCommunicationManager> manager,
 | 
			
		||||
                          string *out_device,
 | 
			
		||||
                          function<AccessCheck(string,shared_ptr<SerialCommunicationManager>)> 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<SerialCommunicationManager> manager,
 | 
			
		||||
                                 function<AccessCheck(string,shared_ptr<SerialCommunicationManager>)> 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<uchar> &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
 | 
			
		||||
| 
						 | 
				
			
			@ -4901,23 +4854,23 @@ Detected detectWMBusDeviceWithCommand(SpecifiedDevice &specified_device,
 | 
			
		|||
 | 
			
		||||
AccessCheck detectUNKNOWN(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
 | 
			
		||||
{
 | 
			
		||||
    return AccessCheck::NotThere;
 | 
			
		||||
    return AccessCheck::NoSuchDevice;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AccessCheck detectSKIP(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
 | 
			
		||||
{
 | 
			
		||||
    return AccessCheck::NotThere;
 | 
			
		||||
    return AccessCheck::NoSuchDevice;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AccessCheck detectSIMULATION(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
 | 
			
		||||
{
 | 
			
		||||
    return AccessCheck::NotThere;
 | 
			
		||||
    return AccessCheck::NoSuchDevice;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AccessCheck detectAUTO(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
 | 
			
		||||
{
 | 
			
		||||
    // Detection of auto is currently not implemented here, but elsewhere.
 | 
			
		||||
    return AccessCheck::NotThere;
 | 
			
		||||
    return AccessCheck::NoSuchDevice;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AccessCheck reDetectDevice(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
 | 
			
		||||
| 
						 | 
				
			
			@ -4929,7 +4882,7 @@ LIST_OF_MBUS_DEVICES
 | 
			
		|||
#undef X
 | 
			
		||||
 | 
			
		||||
    assert(0);
 | 
			
		||||
    return AccessCheck::NotThere;
 | 
			
		||||
    return AccessCheck::NoSuchDevice;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool usesRTLSDR(WMBusDeviceType t)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										11
									
								
								src/wmbus.h
								
								
								
								
							
							
						
						
									
										11
									
								
								src/wmbus.h
								
								
								
								
							| 
						 | 
				
			
			@ -688,17 +688,6 @@ MeasurementType difMeasurementType(int dif);
 | 
			
		|||
string linkModeName(LinkMode link_mode);
 | 
			
		||||
string measurementTypeName(MeasurementType mt);
 | 
			
		||||
 | 
			
		||||
AccessCheck findAndDetect(shared_ptr<SerialCommunicationManager> manager,
 | 
			
		||||
                          string *out_device,
 | 
			
		||||
                          function<AccessCheck(string,shared_ptr<SerialCommunicationManager>)> check,
 | 
			
		||||
                          string dongle_name,
 | 
			
		||||
                          string device_root);
 | 
			
		||||
 | 
			
		||||
AccessCheck checkAccessAndDetect(shared_ptr<SerialCommunicationManager> manager,
 | 
			
		||||
                                 function<AccessCheck(string,shared_ptr<SerialCommunicationManager>)> check,
 | 
			
		||||
                                 string dongle_name,
 | 
			
		||||
                                 string device);
 | 
			
		||||
 | 
			
		||||
enum FrameStatus { PartialFrame, FullFrame, ErrorInFrame, TextAndNotFrame };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -587,14 +587,16 @@ void WMBusAmber::handleMessage(int msgid, vector<uchar> &frame, int rssi_dbm)
 | 
			
		|||
 | 
			
		||||
AccessCheck detectAMB8465(Detected *detected, shared_ptr<SerialCommunicationManager> 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<uchar> response;
 | 
			
		||||
| 
						 | 
				
			
			@ -659,7 +661,7 @@ AccessCheck detectAMB8465(Detected *detected, shared_ptr<SerialCommunicationMana
 | 
			
		|||
                debug("(amb8465) failed to sent query! Giving up!\n");
 | 
			
		||||
                verbose("(amb8465) are you there? no, nothing is there.\n");
 | 
			
		||||
                serial->close();
 | 
			
		||||
                return AccessCheck::NotThere;
 | 
			
		||||
                return AccessCheck::NoProperResponse;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } while (sent == false && count < 4);
 | 
			
		||||
| 
						 | 
				
			
			@ -676,7 +678,7 @@ AccessCheck detectAMB8465(Detected *detected, shared_ptr<SerialCommunicationMana
 | 
			
		|||
        {
 | 
			
		||||
            verbose("(amb8465) are you there? no.\n");
 | 
			
		||||
            serial->close();
 | 
			
		||||
            return AccessCheck::NotThere;
 | 
			
		||||
            return AccessCheck::NoProperResponse;
 | 
			
		||||
        }
 | 
			
		||||
        debug("(amb8465) reading response... %d\n", count);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -725,10 +727,11 @@ static AccessCheck tryFactoryResetAMB8465(string device, shared_ptr<SerialCommun
 | 
			
		|||
{
 | 
			
		||||
    // Talk to the device and expect a very specific answer.
 | 
			
		||||
    auto serial = manager->createSerialDeviceTTY(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<uchar> data;
 | 
			
		||||
| 
						 | 
				
			
			@ -776,7 +779,7 @@ static AccessCheck tryFactoryResetAMB8465(string device, shared_ptr<SerialCommun
 | 
			
		|||
        data[4] != xorChecksum(data, 0, 4))
 | 
			
		||||
    {
 | 
			
		||||
        verbose("(amb8465) no response to factory reset %s using baud %d\n", device.c_str(), baud);
 | 
			
		||||
        return AccessCheck::NotThere;
 | 
			
		||||
        return AccessCheck::NoProperResponse;
 | 
			
		||||
    }
 | 
			
		||||
    verbose("(amb8465) received proper factory reset response %s using baud %d\n", device.c_str(), baud);
 | 
			
		||||
    return AccessCheck::AccessOK;
 | 
			
		||||
| 
						 | 
				
			
			@ -786,7 +789,7 @@ int bauds[] = { 1200, 2400, 4800, 9600, 19200, 38400, 56000, 115200, 0 };
 | 
			
		|||
 | 
			
		||||
AccessCheck factoryResetAMB8465(string device, shared_ptr<SerialCommunicationManager> 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<SerialCommunicationMan
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
    *was_baud = 0;
 | 
			
		||||
    return AccessCheck::NotThere;
 | 
			
		||||
    return AccessCheck::NoSuchDevice;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -382,8 +382,8 @@ AccessCheck detectCUL(Detected *detected, shared_ptr<SerialCommunicationManager>
 | 
			
		|||
    // 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<SerialCommunicationManager>
 | 
			
		|||
        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<SerialCommunicationManager>
 | 
			
		|||
    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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -966,11 +966,17 @@ bool WMBusIM871aIM170A::sendTelegram(ContentStartsWith starts_with, vector<uchar
 | 
			
		|||
 | 
			
		||||
AccessCheck detectIM871AIM170A(Detected *detected, shared_ptr<SerialCommunicationManager> 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<uchar> response;
 | 
			
		||||
    // First clear out any data in the queue.
 | 
			
		||||
| 
						 | 
				
			
			@ -1000,7 +1006,7 @@ AccessCheck detectIM871AIM170A(Detected *detected, shared_ptr<SerialCommunicatio
 | 
			
		|||
    {
 | 
			
		||||
        verbose("(im871a/im170a) are you there? no.\n");
 | 
			
		||||
        serial->close();
 | 
			
		||||
        return AccessCheck::NotThere;
 | 
			
		||||
        return AccessCheck::NoProperResponse;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vector<uchar> payload;
 | 
			
		||||
| 
						 | 
				
			
			@ -1047,7 +1053,7 @@ AccessCheck detectIM871AIM170A(Detected *detected, shared_ptr<SerialCommunicatio
 | 
			
		|||
    {
 | 
			
		||||
        verbose("(im871a/im170a) are you there? no.\n");
 | 
			
		||||
        serial->close();
 | 
			
		||||
        return AccessCheck::NotThere;
 | 
			
		||||
        return AccessCheck::NoProperResponse;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    serial->close();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -235,8 +235,8 @@ AccessCheck detectRAWTTY(Detected *detected, shared_ptr<SerialCommunicationManag
 | 
			
		|||
    // Since we do not know how to talk to the other end, it might not
 | 
			
		||||
    // even respond. The only thing we can do is to try to open the serial device.
 | 
			
		||||
    auto serial = manager->createSerialDeviceTTY(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();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -163,6 +163,8 @@ private:
 | 
			
		|||
 | 
			
		||||
shared_ptr<WMBus> openRC1180(Detected detected, shared_ptr<SerialCommunicationManager> manager, shared_ptr<SerialDevice> 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_ptr<SerialCommunicationManag
 | 
			
		|||
    // Talk to the device and expect a very specific answer.
 | 
			
		||||
    auto serial = manager->createSerialDeviceTTY(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<uchar> data;
 | 
			
		||||
    vector<uchar> msg(1);
 | 
			
		||||
| 
						 | 
				
			
			@ -360,7 +362,7 @@ AccessCheck detectRC1180(Detected *detected, shared_ptr<SerialCommunicationManag
 | 
			
		|||
       // no RC1180 device detected
 | 
			
		||||
       serial->close();
 | 
			
		||||
       verbose("(rc1180) are you there? no.\n");
 | 
			
		||||
       return AccessCheck::NotThere;
 | 
			
		||||
       return AccessCheck::NoProperResponse;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    data.clear();
 | 
			
		||||
| 
						 | 
				
			
			@ -375,7 +377,7 @@ AccessCheck detectRC1180(Detected *detected, shared_ptr<SerialCommunicationManag
 | 
			
		|||
    serial->receive(&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_ptr<SerialCommunicationManag
 | 
			
		|||
        // If not 5, then this is not a rc1180 dongle.
 | 
			
		||||
        serial->close();
 | 
			
		||||
        verbose("(rc1180) are you there? no.\n");
 | 
			
		||||
        return AccessCheck::NotThere;
 | 
			
		||||
        return AccessCheck::NoProperResponse;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    debug("(rc1180) config: %s\n", co.str().c_str());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -367,5 +367,5 @@ FrameStatus WMBusRTL433::checkRTL433Frame(vector<uchar> &data,
 | 
			
		|||
AccessCheck detectRTL433(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
 | 
			
		||||
{
 | 
			
		||||
    assert(0);
 | 
			
		||||
    return AccessCheck::NotThere;
 | 
			
		||||
    return AccessCheck::NoSuchDevice;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -420,5 +420,5 @@ FrameStatus WMBusRTLWMBUS::checkRTLWMBUSFrame(vector<uchar> &data,
 | 
			
		|||
AccessCheck detectRTLWMBUS(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
 | 
			
		||||
{
 | 
			
		||||
    assert(0);
 | 
			
		||||
    return AccessCheck::NotThere;
 | 
			
		||||
    return AccessCheck::NoSuchDevice;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue