automatic wireless device connection (#12)

* fix for omx when performing GST build

* wireless android auto bluetooth negotation

* Grab local bluetooth adapter

* Handling ping and voice session

* wait for both usb and wifi device ]connections

* Make btservice launch with openauto, allows for wireless connection automatically

* WiFi hotspot info pulled from openauto config

* Install btservice correctly

Co-authored-by: Rhys_M <rhys1802@hotmail.co.uk>
Co-authored-by: Robert Judka <robertjudka@gmail.com>
This commit is contained in:
Cole Brinsfield 2020-08-26 17:48:36 -07:00 committed by GitHub
parent 88f71b813a
commit 50e077aa6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 402 additions and 120 deletions

View File

@ -69,6 +69,11 @@ if(GST_BUILD)
message(STATUS "${GST_LIBRARIES}") message(STATUS "${GST_LIBRARIES}")
endif(GST_BUILD) endif(GST_BUILD)
add_subdirectory(btservice_proto)
set(BTSERVICE_PROTO_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR})
include_directories(${BTSERVICE_PROTO_INCLUDE_DIRS})
add_subdirectory(openauto) add_subdirectory(openauto)
add_subdirectory(btservice)
add_subdirectory(autoapp) add_subdirectory(autoapp)
add_dependencies(autoapp btservice_proto)

View File

@ -123,7 +123,7 @@ int main(int argc, char* argv[])
app->start(std::move(socket)); app->start(std::move(socket));
}); });
app->waitForUSBDevice(); app->waitForDevice(true);
auto result = qApplication.exec(); auto result = qApplication.exec();
std::for_each(threadPool.begin(), threadPool.end(), std::bind(&std::thread::join, std::placeholders::_1)); std::for_each(threadPool.begin(), threadPool.end(), std::bind(&std::thread::join, std::placeholders::_1));

View File

