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/common/bluetooth/binder/IBluetoothGattServer.h"
18
19#include <base/logging.h>
20#include <binder/Parcel.h>
21
22#include "service/common/bluetooth/binder/parcel_helpers.h"
23
24using android::IBinder;
25using android::interface_cast;
26using android::Parcel;
27using android::sp;
28using android::status_t;
29
30namespace ipc {
31namespace binder {
32
33// static
34const char IBluetoothGattServer::kServiceName[] =
35    "bluetooth-gatt-server-service";
36
37// BnBluetoothGattServer (server) implementation
38// ========================================================
39
40status_t BnBluetoothGattServer::onTransact(
41    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
42  VLOG(2) << "IBluetoothGattServer: " << code;
43  if (!data.checkInterface(this))
44    return android::PERMISSION_DENIED;
45
46  switch (code) {
47  case REGISTER_SERVER_TRANSACTION: {
48    sp<IBinder> callback = data.readStrongBinder();
49    bool result = RegisterServer(
50        interface_cast<IBluetoothGattServerCallback>(callback));
51    reply->writeInt32(result);
52    return android::NO_ERROR;
53  }
54  case UNREGISTER_SERVER_TRANSACTION: {
55    int server_if = data.readInt32();
56    UnregisterServer(server_if);
57    return android::NO_ERROR;
58  }
59  case UNREGISTER_ALL_TRANSACTION: {
60    UnregisterAll();
61    return android::NO_ERROR;
62  }
63  case BEGIN_SERVICE_DECLARATION_TRANSACTION: {
64    int server_if = data.readInt32();
65    bool is_primary = data.readInt32();
66    auto uuid = CreateUUIDFromParcel(data);
67    CHECK(uuid);
68
69    std::unique_ptr<bluetooth::GattIdentifier> out_id;
70    bool result = BeginServiceDeclaration(
71        server_if, is_primary, *uuid, &out_id);
72
73    reply->writeInt32(result);
74
75    if (result) {
76      CHECK(out_id);
77      WriteGattIdentifierToParcel(*out_id, reply);
78    }
79
80    return android::NO_ERROR;
81  }
82  case ADD_CHARACTERISTIC_TRANSACTION: {
83    int server_if = data.readInt32();
84    auto uuid = CreateUUIDFromParcel(data);
85    CHECK(uuid);
86    int properties = data.readInt32();
87    int permissions = data.readInt32();
88
89    std::unique_ptr<bluetooth::GattIdentifier> out_id;
90    bool result = AddCharacteristic(
91        server_if, *uuid, properties, permissions, &out_id);
92
93    reply->writeInt32(result);
94
95    if (result) {
96      CHECK(out_id);
97      WriteGattIdentifierToParcel(*out_id, reply);
98    }
99
100    return android::NO_ERROR;
101  }
102  case ADD_DESCRIPTOR_TRANSACTION: {
103    int server_if = data.readInt32();
104    auto uuid = CreateUUIDFromParcel(data);
105    CHECK(uuid);
106    int permissions = data.readInt32();
107
108    std::unique_ptr<bluetooth::GattIdentifier> out_id;
109    bool result = AddDescriptor(server_if, *uuid, permissions, &out_id);
110
111    reply->writeInt32(result);
112
113    if (result) {
114      CHECK(out_id);
115      WriteGattIdentifierToParcel(*out_id, reply);
116    }
117
118    return android::NO_ERROR;
119  }
120  case END_SERVICE_DECLARATION_TRANSACTION: {
121    int server_if = data.readInt32();
122    bool result = EndServiceDeclaration(server_if);
123    reply->writeInt32(result);
124    return android::NO_ERROR;
125  }
126  case SEND_RESPONSE_TRANSACTION: {
127    int server_if = data.readInt32();
128    std::string device_address = data.readCString();
129    int request_id = data.readInt32();
130    int status = data.readInt32();
131    int offset = data.readInt32();
132
133    std::unique_ptr<std::vector<uint8_t>> value;
134    data.readByteVector(&value);
135    CHECK(value.get());
136
137    bool result = SendResponse(
138        server_if, device_address, request_id, status, offset, *value);
139
140    reply->writeInt32(result);
141
142    return android::NO_ERROR;
143  }
144  case SEND_NOTIFICATION_TRANSACTION: {
145    int server_if = data.readInt32();
146    std::string device_address = data.readCString();
147    auto char_id = CreateGattIdentifierFromParcel(data);
148    CHECK(char_id);
149    bool confirm = data.readInt32();
150
151    std::unique_ptr<std::vector<uint8_t>> value;
152    data.readByteVector(&value);
153    CHECK(value.get());
154
155    bool result = SendNotification(server_if, device_address, *char_id, confirm,
156                                   *value);
157
158    reply->writeInt32(result);
159
160    return android::NO_ERROR;
161  }
162  default:
163    return BBinder::onTransact(code, data, reply, flags);
164  }
165}
166
167// BpBluetoothGattServer (client) implementation
168// ========================================================
169
170BpBluetoothGattServer::BpBluetoothGattServer(const sp<IBinder>& impl)
171    : BpInterface<IBluetoothGattServer>(impl) {
172}
173
174bool BpBluetoothGattServer::RegisterServer(
175    const sp<IBluetoothGattServerCallback>& callback) {
176  Parcel data, reply;
177
178  data.writeInterfaceToken(IBluetoothGattServer::getInterfaceDescriptor());
179  data.writeStrongBinder(IInterface::asBinder(callback.get()));
180
181  remote()->transact(IBluetoothGattServer::REGISTER_SERVER_TRANSACTION,
182                     data, &reply);
183
184  return reply.readInt32();
185}
186
187void BpBluetoothGattServer::UnregisterServer(int server_if) {
188  Parcel data, reply;
189
190  data.writeInterfaceToken(IBluetoothGattServer::getInterfaceDescriptor());
191  data.writeInt32(server_if);
192
193  remote()->transact(IBluetoothGattServer::UNREGISTER_SERVER_TRANSACTION,
194                     data, &reply);
195}
196
197void BpBluetoothGattServer::UnregisterAll() {
198  Parcel data, reply;
199
200  data.writeInterfaceToken(IBluetoothGattServer::getInterfaceDescriptor());
201
202  remote()->transact(IBluetoothGattServer::UNREGISTER_ALL_TRANSACTION,
203                     data, &reply);
204}
205
206bool BpBluetoothGattServer::BeginServiceDeclaration(
207    int server_if, bool is_primary, const bluetooth::UUID& uuid,
208    std::unique_ptr<bluetooth::GattIdentifier>* out_id) {
209  CHECK(out_id);
210  Parcel data, reply;
211
212  data.writeInterfaceToken(IBluetoothGattServer::getInterfaceDescriptor());
213  data.writeInt32(server_if);
214  data.writeInt32(is_primary);
215  WriteUUIDToParcel(uuid, &data);
216
217  remote()->transact(
218      IBluetoothGattServer::BEGIN_SERVICE_DECLARATION_TRANSACTION,
219      data, &reply);
220
221  bool result = reply.readInt32();
222  if (result)
223    *out_id = CreateGattIdentifierFromParcel(reply);
224
225  return result;
226}
227
228bool BpBluetoothGattServer::AddCharacteristic(
229    int server_if, const bluetooth::UUID& uuid,
230    int properties, int permissions,
231    std::unique_ptr<bluetooth::GattIdentifier>* out_id) {
232  CHECK(out_id);
233  Parcel data, reply;
234
235  data.writeInterfaceToken(IBluetoothGattServer::getInterfaceDescriptor());
236  data.writeInt32(server_if);
237  WriteUUIDToParcel(uuid, &data);
238  data.writeInt32(properties);
239  data.writeInt32(permissions);
240
241  remote()->transact(IBluetoothGattServer::ADD_CHARACTERISTIC_TRANSACTION,
242                     data, &reply);
243
244  bool result = reply.readInt32();
245  if (result)
246    *out_id = CreateGattIdentifierFromParcel(reply);
247
248  return result;
249}
250
251bool BpBluetoothGattServer::AddDescriptor(
252    int server_if, const bluetooth::UUID& uuid, int permissions,
253    std::unique_ptr<bluetooth::GattIdentifier>* out_id) {
254  CHECK(out_id);
255  Parcel data, reply;
256
257  data.writeInterfaceToken(IBluetoothGattServer::getInterfaceDescriptor());
258  data.writeInt32(server_if);
259  WriteUUIDToParcel(uuid, &data);
260  data.writeInt32(permissions);
261
262  remote()->transact(IBluetoothGattServer::ADD_DESCRIPTOR_TRANSACTION,
263                     data, &reply);
264
265  bool result = reply.readInt32();
266  if (result)
267    *out_id = CreateGattIdentifierFromParcel(reply);
268
269  return result;
270}
271
272bool BpBluetoothGattServer::EndServiceDeclaration(int server_if) {
273  Parcel data, reply;
274
275  data.writeInterfaceToken(IBluetoothGattServer::getInterfaceDescriptor());
276  data.writeInt32(server_if);
277
278  remote()->transact(IBluetoothGattServer::END_SERVICE_DECLARATION_TRANSACTION,
279                     data, &reply);
280
281  return reply.readInt32();
282}
283
284bool BpBluetoothGattServer::SendResponse(
285    int server_if,
286    const std::string& device_address,
287    int request_id,
288    int status, int offset,
289    const std::vector<uint8_t>& value) {
290  Parcel data, reply;
291
292  data.writeInterfaceToken(IBluetoothGattServer::getInterfaceDescriptor());
293  data.writeInt32(server_if);
294  data.writeCString(device_address.c_str());
295  data.writeInt32(request_id);
296  data.writeInt32(status);
297  data.writeInt32(offset);
298  data.writeByteVector(value);
299
300  remote()->transact(IBluetoothGattServer::SEND_RESPONSE_TRANSACTION,
301                     data, &reply);
302
303  return reply.readInt32();
304}
305
306bool BpBluetoothGattServer::SendNotification(
307    int server_if,
308    const std::string& device_address,
309    const bluetooth::GattIdentifier& characteristic_id,
310    bool confirm,
311    const std::vector<uint8_t>& value) {
312  Parcel data, reply;
313
314  data.writeInterfaceToken(IBluetoothGattServer::getInterfaceDescriptor());
315  data.writeInt32(server_if);
316  data.writeCString(device_address.c_str());
317  WriteGattIdentifierToParcel(characteristic_id, &data);
318  data.writeInt32(confirm);
319  data.writeByteVector(value);
320
321  remote()->transact(IBluetoothGattServer::SEND_NOTIFICATION_TRANSACTION,
322                     data, &reply);
323
324  return reply.readInt32();
325}
326
327IMPLEMENT_META_INTERFACE(BluetoothGattServer,
328                         IBluetoothGattServer::kServiceName);
329
330}  // namespace binder
331}  // namespace ipc
332