Skip to content

Commit c7eab0f

Browse files
committed
Add dongle mode connection strategy
1 parent 8d9c947 commit c7eab0f

File tree

10 files changed

+175
-25
lines changed

10 files changed

+175
-25
lines changed
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
# Uncomment this setting to wait for the usb to connect first.
2-
# By default, we try to connect and wait for the phone to connect first regardless of the usb connection.
3-
#AAWG_CONNECTION_WAIT_FOR_ACCESSORY=1
1+
# Set the connection strategy to use
2+
# 0 - Dongle mode (default). Waits for both dongle and headunit bluetooth connections and then starts the wifi and usb connections.
3+
# 1 - Phone first. Waits for the phone bluetooth and wifi to connect first, and then starts the usb connection.
4+
# 2 - Usb first. Waits for the usb to connect first, and then starts the bluetooth and wifi connection with phone.
5+
AAWG_CONNECTION_STRATEGY=0

aa_wireless_dongle/package/aawg/src/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ PROTO_HEADERS = $(PROTO_FILES:proto=pb.h)
88

99
ALL_HEADERS = $(wildcard *.h) $(PROTO_HEADERS)
1010

11-
aawgd: aawgd.o bluetoothHandler.o bluetoothProfiles.o proxyHandler.o uevent.o usb.o common.o proto/WifiInfoResponse.pb.o proto/WifiStartRequest.pb.o
11+
aawgd: aawgd.o bluetoothHandler.o bluetoothProfiles.o bluetoothAdvertisement.o proxyHandler.o uevent.o usb.o common.o proto/WifiInfoResponse.pb.o proto/WifiStartRequest.pb.o
1212
$(CXX) $(CXXFLAGS) $(EXTRA_CXXFLAGS) -o '$@' $^
1313

1414
%.o: %.cpp

aa_wireless_dongle/package/aawg/src/aawgd.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,16 @@ int main(void) {
1515
UsbManager::instance().init();
1616
BluetoothHandler::instance().init();
1717

18+
ConnectionStrategy connectionStrategy = Config::instance()->getConnectionStrategy();
19+
if (connectionStrategy == ConnectionStrategy::DONGLE_MODE) {
20+
BluetoothHandler::instance().powerOn();
21+
}
22+
1823
while (true) {
24+
Logger::instance()->info("Connection Strategy: %d\n", connectionStrategy);
25+
1926
// Per connection setup and processing
20-
if (std::getenv("AAWG_CONNECTION_WAIT_FOR_ACCESSORY") != nullptr) {
27+
if (connectionStrategy == ConnectionStrategy::USB_FIRST) {
2128
Logger::instance()->info("Waiting for the accessory to connect first\n");
2229
UsbManager::instance().enableDefaultAndWaitForAccessory();
2330
}
@@ -29,7 +36,10 @@ int main(void) {
2936
return 1;
3037
}
3138

32-
BluetoothHandler::instance().powerOn();
39+
if (connectionStrategy != ConnectionStrategy::DONGLE_MODE) {
40+
BluetoothHandler::instance().powerOn();
41+
}
42+
3343
std::optional<std::thread> btConnectionThread = BluetoothHandler::instance().connectWithRetry();
3444

3545
proxyThread->join();
@@ -41,8 +51,10 @@ int main(void) {
4151

4252
UsbManager::instance().disableGadget();
4353

44-
// sleep for a couple of seconds before retrying
45-
sleep(2);
54+
if (connectionStrategy != ConnectionStrategy::DONGLE_MODE) {
55+
// sleep for a couple of seconds before retrying
56+
sleep(2);
57+
}
4658
}
4759

4860
ueventThread->join();
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include <stdio.h>
2+
3+
#include "common.h"
4+
#include "bluetoothAdvertisement.h"
5+
6+
static constexpr const char* INTERFACE_BLUEZ_LE_ADVERTISEMENT = "org.bluez.LEAdvertisement1";
7+
8+
/* static */ std::shared_ptr<BLEAdvertisement> BLEAdvertisement::create(DBus::Path path) {
9+
return std::shared_ptr<BLEAdvertisement>(new BLEAdvertisement(path));
10+
}
11+
12+
BLEAdvertisement::BLEAdvertisement(DBus::Path path): DBus::Object(path) {
13+
this->create_method<void(void)>(INTERFACE_BLUEZ_LE_ADVERTISEMENT, "Release", sigc::mem_fun(*this, &BLEAdvertisement::Release));
14+
15+
type = this->create_property<std::string>(INTERFACE_BLUEZ_LE_ADVERTISEMENT, "Type", DBus::PropertyAccess::ReadOnly);
16+
serviceUUIDs = this->create_property<std::vector<std::string>>(INTERFACE_BLUEZ_LE_ADVERTISEMENT, "ServiceUUIDs");
17+
localName = this->create_property<std::string>(INTERFACE_BLUEZ_LE_ADVERTISEMENT, "LocalName");
18+
}
19+
20+
void BLEAdvertisement::Release() {
21+
Logger::instance()->info("Bluetooth LE Advertisement released\n");
22+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#pragma once
2+
3+
#include "bluetoothCommon.h"
4+
5+
class BLEAdvertisement: public DBus::Object {
6+
public:
7+
static std::shared_ptr<BLEAdvertisement> create(DBus::Path path);
8+
9+
std::shared_ptr<DBus::Property<std::string>> type;
10+
std::shared_ptr<DBus::Property<std::vector<std::string>>> serviceUUIDs;
11+
std::shared_ptr<DBus::Property<std::string>> localName;
12+
13+
protected:
14+
BLEAdvertisement(DBus::Path path);
15+
16+
void Release();
17+
};

aa_wireless_dongle/package/aawg/src/bluetoothHandler.cpp

Lines changed: 75 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,23 @@
33
#include "common.h"
44
#include "bluetoothHandler.h"
55
#include "bluetoothProfiles.h"
6+
#include "bluetoothAdvertisement.h"
67

78
static constexpr const char* ADAPTER_ALIAS = "AA Wireless Dongle";
9+
static constexpr const char* ADAPTER_ALIAS_DONGLE = "AndroidAuto-Dongle";
810

911
static constexpr const char* BLUEZ_BUS_NAME = "org.bluez";
1012
static constexpr const char* BLUEZ_ROOT_OBJECT_PATH = "/";
1113
static constexpr const char* BLUEZ_OBJECT_PATH = "/org/bluez";
1214

1315
static constexpr const char* INTERFACE_BLUEZ_ADAPTER = "org.bluez.Adapter1";
16+
static constexpr const char* INTERFACE_BLUEZ_LE_ADVERTISING_MANAGER = "org.bluez.LEAdvertisingManager1";
17+
1418
static constexpr const char* INTERFACE_BLUEZ_DEVICE = "org.bluez.Device1";
1519
static constexpr const char* INTERFACE_BLUEZ_PROFILE_MANAGER = "org.bluez.ProfileManager1";
1620

21+
static constexpr const char* LE_ADVERTISEMENT_OBJECT_PATH = "/com/aawgd/bluetooth/advertisement";
22+
1723
static constexpr const char* AAWG_PROFILE_OBJECT_PATH = "/com/aawgd/bluetooth/aawg";
1824
static constexpr const char* AAWG_PROFILE_UUID = "4de17a00-52cb-11e6-bdf4-0800200c9a66";
1925

@@ -28,6 +34,9 @@ class BluezAdapterProxy: private DBus::ObjectProxy {
2834
powered = this->create_property<bool>(INTERFACE_BLUEZ_ADAPTER, "Powered");
2935
discoverable = this->create_property<bool>(INTERFACE_BLUEZ_ADAPTER, "Discoverable");
3036
pairable = this->create_property<bool>(INTERFACE_BLUEZ_ADAPTER, "Pairable");
37+
38+
registerAdvertisement = this->create_method<void(DBus::Path, DBus::Properties)>(INTERFACE_BLUEZ_LE_ADVERTISING_MANAGER, "RegisterAdvertisement");
39+
unregisterAdvertisement = this->create_method<void(DBus::Path)>(INTERFACE_BLUEZ_LE_ADVERTISING_MANAGER, "UnregisterAdvertisement");
3140
}
3241

3342
public:
@@ -40,6 +49,9 @@ class BluezAdapterProxy: private DBus::ObjectProxy {
4049
std::shared_ptr<DBus::PropertyProxy<bool>> powered;
4150
std::shared_ptr<DBus::PropertyProxy<bool>> discoverable;
4251
std::shared_ptr<DBus::PropertyProxy<bool>> pairable;
52+
53+
std::shared_ptr<DBus::MethodProxy<void(DBus::Path, DBus::Properties)>> registerAdvertisement;
54+
std::shared_ptr<DBus::MethodProxy<void(DBus::Path)>> unregisterAdvertisement;
4355
};
4456

4557

@@ -77,7 +89,7 @@ void BluetoothHandler::initAdapter() {
7789
}
7890
else {
7991
m_adapter = BluezAdapterProxy::create(m_connection, adapter_path);
80-
m_adapter->alias->set_value(ADAPTER_ALIAS);
92+
m_adapter->alias->set_value(m_adapterAlias);
8193
}
8294
}
8395

@@ -117,15 +129,46 @@ void BluetoothHandler::exportProfiles() {
117129
});
118130
Logger::instance()->info("Bluetooth AA Wireless profile active\n");
119131

120-
// Register HSP Handset profile
121-
m_hspProfile = HSPHSProfile::create(HSP_HS_PROFILE_OBJECT_PATH);
122-
if (m_connection->register_object(m_hspProfile, DBus::ThreadForCalling::DispatcherThread) != DBus::RegistrationStatus::Success) {
123-
Logger::instance()->info("Failed to register HSP Handset profile\n");
132+
if (Config::instance()->getConnectionStrategy() != ConnectionStrategy::DONGLE_MODE) {
133+
// Register HSP Handset profile
134+
m_hspProfile = HSPHSProfile::create(HSP_HS_PROFILE_OBJECT_PATH);
135+
if (m_connection->register_object(m_hspProfile, DBus::ThreadForCalling::DispatcherThread) != DBus::RegistrationStatus::Success) {
136+
Logger::instance()->info("Failed to register HSP Handset profile\n");
137+
}
138+
registerProfile(HSP_HS_PROFILE_OBJECT_PATH, HSP_HS_UUID, {
139+
{"Name", DBus::Variant("HSP HS")},
140+
});
141+
Logger::instance()->info("HSP Handset profile active\n");
124142
}
125-
registerProfile(HSP_HS_PROFILE_OBJECT_PATH, HSP_HS_UUID, {
126-
{"Name", DBus::Variant("HSP HS")},
127-
});
128-
Logger::instance()->info("HSP Handset profile active\n");
143+
}
144+
145+
void BluetoothHandler::startAdvertising() {
146+
if (!m_adapter) {
147+
return;
148+
}
149+
150+
// Register Advertisement Object
151+
m_leAdvertisement = BLEAdvertisement::create(LE_ADVERTISEMENT_OBJECT_PATH);
152+
153+
m_leAdvertisement->type->set_value("peripheral");
154+
m_leAdvertisement->serviceUUIDs->set_value(std::vector<std::string>{AAWG_PROFILE_UUID});
155+
m_leAdvertisement->localName->set_value(m_adapterAlias);
156+
157+
if (m_connection->register_object(m_leAdvertisement, DBus::ThreadForCalling::DispatcherThread) != DBus::RegistrationStatus::Success) {
158+
Logger::instance()->info("Failed to register BLE Advertisement\n");
159+
}
160+
161+
(*m_adapter->registerAdvertisement)(LE_ADVERTISEMENT_OBJECT_PATH, {});
162+
Logger::instance()->info("BLE Advertisement started\n");
163+
}
164+
165+
void BluetoothHandler::stopAdvertising() {
166+
if (!m_adapter) {
167+
return;
168+
}
169+
170+
(*m_adapter->unregisterAdvertisement)(LE_ADVERTISEMENT_OBJECT_PATH);
171+
Logger::instance()->info("BLE Advertisement stopped\n");
129172
}
130173

131174
void BluetoothHandler::connectDevice() {
@@ -145,6 +188,8 @@ void BluetoothHandler::connectDevice() {
145188
return;
146189
}
147190

191+
const bool isDongleMode = (Config::instance()->getConnectionStrategy() == ConnectionStrategy::DONGLE_MODE);
192+
148193
Logger::instance()->info("Found %d bluetooth devices\n", device_paths.size());
149194

150195
for (const std::string &device_path: device_paths) {
@@ -161,16 +206,21 @@ void BluetoothHandler::connectDevice() {
161206
Logger::instance()->info("Bluetooth device already connected, disconnecting\n");
162207
disconnect();
163208
}
164-
connectProfile(HSP_AG_UUID);
209+
connectProfile(isDongleMode ? "" : HSP_AG_UUID);
165210
Logger::instance()->info("Bluetooth connected to the device\n");
166-
return;
211+
if (!isDongleMode) {
212+
return;
213+
}
167214
} catch (DBus::Error& e) {
168-
Logger::instance()->info("Failed to connect device at path: %s\n", device_path.c_str());
215+
if (!isDongleMode) {
216+
Logger::instance()->info("Failed to connect device at path: %s\n", device_path.c_str());
217+
}
169218
}
170219
}
171220

172-
Logger::instance()->info("Failed to connect to any known bluetooth device\n");
173-
221+
if (!isDongleMode) {
222+
Logger::instance()->info("Failed to connect to any known bluetooth device\n");
223+
}
174224
}
175225

176226
void BluetoothHandler::retryConnectLoop() {
@@ -186,7 +236,9 @@ void BluetoothHandler::retryConnectLoop() {
186236
}
187237
}
188238

189-
BluetoothHandler::instance().powerOff();
239+
if (Config::instance()->getConnectionStrategy() != ConnectionStrategy::DONGLE_MODE) {
240+
BluetoothHandler::instance().powerOff();
241+
}
190242
}
191243

192244
void BluetoothHandler::init() {
@@ -196,7 +248,7 @@ void BluetoothHandler::init() {
196248
m_dispatcher = DBus::StandaloneDispatcher::create();
197249
m_connection = m_dispatcher->create_connection( DBus::BusType::SYSTEM );
198250

199-
Logger::instance()->info("Unique Name: %s\n", m_connection->unique_name().c_str());
251+
m_adapterAlias = (Config::instance()->getConnectionStrategy() == ConnectionStrategy::DONGLE_MODE) ? ADAPTER_ALIAS_DONGLE : ADAPTER_ALIAS;
200252

201253
initAdapter();
202254
exportProfiles();
@@ -209,6 +261,10 @@ void BluetoothHandler::powerOn() {
209261

210262
setPower(true);
211263
setPairable(true);
264+
265+
if (Config::instance()->getConnectionStrategy() == ConnectionStrategy::DONGLE_MODE) {
266+
startAdvertising();
267+
}
212268
}
213269

214270
std::optional<std::thread> BluetoothHandler::connectWithRetry() {
@@ -231,5 +287,8 @@ void BluetoothHandler::powerOff() {
231287
return;
232288
}
233289

290+
if (Config::instance()->getConnectionStrategy() == ConnectionStrategy::DONGLE_MODE) {
291+
stopAdvertising();
292+
}
234293
setPower(false);
235294
}

aa_wireless_dongle/package/aawg/src/bluetoothHandler.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
class BluezAdapterProxy;
99
class AAWirelessProfile;
1010
class HSPHSProfile;
11+
class BLEAdvertisement;
1112

1213
class BluetoothHandler {
1314
public:
@@ -33,6 +34,9 @@ class BluetoothHandler {
3334
void exportProfiles();
3435
void connectDevice();
3536

37+
void startAdvertising();
38+
void stopAdvertising();
39+
3640
void retryConnectLoop();
3741

3842
std::shared_ptr<std::promise<void>> connectWithRetryPromise;
@@ -43,4 +47,8 @@ class BluetoothHandler {
4347

4448
std::shared_ptr<AAWirelessProfile> m_aawProfile;
4549
std::shared_ptr<HSPHSProfile> m_hspProfile;
50+
51+
std::shared_ptr<BLEAdvertisement> m_leAdvertisement;
52+
53+
std::string m_adapterAlias;
4654
};

aa_wireless_dongle/package/aawg/src/common.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,26 @@ WifiInfo Config::getWifiInfo() {
4848
getenv("AAWG_PROXY_PORT", 5288),
4949
};
5050
}
51+
52+
ConnectionStrategy Config::getConnectionStrategy() {
53+
if (!connectionStrategy.has_value()) {
54+
const int32_t connectionStrategyEnv = getenv("AAWG_CONNECTION_STRATEGY", 0);
55+
56+
switch (connectionStrategyEnv) {
57+
case 1:
58+
connectionStrategy = ConnectionStrategy::PHONE_FIRST;
59+
break;
60+
case 2:
61+
connectionStrategy = ConnectionStrategy::USB_FIRST;
62+
break;
63+
default:
64+
connectionStrategy = ConnectionStrategy::DONGLE_MODE;
65+
break;
66+
}
67+
}
68+
69+
return connectionStrategy.value();
70+
}
5171
#pragma endregion Config
5272

5373
#pragma region Logger

aa_wireless_dongle/package/aawg/src/common.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <string>
44
#include <cstdint>
5+
#include <optional>
56

67
enum SecurityMode: int;
78
enum AccessPointType: int;
@@ -16,18 +17,27 @@ struct WifiInfo {
1617
int32_t port;
1718
};
1819

20+
enum class ConnectionStrategy {
21+
DONGLE_MODE = 0,
22+
PHONE_FIRST = 1,
23+
USB_FIRST = 2
24+
};
25+
1926
class Config {
2027
public:
2128
static Config* instance();
2229

2330
WifiInfo getWifiInfo();
31+
ConnectionStrategy getConnectionStrategy();
2432
private:
2533
Config() = default;
2634

2735
int32_t getenv(std::string name, int32_t defaultValue);
2836
std::string getenv(std::string name, std::string defaultValue);
2937

3038
std::string getMacAddress(std::string interface);
39+
40+
std::optional<ConnectionStrategy> connectionStrategy;
3141
};
3242

3343
class Logger {

aa_wireless_dongle/package/aawg/src/proxyHandler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ void AAWProxy::handleClient(int server_sock) {
168168
// Phone connected via TCP, we can stop retrying bluetooth connection
169169
BluetoothHandler::instance().stopConnectWithRetry();
170170

171-
if (std::getenv("AAWG_CONNECTION_WAIT_FOR_ACCESSORY") == nullptr) {
171+
if (Config::instance()->getConnectionStrategy() != ConnectionStrategy::USB_FIRST) {
172172
if (!UsbManager::instance().enableDefaultAndWaitForAccessory(std::chrono::seconds(10))) {
173173
return;
174174
}

0 commit comments

Comments
 (0)