@ -1,47 +1,74 @@
/*
* This file is part of openauto project.
* Copyright (C) 2018 f1x.studio (Michal Szwaj)
*
* openauto is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
* openauto is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with openauto. If not, see <http://www.gnu.org/licenses/>.
*/
#include "OpenautoLog.hpp" #include "OpenautoLog.hpp"
#include "btservice/AndroidBluetoothServer.hpp" #include "btservice/AndroidBluetoothServer.hpp"
#include <QNetworkInterface>
#include <QThread>
namespace openauto namespace openauto
{ {
namespace btservice namespace btservice
{ {
AndroidBluetoothServer::AndroidBluetoothServer() AndroidBluetoothServer::AndroidBluetoothServer(openauto::configuration::IConfiguration::Pointer config_)
: rfcommServer_(std::make_unique<QBluetoothServer>(QBluetoothServiceInfo::RfcommProtocol, this)) : rfcommServer_(std::make_unique<QBluetoothServer>(QBluetoothServiceInfo::RfcommProtocol, this))
, config(std::move(config_))
{ {
handshakeState = IDLE;
connect(rfcommServer_.get(), &QBluetoothServer::newConnection, this, &AndroidBluetoothServer::onClientConnected); connect(rfcommServer_.get(), &QBluetoothServer::newConnection, this, &AndroidBluetoothServer::onClientConnected);
QThread *thread = QThread::create([&]{ this->stateMachine(); });
thread->start();
}
void AndroidBluetoothServer::stateMachine()
{
while(true){
switch(handshakeState){
case IDLE:
break;
case DEVICE_CONNECTED:
handshakeState = SENDING_SOCKETINFO_MESSAGE;
break;
case SENDING_SOCKETINFO_MESSAGE:
writeSocketInfoMessage();
break;
case SENT_SOCKETINFO_MESSAGE:
break;
case PHONE_RESP_SOCKETINFO:
handshakeState = SENDING_NETWORKINFO_MESSAGE;
break;
case SENDING_NETWORKINFO_MESSAGE:
writeNetworkInfoMessage();
break;
case SENT_NETWORKINFO_MESSAGE:
break;
case PHONE_RESP_NETWORKINFO:
break;
}
}
} }
bool AndroidBluetoothServer::start(const QBluetoothAddress& address, uint16_t portNumber) bool AndroidBluetoothServer::start(const QBluetoothAddress& address, uint16_t portNumber)
{ {
OPENAUTO_LOG(info)<<"listening";
return rfcommServer_->listen(address, portNumber); return rfcommServer_->listen(address, portNumber);
} }
void AndroidBluetoothServer::onClientConnected() void AndroidBluetoothServer::onClientConnected()
{ {
auto socket = rfcommServer_->nextPendingConnection(); socket = rfcommServer_->nextPendingConnection();
if(socket != nullptr) if(socket != nullptr)
{ {
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] rfcomm client connected, peer name: " << socket->peerName().toStdString(); OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Device Connected: " << socket->peerName().toStdString();
connect(socket, SIGNAL(readyRead()), this, SLOT(readSocket()));
handshakeState = DEVICE_CONNECTED;
} }
else else
{ {
@ -49,5 +76,139 @@ void AndroidBluetoothServer::onClientConnected()
} }
} }
bool AndroidBluetoothServer::writeProtoMessage(uint16_t messageType, google::protobuf::Message &message){
QByteArray byteArray(message.SerializeAsString().c_str(), message.ByteSize());
uint16_t message_length = message.ByteSize();
char byte1 = messageType & 0x000000ff;
char byte2 = (messageType & 0x0000ff00) >> 8;
byteArray.prepend(byte1);
byteArray.prepend(byte2);
byte1 = message_length & 0x000000ff;
byte2 = (message_length & 0x0000ff00) >> 8;
byteArray.prepend(byte1);
byteArray.prepend(byte2);
int sentBytes = socket->write(byteArray);
if(sentBytes != byteArray.length()) return false;
return true;
} }
void AndroidBluetoothServer::writeSocketInfoMessage(){
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Sending Socket Info";
btservice::proto::SocketInfo socketInfo;
QString ipAddr;
QList<QHostAddress> list = QNetworkInterface::allAddresses();
for(int nIter=0; nIter<list.count(); nIter++)
{
if(!list[nIter].isLoopback())
if (list[nIter].protocol() == QAbstractSocket::IPv4Protocol )
ipAddr = list[nIter].toString();
}
socketInfo.set_address(ipAddr.toStdString());
socketInfo.set_port(5000);
socketInfo.set_unknown_1(0);
if(writeProtoMessage(7, socketInfo)){
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Sent Socket Info";
handshakeState = SENT_SOCKETINFO_MESSAGE;
}
else{
OPENAUTO_LOG(error) << "[AndroidBluetoothServer] Error Sending Socket Info";
handshakeState = ERROR;
}
} }
void AndroidBluetoothServer::writeNetworkInfoMessage(){
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Sending Network Packet";
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);
if(writeProtoMessage(3, networkMessage)){
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Sent Network Packet";
handshakeState = SENT_NETWORKINFO_MESSAGE;
}
else{
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Error sending Network Packet";
handshakeState = ERROR;
}
}
void AndroidBluetoothServer::readSocket(){
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] DATA: ";
if (!socket)
return;
QByteArray data = socket->read(1024);
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 IDLE:
break;
case DEVICE_CONNECTED:
break;
case SENDING_SOCKETINFO_MESSAGE:
break;
case SENT_SOCKETINFO_MESSAGE:
if(messageType == 2){
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Phone acknowledged Socket Info";
handshakeState = PHONE_RESP_SOCKETINFO;
}else{
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Got unexpected message";
handshakeState = ERROR;
}
break;
case PHONE_RESP_SOCKETINFO:
break;
case SENDING_NETWORKINFO_MESSAGE:
break;
case SENT_NETWORKINFO_MESSAGE:
if(messageType == 6){
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Phone acknowledged Network Info with status code: "<<resp.status_code();
handshakeState = PHONE_RESP_NETWORKINFO;
}else{
OPENAUTO_LOG(info) << "[AndroidBluetoothServer] Got unexpected message";
handshakeState = ERROR;
}
break;
case PHONE_RESP_NETWORKINFO:
break;
}
}
}
}

View File

@ -36,7 +36,7 @@ AndroidBluetoothService::AndroidBluetoothService(uint16_t portNumber)
serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId); serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceName, "OpenAuto Bluetooth Service"); serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceName, "OpenAuto Bluetooth Service");
serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceDescription, "AndroidAuto WiFi projection automatic setup"); serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceDescription, "AndroidAuto WiFi projection automatic setup");
serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceProvider, "f1xstudio.com"); serviceInfo_.setAttribute(QBluetoothServiceInfo::ServiceProvider, "openDsh");
serviceInfo_.setServiceUuid(serviceUuid); serviceInfo_.setServiceUuid(serviceUuid);
QBluetoothServiceInfo::Sequence publicBrowse; QBluetoothServiceInfo::Sequence publicBrowse;
@ -49,7 +49,7 @@ AndroidBluetoothService::AndroidBluetoothService(uint16_t portNumber)
protocolDescriptorList.append(QVariant::fromValue(protocol)); protocolDescriptorList.append(QVariant::fromValue(protocol));
protocol.clear(); protocol.clear();
protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm)) protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm))
<< QVariant::fromValue(quint16(portNumber)); << QVariant::fromValue(quint8(portNumber));
protocolDescriptorList.append(QVariant::fromValue(protocol)); protocolDescriptorList.append(QVariant::fromValue(protocol));
serviceInfo_.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList, protocolDescriptorList); serviceInfo_.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList, protocolDescriptorList);
} }

View File

@ -1,25 +0,0 @@
add_executable(btservice
AndroidBluetoothServer.cpp
AndroidBluetoothService.cpp
btservice.cpp
${CMAKE_SOURCE_DIR}/include/btservice/AndroidBluetoothServer.hpp
${CMAKE_SOURCE_DIR}/include/btservice/AndroidBluetoothService.hpp
${CMAKE_SOURCE_DIR}/include/btservice/IAndroidBluetoothServer.hpp
${CMAKE_SOURCE_DIR}/include/btservice/IAndroidBluetoothService.hpp
)
target_include_directories(btservice PRIVATE
${CMAKE_SOURCE_DIR}/include
)
target_link_libraries(btservice
Threads::Threads
${Boost_LIBRARIES}
openauto
)
set_target_properties(btservice
PROPERTIES INSTALL_RPATH_USE_LINK_PATH 1)
install(TARGETS btservice
RUNTIME DESTINATION bin)

View File

@ -1,58 +1,36 @@
/* #include "btservice/btservice.hpp"
* This file is part of openauto project. namespace openauto{
* Copyright (C) 2018 f1x.studio (Michal Szwaj) namespace btservice{
* btservice::btservice(openauto::configuration::IConfiguration::Pointer config) : androidBluetoothService(servicePortNumber), androidBluetoothServer(config){
* openauto is free software: you can redistribute it and/or modify QBluetoothAddress address;
* it under the terms of the GNU General Public License as published by auto adapters = QBluetoothLocalDevice::allDevices();
* the Free Software Foundation; either version 3 of the License, or if (adapters.size() > 0)
* (at your option) any later version. address =adapters.at(0).address();
else{
OPENAUTO_LOG(error) << "[btservice] No adapter found";
}
* openauto is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with openauto. If not, see <http://www.gnu.org/licenses/>.
*/
#include <QApplication>
#include "OpenautoLog.hpp"
#include "btservice/AndroidBluetoothService.hpp"
#include "btservice/AndroidBluetoothServer.hpp"
namespace btservice = openauto::btservice; if(!androidBluetoothServer.start(address, servicePortNumber))
int main(int argc, char* argv[])
{
QApplication qApplication(argc, argv);
const QBluetoothAddress address;
const uint16_t portNumber = 5000;
btservice::AndroidBluetoothServer androidBluetoothServer;
if(!androidBluetoothServer.start(address, portNumber))
{ {
OPENAUTO_LOG(error) << "[btservice] Server start failed."; OPENAUTO_LOG(error) << "[btservice] Server start failed.";
return 2; return;
} }
OPENAUTO_LOG(info) << "[btservice] Listening for connections, address: " << address.toString().toStdString() OPENAUTO_LOG(info) << "[btservice] Listening for connections, address: " << address.toString().toStdString()
<< ", port: " << portNumber; << ", port: " << servicePortNumber;
btservice::AndroidBluetoothService androidBluetoothService(portNumber);
if(!androidBluetoothService.registerService(address)) if(!androidBluetoothService.registerService(address))
{ {
OPENAUTO_LOG(error) << "[btservice] Service registration failed."; OPENAUTO_LOG(error) << "[btservice] Service registration failed.";
return 1;
} }
else else
{ {
OPENAUTO_LOG(info) << "[btservice] Service registered, port: " << portNumber; OPENAUTO_LOG(info) << "[btservice] Service registered, port: " << servicePortNumber;
} }
qApplication.exec();
androidBluetoothService.unregisterService();
return 0;
} }
}
}

View File

