bluetooth handshake / wifi rework (#18)
* Working on cleaning wifi * Reworked bluetooth handshake based around @presslab-us's work * Forgot to remove a line
This commit is contained in:
parent
88833fb5db
commit
3d96b6e6e3
@ -12,44 +12,8 @@ AndroidBluetoothServer::AndroidBluetoothServer(openauto::configuration::IConfigu
|
||||
: rfcommServer_(std::make_unique<QBluetoothServer>(QBluetoothServiceInfo::RfcommProtocol, this))
|
||||
, socket_(nullptr)
|
||||
, config_(std::move(config))
|
||||
, handshakeState_(ConnectionStatus::IDLE)
|
||||
{
|
||||
connect(rfcommServer_.get(), &QBluetoothServer::newConnection, this, &AndroidBluetoothServer::onClientConnected);
|
||||
|
||||
auto* thread = QThread::create([&]{ this->eventLoop(); });
|
||||
thread->start();
|
||||
}
|
||||
|
||||
void AndroidBluetoothServer::eventLoop()
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
switch(handshakeState_)
|
||||
{
|
||||
case ConnectionStatus::IDLE:
|
||||
case ConnectionStatus::SENT_SOCKETINFO_MESSAGE:
|
||||
case ConnectionStatus::SENT_NETWORKINFO_MESSAGE:
|
||||
case ConnectionStatus::PHONE_RESP_NETWORKINFO:
|
||||
case ConnectionStatus::ERROR:
|
||||
break;
|
||||
|
||||
case ConnectionStatus::DEVICE_CONNECTED:
|
||||
handshakeState_ = ConnectionStatus::SENDING_SOCKETINFO_MESSAGE;
|
||||
break;
|
||||
|
||||
case ConnectionStatus::SENDING_SOCKETINFO_MESSAGE:
|
||||
this->writeSocketInfoMessage();
|
||||
break;
|
||||
|
||||
case ConnectionStatus::PHONE_RESP_SOCKETINFO:
|
||||
handshakeState_ = ConnectionStatus::SENDING_NETWORKINFO_MESSAGE;
|
||||
break;
|
||||
|
||||
case ConnectionStatus::SENDING_NETWORKINFO_MESSAGE:
|
||||
this->writeNetworkInfoMessage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool AndroidBluetoothServer::start(const QBluetoothAddress& address, uint16_t portNumber)
|
||||
@ -65,7 +29,7 @@ void AndroidBluetoothServer::onClientConnected()
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Device Connected: " << socket_->peerName().toStdString();
|
||||
connect(socket_, SIGNAL(readyRead()), this, SLOT(readSocket()));
|
||||
handshakeState_ = ConnectionStatus::DEVICE_CONNECTED;
|
||||
writeSocketInfoRequest();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -90,9 +54,9 @@ bool AndroidBluetoothServer::writeProtoMessage(uint16_t messageType, google::pro
|
||||
return true;
|
||||
}
|
||||
|
||||
void AndroidBluetoothServer::writeSocketInfoMessage()
|
||||
void AndroidBluetoothServer::writeSocketInfoRequest()
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Sending socket info.";
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Sending SocketInfoRequest.";
|
||||
|
||||
QString ipAddr;
|
||||
foreach(QHostAddress addr, QNetworkInterface::allAddresses())
|
||||
@ -103,115 +67,147 @@ void AndroidBluetoothServer::writeSocketInfoMessage()
|
||||
}
|
||||
}
|
||||
|
||||
btservice::proto::SocketInfo socketInfo;
|
||||
socketInfo.set_address(ipAddr.toStdString());
|
||||
socketInfo.set_port(5000);
|
||||
socketInfo.set_unknown_1(0);
|
||||
btservice::proto::SocketInfoRequest socketInfoRequest;
|
||||
socketInfoRequest.set_ip_address(ipAddr.toStdString());
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] ipAddress: "<< ipAddr.toStdString();
|
||||
|
||||
if(this->writeProtoMessage(7, socketInfo))
|
||||
socketInfoRequest.set_port(5000);
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] port: "<< 5000;
|
||||
|
||||
if(this->writeProtoMessage(1, socketInfoRequest))
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Sent socket info.";
|
||||
handshakeState_ = ConnectionStatus::SENT_SOCKETINFO_MESSAGE;
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Sent SocketInfoRequest.";
|
||||
}
|
||||
else
|
||||
{
|
||||
OPENAUTO_LOG(error) << "[AndroidBluetoothServer] Error sending socket Info.";
|
||||
handshakeState_ = ConnectionStatus::ERROR;
|
||||
OPENAUTO_LOG(error) << "[AndroidBluetoothServer] Error sending SocketInfoRequest.";
|
||||
}
|
||||
}
|
||||
void AndroidBluetoothServer::writeSocketInfoResponse()
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Sending SocketInfoResponse.";
|
||||
QString ipAddr;
|
||||
foreach(QHostAddress addr, QNetworkInterface::allAddresses())
|
||||
{
|
||||
if(!addr.isLoopback() && (addr.protocol() == QAbstractSocket::IPv4Protocol))
|
||||
{
|
||||
ipAddr = addr.toString();
|
||||
}
|
||||
}
|
||||
|
||||
btservice::proto::SocketInfoResponse socketInfoResponse;
|
||||
socketInfoResponse.set_ip_address(ipAddr.toStdString());
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] ipAddress: "<< ipAddr.toStdString();
|
||||
|
||||
socketInfoResponse.set_port(5000);
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] port: "<< 5000;
|
||||
|
||||
socketInfoResponse.set_status(btservice::proto::Status::STATUS_SUCCESS);
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] status: "<< btservice::proto::Status::STATUS_SUCCESS;
|
||||
|
||||
|
||||
if(this->writeProtoMessage(7, socketInfoResponse))
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Sent SocketInfoResponse.";
|
||||
}
|
||||
else
|
||||
{
|
||||
OPENAUTO_LOG(error) << "[AndroidBluetoothServer] Error sending SocketInfoResponse.";
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidBluetoothServer::handleSocketInfoRequestResponse(QByteArray data)
|
||||
{
|
||||
btservice::proto::SocketInfoResponse socketInfoResponse;
|
||||
socketInfoResponse.ParseFromArray(data, data.size());
|
||||
OPENAUTO_LOG(info) <<"[AndroidBluetoothServer] Received SocketInfoRequestResponse, status: "<<socketInfoResponse.status();
|
||||
}
|
||||
|
||||
|
||||
void AndroidBluetoothServer::handleSocketInfoRequest(QByteArray data)
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Reading SocketInfoRequest.";
|
||||
|
||||
btservice::proto::SocketInfoRequest socketInfoRequest;
|
||||
|
||||
writeSocketInfoResponse();
|
||||
}
|
||||
|
||||
void AndroidBluetoothServer::writeNetworkInfoMessage()
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Sending network packet.";
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Sending NetworkInfoMessage.";
|
||||
|
||||
btservice::proto::NetworkInfo networkMessage;
|
||||
networkMessage.set_ssid(config_->getWifiSSID());
|
||||
networkMessage.set_psk(config_->getWifiPassword());
|
||||
foreach(QNetworkInterface netInterface, QNetworkInterface::allInterfaces())
|
||||
{
|
||||
// Return only the first non-loopback MAC Address
|
||||
if (!(netInterface.flags() & QNetworkInterface::IsLoopBack))
|
||||
{
|
||||
networkMessage.set_mac_addr(netInterface.hardwareAddress().toStdString());
|
||||
}
|
||||
}
|
||||
networkMessage.set_security_mode(8);
|
||||
networkMessage.set_unknown_2(0);
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] SSID: "<<config_->getWifiSSID();
|
||||
|
||||
if(this->writeProtoMessage(3, networkMessage))
|
||||
networkMessage.set_psk(config_->getWifiPassword());
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] PSKEY: "<<config_->getWifiPassword();
|
||||
|
||||
if(config_->getWifiMAC().empty())
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Sent network packet.";
|
||||
handshakeState_ = ConnectionStatus::SENT_NETWORKINFO_MESSAGE;
|
||||
networkMessage.set_mac_addr(QNetworkInterface::interfaceFromName("wlan0").hardwareAddress().toStdString());
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] MAC: "<<QNetworkInterface::interfaceFromName("wlan0").hardwareAddress().toStdString();
|
||||
}
|
||||
else
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Error sending network packet.";
|
||||
handshakeState_ = ConnectionStatus::ERROR;
|
||||
networkMessage.set_mac_addr(config_->getWifiMAC());
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] MAC: "<< config_->getWifiMAC();
|
||||
}
|
||||
|
||||
networkMessage.set_security_mode(btservice::proto::SecurityMode::WPA2_PERSONAL);
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Security: "<< btservice::proto::SecurityMode::WPA2_PERSONAL;
|
||||
|
||||
networkMessage.set_ap_type(btservice::proto::AccessPointType::STATIC);
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] AP Type: "<< btservice::proto::AccessPointType::STATIC;
|
||||
|
||||
|
||||
if(this->writeProtoMessage(3, networkMessage))
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Sent NetworkInfoMessage";
|
||||
}
|
||||
else
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Error sending NetworkInfoMessage.";
|
||||
}
|
||||
}
|
||||
|
||||
void AndroidBluetoothServer::handleUnknownMessage(int messageType, QByteArray data)
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Received unknown MessageType of "<<messageType;
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Unknown Message Data: "<<data.toHex(' ').toStdString() ;
|
||||
}
|
||||
|
||||
void AndroidBluetoothServer::readSocket()
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] DATA: ";
|
||||
if(!socket_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto data = socket_->read(1024);
|
||||
auto data = socket_->readAll();
|
||||
if(data.length() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t messageType = (data[2] << 8) | data[3];
|
||||
btservice::proto::PhoneResponse resp;
|
||||
switch(messageType)
|
||||
{
|
||||
case 2:
|
||||
break;
|
||||
|
||||
case 6:
|
||||
resp.ParseFromString(data.toStdString().c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
switch(handshakeState_)
|
||||
{
|
||||
case ConnectionStatus::IDLE:
|
||||
case ConnectionStatus::DEVICE_CONNECTED:
|
||||
case ConnectionStatus::SENDING_SOCKETINFO_MESSAGE:
|
||||
case ConnectionStatus::PHONE_RESP_SOCKETINFO:
|
||||
case ConnectionStatus::SENDING_NETWORKINFO_MESSAGE:
|
||||
case ConnectionStatus::PHONE_RESP_NETWORKINFO:
|
||||
case ConnectionStatus::ERROR:
|
||||
break;
|
||||
|
||||
case ConnectionStatus::SENT_SOCKETINFO_MESSAGE:
|
||||
if(messageType == 2)
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Phone acknowledged socket info.";
|
||||
handshakeState_ = ConnectionStatus::PHONE_RESP_SOCKETINFO;
|
||||
}
|
||||
else
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Got unexpected message.";
|
||||
handshakeState_ = ConnectionStatus::ERROR;
|
||||
}
|
||||
break;
|
||||
|
||||
case ConnectionStatus::SENT_NETWORKINFO_MESSAGE:
|
||||
if(messageType == 6)
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Phone acknowledged network info with status code: " << resp.status_code();
|
||||
handshakeState_ = ConnectionStatus::PHONE_RESP_NETWORKINFO;
|
||||
}
|
||||
else
|
||||
{
|
||||
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Got unexpected message";
|
||||
handshakeState_ = ConnectionStatus::ERROR;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
handleSocketInfoRequest(data);
|
||||
break;
|
||||
case 2:
|
||||
writeNetworkInfoMessage();
|
||||
break;
|
||||
case 7:
|
||||
data.remove(0, 4);
|
||||
handleSocketInfoRequestResponse(data);
|
||||
break;
|
||||
default:
|
||||
data.remove(0, 4);
|
||||
handleUnknownMessage(messageType, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,29 @@ syntax = "proto2";
|
||||
|
||||
package openauto.btservice.proto;
|
||||
|
||||
enum SecurityMode {
|
||||
UNKNOWN_SECURITY_MODE = 0;
|
||||
OPEN = 1;
|
||||
WEP_64 = 2;
|
||||
WEP_128 = 3;
|
||||
WPA_PERSONAL = 4;
|
||||
WPA2_PERSONAL = 8;
|
||||
WPA_WPA2_PERSONAL = 12;
|
||||
WPA_ENTERPRISE = 20;
|
||||
WPA2_ENTERPRISE = 24;
|
||||
WPA_WPA2_ENTERPRISE = 28;
|
||||
}
|
||||
|
||||
enum AccessPointType {
|
||||
STATIC = 0;
|
||||
DYNAMIC = 1;
|
||||
}
|
||||
|
||||
message NetworkInfo
|
||||
{
|
||||
required string ssid = 1;
|
||||
required string psk = 2;
|
||||
required string mac_addr = 3;
|
||||
required int32 security_mode = 4;
|
||||
required int32 unknown_2 = 5;
|
||||
required SecurityMode security_mode = 4;
|
||||
required AccessPointType ap_type = 5;
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package openauto.btservice.proto;
|
||||
|
||||
message PhoneResponse
|
||||
{
|
||||
int32 status_code = 1;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
syntax = "proto2";
|
||||
|
||||
package openauto.btservice.proto;
|
||||
|
||||
message SocketInfo
|
||||
{
|
||||
required string address = 1;
|
||||
required int32 port = 2;
|
||||
required int32 unknown_1 = 3;
|
||||
}
|
9
btservice_proto/SocketInfoRequest.proto
Normal file
9
btservice_proto/SocketInfoRequest.proto
Normal file
@ -0,0 +1,9 @@
|
||||
syntax = "proto2";
|
||||
|
||||
package openauto.btservice.proto;
|
||||
|
||||
message SocketInfoRequest
|
||||
{
|
||||
required string ip_address = 1;
|
||||
optional uint32 port = 2;
|
||||
}
|
25
btservice_proto/SocketInfoResponse.proto
Normal file
25
btservice_proto/SocketInfoResponse.proto
Normal file
@ -0,0 +1,25 @@
|
||||
syntax = "proto2";
|
||||
|
||||
package openauto.btservice.proto;
|
||||
|
||||
enum Status {
|
||||
STATUS_UNSOLICITED_MESSAGE = 1;
|
||||
STATUS_SUCCESS = 0;
|
||||
STATUS_NO_COMPATIBLE_VERSION = -1;
|
||||
STATUS_WIFI_INACCESSIBLE_CHANNEL = -2;
|
||||
STATUS_WIFI_INCORRECT_CREDENTIALS = -3;
|
||||
STATUS_PROJECTION_ALREADY_STARTED = -4;
|
||||
STATUS_WIFI_DISABLED = -5;
|
||||
STATUS_WIFI_NOT_YET_STARTED = -6;
|
||||
STATUS_INVALID_HOST = -7;
|
||||
STATUS_NO_SUPPORTED_WIFI_CHANNELS = -8;
|
||||
STATUS_INSTRUCT_USER_TO_CHECK_THE_PHONE = -9;
|
||||
STATUS_PHONE_WIFI_DISABLED = -10;
|
||||
}
|
||||
|
||||
message SocketInfoResponse
|
||||
{
|
||||
optional string ip_address = 1;
|
||||
optional int32 port = 2;
|
||||
required Status status = 3;
|
||||
}
|
@ -8,8 +8,8 @@
|
||||
#include <QBluetoothLocalDevice>
|
||||
#include <QDataStream>
|
||||
#include <btservice_proto/NetworkInfo.pb.h>
|
||||
#include <btservice_proto/PhoneResponse.pb.h>
|
||||
#include <btservice_proto/SocketInfo.pb.h>
|
||||
#include <btservice_proto/SocketInfoRequest.pb.h>
|
||||
#include <btservice_proto/SocketInfoResponse.pb.h>
|
||||
#include "openauto/Configuration/Configuration.hpp"
|
||||
#include "IAndroidBluetoothServer.hpp"
|
||||
|
||||
@ -18,19 +18,6 @@ namespace openauto
|
||||
namespace btservice
|
||||
{
|
||||
|
||||
enum class ConnectionStatus
|
||||
{
|
||||
IDLE,
|
||||
DEVICE_CONNECTED,
|
||||
SENDING_SOCKETINFO_MESSAGE,
|
||||
SENT_SOCKETINFO_MESSAGE,
|
||||
PHONE_RESP_SOCKETINFO,
|
||||
SENDING_NETWORKINFO_MESSAGE,
|
||||
SENT_NETWORKINFO_MESSAGE,
|
||||
PHONE_RESP_NETWORKINFO,
|
||||
ERROR
|
||||
};
|
||||
|
||||
class AndroidBluetoothServer: public QObject, public IAndroidBluetoothServer
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -47,11 +34,13 @@ private:
|
||||
std::unique_ptr<QBluetoothServer> rfcommServer_;
|
||||
QBluetoothSocket* socket_;
|
||||
openauto::configuration::IConfiguration::Pointer config_;
|
||||
std::atomic<ConnectionStatus> handshakeState_;
|
||||
|
||||
void writeSocketInfoMessage();
|
||||
void handleUnknownMessage(int messageType, QByteArray data);
|
||||
void handleSocketInfoRequest(QByteArray data);
|
||||
void handleSocketInfoRequestResponse(QByteArray data);
|
||||
void writeSocketInfoRequest();
|
||||
void writeSocketInfoResponse();
|
||||
void writeNetworkInfoMessage();
|
||||
void eventLoop();
|
||||
bool writeProtoMessage(uint16_t messageType, google::protobuf::Message& message);
|
||||
|
||||
};
|
||||
|
@ -72,6 +72,8 @@ public:
|
||||
void setWifiSSID(std::string value) override;
|
||||
std::string getWifiPassword() override;
|
||||
void setWifiPassword(std::string value) override;
|
||||
std::string getWifiMAC() override;
|
||||
void setWifiMAC(std::string value) override;
|
||||
|
||||
private:
|
||||
void readButtonCodes(boost::property_tree::ptree& iniConfig);
|
||||
@ -94,6 +96,7 @@ private:
|
||||
AudioOutputBackendType audioOutputBackendType_;
|
||||
std::string wifiSSID_;
|
||||
std::string wifiPassword_;
|
||||
std::string wifiMAC_;
|
||||
|
||||
static const std::string cConfigFileName;
|
||||
|
||||
@ -134,6 +137,7 @@ private:
|
||||
|
||||
static const std::string cWifiSSID;
|
||||
static const std::string cWifiPskey;
|
||||
static const std::string cWifiMAC;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -81,6 +81,8 @@ public:
|
||||
virtual void setWifiSSID(std::string value) = 0;
|
||||
virtual std::string getWifiPassword() = 0;
|
||||
virtual void setWifiPassword(std::string value) = 0;
|
||||
virtual std::string getWifiMAC() = 0;
|
||||
virtual void setWifiMAC(std::string value) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ const std::string Configuration::cInputEnterButtonKey = "Input.EnterButton";
|
||||
|
||||
const std::string Configuration::cWifiSSID = "WiFi.SSID";
|
||||
const std::string Configuration::cWifiPskey = "WiFi.Password";
|
||||
const std::string Configuration::cWifiMAC = "WiFi.AdapterMAC";
|
||||
|
||||
Configuration::Configuration()
|
||||
{
|
||||
@ -105,6 +106,7 @@ void Configuration::load()
|
||||
|
||||
wifiSSID_ = iniConfig.get<std::string>(cWifiSSID, "");
|
||||
wifiPassword_ = iniConfig.get<std::string>(cWifiPskey, "");
|
||||
wifiMAC_ = iniConfig.get<std::string>(cWifiMAC, "");
|
||||
}
|
||||
catch(const boost::property_tree::ini_parser_error& e)
|
||||
{
|
||||
@ -158,6 +160,7 @@ void Configuration::save()
|
||||
|
||||
iniConfig.put<std::string>(cWifiSSID, wifiSSID_);
|
||||
iniConfig.put<std::string>(cWifiPskey, wifiPassword_);
|
||||
iniConfig.put<std::string>(cWifiMAC, wifiMAC_);
|
||||
boost::property_tree::ini_parser::write_ini(cConfigFileName, iniConfig);
|
||||
}
|
||||
|
||||
@ -321,6 +324,16 @@ void Configuration::setWifiPassword(std::string value)
|
||||
wifiPassword_ = value;
|
||||
}
|
||||
|
||||
std::string Configuration::getWifiMAC()
|
||||
{
|
||||
return wifiMAC_;
|
||||
}
|
||||
|
||||
void Configuration::setWifiMAC(std::string value)
|
||||
{
|
||||
wifiMAC_ = value;
|
||||
}
|
||||
|
||||
void Configuration::readButtonCodes(boost::property_tree::ptree& iniConfig)
|
||||
{
|
||||
this->insertButtonCode(iniConfig, cInputPlayButtonKey, aasdk::proto::enums::ButtonCode::PLAY);
|
||||
|
Loading…
x
Reference in New Issue
Block a user