First working version containing rfcom connectivity
This commit is contained in:
parent
0e50c481fb
commit
e84ff331fa
@ -34,6 +34,7 @@ BluetoothInterface::BluetoothInterface(QObject *parent) :
|
|||||||
QObject::connect(m_socket, &QBluetoothSocket::connected, this, &BluetoothInterface::onConnected);
|
QObject::connect(m_socket, &QBluetoothSocket::connected, this, &BluetoothInterface::onConnected);
|
||||||
QObject::connect(m_socket, &QBluetoothSocket::disconnected, this, &BluetoothInterface::onDisconnected);
|
QObject::connect(m_socket, &QBluetoothSocket::disconnected, this, &BluetoothInterface::onDisconnected);
|
||||||
QObject::connect(m_socket, &QBluetoothSocket::readyRead, this, &BluetoothInterface::onDataReady);
|
QObject::connect(m_socket, &QBluetoothSocket::readyRead, this, &BluetoothInterface::onDataReady);
|
||||||
|
QObject::connect(m_socket, &QBluetoothSocket::stateChanged, this, &BluetoothInterface::onDataReady);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList BluetoothInterface::supportedSchemes() const
|
QStringList BluetoothInterface::supportedSchemes() const
|
||||||
@ -50,9 +51,10 @@ void BluetoothInterface::connect(const QUrl &url)
|
|||||||
|
|
||||||
QUrlQuery query(url);
|
QUrlQuery query(url);
|
||||||
QString macAddressString = query.queryItemValue("mac");
|
QString macAddressString = query.queryItemValue("mac");
|
||||||
|
QString name = query.queryItemValue("name");
|
||||||
QBluetoothAddress macAddress = QBluetoothAddress(macAddressString);
|
QBluetoothAddress macAddress = QBluetoothAddress(macAddressString);
|
||||||
|
|
||||||
qDebug() << "Connecting to bluetooth server" << macAddressString << macAddress.toString();
|
qDebug() << "Connecting to bluetooth server" << name << macAddress.toString();
|
||||||
m_socket->connectToService(macAddress, QBluetoothUuid(QUuid("997936b5-d2cd-4c57-b41b-c6048320cd2b")));
|
m_socket->connectToService(macAddress, QBluetoothUuid(QUuid("997936b5-d2cd-4c57-b41b-c6048320cd2b")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +78,8 @@ NymeaInterface::ConnectionState BluetoothInterface::connectionState() const
|
|||||||
|
|
||||||
void BluetoothInterface::sendData(const QByteArray &data)
|
void BluetoothInterface::sendData(const QByteArray &data)
|
||||||
{
|
{
|
||||||
m_socket->write(data + '\n');
|
qDebug() << "BluetoothInterface: send data:" << qUtf8Printable(data);
|
||||||
|
m_socket->write(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BluetoothInterface::onServiceFound(const QBluetoothServiceInfo &service)
|
void BluetoothInterface::onServiceFound(const QBluetoothServiceInfo &service)
|
||||||
@ -101,8 +104,14 @@ void BluetoothInterface::onDisconnected()
|
|||||||
emit disconnected();
|
emit disconnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BluetoothInterface::onStateChanged(const QBluetoothSocket::SocketState &state)
|
||||||
|
{
|
||||||
|
qDebug() << "BluetoothInterface" << state;
|
||||||
|
}
|
||||||
|
|
||||||
void BluetoothInterface::onDataReady()
|
void BluetoothInterface::onDataReady()
|
||||||
{
|
{
|
||||||
QByteArray data = m_socket->readAll();
|
QByteArray data = m_socket->readAll();
|
||||||
|
qDebug() << "BluetoothInterface: recived data:" << qUtf8Printable(data);
|
||||||
emit dataReady(data);
|
emit dataReady(data);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,6 +49,7 @@ private slots:
|
|||||||
void onServiceFound(const QBluetoothServiceInfo &service);
|
void onServiceFound(const QBluetoothServiceInfo &service);
|
||||||
void onConnected();
|
void onConnected();
|
||||||
void onDisconnected();
|
void onDisconnected();
|
||||||
|
void onStateChanged(const QBluetoothSocket::SocketState &state);
|
||||||
void onDataReady();
|
void onDataReady();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -71,25 +71,24 @@ void BluetoothServiceDiscovery::onHostModeChanged(const QBluetoothLocalDevice::H
|
|||||||
|
|
||||||
if (mode != QBluetoothLocalDevice::HostPoweredOff && m_enabed) {
|
if (mode != QBluetoothLocalDevice::HostPoweredOff && m_enabed) {
|
||||||
qDebug() << "Bluetooth available again, continue discovery";
|
qDebug() << "Bluetooth available again, continue discovery";
|
||||||
m_serviceDiscovery->start(QBluetoothServiceDiscoveryAgent::FullDiscovery);
|
discover();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == QBluetoothLocalDevice::HostPoweredOff) {
|
||||||
|
qDebug() << "BluetoothServiceDiscovery: Bluetooth adapter disabled. Stop discovering";
|
||||||
|
m_serviceDiscovery->stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BluetoothServiceDiscovery::onServiceDiscovered(const QBluetoothServiceInfo &serviceInfo)
|
void BluetoothServiceDiscovery::onServiceDiscovered(const QBluetoothServiceInfo &serviceInfo)
|
||||||
{
|
{
|
||||||
qDebug() << "BluetoothServiceDiscovery: Service [+]" << serviceInfo.device().name() << serviceInfo.serviceName() << serviceInfo.serviceProvider();
|
qDebug() << "BluetoothServiceDiscovery: Discovered service on" << serviceInfo.device().name() << serviceInfo.device().address().toString();
|
||||||
|
qDebug() << "\tDevive name:" << serviceInfo.device().name();
|
||||||
qDebug() << "Discovered service on"
|
|
||||||
<< serviceInfo.device().name() << serviceInfo.device().address().toString();
|
|
||||||
qDebug() << "\tService name:" << serviceInfo.serviceName();
|
qDebug() << "\tService name:" << serviceInfo.serviceName();
|
||||||
qDebug() << "\tDescription:"
|
qDebug() << "\tDescription:" << serviceInfo.attribute(QBluetoothServiceInfo::ServiceDescription).toString();
|
||||||
<< serviceInfo.attribute(QBluetoothServiceInfo::ServiceDescription).toString();
|
qDebug() << "\tProvider:" << serviceInfo.attribute(QBluetoothServiceInfo::ServiceProvider).toString();
|
||||||
qDebug() << "\tProvider:"
|
qDebug() << "\tDocumentation:" << serviceInfo.attribute(QBluetoothServiceInfo::DocumentationUrl).toString();
|
||||||
<< serviceInfo.attribute(QBluetoothServiceInfo::ServiceProvider).toString();
|
qDebug() << "\tL2CAP protocol service multiplexer:" << serviceInfo.protocolServiceMultiplexer();
|
||||||
qDebug() << "\Documentation:"
|
|
||||||
<< serviceInfo.attribute(QBluetoothServiceInfo::DocumentationUrl).toString();
|
|
||||||
qDebug() << "\tL2CAP protocol service multiplexer:"
|
|
||||||
<< serviceInfo.protocolServiceMultiplexer();
|
|
||||||
qDebug() << "\tRFCOMM server channel:" << serviceInfo.serverChannel();
|
qDebug() << "\tRFCOMM server channel:" << serviceInfo.serverChannel();
|
||||||
|
|
||||||
if (serviceInfo.serviceClassUuids().isEmpty())
|
if (serviceInfo.serviceClassUuids().isEmpty())
|
||||||
|
|||||||
@ -128,11 +128,6 @@ QString DiscoveryDevice::toUrl(int portConfigIndex)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DiscoveryDevice::toUrl(const QString &hostAddress)
|
|
||||||
{
|
|
||||||
return QString("rfcom://%1").arg(hostAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
PortConfigs::PortConfigs(QObject *parent): QAbstractListModel(parent)
|
PortConfigs::PortConfigs(QObject *parent): QAbstractListModel(parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@ -134,7 +134,6 @@ public:
|
|||||||
PortConfigs *portConfigs() const;
|
PortConfigs *portConfigs() const;
|
||||||
|
|
||||||
Q_INVOKABLE QString toUrl(int portConfigIndex);
|
Q_INVOKABLE QString toUrl(int portConfigIndex);
|
||||||
Q_INVOKABLE QString toUrl(const QString &hostAddress);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void nameChanged();
|
void nameChanged();
|
||||||
|
|||||||
@ -38,7 +38,7 @@ QVariant DiscoveryModel::data(const QModelIndex &index, int role) const
|
|||||||
|
|
||||||
DiscoveryDevice *device = m_devices.at(index.row());
|
DiscoveryDevice *device = m_devices.at(index.row());
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case TypeRole:
|
case DeviceTypeRole:
|
||||||
return device->deviceType();
|
return device->deviceType();
|
||||||
case UuidRole:
|
case UuidRole:
|
||||||
return device->uuid();
|
return device->uuid();
|
||||||
@ -112,7 +112,7 @@ void DiscoveryModel::clearModel()
|
|||||||
QHash<int, QByteArray> DiscoveryModel::roleNames() const
|
QHash<int, QByteArray> DiscoveryModel::roleNames() const
|
||||||
{
|
{
|
||||||
QHash<int, QByteArray> roles;
|
QHash<int, QByteArray> roles;
|
||||||
roles[TypeRole] = "type";
|
roles[DeviceTypeRole] = "deviceType";
|
||||||
roles[UuidRole] = "uuid";
|
roles[UuidRole] = "uuid";
|
||||||
roles[NameRole] = "name";
|
roles[NameRole] = "name";
|
||||||
roles[HostAddressRole] = "hostAddress";
|
roles[HostAddressRole] = "hostAddress";
|
||||||
|
|||||||
@ -32,7 +32,7 @@ class DiscoveryModel : public QAbstractListModel
|
|||||||
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||||
public:
|
public:
|
||||||
enum DeviceRole {
|
enum DeviceRole {
|
||||||
TypeRole,
|
DeviceTypeRole,
|
||||||
UuidRole,
|
UuidRole,
|
||||||
NameRole,
|
NameRole,
|
||||||
HostAddressRole,
|
HostAddressRole,
|
||||||
|
|||||||
@ -267,6 +267,7 @@ void JsonRpcClient::onInterfaceConnectedChanged(bool connected)
|
|||||||
|
|
||||||
void JsonRpcClient::dataReceived(const QByteArray &data)
|
void JsonRpcClient::dataReceived(const QByteArray &data)
|
||||||
{
|
{
|
||||||
|
qDebug() << "JsonRpcClient: received data:" << qUtf8Printable(data);
|
||||||
m_receiveBuffer.append(data);
|
m_receiveBuffer.append(data);
|
||||||
|
|
||||||
int splitIndex = m_receiveBuffer.indexOf("}\n{") + 1;
|
int splitIndex = m_receiveBuffer.indexOf("}\n{") + 1;
|
||||||
|
|||||||
@ -37,6 +37,7 @@ void NymeaConnection::connect(const QString &url)
|
|||||||
qWarning() << "Cannot connect to urls of scheme" << m_currentUrl.scheme() << "Supported schemes are" << m_interfaces.keys();
|
qWarning() << "Cannot connect to urls of scheme" << m_currentUrl.scheme() << "Supported schemes are" << m_interfaces.keys();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "Should connect to url" << m_currentUrl;
|
qDebug() << "Should connect to url" << m_currentUrl;
|
||||||
m_currentInterface->connect(m_currentUrl);
|
m_currentInterface->connect(m_currentUrl);
|
||||||
}
|
}
|
||||||
@ -80,13 +81,19 @@ QString NymeaConnection::hostAddress() const
|
|||||||
return m_currentUrl.host();
|
return m_currentUrl.host();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString NymeaConnection::bluetoothAddress() const
|
||||||
|
{
|
||||||
|
QUrlQuery query(m_currentUrl);
|
||||||
|
return query.queryItemValue("mac");
|
||||||
|
}
|
||||||
|
|
||||||
void NymeaConnection::sendData(const QByteArray &data)
|
void NymeaConnection::sendData(const QByteArray &data)
|
||||||
{
|
{
|
||||||
if (connected()) {
|
if (connected()) {
|
||||||
// qDebug() << "sending data:" << data;
|
// qDebug() << "sending data:" << data;
|
||||||
m_currentInterface->sendData(data);
|
m_currentInterface->sendData(data);
|
||||||
} else {
|
} else {
|
||||||
qWarning() << "Not connected. Cannot send.";
|
qWarning() << "Connection: Not connected. Cannot send.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +157,7 @@ void NymeaConnection::onConnected()
|
|||||||
qWarning() << "An inactive interface is emitting signals... ignoring.";
|
qWarning() << "An inactive interface is emitting signals... ignoring.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
qDebug() << "connected";
|
qDebug() << "NymeaConnection: connected.";
|
||||||
emit connectedChanged(true);
|
emit connectedChanged(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +168,7 @@ void NymeaConnection::onDisconnected()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_currentInterface = nullptr;
|
m_currentInterface = nullptr;
|
||||||
qDebug() << "disconnected";
|
qDebug() << "NymeaConnection: disconnected.";
|
||||||
emit connectedChanged(false);
|
emit connectedChanged(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,7 @@ class NymeaConnection : public QObject
|
|||||||
Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
|
Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
|
||||||
Q_PROPERTY(QString url READ url NOTIFY connectedChanged)
|
Q_PROPERTY(QString url READ url NOTIFY connectedChanged)
|
||||||
Q_PROPERTY(QString hostAddress READ hostAddress NOTIFY connectedChanged)
|
Q_PROPERTY(QString hostAddress READ hostAddress NOTIFY connectedChanged)
|
||||||
|
Q_PROPERTY(QString bluetoothAddress READ bluetoothAddress NOTIFY connectedChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit NymeaConnection(QObject *parent = nullptr);
|
explicit NymeaConnection(QObject *parent = nullptr);
|
||||||
@ -28,6 +29,7 @@ public:
|
|||||||
|
|
||||||
QString url() const;
|
QString url() const;
|
||||||
QString hostAddress() const;
|
QString hostAddress() const;
|
||||||
|
QString bluetoothAddress() const;
|
||||||
|
|
||||||
void sendData(const QByteArray &data);
|
void sendData(const QByteArray &data);
|
||||||
|
|
||||||
|
|||||||
@ -150,6 +150,11 @@ Page {
|
|||||||
objectName: "discoveryDelegate" + index
|
objectName: "discoveryDelegate" + index
|
||||||
property var discoveryDevice: discovery.discoveryModel.get(index)
|
property var discoveryDevice: discovery.discoveryModel.get(index)
|
||||||
property string defaultPortConfigIndex: {
|
property string defaultPortConfigIndex: {
|
||||||
|
|
||||||
|
if (model.deviceType !== DiscoveryDevice.DeviceTypeNetwork) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
var usedConfigIndex = 0;
|
var usedConfigIndex = 0;
|
||||||
for (var i = 1; i < discoveryDevice.portConfigs.count; i++) {
|
for (var i = 1; i < discoveryDevice.portConfigs.count; i++) {
|
||||||
var oldConfig = discoveryDevice.portConfigs.get(usedConfigIndex);
|
var oldConfig = discoveryDevice.portConfigs.get(usedConfigIndex);
|
||||||
@ -172,18 +177,18 @@ Page {
|
|||||||
return usedConfigIndex
|
return usedConfigIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
iconName: model.type === DiscoveryDevice.DeviceTypeNetwork ? "../images/network-wifi-symbolic.svg" : "../images/bluetooth.svg"
|
iconName: model.deviceType === DiscoveryDevice.DeviceTypeNetwork ? "../images/network-wifi-symbolic.svg" : "../images/bluetooth.svg"
|
||||||
text: model.name
|
text: model.name
|
||||||
subText: model.type === DiscoveryDevice.DeviceTypeNetwork ? model.hostAddress : model.bluetoothAddress
|
subText: model.deviceType === DiscoveryDevice.DeviceTypeNetwork ? discoveryDevice.hostAddress : discoveryDevice.bluetoothAddress
|
||||||
property bool hasSecurePort: {
|
property bool hasSecurePort: {
|
||||||
if (model.type === DiscoveryDevice.DeviceTypeNetwork) {
|
if (discoveryDevice.deviceType === DiscoveryDevice.DeviceTypeNetwork) {
|
||||||
return discoveryDeviceDelegate.discoveryDevice.portConfigs.get(discoveryDeviceDelegate.defaultPortConfigIndex).sslEnabled
|
return discoveryDeviceDelegate.discoveryDevice.portConfigs.get(discoveryDeviceDelegate.defaultPortConfigIndex).sslEnabled
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
property bool isTrusted: {
|
property bool isTrusted: {
|
||||||
if (model.type === DiscoveryDevice.DeviceTypeNetwork) {
|
if (discoveryDeviceDelegate.discoveryDevice.deviceType === DiscoveryDevice.DeviceTypeNetwork) {
|
||||||
Engine.connection.isTrusted(discoveryDeviceDelegate.discoveryDevice.toUrl(discoveryDeviceDelegate.defaultPortConfigIndex))
|
Engine.connection.isTrusted(discoveryDeviceDelegate.discoveryDevice.toUrl(discoveryDeviceDelegate.defaultPortConfigIndex))
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
@ -192,13 +197,19 @@ Page {
|
|||||||
progressive: hasSecurePort
|
progressive: hasSecurePort
|
||||||
secondaryIconName: "../images/network-secure.svg"
|
secondaryIconName: "../images/network-secure.svg"
|
||||||
secondaryIconColor: isTrusted ? app.guhAccent : Material.foreground
|
secondaryIconColor: isTrusted ? app.guhAccent : Material.foreground
|
||||||
swipe.enabled: model.type === DiscoveryDevice.DeviceTypeNetwork
|
swipe.enabled: discoveryDeviceDelegate.discoveryDevice.deviceType === DiscoveryDevice.DeviceTypeNetwork
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (model.type === DiscoveryDevice.DeviceTypeNetwork) {
|
switch (discoveryDeviceDelegate.discoveryDevice.deviceType) {
|
||||||
Engine.connection.connect(discoveryDevice.toUrl(defaultPortConfigIndex))
|
case DiscoveryDevice.DeviceTypeNetwork:
|
||||||
} else if (model.type === DiscoveryDevice.DeviceTypeBluetooth) {
|
Engine.connection.connect(discoveryDeviceDelegate.discoveryDevice.toUrl(discoveryDeviceDelegate.defaultPortConfigIndex))
|
||||||
Engine.connection.connect("rfcom://bluetooth.local?mac=" + model.bluetoothAddress)
|
break;
|
||||||
|
case DiscoveryDevice.DeviceTypeBluetooth:
|
||||||
|
Engine.connection.connect("rfcom://bluetooth.local?mac=" + model.bluetoothAddress + "&name=" + model.name)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.warn("Could not connect, unknown type")
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pageStack.push(connectingPage)
|
pageStack.push(connectingPage)
|
||||||
@ -214,7 +225,7 @@ Page {
|
|||||||
name: "../images/info.svg"
|
name: "../images/info.svg"
|
||||||
}
|
}
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (model.type === DiscoveryDevice.DeviceTypeNetwork) {
|
if (model.deviceType === DiscoveryDevice.DeviceTypeNetwork) {
|
||||||
swipe.close()
|
swipe.close()
|
||||||
var popup = infoDialog.createObject(app,{discoveryDevice: discovery.discoveryModel.get(index)})
|
var popup = infoDialog.createObject(app,{discoveryDevice: discovery.discoveryModel.get(index)})
|
||||||
popup.open()
|
popup.open()
|
||||||
|
|||||||
Reference in New Issue
Block a user