@ -0,0 +1,13 @@
include(FindProtobuf)
find_package(Protobuf REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIR})
file(GLOB_RECURSE proto_files ${CMAKE_CURRENT_SOURCE_DIR}/*.proto)
protobuf_generate_cpp(proto_sources proto_headers ${proto_files})
add_library(btservice_proto SHARED ${proto_headers} ${proto_sources})
target_link_libraries(btservice_proto ${PROTOBUF_LIBRARIES})
install(TARGETS btservice_proto DESTINATION lib)
install(DIRECTORY . DESTINATION include/btservice_proto
FILES_MATCHING PATTERN *.h
PATTERN CMakeFiles EXCLUDE )

View File

@ -0,0 +1,11 @@
syntax = "proto2";
package openauto.btservice.proto;
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;
}

View File

@ -0,0 +1,7 @@
syntax = "proto3";
package openauto.btservice.proto;
message PhoneResponse{
int32 status_code = 1;
}

View File

@ -0,0 +1,9 @@
syntax = "proto2";
package openauto.btservice.proto;
message SocketInfo{
required string address = 1;
required int32 port = 2;
required int32 unknown_1 = 3;
}

View File

@ -1,26 +1,15 @@
/*
* This file is part of openauto project.
* Copyright (C) 2018 f1x.studio (Michal Szwaj)
*
* openauto is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
* openauto is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with openauto. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <memory> #include <memory>
#include <sstream>
#include <QBluetoothServer> #include <QBluetoothServer>
#include <QBluetoothLocalDevice>
#include <QDataStream>
#include <btservice_proto/NetworkInfo.pb.h>
#include <btservice_proto/PhoneResponse.pb.h>
#include <btservice_proto/SocketInfo.pb.h>
#include "openauto/Configuration/Configuration.hpp"
#include "IAndroidBluetoothServer.hpp" #include "IAndroidBluetoothServer.hpp"
namespace openauto namespace openauto
@ -33,15 +22,38 @@ class AndroidBluetoothServer: public QObject, public IAndroidBluetoothServer
Q_OBJECT Q_OBJECT
public: public:
AndroidBluetoothServer(); AndroidBluetoothServer(openauto::configuration::IConfiguration::Pointer config_);
bool start(const QBluetoothAddress& address, uint16_t portNumber) override; bool start(const QBluetoothAddress& address, uint16_t portNumber) override;
private slots: private slots:
void onClientConnected(); void onClientConnected();
void readSocket();
private: private:
std::unique_ptr<QBluetoothServer> rfcommServer_; std::unique_ptr<QBluetoothServer> rfcommServer_;
QBluetoothSocket* socket;
void writeSocketInfoMessage();
void writeNetworkInfoMessage();
void stateMachine();
bool writeProtoMessage(uint16_t messageType, google::protobuf::Message &message);
enum CONNECTION_STATUS {
IDLE,
DEVICE_CONNECTED,
SENDING_SOCKETINFO_MESSAGE,
SENT_SOCKETINFO_MESSAGE,
PHONE_RESP_SOCKETINFO,
SENDING_NETWORKINFO_MESSAGE,
SENT_NETWORKINFO_MESSAGE,
PHONE_RESP_NETWORKINFO,
ERROR
};
CONNECTION_STATUS handshakeState = IDLE;
protected:
openauto::configuration::IConfiguration::Pointer config;
}; };
} }

View File

@ -0,0 +1,23 @@
#pragma once
#include <QBluetoothAddress>
#include "OpenautoLog.hpp"
#include "btservice/AndroidBluetoothService.hpp"
#include "btservice/AndroidBluetoothServer.hpp"
#include "openauto/Configuration/Configuration.hpp"
namespace openauto{
namespace btservice{
class btservice{
public:
btservice(openauto::configuration::IConfiguration::Pointer config);
private:
const uint16_t servicePortNumber = 22;
openauto::btservice::AndroidBluetoothServer androidBluetoothServer;
openauto::btservice::AndroidBluetoothService androidBluetoothService;
};
}
}

View File

@ -37,7 +37,7 @@ public:
App(boost::asio::io_service& ioService, aasdk::usb::USBWrapper& usbWrapper, aasdk::tcp::ITCPWrapper& tcpWrapper, openauto::service::IAndroidAutoEntityFactory& androidAutoEntityFactory, App(boost::asio::io_service& ioService, aasdk::usb::USBWrapper& usbWrapper, aasdk::tcp::ITCPWrapper& tcpWrapper, openauto::service::IAndroidAutoEntityFactory& androidAutoEntityFactory,
aasdk::usb::IUSBHub::Pointer usbHub, aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator); aasdk::usb::IUSBHub::Pointer usbHub, aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator);
void waitForUSBDevice(); void waitForDevice(bool enumerate = false);
void start(aasdk::tcp::ITCPEndpoint::SocketPointer socket); void start(aasdk::tcp::ITCPEndpoint::SocketPointer socket);
void stop(); void stop();
void onAndroidAutoQuit() override; void onAndroidAutoQuit() override;
@ -45,7 +45,8 @@ public:
private: private:
using std::enable_shared_from_this<App>::shared_from_this; using std::enable_shared_from_this<App>::shared_from_this;
void enumerateDevices(); void enumerateDevices();
void waitForDevice(); void waitForUSBDevice();
void waitForWirelessDevice();
void aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle); void aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle);
void onUSBHubError(const aasdk::error::Error& error); void onUSBHubError(const aasdk::error::Error& error);
@ -55,6 +56,7 @@ private:
boost::asio::io_service::strand strand_; boost::asio::io_service::strand strand_;
openauto::service::IAndroidAutoEntityFactory& androidAutoEntityFactory_; openauto::service::IAndroidAutoEntityFactory& androidAutoEntityFactory_;
aasdk::usb::IUSBHub::Pointer usbHub_; aasdk::usb::IUSBHub::Pointer usbHub_;
boost::asio::ip::tcp::acceptor acceptor_;
aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator_; aasdk::usb::IConnectedAccessoriesEnumerator::Pointer connectedAccessoriesEnumerator_;
openauto::service::IAndroidAutoEntity::Pointer androidAutoEntity_; openauto::service::IAndroidAutoEntity::Pointer androidAutoEntity_;
bool isStopped_; bool isStopped_;

View File

@ -68,6 +68,10 @@ public:
AudioOutputBackendType getAudioOutputBackendType() const override; AudioOutputBackendType getAudioOutputBackendType() const override;
void setAudioOutputBackendType(AudioOutputBackendType value) override; void setAudioOutputBackendType(AudioOutputBackendType value) override;
std::string getWifiSSID() override;
std::string getWifiPassword() override;
private: private:
void readButtonCodes(boost::property_tree::ptree& iniConfig); void readButtonCodes(boost::property_tree::ptree& iniConfig);
void insertButtonCode(boost::property_tree::ptree& iniConfig, const std::string& buttonCodeKey, aasdk::proto::enums::ButtonCode::Enum buttonCode); void insertButtonCode(boost::property_tree::ptree& iniConfig, const std::string& buttonCodeKey, aasdk::proto::enums::ButtonCode::Enum buttonCode);
@ -87,6 +91,8 @@ private:
bool musicAudioChannelEnabled_; bool musicAudioChannelEnabled_;
bool speechAudiochannelEnabled_; bool speechAudiochannelEnabled_;
AudioOutputBackendType audioOutputBackendType_; AudioOutputBackendType audioOutputBackendType_;
std::string ssid;
std::string pskey;
static const std::string cConfigFileName; static const std::string cConfigFileName;
@ -124,6 +130,9 @@ private:
static const std::string cInputScrollWheelButtonKey; static const std::string cInputScrollWheelButtonKey;
static const std::string cInputBackButtonKey; static const std::string cInputBackButtonKey;
static const std::string cInputEnterButtonKey; static const std::string cInputEnterButtonKey;
static const std::string cWifiSSID;
static const std::string cWifiPskey;
}; };
} }

View File

@ -44,6 +44,9 @@ public:
virtual void reset() = 0; virtual void reset() = 0;
virtual void save() = 0; virtual void save() = 0;
virtual std::string getWifiSSID() = 0;
virtual std::string getWifiPassword() = 0;
virtual void setHandednessOfTrafficType(HandednessOfTrafficType value) = 0; virtual void setHandednessOfTrafficType(HandednessOfTrafficType value) = 0;
virtual HandednessOfTrafficType getHandednessOfTrafficType() const = 0; virtual HandednessOfTrafficType getHandednessOfTrafficType() const = 0;
virtual void showClock(bool value) = 0; virtual void showClock(bool value) = 0;

View File

@ -54,8 +54,10 @@ public:
void onShutdownRequest(const aasdk::proto::messages::ShutdownRequest& request) override; void onShutdownRequest(const aasdk::proto::messages::ShutdownRequest& request) override;
void onShutdownResponse(const aasdk::proto::messages::ShutdownResponse& response) override; void onShutdownResponse(const aasdk::proto::messages::ShutdownResponse& response) override;
void onNavigationFocusRequest(const aasdk::proto::messages::NavigationFocusRequest& request) override; void onNavigationFocusRequest(const aasdk::proto::messages::NavigationFocusRequest& request) override;
void onPingRequest(const aasdk::proto::messages::PingRequest& request) override;
void onPingResponse(const aasdk::proto::messages::PingResponse& response) override; void onPingResponse(const aasdk::proto::messages::PingResponse& response) override;
void onChannelError(const aasdk::error::Error& e) override; void onChannelError(const aasdk::error::Error& e) override;
void onVoiceSessionRequest(const aasdk::proto::messages::VoiceSessionRequest& request) override;
private: private:
using std::enable_shared_from_this<AndroidAutoEntity>::shared_from_this; using std::enable_shared_from_this<AndroidAutoEntity>::shared_from_this;

View File

@ -25,6 +25,7 @@
#include "openauto/Projection/GSTVideoOutput.hpp" #include "openauto/Projection/GSTVideoOutput.hpp"
#include "openauto/Projection/QtVideoOutput.hpp" #include "openauto/Projection/QtVideoOutput.hpp"
#include "openauto/Service/SensorService.hpp" #include "openauto/Service/SensorService.hpp"
#include "btservice/btservice.hpp"
namespace openauto namespace openauto
{ {
@ -64,6 +65,7 @@ private:
#else #else
projection::QtVideoOutput *qtVideoOutput_; projection::QtVideoOutput *qtVideoOutput_;
#endif #endif
btservice::btservice btservice_;
bool nightMode_; bool nightMode_;
std::weak_ptr<SensorService> sensorService_; std::weak_ptr<SensorService> sensorService_;
}; };

View File

@ -33,22 +33,30 @@ App::App(boost::asio::io_service& ioService, aasdk::usb::USBWrapper& usbWrapper,
, strand_(ioService_) , strand_(ioService_)
, androidAutoEntityFactory_(androidAutoEntityFactory) , androidAutoEntityFactory_(androidAutoEntityFactory)
, usbHub_(std::move(usbHub)) , usbHub_(std::move(usbHub))
, acceptor_(ioService_, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 5000))
, connectedAccessoriesEnumerator_(std::move(connectedAccessoriesEnumerator)) , connectedAccessoriesEnumerator_(std::move(connectedAccessoriesEnumerator))
, isStopped_(false) , isStopped_(false)
{ {
} }
void App::waitForUSBDevice() void App::waitForDevice(bool enumerate)
{ {
strand_.dispatch([this, self = this->shared_from_this()]() { this->waitForUSBDevice();
this->waitForDevice(); this->waitForWirelessDevice();
this->enumerateDevices();
}); if(enumerate)
{
strand_.dispatch([this, self = this->shared_from_this()]() {
this->enumerateDevices();
});
}
} }
void App::start(aasdk::tcp::ITCPEndpoint::SocketPointer socket) void App::start(aasdk::tcp::ITCPEndpoint::SocketPointer socket)
{ {
OPENAUTO_LOG(info) << "[App] Wireless Device connected.";
strand_.dispatch([this, self = this->shared_from_this(), socket = std::move(socket)]() mutable { strand_.dispatch([this, self = this->shared_from_this(), socket = std::move(socket)]() mutable {
if(androidAutoEntity_ != nullptr) if(androidAutoEntity_ != nullptr)
{ {
@ -93,7 +101,7 @@ void App::stop()
void App::aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle) void App::aoapDeviceHandler(aasdk::usb::DeviceHandle deviceHandle)
{ {
OPENAUTO_LOG(info) << "[App] Device connected."; OPENAUTO_LOG(info) << "[App] USB Device connected.";
if(androidAutoEntity_ != nullptr) if(androidAutoEntity_ != nullptr)
{ {
@ -131,9 +139,9 @@ void App::enumerateDevices()
connectedAccessoriesEnumerator_->enumerate(std::move(promise)); connectedAccessoriesEnumerator_->enumerate(std::move(promise));
} }
void App::waitForDevice() void App::waitForUSBDevice()
{ {
OPENAUTO_LOG(info) << "[App] Waiting for device..."; OPENAUTO_LOG(info) << "[App] Waiting for USB device...";
auto promise = aasdk::usb::IUSBHub::Promise::defer(strand_); auto promise = aasdk::usb::IUSBHub::Promise::defer(strand_);
promise->then(std::bind(&App::aoapDeviceHandler, this->shared_from_this(), std::placeholders::_1), promise->then(std::bind(&App::aoapDeviceHandler, this->shared_from_this(), std::placeholders::_1),
@ -141,6 +149,14 @@ void App::waitForDevice()
usbHub_->start(std::move(promise)); usbHub_->start(std::move(promise));
} }
void App::waitForWirelessDevice()
{
OPENAUTO_LOG(info) << "[App] Waiting for Wireless device...";
auto socket = std::make_shared<boost::asio::ip::tcp::socket>(ioService_);
acceptor_.async_accept(*socket, [this, socket](const boost::system::error_code &) { this->start(socket); });
}
void App::onAndroidAutoQuit() void App::onAndroidAutoQuit()
{ {
strand_.dispatch([this, self = this->shared_from_this()]() { strand_.dispatch([this, self = this->shared_from_this()]() {

View File

@ -1,5 +1,12 @@
add_library(openauto SHARED add_library(openauto SHARED
App.cpp App.cpp
../btservice/AndroidBluetoothServer.cpp
../btservice/AndroidBluetoothService.cpp
../btservice/btservice.cpp
${CMAKE_SOURCE_DIR}/include/btservice/AndroidBluetoothServer.hpp
${CMAKE_SOURCE_DIR}/include/btservice/AndroidBluetoothService.hpp
${CMAKE_SOURCE_DIR}/include/btservice/IAndroidBluetoothServer.hpp
${CMAKE_SOURCE_DIR}/include/btservice/IAndroidBluetoothService.hpp
Service/BluetoothService.cpp Service/BluetoothService.cpp
Service/InputService.cpp Service/InputService.cpp
Service/MediaAudioService.cpp Service/MediaAudioService.cpp
@ -95,6 +102,7 @@ endif()
target_include_directories(openauto PRIVATE target_include_directories(openauto PRIVATE
${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/include
${RTAUDIO_INCLUDE_DIRS} ${RTAUDIO_INCLUDE_DIRS}
${Protobuf_INCLUDE_DIRS}
) )
target_link_libraries(openauto PUBLIC target_link_libraries(openauto PUBLIC
@ -105,6 +113,8 @@ target_link_libraries(openauto PUBLIC
rtaudio rtaudio
Qt5::Bluetooth Qt5::Bluetooth
Qt5::MultimediaWidgets Qt5::MultimediaWidgets
btservice_proto
${Protobuf_LIBRARIES}
) )
install(TARGETS openauto install(TARGETS openauto
@ -114,4 +124,5 @@ set_target_properties(openauto
PROPERTIES INSTALL_RPATH_USE_LINK_PATH 1) PROPERTIES INSTALL_RPATH_USE_LINK_PATH 1)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/openauto DESTINATION include) install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/openauto DESTINATION include)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/btservice DESTINATION include)
install(FILES ${CMAKE_SOURCE_DIR}/include/OpenautoLog.hpp DESTINATION include) install(FILES ${CMAKE_SOURCE_DIR}/include/OpenautoLog.hpp DESTINATION include)

View File

@ -61,6 +61,9 @@ const std::string Configuration::cInputScrollWheelButtonKey = "Input.ScrollWheel
const std::string Configuration::cInputBackButtonKey = "Input.BackButton"; const std::string Configuration::cInputBackButtonKey = "Input.BackButton";
const std::string Configuration::cInputEnterButtonKey = "Input.EnterButton"; const std::string Configuration::cInputEnterButtonKey = "Input.EnterButton";
const std::string Configuration::cWifiSSID = "WiFi.SSID";
const std::string Configuration::cWifiPskey = "WiFi.Password";
Configuration::Configuration() Configuration::Configuration()
{ {
this->load(); this->load();
@ -99,6 +102,8 @@ void Configuration::load()
musicAudioChannelEnabled_ = iniConfig.get<bool>(cAudioMusicAudioChannelEnabled, true); musicAudioChannelEnabled_ = iniConfig.get<bool>(cAudioMusicAudioChannelEnabled, true);
speechAudiochannelEnabled_ = iniConfig.get<bool>(cAudioSpeechAudioChannelEnabled, true); speechAudiochannelEnabled_ = iniConfig.get<bool>(cAudioSpeechAudioChannelEnabled, true);
audioOutputBackendType_ = static_cast<AudioOutputBackendType>(iniConfig.get<uint32_t>(cAudioOutputBackendType, static_cast<uint32_t>(AudioOutputBackendType::RTAUDIO))); audioOutputBackendType_ = static_cast<AudioOutputBackendType>(iniConfig.get<uint32_t>(cAudioOutputBackendType, static_cast<uint32_t>(AudioOutputBackendType::RTAUDIO)));
ssid = iniConfig.get<std::string>(cWifiSSID, "");
pskey = iniConfig.get<std::string>(cWifiPskey, "");
} }
catch(const boost::property_tree::ini_parser_error& e) catch(const boost::property_tree::ini_parser_error& e)
{ {
@ -149,7 +154,10 @@ void Configuration::save()
iniConfig.put<bool>(cAudioMusicAudioChannelEnabled, musicAudioChannelEnabled_); iniConfig.put<bool>(cAudioMusicAudioChannelEnabled, musicAudioChannelEnabled_);
iniConfig.put<bool>(cAudioSpeechAudioChannelEnabled, speechAudiochannelEnabled_); iniConfig.put<bool>(cAudioSpeechAudioChannelEnabled, speechAudiochannelEnabled_);
iniConfig.put<uint32_t>(cAudioOutputBackendType, static_cast<uint32_t>(audioOutputBackendType_)); iniConfig.put<uint32_t>(cAudioOutputBackendType, static_cast<uint32_t>(audioOutputBackendType_));
iniConfig.put<std::string>(cWifiSSID, ssid);
iniConfig.put<std::string>(cWifiPskey, pskey);
boost::property_tree::ini_parser::write_ini(cConfigFileName, iniConfig); boost::property_tree::ini_parser::write_ini(cConfigFileName, iniConfig);
} }
void Configuration::setHandednessOfTrafficType(HandednessOfTrafficType value) void Configuration::setHandednessOfTrafficType(HandednessOfTrafficType value)
@ -292,6 +300,17 @@ void Configuration::setAudioOutputBackendType(AudioOutputBackendType value)
audioOutputBackendType_ = value; audioOutputBackendType_ = value;
} }
std::string Configuration::getWifiSSID()
{
return ssid;
}
std::string Configuration::getWifiPassword()
{
return pskey;
}
void Configuration::readButtonCodes(boost::property_tree::ptree& iniConfig) void Configuration::readButtonCodes(boost::property_tree::ptree& iniConfig)
{ {
this->insertButtonCode(iniConfig, cInputPlayButtonKey, aasdk::proto::enums::ButtonCode::PLAY); this->insertButtonCode(iniConfig, cInputPlayButtonKey, aasdk::proto::enums::ButtonCode::PLAY);

View File

@ -223,6 +223,28 @@ void AndroidAutoEntity::onNavigationFocusRequest(const aasdk::proto::messages::N
controlServiceChannel_->receive(this->shared_from_this()); controlServiceChannel_->receive(this->shared_from_this());
} }
void AndroidAutoEntity::onVoiceSessionRequest(const aasdk::proto::messages::VoiceSessionRequest& request)
{
OPENAUTO_LOG(info) << "[AndroidAutoEntity] Voice session request, type: " << (request.type()==1)?("START"):((request.type()==2)?("STOP"):("UNKNOWN"));
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1));
controlServiceChannel_->receive(this->shared_from_this());
}
void AndroidAutoEntity::onPingRequest(const aasdk::proto::messages::PingRequest& request)
{
OPENAUTO_LOG(info) << "[AndroidAutoEntity] Ping Request";
aasdk::proto::messages::PingResponse response;
response.set_timestamp(request.timestamp());
auto promise = aasdk::channel::SendPromise::defer(strand_);
promise->then([]() {}, std::bind(&AndroidAutoEntity::onChannelError, this->shared_from_this(), std::placeholders::_1));
controlServiceChannel_->sendPingResponse(response, std::move(promise));
controlServiceChannel_->receive(this->shared_from_this());
}
void AndroidAutoEntity::onPingResponse(const aasdk::proto::messages::PingResponse&) void AndroidAutoEntity::onPingResponse(const aasdk::proto::messages::PingResponse&)
{ {
pinger_->pong(); pinger_->pong();

View File

@ -60,6 +60,7 @@ void BluetoothService::fillFeatures(aasdk::proto::messages::ServiceDiscoveryResp
channelDescriptor->set_channel_id(static_cast<uint32_t>(channel_->getId())); channelDescriptor->set_channel_id(static_cast<uint32_t>(channel_->getId()));
auto bluetoothChannel = channelDescriptor->mutable_bluetooth_channel(); auto bluetoothChannel = channelDescriptor->mutable_bluetooth_channel();
bluetoothChannel->set_adapter_address(bluetoothDevice_->getLocalAddress()); bluetoothChannel->set_adapter_address(bluetoothDevice_->getLocalAddress());
bluetoothChannel->add_supported_pairing_methods(aasdk::proto::enums::BluetoothPairingMethod_Enum_HFP);
} }
} }

View File

@ -59,6 +59,7 @@ ServiceFactory::ServiceFactory(boost::asio::io_service& ioService, configuration
#else #else
, qtVideoOutput_(nullptr) , qtVideoOutput_(nullptr)
#endif #endif
, btservice_(configuration_)
, nightMode_(nightMode) , nightMode_(nightMode)
{ {