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 Hydrocal-M3 heating/cooling meter.
|
||||||
Added support for the Apator uniSMART gas 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
|
# 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.
|
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 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
|
## How to receive telegrams over longer distances
|
||||||
|
|
||||||
I only have personal experience of the im871a,amb8465 and an rtlsdr
|
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_default_configuration.sh
|
||||||
|
|
||||||
ROOT=$ROOT /bin/sh ./scripts/install_systemd_service.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"serial.h"
|
||||||
#include"shell.h"
|
#include"shell.h"
|
||||||
#include"ui.h"
|
#include"ui.h"
|
||||||
|
#include"util.h"
|
||||||
#include"wmbus.h"
|
#include"wmbus.h"
|
||||||
|
|
||||||
bool running_as_root_ = false;
|
bool running_as_root_ = false;
|
||||||
|
@ -99,6 +100,9 @@ int main(int argc, char **argv)
|
||||||
enableSyslog();
|
enableSyslog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle exit on signals...
|
||||||
|
onExit(exitUI);
|
||||||
|
|
||||||
initUI();
|
initUI();
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
|
@ -160,6 +164,8 @@ int main(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (running);
|
} while (running);
|
||||||
|
|
||||||
|
exitUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
void alwaysOnScreen()
|
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 {};
|
Detected detected {};
|
||||||
vector<string> devices = handler->listSerialTTYs();
|
vector<string> devices = handler->listSerialTTYs();
|
||||||
|
@ -297,24 +303,33 @@ void probeFor(string type, AccessCheck (*check)(Detected*,shared_ptr<SerialCommu
|
||||||
for (string& device : devices)
|
for (string& device : devices)
|
||||||
{
|
{
|
||||||
string tty = "?";
|
string tty = "?";
|
||||||
AccessCheck ac = checkAccessAndDetect(
|
AccessCheck ac = handler->checkAccess(device,
|
||||||
handler,
|
handler,
|
||||||
[&](string d, shared_ptr<SerialCommunicationManager> m){ detected.specified_device.file=d; return check(&detected, m);},
|
|
||||||
type,
|
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)
|
if (ac == AccessCheck::AccessOK)
|
||||||
{
|
{
|
||||||
tty = device+" DETECTED "+type;
|
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)
|
else if (ac == AccessCheck::NotSameGroup)
|
||||||
{
|
{
|
||||||
tty = device+" not same group";
|
tty = device+" not same group";
|
||||||
}
|
}
|
||||||
|
else if (ac == AccessCheck::NoPermission)
|
||||||
|
{
|
||||||
|
tty = device+" same group but wrong permissions";
|
||||||
|
}
|
||||||
entries.push_back(tty);
|
entries.push_back(tty);
|
||||||
}
|
}
|
||||||
if (entries.size() == 0)
|
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
|
// 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.
|
// 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");
|
auto serial = manager->createSerialDeviceTTY(tty.c_str(), bps, PARITY::EVEN, "detect mbus");
|
||||||
AccessCheck rc = serial->open(false);
|
bool ok = serial->open(false);
|
||||||
if (rc != AccessCheck::AccessOK) return AccessCheck::NotThere;
|
if (!ok) return AccessCheck::NoSuchDevice;
|
||||||
|
|
||||||
serial->close();
|
serial->close();
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ AccessCheck detectRTLSDR(string serialnr, Detected *detected)
|
||||||
if (detected->specified_device.type != WMBusDeviceType::DEVICE_RTLWMBUS &&
|
if (detected->specified_device.type != WMBusDeviceType::DEVICE_RTLWMBUS &&
|
||||||
detected->specified_device.type != WMBusDeviceType::DEVICE_RTL433)
|
detected->specified_device.type != WMBusDeviceType::DEVICE_RTL433)
|
||||||
{
|
{
|
||||||
return AccessCheck::NotThere;
|
return AccessCheck::NoSuchDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t n = rtlsdr_get_device_count();
|
uint32_t n = rtlsdr_get_device_count();
|
||||||
|
@ -129,7 +129,7 @@ AccessCheck detectRTLSDR(string serialnr, Detected *detected)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Something is wrong.
|
// 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>
|
#include <linux/serial.h>
|
||||||
#endif
|
#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 int openSerialTTY(const char *tty, int baud_rate, PARITY parity);
|
||||||
static string showTTYSettings(int fd);
|
static string showTTYSettings(int fd);
|
||||||
|
|
||||||
|
@ -94,6 +96,11 @@ struct SerialCommunicationManagerImp : public SerialCommunicationManager
|
||||||
int startRegularCallback(string name, int seconds, function<void()> callback);
|
int startRegularCallback(string name, int seconds, function<void()> callback);
|
||||||
void stopRegularCallback(int id);
|
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();
|
vector<string> listSerialTTYs();
|
||||||
shared_ptr<SerialDevice> lookup(std::string device);
|
shared_ptr<SerialDevice> lookup(std::string device);
|
||||||
bool removeNonWorking(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(string device, int baud_rate, PARITY parity, SerialCommunicationManagerImp * manager, string purpose);
|
||||||
~SerialDeviceTTY();
|
~SerialDeviceTTY();
|
||||||
|
|
||||||
AccessCheck open(bool fail_if_not_ok);
|
bool open(bool fail_if_not_ok);
|
||||||
void close();
|
void close();
|
||||||
bool send(vector<uchar> &data);
|
bool send(vector<uchar> &data);
|
||||||
bool working();
|
bool working();
|
||||||
|
@ -313,39 +320,26 @@ SerialDeviceTTY::~SerialDeviceTTY()
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessCheck SerialDeviceTTY::open(bool fail_if_not_ok)
|
bool SerialDeviceTTY::open(bool fail_if_not_ok)
|
||||||
{
|
{
|
||||||
assert(device_ != "");
|
assert(device_ != "");
|
||||||
bool ok = checkCharacterDeviceExists(device_.c_str(), fail_if_not_ok);
|
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_);
|
fd_ = openSerialTTY(device_.c_str(), baud_rate_, parity_);
|
||||||
if (fd_ < 0)
|
|
||||||
{
|
|
||||||
if (fail_if_not_ok)
|
|
||||||
{
|
|
||||||
if (fd_ == -1)
|
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());
|
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;
|
||||||
else
|
|
||||||
{
|
|
||||||
if (fd_ == -1)
|
|
||||||
{
|
|
||||||
return AccessCheck::NotThere;
|
|
||||||
}
|
|
||||||
else if (fd_ == -2)
|
|
||||||
{
|
|
||||||
return AccessCheck::NotSameGroup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
verbose("(serialtty) opened %s fd %d (%s)\n", device_.c_str(), fd_, purpose_.c_str());
|
verbose("(serialtty) opened %s fd %d (%s)\n", device_.c_str(), fd_, purpose_.c_str());
|
||||||
return AccessCheck::AccessOK;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialDeviceTTY::close()
|
void SerialDeviceTTY::close()
|
||||||
|
@ -426,7 +420,7 @@ struct SerialDeviceCommand : public SerialDeviceImp
|
||||||
string purpose);
|
string purpose);
|
||||||
~SerialDeviceCommand();
|
~SerialDeviceCommand();
|
||||||
|
|
||||||
AccessCheck open(bool fail_if_not_ok);
|
bool open(bool fail_if_not_ok);
|
||||||
void close();
|
void close();
|
||||||
bool send(vector<uchar> &data);
|
bool send(vector<uchar> &data);
|
||||||
int available();
|
int available();
|
||||||
|
@ -466,15 +460,15 @@ SerialDeviceCommand::~SerialDeviceCommand()
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessCheck SerialDeviceCommand::open(bool fail_if_not_ok)
|
bool SerialDeviceCommand::open(bool fail_if_not_ok)
|
||||||
{
|
{
|
||||||
expectAscii();
|
expectAscii();
|
||||||
bool ok = invokeBackgroundShell("/bin/sh", args_, envs_, &fd_, &pid_);
|
bool ok = invokeBackgroundShell("/bin/sh", args_, envs_, &fd_, &pid_);
|
||||||
assert(fd_ >= 0);
|
assert(fd_ >= 0);
|
||||||
if (!ok) return AccessCheck::NotThere;
|
if (!ok) return false;
|
||||||
setIsStdin();
|
setIsStdin();
|
||||||
verbose("(serialcmd) opened %s pid %d fd %d (%s)\n", command_.c_str(), pid_, fd_, purpose_.c_str());
|
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()
|
void SerialDeviceCommand::close()
|
||||||
|
@ -553,7 +547,7 @@ struct SerialDeviceFile : public SerialDeviceImp
|
||||||
SerialDeviceFile(string file, SerialCommunicationManagerImp *manager, string purpose);
|
SerialDeviceFile(string file, SerialCommunicationManagerImp *manager, string purpose);
|
||||||
~SerialDeviceFile();
|
~SerialDeviceFile();
|
||||||
|
|
||||||
AccessCheck open(bool fail_if_not_ok);
|
bool open(bool fail_if_not_ok);
|
||||||
void close();
|
void close();
|
||||||
bool working();
|
bool working();
|
||||||
bool send(vector<uchar> &data);
|
bool send(vector<uchar> &data);
|
||||||
|
@ -578,7 +572,7 @@ SerialDeviceFile::~SerialDeviceFile()
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessCheck SerialDeviceFile::open(bool fail_if_not_ok)
|
bool SerialDeviceFile::open(bool fail_if_not_ok)
|
||||||
{
|
{
|
||||||
if (file_ == "stdin")
|
if (file_ == "stdin")
|
||||||
{
|
{
|
||||||
|
@ -592,25 +586,20 @@ AccessCheck SerialDeviceFile::open(bool fail_if_not_ok)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool ok = checkFileExists(file_.c_str());
|
bool ok = checkFileExists(file_.c_str());
|
||||||
if (!ok) return AccessCheck::NotThere;
|
if (!ok) return false;
|
||||||
fd_ = ::open(file_.c_str(), O_RDONLY | O_NONBLOCK);
|
fd_ = ::open(file_.c_str(), O_RDONLY | O_NONBLOCK);
|
||||||
if (fd_ == -1)
|
if (fd_ == -1)
|
||||||
{
|
{
|
||||||
if (fail_if_not_ok)
|
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());
|
||||||
error("Could not open file %s for reading.\n", file_.c_str());
|
return false;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return AccessCheck::NotThere;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
setIsFile();
|
setIsFile();
|
||||||
verbose("(serialfile) reading from file %s (%s)\n", file_.c_str(), purpose_.c_str());
|
verbose("(serialfile) reading from file %s (%s)\n", file_.c_str(), purpose_.c_str());
|
||||||
}
|
}
|
||||||
manager_->tickleEventLoop();
|
manager_->tickleEventLoop();
|
||||||
|
|
||||||
return AccessCheck::AccessOK;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialDeviceFile::close()
|
void SerialDeviceFile::close()
|
||||||
|
@ -656,7 +645,7 @@ struct SerialDeviceSimulator : public SerialDeviceImp
|
||||||
};
|
};
|
||||||
~SerialDeviceSimulator() { };
|
~SerialDeviceSimulator() { };
|
||||||
|
|
||||||
AccessCheck open(bool fail_if_not_ok) { return AccessCheck::AccessOK; };
|
bool open(bool fail_if_not_ok) { return true; };
|
||||||
void close() { };
|
void close() { };
|
||||||
bool readonly() { return true; }
|
bool readonly() { return true; }
|
||||||
bool send(vector<uchar> &data) { return true; };
|
bool send(vector<uchar> &data) { return true; };
|
||||||
|
@ -1602,3 +1591,52 @@ err:
|
||||||
|
|
||||||
return "error";
|
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
|
struct SerialDevice
|
||||||
{
|
{
|
||||||
// If fail_if_not_ok then forcefully exit the program if cannot be opened.
|
// 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;
|
virtual void close() = 0;
|
||||||
// Explicitly closed fd == -1
|
// Explicitly closed fd == -1
|
||||||
virtual bool isClosed() = 0;
|
virtual bool isClosed() = 0;
|
||||||
|
@ -106,6 +106,11 @@ struct SerialCommunicationManager
|
||||||
virtual int startRegularCallback(std::string name, int seconds, function<void()> callback) = 0;
|
virtual int startRegularCallback(std::string name, int seconds, function<void()> callback) = 0;
|
||||||
virtual void stopRegularCallback(int id) = 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)
|
// List all real serial devices (avoid pseudo ttys)
|
||||||
virtual std::vector<std::string> listSerialTTYs() = 0;
|
virtual std::vector<std::string> listSerialTTYs() = 0;
|
||||||
// Return a serial device for the given device, if it exists! Otherwise NULL.
|
// 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));
|
wbkgd(stdscr, COLOR_PAIR(BG_PAIR));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void exitUI()
|
||||||
|
{
|
||||||
|
endwin();
|
||||||
|
}
|
||||||
|
|
||||||
void registerUpdateCB(std::function<void()> cb)
|
void registerUpdateCB(std::function<void()> cb)
|
||||||
{
|
{
|
||||||
update_cb_ = cb;
|
update_cb_ = cb;
|
||||||
|
|
1
src/ui.h
1
src/ui.h
|
@ -36,6 +36,7 @@
|
||||||
#define HILIGHT_PAIR 4
|
#define HILIGHT_PAIR 4
|
||||||
|
|
||||||
void initUI();
|
void initUI();
|
||||||
|
void exitUI();
|
||||||
|
|
||||||
void registerUpdateCB(std::function<void()> cb);
|
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;
|
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.
|
// 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__)
|
#if defined(__APPLE__) && defined(__MACH__)
|
||||||
int groups[256];
|
int my_groups[256];
|
||||||
#else
|
#else
|
||||||
gid_t groups[256];
|
gid_t my_groups[256];
|
||||||
#endif
|
#endif
|
||||||
int ngroups = 256;
|
int ngroups = 256;
|
||||||
|
|
||||||
struct passwd *p = getpwuid(getuid());
|
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) {
|
if (rc < 0) {
|
||||||
error("(wmbusmeters) cannot handle users with more than 256 groups\n");
|
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) {
|
// What is the group of the tty?
|
||||||
if (groups[i] == g->gr_gid) {
|
struct group *device_group = getgrgid(device_sb.st_gid);
|
||||||
return AccessCheck::AccessOK;
|
|
||||||
|
// 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;
|
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);
|
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
|
// Remove leading and trailing white space
|
||||||
void trimWhitespace(std::string *s);
|
void trimWhitespace(std::string *s);
|
||||||
// Returns true if device exists and this programs user, belongs
|
// Returns AccessOK if device exists and is accessible.
|
||||||
// to the same group that the device belongs to.
|
// NotSameGroup means that there is no permission and the groups do not match.
|
||||||
enum class AccessCheck { NotThere, NotSameGroup, Locked, AccessOK };
|
// NoPermission means some other reason for no access. (missing rw etc)
|
||||||
AccessCheck checkIfExistsAndSameGroup(std::string device);
|
// 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.
|
// Count the number of 1:s in the binary number v.
|
||||||
int countSetBits(int v);
|
int countSetBits(int v);
|
||||||
|
|
||||||
|
|
77
src/wmbus.cc
77
src/wmbus.cc
|
@ -3693,9 +3693,9 @@ bool WMBusCommonImplementation::reset()
|
||||||
usleep(3000*1000);
|
usleep(3000*1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessCheck rc = serial()->open(false);
|
bool ok = serial()->open(false);
|
||||||
|
|
||||||
if (rc != AccessCheck::AccessOK)
|
if (!ok)
|
||||||
{
|
{
|
||||||
// Ouch....
|
// Ouch....
|
||||||
return false;
|
return false;
|
||||||
|
@ -4008,61 +4008,6 @@ LIST_OF_AFL_AUTH_TYPES
|
||||||
return AFLAuthenticationType::Reserved1;
|
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)
|
bool trimCRCsFrameFormatA(std::vector<uchar> &payload)
|
||||||
{
|
{
|
||||||
if (payload.size() < 12) {
|
if (payload.size() < 12) {
|
||||||
|
@ -4750,6 +4695,14 @@ Detected detectWMBusDeviceOnTTY(string tty,
|
||||||
detected.specified_device.is_tty = true;
|
detected.specified_device.is_tty = true;
|
||||||
detected.specified_device.linkmodes = desired_linkmodes;
|
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
|
// If im87a is tested first, a delay of 1s must be inserted
|
||||||
// before amb8465 is tested, lest it will not respond properly.
|
// before amb8465 is tested, lest it will not respond properly.
|
||||||
// It really should not matter, but perhaps is the uart of the amber
|
// 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)
|
AccessCheck detectUNKNOWN(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
|
||||||
{
|
{
|
||||||
return AccessCheck::NotThere;
|
return AccessCheck::NoSuchDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessCheck detectSKIP(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
|
AccessCheck detectSKIP(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
|
||||||
{
|
{
|
||||||
return AccessCheck::NotThere;
|
return AccessCheck::NoSuchDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessCheck detectSIMULATION(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
|
AccessCheck detectSIMULATION(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
|
||||||
{
|
{
|
||||||
return AccessCheck::NotThere;
|
return AccessCheck::NoSuchDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessCheck detectAUTO(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
|
AccessCheck detectAUTO(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
|
||||||
{
|
{
|
||||||
// Detection of auto is currently not implemented here, but elsewhere.
|
// Detection of auto is currently not implemented here, but elsewhere.
|
||||||
return AccessCheck::NotThere;
|
return AccessCheck::NoSuchDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessCheck reDetectDevice(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
|
AccessCheck reDetectDevice(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
|
||||||
|
@ -4929,7 +4882,7 @@ LIST_OF_MBUS_DEVICES
|
||||||
#undef X
|
#undef X
|
||||||
|
|
||||||
assert(0);
|
assert(0);
|
||||||
return AccessCheck::NotThere;
|
return AccessCheck::NoSuchDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool usesRTLSDR(WMBusDeviceType t)
|
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 linkModeName(LinkMode link_mode);
|
||||||
string measurementTypeName(MeasurementType mt);
|
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 };
|
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)
|
AccessCheck detectAMB8465(Detected *detected, shared_ptr<SerialCommunicationManager> manager)
|
||||||
{
|
{
|
||||||
|
assert(detected->found_file != "");
|
||||||
|
|
||||||
// Talk to the device and expect a very specific answer.
|
// Talk to the device and expect a very specific answer.
|
||||||
auto serial = manager->createSerialDeviceTTY(detected->found_file.c_str(), 9600, PARITY::NONE, "detect amb8465");
|
auto serial = manager->createSerialDeviceTTY(detected->found_file.c_str(), 9600, PARITY::NONE, "detect amb8465");
|
||||||
serial->disableCallbacks();
|
serial->disableCallbacks();
|
||||||
AccessCheck rc = serial->open(false);
|
bool ok = serial->open(false);
|
||||||
if (rc != AccessCheck::AccessOK)
|
if (!ok)
|
||||||
{
|
{
|
||||||
debug("(amb8465) could not open tty for detection\n");
|
verbose("(amb8465) could not open tty %s for detection\n", detected->found_file.c_str());
|
||||||
return AccessCheck::NotThere;
|
return AccessCheck::NoSuchDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<uchar> response;
|
vector<uchar> response;
|
||||||
|
@ -659,7 +661,7 @@ AccessCheck detectAMB8465(Detected *detected, shared_ptr<SerialCommunicationMana
|
||||||
debug("(amb8465) failed to sent query! Giving up!\n");
|
debug("(amb8465) failed to sent query! Giving up!\n");
|
||||||
verbose("(amb8465) are you there? no, nothing is there.\n");
|
verbose("(amb8465) are you there? no, nothing is there.\n");
|
||||||
serial->close();
|
serial->close();
|
||||||
return AccessCheck::NotThere;
|
return AccessCheck::NoProperResponse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (sent == false && count < 4);
|
} while (sent == false && count < 4);
|
||||||
|
@ -676,7 +678,7 @@ AccessCheck detectAMB8465(Detected *detected, shared_ptr<SerialCommunicationMana
|
||||||
{
|
{
|
||||||
verbose("(amb8465) are you there? no.\n");
|
verbose("(amb8465) are you there? no.\n");
|
||||||
serial->close();
|
serial->close();
|
||||||
return AccessCheck::NotThere;
|
return AccessCheck::NoProperResponse;
|
||||||
}
|
}
|
||||||
debug("(amb8465) reading response... %d\n", count);
|
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.
|
// Talk to the device and expect a very specific answer.
|
||||||
auto serial = manager->createSerialDeviceTTY(device.c_str(), baud, PARITY::NONE, "reset amb8465");
|
auto serial = manager->createSerialDeviceTTY(device.c_str(), baud, PARITY::NONE, "reset amb8465");
|
||||||
AccessCheck rc = serial->open(false);
|
bool ok = serial->open(false);
|
||||||
if (rc != AccessCheck::AccessOK) {
|
if (!ok)
|
||||||
verbose("(amb8465) could not open device %s using baud %d\n", device.c_str(), baud);
|
{
|
||||||
return AccessCheck::NotThere;
|
verbose("(amb8465) could not open device %s using baud %d for reset\n", device.c_str(), baud);
|
||||||
|
return AccessCheck::NoSuchDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<uchar> data;
|
vector<uchar> data;
|
||||||
|
@ -776,7 +779,7 @@ static AccessCheck tryFactoryResetAMB8465(string device, shared_ptr<SerialCommun
|
||||||
data[4] != xorChecksum(data, 0, 4))
|
data[4] != xorChecksum(data, 0, 4))
|
||||||
{
|
{
|
||||||
verbose("(amb8465) no response to factory reset %s using baud %d\n", device.c_str(), baud);
|
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);
|
verbose("(amb8465) received proper factory reset response %s using baud %d\n", device.c_str(), baud);
|
||||||
return AccessCheck::AccessOK;
|
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 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)
|
for (int i=0; bauds[i] != 0; ++i)
|
||||||
{
|
{
|
||||||
|
@ -798,5 +801,5 @@ AccessCheck factoryResetAMB8465(string device, shared_ptr<SerialCommunicationMan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*was_baud = 0;
|
*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.
|
// Talk to the device and expect a very specific answer.
|
||||||
auto serial = manager->createSerialDeviceTTY(detected->found_file.c_str(), 38400, PARITY::NONE, "detect cul");
|
auto serial = manager->createSerialDeviceTTY(detected->found_file.c_str(), 38400, PARITY::NONE, "detect cul");
|
||||||
serial->disableCallbacks();
|
serial->disableCallbacks();
|
||||||
AccessCheck rc = serial->open(false);
|
bool ok = serial->open(false);
|
||||||
if (rc != AccessCheck::AccessOK) return AccessCheck::NotThere;
|
if (!ok) return AccessCheck::NoSuchDevice;
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (int i=0; i<3; ++i)
|
for (int i=0; i<3; ++i)
|
||||||
|
@ -401,7 +401,7 @@ AccessCheck detectCUL(Detected *detected, shared_ptr<SerialCommunicationManager>
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
verbose("(cul) are you there? no\n");
|
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.
|
// 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)
|
if (!found)
|
||||||
{
|
{
|
||||||
verbose("(cul) are you there? no\n");
|
verbose("(cul) are you there? no\n");
|
||||||
return AccessCheck::NotThere;
|
return AccessCheck::NoProperResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
detected->setAsFound("", WMBusDeviceType::DEVICE_CUL, 38400, false, detected->specified_device.linkmodes);
|
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)
|
AccessCheck detectIM871AIM170A(Detected *detected, shared_ptr<SerialCommunicationManager> manager)
|
||||||
{
|
{
|
||||||
|
assert(detected->found_file != "");
|
||||||
|
|
||||||
// Talk to the device and expect a very specific answer.
|
// Talk to the device and expect a very specific answer.
|
||||||
auto serial = manager->createSerialDeviceTTY(detected->found_file.c_str(), 57600, PARITY::NONE, "detect im871a");
|
auto serial = manager->createSerialDeviceTTY(detected->found_file.c_str(), 57600, PARITY::NONE, "detect im871a");
|
||||||
serial->disableCallbacks();
|
serial->disableCallbacks();
|
||||||
AccessCheck rc = serial->open(false);
|
bool ok = serial->open(false);
|
||||||
if (rc != AccessCheck::AccessOK) return AccessCheck::NotThere;
|
if (!ok)
|
||||||
|
{
|
||||||
|
verbose("(im871a) could not open tty %s for detection\n", detected->found_file.c_str());
|
||||||
|
return AccessCheck::NoSuchDevice;
|
||||||
|
}
|
||||||
|
|
||||||
vector<uchar> response;
|
vector<uchar> response;
|
||||||
// First clear out any data in the queue.
|
// 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");
|
verbose("(im871a/im170a) are you there? no.\n");
|
||||||
serial->close();
|
serial->close();
|
||||||
return AccessCheck::NotThere;
|
return AccessCheck::NoProperResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<uchar> payload;
|
vector<uchar> payload;
|
||||||
|
@ -1047,7 +1053,7 @@ AccessCheck detectIM871AIM170A(Detected *detected, shared_ptr<SerialCommunicatio
|
||||||
{
|
{
|
||||||
verbose("(im871a/im170a) are you there? no.\n");
|
verbose("(im871a/im170a) are you there? no.\n");
|
||||||
serial->close();
|
serial->close();
|
||||||
return AccessCheck::NotThere;
|
return AccessCheck::NoProperResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
serial->close();
|
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
|
// 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.
|
// 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");
|
auto serial = manager->createSerialDeviceTTY(tty.c_str(), bps, PARITY::NONE, "detect rawtty");
|
||||||
AccessCheck rc = serial->open(false);
|
bool ok = serial->open(false);
|
||||||
if (rc != AccessCheck::AccessOK) return AccessCheck::NotThere;
|
if (!ok) return AccessCheck::NoSuchDevice;
|
||||||
|
|
||||||
serial->close();
|
serial->close();
|
||||||
|
|
||||||
|
|
|
@ -163,6 +163,8 @@ private:
|
||||||
|
|
||||||
shared_ptr<WMBus> openRC1180(Detected detected, shared_ptr<SerialCommunicationManager> manager, shared_ptr<SerialDevice> serial_override)
|
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 bus_alias = detected.specified_device.bus_alias;
|
||||||
string device = detected.found_file;
|
string device = detected.found_file;
|
||||||
assert(device != "");
|
assert(device != "");
|
||||||
|
@ -341,8 +343,8 @@ AccessCheck detectRC1180(Detected *detected, shared_ptr<SerialCommunicationManag
|
||||||
// Talk to the device and expect a very specific answer.
|
// Talk to the device and expect a very specific answer.
|
||||||
auto serial = manager->createSerialDeviceTTY(detected->found_file.c_str(), 19200, PARITY::NONE, "detect rc1180");
|
auto serial = manager->createSerialDeviceTTY(detected->found_file.c_str(), 19200, PARITY::NONE, "detect rc1180");
|
||||||
serial->disableCallbacks();
|
serial->disableCallbacks();
|
||||||
AccessCheck rc = serial->open(false);
|
bool ok = serial->open(false);
|
||||||
if (rc != AccessCheck::AccessOK) return AccessCheck::NotThere;
|
if (!ok) return AccessCheck::NoSuchDevice;
|
||||||
|
|
||||||
vector<uchar> data;
|
vector<uchar> data;
|
||||||
vector<uchar> msg(1);
|
vector<uchar> msg(1);
|
||||||
|
@ -360,7 +362,7 @@ AccessCheck detectRC1180(Detected *detected, shared_ptr<SerialCommunicationManag
|
||||||
// no RC1180 device detected
|
// no RC1180 device detected
|
||||||
serial->close();
|
serial->close();
|
||||||
verbose("(rc1180) are you there? no.\n");
|
verbose("(rc1180) are you there? no.\n");
|
||||||
return AccessCheck::NotThere;
|
return AccessCheck::NoProperResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.clear();
|
data.clear();
|
||||||
|
@ -375,7 +377,7 @@ AccessCheck detectRC1180(Detected *detected, shared_ptr<SerialCommunicationManag
|
||||||
serial->receive(&data);
|
serial->receive(&data);
|
||||||
|
|
||||||
ConfigRC1180 co;
|
ConfigRC1180 co;
|
||||||
bool ok = co.decode(data);
|
ok = co.decode(data);
|
||||||
if (!ok || co.uart_bps != 5)
|
if (!ok || co.uart_bps != 5)
|
||||||
{
|
{
|
||||||
// Decode must be ok and the uart bps must be 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.
|
// If not 5, then this is not a rc1180 dongle.
|
||||||
serial->close();
|
serial->close();
|
||||||
verbose("(rc1180) are you there? no.\n");
|
verbose("(rc1180) are you there? no.\n");
|
||||||
return AccessCheck::NotThere;
|
return AccessCheck::NoProperResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("(rc1180) config: %s\n", co.str().c_str());
|
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)
|
AccessCheck detectRTL433(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
|
||||||
{
|
{
|
||||||
assert(0);
|
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)
|
AccessCheck detectRTLWMBUS(Detected *detected, shared_ptr<SerialCommunicationManager> handler)
|
||||||
{
|
{
|
||||||
assert(0);
|
assert(0);
|
||||||
return AccessCheck::NotThere;
|
return AccessCheck::NoSuchDevice;
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue