1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
/*
* scribiu -- read notebooks and voice memos from Livescribe pens
* Copyright (C) 2015 Javier S. Pedro <javier@javispedro.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QtCore/QDebug>
#include <libudev.h>
#include "smartpenmanager.h"
SmartpenManager::SmartpenManager(QObject *parent)
: QObject(parent), _udev(udev_new()), _monitor(udev_monitor_new_from_netlink(_udev, "udev")),
_notifier(new QSocketNotifier(udev_monitor_get_fd(_monitor), QSocketNotifier::Read))
{
udev_monitor_filter_add_match_tag(_monitor, "livescribe-pen");
connect(_notifier, SIGNAL(activated(int)), SLOT(handleMonitorActivity()));
udev_monitor_enable_receiving(_monitor);
udev_enumerate *scan = udev_enumerate_new(_udev);
udev_enumerate_add_match_tag(scan, "livescribe-pen");
if (udev_enumerate_scan_devices(scan) == 0) {
udev_list_entry *l = udev_enumerate_get_list_entry(scan), *i;
udev_list_entry_foreach(i, l) {
const char *path = udev_list_entry_get_name(i);
udev_device *dev = udev_device_new_from_syspath(_udev, path);
processDevice(dev);
udev_device_unref(dev);
}
} else {
qWarning() << "Failed to scan for devices";
}
udev_enumerate_unref(scan);
}
SmartpenManager::~SmartpenManager()
{
delete _notifier;
udev_monitor_unref(_monitor);
udev_unref(_udev);
}
QStringList SmartpenManager::pensBeingSynchronized() const
{
QStringList pens;
pens.reserve(_syncers.size());
for (QMap<Smartpen::Address, SmartpenSyncer*>::const_iterator it = _syncers.begin();
it != _syncers.end(); ++it) {
QString name = it.value()->penName();
if (name.isEmpty()) {
Smartpen::Address addr = it.value()->penAddress();
name = QString("%1-%2").arg(addr.first).arg(addr.second);
}
pens.append(name);
}
return pens;
}
void SmartpenManager::handleMonitorActivity()
{
qDebug() << "udev activity";
udev_device *dev = udev_monitor_receive_device(_monitor);
if (dev) {
const char *action = udev_device_get_action(dev);
if (action && strcmp(action, "add") == 0) {
processDevice(dev);
}
udev_device_unref(dev);
}
}
void SmartpenManager::handleSyncerFinished()
{
SmartpenSyncer *syncer = static_cast<SmartpenSyncer*>(sender());
Smartpen::Address addr = syncer->penAddress();
qDebug() << "Finished synchronization with pen with address:" << addr;
_syncers.remove(addr);
emit pensBeingSynchronizedChanged();
if (syncer->hasErrors()) {
qWarning() << "Synchronization with address" << addr << "failed";
emit syncFailed(syncer->penName());
} else {
emit syncComplete(syncer->penName());
}
syncer->deleteLater();
}
void SmartpenManager::processDevice(udev_device *dev)
{
uint busnum = atol(udev_device_get_sysattr_value(dev, "busnum"));
uint devnum = atol(udev_device_get_sysattr_value(dev, "devnum"));
Smartpen::Address addr(busnum, devnum);
if (!_syncers.contains(addr)) {
SmartpenSyncer *syncer = new SmartpenSyncer(addr, this);
_syncers.insert(addr, syncer);
connect(syncer, SIGNAL(finished()), SLOT(handleSyncerFinished()));
connect(syncer, SIGNAL(penNameChanged()), SIGNAL(pensBeingSynchronizedChanged()));
syncer->start();
emit pensBeingSynchronizedChanged();
}
}
|