Move remaining Bluetooth Signals to BtService to prevent overlaps.
This commit is contained in:
parent
28caa06b09
commit
361e1467b7
@ -38,17 +38,8 @@ public:
|
||||
std::string getAdapterAddress() const override;
|
||||
bool isAvailable() const override;
|
||||
|
||||
signals:
|
||||
void startPairing(const QString& address, PairingPromise::Pointer promise);
|
||||
|
||||
private slots:
|
||||
void createBluetoothLocalDevice();
|
||||
void onStartPairing(const QString& address, PairingPromise::Pointer promise);
|
||||
void onPairingDisplayConfirmation(const QBluetoothAddress &address, QString pin);
|
||||
void onPairingDisplayPinCode(const QBluetoothAddress &address, QString pin);
|
||||
void onPairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing);
|
||||
void onError(QBluetoothLocalDevice::Error error);
|
||||
void onHostModeStateChanged(QBluetoothLocalDevice::HostMode state);
|
||||
void createBluetoothLocalDevice(const QString &adapterAddress);
|
||||
|
||||
private:
|
||||
mutable std::mutex mutex_;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <QWidget>
|
||||
#include <f1x/openauto/autoapp/Configuration/IConfiguration.hpp>
|
||||
#include <QFileDialog>
|
||||
#include <QComboBox>
|
||||
#include <QKeyEvent>
|
||||
#ifdef MAC_OS
|
||||
#else
|
||||
@ -98,7 +99,16 @@ private:
|
||||
void saveButtonCheckBoxes();
|
||||
void saveButtonCheckBox(const QCheckBox* checkBox, configuration::IConfiguration::ButtonCodes& buttonCodes, aap_protobuf::service::media::sink::message::KeyCode buttonCode);
|
||||
void setButtonCheckBoxes(bool value);
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
void populateBluetoothComboBoxLinux(QComboBox *comboBoxBluetooth);
|
||||
#endif
|
||||
#ifdef Q_OS_WIN
|
||||
void populateBluetoothComboBoxWindows(QComboBox *comboBoxBluetooth);
|
||||
#endif
|
||||
#ifdef Q_OS_MAC
|
||||
void populateBluetoothComboBoxMac(QComboBox *comboBoxBluetooth);
|
||||
#endif
|
||||
void populateBluetoothComboBox(QComboBox *comboBoxBluetooth);
|
||||
Ui::SettingsWindow* ui_;
|
||||
configuration::IConfiguration::Pointer configuration_;
|
||||
|
||||
|
@ -33,47 +33,46 @@
|
||||
#include <aap_protobuf/aaw/WifiStartResponse.pb.h>
|
||||
#include <aap_protobuf/aaw/WifiStartRequest.pb.h>
|
||||
|
||||
namespace f1x {
|
||||
namespace openauto {
|
||||
namespace btservice {
|
||||
|
||||
class AndroidBluetoothServer : public QObject, public IAndroidBluetoothServer {
|
||||
Q_OBJECT
|
||||
namespace f1x::openauto::btservice {
|
||||
|
||||
public:
|
||||
AndroidBluetoothServer(autoapp::configuration::IConfiguration::Pointer configuration);
|
||||
class AndroidBluetoothServer : public QObject, public IAndroidBluetoothServer {
|
||||
Q_OBJECT
|
||||
|
||||
uint16_t start(const QBluetoothAddress &address) override;
|
||||
public:
|
||||
AndroidBluetoothServer(autoapp::configuration::IConfiguration::Pointer configuration);
|
||||
|
||||
private slots:
|
||||
uint16_t start(const QBluetoothAddress &address) override;
|
||||
|
||||
void onClientConnected();
|
||||
private slots:
|
||||
|
||||
private:
|
||||
std::unique_ptr<QBluetoothServer> rfcommServer_;
|
||||
QBluetoothSocket *socket = nullptr;
|
||||
autoapp::configuration::IConfiguration::Pointer configuration_;
|
||||
void onClientConnected();
|
||||
|
||||
void readSocket();
|
||||
private:
|
||||
std::unique_ptr<QBluetoothServer> rfcommServer_;
|
||||
QBluetoothSocket *socket = nullptr;
|
||||
autoapp::configuration::IConfiguration::Pointer configuration_;
|
||||
|
||||
QByteArray buffer;
|
||||
void readSocket();
|
||||
|
||||
void handleWifiInfoRequest(QByteArray &buffer, uint16_t length);
|
||||
QByteArray buffer;
|
||||
|
||||
void handleWifiVersionResponse(QByteArray &buffer, uint16_t length);
|
||||
void handleWifiInfoRequest(QByteArray &buffer, uint16_t length);
|
||||
|
||||
void handleWifiConnectionStatus(QByteArray &buffer, uint16_t length);
|
||||
void handleWifiVersionResponse(QByteArray &buffer, uint16_t length);
|
||||
|
||||
void handleWifiStartResponse(QByteArray &buffer, uint16_t length);
|
||||
void handleWifiConnectionStatus(QByteArray &buffer, uint16_t length);
|
||||
|
||||
void sendMessage(const google::protobuf::Message &message, uint16_t type);
|
||||
void handleWifiStartResponse(QByteArray &buffer, uint16_t length);
|
||||
|
||||
void sendMessage(const google::protobuf::Message &message, uint16_t type);
|
||||
|
||||
|
||||
const ::std::string getIP4_(const QString intf);
|
||||
const ::std::string getIP4_(const QString intf);
|
||||
|
||||
void DecodeProtoMessage(const std::string &proto_data);
|
||||
};
|
||||
void DecodeProtoMessage(const std::string &proto_data);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -21,11 +21,7 @@
|
||||
#include <QBluetoothServiceInfo>
|
||||
#include <f1x/openauto/btservice/IAndroidBluetoothService.hpp>
|
||||
|
||||
namespace f1x
|
||||
{
|
||||
namespace openauto
|
||||
{
|
||||
namespace btservice
|
||||
namespace f1x::openauto::btservice
|
||||
{
|
||||
|
||||
class AndroidBluetoothService: public IAndroidBluetoothService
|
||||
@ -41,5 +37,5 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
38
include/f1x/openauto/btservice/BluetoothHandler.hpp
Normal file
38
include/f1x/openauto/btservice/BluetoothHandler.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
//
|
||||
// Created by Simon Dean on 26/11/2024.
|
||||
//
|
||||
|
||||
#ifndef OPENAUTO_BLUETOOTHHANDLER_HPP
|
||||
#define OPENAUTO_BLUETOOTHHANDLER_HPP
|
||||
|
||||
#include <f1x/openauto/btservice/IBluetoothHandler.hpp>
|
||||
#include <f1x/openauto/autoapp/Configuration/IConfiguration.hpp>
|
||||
#include <QObject>
|
||||
|
||||
|
||||
namespace f1x::openauto::btservice {
|
||||
|
||||
class BluetoothHandler : public QObject, public IBluetoothHandler {
|
||||
Q_OBJECT
|
||||
public:
|
||||
BluetoothHandler(autoapp::configuration::IConfiguration::Pointer configuration);
|
||||
|
||||
private slots:
|
||||
void onPairingDisplayPinCode(const QBluetoothAddress &address, QString pin);
|
||||
|
||||
void onPairingDisplayConfirmation(const QBluetoothAddress &address, QString pin);
|
||||
|
||||
void onPairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing);
|
||||
|
||||
void onError(QBluetoothLocalDevice::Error error);
|
||||
|
||||
void onHostModeStateChanged(QBluetoothLocalDevice::HostMode state);
|
||||
|
||||
private:
|
||||
std::unique_ptr<QBluetoothLocalDevice> localDevice_;
|
||||
autoapp::configuration::IConfiguration::Pointer configuration_;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //OPENAUTO_BLUETOOTHHANDLER_HPP
|
@ -20,11 +20,9 @@
|
||||
|
||||
#include <QBluetoothAddress>
|
||||
|
||||
namespace f1x
|
||||
{
|
||||
namespace openauto
|
||||
{
|
||||
namespace btservice
|
||||
|
||||
|
||||
namespace f1x::openauto::btservice
|
||||
{
|
||||
|
||||
class IAndroidBluetoothServer
|
||||
@ -36,5 +34,5 @@ public:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,11 +20,7 @@
|
||||
|
||||
#include <QBluetoothAddress>
|
||||
|
||||
namespace f1x
|
||||
{
|
||||
namespace openauto
|
||||
{
|
||||
namespace btservice
|
||||
namespace f1x::openauto::btservice
|
||||
{
|
||||
|
||||
class IAndroidBluetoothService
|
||||
@ -37,5 +33,5 @@ public:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
24
include/f1x/openauto/btservice/IBluetoothHandler.hpp
Normal file
24
include/f1x/openauto/btservice/IBluetoothHandler.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by Simon Dean on 26/11/2024.
|
||||
//
|
||||
|
||||
#ifndef OPENAUTO_IBLUETOOTHHANDLER_HPP
|
||||
#define OPENAUTO_IBLUETOOTHHANDLER_HPP
|
||||
|
||||
#include <QBluetoothAddress>
|
||||
#include <QBluetoothLocalDevice>
|
||||
|
||||
namespace f1x::openauto::btservice {
|
||||
|
||||
class IBluetoothHandler
|
||||
{
|
||||
public:
|
||||
virtual ~IBluetoothHandler() = default;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //OPENAUTO_IBLUETOOTHHANDLER_HPP
|
@ -34,12 +34,7 @@ bool DummyBluetoothDevice::isPaired(const std::string&) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void DummyBluetoothDevice::pair(const std::string&, PairingPromise::Pointer promise)
|
||||
{
|
||||
promise->reject();
|
||||
}
|
||||
|
||||
std::string DummyBluetoothDevice::getLocalAddress() const
|
||||
std::string DummyBluetoothDevice::getAdapterAddress() const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
@ -19,159 +19,53 @@
|
||||
#include <QApplication>
|
||||
#include <f1x/openauto/Common/Log.hpp>
|
||||
#include <f1x/openauto/autoapp/Projection/LocalBluetoothDevice.hpp>
|
||||
#include <QBluetoothUuid>
|
||||
#include <QtBluetooth>
|
||||
|
||||
namespace f1x::openauto::autoapp::projection {
|
||||
|
||||
LocalBluetoothDevice::LocalBluetoothDevice()
|
||||
{
|
||||
LocalBluetoothDevice::LocalBluetoothDevice(const QString &adapterAddress, QObject *parent) : QObject(parent) {
|
||||
qRegisterMetaType<IBluetoothDevice::PairingPromise::Pointer>("PairingPromise::Pointer");
|
||||
|
||||
this->moveToThread(QApplication::instance()->thread());
|
||||
connect(this, &LocalBluetoothDevice::startPairing, this, &LocalBluetoothDevice::onStartPairing, Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(this, "createBluetoothLocalDevice", Qt::BlockingQueuedConnection);
|
||||
}
|
||||
|
||||
void LocalBluetoothDevice::createBluetoothLocalDevice()
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "createBluetoothLocalDevice", Qt::BlockingQueuedConnection,
|
||||
Q_ARG(QString, adapterAddress));
|
||||
|
||||
}
|
||||
|
||||
void LocalBluetoothDevice::createBluetoothLocalDevice(const QString &adapterAddress) {
|
||||
OPENAUTO_LOG(info) << "[LocalBluetoothDevice] create.";
|
||||
|
||||
localDevice_ = std::make_unique<QBluetoothLocalDevice>(QBluetoothAddress());
|
||||
|
||||
connect(localDevice_.get(), &QBluetoothLocalDevice::pairingDisplayConfirmation, this, &LocalBluetoothDevice::onPairingDisplayConfirmation);
|
||||
connect(localDevice_.get(), &QBluetoothLocalDevice::pairingDisplayPinCode, this, &LocalBluetoothDevice::onPairingDisplayPinCode);
|
||||
connect(localDevice_.get(), &QBluetoothLocalDevice::pairingFinished, this, &LocalBluetoothDevice::onPairingFinished);
|
||||
connect(localDevice_.get(), &QBluetoothLocalDevice::error, this, &LocalBluetoothDevice::onError);
|
||||
connect(localDevice_.get(), &QBluetoothLocalDevice::hostModeStateChanged, this, &LocalBluetoothDevice::onHostModeStateChanged);
|
||||
QBluetoothAddress address(adapterAddress);
|
||||
localDevice_ = std::make_unique<QBluetoothLocalDevice>(address);
|
||||
|
||||
localDevice_->powerOn();
|
||||
localDevice_->setHostMode(QBluetoothLocalDevice::HostDiscoverable);
|
||||
// Pairing signals are being handled by btservice
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void LocalBluetoothDevice::stop()
|
||||
{
|
||||
void LocalBluetoothDevice::stop() {
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
|
||||
if(pairingPromise_ != nullptr)
|
||||
{
|
||||
pairingPromise_->reject();
|
||||
pairingPromise_.reset();
|
||||
pairingAddress_ = QBluetoothAddress();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LocalBluetoothDevice::isPaired(const std::string& address) const
|
||||
{
|
||||
bool LocalBluetoothDevice::isPaired(const std::string &address) const {
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
|
||||
return localDevice_->pairingStatus(QBluetoothAddress(QString::fromStdString(address))) != QBluetoothLocalDevice::Unpaired;
|
||||
}
|
||||
|
||||
void LocalBluetoothDevice::pair(const std::string& address, PairingPromise::Pointer promise)
|
||||
{
|
||||
emit startPairing(QString::fromStdString(address), std::move(promise));
|
||||
}
|
||||
return localDevice_->pairingStatus(QBluetoothAddress(QString::fromStdString(address))) !=
|
||||
QBluetoothLocalDevice::Unpaired;
|
||||
}
|
||||
|
||||
std::string LocalBluetoothDevice::getAdapterAddress() const {
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
return localDevice_->isValid() ? localDevice_->address().toString().toStdString() : "";
|
||||
}
|
||||
}
|
||||
|
||||
bool LocalBluetoothDevice::isAvailable() const
|
||||
{
|
||||
bool LocalBluetoothDevice::isAvailable() const {
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
return localDevice_->isValid();
|
||||
}
|
||||
}
|
||||
|
||||
void LocalBluetoothDevice::onStartPairing(const QString& address, PairingPromise::Pointer promise)
|
||||
{
|
||||
OPENAUTO_LOG(debug) << "[LocalBluetoothDevice] onStartPairing, address: " << address.toStdString();
|
||||
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
|
||||
if(!localDevice_->isValid())
|
||||
{
|
||||
promise->reject();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pairingPromise_ != nullptr)
|
||||
{
|
||||
pairingPromise_->reject();
|
||||
}
|
||||
|
||||
pairingAddress_ = QBluetoothAddress(address);
|
||||
pairingPromise_ = std::move(promise);
|
||||
localDevice_->requestPairing(pairingAddress_, QBluetoothLocalDevice::AuthorizedPaired);
|
||||
}
|
||||
}
|
||||
|
||||
void LocalBluetoothDevice::onPairingDisplayConfirmation(const QBluetoothAddress &address, QString pin)
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[LocalBluetoothDevice] onPairingDisplayConfirmation, address: " << address.toString().toStdString()
|
||||
<< ", pin: " << pin.toStdString();
|
||||
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
localDevice_->pairingConfirmation(address == pairingAddress_);
|
||||
}
|
||||
|
||||
void LocalBluetoothDevice::onPairingDisplayPinCode(const QBluetoothAddress &address, QString pin)
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[LocalBluetoothDevice] onPairingDisplayPinCode, address: " << address.toString().toStdString()
|
||||
<< ", pin: " << pin.toStdString();
|
||||
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
localDevice_->pairingConfirmation(address == pairingAddress_);
|
||||
}
|
||||
|
||||
void LocalBluetoothDevice::onPairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing)
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[LocalBluetoothDevice] onPairingDisplayPinCode, address: " << address.toString().toStdString()
|
||||
<< ", pin: " << pairing;
|
||||
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
|
||||
if(address == pairingAddress_)
|
||||
{
|
||||
if(pairing != QBluetoothLocalDevice::Unpaired)
|
||||
{
|
||||
pairingPromise_->resolve();
|
||||
}
|
||||
else
|
||||
{
|
||||
pairingPromise_->reject();
|
||||
}
|
||||
|
||||
pairingPromise_.reset();
|
||||
pairingAddress_ = QBluetoothAddress();
|
||||
}
|
||||
}
|
||||
|
||||
void LocalBluetoothDevice::onError(QBluetoothLocalDevice::Error error)
|
||||
{
|
||||
OPENAUTO_LOG(warning) << "[LocalBluetoothDevice] onError, error: " << error;
|
||||
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
|
||||
if(pairingPromise_ != nullptr)
|
||||
{
|
||||
pairingPromise_->reject();
|
||||
pairingPromise_.reset();
|
||||
pairingAddress_ = QBluetoothAddress();
|
||||
}
|
||||
}
|
||||
|
||||
void LocalBluetoothDevice::onHostModeStateChanged(QBluetoothLocalDevice::HostMode state)
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
|
||||
if(state == QBluetoothLocalDevice::HostPoweredOff && pairingPromise_ != nullptr)
|
||||
{
|
||||
pairingPromise_->reject();
|
||||
pairingPromise_.reset();
|
||||
pairingAddress_ = QBluetoothAddress();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include <f1x/openauto/autoapp/Service/Bluetooth/BluetoothService.hpp>
|
||||
#include <f1x/openauto/autoapp/Service/InputSource/InputSourceService.hpp>
|
||||
#include <f1x/openauto/autoapp/Service/WifiProjection/WifiProjectionService.hpp>
|
||||
|
||||
#include <f1x/openauto/autoapp/Projection/QtVideoOutput.hpp>
|
||||
#include <f1x/openauto/autoapp/Projection/OMXVideoOutput.hpp>
|
||||
#include <f1x/openauto/autoapp/Projection/RtAudioOutput.hpp>
|
||||
@ -46,7 +45,6 @@
|
||||
#include <f1x/openauto/autoapp/Projection/QtAudioInput.hpp>
|
||||
#include <f1x/openauto/autoapp/Projection/InputDevice.hpp>
|
||||
#include <f1x/openauto/autoapp/Projection/LocalBluetoothDevice.hpp>
|
||||
#include <f1x/openauto/autoapp/Projection/RemoteBluetoothDevice.hpp>
|
||||
#include <f1x/openauto/autoapp/Projection/DummyBluetoothDevice.hpp>
|
||||
|
||||
namespace f1x::openauto::autoapp::service {
|
||||
|
@ -2163,7 +2163,7 @@ void f1x::openauto::autoapp::ui::MainWindow::tmpChanged()
|
||||
ui_->devlabel_right->show();
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
||||
if (std::ifstream("/tmp/btdevice") || std::ifstream("/tmp/media_playing") || std::ifstream("/tmp/dev_mode_enabled") || std::ifstream("/tmp/android_device")) {
|
||||
if (ui_->labelLock->isVisible() == false) {
|
||||
|
@ -16,6 +16,7 @@
|
||||
* along with openauto. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <boost/algorithm/hex.hpp>
|
||||
#include <f1x/openauto/Common/Log.hpp>
|
||||
#include <f1x/openauto/autoapp/Configuration/IConfiguration.hpp>
|
||||
@ -23,7 +24,15 @@
|
||||
#include <QString>
|
||||
#include <QtCore/QDataStream>
|
||||
#include <QNetworkInterface>
|
||||
#include <iostream>
|
||||
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
|
||||
#include <google/protobuf/io/coded_stream.h>
|
||||
#include <google/protobuf/unknown_field_set.h>
|
||||
|
||||
using namespace google::protobuf;
|
||||
using namespace google::protobuf::io;
|
||||
|
||||
// 39171FDJG002WHhandleWifiVersionRequest
|
||||
|
||||
namespace f1x::openauto::btservice {
|
||||
|
||||
@ -34,14 +43,18 @@ namespace f1x::openauto::btservice {
|
||||
&AndroidBluetoothServer::onClientConnected);
|
||||
}
|
||||
|
||||
/// Start Server listening on Address
|
||||
uint16_t AndroidBluetoothServer::start(const QBluetoothAddress &address) {
|
||||
OPENAUTO_LOG(debug) << "[AndroidBluetoothServer] start()";
|
||||
if (rfcommServer_->listen(address)) {
|
||||
return rfcommServer_->serverPort();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Call-Back for when Client Connected
|
||||
void AndroidBluetoothServer::onClientConnected() {
|
||||
OPENAUTO_LOG(debug) << "[AndroidBluetoothServer] onClientConnected()";
|
||||
if (socket != nullptr) {
|
||||
socket->deleteLater();
|
||||
}
|
||||
@ -49,31 +62,31 @@ namespace f1x::openauto::btservice {
|
||||
socket = rfcommServer_->nextPendingConnection();
|
||||
|
||||
if (socket != nullptr) {
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] rfcomm client connected, peer name: "
|
||||
OPENAUTO_LOG(debug) << "[AndroidBluetoothServer] rfcomm client connected, peer name: "
|
||||
<< socket->peerName().toStdString();
|
||||
|
||||
connect(socket, &QBluetoothSocket::readyRead, this, &AndroidBluetoothServer::readSocket);
|
||||
|
||||
aap_protobuf::service::wifiprojection::message::WifiCredentialsRequest request;
|
||||
// TODO: How do we ping back the Wireless Port and IP?
|
||||
//aap_protobuf::service::::WifiInfoRequest request;
|
||||
request.set_ip_address(getIP4_("wlan0"));
|
||||
getIP4_()
|
||||
//request.set_port(5000);
|
||||
aap_protobuf::aaw::WifiVersionRequest versionRequest;
|
||||
aap_protobuf::aaw::WifiStartRequest startRequest;
|
||||
startRequest.set_ip_address(getIP4_("wlan0"));
|
||||
startRequest.set_port(5000);
|
||||
|
||||
sendMessage(request, 1);
|
||||
sendMessage(versionRequest, aap_protobuf::aaw::MessageId::WIFI_VERSION_REQUEST);
|
||||
sendMessage(startRequest, aap_protobuf::aaw::MessageId::WIFI_START_REQUEST);
|
||||
} else {
|
||||
OPENAUTO_LOG(error) << "[AndroidBluetoothServer] received null socket during client connection.";
|
||||
}
|
||||
}
|
||||
|
||||
/// Read data from Bluetooth Socket
|
||||
void AndroidBluetoothServer::readSocket() {
|
||||
buffer += socket->readAll();
|
||||
|
||||
OPENAUTO_LOG(info) << "Received message";
|
||||
OPENAUTO_LOG(debug) << "[AndroidBluetoothServer::readSocket] Reading from socket.";
|
||||
|
||||
if (buffer.length() < 4) {
|
||||
OPENAUTO_LOG(debug) << "Not enough data, waiting for more";
|
||||
OPENAUTO_LOG(debug) << "[AndroidBluetoothServer::readSocket] Not enough data, waiting for more.";
|
||||
return;
|
||||
}
|
||||
|
||||
@ -82,66 +95,112 @@ namespace f1x::openauto::btservice {
|
||||
stream >> length;
|
||||
|
||||
if (buffer.length() < length + 4) {
|
||||
OPENAUTO_LOG(info) << "Not enough data, waiting for more: " << buffer.length();
|
||||
OPENAUTO_LOG(debug) << "[AndroidBluetoothServer::readSocket] Not enough data, waiting for more: " << buffer.length();
|
||||
return;
|
||||
}
|
||||
|
||||
aap_protobuf::service::wifiprojection::WifiProjectionMessageId messageId;
|
||||
//uint16_t messageId;
|
||||
stream >> messageId;
|
||||
quint16 rawMessageId;
|
||||
stream >> rawMessageId;
|
||||
|
||||
//OPENAUTO_LOG(info) << "[AndroidBluetoothServer] " << length << " " << messageId;
|
||||
OPENAUTO_LOG(debug) << messageId;
|
||||
aap_protobuf::aaw::MessageId messageId;
|
||||
messageId = static_cast<aap_protobuf::aaw::MessageId>(rawMessageId);
|
||||
|
||||
OPENAUTO_LOG(debug) << "[AndroidBluetoothServer::readSocket] Message length: " << length << " MessageId: " << messageId;
|
||||
|
||||
switch (messageId) {
|
||||
|
||||
case aap_protobuf::aaw::MessageId::WIFI_INFO_REQUEST: // WifiInfoRequest - Respond with a WifiInfoResponse
|
||||
handleWifiInfoRequest(buffer, length);
|
||||
break;
|
||||
case aap_protobuf::aaw::MessageId::WIFI_VERSION_RESPONSE: // WifiVersionRequest - Send a Version Request
|
||||
handleWifiVersionResponse(buffer, length);// do something
|
||||
break;
|
||||
case aap_protobuf::aaw::MessageId::WIFI_CONNECTION_STATUS: // WifiStartResponse - Receive a confirmation
|
||||
handleWifiConnectionStatus(buffer, length);
|
||||
break;
|
||||
case aap_protobuf::aaw::MessageId::WIFI_START_RESPONSE: // WifiStartResponse - Receive a confirmation
|
||||
handleWifiStartResponse(buffer, length);
|
||||
break;
|
||||
case aap_protobuf::aaw::MessageId::WIFI_START_REQUEST: // These are not received from the MD.
|
||||
case aap_protobuf::aaw::MessageId::WIFI_INFO_RESPONSE: // These are not received from the MD.
|
||||
case aap_protobuf::aaw::MessageId::WIFI_VERSION_REQUEST: // These are not received from the MD.
|
||||
default:
|
||||
QByteArray messageData = buffer.mid(stream.device()->pos(), length - 2);
|
||||
|
||||
// Convert QByteArray to std::string
|
||||
std::string protoData = messageData.toStdString();
|
||||
|
||||
// Pass it to your function
|
||||
this->DecodeProtoMessage(protoData);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << std::hex << std::setfill('0');
|
||||
for (auto &&val: buffer) {
|
||||
ss << std::setw(2) << static_cast<unsigned>(val);
|
||||
}
|
||||
OPENAUTO_LOG(info) << "Unknown message: " << messageId;
|
||||
OPENAUTO_LOG(info) << ss.str();
|
||||
OPENAUTO_LOG(debug) << "[AndroidBluetoothServer::readSocket] Unknown message: " << messageId;
|
||||
OPENAUTO_LOG(debug) << "[AndroidBluetoothServer::readSocket] Data " << ss.str();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
buffer = buffer.mid(length + 4);
|
||||
}
|
||||
|
||||
/// Handles request for WifiInfoRequest by sending a WifiInfoResponse
|
||||
/// \param buffer
|
||||
/// \param length
|
||||
void AndroidBluetoothServer::handleWifiInfoRequest(QByteArray &buffer, uint16_t length) {
|
||||
aap_protobuf::service::wifiprojection::message::WifiCredentialsRequest msg;
|
||||
msg.ParseFromArray(buffer.data() + 4, length);
|
||||
OPENAUTO_LOG(info) << "WifiInfoRequest: " << msg.DebugString();
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer::handleWifiInfoRequest] Handling wifi info request";
|
||||
|
||||
aap_protobuf::service::wifiprojection::message::WifiCredentialsResponse response;
|
||||
aap_protobuf::aaw::WifiInfoResponse response;
|
||||
|
||||
//response.set_ip_address(getIP4_("wlan0"));
|
||||
//response.set_port(5000);
|
||||
//response.set_status(aap_protobuf::service::control::WifiInfoResponse_Status_STATUS_SUCCESS);
|
||||
|
||||
sendMessage(response, 7);
|
||||
}
|
||||
|
||||
void AndroidBluetoothServer::handleWifiSecurityRequest(QByteArray &buffer, uint16_t length) {
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] WifiSecurityRequest:";
|
||||
aap_protobuf::service::wifiprojection::message::WifiCredentialsResponse response;
|
||||
|
||||
response.set_car_wifi_security_mode(
|
||||
aap_protobuf::service::wifiprojection::message::WifiSecurityMode::WPA2_PERSONAL);
|
||||
response.set_car_wifi_ssid(configuration_->getParamFromFile("/etc/hostapd/hostapd.conf", "ssid").toStdString());
|
||||
response.set_car_wifi_password(
|
||||
response.set_ssid(configuration_->getParamFromFile("/etc/hostapd/hostapd.conf", "ssid").toStdString());
|
||||
response.set_password(
|
||||
configuration_->getParamFromFile("/etc/hostapd/hostapd.conf", "wpa_passphrase").toStdString());
|
||||
response.set_bssid(QNetworkInterface::interfaceFromName("wlan0").hardwareAddress().toStdString());
|
||||
response.set_security_mode(
|
||||
aap_protobuf::service::wifiprojection::message::WifiSecurityMode::WPA2_PERSONAL);
|
||||
response.set_access_point_type(aap_protobuf::service::wifiprojection::message::AccessPointType::STATIC);
|
||||
response.add_supported_wifi_channels(1);
|
||||
|
||||
|
||||
//response.set_ssid(configuration_->getParamFromFile("/etc/hostapd/hostapd.conf","ssid").toStdString());
|
||||
//response.set_bssid(QNetworkInterface::interfaceFromName("wlan0").hardwareAddress().toStdString());
|
||||
//response.set_key(configuration_->getParamFromFile("/etc/hostapd/hostapd.conf","wpa_passphrase").toStdString());
|
||||
//response.set_security_mode(aap_protobuf::messages::WifiSecurityReponse_SecurityMode_WPA2_PERSONAL);
|
||||
//response.set_access_point_type(aap_protobuf::messages::WifiSecurityReponse_AccessPointType_STATIC);
|
||||
|
||||
sendMessage(response, 3);
|
||||
}
|
||||
|
||||
/// Listens for a WifiVersionResponse from the MD - usually just a notification
|
||||
/// \param buffer
|
||||
/// \param length
|
||||
void AndroidBluetoothServer::handleWifiVersionResponse(QByteArray &buffer, uint16_t length) {
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer::handleWifiVersionResponse] Handling wifi version response";
|
||||
|
||||
aap_protobuf::aaw::WifiVersionResponse response;
|
||||
response.ParseFromArray(buffer.data() + 4, length);
|
||||
OPENAUTO_LOG(debug) << "[AndroidBluetoothServer::handleWifiVersionResponse] Unknown Param 1: " << response.unknown_value_a() << " Unknown Param 2: " << response.unknown_value_b();
|
||||
}
|
||||
|
||||
/// Listens for WifiStartResponse from MD - usually just a notification with a status
|
||||
/// \param buffer
|
||||
/// \param length
|
||||
void AndroidBluetoothServer::handleWifiStartResponse(QByteArray &buffer, uint16_t length) {
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer::handleWifiStartResponse] Handling wifi start response";
|
||||
|
||||
aap_protobuf::aaw::WifiStartResponse response;
|
||||
response.ParseFromArray(buffer.data() + 4, length);
|
||||
OPENAUTO_LOG(debug) << "[AndroidBluetoothServer::handleWifiStartResponse] " << response.ip_address() << " port " << response.port() << " status " << Status_Name(response.status());
|
||||
}
|
||||
|
||||
/// Handles request for WifiStartRequest by sending a WifiStartResponse
|
||||
/// \param buffer
|
||||
/// \param length
|
||||
void AndroidBluetoothServer::handleWifiConnectionStatus(QByteArray &buffer, uint16_t length) {
|
||||
aap_protobuf::aaw::WifiConnectionStatus status;
|
||||
status.ParseFromArray(buffer.data() + 4, length);
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer::handleWifiConnectionStatus] Handle wifi connection status, received: " << Status_Name(status.status());
|
||||
}
|
||||
|
||||
void AndroidBluetoothServer::sendMessage(const google::protobuf::Message &message, uint16_t type) {
|
||||
int byteSize = message.ByteSize();
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer::sendMessage] Sending message to connected device";
|
||||
|
||||
int byteSize = message.ByteSizeLong();
|
||||
QByteArray out(byteSize + 4, 0);
|
||||
QDataStream ds(&out, QIODevice::ReadWrite);
|
||||
ds << (uint16_t) byteSize;
|
||||
@ -153,24 +212,17 @@ namespace f1x::openauto::btservice {
|
||||
for (auto &&val: out) {
|
||||
ss << std::setw(2) << static_cast<unsigned>(val);
|
||||
}
|
||||
//OPENAUTO_LOG(info) << "Writing message: " << ss.str();
|
||||
|
||||
OPENAUTO_LOG(debug) << message.GetTypeName() << " - " + message.DebugString();
|
||||
|
||||
auto written = socket->write(out);
|
||||
if (written > -1) {
|
||||
OPENAUTO_LOG(info) << "Bytes written: " << written;
|
||||
OPENAUTO_LOG(debug) << "[AndroidBluetoothServer::sendMessage] Bytes written: " << written;
|
||||
} else {
|
||||
OPENAUTO_LOG(info) << "Could not write data";
|
||||
OPENAUTO_LOG(debug) << "[AndroidBluetoothServer::sendMessage] Could not write data";
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidBluetoothServer::handleWifiInfoRequestResponse(QByteArray &buffer, uint16_t length) {
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] WifiInfoRequestResponse";
|
||||
aap_protobuf::service::wifiprojection::message::WifiCredentialsResponse msg;
|
||||
msg.ParseFromArray(buffer.data() + 4, length);
|
||||
OPENAUTO_LOG(info) << "WifiInfoResponse: " << msg.DebugString();
|
||||
}
|
||||
|
||||
const ::std::string AndroidBluetoothServer::getIP4_(const QString intf) {
|
||||
for (const QNetworkAddressEntry &address: QNetworkInterface::interfaceFromName(intf).addressEntries()) {
|
||||
if (address.ip().protocol() == QAbstractSocket::IPv4Protocol)
|
||||
@ -178,5 +230,47 @@ namespace f1x::openauto::btservice {
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/// Decode Proto Messages to their constituent components
|
||||
/// \param proto_data
|
||||
void AndroidBluetoothServer::DecodeProtoMessage(const std::string& proto_data) {
|
||||
UnknownFieldSet set;
|
||||
|
||||
// Create streams
|
||||
ArrayInputStream raw_input(proto_data.data(), proto_data.size());
|
||||
CodedInputStream input(&raw_input);
|
||||
|
||||
// Decode the message
|
||||
if (!set.MergeFromCodedStream(&input)) {
|
||||
std::cerr << "Failed to decode the message." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Iterate over the fields
|
||||
for (int i = 0; i < set.field_count(); ++i) {
|
||||
const UnknownField& field = set.field(i);
|
||||
switch (field.type()) {
|
||||
case UnknownField::TYPE_VARINT:
|
||||
std::cout << "Field number " << field.number() << " is a varint: " << field.varint() << std::endl;
|
||||
break;
|
||||
case UnknownField::TYPE_FIXED32:
|
||||
std::cout << "Field number " << field.number() << " is a fixed32: " << field.fixed32() << std::endl;
|
||||
break;
|
||||
case UnknownField::TYPE_FIXED64:
|
||||
std::cout << "Field number " << field.number() << " is a fixed64: " << field.fixed64() << std::endl;
|
||||
break;
|
||||
case UnknownField::TYPE_LENGTH_DELIMITED:
|
||||
std::cout << "Field number " << field.number() << " is length-delimited: ";
|
||||
for (char ch : field.length_delimited()) {
|
||||
std::cout << std::hex << (int)(unsigned char)ch;
|
||||
}
|
||||
std::cout << std::dec << std::endl;
|
||||
break;
|
||||
case UnknownField::TYPE_GROUP: // Deprecated in modern Protobuf
|
||||
std::cout << "Field number " << field.number() << " is a group." << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
85
src/btservice/BluetoothHandler.cpp
Normal file
85
src/btservice/BluetoothHandler.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
//
|
||||
// Created by Simon Dean on 26/11/2024.
|
||||
//
|
||||
|
||||
#include <f1x/openauto/btservice/BluetoothHandler.hpp>
|
||||
#include <f1x/openauto/btservice/AndroidBluetoothService.hpp>
|
||||
#include <f1x/openauto/btservice/AndroidBluetoothServer.hpp>
|
||||
#include <f1x/openauto/Common/Log.hpp>
|
||||
|
||||
namespace f1x::openauto::btservice {
|
||||
BluetoothHandler::BluetoothHandler(autoapp::configuration::IConfiguration::Pointer configuration)
|
||||
: configuration_(std::move(configuration)) {
|
||||
|
||||
OPENAUTO_LOG(info) << "[BluetoothHandler::BluetoothHandler] Starting Up...";
|
||||
|
||||
QString adapterAddress = QString::fromStdString(configuration_->getBluetoothAdapterAddress());
|
||||
QBluetoothAddress address(adapterAddress);
|
||||
localDevice_ = std::make_unique<QBluetoothLocalDevice>(QBluetoothAddress());
|
||||
|
||||
if (!localDevice_->isValid()) {
|
||||
OPENAUTO_LOG(error) << "[BluetoothHandler] Bluetooth adapter is not valid.";
|
||||
} else {
|
||||
OPENAUTO_LOG(info) << "[BluetoothHandler] Bluetooth adapter is valid.";
|
||||
}
|
||||
|
||||
QObject::connect(localDevice_.get(), &QBluetoothLocalDevice::pairingDisplayPinCode, this, &BluetoothHandler::onPairingDisplayPinCode);
|
||||
QObject::connect(localDevice_.get(), &QBluetoothLocalDevice::pairingDisplayConfirmation, this, &BluetoothHandler::onPairingDisplayConfirmation);
|
||||
QObject::connect(localDevice_.get(), &QBluetoothLocalDevice::pairingFinished, this, &BluetoothHandler::onPairingFinished);
|
||||
QObject::connect(localDevice_.get(), &QBluetoothLocalDevice::hostModeStateChanged, this, &BluetoothHandler::onHostModeStateChanged);
|
||||
QObject::connect(localDevice_.get(), &QBluetoothLocalDevice::error, this, &BluetoothHandler::onError);
|
||||
|
||||
// Turn Bluetooth on
|
||||
localDevice_->powerOn();
|
||||
|
||||
// Make it visible to others
|
||||
localDevice_->setHostMode(QBluetoothLocalDevice::HostDiscoverable);
|
||||
|
||||
btservice::AndroidBluetoothServer androidBluetoothServer(configuration_);
|
||||
uint16_t portNumber = androidBluetoothServer.start(address);
|
||||
|
||||
if (portNumber == 0) {
|
||||
OPENAUTO_LOG(error) << "[BluetoothHandler::BluetoothHandler] Server start failed.";
|
||||
throw std::runtime_error("Unable to start bluetooth server");
|
||||
}
|
||||
|
||||
OPENAUTO_LOG(info) << "[BluetoothHandler::BluetoothHandler] Listening for connections, address: " << address.toString().toStdString()
|
||||
<< ", port: " << portNumber;
|
||||
|
||||
btservice::AndroidBluetoothService androidBluetoothService(portNumber);
|
||||
if (!androidBluetoothService.registerService(address)) {
|
||||
OPENAUTO_LOG(error) << "[BluetoothHandler::BluetoothHandler] Service registration failed.";
|
||||
throw std::runtime_error("Unable to register btservice");
|
||||
} else {
|
||||
OPENAUTO_LOG(info) << "[BluetoothHandler::BluetoothHandler] Service registered, port: " << portNumber;
|
||||
}
|
||||
|
||||
androidBluetoothService.unregisterService();
|
||||
}
|
||||
|
||||
void BluetoothHandler::onPairingDisplayPinCode(const QBluetoothAddress &address, QString pin) {
|
||||
OPENAUTO_LOG(debug) << "[BluetoothHandler::onPairingDisplayPinCode] Pairing display PIN code: " << pin.toStdString();
|
||||
}
|
||||
|
||||
void BluetoothHandler::onPairingDisplayConfirmation(const QBluetoothAddress &address, QString pin) {
|
||||
OPENAUTO_LOG(debug) << "[BluetoothHandler::onPairingDisplayConfirmation] Pairing display confirmation: " << pin.toStdString();
|
||||
|
||||
// Here you can implement logic to show this PIN to the user or automatically accept if you trust all devices
|
||||
localDevice_->pairingConfirmation(true); // Confirm pairing (for security, you might want to verify the PIN)
|
||||
}
|
||||
|
||||
void BluetoothHandler::onPairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing) {
|
||||
OPENAUTO_LOG(info) << "[BluetoothHandler::onPairingFinished] pairingFinished, address: " << address.toString().toStdString()
|
||||
<< ", pairing: " << pairing;
|
||||
}
|
||||
|
||||
void BluetoothHandler::onError(QBluetoothLocalDevice::Error error) {
|
||||
OPENAUTO_LOG(warning) << "[BluetoothHandler::onError] Bluetooth error: " << error;
|
||||
// ... your logic to handle the error ...
|
||||
}
|
||||
|
||||
void BluetoothHandler::onHostModeStateChanged(QBluetoothLocalDevice::HostMode state) {
|
||||
OPENAUTO_LOG(info) << "[BluetoothHandler::onHostModeStateChanged] Host mode state changed: " << state;
|
||||
// ... your logic to handle the state change ...
|
||||
}
|
||||
}
|
@ -20,8 +20,7 @@
|
||||
#include <QtBluetooth>
|
||||
#include <f1x/openauto/Common/Log.hpp>
|
||||
#include <f1x/openauto/autoapp/Configuration/Configuration.hpp>
|
||||
#include <f1x/openauto/btservice/AndroidBluetoothService.hpp>
|
||||
#include <f1x/openauto/btservice/AndroidBluetoothServer.hpp>
|
||||
#include <f1x/openauto/btservice/BluetoothHandler.hpp>
|
||||
|
||||
namespace btservice = f1x::openauto::btservice;
|
||||
|
||||
@ -29,39 +28,16 @@ int main(int argc, char *argv[]) {
|
||||
QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth*=true"));
|
||||
QCoreApplication qApplication(argc, argv);
|
||||
|
||||
QBluetoothLocalDevice localDevice;
|
||||
const QBluetoothAddress address = localDevice.address();
|
||||
|
||||
auto configuration = std::make_shared<f1x::openauto::autoapp::configuration::Configuration>();
|
||||
|
||||
// Turn Bluetooth on
|
||||
localDevice.powerOn();
|
||||
// Make it visible to others
|
||||
localDevice.setHostMode(QBluetoothLocalDevice::HostDiscoverable);
|
||||
|
||||
btservice::AndroidBluetoothServer androidBluetoothServer(configuration);
|
||||
uint16_t portNumber = androidBluetoothServer.start(address);
|
||||
|
||||
if (portNumber == 0) {
|
||||
OPENAUTO_LOG(error) << "[btservice] Server start failed.";
|
||||
return 2;
|
||||
try {
|
||||
btservice::BluetoothHandler bluetoothHandler(configuration);
|
||||
QCoreApplication::exec();
|
||||
} catch (std::runtime_error& e) {
|
||||
std::cerr << "Exception caught: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
OPENAUTO_LOG(info) << "[btservice] Listening for connections, address: " << address.toString().toStdString()
|
||||
<< ", port: " << portNumber;
|
||||
|
||||
btservice::AndroidBluetoothService androidBluetoothService(portNumber);
|
||||
if (!androidBluetoothService.registerService(address)) {
|
||||
OPENAUTO_LOG(error) << "[btservice] Service registration failed.";
|
||||
return 1;
|
||||
} else {
|
||||
OPENAUTO_LOG(info) << "[btservice] Service registered, port: " << portNumber;
|
||||
}
|
||||
|
||||
QCoreApplication::exec();
|
||||
|
||||
OPENAUTO_LOG(info) << "stop";
|
||||
androidBluetoothService.unregisterService();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user