OSDN Git Service

Add file write error checks to config_save am: fd2f03a2e0
[android-x86/system-bt.git] / service / adapter.cpp
1 //
2 //  Copyright (C) 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
17 #include "service/adapter.h"
18
19 #include <base/logging.h>
20
21 #include "service/logging_helpers.h"
22
23 namespace bluetooth {
24
25 // static
26 const char Adapter::kDefaultAddress[] = "00:00:00:00:00:00";
27 // static
28 const char Adapter::kDefaultName[] = "not-initialized";
29
30 // The minimum number of advertising instances required for multi-advertisement
31 // support.
32 //
33 // TODO(armansito): This number comes straight from
34 // packages/apps/Bluetooth/src/c/a/b/btservice/AdapterService.java. It would be
35 // nice to know if there were a way to obtain this number from the stack instead
36 // of hardcoding it here.
37 const char kMinAdvInstancesForMultiAdv = 5;
38
39 void Adapter::Observer::OnAdapterStateChanged(Adapter* adapter,
40                                               AdapterState prev_state,
41                                               AdapterState new_state) {
42   // Default implementation does nothing
43 }
44
45 Adapter::Adapter()
46     : state_(ADAPTER_STATE_OFF),
47       address_(kDefaultAddress),
48       name_(kDefaultName) {
49   memset(&local_le_features_, 0, sizeof(local_le_features_));
50   hal::BluetoothInterface::Get()->AddObserver(this);
51   ble_client_factory_.reset(new LowEnergyClientFactory());
52   gatt_client_factory_.reset(new GattClientFactory());
53   gatt_server_factory_.reset(new GattServerFactory());
54   hal::BluetoothInterface::Get()->GetHALInterface()->get_adapter_properties();
55 }
56
57 Adapter::~Adapter() {
58   hal::BluetoothInterface::Get()->RemoveObserver(this);
59 }
60
61 void Adapter::AddObserver(Observer* observer) {
62   std::lock_guard<std::mutex> lock(observers_lock_);
63   observers_.AddObserver(observer);
64 }
65
66 void Adapter::RemoveObserver(Observer* observer) {
67   std::lock_guard<std::mutex> lock(observers_lock_);
68   observers_.RemoveObserver(observer);
69 }
70
71 AdapterState Adapter::GetState() const {
72   return state_.load();
73 }
74
75 bool Adapter::IsEnabled() const {
76   return state_.load() == ADAPTER_STATE_ON;
77 }
78
79 bool Adapter::Enable() {
80   AdapterState current_state = GetState();
81   if (current_state != ADAPTER_STATE_OFF) {
82     LOG(INFO) << "Adapter not disabled - state: "
83               << AdapterStateToString(current_state);
84     return false;
85   }
86
87   // Set the state before calling enable() as there might be a race between here
88   // and the AdapterStateChangedCallback.
89   state_ = ADAPTER_STATE_TURNING_ON;
90   NotifyAdapterStateChanged(current_state, state_);
91
92   int status = hal::BluetoothInterface::Get()->GetHALInterface()->enable();
93   if (status != BT_STATUS_SUCCESS) {
94     LOG(ERROR) << "Failed to enable Bluetooth - status: "
95                << BtStatusText((const bt_status_t)status);
96     state_ = ADAPTER_STATE_OFF;
97     NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_ON, state_);
98     return false;
99   }
100
101   return true;
102 }
103
104 bool Adapter::Disable() {
105   if (!IsEnabled()) {
106     LOG(INFO) << "Adapter is not enabled";
107     return false;
108   }
109
110   AdapterState current_state = GetState();
111
112   // Set the state before calling enable() as there might be a race between here
113   // and the AdapterStateChangedCallback.
114   state_ = ADAPTER_STATE_TURNING_OFF;
115   NotifyAdapterStateChanged(current_state, state_);
116
117   int status = hal::BluetoothInterface::Get()->GetHALInterface()->disable();
118   if (status != BT_STATUS_SUCCESS) {
119     LOG(ERROR) << "Failed to disable Bluetooth - status: "
120                << BtStatusText((const bt_status_t)status);
121     state_ = current_state;
122     NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_OFF, state_);
123     return false;
124   }
125
126   return true;
127 }
128
129 std::string Adapter::GetName() const {
130   return name_.Get();
131 }
132
133 bool Adapter::SetName(const std::string& name) {
134   bt_bdname_t hal_name;
135   size_t max_name_len = sizeof(hal_name.name);
136
137   // Include the \0 byte in size measurement.
138   if (name.length() >= max_name_len) {
139     LOG(ERROR) << "Given name \"" << name << "\" is larger than maximum allowed"
140                << " size: " << max_name_len;
141     return false;
142   }
143
144   strncpy(reinterpret_cast<char*>(hal_name.name), name.c_str(),
145           name.length() + 1);
146
147   VLOG(1) << "Setting adapter name: " << name;
148
149   if (!SetAdapterProperty(BT_PROPERTY_BDNAME, &hal_name, sizeof(hal_name))) {
150     LOG(ERROR) << "Failed to set adapter name: " << name;
151     return false;
152   }
153
154   return true;
155 }
156
157 std::string Adapter::GetAddress() const {
158   return address_.Get();
159 }
160
161 bool Adapter::IsMultiAdvertisementSupported() const {
162   return local_le_features_.max_adv_instance >= kMinAdvInstancesForMultiAdv;
163 }
164
165 LowEnergyClientFactory* Adapter::GetLowEnergyClientFactory() const {
166   return ble_client_factory_.get();
167 }
168
169 GattClientFactory* Adapter::GetGattClientFactory() const {
170   return gatt_client_factory_.get();
171 }
172
173 GattServerFactory* Adapter::GetGattServerFactory() const {
174   return gatt_server_factory_.get();
175 }
176
177 void Adapter::AdapterStateChangedCallback(bt_state_t state) {
178   LOG(INFO) << "Adapter state changed: " << BtStateText(state);
179
180   AdapterState prev_state = GetState();
181
182   switch (state) {
183   case BT_STATE_OFF:
184     state_ = ADAPTER_STATE_OFF;
185     break;
186
187   case BT_STATE_ON:
188     state_ = ADAPTER_STATE_ON;
189     break;
190
191   default:
192     NOTREACHED();
193   }
194
195   NotifyAdapterStateChanged(prev_state, GetState());
196 }
197
198 void Adapter::AdapterPropertiesCallback(bt_status_t status,
199                                         int num_properties,
200                                         bt_property_t* properties) {
201   LOG(INFO) << "Adapter properties changed";
202
203   if (status != BT_STATUS_SUCCESS) {
204     LOG(ERROR) << "status: " << BtStatusText(status);
205     return;
206   }
207
208   for (int i = 0; i < num_properties; i++) {
209     bt_property_t* property = properties + i;
210     switch (property->type) {
211       case BT_PROPERTY_BDADDR: {
212         std::string address = BtAddrString(reinterpret_cast<bt_bdaddr_t*>(
213             property->val));
214         LOG(INFO) << "Adapter address changed: " << address;
215         address_.Set(address);
216         break;
217       }
218       case BT_PROPERTY_BDNAME: {
219         bt_bdname_t* hal_name = reinterpret_cast<bt_bdname_t*>(property->val);
220         std::string name = reinterpret_cast<char*>(hal_name->name);
221         LOG(INFO) << "Adapter name changed: " << name;
222         name_.Set(name);
223         break;
224       }
225       case BT_PROPERTY_LOCAL_LE_FEATURES: {
226         if (property->len != sizeof(bt_local_le_features_t)) {
227           LOG(WARNING) << "Malformed value received for property: "
228                        << "BT_PROPERTY_LOCAL_LE_FEATURES";
229           break;
230         }
231         bt_local_le_features_t* features =
232             reinterpret_cast<bt_local_le_features_t*>(property->val);
233         memcpy(&local_le_features_, features, sizeof(*features));
234         LOG(INFO) << "Supported LE features updated";
235         break;
236       }
237       default:
238         VLOG(1) << "Unhandled adapter property: "
239                 << BtPropertyText(property->type);
240         break;
241     }
242
243     // TODO(armansito): notify others of the updated properties
244   }
245 }
246
247 bool Adapter::SetAdapterProperty(bt_property_type_t type,
248                                  void* value, int length) {
249   CHECK(length > 0);
250   CHECK(value);
251
252   bt_property_t property;
253   property.len = length;
254   property.val = value;
255   property.type = type;
256
257   int status = hal::BluetoothInterface::Get()->GetHALInterface()->
258       set_adapter_property(&property);
259   if (status != BT_STATUS_SUCCESS) {
260     VLOG(1) << "Failed to set property";
261     return false;
262   }
263
264   return true;
265 }
266
267 void Adapter::NotifyAdapterStateChanged(AdapterState prev_state,
268                                         AdapterState new_state) {
269   if (prev_state == new_state)
270     return;
271
272   std::lock_guard<std::mutex> lock(observers_lock_);
273   FOR_EACH_OBSERVER(Observer, observers_,
274                     OnAdapterStateChanged(this, prev_state, new_state));
275 }
276
277 }  // namespace bluetooth