gatt_server_old.cc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. //
  2. // Copyright 2015 Google, Inc.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at:
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. #define LOG_TAG "bt_gatts"
  17. #include "gatt_server_old.h"
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <unistd.h>
  21. #include <base/bind.h>
  22. #include <base/bind_helpers.h>
  23. #include <base/callback.h>
  24. #include <algorithm>
  25. #include <array>
  26. #include <condition_variable>
  27. #include <map>
  28. #include <memory>
  29. #include <mutex>
  30. #include <set>
  31. #include <string>
  32. #include <unordered_map>
  33. #include <unordered_set>
  34. #include <vector>
  35. #include <hardware/bluetooth.h>
  36. #include <hardware/bt_gatt.h>
  37. #include "service/hal/bluetooth_interface.h"
  38. #include "service/logging_helpers.h"
  39. #include "osi/include/log.h"
  40. #include "osi/include/osi.h"
  41. namespace {
  42. const size_t kMaxGattAttributeSize = 512;
  43. std::vector<btgatt_db_element_t> pending_svc_decl;
  44. std::unordered_set<int> blob_index;
  45. // TODO(icoolidge): Support multiple instances
  46. // TODO(armansito): Remove this variable. No point of having this if
  47. // each bluetooth::gatt::Server instance already keeps a pointer to the
  48. // ServerInternals that is associated with it (which is much cleaner). It looks
  49. // like this variable exists because the btif callbacks don't allow the
  50. // upper-layer to pass user data to them. We could:
  51. //
  52. // 1. Fix the btif callbacks so that some sort of continuation can be
  53. // attached to a callback. This might be a long shot since the callback
  54. // interface doesn't allow more than one caller to register its own callbacks
  55. // (which might be what we want though, since this would make the API more
  56. // flexible).
  57. //
  58. // 2. Allow creation of Server objects using a factory method that returns
  59. // the result asynchronously in a base::Callback. The RegisterServerCallback
  60. // provides an |app_uuid|, which can be used to store callback structures in
  61. // a map and lazily instantiate the Server and invoke the correct callback.
  62. // This is a general pattern that we should use throughout the daemon, since
  63. // all operations can timeout or fail and this is best reported in an
  64. // asynchronous base::Callback.
  65. //
  66. static bluetooth::gatt::ServerInternals* g_internal = nullptr;
  67. enum { kPipeReadEnd = 0, kPipeWriteEnd = 1, kPipeNumEnds = 2 };
  68. } // namespace
  69. namespace bluetooth {
  70. namespace gatt {
  71. struct Characteristic {
  72. Uuid uuid;
  73. int blob_section;
  74. std::vector<uint8_t> blob;
  75. // Support synchronized blob updates by latching under mutex.
  76. std::vector<uint8_t> next_blob;
  77. bool next_blob_pending;
  78. bool notify;
  79. };
  80. struct ServerInternals {
  81. ServerInternals();
  82. ~ServerInternals();
  83. int Initialize();
  84. bt_status_t AddCharacteristic(const Uuid& uuid, uint8_t properties,
  85. uint16_t permissions);
  86. // This maps API attribute Uuids to BlueDroid handles.
  87. std::map<Uuid, int> uuid_to_attribute;
  88. // The attribute cache, indexed by BlueDroid handles.
  89. std::unordered_map<int, Characteristic> characteristics;
  90. // Associate a control attribute with its value attribute.
  91. std::unordered_map<int, int> controlled_blobs;
  92. ScanResults scan_results;
  93. Uuid last_write;
  94. const btgatt_interface_t* gatt;
  95. int server_if;
  96. int client_if;
  97. int service_handle;
  98. std::set<int> connections;
  99. std::mutex lock;
  100. std::condition_variable api_synchronize;
  101. int pipefd[kPipeNumEnds];
  102. };
  103. } // namespace gatt
  104. } // namespace bluetooth
  105. namespace {
  106. /** Callback invoked in response to register_server */
  107. void RegisterServerCallback(int status, int server_if,
  108. const bluetooth::Uuid& app_uuid) {
  109. LOG_INFO(LOG_TAG, "%s: status:%d server_if:%d app_uuid:%p", __func__, status,
  110. server_if, &app_uuid);
  111. g_internal->server_if = server_if;
  112. pending_svc_decl.push_back(
  113. {.type = BTGATT_DB_PRIMARY_SERVICE, .uuid = app_uuid});
  114. }
  115. void ServiceAddedCallback(int status, int server_if,
  116. std::vector<btgatt_db_element_t> service) {
  117. LOG_INFO(LOG_TAG, "%s: status:%d server_if:%d count:%zu svc_handle:%d",
  118. __func__, status, server_if, service.size(),
  119. service[0].attribute_handle);
  120. std::lock_guard<std::mutex> lock(g_internal->lock);
  121. g_internal->server_if = server_if;
  122. g_internal->service_handle = service[0].attribute_handle;
  123. uint16_t prev_char_handle = 0;
  124. uint16_t prev_char_properties = 0;
  125. for (size_t i = 1; i < service.size(); i++) {
  126. const btgatt_db_element_t& el = service[i];
  127. if (el.type == BTGATT_DB_DESCRIPTOR) {
  128. LOG_INFO(LOG_TAG, "%s: descr_handle:%d", __func__, el.attribute_handle);
  129. } else if (el.type == BTGATT_DB_CHARACTERISTIC) {
  130. bluetooth::Uuid id(el.uuid);
  131. uint16_t char_handle = el.attribute_handle;
  132. LOG_INFO(LOG_TAG, "%s: char_handle:%d", __func__, char_handle);
  133. g_internal->uuid_to_attribute[id] = char_handle;
  134. g_internal->characteristics[char_handle].uuid = id;
  135. g_internal->characteristics[char_handle].blob_section = 0;
  136. // If the added characteristic is blob
  137. if (blob_index.find(i) != blob_index.end()) {
  138. // Finally, associate the control attribute with the value attribute.
  139. // Also, initialize the control attribute to a readable zero.
  140. const uint16_t control_attribute = char_handle;
  141. const uint16_t blob_attribute = prev_char_handle;
  142. g_internal->controlled_blobs[control_attribute] = blob_attribute;
  143. g_internal->characteristics[blob_attribute].notify =
  144. prev_char_properties & bluetooth::gatt::kPropertyNotify;
  145. bluetooth::gatt::Characteristic& ctrl =
  146. g_internal->characteristics[control_attribute];
  147. ctrl.next_blob.clear();
  148. ctrl.next_blob.push_back(0);
  149. ctrl.next_blob_pending = true;
  150. ctrl.blob_section = 0;
  151. ctrl.notify = false;
  152. }
  153. prev_char_handle = char_handle;
  154. prev_char_properties = el.properties;
  155. }
  156. }
  157. pending_svc_decl.clear();
  158. blob_index.clear();
  159. // The Uuid provided here is unimportant, and is only used to satisfy
  160. // BlueDroid.
  161. // It must be different than any other registered Uuid.
  162. bluetooth::Uuid client_id = bluetooth::Uuid::GetRandom();
  163. bt_status_t btstat = g_internal->gatt->client->register_client(client_id);
  164. if (btstat != BT_STATUS_SUCCESS) {
  165. LOG_ERROR(LOG_TAG, "%s: Failed to register client", __func__);
  166. }
  167. }
  168. void RequestReadCallback(int conn_id, int trans_id, const RawAddress& bda,
  169. int attr_handle, int attribute_offset_octets,
  170. bool is_long) {
  171. std::lock_guard<std::mutex> lock(g_internal->lock);
  172. bluetooth::gatt::Characteristic& ch =
  173. g_internal->characteristics[attr_handle];
  174. // Latch next_blob to blob on a 'fresh' read.
  175. if (ch.next_blob_pending && attribute_offset_octets == 0 &&
  176. ch.blob_section == 0) {
  177. std::swap(ch.blob, ch.next_blob);
  178. ch.next_blob_pending = false;
  179. }
  180. const size_t blob_offset_octets =
  181. std::min(ch.blob.size(), ch.blob_section * kMaxGattAttributeSize);
  182. const size_t blob_remaining = ch.blob.size() - blob_offset_octets;
  183. const size_t attribute_size = std::min(kMaxGattAttributeSize, blob_remaining);
  184. std::string addr(BtAddrString(&bda));
  185. LOG_INFO(LOG_TAG,
  186. "%s: connection:%d (%s) reading attr:%d attribute_offset_octets:%d "
  187. "blob_section:%u (is_long:%u)",
  188. __func__, conn_id, addr.c_str(), attr_handle,
  189. attribute_offset_octets, ch.blob_section, is_long);
  190. btgatt_response_t response;
  191. response.attr_value.len = 0;
  192. if (attribute_offset_octets < static_cast<int>(attribute_size)) {
  193. std::copy(ch.blob.begin() + blob_offset_octets + attribute_offset_octets,
  194. ch.blob.begin() + blob_offset_octets + attribute_size,
  195. response.attr_value.value);
  196. response.attr_value.len = attribute_size - attribute_offset_octets;
  197. }
  198. response.attr_value.handle = attr_handle;
  199. response.attr_value.offset = attribute_offset_octets;
  200. response.attr_value.auth_req = 0;
  201. g_internal->gatt->server->send_response(conn_id, trans_id, 0, response);
  202. }
  203. void RequestWriteCallback(int conn_id, int trans_id, const RawAddress& bda,
  204. int attr_handle, int attribute_offset, bool need_rsp,
  205. bool is_prep, std::vector<uint8_t> value) {
  206. std::string addr(BtAddrString(&bda));
  207. LOG_INFO(LOG_TAG,
  208. "%s: connection:%d (%s:trans:%d) write attr:%d attribute_offset:%d "
  209. "length:%zu "
  210. "need_resp:%u is_prep:%u",
  211. __func__, conn_id, addr.c_str(), trans_id, attr_handle,
  212. attribute_offset, value.size(), need_rsp, is_prep);
  213. std::lock_guard<std::mutex> lock(g_internal->lock);
  214. bluetooth::gatt::Characteristic& ch =
  215. g_internal->characteristics[attr_handle];
  216. ch.blob.resize(attribute_offset + value.size());
  217. std::copy(value.begin(), value.end(), ch.blob.begin() + attribute_offset);
  218. auto target_blob = g_internal->controlled_blobs.find(attr_handle);
  219. // If this is a control attribute, adjust offset of the target blob.
  220. if (target_blob != g_internal->controlled_blobs.end() &&
  221. ch.blob.size() == 1u) {
  222. g_internal->characteristics[target_blob->second].blob_section = ch.blob[0];
  223. LOG_INFO(LOG_TAG, "%s: updating attribute %d blob_section to %u", __func__,
  224. target_blob->second, ch.blob[0]);
  225. } else if (!is_prep) {
  226. // This is a single frame characteristic write.
  227. // Notify upwards because we're done now.
  228. const bluetooth::Uuid::UUID128Bit& attr_uuid = ch.uuid.To128BitBE();
  229. ssize_t status;
  230. OSI_NO_INTR(status = write(g_internal->pipefd[kPipeWriteEnd],
  231. attr_uuid.data(), attr_uuid.size()));
  232. if (-1 == status)
  233. LOG_ERROR(LOG_TAG, "%s: write failed: %s", __func__, strerror(errno));
  234. } else {
  235. // This is a multi-frame characteristic write.
  236. // Wait for an 'RequestExecWriteCallback' to notify completion.
  237. g_internal->last_write = ch.uuid;
  238. }
  239. // Respond only if needed.
  240. if (!need_rsp) return;
  241. btgatt_response_t response;
  242. response.attr_value.handle = attr_handle;
  243. response.attr_value.offset = attribute_offset;
  244. response.attr_value.len = value.size();
  245. response.attr_value.auth_req = 0;
  246. // Provide written data back to sender for the response.
  247. // Remote stacks use this to validate the success of the write.
  248. std::copy(value.begin(), value.end(), response.attr_value.value);
  249. g_internal->gatt->server->send_response(conn_id, trans_id, 0, response);
  250. }
  251. void RequestExecWriteCallback(int conn_id, int trans_id, const RawAddress& bda,
  252. int exec_write) {
  253. std::string addr(BtAddrString(&bda));
  254. LOG_INFO(LOG_TAG, "%s: connection:%d (%s:trans:%d) exec_write:%d", __func__,
  255. conn_id, addr.c_str(), trans_id, exec_write);
  256. // This 'response' data is unused for ExecWriteResponses.
  257. // It is only used to pass BlueDroid argument validation.
  258. btgatt_response_t response = {};
  259. g_internal->gatt->server->send_response(conn_id, trans_id, 0, response);
  260. if (!exec_write) return;
  261. std::lock_guard<std::mutex> lock(g_internal->lock);
  262. // Communicate the attribute Uuid as notification of a write update.
  263. const bluetooth::Uuid::UUID128Bit uuid = g_internal->last_write.To128BitBE();
  264. ssize_t status;
  265. OSI_NO_INTR(status = write(g_internal->pipefd[kPipeWriteEnd], uuid.data(),
  266. uuid.size()));
  267. if (-1 == status)
  268. LOG_ERROR(LOG_TAG, "%s: write failed: %s", __func__, strerror(errno));
  269. }
  270. void ConnectionCallback(int conn_id, int server_if, int connected,
  271. const RawAddress& bda) {
  272. std::string addr(BtAddrString(&bda));
  273. LOG_INFO(LOG_TAG, "%s: connection:%d server_if:%d connected:%d addr:%s",
  274. __func__, conn_id, server_if, connected, addr.c_str());
  275. if (connected == 1) {
  276. g_internal->connections.insert(conn_id);
  277. } else if (connected == 0) {
  278. g_internal->connections.erase(conn_id);
  279. }
  280. }
  281. void EnableAdvertisingCallback(uint8_t status) {
  282. LOG_INFO(LOG_TAG, "%s: status:%d", __func__, status);
  283. // This terminates a Start call.
  284. std::lock_guard<std::mutex> lock(g_internal->lock);
  285. g_internal->api_synchronize.notify_one();
  286. }
  287. void RegisterClientCallback(int status, int client_if,
  288. const bluetooth::Uuid& app_uuid) {
  289. LOG_INFO(LOG_TAG, "%s: status:%d client_if:%d uuid[0]:%s", __func__, status,
  290. client_if, app_uuid.ToString().c_str());
  291. g_internal->client_if = client_if;
  292. // Setup our advertisement. This has no callback.
  293. g_internal->gatt->advertiser->SetData(0 /* std_inst */, false,
  294. {/*TODO: put inverval 2,2 here*/},
  295. base::DoNothing());
  296. g_internal->gatt->advertiser->Enable(
  297. 0 /* std_inst */, true, base::Bind(&EnableAdvertisingCallback),
  298. 0 /* no duration */, 0 /* no maxExtAdvEvent*/, base::DoNothing());
  299. }
  300. void ServiceStoppedCallback(int status, int server_if, int srvc_handle) {
  301. LOG_INFO(LOG_TAG, "%s: status:%d server_if:%d srvc_handle:%d", __func__,
  302. status, server_if, srvc_handle);
  303. // This terminates a Stop call.
  304. // TODO(icoolidge): make this symmetric with start
  305. std::lock_guard<std::mutex> lock(g_internal->lock);
  306. g_internal->api_synchronize.notify_one();
  307. }
  308. void ScanResultCallback(uint16_t ble_evt_type, uint8_t addr_type,
  309. RawAddress* bda, uint8_t ble_primary_phy,
  310. uint8_t ble_secondary_phy, uint8_t ble_advertising_sid,
  311. int8_t ble_tx_power, int8_t rssi,
  312. uint16_t ble_periodic_adv_int,
  313. std::vector<uint8_t> adv_data) {
  314. std::string addr(BtAddrString(bda));
  315. std::lock_guard<std::mutex> lock(g_internal->lock);
  316. g_internal->scan_results[addr] = rssi;
  317. }
  318. void ClientConnectCallback(int conn_id, int status, int client_if,
  319. const RawAddress& bda) {
  320. std::string addr(BtAddrString(&bda));
  321. LOG_INFO(LOG_TAG, "%s: conn_id:%d status:%d client_if:%d %s", __func__,
  322. conn_id, status, client_if, addr.c_str());
  323. }
  324. void ClientDisconnectCallback(int conn_id, int status, int client_if,
  325. const RawAddress& bda) {
  326. std::string addr(BtAddrString(&bda));
  327. LOG_INFO(LOG_TAG, "%s: conn_id:%d status:%d client_if:%d %s", __func__,
  328. conn_id, status, client_if, addr.c_str());
  329. }
  330. void IndicationSentCallback(UNUSED_ATTR int conn_id, UNUSED_ATTR int status) {
  331. // TODO(icoolidge): what to do
  332. }
  333. void ResponseConfirmationCallback(UNUSED_ATTR int status,
  334. UNUSED_ATTR int handle) {
  335. // TODO(icoolidge): what to do
  336. }
  337. const btgatt_server_callbacks_t gatt_server_callbacks = {
  338. RegisterServerCallback,
  339. ConnectionCallback,
  340. ServiceAddedCallback,
  341. ServiceStoppedCallback,
  342. nullptr, /* service_deleted_cb */
  343. RequestReadCallback,
  344. RequestReadCallback,
  345. RequestWriteCallback,
  346. RequestWriteCallback,
  347. RequestExecWriteCallback,
  348. ResponseConfirmationCallback,
  349. IndicationSentCallback,
  350. nullptr, /* congestion_cb*/
  351. nullptr, /* mtu_changed_cb */
  352. nullptr, /* phy_update_cb */
  353. nullptr, /* conn_update_cb */
  354. };
  355. // TODO(eisenbach): Refactor GATT interface to not require servers
  356. // to refer to the client interface.
  357. const btgatt_client_callbacks_t gatt_client_callbacks = {
  358. RegisterClientCallback,
  359. ClientConnectCallback,
  360. ClientDisconnectCallback,
  361. nullptr, /* search_complete_cb; */
  362. nullptr, /* register_for_notification_cb; */
  363. nullptr, /* notify_cb; */
  364. nullptr, /* read_characteristic_cb; */
  365. nullptr, /* write_characteristic_cb; */
  366. nullptr, /* read_descriptor_cb; */
  367. nullptr, /* write_descriptor_cb; */
  368. nullptr, /* execute_write_cb; */
  369. nullptr, /* read_remote_rssi_cb; */
  370. nullptr, /* configure_mtu_cb; */
  371. nullptr, /* congestion_cb; */
  372. nullptr, /* get_gatt_db_cb; */
  373. nullptr, /* services_removed_cb */
  374. nullptr, /* services_added_cb */
  375. nullptr, /* phy_update_cb */
  376. nullptr, /* conn_update_cb */
  377. };
  378. const btgatt_scanner_callbacks_t gatt_scanner_callbacks = {
  379. ScanResultCallback,
  380. nullptr, /* batchscan_reports_cb; */
  381. nullptr, /* batchscan_threshold_cb; */
  382. nullptr, /* track_adv_event_cb; */
  383. };
  384. const btgatt_callbacks_t gatt_callbacks = {
  385. /** Set to sizeof(btgatt_callbacks_t) */
  386. sizeof(btgatt_callbacks_t),
  387. /** GATT Client callbacks */
  388. &gatt_client_callbacks,
  389. /** GATT Server callbacks */
  390. &gatt_server_callbacks,
  391. /** GATT Server callbacks */
  392. &gatt_scanner_callbacks,
  393. };
  394. } // namespace
  395. namespace bluetooth {
  396. namespace gatt {
  397. int ServerInternals::Initialize() {
  398. // Get the interface to the GATT profile.
  399. const bt_interface_t* bt_iface =
  400. hal::BluetoothInterface::Get()->GetHALInterface();
  401. gatt = reinterpret_cast<const btgatt_interface_t*>(
  402. bt_iface->get_profile_interface(BT_PROFILE_GATT_ID));
  403. if (!gatt) {
  404. LOG_ERROR(LOG_TAG, "Error getting GATT interface");
  405. return -1;
  406. }
  407. bt_status_t btstat = gatt->init(&gatt_callbacks);
  408. if (btstat != BT_STATUS_SUCCESS) {
  409. LOG_ERROR(LOG_TAG, "Failed to initialize gatt interface");
  410. return -1;
  411. }
  412. int status = pipe(pipefd);
  413. if (status == -1) {
  414. LOG_ERROR(LOG_TAG, "pipe creation failed: %s", strerror(errno));
  415. return -1;
  416. }
  417. return 0;
  418. }
  419. bt_status_t ServerInternals::AddCharacteristic(const Uuid& uuid,
  420. uint8_t properties,
  421. uint16_t permissions) {
  422. pending_svc_decl.push_back({.type = BTGATT_DB_CHARACTERISTIC,
  423. .uuid = uuid,
  424. .properties = properties,
  425. .permissions = permissions});
  426. return BT_STATUS_SUCCESS;
  427. }
  428. ServerInternals::ServerInternals()
  429. : gatt(nullptr),
  430. server_if(0),
  431. client_if(0),
  432. service_handle(0),
  433. pipefd{INVALID_FD, INVALID_FD} {}
  434. ServerInternals::~ServerInternals() {
  435. if (pipefd[0] != INVALID_FD) close(pipefd[0]);
  436. if (pipefd[1] != INVALID_FD) close(pipefd[1]);
  437. gatt->server->delete_service(server_if, service_handle);
  438. gatt->server->unregister_server(server_if);
  439. gatt->client->unregister_client(client_if);
  440. }
  441. Server::Server() : internal_(nullptr) {}
  442. Server::~Server() {}
  443. bool Server::Initialize(const Uuid& service_id, int* gatt_pipe) {
  444. internal_.reset(new ServerInternals);
  445. if (!internal_) {
  446. LOG_ERROR(LOG_TAG, "Error creating internals");
  447. return false;
  448. }
  449. g_internal = internal_.get();
  450. std::unique_lock<std::mutex> lock(internal_->lock);
  451. int status = internal_->Initialize();
  452. if (status) {
  453. LOG_ERROR(LOG_TAG, "Error initializing internals");
  454. return false;
  455. }
  456. bt_status_t btstat = internal_->gatt->server->register_server(service_id);
  457. if (btstat != BT_STATUS_SUCCESS) {
  458. LOG_ERROR(LOG_TAG, "Failed to register server");
  459. return false;
  460. }
  461. internal_->api_synchronize.wait(lock);
  462. // TODO(icoolidge): Better error handling.
  463. if (internal_->server_if == 0) {
  464. LOG_ERROR(LOG_TAG, "Initialization of server failed");
  465. return false;
  466. }
  467. *gatt_pipe = internal_->pipefd[kPipeReadEnd];
  468. LOG_INFO(LOG_TAG, "Server Initialize succeeded");
  469. return true;
  470. }
  471. bool Server::SetAdvertisement(const std::vector<Uuid>& ids,
  472. const std::vector<uint8_t>& service_data,
  473. const std::vector<uint8_t>& manufacturer_data,
  474. bool transmit_name) {
  475. // std::vector<uint8_t> id_data;
  476. // const auto& mutable_manufacturer_data = manufacturer_data;
  477. // const auto& mutable_service_data = service_data;
  478. // for (const Uuid &id : ids) {
  479. // const auto le_id = id.To128BitLE();
  480. // id_data.insert(id_data.end(), le_id.begin(), le_id.end());
  481. // }
  482. std::lock_guard<std::mutex> lock(internal_->lock);
  483. // Setup our advertisement. This has no callback.
  484. internal_->gatt->advertiser->SetData(0, false, /* beacon, not scan response */
  485. {}, base::DoNothing());
  486. // transmit_name, /* name */
  487. // 2, 2, interval
  488. // mutable_manufacturer_data,
  489. // mutable_service_data,
  490. // id_data);
  491. return true;
  492. }
  493. bool Server::SetScanResponse(const std::vector<Uuid>& ids,
  494. const std::vector<uint8_t>& service_data,
  495. const std::vector<uint8_t>& manufacturer_data,
  496. bool transmit_name) {
  497. // std::vector<uint8_t> id_data;
  498. // const auto& mutable_manufacturer_data = manufacturer_data;
  499. // const auto& mutable_service_data = service_data;
  500. // for (const Uuid &id : ids) {
  501. // const auto le_id = id.To128BitLE();
  502. // id_data.insert(id_data.end(), le_id.begin(), le_id.end());
  503. // }
  504. std::lock_guard<std::mutex> lock(internal_->lock);
  505. // Setup our advertisement. This has no callback.
  506. internal_->gatt->advertiser->SetData(0, true, /* scan response */
  507. {}, base::DoNothing());
  508. // transmit_name, /* name */
  509. // false, /* no txpower */
  510. // 2, 2, interval
  511. // 0, /* appearance */
  512. // mutable_manufacturer_data,
  513. // mutable_service_data,
  514. // id_data);
  515. return true;
  516. }
  517. bool Server::AddCharacteristic(const Uuid& id, int properties,
  518. int permissions) {
  519. std::unique_lock<std::mutex> lock(internal_->lock);
  520. bt_status_t btstat =
  521. internal_->AddCharacteristic(id, properties, permissions);
  522. if (btstat != BT_STATUS_SUCCESS) {
  523. LOG_ERROR(LOG_TAG, "Failed to add characteristic to service: 0x%04x",
  524. internal_->service_handle);
  525. return false;
  526. }
  527. internal_->api_synchronize.wait(lock);
  528. const int handle = internal_->uuid_to_attribute[id];
  529. internal_->characteristics[handle].notify = properties & kPropertyNotify;
  530. return true;
  531. }
  532. bool Server::AddBlob(const Uuid& id, const Uuid& control_id, int properties,
  533. int permissions) {
  534. std::unique_lock<std::mutex> lock(internal_->lock);
  535. // First, add the primary attribute (characteristic value)
  536. bt_status_t btstat =
  537. internal_->AddCharacteristic(id, properties, permissions);
  538. if (btstat != BT_STATUS_SUCCESS) {
  539. LOG_ERROR(LOG_TAG, "Failed to set scan response data");
  540. return false;
  541. }
  542. // Next, add the secondary attribute (blob control).
  543. // Control attributes have fixed permissions/properties.
  544. // Remember position at which blob was added.
  545. blob_index.insert(pending_svc_decl.size());
  546. btstat =
  547. internal_->AddCharacteristic(control_id, kPropertyRead | kPropertyWrite,
  548. kPermissionRead | kPermissionWrite);
  549. return true;
  550. }
  551. bool Server::Start() {
  552. std::unique_lock<std::mutex> lock(internal_->lock);
  553. bt_status_t btstat = internal_->gatt->server->add_service(
  554. internal_->server_if, pending_svc_decl);
  555. if (btstat != BT_STATUS_SUCCESS) {
  556. LOG_ERROR(LOG_TAG, "Failed to start service with handle: 0x%04x",
  557. internal_->service_handle);
  558. return false;
  559. }
  560. internal_->api_synchronize.wait(lock);
  561. return true;
  562. }
  563. bool Server::Stop() {
  564. std::unique_lock<std::mutex> lock(internal_->lock);
  565. bt_status_t btstat = internal_->gatt->server->stop_service(
  566. internal_->server_if, internal_->service_handle);
  567. if (btstat != BT_STATUS_SUCCESS) {
  568. LOG_ERROR(LOG_TAG, "Failed to stop service with handle: 0x%04x",
  569. internal_->service_handle);
  570. return false;
  571. }
  572. internal_->api_synchronize.wait(lock);
  573. return true;
  574. }
  575. bool Server::ScanEnable() {
  576. internal_->gatt->scanner->Scan(true);
  577. return true;
  578. }
  579. bool Server::ScanDisable() {
  580. internal_->gatt->scanner->Scan(false);
  581. return true;
  582. }
  583. bool Server::GetScanResults(ScanResults* results) {
  584. std::lock_guard<std::mutex> lock(internal_->lock);
  585. *results = internal_->scan_results;
  586. return true;
  587. }
  588. bool Server::SetCharacteristicValue(const Uuid& id,
  589. const std::vector<uint8_t>& value) {
  590. std::lock_guard<std::mutex> lock(internal_->lock);
  591. const int attribute_id = internal_->uuid_to_attribute[id];
  592. Characteristic& ch = internal_->characteristics[attribute_id];
  593. ch.next_blob = value;
  594. ch.next_blob_pending = true;
  595. if (!ch.notify) return true;
  596. for (auto connection : internal_->connections) {
  597. internal_->gatt->server->send_indication(internal_->server_if, attribute_id,
  598. connection, true, {0});
  599. }
  600. return true;
  601. }
  602. bool Server::GetCharacteristicValue(const Uuid& id,
  603. std::vector<uint8_t>* value) {
  604. std::lock_guard<std::mutex> lock(internal_->lock);
  605. const int attribute_id = internal_->uuid_to_attribute[id];
  606. *value = internal_->characteristics[attribute_id].blob;
  607. return true;
  608. }
  609. } // namespace gatt
  610. } // namespace bluetooth