[Bluetooth] Clear all GATT data after unregistering all services
[platform/core/api/webapi-plugins.git] / src / bluetooth / bluetooth_gatt_server.cc
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
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
17 #include "bluetooth/bluetooth_gatt_server.h"
18 #include "bluetooth/bluetooth_instance.h"
19 #include "bluetooth/bluetooth_util.h"
20
21 #include "common/logger.h"
22 #include "common/tools.h"
23
24 using namespace extension::bluetooth::util;
25 using namespace common;
26 using namespace common::tools;
27
28 namespace extension {
29 namespace bluetooth {
30
31 BluetoothGATTServer::BluetoothGATTServer(BluetoothInstance& instance,
32                                          BluetoothGATTServerService& service)
33     : instance_{instance},
34       service_{service},
35       initialized_{false},
36       running_{false},
37       handle_{nullptr},
38       power_state_change_callback_id_{-1} {
39   ScopeLogger();
40
41   power_state_change_callback_id_ =
42       instance_.GetBluetoothAdapter().AddPowerStateListener([this](const int state) {
43         ScopeLogger("BluetoothGATTServer PowerStateListenerCallback: %d", state);
44         if ((false == state) && (true == running_)) {
45           UnregisterAllServicesImpl();
46           DestroyAllGATTObjects();
47           Deinitialize();
48           PowerStateChangeCb(false);
49           SetRunningState(false);
50         }
51       });
52 }
53
54 BluetoothGATTServer::~BluetoothGATTServer() {
55   ScopeLogger();
56
57   instance_.GetBluetoothAdapter().RemovePowerStateListener(power_state_change_callback_id_);
58   UnregisterAllServicesImpl();
59   DestroyAllGATTObjects();
60   Deinitialize();
61 }
62
63 void BluetoothGATTServer::Start(picojson::object& out) {
64   ScopeLogger();
65
66   if (running_) {
67     LoggerD("Server is running");
68     ReportSuccess(out);
69     return;
70   }
71
72   if (!initialized_) {
73     /*
74      * Server is initialized when its services are registered.
75      * However, the case when server is uninitialized until start is
76      * also valid. It happens, when user doesn't register any services
77      * and starts the server with the default ones.
78      */
79     auto result = InitializeAndCreateHandle();
80     if (!result) {
81       result.SetMessage("Couldn't start GATT server");
82       ReportError(result, &out);
83       return;
84     }
85   }
86
87   auto ret = bt_gatt_server_start();
88   if (BT_ERROR_NONE != ret) {
89     LoggerE("bt_gatt_server_start(): %d (%s)", ret, get_error_message(ret));
90     ReportError(BluetoothErrorToPlatformResult(ret, "Couldn't start GATT server"), &out);
91     return;
92   }
93   LoggerD("bt_gatt_server_start(): success");
94
95   SetRunningState(true);
96   ReportSuccess(out);
97 }
98
99 void BluetoothGATTServer::Stop(picojson::object& out) {
100   ScopeLogger();
101
102   if (!running_) {
103     LoggerD("Server is not running");
104     ReportSuccess(out);
105     return;
106   }
107
108   // Unregistering all services should not fail.
109   // Even if it does we just let UnregisterAllSerivcesImpl() log the error
110   // and proceed with server destruction.
111   UnregisterAllServicesImpl();
112
113   // DestroyAllGATTObjects() should not fail
114   // If it does, it logs the error message.
115   DestroyAllGATTObjects();
116
117   // Deinitialize() is the function that actually stops the server,
118   // thus we return the result, it returns.
119   auto result = Deinitialize();
120   if (!result) {
121     result.SetMessage("Couldn't stop GATT server");
122     ReportError(result, &out);
123   } else {
124     ReportSuccess(out);
125     SetRunningState(false);
126   }
127 }
128
129 void BluetoothGATTServer::GetConnectionMtu(const picojson::value& args, picojson::object& out) {
130   ScopeLogger();
131
132   const auto client_address = args.get("clientAddress").get<std::string>();
133
134   unsigned int mtu = 0;
135   auto ret = bt_gatt_server_get_device_mtu(client_address.c_str(), &mtu);
136   if (BT_ERROR_NONE != ret) {
137     LoggerE("bt_gatt_server_get_device_mtu(): %d (%s)", ret, get_error_message(ret));
138     ReportError(BluetoothErrorToPlatformResult(ret), &out);
139   }
140   LoggerD("bt_gatt_server_get_device_mtu(): success, MTU: %u", mtu);
141
142   ReportSuccess(picojson::value{static_cast<double>(mtu)}, out);
143 }
144
145 void BluetoothGATTServer::RegisterService(const picojson::value& args, picojson::object& out) {
146   ScopeLogger();
147
148   bt_gatt_h service_handle = nullptr;
149
150   /*
151    * Each successfully created GATT{Service, Characteristic, Descriptor} has a
152    * corresponding entry in service_.gatt_objects, mapping its _id field of its JS
153    * object to its bt_gatt_h handle.
154    * new_gatt_objects is a container for the entries, that are added to
155    * service_.gatt_objects if both CreateService() and RegisterService()
156    * succeed.
157    * Otherwise, the service is not registered and the map is not updated.
158    */
159   std::vector<std::pair<int, bt_gatt_h>> new_gatt_objects;
160   auto result = service_.CreateService(args, &service_handle, new_gatt_objects);
161   if (result.IsError()) {
162     ReportError(result, &out);
163     return;
164   }
165
166   if (!initialized_) {
167     /*
168      * Server is initialized when its services are registered.
169      * However, the case when server is uninitialized until start is
170      * also valid. It happens, when user doesn't register any services
171      * and starts the server with the default ones.
172      */
173     auto result = InitializeAndCreateHandle();
174     if (!result) {
175       result.SetMessage("Couldn't register the service");
176       ReportError(result, &out);
177       return;
178     }
179   }
180
181   result = service_.RegisterService(service_handle, this->handle_, new_gatt_objects);
182   if (result.IsError()) {
183     ReportError(result, &out);
184     return;
185   }
186
187   ReportSuccess(out);
188 }
189
190 void BluetoothGATTServer::UnregisterService(const picojson::value& args, picojson::object& out) {
191   ScopeLogger();
192
193   auto result = service_.UnregisterService(args, handle_);
194
195   if (result.IsError()) {
196     ReportError(result, &out);
197     return;
198   }
199
200   ReportSuccess(out);
201 }
202
203 void BluetoothGATTServer::SetReadValueRequestCallback(const picojson::value& args,
204                                                       picojson::object& out) {
205   ScopeLogger();
206
207   auto result = service_.SetReadValueRequestCallback(args);
208
209   if (result.IsError()) {
210     ReportError(result, &out);
211     return;
212   }
213
214   ReportSuccess(out);
215 }
216
217 void BluetoothGATTServer::SetWriteValueRequestCallback(const picojson::value& args,
218                                                        picojson::object& out) {
219   ScopeLogger();
220
221   auto result = service_.SetWriteValueRequestCallback(args);
222
223   if (result.IsError()) {
224     ReportError(result, &out);
225     return;
226   }
227
228   ReportSuccess(out);
229 }
230
231 void BluetoothGATTServer::SendResponse(const picojson::value& args, picojson::object& out) {
232   ScopeLogger();
233
234   auto result = service_.SendResponse(args);
235
236   if (result.IsError()) {
237     ReportError(result, &out);
238     return;
239   }
240
241   ReportSuccess(out);
242 }
243
244 bool BluetoothGATTServer::IsRunning() {
245   return running_;
246 }
247
248 void BluetoothGATTServer::NotifyAboutValueChange(const picojson::value& args,
249                                                  picojson::object& out) {
250   ScopeLogger();
251
252   if (!initialized_) {
253     LoggerE("Server not started");
254     ReportError(common::PlatformResult{common::ErrorCode::ABORT_ERR, "Server not started"}, &out);
255     return;
256   }
257
258   auto result = service_.NotifyAboutValueChange(args);
259   if (result.IsError()) {
260     ReportError(result, &out);
261     return;
262   }
263
264   ReportSuccess(out);
265 }
266
267 PlatformResult BluetoothGATTServer::Initialize() {
268   ScopeLogger();
269
270   auto ret = bt_gatt_server_initialize();
271   if (BT_ERROR_NONE != ret) {
272     LoggerE("bt_gatt_server_initialize(): %d (%s)", ret, get_error_message(ret));
273     return BluetoothErrorToPlatformResult(ret);
274   }
275   LoggerD("bt_gatt_server_initialize(): success");
276   initialized_ = true;
277
278   return PlatformResult{};
279 }
280
281 PlatformResult BluetoothGATTServer::CreateHandle() {
282   ScopeLogger();
283
284   if (handle_) {
285     LoggerE("Server handle is already created");
286     return PlatformResult{ErrorCode::INVALID_STATE_ERR};
287   }
288
289   auto ret = bt_gatt_server_create(&handle_);
290   if (BT_ERROR_NONE != ret) {
291     LoggerE("bt_gatt_server_create(): %d (%s)", ret, get_error_message(ret));
292   } else {
293     LoggerD("bt_gatt_server_create(): success");
294   }
295
296   return BluetoothErrorToPlatformResult(ret);
297 }
298
299 PlatformResult BluetoothGATTServer::Deinitialize() {
300   ScopeLogger();
301
302   if (!initialized_) {
303     LoggerE("Server is not initialized");
304     return PlatformResult{ErrorCode::INVALID_STATE_ERR};
305   }
306
307   auto ret = bt_gatt_server_deinitialize();
308   if (BT_ERROR_NONE != ret) {
309     LoggerE("bt_gatt_server_deinitialize(): %d (%s)", ret, get_error_message(ret));
310     return BluetoothErrorToPlatformResult(ret);
311   }
312
313   LoggerD("bt_gatt_server_deinitialize(): success");
314   initialized_ = false;
315
316   /*
317    * Undocumented behavior of native API: bt_gatt_server_deinitialize() calls
318    * bt_gatt_server_destroy() - after Deinitialize() bt_gatt_server_destroy()
319    * should not be called (a call results in a BT_INVALID_STATE_ERROR).
320    * handle_ is to be nullified, as it is no longer valid.
321    */
322   handle_ = nullptr;
323
324   return PlatformResult{};
325 }
326
327 PlatformResult BluetoothGATTServer::InitializeAndCreateHandle() {
328   ScopeLogger();
329
330   auto result = Initialize();
331   if (!result) {
332     return result;
333   }
334
335   result = CreateHandle();
336   if (!result) {
337     Deinitialize();
338   }
339   return result;
340 }
341
342 PlatformResult BluetoothGATTServer::UnregisterAllServicesImpl() {
343   ScopeLogger();
344
345   if (!handle_) {
346     LoggerE("Server handle is a nullptr");
347     return PlatformResult{ErrorCode::INVALID_STATE_ERR};
348   }
349
350   service_.ClearGATTData();
351
352   auto ret = bt_gatt_server_unregister_all_services(handle_);
353   if (BT_ERROR_NONE != ret) {
354     LoggerE("bt_gatt_server_unregister_all_services(): %d (%s)", ret, get_error_message(ret));
355     return BluetoothErrorToPlatformResult(ret);
356   } else {
357     LoggerD("bt_gatt_server_unregister_all_services(): success");
358     return PlatformResult{};
359   }
360 }
361
362 PlatformResult BluetoothGATTServer::DestroyAllGATTObjects() {
363   ScopeLogger();
364
365   if (!handle_) {
366     LoggerE("Server handle is a nullptr");
367     return PlatformResult{ErrorCode::INVALID_STATE_ERR};
368   }
369
370   auto ret = bt_gatt_server_foreach_services(handle_, DestroyService, nullptr);
371   if (BT_ERROR_NONE != ret) {
372     LoggerE("bt_gatt_server_unregister_all_services(): %d (%s)", ret, get_error_message(ret));
373     return BluetoothErrorToPlatformResult(ret);
374   } else {
375     LoggerD("bt_gatt_server_unregister_all_services(): success");
376     return PlatformResult{};
377   }
378
379   /*
380    * TODO: remove handles from service id -> service handle map
381    */
382 }
383
384 bool BluetoothGATTServer::DestroyService(int total, int index, bt_gatt_h handle, void* user_data) {
385   ScopeLogger("total: %d, index: %d, handle: %p", total, index, handle);
386
387   auto ret = bt_gatt_service_foreach_included_services(handle, DestroyService, nullptr);
388   if (BT_ERROR_NONE != ret) {
389     LoggerE("bt_gatt_service_foreach_included_servics(): %d (%s)", ret, get_error_message(ret));
390   }
391   LoggerD("bt_gatt_service_foreach_included_servics(): success");
392
393   ret = bt_gatt_service_foreach_characteristics(handle, DestroyCharacteristic, nullptr);
394   if (BT_ERROR_NONE != ret) {
395     LoggerE("bt_gatt_service_foreach_characteristics(): %d (%s)", ret, get_error_message(ret));
396   }
397   LoggerD("bt_gatt_service_foreach_characteristics(): success");
398
399   ret = bt_gatt_service_destroy(handle);
400   if (BT_ERROR_NONE != ret) {
401     LoggerE("bt_gatt_service_destroy(): %d (%s)", ret, get_error_message(ret));
402   }
403
404   return true;
405 }
406
407 bool BluetoothGATTServer::DestroyCharacteristic(int total, int index, bt_gatt_h handle,
408                                                 void* user_data) {
409   ScopeLogger("total: %d, index: %d, handle: %p", total, index, handle);
410
411   auto ret = bt_gatt_characteristic_foreach_descriptors(handle, DestroyDescriptor, nullptr);
412   if (BT_ERROR_NONE != ret) {
413     LoggerE("bt_gatt_characteristic_foreach_descriptors(): %d (%s)", ret, get_error_message(ret));
414   }
415   LoggerD("bt_gatt_characteristic_foreach_descriptors(): success");
416
417   ret = bt_gatt_characteristic_destroy(handle);
418   if (BT_ERROR_NONE != ret) {
419     LoggerE("bt_gatt_characteristic_destroy(): %d (%s)", ret, get_error_message(ret));
420   }
421
422   return true;
423 }
424
425 bool BluetoothGATTServer::DestroyDescriptor(int total, int index, bt_gatt_h handle,
426                                             void* user_data) {
427   ScopeLogger("total: %d, index: %d, handle: %p", total, index, handle);
428
429   auto ret = bt_gatt_descriptor_destroy(handle);
430   if (BT_ERROR_NONE != ret) {
431     LoggerE("bt_gatt_descriptor_destroy(): %d (%s)", ret, get_error_message(ret));
432   }
433   return true;
434 }
435
436 void BluetoothGATTServer::PowerStateChangeCb(bool state) {
437   ScopeLogger();
438   picojson::value result{picojson::object{}};
439   auto& obj = result.get<picojson::object>();
440
441   obj.insert(
442       std::make_pair("listenerId", "BluetoothGattServerBluetoothAdapterStateChangeListener"));
443   obj.insert(std::make_pair("state", picojson::value(state)));
444
445   Instance::PostMessage(&instance_, result.serialize().c_str());
446 }
447
448 void BluetoothGATTServer::SetRunningState(bool state) {
449   ScopeLogger();
450   if (state != running_) {
451     LoggerD("Changing GATTServer running state to: %s", state ? "start" : "stop");
452     running_ = state;
453     picojson::value result{picojson::object{}};
454     auto& obj = result.get<picojson::object>();
455
456     obj.insert(std::make_pair("listenerId", "BluetoothGattServerIsRunningChangeListener"));
457     obj.insert(std::make_pair("state", picojson::value(running_)));
458
459     Instance::PostMessage(&instance_, result.serialize().c_str());
460   }
461 }
462
463 }  // namespace bluetooth
464 }  // namespace extension