Move remaining Bluetooth Signals to BtService to prevent overlaps.

This commit is contained in:
Simon Dean 2024-11-27 11:27:12 +00:00
parent 28caa06b09
commit 361e1467b7
15 changed files with 373 additions and 279 deletions

View File

@ -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_;

View File

@ -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_;

View File

@ -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);
};
}
}
}

View File

@ -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:
};
}
}
}

View 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

View File

@ -20,11 +20,9 @@
#include <QBluetoothAddress>
namespace f1x
{
namespace openauto
{
namespace btservice
namespace f1x::openauto::btservice
{
class IAndroidBluetoothServer
@ -36,5 +34,5 @@ public:
};
}
}
}

View File

@ -20,11 +20,7 @@
#include <QBluetoothAddress>
namespace f1x
{
namespace openauto
{
namespace btservice
namespace f1x::openauto::btservice
{
class IAndroidBluetoothService
@ -37,5 +33,5 @@ public:
};
}
}
}

View 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

View File

@ -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 "";
}

View File

@ -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();
}
}

View File

@ -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 {

View File

@ -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) {

View File

@ -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;
}
}
}
}

View 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 ...
}
}

View File

@ -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;
}