## Building and running on Linux
-Instructions for Ubuntu, tested on 15.10 with GCC 5.2.1.
+Instructions for Ubuntu, tested on 14.04 with Clang 3.5.0 and 16.10 with Clang
+ 3.8.0
### Install required libraries
```sh
-sudo apt-get install libevent-dev
+sudo apt-get install libevent-dev libc++-dev libc++abi-dev
```
### Install build tools
or download binary from https://github.com/ninja-build/ninja/releases
- - Install [gn](https://chromium.googlesource.com/chromium/src/tools/gn/) - meta-build system that generates NinjaBuild files.
+ - Install [gn](https://chromium.googlesource.com/chromium/src/tools/gn/) -
+ meta-build system that generates NinjaBuild files.
Get sha1 of current version from [here](
-https://chromium.googlesource.com/chromium/buildtools/+/master/linux64/gn.sha1) and then download corresponding executable:
+https://chromium.googlesource.com/chromium/buildtools/+/master/linux64/gn.sha1)
+ and then download corresponding executable:
```sh
wget -O gn http://storage.googleapis.com/chromium-gn/<gn.sha1>
```
-i.e. if sha1 is "3491f6687bd9f19946035700eb84ce3eed18c5fa" (value from 24 Feb 2016) do
+i.e. if sha1 is "3491f6687bd9f19946035700eb84ce3eed18c5fa" (value from 24 Feb
+ 2016) do
```sh
wget -O gn http://storage.googleapis.com/chromium-gn/3491f6687bd9f19946035700eb84ce3eed18c5fa
curl https://chromium.googlesource.com/chromium/src/base/+/master/third_party/valgrind/memcheck.h?format=TEXT | base64 -d > memcheck.h
```
+NOTE: If system/bt is checked out under AOSP, then create symbolic links instead
+of downloading sources
+
+```
+cd system/bt
+mkdir third_party
+cd third_party
+ln -s ../../../external/libchrome libchrome
+ln -s ../../../external/modp_b64 modp_b64
+ln -s ../../../external/tinyxml2 tinyxml2
+ln -s ../../../hardware/libhardware libhardware
+ln -s ../../../external/googletest googletest
+```
+
### Generate your build files
```sh
ninja -C out/Default all
```
-This will build all targets (the shared library, executables, tests, etc) and put them in out/Default. To build an individual target, replace "all" with the target of your choice, e.g. ```ninja -C out/Default net_test_osi```.
+This will build all targets (the shared library, executables, tests, etc) and
+ put them in out/Default. To build an individual target, replace "all" with the
+ target of your choice, e.g. ```ninja -C out/Default net_test_osi```.
### Run
cd ~/fluoride/bt/out/Default
LD_LIBRARY_PATH=./ ./bluetoothtbd -create-ipc-socket=fluoride
```
+
+### Eclipse IDE Support
+
+1. Follows the Chromium project
+ [Eclipse Setup Instructions](https://chromium.googlesource.com/chromium/src/+/master/docs/linux_eclipse_dev.md)
+ until "Optional: Building inside Eclipse" section (don't do that section, we
+ will set it up differently)
+
+2. Generate Eclipse settings:
+
+ ```sh
+ cd system/bt
+ gn gen --ide=eclipse out/Default
+ ```
+
+3. In Eclipse, do File->Import->C/C++->C/C++ Project Settings, choose the XML
+ location under system/bt/out/Default
+
+4. Right click on the project. Go to Preferences->C/C++ Build->Builder Settings.
+ Uncheck "Use default build command", but instead using "ninja -C out/Default"
+
+5. Goto Behaviour tab, change clean command to "-t clean"
+
#include "service/hal/bluetooth_gatt_interface.h"
#include <mutex>
-#define _LIBCPP_BUILDING_SHARED_MUTEX
#include <shared_mutex>
-#undef _LIBCPP_BUILDING_SHARED_MUTEX
#include <base/logging.h>
#include <base/observer_list.h>
using std::unique_lock;
using std::shared_lock;
using std::mutex;
-using std::shared_timed_mutex;
+#if defined(OS_GENERIC) && defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION < 3500)
+using shared_mutex_impl = std::shared_mutex;
+#else
+using shared_mutex_impl = std::shared_timed_mutex;
+#endif
namespace bluetooth {
namespace hal {
// use unique_lock. If only accessing |g_interface| use shared lock.
//TODO(jpawlowski): this should be just shared_mutex, as we currently don't use
// timed methods. Change to shared_mutex when we upgrade to C++14
-shared_timed_mutex g_instance_lock;
+shared_mutex_impl g_instance_lock;
// Helper for obtaining the observer lists. This is forward declared here
// and defined below since it depends on BluetoothInterfaceImpl.
} while (0)
void RegisterClientCallback(int status, int client_if, bt_uuid_t* app_uuid) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - status: " << status << " client_if: " << client_if;
VERIFY_INTERFACE_OR_RETURN();
CHECK(app_uuid);
}
void RegisterScannerCallback(int status, int scanner_id, bt_uuid_t* app_uuid) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - status: " << status << " scanner_id: " << scanner_id;
VERIFY_INTERFACE_OR_RETURN();
CHECK(app_uuid);
}
void ScanResultCallback(bt_bdaddr_t* bda, int rssi, vector<uint8_t> adv_data) { // NOLINT(pass-by-value)
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
CHECK(bda);
}
void ConnectCallback(int conn_id, int status, int client_if, bt_bdaddr_t* bda) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
CHECK(bda);
void DisconnectCallback(int conn_id, int status, int client_if,
bt_bdaddr_t* bda) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
CHECK(bda);
}
void SearchCompleteCallback(int conn_id, int status) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
VLOG(2) << __func__ << " - conn_id: " << conn_id
}
void RegisterForNotificationCallback(int conn_id, int registered, int status, uint16_t handle) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
LOG(INFO) << __func__ << " - conn_id: " << conn_id
}
void NotifyCallback(int conn_id, btgatt_notify_params_t *p_data) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
VLOG(2) << __func__ << " - conn_id: " << conn_id
}
void WriteCharacteristicCallback(int conn_id, int status, uint16_t handle) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
VLOG(2) << __func__ << " - conn_id: " << conn_id
void WriteDescriptorCallback(int conn_id, int status,
uint16_t handle) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
VLOG(2) << __func__ << " - conn_id: " << conn_id
}
void MtuChangedCallback(int conn_id, int status, int mtu) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
VLOG(2) << __func__ << " - conn_id: " << conn_id
}
void GetGattDbCallback(int conn_id, btgatt_db_element_t *db, int size) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - conn_id: " << conn_id << " size: " << size;
VERIFY_INTERFACE_OR_RETURN();
}
void ServicesRemovedCallback(int conn_id, uint16_t start_handle, uint16_t end_handle) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - conn_id: " << conn_id
<< " start_handle: " << start_handle
<< " end_handle: " << end_handle;
}
void ServicesAddedCallback(int conn_id, btgatt_db_element_t *added, int added_count) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - conn_id: " << conn_id
<< " added_count: " << added_count;
VERIFY_INTERFACE_OR_RETURN();
}
void RegisterServerCallback(int status, int server_if, bt_uuid_t* app_uuid) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - status: " << status << " server_if: " << server_if;
VERIFY_INTERFACE_OR_RETURN();
CHECK(app_uuid);
void ConnectionCallback(int conn_id, int server_if, int connected,
bt_bdaddr_t* bda) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - conn_id: " << conn_id
<< " server_if: " << server_if << " connected: " << connected;
VERIFY_INTERFACE_OR_RETURN();
int status,
int server_if,
vector<btgatt_db_element_t> service) { // NOLINT(pass-by-value)
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - status: " << status << " server_if: " << server_if
<< " count: " << service.size();
VERIFY_INTERFACE_OR_RETURN();
}
void ServiceStoppedCallback(int status, int server_if, int srvc_handle) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - status: " << status << " server_if: " << server_if
<< " handle: " << srvc_handle;
VERIFY_INTERFACE_OR_RETURN();
}
void ServiceDeletedCallback(int status, int server_if, int srvc_handle) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - status: " << status << " server_if: " << server_if
<< " handle: " << srvc_handle;
VERIFY_INTERFACE_OR_RETURN();
void RequestReadCharacteristicCallback(int conn_id, int trans_id, bt_bdaddr_t* bda,
int attr_handle, int offset, bool is_long) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
<< " attr_handle: " << attr_handle << " offset: " << offset
<< " is_long: " << is_long;
void RequestReadDescriptorCallback(int conn_id, int trans_id, bt_bdaddr_t* bda,
int attr_handle, int offset, bool is_long) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
<< " attr_handle: " << attr_handle << " offset: " << offset
<< " is_long: " << is_long;
int attr_handle, int offset,
bool need_rsp, bool is_prep,
vector<uint8_t> value) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
<< " attr_handle: " << attr_handle << " offset: " << offset
<< " length: " << value.size() << " need_rsp: " << need_rsp
int attr_handle, int offset,
bool need_rsp, bool is_prep,
vector<uint8_t> value) { // NOLINT(pass-by-value)
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
<< " attr_handle: " << attr_handle << " offset: " << offset
<< " length: " << value.size() << " need_rsp: " << need_rsp
void RequestExecWriteCallback(int conn_id, int trans_id,
bt_bdaddr_t* bda, int exec_write) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - conn_id: " << conn_id << " trans_id: " << trans_id
<< " exec_write: " << exec_write;
VERIFY_INTERFACE_OR_RETURN();
}
void ResponseConfirmationCallback(int status, int handle) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - status: " << status << " handle: " << handle;
VERIFY_INTERFACE_OR_RETURN();
}
void IndicationSentCallback(int conn_id, int status) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - conn_id: " << conn_id << " status: " << status;
VERIFY_INTERFACE_OR_RETURN();
}
void MtuChangedCallback(int conn_id, int mtu) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VLOG(2) << __func__ << " - conn_id: " << conn_id << " mtu: " << mtu;
VERIFY_INTERFACE_OR_RETURN();
// static
bool BluetoothGattInterface::Initialize() {
- unique_lock<shared_timed_mutex> lock(g_instance_lock);
+ unique_lock<shared_mutex_impl> lock(g_instance_lock);
CHECK(!g_interface);
std::unique_ptr<BluetoothGattInterfaceImpl> impl(
// static
void BluetoothGattInterface::CleanUp() {
- unique_lock<shared_timed_mutex> lock(g_instance_lock);
+ unique_lock<shared_mutex_impl> lock(g_instance_lock);
CHECK(g_interface);
delete g_interface;
// static
bool BluetoothGattInterface::IsInitialized() {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
return g_interface != nullptr;
}
// static
BluetoothGattInterface* BluetoothGattInterface::Get() {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
CHECK(g_interface);
return g_interface;
}
// static
void BluetoothGattInterface::InitializeForTesting(
BluetoothGattInterface* test_instance) {
- unique_lock<shared_timed_mutex> lock(g_instance_lock);
+ unique_lock<shared_mutex_impl> lock(g_instance_lock);
CHECK(test_instance);
CHECK(!g_interface);
#include "service/hal/bluetooth_interface.h"
#include <mutex>
-#define _LIBCPP_BUILDING_SHARED_MUTEX
#include <shared_mutex>
-#undef _LIBCPP_BUILDING_SHARED_MUTEX
#include <base/logging.h>
#include <base/observer_list.h>
using std::unique_lock;
using std::shared_lock;
using std::mutex;
-using std::shared_timed_mutex;
+#if defined(OS_GENERIC) && defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION < 3500)
+using shared_mutex_impl = std::shared_mutex;
+#else
+using shared_mutex_impl = std::shared_timed_mutex;
+#endif
namespace bluetooth {
namespace hal {
// use unique_lock. If only accessing |g_interface| use shared lock.
//TODO(jpawlowski): this should be just shared_mutex, as we currently don't use
// timed methods. Change to shared_mutex when we upgrade to C++14
-shared_timed_mutex g_instance_lock;
+shared_mutex_impl g_instance_lock;
// Helper for obtaining the observer list. This is forward declared here and
// defined below since it depends on BluetoothInterfaceImpl.
} while (0)
void AdapterStateChangedCallback(bt_state_t state) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
VLOG(1) << "Adapter state changed: " << BtStateText(state);
FOR_EACH_BLUETOOTH_OBSERVER(AdapterStateChangedCallback(state));
void AdapterPropertiesCallback(bt_status_t status,
int num_properties,
bt_property_t* properties) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
VLOG(1) << "Adapter properties changed - status: " << BtStatusText(status)
<< ", num_properties: " << num_properties;
bt_bdaddr_t *remote_bd_addr,
int num_properties,
bt_property_t* properties) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
VLOG(1) << " Remote device properties changed - status: " << BtStatusText(status)
<< " - BD_ADDR: " << BtAddrString(remote_bd_addr)
}
void DiscoveryStateChangedCallback(bt_discovery_state_t state) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
VLOG(1) << "Discovery state changed - state: " << BtDiscoveryStateText(state);
FOR_EACH_BLUETOOTH_OBSERVER(DiscoveryStateChangedCallback(state));
void PinRequestCallback(bt_bdaddr_t *remote_bd_addr, bt_bdname_t *bd_name,
uint32_t cod, bool min_16_digit) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
VLOG(2) << __func__
<< " - remote_bd_addr: " << remote_bd_addr
void SSPRequestCallback(bt_bdaddr_t *remote_bd_addr,
bt_bdname_t *bd_name, uint32_t cod, bt_ssp_variant_t pairing_variant, uint32_t pass_key) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
VLOG(2) << __func__
<< " - remote_bd_addr: " << remote_bd_addr
bt_status_t status,
bt_bdaddr_t *remote_bd_addr,
bt_bond_state_t state) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
VLOG(2) << __func__
<< " - remote_bd_addr: " << BtAddrString(remote_bd_addr)
void AclStateChangedCallback(bt_status_t status,
bt_bdaddr_t *remote_bd_addr,
bt_acl_state_t state) {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
VERIFY_INTERFACE_OR_RETURN();
CHECK(remote_bd_addr);
VLOG(1) << "Remote device ACL state changed - status: "
// BluetoothInterface overrides.
void AddObserver(Observer* observer) override {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
observers_.AddObserver(observer);
}
void RemoveObserver(Observer* observer) override {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
observers_.RemoveObserver(observer);
}
// static
bool BluetoothInterface::Initialize() {
- unique_lock<shared_timed_mutex> lock(g_instance_lock);
+ unique_lock<shared_mutex_impl> lock(g_instance_lock);
CHECK(!g_bluetooth_interface);
std::unique_ptr<BluetoothInterfaceImpl> impl(new BluetoothInterfaceImpl());
// static
void BluetoothInterface::CleanUp() {
- unique_lock<shared_timed_mutex> lock(g_instance_lock);
+ unique_lock<shared_mutex_impl> lock(g_instance_lock);
CHECK(g_bluetooth_interface);
delete g_bluetooth_interface;
// static
bool BluetoothInterface::IsInitialized() {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
return g_bluetooth_interface != nullptr;
}
// static
BluetoothInterface* BluetoothInterface::Get() {
- shared_lock<shared_timed_mutex> lock(g_instance_lock);
+ shared_lock<shared_mutex_impl> lock(g_instance_lock);
CHECK(g_bluetooth_interface);
return g_bluetooth_interface;
}
// static
void BluetoothInterface::InitializeForTesting(
BluetoothInterface* test_instance) {
- unique_lock<shared_timed_mutex> lock(g_instance_lock);
+ unique_lock<shared_mutex_impl> lock(g_instance_lock);
CHECK(test_instance);
CHECK(!g_bluetooth_interface);