1 /*
2  * Copyright (C) 2013 The Android Open Source Project
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 #define LOG_TAG "BtGatt.JNI"
18 
19 #define LOG_NDEBUG 0
20 
21 #include "com_android_bluetooth.h"
22 #include "hardware/bt_gatt.h"
23 #include "utils/Log.h"
24 
25 #include <base/bind.h>
26 #include <base/callback.h>
27 #include <string.h>
28 #include <array>
29 #include <memory>
30 
31 #include <cutils/log.h>
32 #define info(fmt, ...) ALOGI("%s(L%d): " fmt, __func__, __LINE__, ##__VA_ARGS__)
33 #define debug(fmt, ...) \
34   ALOGD("%s(L%d): " fmt, __func__, __LINE__, ##__VA_ARGS__)
35 #define warn(fmt, ...) \
36   ALOGW("WARNING: %s(L%d): " fmt "##", __func__, __LINE__, ##__VA_ARGS__)
37 #define error(fmt, ...) \
38   ALOGE("ERROR: %s(L%d): " fmt "##", __func__, __LINE__, ##__VA_ARGS__)
39 #define asrt(s) \
40   if (!(s)) ALOGE("%s(L%d): ASSERT %s failed! ##", __func__, __LINE__, #s)
41 
42 using bluetooth::Uuid;
43 
44 #define UUID_PARAMS(uuid) uuid_lsb(uuid), uuid_msb(uuid)
45 
from_java_uuid(jlong uuid_msb,jlong uuid_lsb)46 static Uuid from_java_uuid(jlong uuid_msb, jlong uuid_lsb) {
47   std::array<uint8_t, Uuid::kNumBytes128> uu;
48   for (int i = 0; i < 8; i++) {
49     uu[7 - i] = (uuid_msb >> (8 * i)) & 0xFF;
50     uu[15 - i] = (uuid_lsb >> (8 * i)) & 0xFF;
51   }
52   return Uuid::From128BitBE(uu);
53 }
54 
uuid_lsb(const Uuid & uuid)55 static uint64_t uuid_lsb(const Uuid& uuid) {
56   uint64_t lsb = 0;
57 
58   auto uu = uuid.To128BitBE();
59   for (int i = 8; i <= 15; i++) {
60     lsb <<= 8;
61     lsb |= uu[i];
62   }
63 
64   return lsb;
65 }
66 
uuid_msb(const Uuid & uuid)67 static uint64_t uuid_msb(const Uuid& uuid) {
68   uint64_t msb = 0;
69 
70   auto uu = uuid.To128BitBE();
71   for (int i = 0; i <= 7; i++) {
72     msb <<= 8;
73     msb |= uu[i];
74   }
75 
76   return msb;
77 }
78 
str2addr(JNIEnv * env,jstring address)79 static RawAddress str2addr(JNIEnv* env, jstring address) {
80   RawAddress bd_addr;
81   const char* c_address = env->GetStringUTFChars(address, NULL);
82   if (!c_address) return bd_addr;
83 
84   RawAddress::FromString(std::string(c_address), bd_addr);
85   env->ReleaseStringUTFChars(address, c_address);
86 
87   return bd_addr;
88 }
89 
bdaddr2newjstr(JNIEnv * env,const RawAddress * bda)90 static jstring bdaddr2newjstr(JNIEnv* env, const RawAddress* bda) {
91   char c_address[32];
92   snprintf(c_address, sizeof(c_address), "%02X:%02X:%02X:%02X:%02X:%02X",
93            bda->address[0], bda->address[1], bda->address[2], bda->address[3],
94            bda->address[4], bda->address[5]);
95 
96   return env->NewStringUTF(c_address);
97 }
98 
toVector(JNIEnv * env,jbyteArray ba)99 static std::vector<uint8_t> toVector(JNIEnv* env, jbyteArray ba) {
100   jbyte* data_data = env->GetByteArrayElements(ba, NULL);
101   uint16_t data_len = (uint16_t)env->GetArrayLength(ba);
102   std::vector<uint8_t> data_vec(data_data, data_data + data_len);
103   env->ReleaseByteArrayElements(ba, data_data, JNI_ABORT);
104   return data_vec;
105 }
106 
107 namespace android {
108 
109 /**
110  * Client callback methods
111  */
112 
113 static jmethodID method_onClientRegistered;
114 static jmethodID method_onScannerRegistered;
115 static jmethodID method_onScanResult;
116 static jmethodID method_onConnected;
117 static jmethodID method_onDisconnected;
118 static jmethodID method_onReadCharacteristic;
119 static jmethodID method_onWriteCharacteristic;
120 static jmethodID method_onExecuteCompleted;
121 static jmethodID method_onSearchCompleted;
122 static jmethodID method_onReadDescriptor;
123 static jmethodID method_onWriteDescriptor;
124 static jmethodID method_onNotify;
125 static jmethodID method_onRegisterForNotifications;
126 static jmethodID method_onReadRemoteRssi;
127 static jmethodID method_onConfigureMTU;
128 static jmethodID method_onScanFilterConfig;
129 static jmethodID method_onScanFilterParamsConfigured;
130 static jmethodID method_onScanFilterEnableDisabled;
131 static jmethodID method_onClientCongestion;
132 static jmethodID method_onBatchScanStorageConfigured;
133 static jmethodID method_onBatchScanStartStopped;
134 static jmethodID method_onBatchScanReports;
135 static jmethodID method_onBatchScanThresholdCrossed;
136 
137 static jmethodID method_createOnTrackAdvFoundLostObject;
138 static jmethodID method_onTrackAdvFoundLost;
139 static jmethodID method_onScanParamSetupCompleted;
140 static jmethodID method_getSampleGattDbElement;
141 static jmethodID method_onGetGattDb;
142 static jmethodID method_onClientPhyUpdate;
143 static jmethodID method_onClientPhyRead;
144 static jmethodID method_onClientConnUpdate;
145 
146 /**
147  * Server callback methods
148  */
149 static jmethodID method_onServerRegistered;
150 static jmethodID method_onClientConnected;
151 static jmethodID method_onServiceAdded;
152 static jmethodID method_onServiceStopped;
153 static jmethodID method_onServiceDeleted;
154 static jmethodID method_onResponseSendCompleted;
155 static jmethodID method_onServerReadCharacteristic;
156 static jmethodID method_onServerReadDescriptor;
157 static jmethodID method_onServerWriteCharacteristic;
158 static jmethodID method_onServerWriteDescriptor;
159 static jmethodID method_onExecuteWrite;
160 static jmethodID method_onNotificationSent;
161 static jmethodID method_onServerCongestion;
162 static jmethodID method_onServerMtuChanged;
163 static jmethodID method_onServerPhyUpdate;
164 static jmethodID method_onServerPhyRead;
165 static jmethodID method_onServerConnUpdate;
166 
167 /**
168  * Advertiser callback methods
169  */
170 static jmethodID method_onAdvertisingSetStarted;
171 static jmethodID method_onOwnAddressRead;
172 static jmethodID method_onAdvertisingEnabled;
173 static jmethodID method_onAdvertisingDataSet;
174 static jmethodID method_onScanResponseDataSet;
175 static jmethodID method_onAdvertisingParametersUpdated;
176 static jmethodID method_onPeriodicAdvertisingParametersUpdated;
177 static jmethodID method_onPeriodicAdvertisingDataSet;
178 static jmethodID method_onPeriodicAdvertisingEnabled;
179 
180 /**
181  * Periodic scanner callback methods
182  */
183 static jmethodID method_onSyncLost;
184 static jmethodID method_onSyncReport;
185 static jmethodID method_onSyncStarted;
186 
187 /**
188  * Static variables
189  */
190 
191 static const btgatt_interface_t* sGattIf = NULL;
192 static jobject mCallbacksObj = NULL;
193 static jobject mAdvertiseCallbacksObj = NULL;
194 static jobject mPeriodicScanCallbacksObj = NULL;
195 
196 /**
197  * BTA client callbacks
198  */
199 
btgattc_register_app_cb(int status,int clientIf,const Uuid & app_uuid)200 void btgattc_register_app_cb(int status, int clientIf, const Uuid& app_uuid) {
201   CallbackEnv sCallbackEnv(__func__);
202   if (!sCallbackEnv.valid()) return;
203   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientRegistered, status,
204                                clientIf, UUID_PARAMS(app_uuid));
205 }
206 
btgattc_scan_result_cb(uint16_t event_type,uint8_t addr_type,RawAddress * bda,uint8_t primary_phy,uint8_t secondary_phy,uint8_t advertising_sid,int8_t tx_power,int8_t rssi,uint16_t periodic_adv_int,std::vector<uint8_t> adv_data)207 void btgattc_scan_result_cb(uint16_t event_type, uint8_t addr_type,
208                             RawAddress* bda, uint8_t primary_phy,
209                             uint8_t secondary_phy, uint8_t advertising_sid,
210                             int8_t tx_power, int8_t rssi,
211                             uint16_t periodic_adv_int,
212                             std::vector<uint8_t> adv_data) {
213   CallbackEnv sCallbackEnv(__func__);
214   if (!sCallbackEnv.valid()) return;
215 
216   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
217                                   bdaddr2newjstr(sCallbackEnv.get(), bda));
218   ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(),
219                                 sCallbackEnv->NewByteArray(adv_data.size()));
220   sCallbackEnv->SetByteArrayRegion(jb.get(), 0, adv_data.size(),
221                                    (jbyte*)adv_data.data());
222 
223   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanResult, event_type,
224                                addr_type, address.get(), primary_phy,
225                                secondary_phy, advertising_sid, tx_power, rssi,
226                                periodic_adv_int, jb.get());
227 }
228 
btgattc_open_cb(int conn_id,int status,int clientIf,const RawAddress & bda)229 void btgattc_open_cb(int conn_id, int status, int clientIf,
230                      const RawAddress& bda) {
231   CallbackEnv sCallbackEnv(__func__);
232   if (!sCallbackEnv.valid()) return;
233 
234   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
235                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
236   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnected, clientIf,
237                                conn_id, status, address.get());
238 }
239 
btgattc_close_cb(int conn_id,int status,int clientIf,const RawAddress & bda)240 void btgattc_close_cb(int conn_id, int status, int clientIf,
241                       const RawAddress& bda) {
242   CallbackEnv sCallbackEnv(__func__);
243   if (!sCallbackEnv.valid()) return;
244 
245   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
246                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
247   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onDisconnected, clientIf,
248                                conn_id, status, address.get());
249 }
250 
btgattc_search_complete_cb(int conn_id,int status)251 void btgattc_search_complete_cb(int conn_id, int status) {
252   CallbackEnv sCallbackEnv(__func__);
253   if (!sCallbackEnv.valid()) return;
254 
255   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onSearchCompleted, conn_id,
256                                status);
257 }
258 
btgattc_register_for_notification_cb(int conn_id,int registered,int status,uint16_t handle)259 void btgattc_register_for_notification_cb(int conn_id, int registered,
260                                           int status, uint16_t handle) {
261   CallbackEnv sCallbackEnv(__func__);
262   if (!sCallbackEnv.valid()) return;
263 
264   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onRegisterForNotifications,
265                                conn_id, status, registered, handle);
266 }
267 
btgattc_notify_cb(int conn_id,const btgatt_notify_params_t & p_data)268 void btgattc_notify_cb(int conn_id, const btgatt_notify_params_t& p_data) {
269   CallbackEnv sCallbackEnv(__func__);
270   if (!sCallbackEnv.valid()) return;
271 
272   ScopedLocalRef<jstring> address(
273       sCallbackEnv.get(), bdaddr2newjstr(sCallbackEnv.get(), &p_data.bda));
274   ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(),
275                                 sCallbackEnv->NewByteArray(p_data.len));
276   sCallbackEnv->SetByteArrayRegion(jb.get(), 0, p_data.len,
277                                    (jbyte*)p_data.value);
278 
279   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotify, conn_id,
280                                address.get(), p_data.handle, p_data.is_notify,
281                                jb.get());
282 }
283 
btgattc_read_characteristic_cb(int conn_id,int status,btgatt_read_params_t * p_data)284 void btgattc_read_characteristic_cb(int conn_id, int status,
285                                     btgatt_read_params_t* p_data) {
286   CallbackEnv sCallbackEnv(__func__);
287   if (!sCallbackEnv.valid()) return;
288 
289   ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), NULL);
290   if (status == 0) {  // Success
291     jb.reset(sCallbackEnv->NewByteArray(p_data->value.len));
292     sCallbackEnv->SetByteArrayRegion(jb.get(), 0, p_data->value.len,
293                                      (jbyte*)p_data->value.value);
294   } else {
295     uint8_t value = 0;
296     jb.reset(sCallbackEnv->NewByteArray(1));
297     sCallbackEnv->SetByteArrayRegion(jb.get(), 0, 1, (jbyte*)&value);
298   }
299 
300   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadCharacteristic,
301                                conn_id, status, p_data->handle, jb.get());
302 }
303 
btgattc_write_characteristic_cb(int conn_id,int status,uint16_t handle)304 void btgattc_write_characteristic_cb(int conn_id, int status, uint16_t handle) {
305   CallbackEnv sCallbackEnv(__func__);
306   if (!sCallbackEnv.valid()) return;
307 
308   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteCharacteristic,
309                                conn_id, status, handle);
310 }
311 
btgattc_execute_write_cb(int conn_id,int status)312 void btgattc_execute_write_cb(int conn_id, int status) {
313   CallbackEnv sCallbackEnv(__func__);
314   if (!sCallbackEnv.valid()) return;
315 
316   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteCompleted,
317                                conn_id, status);
318 }
319 
btgattc_read_descriptor_cb(int conn_id,int status,const btgatt_read_params_t & p_data)320 void btgattc_read_descriptor_cb(int conn_id, int status,
321                                 const btgatt_read_params_t& p_data) {
322   CallbackEnv sCallbackEnv(__func__);
323   if (!sCallbackEnv.valid()) return;
324 
325   ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(), NULL);
326   if (p_data.value.len != 0) {
327     jb.reset(sCallbackEnv->NewByteArray(p_data.value.len));
328     sCallbackEnv->SetByteArrayRegion(jb.get(), 0, p_data.value.len,
329                                      (jbyte*)p_data.value.value);
330   } else {
331     jb.reset(sCallbackEnv->NewByteArray(1));
332   }
333 
334   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadDescriptor, conn_id,
335                                status, p_data.handle, jb.get());
336 }
337 
btgattc_write_descriptor_cb(int conn_id,int status,uint16_t handle)338 void btgattc_write_descriptor_cb(int conn_id, int status, uint16_t handle) {
339   CallbackEnv sCallbackEnv(__func__);
340   if (!sCallbackEnv.valid()) return;
341 
342   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onWriteDescriptor, conn_id,
343                                status, handle);
344 }
345 
btgattc_remote_rssi_cb(int client_if,const RawAddress & bda,int rssi,int status)346 void btgattc_remote_rssi_cb(int client_if, const RawAddress& bda, int rssi,
347                             int status) {
348   CallbackEnv sCallbackEnv(__func__);
349   if (!sCallbackEnv.valid()) return;
350 
351   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
352                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
353 
354   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onReadRemoteRssi,
355                                client_if, address.get(), rssi, status);
356 }
357 
btgattc_configure_mtu_cb(int conn_id,int status,int mtu)358 void btgattc_configure_mtu_cb(int conn_id, int status, int mtu) {
359   CallbackEnv sCallbackEnv(__func__);
360   if (!sCallbackEnv.valid()) return;
361   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConfigureMTU, conn_id,
362                                status, mtu);
363 }
364 
btgattc_congestion_cb(int conn_id,bool congested)365 void btgattc_congestion_cb(int conn_id, bool congested) {
366   CallbackEnv sCallbackEnv(__func__);
367   if (!sCallbackEnv.valid()) return;
368   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientCongestion,
369                                conn_id, congested);
370 }
371 
btgattc_batchscan_reports_cb(int client_if,int status,int report_format,int num_records,std::vector<uint8_t> data)372 void btgattc_batchscan_reports_cb(int client_if, int status, int report_format,
373                                   int num_records, std::vector<uint8_t> data) {
374   CallbackEnv sCallbackEnv(__func__);
375   if (!sCallbackEnv.valid()) return;
376   ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(),
377                                 sCallbackEnv->NewByteArray(data.size()));
378   sCallbackEnv->SetByteArrayRegion(jb.get(), 0, data.size(),
379                                    (jbyte*)data.data());
380 
381   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanReports, status,
382                                client_if, report_format, num_records, jb.get());
383 }
384 
btgattc_batchscan_threshold_cb(int client_if)385 void btgattc_batchscan_threshold_cb(int client_if) {
386   CallbackEnv sCallbackEnv(__func__);
387   if (!sCallbackEnv.valid()) return;
388   sCallbackEnv->CallVoidMethod(mCallbacksObj,
389                                method_onBatchScanThresholdCrossed, client_if);
390 }
391 
btgattc_track_adv_event_cb(btgatt_track_adv_info_t * p_adv_track_info)392 void btgattc_track_adv_event_cb(btgatt_track_adv_info_t* p_adv_track_info) {
393   CallbackEnv sCallbackEnv(__func__);
394   if (!sCallbackEnv.valid()) return;
395 
396   ScopedLocalRef<jstring> address(
397       sCallbackEnv.get(),
398       bdaddr2newjstr(sCallbackEnv.get(), &p_adv_track_info->bd_addr));
399 
400   ScopedLocalRef<jbyteArray> jb_adv_pkt(
401       sCallbackEnv.get(),
402       sCallbackEnv->NewByteArray(p_adv_track_info->adv_pkt_len));
403   ScopedLocalRef<jbyteArray> jb_scan_rsp(
404       sCallbackEnv.get(),
405       sCallbackEnv->NewByteArray(p_adv_track_info->scan_rsp_len));
406 
407   sCallbackEnv->SetByteArrayRegion(jb_adv_pkt.get(), 0,
408                                    p_adv_track_info->adv_pkt_len,
409                                    (jbyte*)p_adv_track_info->p_adv_pkt_data);
410 
411   sCallbackEnv->SetByteArrayRegion(jb_scan_rsp.get(), 0,
412                                    p_adv_track_info->scan_rsp_len,
413                                    (jbyte*)p_adv_track_info->p_scan_rsp_data);
414 
415   ScopedLocalRef<jobject> trackadv_obj(
416       sCallbackEnv.get(),
417       sCallbackEnv->CallObjectMethod(
418           mCallbacksObj, method_createOnTrackAdvFoundLostObject,
419           p_adv_track_info->client_if, p_adv_track_info->adv_pkt_len,
420           jb_adv_pkt.get(), p_adv_track_info->scan_rsp_len, jb_scan_rsp.get(),
421           p_adv_track_info->filt_index, p_adv_track_info->advertiser_state,
422           p_adv_track_info->advertiser_info_present, address.get(),
423           p_adv_track_info->addr_type, p_adv_track_info->tx_power,
424           p_adv_track_info->rssi_value, p_adv_track_info->time_stamp));
425 
426   if (NULL != trackadv_obj.get()) {
427     sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onTrackAdvFoundLost,
428                                  trackadv_obj.get());
429   }
430 }
431 
fillGattDbElementArray(JNIEnv * env,jobject * array,const btgatt_db_element_t * db,int count)432 void fillGattDbElementArray(JNIEnv* env, jobject* array,
433                             const btgatt_db_element_t* db, int count) {
434   // Because JNI uses a different class loader in the callback context, we
435   // cannot simply get the class.
436   // As a workaround, we have to make sure we obtain an object of the class
437   // first, as this will cause
438   // class loader to load it.
439   ScopedLocalRef<jobject> objectForClass(
440       env, env->CallObjectMethod(mCallbacksObj, method_getSampleGattDbElement));
441   ScopedLocalRef<jclass> gattDbElementClazz(
442       env, env->GetObjectClass(objectForClass.get()));
443 
444   jmethodID gattDbElementConstructor =
445       env->GetMethodID(gattDbElementClazz.get(), "<init>", "()V");
446 
447   ScopedLocalRef<jclass> arrayListclazz(env,
448                                         env->FindClass("java/util/ArrayList"));
449   jmethodID arrayAdd =
450       env->GetMethodID(arrayListclazz.get(), "add", "(Ljava/lang/Object;)Z");
451 
452   ScopedLocalRef<jclass> uuidClazz(env, env->FindClass("java/util/UUID"));
453   jmethodID uuidConstructor =
454       env->GetMethodID(uuidClazz.get(), "<init>", "(JJ)V");
455 
456   for (int i = 0; i < count; i++) {
457     const btgatt_db_element_t& curr = db[i];
458 
459     ScopedLocalRef<jobject> element(
460         env,
461         env->NewObject(gattDbElementClazz.get(), gattDbElementConstructor));
462 
463     jfieldID fid = env->GetFieldID(gattDbElementClazz.get(), "id", "I");
464     env->SetIntField(element.get(), fid, curr.id);
465 
466     fid = env->GetFieldID(gattDbElementClazz.get(), "attributeHandle", "I");
467     env->SetIntField(element.get(), fid, curr.attribute_handle);
468 
469     ScopedLocalRef<jobject> uuid(
470         env, env->NewObject(uuidClazz.get(), uuidConstructor,
471                             uuid_msb(curr.uuid), uuid_lsb(curr.uuid)));
472     fid = env->GetFieldID(gattDbElementClazz.get(), "uuid", "Ljava/util/UUID;");
473     env->SetObjectField(element.get(), fid, uuid.get());
474 
475     fid = env->GetFieldID(gattDbElementClazz.get(), "type", "I");
476     env->SetIntField(element.get(), fid, curr.type);
477 
478     fid = env->GetFieldID(gattDbElementClazz.get(), "attributeHandle", "I");
479     env->SetIntField(element.get(), fid, curr.attribute_handle);
480 
481     fid = env->GetFieldID(gattDbElementClazz.get(), "startHandle", "I");
482     env->SetIntField(element.get(), fid, curr.start_handle);
483 
484     fid = env->GetFieldID(gattDbElementClazz.get(), "endHandle", "I");
485     env->SetIntField(element.get(), fid, curr.end_handle);
486 
487     fid = env->GetFieldID(gattDbElementClazz.get(), "properties", "I");
488     env->SetIntField(element.get(), fid, curr.properties);
489 
490     env->CallBooleanMethod(*array, arrayAdd, element.get());
491   }
492 }
493 
btgattc_get_gatt_db_cb(int conn_id,const btgatt_db_element_t * db,int count)494 void btgattc_get_gatt_db_cb(int conn_id, const btgatt_db_element_t* db,
495                             int count) {
496   CallbackEnv sCallbackEnv(__func__);
497   if (!sCallbackEnv.valid()) return;
498 
499   jclass arrayListclazz = sCallbackEnv->FindClass("java/util/ArrayList");
500   ScopedLocalRef<jobject> array(
501       sCallbackEnv.get(),
502       sCallbackEnv->NewObject(
503           arrayListclazz,
504           sCallbackEnv->GetMethodID(arrayListclazz, "<init>", "()V")));
505 
506   jobject arrayPtr = array.get();
507   fillGattDbElementArray(sCallbackEnv.get(), &arrayPtr, db, count);
508 
509   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onGetGattDb, conn_id,
510                                array.get());
511 }
512 
btgattc_phy_updated_cb(int conn_id,uint8_t tx_phy,uint8_t rx_phy,uint8_t status)513 void btgattc_phy_updated_cb(int conn_id, uint8_t tx_phy, uint8_t rx_phy,
514                             uint8_t status) {
515   CallbackEnv sCallbackEnv(__func__);
516   if (!sCallbackEnv.valid()) return;
517 
518   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientPhyUpdate, conn_id,
519                                tx_phy, rx_phy, status);
520 }
521 
btgattc_conn_updated_cb(int conn_id,uint16_t interval,uint16_t latency,uint16_t timeout,uint8_t status)522 void btgattc_conn_updated_cb(int conn_id, uint16_t interval, uint16_t latency,
523                              uint16_t timeout, uint8_t status) {
524   CallbackEnv sCallbackEnv(__func__);
525   if (!sCallbackEnv.valid()) return;
526 
527   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientConnUpdate,
528                                conn_id, interval, latency, timeout, status);
529 }
530 
531 static const btgatt_scanner_callbacks_t sGattScannerCallbacks = {
532     btgattc_scan_result_cb,
533     btgattc_batchscan_reports_cb,
534     btgattc_batchscan_threshold_cb,
535     btgattc_track_adv_event_cb,
536 };
537 
538 static const btgatt_client_callbacks_t sGattClientCallbacks = {
539     btgattc_register_app_cb,
540     btgattc_open_cb,
541     btgattc_close_cb,
542     btgattc_search_complete_cb,
543     btgattc_register_for_notification_cb,
544     btgattc_notify_cb,
545     btgattc_read_characteristic_cb,
546     btgattc_write_characteristic_cb,
547     btgattc_read_descriptor_cb,
548     btgattc_write_descriptor_cb,
549     btgattc_execute_write_cb,
550     btgattc_remote_rssi_cb,
551     btgattc_configure_mtu_cb,
552     btgattc_congestion_cb,
553     btgattc_get_gatt_db_cb,
554     NULL, /* services_removed_cb */
555     NULL, /* services_added_cb */
556     btgattc_phy_updated_cb,
557     btgattc_conn_updated_cb};
558 
559 /**
560  * BTA server callbacks
561  */
562 
btgatts_register_app_cb(int status,int server_if,const Uuid & uuid)563 void btgatts_register_app_cb(int status, int server_if, const Uuid& uuid) {
564   CallbackEnv sCallbackEnv(__func__);
565   if (!sCallbackEnv.valid()) return;
566   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerRegistered, status,
567                                server_if, UUID_PARAMS(uuid));
568 }
569 
btgatts_connection_cb(int conn_id,int server_if,int connected,const RawAddress & bda)570 void btgatts_connection_cb(int conn_id, int server_if, int connected,
571                            const RawAddress& bda) {
572   CallbackEnv sCallbackEnv(__func__);
573   if (!sCallbackEnv.valid()) return;
574 
575   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
576                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
577   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientConnected,
578                                address.get(), connected, conn_id, server_if);
579 }
580 
btgatts_service_added_cb(int status,int server_if,std::vector<btgatt_db_element_t> service)581 void btgatts_service_added_cb(int status, int server_if,
582                               std::vector<btgatt_db_element_t> service) {
583   CallbackEnv sCallbackEnv(__func__);
584   if (!sCallbackEnv.valid()) return;
585 
586   jclass arrayListclazz = sCallbackEnv->FindClass("java/util/ArrayList");
587   ScopedLocalRef<jobject> array(
588       sCallbackEnv.get(),
589       sCallbackEnv->NewObject(
590           arrayListclazz,
591           sCallbackEnv->GetMethodID(arrayListclazz, "<init>", "()V")));
592   jobject arrayPtr = array.get();
593   fillGattDbElementArray(sCallbackEnv.get(), &arrayPtr, service.data(),
594                          service.size());
595 
596   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceAdded, status,
597                                server_if, array.get());
598 }
599 
btgatts_service_stopped_cb(int status,int server_if,int srvc_handle)600 void btgatts_service_stopped_cb(int status, int server_if, int srvc_handle) {
601   CallbackEnv sCallbackEnv(__func__);
602   if (!sCallbackEnv.valid()) return;
603   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceStopped, status,
604                                server_if, srvc_handle);
605 }
606 
btgatts_service_deleted_cb(int status,int server_if,int srvc_handle)607 void btgatts_service_deleted_cb(int status, int server_if, int srvc_handle) {
608   CallbackEnv sCallbackEnv(__func__);
609   if (!sCallbackEnv.valid()) return;
610   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServiceDeleted, status,
611                                server_if, srvc_handle);
612 }
613 
btgatts_request_read_characteristic_cb(int conn_id,int trans_id,const RawAddress & bda,int attr_handle,int offset,bool is_long)614 void btgatts_request_read_characteristic_cb(int conn_id, int trans_id,
615                                             const RawAddress& bda,
616                                             int attr_handle, int offset,
617                                             bool is_long) {
618   CallbackEnv sCallbackEnv(__func__);
619   if (!sCallbackEnv.valid()) return;
620 
621   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
622                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
623   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerReadCharacteristic,
624                                address.get(), conn_id, trans_id, attr_handle,
625                                offset, is_long);
626 }
627 
btgatts_request_read_descriptor_cb(int conn_id,int trans_id,const RawAddress & bda,int attr_handle,int offset,bool is_long)628 void btgatts_request_read_descriptor_cb(int conn_id, int trans_id,
629                                         const RawAddress& bda, int attr_handle,
630                                         int offset, bool is_long) {
631   CallbackEnv sCallbackEnv(__func__);
632   if (!sCallbackEnv.valid()) return;
633 
634   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
635                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
636   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerReadDescriptor,
637                                address.get(), conn_id, trans_id, attr_handle,
638                                offset, is_long);
639 }
640 
btgatts_request_write_characteristic_cb(int conn_id,int trans_id,const RawAddress & bda,int attr_handle,int offset,bool need_rsp,bool is_prep,std::vector<uint8_t> value)641 void btgatts_request_write_characteristic_cb(int conn_id, int trans_id,
642                                              const RawAddress& bda,
643                                              int attr_handle, int offset,
644                                              bool need_rsp, bool is_prep,
645                                              std::vector<uint8_t> value) {
646   CallbackEnv sCallbackEnv(__func__);
647   if (!sCallbackEnv.valid()) return;
648 
649   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
650                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
651   ScopedLocalRef<jbyteArray> val(sCallbackEnv.get(),
652                                  sCallbackEnv->NewByteArray(value.size()));
653   if (val.get())
654     sCallbackEnv->SetByteArrayRegion(val.get(), 0, value.size(),
655                                      (jbyte*)value.data());
656   sCallbackEnv->CallVoidMethod(
657       mCallbacksObj, method_onServerWriteCharacteristic, address.get(), conn_id,
658       trans_id, attr_handle, offset, value.size(), need_rsp, is_prep,
659       val.get());
660 }
661 
btgatts_request_write_descriptor_cb(int conn_id,int trans_id,const RawAddress & bda,int attr_handle,int offset,bool need_rsp,bool is_prep,std::vector<uint8_t> value)662 void btgatts_request_write_descriptor_cb(int conn_id, int trans_id,
663                                          const RawAddress& bda, int attr_handle,
664                                          int offset, bool need_rsp,
665                                          bool is_prep,
666                                          std::vector<uint8_t> value) {
667   CallbackEnv sCallbackEnv(__func__);
668   if (!sCallbackEnv.valid()) return;
669 
670   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
671                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
672   ScopedLocalRef<jbyteArray> val(sCallbackEnv.get(),
673                                  sCallbackEnv->NewByteArray(value.size()));
674   if (val.get())
675     sCallbackEnv->SetByteArrayRegion(val.get(), 0, value.size(),
676                                      (jbyte*)value.data());
677   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerWriteDescriptor,
678                                address.get(), conn_id, trans_id, attr_handle,
679                                offset, value.size(), need_rsp, is_prep,
680                                val.get());
681 }
682 
btgatts_request_exec_write_cb(int conn_id,int trans_id,const RawAddress & bda,int exec_write)683 void btgatts_request_exec_write_cb(int conn_id, int trans_id,
684                                    const RawAddress& bda, int exec_write) {
685   CallbackEnv sCallbackEnv(__func__);
686   if (!sCallbackEnv.valid()) return;
687 
688   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
689                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
690   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onExecuteWrite,
691                                address.get(), conn_id, trans_id, exec_write);
692 }
693 
btgatts_response_confirmation_cb(int status,int handle)694 void btgatts_response_confirmation_cb(int status, int handle) {
695   CallbackEnv sCallbackEnv(__func__);
696   if (!sCallbackEnv.valid()) return;
697   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onResponseSendCompleted,
698                                status, handle);
699 }
700 
btgatts_indication_sent_cb(int conn_id,int status)701 void btgatts_indication_sent_cb(int conn_id, int status) {
702   CallbackEnv sCallbackEnv(__func__);
703   if (!sCallbackEnv.valid()) return;
704   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onNotificationSent,
705                                conn_id, status);
706 }
707 
btgatts_congestion_cb(int conn_id,bool congested)708 void btgatts_congestion_cb(int conn_id, bool congested) {
709   CallbackEnv sCallbackEnv(__func__);
710   if (!sCallbackEnv.valid()) return;
711   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerCongestion,
712                                conn_id, congested);
713 }
714 
btgatts_mtu_changed_cb(int conn_id,int mtu)715 void btgatts_mtu_changed_cb(int conn_id, int mtu) {
716   CallbackEnv sCallbackEnv(__func__);
717   if (!sCallbackEnv.valid()) return;
718   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerMtuChanged,
719                                conn_id, mtu);
720 }
721 
btgatts_phy_updated_cb(int conn_id,uint8_t tx_phy,uint8_t rx_phy,uint8_t status)722 void btgatts_phy_updated_cb(int conn_id, uint8_t tx_phy, uint8_t rx_phy,
723                             uint8_t status) {
724   CallbackEnv sCallbackEnv(__func__);
725   if (!sCallbackEnv.valid()) return;
726 
727   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerPhyUpdate, conn_id,
728                                tx_phy, rx_phy, status);
729 }
730 
btgatts_conn_updated_cb(int conn_id,uint16_t interval,uint16_t latency,uint16_t timeout,uint8_t status)731 void btgatts_conn_updated_cb(int conn_id, uint16_t interval, uint16_t latency,
732                              uint16_t timeout, uint8_t status) {
733   CallbackEnv sCallbackEnv(__func__);
734   if (!sCallbackEnv.valid()) return;
735 
736   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerConnUpdate,
737                                conn_id, interval, latency, timeout, status);
738 }
739 
740 static const btgatt_server_callbacks_t sGattServerCallbacks = {
741     btgatts_register_app_cb,
742     btgatts_connection_cb,
743     btgatts_service_added_cb,
744     btgatts_service_stopped_cb,
745     btgatts_service_deleted_cb,
746     btgatts_request_read_characteristic_cb,
747     btgatts_request_read_descriptor_cb,
748     btgatts_request_write_characteristic_cb,
749     btgatts_request_write_descriptor_cb,
750     btgatts_request_exec_write_cb,
751     btgatts_response_confirmation_cb,
752     btgatts_indication_sent_cb,
753     btgatts_congestion_cb,
754     btgatts_mtu_changed_cb,
755     btgatts_phy_updated_cb,
756     btgatts_conn_updated_cb};
757 
758 /**
759  * GATT callbacks
760  */
761 
762 static const btgatt_callbacks_t sGattCallbacks = {
763     sizeof(btgatt_callbacks_t), &sGattClientCallbacks, &sGattServerCallbacks,
764     &sGattScannerCallbacks,
765 };
766 
767 /**
768  * Native function definitions
769  */
classInitNative(JNIEnv * env,jclass clazz)770 static void classInitNative(JNIEnv* env, jclass clazz) {
771   // Client callbacks
772 
773   method_onClientRegistered =
774       env->GetMethodID(clazz, "onClientRegistered", "(IIJJ)V");
775   method_onScannerRegistered =
776       env->GetMethodID(clazz, "onScannerRegistered", "(IIJJ)V");
777   method_onScanResult = env->GetMethodID(clazz, "onScanResult",
778                                          "(IILjava/lang/String;IIIIII[B)V");
779   method_onConnected =
780       env->GetMethodID(clazz, "onConnected", "(IIILjava/lang/String;)V");
781   method_onDisconnected =
782       env->GetMethodID(clazz, "onDisconnected", "(IIILjava/lang/String;)V");
783   method_onReadCharacteristic =
784       env->GetMethodID(clazz, "onReadCharacteristic", "(III[B)V");
785   method_onWriteCharacteristic =
786       env->GetMethodID(clazz, "onWriteCharacteristic", "(III)V");
787   method_onExecuteCompleted =
788       env->GetMethodID(clazz, "onExecuteCompleted", "(II)V");
789   method_onSearchCompleted =
790       env->GetMethodID(clazz, "onSearchCompleted", "(II)V");
791   method_onReadDescriptor =
792       env->GetMethodID(clazz, "onReadDescriptor", "(III[B)V");
793   method_onWriteDescriptor =
794       env->GetMethodID(clazz, "onWriteDescriptor", "(III)V");
795   method_onNotify =
796       env->GetMethodID(clazz, "onNotify", "(ILjava/lang/String;IZ[B)V");
797   method_onRegisterForNotifications =
798       env->GetMethodID(clazz, "onRegisterForNotifications", "(IIII)V");
799   method_onReadRemoteRssi =
800       env->GetMethodID(clazz, "onReadRemoteRssi", "(ILjava/lang/String;II)V");
801   method_onConfigureMTU = env->GetMethodID(clazz, "onConfigureMTU", "(III)V");
802   method_onScanFilterConfig =
803       env->GetMethodID(clazz, "onScanFilterConfig", "(IIIII)V");
804   method_onScanFilterParamsConfigured =
805       env->GetMethodID(clazz, "onScanFilterParamsConfigured", "(IIII)V");
806   method_onScanFilterEnableDisabled =
807       env->GetMethodID(clazz, "onScanFilterEnableDisabled", "(III)V");
808   method_onClientCongestion =
809       env->GetMethodID(clazz, "onClientCongestion", "(IZ)V");
810   method_onBatchScanStorageConfigured =
811       env->GetMethodID(clazz, "onBatchScanStorageConfigured", "(II)V");
812   method_onBatchScanStartStopped =
813       env->GetMethodID(clazz, "onBatchScanStartStopped", "(III)V");
814   method_onBatchScanReports =
815       env->GetMethodID(clazz, "onBatchScanReports", "(IIII[B)V");
816   method_onBatchScanThresholdCrossed =
817       env->GetMethodID(clazz, "onBatchScanThresholdCrossed", "(I)V");
818   method_createOnTrackAdvFoundLostObject =
819       env->GetMethodID(clazz, "createOnTrackAdvFoundLostObject",
820                        "(II[BI[BIIILjava/lang/String;IIII)Lcom/android/"
821                        "bluetooth/gatt/AdvtFilterOnFoundOnLostInfo;");
822   method_onTrackAdvFoundLost = env->GetMethodID(
823       clazz, "onTrackAdvFoundLost",
824       "(Lcom/android/bluetooth/gatt/AdvtFilterOnFoundOnLostInfo;)V");
825   method_onScanParamSetupCompleted =
826       env->GetMethodID(clazz, "onScanParamSetupCompleted", "(II)V");
827   method_getSampleGattDbElement =
828       env->GetMethodID(clazz, "getSampleGattDbElement",
829                        "()Lcom/android/bluetooth/gatt/GattDbElement;");
830   method_onGetGattDb =
831       env->GetMethodID(clazz, "onGetGattDb", "(ILjava/util/ArrayList;)V");
832   method_onClientPhyRead =
833       env->GetMethodID(clazz, "onClientPhyRead", "(ILjava/lang/String;III)V");
834   method_onClientPhyUpdate =
835       env->GetMethodID(clazz, "onClientPhyUpdate", "(IIII)V");
836   method_onClientConnUpdate =
837       env->GetMethodID(clazz, "onClientConnUpdate", "(IIIII)V");
838 
839   // Server callbacks
840 
841   method_onServerRegistered =
842       env->GetMethodID(clazz, "onServerRegistered", "(IIJJ)V");
843   method_onClientConnected =
844       env->GetMethodID(clazz, "onClientConnected", "(Ljava/lang/String;ZII)V");
845   method_onServiceAdded =
846       env->GetMethodID(clazz, "onServiceAdded", "(IILjava/util/List;)V");
847   method_onServiceStopped =
848       env->GetMethodID(clazz, "onServiceStopped", "(III)V");
849   method_onServiceDeleted =
850       env->GetMethodID(clazz, "onServiceDeleted", "(III)V");
851   method_onResponseSendCompleted =
852       env->GetMethodID(clazz, "onResponseSendCompleted", "(II)V");
853   method_onServerReadCharacteristic = env->GetMethodID(
854       clazz, "onServerReadCharacteristic", "(Ljava/lang/String;IIIIZ)V");
855   method_onServerReadDescriptor = env->GetMethodID(
856       clazz, "onServerReadDescriptor", "(Ljava/lang/String;IIIIZ)V");
857   method_onServerWriteCharacteristic = env->GetMethodID(
858       clazz, "onServerWriteCharacteristic", "(Ljava/lang/String;IIIIIZZ[B)V");
859   method_onServerWriteDescriptor = env->GetMethodID(
860       clazz, "onServerWriteDescriptor", "(Ljava/lang/String;IIIIIZZ[B)V");
861   method_onExecuteWrite =
862       env->GetMethodID(clazz, "onExecuteWrite", "(Ljava/lang/String;III)V");
863   method_onNotificationSent =
864       env->GetMethodID(clazz, "onNotificationSent", "(II)V");
865   method_onServerCongestion =
866       env->GetMethodID(clazz, "onServerCongestion", "(IZ)V");
867   method_onServerMtuChanged = env->GetMethodID(clazz, "onMtuChanged", "(II)V");
868   method_onServerPhyRead =
869       env->GetMethodID(clazz, "onServerPhyRead", "(ILjava/lang/String;III)V");
870   method_onServerPhyUpdate =
871       env->GetMethodID(clazz, "onServerPhyUpdate", "(IIII)V");
872   method_onServerConnUpdate =
873       env->GetMethodID(clazz, "onServerConnUpdate", "(IIIII)V");
874 
875   info("classInitNative: Success!");
876 }
877 
878 static const bt_interface_t* btIf;
879 
initializeNative(JNIEnv * env,jobject object)880 static void initializeNative(JNIEnv* env, jobject object) {
881   if (btIf) return;
882 
883   btIf = getBluetoothInterface();
884   if (btIf == NULL) {
885     error("Bluetooth module is not loaded");
886     return;
887   }
888 
889   if (sGattIf != NULL) {
890     ALOGW("Cleaning up Bluetooth GATT Interface before initializing...");
891     sGattIf->cleanup();
892     sGattIf = NULL;
893   }
894 
895   if (mCallbacksObj != NULL) {
896     ALOGW("Cleaning up Bluetooth GATT callback object");
897     env->DeleteGlobalRef(mCallbacksObj);
898     mCallbacksObj = NULL;
899   }
900 
901   sGattIf =
902       (btgatt_interface_t*)btIf->get_profile_interface(BT_PROFILE_GATT_ID);
903   if (sGattIf == NULL) {
904     error("Failed to get Bluetooth GATT Interface");
905     return;
906   }
907 
908   bt_status_t status = sGattIf->init(&sGattCallbacks);
909   if (status != BT_STATUS_SUCCESS) {
910     error("Failed to initialize Bluetooth GATT, status: %d", status);
911     sGattIf = NULL;
912     return;
913   }
914 
915   mCallbacksObj = env->NewGlobalRef(object);
916 }
917 
cleanupNative(JNIEnv * env,jobject object)918 static void cleanupNative(JNIEnv* env, jobject object) {
919   if (!btIf) return;
920 
921   if (sGattIf != NULL) {
922     sGattIf->cleanup();
923     sGattIf = NULL;
924   }
925 
926   if (mCallbacksObj != NULL) {
927     env->DeleteGlobalRef(mCallbacksObj);
928     mCallbacksObj = NULL;
929   }
930   btIf = NULL;
931 }
932 
933 /**
934  * Native Client functions
935  */
936 
gattClientGetDeviceTypeNative(JNIEnv * env,jobject object,jstring address)937 static int gattClientGetDeviceTypeNative(JNIEnv* env, jobject object,
938                                          jstring address) {
939   if (!sGattIf) return 0;
940   return sGattIf->client->get_device_type(str2addr(env, address));
941 }
942 
gattClientRegisterAppNative(JNIEnv * env,jobject object,jlong app_uuid_lsb,jlong app_uuid_msb)943 static void gattClientRegisterAppNative(JNIEnv* env, jobject object,
944                                         jlong app_uuid_lsb,
945                                         jlong app_uuid_msb) {
946   if (!sGattIf) return;
947   Uuid uuid = from_java_uuid(app_uuid_msb, app_uuid_lsb);
948   sGattIf->client->register_client(uuid);
949 }
950 
gattClientUnregisterAppNative(JNIEnv * env,jobject object,jint clientIf)951 static void gattClientUnregisterAppNative(JNIEnv* env, jobject object,
952                                           jint clientIf) {
953   if (!sGattIf) return;
954   sGattIf->client->unregister_client(clientIf);
955 }
956 
btgattc_register_scanner_cb(const Uuid & app_uuid,uint8_t scannerId,uint8_t status)957 void btgattc_register_scanner_cb(const Uuid& app_uuid, uint8_t scannerId,
958                                  uint8_t status) {
959   CallbackEnv sCallbackEnv(__func__);
960   if (!sCallbackEnv.valid()) return;
961   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScannerRegistered,
962                                status, scannerId, UUID_PARAMS(app_uuid));
963 }
964 
registerScannerNative(JNIEnv * env,jobject object,jlong app_uuid_lsb,jlong app_uuid_msb)965 static void registerScannerNative(JNIEnv* env, jobject object,
966                                   jlong app_uuid_lsb, jlong app_uuid_msb) {
967   if (!sGattIf) return;
968 
969   Uuid uuid = from_java_uuid(app_uuid_msb, app_uuid_lsb);
970   sGattIf->scanner->RegisterScanner(
971       base::Bind(&btgattc_register_scanner_cb, uuid));
972 }
973 
unregisterScannerNative(JNIEnv * env,jobject object,jint scanner_id)974 static void unregisterScannerNative(JNIEnv* env, jobject object,
975                                     jint scanner_id) {
976   if (!sGattIf) return;
977 
978   sGattIf->scanner->Unregister(scanner_id);
979 }
980 
gattClientScanNative(JNIEnv * env,jobject object,jboolean start)981 static void gattClientScanNative(JNIEnv* env, jobject object, jboolean start) {
982   if (!sGattIf) return;
983   sGattIf->scanner->Scan(start);
984 }
985 
gattClientConnectNative(JNIEnv * env,jobject object,jint clientif,jstring address,jboolean isDirect,jint transport,jboolean opportunistic,jint initiating_phys)986 static void gattClientConnectNative(JNIEnv* env, jobject object, jint clientif,
987                                     jstring address, jboolean isDirect,
988                                     jint transport, jboolean opportunistic,
989                                     jint initiating_phys) {
990   if (!sGattIf) return;
991 
992   sGattIf->client->connect(clientif, str2addr(env, address), isDirect,
993                            transport, opportunistic, initiating_phys);
994 }
995 
gattClientDisconnectNative(JNIEnv * env,jobject object,jint clientIf,jstring address,jint conn_id)996 static void gattClientDisconnectNative(JNIEnv* env, jobject object,
997                                        jint clientIf, jstring address,
998                                        jint conn_id) {
999   if (!sGattIf) return;
1000   sGattIf->client->disconnect(clientIf, str2addr(env, address), conn_id);
1001 }
1002 
gattClientSetPreferredPhyNative(JNIEnv * env,jobject object,jint clientIf,jstring address,jint tx_phy,jint rx_phy,jint phy_options)1003 static void gattClientSetPreferredPhyNative(JNIEnv* env, jobject object,
1004                                             jint clientIf, jstring address,
1005                                             jint tx_phy, jint rx_phy,
1006                                             jint phy_options) {
1007   if (!sGattIf) return;
1008   sGattIf->client->set_preferred_phy(str2addr(env, address), tx_phy, rx_phy,
1009                                      phy_options);
1010 }
1011 
readClientPhyCb(uint8_t clientIf,RawAddress bda,uint8_t tx_phy,uint8_t rx_phy,uint8_t status)1012 static void readClientPhyCb(uint8_t clientIf, RawAddress bda, uint8_t tx_phy,
1013                             uint8_t rx_phy, uint8_t status) {
1014   CallbackEnv sCallbackEnv(__func__);
1015   if (!sCallbackEnv.valid()) return;
1016 
1017   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
1018                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
1019 
1020   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onClientPhyRead, clientIf,
1021                                address.get(), tx_phy, rx_phy, status);
1022 }
1023 
gattClientReadPhyNative(JNIEnv * env,jobject object,jint clientIf,jstring address)1024 static void gattClientReadPhyNative(JNIEnv* env, jobject object, jint clientIf,
1025                                     jstring address) {
1026   if (!sGattIf) return;
1027 
1028   RawAddress bda = str2addr(env, address);
1029   sGattIf->client->read_phy(bda, base::Bind(&readClientPhyCb, clientIf, bda));
1030 }
1031 
gattClientRefreshNative(JNIEnv * env,jobject object,jint clientIf,jstring address)1032 static void gattClientRefreshNative(JNIEnv* env, jobject object, jint clientIf,
1033                                     jstring address) {
1034   if (!sGattIf) return;
1035 
1036   sGattIf->client->refresh(clientIf, str2addr(env, address));
1037 }
1038 
gattClientSearchServiceNative(JNIEnv * env,jobject object,jint conn_id,jboolean search_all,jlong service_uuid_lsb,jlong service_uuid_msb)1039 static void gattClientSearchServiceNative(JNIEnv* env, jobject object,
1040                                           jint conn_id, jboolean search_all,
1041                                           jlong service_uuid_lsb,
1042                                           jlong service_uuid_msb) {
1043   if (!sGattIf) return;
1044 
1045   Uuid uuid = from_java_uuid(service_uuid_msb, service_uuid_lsb);
1046   sGattIf->client->search_service(conn_id, search_all ? 0 : &uuid);
1047 }
1048 
gattClientDiscoverServiceByUuidNative(JNIEnv * env,jobject object,jint conn_id,jlong service_uuid_lsb,jlong service_uuid_msb)1049 static void gattClientDiscoverServiceByUuidNative(JNIEnv* env, jobject object,
1050                                                   jint conn_id,
1051                                                   jlong service_uuid_lsb,
1052                                                   jlong service_uuid_msb) {
1053   if (!sGattIf) return;
1054 
1055   Uuid uuid = from_java_uuid(service_uuid_msb, service_uuid_lsb);
1056   sGattIf->client->btif_gattc_discover_service_by_uuid(conn_id, uuid);
1057 }
1058 
gattClientGetGattDbNative(JNIEnv * env,jobject object,jint conn_id)1059 static void gattClientGetGattDbNative(JNIEnv* env, jobject object,
1060                                       jint conn_id) {
1061   if (!sGattIf) return;
1062 
1063   sGattIf->client->get_gatt_db(conn_id);
1064 }
1065 
gattClientReadCharacteristicNative(JNIEnv * env,jobject object,jint conn_id,jint handle,jint authReq)1066 static void gattClientReadCharacteristicNative(JNIEnv* env, jobject object,
1067                                                jint conn_id, jint handle,
1068                                                jint authReq) {
1069   if (!sGattIf) return;
1070 
1071   sGattIf->client->read_characteristic(conn_id, handle, authReq);
1072 }
1073 
gattClientReadUsingCharacteristicUuidNative(JNIEnv * env,jobject object,jint conn_id,jlong uuid_lsb,jlong uuid_msb,jint s_handle,jint e_handle,jint authReq)1074 static void gattClientReadUsingCharacteristicUuidNative(
1075     JNIEnv* env, jobject object, jint conn_id, jlong uuid_lsb, jlong uuid_msb,
1076     jint s_handle, jint e_handle, jint authReq) {
1077   if (!sGattIf) return;
1078 
1079   Uuid uuid = from_java_uuid(uuid_msb, uuid_lsb);
1080   sGattIf->client->read_using_characteristic_uuid(conn_id, uuid, s_handle,
1081                                                   e_handle, authReq);
1082 }
1083 
gattClientReadDescriptorNative(JNIEnv * env,jobject object,jint conn_id,jint handle,jint authReq)1084 static void gattClientReadDescriptorNative(JNIEnv* env, jobject object,
1085                                            jint conn_id, jint handle,
1086                                            jint authReq) {
1087   if (!sGattIf) return;
1088 
1089   sGattIf->client->read_descriptor(conn_id, handle, authReq);
1090 }
1091 
gattClientWriteCharacteristicNative(JNIEnv * env,jobject object,jint conn_id,jint handle,jint write_type,jint auth_req,jbyteArray value)1092 static void gattClientWriteCharacteristicNative(JNIEnv* env, jobject object,
1093                                                 jint conn_id, jint handle,
1094                                                 jint write_type, jint auth_req,
1095                                                 jbyteArray value) {
1096   if (!sGattIf) return;
1097 
1098   if (value == NULL) {
1099     warn("gattClientWriteCharacteristicNative() ignoring NULL array");
1100     return;
1101   }
1102 
1103   uint16_t len = (uint16_t)env->GetArrayLength(value);
1104   jbyte* p_value = env->GetByteArrayElements(value, NULL);
1105   if (p_value == NULL) return;
1106 
1107   std::vector<uint8_t> vect_val(p_value, p_value + len);
1108   env->ReleaseByteArrayElements(value, p_value, 0);
1109 
1110   sGattIf->client->write_characteristic(conn_id, handle, write_type, auth_req,
1111                                         std::move(vect_val));
1112 }
1113 
gattClientExecuteWriteNative(JNIEnv * env,jobject object,jint conn_id,jboolean execute)1114 static void gattClientExecuteWriteNative(JNIEnv* env, jobject object,
1115                                          jint conn_id, jboolean execute) {
1116   if (!sGattIf) return;
1117   sGattIf->client->execute_write(conn_id, execute ? 1 : 0);
1118 }
1119 
gattClientWriteDescriptorNative(JNIEnv * env,jobject object,jint conn_id,jint handle,jint auth_req,jbyteArray value)1120 static void gattClientWriteDescriptorNative(JNIEnv* env, jobject object,
1121                                             jint conn_id, jint handle,
1122                                             jint auth_req, jbyteArray value) {
1123   if (!sGattIf) return;
1124 
1125   if (value == NULL) {
1126     warn("gattClientWriteDescriptorNative() ignoring NULL array");
1127     return;
1128   }
1129 
1130   uint16_t len = (uint16_t)env->GetArrayLength(value);
1131   jbyte* p_value = env->GetByteArrayElements(value, NULL);
1132   if (p_value == NULL) return;
1133 
1134   std::vector<uint8_t> vect_val(p_value, p_value + len);
1135   env->ReleaseByteArrayElements(value, p_value, 0);
1136 
1137   sGattIf->client->write_descriptor(conn_id, handle, auth_req,
1138                                     std::move(vect_val));
1139 }
1140 
gattClientRegisterForNotificationsNative(JNIEnv * env,jobject object,jint clientIf,jstring address,jint handle,jboolean enable)1141 static void gattClientRegisterForNotificationsNative(
1142     JNIEnv* env, jobject object, jint clientIf, jstring address, jint handle,
1143     jboolean enable) {
1144   if (!sGattIf) return;
1145 
1146   RawAddress bd_addr = str2addr(env, address);
1147   if (enable)
1148     sGattIf->client->register_for_notification(clientIf, bd_addr, handle);
1149   else
1150     sGattIf->client->deregister_for_notification(clientIf, bd_addr, handle);
1151 }
1152 
gattClientReadRemoteRssiNative(JNIEnv * env,jobject object,jint clientif,jstring address)1153 static void gattClientReadRemoteRssiNative(JNIEnv* env, jobject object,
1154                                            jint clientif, jstring address) {
1155   if (!sGattIf) return;
1156 
1157   sGattIf->client->read_remote_rssi(clientif, str2addr(env, address));
1158 }
1159 
set_scan_params_cmpl_cb(int client_if,uint8_t status)1160 void set_scan_params_cmpl_cb(int client_if, uint8_t status) {
1161   CallbackEnv sCallbackEnv(__func__);
1162   if (!sCallbackEnv.valid()) return;
1163   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanParamSetupCompleted,
1164                                status, client_if);
1165 }
1166 
gattSetScanParametersNative(JNIEnv * env,jobject object,jint client_if,jint scan_interval_unit,jint scan_window_unit)1167 static void gattSetScanParametersNative(JNIEnv* env, jobject object,
1168                                         jint client_if, jint scan_interval_unit,
1169                                         jint scan_window_unit) {
1170   if (!sGattIf) return;
1171   sGattIf->scanner->SetScanParameters(
1172       scan_interval_unit, scan_window_unit,
1173       base::Bind(&set_scan_params_cmpl_cb, client_if));
1174 }
1175 
scan_filter_param_cb(uint8_t client_if,uint8_t avbl_space,uint8_t action,uint8_t status)1176 void scan_filter_param_cb(uint8_t client_if, uint8_t avbl_space, uint8_t action,
1177                           uint8_t status) {
1178   CallbackEnv sCallbackEnv(__func__);
1179   if (!sCallbackEnv.valid()) return;
1180   sCallbackEnv->CallVoidMethod(mCallbacksObj,
1181                                method_onScanFilterParamsConfigured, action,
1182                                status, client_if, avbl_space);
1183 }
1184 
gattClientScanFilterParamAddNative(JNIEnv * env,jobject object,jobject params)1185 static void gattClientScanFilterParamAddNative(JNIEnv* env, jobject object,
1186                                                jobject params) {
1187   if (!sGattIf) return;
1188   const int add_scan_filter_params_action = 0;
1189   auto filt_params = std::make_unique<btgatt_filt_param_setup_t>();
1190 
1191   jmethodID methodId = 0;
1192   ScopedLocalRef<jclass> filtparam(env, env->GetObjectClass(params));
1193 
1194   methodId = env->GetMethodID(filtparam.get(), "getClientIf", "()I");
1195   uint8_t client_if = env->CallIntMethod(params, methodId);
1196 
1197   methodId = env->GetMethodID(filtparam.get(), "getFiltIndex", "()I");
1198   uint8_t filt_index = env->CallIntMethod(params, methodId);
1199 
1200   methodId = env->GetMethodID(filtparam.get(), "getFeatSeln", "()I");
1201   filt_params->feat_seln = env->CallIntMethod(params, methodId);
1202 
1203   methodId = env->GetMethodID(filtparam.get(), "getListLogicType", "()I");
1204   filt_params->list_logic_type = env->CallIntMethod(params, methodId);
1205 
1206   methodId = env->GetMethodID(filtparam.get(), "getFiltLogicType", "()I");
1207   filt_params->filt_logic_type = env->CallIntMethod(params, methodId);
1208 
1209   methodId = env->GetMethodID(filtparam.get(), "getDelyMode", "()I");
1210   filt_params->dely_mode = env->CallIntMethod(params, methodId);
1211 
1212   methodId = env->GetMethodID(filtparam.get(), "getFoundTimeout", "()I");
1213   filt_params->found_timeout = env->CallIntMethod(params, methodId);
1214 
1215   methodId = env->GetMethodID(filtparam.get(), "getLostTimeout", "()I");
1216   filt_params->lost_timeout = env->CallIntMethod(params, methodId);
1217 
1218   methodId = env->GetMethodID(filtparam.get(), "getFoundTimeOutCnt", "()I");
1219   filt_params->found_timeout_cnt = env->CallIntMethod(params, methodId);
1220 
1221   methodId = env->GetMethodID(filtparam.get(), "getNumOfTrackEntries", "()I");
1222   filt_params->num_of_tracking_entries = env->CallIntMethod(params, methodId);
1223 
1224   methodId = env->GetMethodID(filtparam.get(), "getRSSIHighValue", "()I");
1225   filt_params->rssi_high_thres = env->CallIntMethod(params, methodId);
1226 
1227   methodId = env->GetMethodID(filtparam.get(), "getRSSILowValue", "()I");
1228   filt_params->rssi_low_thres = env->CallIntMethod(params, methodId);
1229 
1230   sGattIf->scanner->ScanFilterParamSetup(
1231       client_if, add_scan_filter_params_action, filt_index,
1232       std::move(filt_params), base::Bind(&scan_filter_param_cb, client_if));
1233 }
1234 
gattClientScanFilterParamDeleteNative(JNIEnv * env,jobject object,jint client_if,jint filt_index)1235 static void gattClientScanFilterParamDeleteNative(JNIEnv* env, jobject object,
1236                                                   jint client_if,
1237                                                   jint filt_index) {
1238   if (!sGattIf) return;
1239   const int delete_scan_filter_params_action = 1;
1240   sGattIf->scanner->ScanFilterParamSetup(
1241       client_if, delete_scan_filter_params_action, filt_index, nullptr,
1242       base::Bind(&scan_filter_param_cb, client_if));
1243 }
1244 
gattClientScanFilterParamClearAllNative(JNIEnv * env,jobject object,jint client_if)1245 static void gattClientScanFilterParamClearAllNative(JNIEnv* env, jobject object,
1246                                                     jint client_if) {
1247   if (!sGattIf) return;
1248   const int clear_scan_filter_params_action = 2;
1249   sGattIf->scanner->ScanFilterParamSetup(
1250       client_if, clear_scan_filter_params_action, 0 /* index, unused */,
1251       nullptr, base::Bind(&scan_filter_param_cb, client_if));
1252 }
1253 
scan_filter_cfg_cb(uint8_t client_if,uint8_t filt_type,uint8_t avbl_space,uint8_t action,uint8_t status)1254 static void scan_filter_cfg_cb(uint8_t client_if, uint8_t filt_type,
1255                                uint8_t avbl_space, uint8_t action,
1256                                uint8_t status) {
1257   CallbackEnv sCallbackEnv(__func__);
1258   if (!sCallbackEnv.valid()) return;
1259   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterConfig, action,
1260                                status, client_if, filt_type, avbl_space);
1261 }
1262 
gattClientScanFilterAddNative(JNIEnv * env,jobject object,jint client_if,jobjectArray filters,jint filter_index)1263 static void gattClientScanFilterAddNative(JNIEnv* env, jobject object,
1264                                           jint client_if, jobjectArray filters,
1265                                           jint filter_index) {
1266   if (!sGattIf) return;
1267 
1268   jclass uuidClazz = env->FindClass("java/util/UUID");
1269   jmethodID uuidGetMsb =
1270       env->GetMethodID(uuidClazz, "getMostSignificantBits", "()J");
1271   jmethodID uuidGetLsb =
1272       env->GetMethodID(uuidClazz, "getLeastSignificantBits", "()J");
1273 
1274   std::vector<ApcfCommand> native_filters;
1275 
1276   int numFilters = env->GetArrayLength(filters);
1277   if (numFilters == 0) {
1278     sGattIf->scanner->ScanFilterAdd(filter_index, std::move(native_filters),
1279                                     base::Bind(&scan_filter_cfg_cb, client_if));
1280     return;
1281   }
1282 
1283   jclass entryClazz =
1284       env->GetObjectClass(env->GetObjectArrayElement(filters, 0));
1285 
1286   jfieldID typeFid = env->GetFieldID(entryClazz, "type", "B");
1287   jfieldID addressFid =
1288       env->GetFieldID(entryClazz, "address", "Ljava/lang/String;");
1289   jfieldID addrTypeFid = env->GetFieldID(entryClazz, "addr_type", "B");
1290   jfieldID uuidFid = env->GetFieldID(entryClazz, "uuid", "Ljava/util/UUID;");
1291   jfieldID uuidMaskFid =
1292       env->GetFieldID(entryClazz, "uuid_mask", "Ljava/util/UUID;");
1293   jfieldID nameFid = env->GetFieldID(entryClazz, "name", "Ljava/lang/String;");
1294   jfieldID companyFid = env->GetFieldID(entryClazz, "company", "I");
1295   jfieldID companyMaskFid = env->GetFieldID(entryClazz, "company_mask", "I");
1296   jfieldID dataFid = env->GetFieldID(entryClazz, "data", "[B");
1297   jfieldID dataMaskFid = env->GetFieldID(entryClazz, "data_mask", "[B");
1298 
1299   for (int i = 0; i < numFilters; ++i) {
1300     ApcfCommand curr;
1301 
1302     ScopedLocalRef<jobject> current(env,
1303                                     env->GetObjectArrayElement(filters, i));
1304 
1305     curr.type = env->GetByteField(current.get(), typeFid);
1306 
1307     ScopedLocalRef<jstring> address(
1308         env, (jstring)env->GetObjectField(current.get(), addressFid));
1309     if (address.get() != NULL) {
1310       curr.address = str2addr(env, address.get());
1311     }
1312 
1313     curr.addr_type = env->GetByteField(current.get(), addrTypeFid);
1314 
1315     ScopedLocalRef<jobject> uuid(env,
1316                                  env->GetObjectField(current.get(), uuidFid));
1317     if (uuid.get() != NULL) {
1318       jlong uuid_msb = env->CallLongMethod(uuid.get(), uuidGetMsb);
1319       jlong uuid_lsb = env->CallLongMethod(uuid.get(), uuidGetLsb);
1320       curr.uuid = from_java_uuid(uuid_msb, uuid_lsb);
1321     }
1322 
1323     ScopedLocalRef<jobject> uuid_mask(
1324         env, env->GetObjectField(current.get(), uuidMaskFid));
1325     if (uuid.get() != NULL) {
1326       jlong uuid_msb = env->CallLongMethod(uuid_mask.get(), uuidGetMsb);
1327       jlong uuid_lsb = env->CallLongMethod(uuid_mask.get(), uuidGetLsb);
1328       curr.uuid_mask = from_java_uuid(uuid_msb, uuid_lsb);
1329     }
1330 
1331     ScopedLocalRef<jstring> name(
1332         env, (jstring)env->GetObjectField(current.get(), nameFid));
1333     if (name.get() != NULL) {
1334       const char* c_name = env->GetStringUTFChars(name.get(), NULL);
1335       if (c_name != NULL && strlen(c_name) != 0) {
1336         curr.name = std::vector<uint8_t>(c_name, c_name + strlen(c_name));
1337         env->ReleaseStringUTFChars(name.get(), c_name);
1338       }
1339     }
1340 
1341     curr.company = env->GetIntField(current.get(), companyFid);
1342 
1343     curr.company_mask = env->GetIntField(current.get(), companyMaskFid);
1344 
1345     ScopedLocalRef<jbyteArray> data(
1346         env, (jbyteArray)env->GetObjectField(current.get(), dataFid));
1347     if (data.get() != NULL) {
1348       jbyte* data_array = env->GetByteArrayElements(data.get(), 0);
1349       int data_len = env->GetArrayLength(data.get());
1350       if (data_array && data_len) {
1351         curr.data = std::vector<uint8_t>(data_array, data_array + data_len);
1352         env->ReleaseByteArrayElements(data.get(), data_array, JNI_ABORT);
1353       }
1354     }
1355 
1356     ScopedLocalRef<jbyteArray> data_mask(
1357         env, (jbyteArray)env->GetObjectField(current.get(), dataMaskFid));
1358     if (data_mask.get() != NULL) {
1359       jbyte* data_array = env->GetByteArrayElements(data_mask.get(), 0);
1360       int data_len = env->GetArrayLength(data_mask.get());
1361       if (data_array && data_len) {
1362         curr.data_mask =
1363             std::vector<uint8_t>(data_array, data_array + data_len);
1364         env->ReleaseByteArrayElements(data_mask.get(), data_array, JNI_ABORT);
1365       }
1366     }
1367     native_filters.push_back(curr);
1368   }
1369 
1370   sGattIf->scanner->ScanFilterAdd(filter_index, std::move(native_filters),
1371                                   base::Bind(&scan_filter_cfg_cb, client_if));
1372 }
1373 
gattClientScanFilterClearNative(JNIEnv * env,jobject object,jint client_if,jint filt_index)1374 static void gattClientScanFilterClearNative(JNIEnv* env, jobject object,
1375                                             jint client_if, jint filt_index) {
1376   if (!sGattIf) return;
1377   sGattIf->scanner->ScanFilterClear(filt_index,
1378                                     base::Bind(&scan_filter_cfg_cb, client_if));
1379 }
1380 
scan_enable_cb(uint8_t client_if,uint8_t action,uint8_t status)1381 void scan_enable_cb(uint8_t client_if, uint8_t action, uint8_t status) {
1382   CallbackEnv sCallbackEnv(__func__);
1383   if (!sCallbackEnv.valid()) return;
1384   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onScanFilterEnableDisabled,
1385                                action, status, client_if);
1386 }
1387 
gattClientScanFilterEnableNative(JNIEnv * env,jobject object,jint client_if,jboolean enable)1388 static void gattClientScanFilterEnableNative(JNIEnv* env, jobject object,
1389                                              jint client_if, jboolean enable) {
1390   if (!sGattIf) return;
1391   sGattIf->scanner->ScanFilterEnable(enable,
1392                                      base::Bind(&scan_enable_cb, client_if));
1393 }
1394 
gattClientConfigureMTUNative(JNIEnv * env,jobject object,jint conn_id,jint mtu)1395 static void gattClientConfigureMTUNative(JNIEnv* env, jobject object,
1396                                          jint conn_id, jint mtu) {
1397   if (!sGattIf) return;
1398   sGattIf->client->configure_mtu(conn_id, mtu);
1399 }
1400 
gattConnectionParameterUpdateNative(JNIEnv * env,jobject object,jint client_if,jstring address,jint min_interval,jint max_interval,jint latency,jint timeout,jint min_ce_len,jint max_ce_len)1401 static void gattConnectionParameterUpdateNative(JNIEnv* env, jobject object,
1402                                                 jint client_if, jstring address,
1403                                                 jint min_interval,
1404                                                 jint max_interval, jint latency,
1405                                                 jint timeout, jint min_ce_len,
1406                                                 jint max_ce_len) {
1407   if (!sGattIf) return;
1408   sGattIf->client->conn_parameter_update(
1409       str2addr(env, address), min_interval, max_interval, latency, timeout,
1410       (uint16_t)min_ce_len, (uint16_t)max_ce_len);
1411 }
1412 
batchscan_cfg_storage_cb(uint8_t client_if,uint8_t status)1413 void batchscan_cfg_storage_cb(uint8_t client_if, uint8_t status) {
1414   CallbackEnv sCallbackEnv(__func__);
1415   if (!sCallbackEnv.valid()) return;
1416   sCallbackEnv->CallVoidMethod(
1417       mCallbacksObj, method_onBatchScanStorageConfigured, status, client_if);
1418 }
1419 
gattClientConfigBatchScanStorageNative(JNIEnv * env,jobject object,jint client_if,jint max_full_reports_percent,jint max_trunc_reports_percent,jint notify_threshold_level_percent)1420 static void gattClientConfigBatchScanStorageNative(
1421     JNIEnv* env, jobject object, jint client_if, jint max_full_reports_percent,
1422     jint max_trunc_reports_percent, jint notify_threshold_level_percent) {
1423   if (!sGattIf) return;
1424   sGattIf->scanner->BatchscanConfigStorage(
1425       client_if, max_full_reports_percent, max_trunc_reports_percent,
1426       notify_threshold_level_percent,
1427       base::Bind(&batchscan_cfg_storage_cb, client_if));
1428 }
1429 
batchscan_enable_cb(uint8_t client_if,uint8_t status)1430 void batchscan_enable_cb(uint8_t client_if, uint8_t status) {
1431   CallbackEnv sCallbackEnv(__func__);
1432   if (!sCallbackEnv.valid()) return;
1433   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onBatchScanStartStopped,
1434                                0 /* unused */, status, client_if);
1435 }
1436 
gattClientStartBatchScanNative(JNIEnv * env,jobject object,jint client_if,jint scan_mode,jint scan_interval_unit,jint scan_window_unit,jint addr_type,jint discard_rule)1437 static void gattClientStartBatchScanNative(JNIEnv* env, jobject object,
1438                                            jint client_if, jint scan_mode,
1439                                            jint scan_interval_unit,
1440                                            jint scan_window_unit,
1441                                            jint addr_type, jint discard_rule) {
1442   if (!sGattIf) return;
1443   sGattIf->scanner->BatchscanEnable(
1444       scan_mode, scan_interval_unit, scan_window_unit, addr_type, discard_rule,
1445       base::Bind(&batchscan_enable_cb, client_if));
1446 }
1447 
gattClientStopBatchScanNative(JNIEnv * env,jobject object,jint client_if)1448 static void gattClientStopBatchScanNative(JNIEnv* env, jobject object,
1449                                           jint client_if) {
1450   if (!sGattIf) return;
1451   sGattIf->scanner->BatchscanDisable(
1452       base::Bind(&batchscan_enable_cb, client_if));
1453 }
1454 
gattClientReadScanReportsNative(JNIEnv * env,jobject object,jint client_if,jint scan_type)1455 static void gattClientReadScanReportsNative(JNIEnv* env, jobject object,
1456                                             jint client_if, jint scan_type) {
1457   if (!sGattIf) return;
1458   sGattIf->scanner->BatchscanReadReports(client_if, scan_type);
1459 }
1460 
1461 /**
1462  * Native server functions
1463  */
gattServerRegisterAppNative(JNIEnv * env,jobject object,jlong app_uuid_lsb,jlong app_uuid_msb)1464 static void gattServerRegisterAppNative(JNIEnv* env, jobject object,
1465                                         jlong app_uuid_lsb,
1466                                         jlong app_uuid_msb) {
1467   if (!sGattIf) return;
1468   Uuid uuid = from_java_uuid(app_uuid_msb, app_uuid_lsb);
1469   sGattIf->server->register_server(uuid);
1470 }
1471 
gattServerUnregisterAppNative(JNIEnv * env,jobject object,jint serverIf)1472 static void gattServerUnregisterAppNative(JNIEnv* env, jobject object,
1473                                           jint serverIf) {
1474   if (!sGattIf) return;
1475   sGattIf->server->unregister_server(serverIf);
1476 }
1477 
gattServerConnectNative(JNIEnv * env,jobject object,jint server_if,jstring address,jboolean is_direct,jint transport)1478 static void gattServerConnectNative(JNIEnv* env, jobject object, jint server_if,
1479                                     jstring address, jboolean is_direct,
1480                                     jint transport) {
1481   if (!sGattIf) return;
1482 
1483   RawAddress bd_addr = str2addr(env, address);
1484   sGattIf->server->connect(server_if, bd_addr, is_direct, transport);
1485 }
1486 
gattServerDisconnectNative(JNIEnv * env,jobject object,jint serverIf,jstring address,jint conn_id)1487 static void gattServerDisconnectNative(JNIEnv* env, jobject object,
1488                                        jint serverIf, jstring address,
1489                                        jint conn_id) {
1490   if (!sGattIf) return;
1491   sGattIf->server->disconnect(serverIf, str2addr(env, address), conn_id);
1492 }
1493 
gattServerSetPreferredPhyNative(JNIEnv * env,jobject object,jint serverIf,jstring address,jint tx_phy,jint rx_phy,jint phy_options)1494 static void gattServerSetPreferredPhyNative(JNIEnv* env, jobject object,
1495                                             jint serverIf, jstring address,
1496                                             jint tx_phy, jint rx_phy,
1497                                             jint phy_options) {
1498   if (!sGattIf) return;
1499   RawAddress bda = str2addr(env, address);
1500   sGattIf->server->set_preferred_phy(bda, tx_phy, rx_phy, phy_options);
1501 }
1502 
readServerPhyCb(uint8_t serverIf,RawAddress bda,uint8_t tx_phy,uint8_t rx_phy,uint8_t status)1503 static void readServerPhyCb(uint8_t serverIf, RawAddress bda, uint8_t tx_phy,
1504                             uint8_t rx_phy, uint8_t status) {
1505   CallbackEnv sCallbackEnv(__func__);
1506   if (!sCallbackEnv.valid()) return;
1507 
1508   ScopedLocalRef<jstring> address(sCallbackEnv.get(),
1509                                   bdaddr2newjstr(sCallbackEnv.get(), &bda));
1510 
1511   sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onServerPhyRead, serverIf,
1512                                address.get(), tx_phy, rx_phy, status);
1513 }
1514 
gattServerReadPhyNative(JNIEnv * env,jobject object,jint serverIf,jstring address)1515 static void gattServerReadPhyNative(JNIEnv* env, jobject object, jint serverIf,
1516                                     jstring address) {
1517   if (!sGattIf) return;
1518 
1519   RawAddress bda = str2addr(env, address);
1520   sGattIf->server->read_phy(bda, base::Bind(&readServerPhyCb, serverIf, bda));
1521 }
1522 
gattServerAddServiceNative(JNIEnv * env,jobject object,jint server_if,jobject gatt_db_elements)1523 static void gattServerAddServiceNative(JNIEnv* env, jobject object,
1524                                        jint server_if,
1525                                        jobject gatt_db_elements) {
1526   if (!sGattIf) return;
1527 
1528   jclass arrayListclazz = env->FindClass("java/util/List");
1529   jmethodID arrayGet =
1530       env->GetMethodID(arrayListclazz, "get", "(I)Ljava/lang/Object;");
1531   jmethodID arraySize = env->GetMethodID(arrayListclazz, "size", "()I");
1532 
1533   int count = env->CallIntMethod(gatt_db_elements, arraySize);
1534   std::vector<btgatt_db_element_t> db;
1535 
1536   jclass uuidClazz = env->FindClass("java/util/UUID");
1537   jmethodID uuidGetMsb =
1538       env->GetMethodID(uuidClazz, "getMostSignificantBits", "()J");
1539   jmethodID uuidGetLsb =
1540       env->GetMethodID(uuidClazz, "getLeastSignificantBits", "()J");
1541 
1542   jobject objectForClass =
1543       env->CallObjectMethod(mCallbacksObj, method_getSampleGattDbElement);
1544   jclass gattDbElementClazz = env->GetObjectClass(objectForClass);
1545 
1546   for (int i = 0; i < count; i++) {
1547     btgatt_db_element_t curr;
1548 
1549     jint index = i;
1550     ScopedLocalRef<jobject> element(
1551         env, env->CallObjectMethod(gatt_db_elements, arrayGet, index));
1552 
1553     jfieldID fid;
1554 
1555     fid = env->GetFieldID(gattDbElementClazz, "id", "I");
1556     curr.id = env->GetIntField(element.get(), fid);
1557 
1558     fid = env->GetFieldID(gattDbElementClazz, "uuid", "Ljava/util/UUID;");
1559     ScopedLocalRef<jobject> uuid(env, env->GetObjectField(element.get(), fid));
1560     if (uuid.get() != NULL) {
1561       jlong uuid_msb = env->CallLongMethod(uuid.get(), uuidGetMsb);
1562       jlong uuid_lsb = env->CallLongMethod(uuid.get(), uuidGetLsb);
1563       curr.uuid = from_java_uuid(uuid_msb, uuid_lsb);
1564     }
1565 
1566     fid = env->GetFieldID(gattDbElementClazz, "type", "I");
1567     curr.type =
1568         (bt_gatt_db_attribute_type_t)env->GetIntField(element.get(), fid);
1569 
1570     fid = env->GetFieldID(gattDbElementClazz, "attributeHandle", "I");
1571     curr.attribute_handle = env->GetIntField(element.get(), fid);
1572 
1573     fid = env->GetFieldID(gattDbElementClazz, "startHandle", "I");
1574     curr.start_handle = env->GetIntField(element.get(), fid);
1575 
1576     fid = env->GetFieldID(gattDbElementClazz, "endHandle", "I");
1577     curr.end_handle = env->GetIntField(element.get(), fid);
1578 
1579     fid = env->GetFieldID(gattDbElementClazz, "properties", "I");
1580     curr.properties = env->GetIntField(element.get(), fid);
1581 
1582     fid = env->GetFieldID(gattDbElementClazz, "permissions", "I");
1583     curr.permissions = env->GetIntField(element.get(), fid);
1584 
1585     db.push_back(curr);
1586   }
1587 
1588   sGattIf->server->add_service(server_if, std::move(db));
1589 }
1590 
gattServerStopServiceNative(JNIEnv * env,jobject object,jint server_if,jint svc_handle)1591 static void gattServerStopServiceNative(JNIEnv* env, jobject object,
1592                                         jint server_if, jint svc_handle) {
1593   if (!sGattIf) return;
1594   sGattIf->server->stop_service(server_if, svc_handle);
1595 }
1596 
gattServerDeleteServiceNative(JNIEnv * env,jobject object,jint server_if,jint svc_handle)1597 static void gattServerDeleteServiceNative(JNIEnv* env, jobject object,
1598                                           jint server_if, jint svc_handle) {
1599   if (!sGattIf) return;
1600   sGattIf->server->delete_service(server_if, svc_handle);
1601 }
1602 
gattServerSendIndicationNative(JNIEnv * env,jobject object,jint server_if,jint attr_handle,jint conn_id,jbyteArray val)1603 static void gattServerSendIndicationNative(JNIEnv* env, jobject object,
1604                                            jint server_if, jint attr_handle,
1605                                            jint conn_id, jbyteArray val) {
1606   if (!sGattIf) return;
1607 
1608   jbyte* array = env->GetByteArrayElements(val, 0);
1609   int val_len = env->GetArrayLength(val);
1610 
1611   std::vector<uint8_t> vect_val((uint8_t*)array, (uint8_t*)array + val_len);
1612   env->ReleaseByteArrayElements(val, array, JNI_ABORT);
1613 
1614   sGattIf->server->send_indication(server_if, attr_handle, conn_id,
1615                                    /*confirm*/ 1, std::move(vect_val));
1616 }
1617 
gattServerSendNotificationNative(JNIEnv * env,jobject object,jint server_if,jint attr_handle,jint conn_id,jbyteArray val)1618 static void gattServerSendNotificationNative(JNIEnv* env, jobject object,
1619                                              jint server_if, jint attr_handle,
1620                                              jint conn_id, jbyteArray val) {
1621   if (!sGattIf) return;
1622 
1623   jbyte* array = env->GetByteArrayElements(val, 0);
1624   int val_len = env->GetArrayLength(val);
1625 
1626   std::vector<uint8_t> vect_val((uint8_t*)array, (uint8_t*)array + val_len);
1627   env->ReleaseByteArrayElements(val, array, JNI_ABORT);
1628 
1629   sGattIf->server->send_indication(server_if, attr_handle, conn_id,
1630                                    /*confirm*/ 0, std::move(vect_val));
1631 }
1632 
gattServerSendResponseNative(JNIEnv * env,jobject object,jint server_if,jint conn_id,jint trans_id,jint status,jint handle,jint offset,jbyteArray val,jint auth_req)1633 static void gattServerSendResponseNative(JNIEnv* env, jobject object,
1634                                          jint server_if, jint conn_id,
1635                                          jint trans_id, jint status,
1636                                          jint handle, jint offset,
1637                                          jbyteArray val, jint auth_req) {
1638   if (!sGattIf) return;
1639 
1640   btgatt_response_t response;
1641 
1642   response.attr_value.handle = handle;
1643   response.attr_value.auth_req = auth_req;
1644   response.attr_value.offset = offset;
1645   response.attr_value.len = 0;
1646 
1647   if (val != NULL) {
1648     if (env->GetArrayLength(val) < BTGATT_MAX_ATTR_LEN) {
1649       response.attr_value.len = (uint16_t)env->GetArrayLength(val);
1650     } else {
1651       android_errorWriteLog(0x534e4554, "78787521");
1652       response.attr_value.len = BTGATT_MAX_ATTR_LEN;
1653     }
1654 
1655     jbyte* array = env->GetByteArrayElements(val, 0);
1656 
1657     for (int i = 0; i != response.attr_value.len; ++i)
1658       response.attr_value.value[i] = (uint8_t)array[i];
1659     env->ReleaseByteArrayElements(val, array, JNI_ABORT);
1660   }
1661 
1662   sGattIf->server->send_response(conn_id, trans_id, status, response);
1663 }
1664 
advertiseClassInitNative(JNIEnv * env,jclass clazz)1665 static void advertiseClassInitNative(JNIEnv* env, jclass clazz) {
1666   method_onAdvertisingSetStarted =
1667       env->GetMethodID(clazz, "onAdvertisingSetStarted", "(IIII)V");
1668   method_onOwnAddressRead =
1669       env->GetMethodID(clazz, "onOwnAddressRead", "(IILjava/lang/String;)V");
1670   method_onAdvertisingEnabled =
1671       env->GetMethodID(clazz, "onAdvertisingEnabled", "(IZI)V");
1672   method_onAdvertisingDataSet =
1673       env->GetMethodID(clazz, "onAdvertisingDataSet", "(II)V");
1674   method_onScanResponseDataSet =
1675       env->GetMethodID(clazz, "onScanResponseDataSet", "(II)V");
1676   method_onAdvertisingParametersUpdated =
1677       env->GetMethodID(clazz, "onAdvertisingParametersUpdated", "(III)V");
1678   method_onPeriodicAdvertisingParametersUpdated = env->GetMethodID(
1679       clazz, "onPeriodicAdvertisingParametersUpdated", "(II)V");
1680   method_onPeriodicAdvertisingDataSet =
1681       env->GetMethodID(clazz, "onPeriodicAdvertisingDataSet", "(II)V");
1682   method_onPeriodicAdvertisingEnabled =
1683       env->GetMethodID(clazz, "onPeriodicAdvertisingEnabled", "(IZI)V");
1684 }
1685 
advertiseInitializeNative(JNIEnv * env,jobject object)1686 static void advertiseInitializeNative(JNIEnv* env, jobject object) {
1687   if (mAdvertiseCallbacksObj != NULL) {
1688     ALOGW("Cleaning up Advertise callback object");
1689     env->DeleteGlobalRef(mAdvertiseCallbacksObj);
1690     mAdvertiseCallbacksObj = NULL;
1691   }
1692 
1693   mAdvertiseCallbacksObj = env->NewGlobalRef(object);
1694 }
1695 
advertiseCleanupNative(JNIEnv * env,jobject object)1696 static void advertiseCleanupNative(JNIEnv* env, jobject object) {
1697   if (mAdvertiseCallbacksObj != NULL) {
1698     env->DeleteGlobalRef(mAdvertiseCallbacksObj);
1699     mAdvertiseCallbacksObj = NULL;
1700   }
1701 }
1702 
1703 static uint32_t INTERVAL_MAX = 0xFFFFFF;
1704 // Always give controller 31.25ms difference between min and max
1705 static uint32_t INTERVAL_DELTA = 50;
1706 
parseParams(JNIEnv * env,jobject i)1707 static AdvertiseParameters parseParams(JNIEnv* env, jobject i) {
1708   AdvertiseParameters p;
1709 
1710   jclass clazz = env->GetObjectClass(i);
1711   jmethodID methodId;
1712 
1713   methodId = env->GetMethodID(clazz, "isConnectable", "()Z");
1714   jboolean isConnectable = env->CallBooleanMethod(i, methodId);
1715   methodId = env->GetMethodID(clazz, "isScannable", "()Z");
1716   jboolean isScannable = env->CallBooleanMethod(i, methodId);
1717   methodId = env->GetMethodID(clazz, "isLegacy", "()Z");
1718   jboolean isLegacy = env->CallBooleanMethod(i, methodId);
1719   methodId = env->GetMethodID(clazz, "isAnonymous", "()Z");
1720   jboolean isAnonymous = env->CallBooleanMethod(i, methodId);
1721   methodId = env->GetMethodID(clazz, "includeTxPower", "()Z");
1722   jboolean includeTxPower = env->CallBooleanMethod(i, methodId);
1723   methodId = env->GetMethodID(clazz, "getPrimaryPhy", "()I");
1724   uint8_t primaryPhy = env->CallIntMethod(i, methodId);
1725   methodId = env->GetMethodID(clazz, "getSecondaryPhy", "()I");
1726   uint8_t secondaryPhy = env->CallIntMethod(i, methodId);
1727   methodId = env->GetMethodID(clazz, "getInterval", "()I");
1728   uint32_t interval = env->CallIntMethod(i, methodId);
1729   methodId = env->GetMethodID(clazz, "getTxPowerLevel", "()I");
1730   int8_t txPowerLevel = env->CallIntMethod(i, methodId);
1731 
1732   uint16_t props = 0;
1733   if (isConnectable) props |= 0x01;
1734   if (isScannable) props |= 0x02;
1735   if (isLegacy) props |= 0x10;
1736   if (isAnonymous) props |= 0x20;
1737   if (includeTxPower) props |= 0x40;
1738 
1739   if (interval > INTERVAL_MAX - INTERVAL_DELTA) {
1740     interval = INTERVAL_MAX - INTERVAL_DELTA;
1741   }
1742 
1743   p.advertising_event_properties = props;
1744   p.min_interval = interval;
1745   p.max_interval = interval + INTERVAL_DELTA;
1746   p.channel_map = 0x07; /* all channels */
1747   p.tx_power = txPowerLevel;
1748   p.primary_advertising_phy = primaryPhy;
1749   p.secondary_advertising_phy = secondaryPhy;
1750   p.scan_request_notification_enable = false;
1751   return p;
1752 }
1753 
parsePeriodicParams(JNIEnv * env,jobject i)1754 static PeriodicAdvertisingParameters parsePeriodicParams(JNIEnv* env,
1755                                                          jobject i) {
1756   PeriodicAdvertisingParameters p;
1757 
1758   if (i == NULL) {
1759     p.enable = false;
1760     return p;
1761   }
1762 
1763   jclass clazz = env->GetObjectClass(i);
1764   jmethodID methodId;
1765 
1766   methodId = env->GetMethodID(clazz, "getIncludeTxPower", "()Z");
1767   jboolean includeTxPower = env->CallBooleanMethod(i, methodId);
1768   methodId = env->GetMethodID(clazz, "getInterval", "()I");
1769   uint16_t interval = env->CallIntMethod(i, methodId);
1770 
1771   p.enable = true;
1772   p.min_interval = interval;
1773   p.max_interval = interval + 16; /* 20ms difference betwen min and max */
1774   uint16_t props = 0;
1775   if (includeTxPower) props |= 0x40;
1776   p.periodic_advertising_properties = props;
1777   return p;
1778 }
1779 
ble_advertising_set_started_cb(int reg_id,uint8_t advertiser_id,int8_t tx_power,uint8_t status)1780 static void ble_advertising_set_started_cb(int reg_id, uint8_t advertiser_id,
1781                                            int8_t tx_power, uint8_t status) {
1782   CallbackEnv sCallbackEnv(__func__);
1783   if (!sCallbackEnv.valid()) return;
1784   sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
1785                                method_onAdvertisingSetStarted, reg_id,
1786                                advertiser_id, tx_power, status);
1787 }
1788 
ble_advertising_set_timeout_cb(uint8_t advertiser_id,uint8_t status)1789 static void ble_advertising_set_timeout_cb(uint8_t advertiser_id,
1790                                            uint8_t status) {
1791   CallbackEnv sCallbackEnv(__func__);
1792   if (!sCallbackEnv.valid()) return;
1793   sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
1794                                method_onAdvertisingEnabled, advertiser_id,
1795                                false, status);
1796 }
1797 
startAdvertisingSetNative(JNIEnv * env,jobject object,jobject parameters,jbyteArray adv_data,jbyteArray scan_resp,jobject periodic_parameters,jbyteArray periodic_data,jint duration,jint maxExtAdvEvents,jint reg_id)1798 static void startAdvertisingSetNative(JNIEnv* env, jobject object,
1799                                       jobject parameters, jbyteArray adv_data,
1800                                       jbyteArray scan_resp,
1801                                       jobject periodic_parameters,
1802                                       jbyteArray periodic_data, jint duration,
1803                                       jint maxExtAdvEvents, jint reg_id) {
1804   if (!sGattIf) return;
1805 
1806   jbyte* scan_resp_data = env->GetByteArrayElements(scan_resp, NULL);
1807   uint16_t scan_resp_len = (uint16_t)env->GetArrayLength(scan_resp);
1808   std::vector<uint8_t> scan_resp_vec(scan_resp_data,
1809                                      scan_resp_data + scan_resp_len);
1810   env->ReleaseByteArrayElements(scan_resp, scan_resp_data, JNI_ABORT);
1811 
1812   AdvertiseParameters params = parseParams(env, parameters);
1813   PeriodicAdvertisingParameters periodicParams =
1814       parsePeriodicParams(env, periodic_parameters);
1815 
1816   jbyte* adv_data_data = env->GetByteArrayElements(adv_data, NULL);
1817   uint16_t adv_data_len = (uint16_t)env->GetArrayLength(adv_data);
1818   std::vector<uint8_t> data_vec(adv_data_data, adv_data_data + adv_data_len);
1819   env->ReleaseByteArrayElements(adv_data, adv_data_data, JNI_ABORT);
1820 
1821   jbyte* periodic_data_data = env->GetByteArrayElements(periodic_data, NULL);
1822   uint16_t periodic_data_len = (uint16_t)env->GetArrayLength(periodic_data);
1823   std::vector<uint8_t> periodic_data_vec(
1824       periodic_data_data, periodic_data_data + periodic_data_len);
1825   env->ReleaseByteArrayElements(periodic_data, periodic_data_data, JNI_ABORT);
1826 
1827   sGattIf->advertiser->StartAdvertisingSet(
1828       base::Bind(&ble_advertising_set_started_cb, reg_id), params, data_vec,
1829       scan_resp_vec, periodicParams, periodic_data_vec, duration,
1830       maxExtAdvEvents, base::Bind(ble_advertising_set_timeout_cb));
1831 }
1832 
stopAdvertisingSetNative(JNIEnv * env,jobject object,jint advertiser_id)1833 static void stopAdvertisingSetNative(JNIEnv* env, jobject object,
1834                                      jint advertiser_id) {
1835   if (!sGattIf) return;
1836 
1837   sGattIf->advertiser->Unregister(advertiser_id);
1838 }
1839 
getOwnAddressCb(uint8_t advertiser_id,uint8_t address_type,RawAddress address)1840 static void getOwnAddressCb(uint8_t advertiser_id, uint8_t address_type,
1841                             RawAddress address) {
1842   CallbackEnv sCallbackEnv(__func__);
1843   if (!sCallbackEnv.valid()) return;
1844 
1845   ScopedLocalRef<jstring> addr(sCallbackEnv.get(),
1846                                bdaddr2newjstr(sCallbackEnv.get(), &address));
1847   sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method_onOwnAddressRead,
1848                                advertiser_id, address_type, addr.get());
1849 }
1850 
getOwnAddressNative(JNIEnv * env,jobject object,jint advertiser_id)1851 static void getOwnAddressNative(JNIEnv* env, jobject object,
1852                                 jint advertiser_id) {
1853   if (!sGattIf) return;
1854   sGattIf->advertiser->GetOwnAddress(
1855       advertiser_id, base::Bind(&getOwnAddressCb, advertiser_id));
1856 }
1857 
callJniCallback(jmethodID method,uint8_t advertiser_id,uint8_t status)1858 static void callJniCallback(jmethodID method, uint8_t advertiser_id,
1859                             uint8_t status) {
1860   CallbackEnv sCallbackEnv(__func__);
1861   if (!sCallbackEnv.valid()) return;
1862   sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj, method, advertiser_id,
1863                                status);
1864 }
1865 
enableSetCb(uint8_t advertiser_id,bool enable,uint8_t status)1866 static void enableSetCb(uint8_t advertiser_id, bool enable, uint8_t status) {
1867   CallbackEnv sCallbackEnv(__func__);
1868   if (!sCallbackEnv.valid()) return;
1869   sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
1870                                method_onAdvertisingEnabled, advertiser_id,
1871                                enable, status);
1872 }
1873 
enableAdvertisingSetNative(JNIEnv * env,jobject object,jint advertiser_id,jboolean enable,jint duration,jint maxExtAdvEvents)1874 static void enableAdvertisingSetNative(JNIEnv* env, jobject object,
1875                                        jint advertiser_id, jboolean enable,
1876                                        jint duration, jint maxExtAdvEvents) {
1877   if (!sGattIf) return;
1878 
1879   sGattIf->advertiser->Enable(advertiser_id, enable,
1880                               base::Bind(&enableSetCb, advertiser_id, enable),
1881                               duration, maxExtAdvEvents,
1882                               base::Bind(&enableSetCb, advertiser_id, false));
1883 }
1884 
setAdvertisingDataNative(JNIEnv * env,jobject object,jint advertiser_id,jbyteArray data)1885 static void setAdvertisingDataNative(JNIEnv* env, jobject object,
1886                                      jint advertiser_id, jbyteArray data) {
1887   if (!sGattIf) return;
1888 
1889   sGattIf->advertiser->SetData(
1890       advertiser_id, false, toVector(env, data),
1891       base::Bind(&callJniCallback, method_onAdvertisingDataSet, advertiser_id));
1892 }
1893 
setScanResponseDataNative(JNIEnv * env,jobject object,jint advertiser_id,jbyteArray data)1894 static void setScanResponseDataNative(JNIEnv* env, jobject object,
1895                                       jint advertiser_id, jbyteArray data) {
1896   if (!sGattIf) return;
1897 
1898   sGattIf->advertiser->SetData(
1899       advertiser_id, true, toVector(env, data),
1900       base::Bind(&callJniCallback, method_onScanResponseDataSet,
1901                  advertiser_id));
1902 }
1903 
setAdvertisingParametersNativeCb(uint8_t advertiser_id,uint8_t status,int8_t tx_power)1904 static void setAdvertisingParametersNativeCb(uint8_t advertiser_id,
1905                                              uint8_t status, int8_t tx_power) {
1906   CallbackEnv sCallbackEnv(__func__);
1907   if (!sCallbackEnv.valid()) return;
1908   sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
1909                                method_onAdvertisingParametersUpdated,
1910                                advertiser_id, tx_power, status);
1911 }
1912 
setAdvertisingParametersNative(JNIEnv * env,jobject object,jint advertiser_id,jobject parameters)1913 static void setAdvertisingParametersNative(JNIEnv* env, jobject object,
1914                                            jint advertiser_id,
1915                                            jobject parameters) {
1916   if (!sGattIf) return;
1917 
1918   AdvertiseParameters params = parseParams(env, parameters);
1919   sGattIf->advertiser->SetParameters(
1920       advertiser_id, params,
1921       base::Bind(&setAdvertisingParametersNativeCb, advertiser_id));
1922 }
1923 
setPeriodicAdvertisingParametersNative(JNIEnv * env,jobject object,jint advertiser_id,jobject periodic_parameters)1924 static void setPeriodicAdvertisingParametersNative(
1925     JNIEnv* env, jobject object, jint advertiser_id,
1926     jobject periodic_parameters) {
1927   if (!sGattIf) return;
1928 
1929   PeriodicAdvertisingParameters periodicParams =
1930       parsePeriodicParams(env, periodic_parameters);
1931   sGattIf->advertiser->SetPeriodicAdvertisingParameters(
1932       advertiser_id, periodicParams,
1933       base::Bind(&callJniCallback,
1934                  method_onPeriodicAdvertisingParametersUpdated, advertiser_id));
1935 }
1936 
setPeriodicAdvertisingDataNative(JNIEnv * env,jobject object,jint advertiser_id,jbyteArray data)1937 static void setPeriodicAdvertisingDataNative(JNIEnv* env, jobject object,
1938                                              jint advertiser_id,
1939                                              jbyteArray data) {
1940   if (!sGattIf) return;
1941 
1942   sGattIf->advertiser->SetPeriodicAdvertisingData(
1943       advertiser_id, toVector(env, data),
1944       base::Bind(&callJniCallback, method_onPeriodicAdvertisingDataSet,
1945                  advertiser_id));
1946 }
1947 
enablePeriodicSetCb(uint8_t advertiser_id,bool enable,uint8_t status)1948 static void enablePeriodicSetCb(uint8_t advertiser_id, bool enable,
1949                                 uint8_t status) {
1950   CallbackEnv sCallbackEnv(__func__);
1951   if (!sCallbackEnv.valid()) return;
1952   sCallbackEnv->CallVoidMethod(mAdvertiseCallbacksObj,
1953                                method_onPeriodicAdvertisingEnabled,
1954                                advertiser_id, enable, status);
1955 }
1956 
setPeriodicAdvertisingEnableNative(JNIEnv * env,jobject object,jint advertiser_id,jboolean enable)1957 static void setPeriodicAdvertisingEnableNative(JNIEnv* env, jobject object,
1958                                                jint advertiser_id,
1959                                                jboolean enable) {
1960   if (!sGattIf) return;
1961 
1962   sGattIf->advertiser->SetPeriodicAdvertisingEnable(
1963       advertiser_id, enable,
1964       base::Bind(&enablePeriodicSetCb, advertiser_id, enable));
1965 }
1966 
periodicScanClassInitNative(JNIEnv * env,jclass clazz)1967 static void periodicScanClassInitNative(JNIEnv* env, jclass clazz) {
1968   method_onSyncStarted =
1969       env->GetMethodID(clazz, "onSyncStarted", "(IIIILjava/lang/String;III)V");
1970   method_onSyncReport = env->GetMethodID(clazz, "onSyncReport", "(IIII[B)V");
1971   method_onSyncLost = env->GetMethodID(clazz, "onSyncLost", "(I)V");
1972 }
1973 
periodicScanInitializeNative(JNIEnv * env,jobject object)1974 static void periodicScanInitializeNative(JNIEnv* env, jobject object) {
1975   if (mPeriodicScanCallbacksObj != NULL) {
1976     ALOGW("Cleaning up periodic scan callback object");
1977     env->DeleteGlobalRef(mPeriodicScanCallbacksObj);
1978     mPeriodicScanCallbacksObj = NULL;
1979   }
1980 
1981   mPeriodicScanCallbacksObj = env->NewGlobalRef(object);
1982 }
1983 
periodicScanCleanupNative(JNIEnv * env,jobject object)1984 static void periodicScanCleanupNative(JNIEnv* env, jobject object) {
1985   if (mPeriodicScanCallbacksObj != NULL) {
1986     env->DeleteGlobalRef(mPeriodicScanCallbacksObj);
1987     mPeriodicScanCallbacksObj = NULL;
1988   }
1989 }
1990 
onSyncStarted(int reg_id,uint8_t status,uint16_t sync_handle,uint8_t sid,uint8_t address_type,RawAddress address,uint8_t phy,uint16_t interval)1991 static void onSyncStarted(int reg_id, uint8_t status, uint16_t sync_handle,
1992                           uint8_t sid, uint8_t address_type, RawAddress address,
1993                           uint8_t phy, uint16_t interval) {
1994   CallbackEnv sCallbackEnv(__func__);
1995   if (!sCallbackEnv.valid()) return;
1996 
1997   sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, method_onSyncStarted,
1998                                reg_id, sync_handle, sid, address_type, address,
1999                                phy, interval, status);
2000 }
2001 
onSyncReport(uint16_t sync_handle,int8_t tx_power,int8_t rssi,uint8_t data_status,std::vector<uint8_t> data)2002 static void onSyncReport(uint16_t sync_handle, int8_t tx_power, int8_t rssi,
2003                          uint8_t data_status, std::vector<uint8_t> data) {
2004   CallbackEnv sCallbackEnv(__func__);
2005   if (!sCallbackEnv.valid()) return;
2006 
2007   ScopedLocalRef<jbyteArray> jb(sCallbackEnv.get(),
2008                                 sCallbackEnv->NewByteArray(data.size()));
2009   sCallbackEnv->SetByteArrayRegion(jb.get(), 0, data.size(),
2010                                    (jbyte*)data.data());
2011 
2012   sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, method_onSyncReport,
2013                                sync_handle, tx_power, rssi, data_status,
2014                                jb.get());
2015 }
2016 
onSyncLost(uint16_t sync_handle)2017 static void onSyncLost(uint16_t sync_handle) {
2018   CallbackEnv sCallbackEnv(__func__);
2019   if (!sCallbackEnv.valid()) return;
2020 
2021   sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, method_onSyncLost,
2022                                sync_handle);
2023 }
2024 
startSyncNative(JNIEnv * env,jobject object,jint sid,jstring address,jint skip,jint timeout,jint reg_id)2025 static void startSyncNative(JNIEnv* env, jobject object, jint sid,
2026                             jstring address, jint skip, jint timeout,
2027                             jint reg_id) {
2028   if (!sGattIf) return;
2029 
2030   sGattIf->scanner->StartSync(sid, str2addr(env, address), skip, timeout,
2031                               base::Bind(&onSyncStarted, reg_id),
2032                               base::Bind(&onSyncReport),
2033                               base::Bind(&onSyncLost));
2034 }
2035 
stopSyncNative(int sync_handle)2036 static void stopSyncNative(int sync_handle) {
2037   if (!sGattIf) return;
2038 
2039   sGattIf->scanner->StopSync(sync_handle);
2040 }
2041 
gattTestNative(JNIEnv * env,jobject object,jint command,jlong uuid1_lsb,jlong uuid1_msb,jstring bda1,jint p1,jint p2,jint p3,jint p4,jint p5)2042 static void gattTestNative(JNIEnv* env, jobject object, jint command,
2043                            jlong uuid1_lsb, jlong uuid1_msb, jstring bda1,
2044                            jint p1, jint p2, jint p3, jint p4, jint p5) {
2045   if (!sGattIf) return;
2046 
2047   RawAddress bt_bda1 = str2addr(env, bda1);
2048 
2049   Uuid uuid1 = from_java_uuid(uuid1_msb, uuid1_lsb);
2050 
2051   btgatt_test_params_t params;
2052   params.bda1 = &bt_bda1;
2053   params.uuid1 = &uuid1;
2054   params.u1 = p1;
2055   params.u2 = p2;
2056   params.u3 = p3;
2057   params.u4 = p4;
2058   params.u5 = p5;
2059   sGattIf->client->test_command(command, params);
2060 }
2061 
2062 /**
2063  * JNI function definitinos
2064  */
2065 
2066 // JNI functions defined in AdvertiseManager class.
2067 static JNINativeMethod sAdvertiseMethods[] = {
2068     {"classInitNative", "()V", (void*)advertiseClassInitNative},
2069     {"initializeNative", "()V", (void*)advertiseInitializeNative},
2070     {"cleanupNative", "()V", (void*)advertiseCleanupNative},
2071     {"startAdvertisingSetNative",
2072      "(Landroid/bluetooth/le/AdvertisingSetParameters;[B[BLandroid/bluetooth/"
2073      "le/PeriodicAdvertisingParameters;[BIII)V",
2074      (void*)startAdvertisingSetNative},
2075     {"getOwnAddressNative", "(I)V", (void*)getOwnAddressNative},
2076     {"stopAdvertisingSetNative", "(I)V", (void*)stopAdvertisingSetNative},
2077     {"enableAdvertisingSetNative", "(IZII)V",
2078      (void*)enableAdvertisingSetNative},
2079     {"setAdvertisingDataNative", "(I[B)V", (void*)setAdvertisingDataNative},
2080     {"setScanResponseDataNative", "(I[B)V", (void*)setScanResponseDataNative},
2081     {"setAdvertisingParametersNative",
2082      "(ILandroid/bluetooth/le/AdvertisingSetParameters;)V",
2083      (void*)setAdvertisingParametersNative},
2084     {"setPeriodicAdvertisingParametersNative",
2085      "(ILandroid/bluetooth/le/PeriodicAdvertisingParameters;)V",
2086      (void*)setPeriodicAdvertisingParametersNative},
2087     {"setPeriodicAdvertisingDataNative", "(I[B)V",
2088      (void*)setPeriodicAdvertisingDataNative},
2089     {"setPeriodicAdvertisingEnableNative", "(IZ)V",
2090      (void*)setPeriodicAdvertisingEnableNative},
2091 };
2092 
2093 // JNI functions defined in PeriodicScanManager class.
2094 static JNINativeMethod sPeriodicScanMethods[] = {
2095     {"classInitNative", "()V", (void*)periodicScanClassInitNative},
2096     {"initializeNative", "()V", (void*)periodicScanInitializeNative},
2097     {"cleanupNative", "()V", (void*)periodicScanCleanupNative},
2098     {"startSyncNative", "(ILjava/lang/String;III)V", (void*)startSyncNative},
2099     {"stopSyncNative", "(I)V", (void*)stopSyncNative},
2100 };
2101 
2102 // JNI functions defined in ScanManager class.
2103 static JNINativeMethod sScanMethods[] = {
2104     {"registerScannerNative", "(JJ)V", (void*)registerScannerNative},
2105     {"unregisterScannerNative", "(I)V", (void*)unregisterScannerNative},
2106     {"gattClientScanNative", "(Z)V", (void*)gattClientScanNative},
2107     // Batch scan JNI functions.
2108     {"gattClientConfigBatchScanStorageNative", "(IIII)V",
2109      (void*)gattClientConfigBatchScanStorageNative},
2110     {"gattClientStartBatchScanNative", "(IIIIII)V",
2111      (void*)gattClientStartBatchScanNative},
2112     {"gattClientStopBatchScanNative", "(I)V",
2113      (void*)gattClientStopBatchScanNative},
2114     {"gattClientReadScanReportsNative", "(II)V",
2115      (void*)gattClientReadScanReportsNative},
2116     // Scan filter JNI functions.
2117     {"gattClientScanFilterParamAddNative",
2118      "(Lcom/android/bluetooth/gatt/FilterParams;)V",
2119      (void*)gattClientScanFilterParamAddNative},
2120     {"gattClientScanFilterParamDeleteNative", "(II)V",
2121      (void*)gattClientScanFilterParamDeleteNative},
2122     {"gattClientScanFilterParamClearAllNative", "(I)V",
2123      (void*)gattClientScanFilterParamClearAllNative},
2124     {"gattClientScanFilterAddNative",
2125      "(I[Lcom/android/bluetooth/gatt/ScanFilterQueue$Entry;I)V",
2126      (void*)gattClientScanFilterAddNative},
2127     {"gattClientScanFilterClearNative", "(II)V",
2128      (void*)gattClientScanFilterClearNative},
2129     {"gattClientScanFilterEnableNative", "(IZ)V",
2130      (void*)gattClientScanFilterEnableNative},
2131     {"gattSetScanParametersNative", "(III)V",
2132      (void*)gattSetScanParametersNative},
2133 };
2134 
2135 // JNI functions defined in GattService class.
2136 static JNINativeMethod sMethods[] = {
2137     {"classInitNative", "()V", (void*)classInitNative},
2138     {"initializeNative", "()V", (void*)initializeNative},
2139     {"cleanupNative", "()V", (void*)cleanupNative},
2140     {"gattClientGetDeviceTypeNative", "(Ljava/lang/String;)I",
2141      (void*)gattClientGetDeviceTypeNative},
2142     {"gattClientRegisterAppNative", "(JJ)V",
2143      (void*)gattClientRegisterAppNative},
2144     {"gattClientUnregisterAppNative", "(I)V",
2145      (void*)gattClientUnregisterAppNative},
2146     {"gattClientConnectNative", "(ILjava/lang/String;ZIZI)V",
2147      (void*)gattClientConnectNative},
2148     {"gattClientDisconnectNative", "(ILjava/lang/String;I)V",
2149      (void*)gattClientDisconnectNative},
2150     {"gattClientSetPreferredPhyNative", "(ILjava/lang/String;III)V",
2151      (void*)gattClientSetPreferredPhyNative},
2152     {"gattClientReadPhyNative", "(ILjava/lang/String;)V",
2153      (void*)gattClientReadPhyNative},
2154     {"gattClientRefreshNative", "(ILjava/lang/String;)V",
2155      (void*)gattClientRefreshNative},
2156     {"gattClientSearchServiceNative", "(IZJJ)V",
2157      (void*)gattClientSearchServiceNative},
2158     {"gattClientDiscoverServiceByUuidNative", "(IJJ)V",
2159      (void*)gattClientDiscoverServiceByUuidNative},
2160     {"gattClientGetGattDbNative", "(I)V", (void*)gattClientGetGattDbNative},
2161     {"gattClientReadCharacteristicNative", "(III)V",
2162      (void*)gattClientReadCharacteristicNative},
2163     {"gattClientReadUsingCharacteristicUuidNative", "(IJJIII)V",
2164      (void*)gattClientReadUsingCharacteristicUuidNative},
2165     {"gattClientReadDescriptorNative", "(III)V",
2166      (void*)gattClientReadDescriptorNative},
2167     {"gattClientWriteCharacteristicNative", "(IIII[B)V",
2168      (void*)gattClientWriteCharacteristicNative},
2169     {"gattClientWriteDescriptorNative", "(III[B)V",
2170      (void*)gattClientWriteDescriptorNative},
2171     {"gattClientExecuteWriteNative", "(IZ)V",
2172      (void*)gattClientExecuteWriteNative},
2173     {"gattClientRegisterForNotificationsNative", "(ILjava/lang/String;IZ)V",
2174      (void*)gattClientRegisterForNotificationsNative},
2175     {"gattClientReadRemoteRssiNative", "(ILjava/lang/String;)V",
2176      (void*)gattClientReadRemoteRssiNative},
2177     {"gattClientConfigureMTUNative", "(II)V",
2178      (void*)gattClientConfigureMTUNative},
2179     {"gattConnectionParameterUpdateNative", "(ILjava/lang/String;IIIIII)V",
2180      (void*)gattConnectionParameterUpdateNative},
2181     {"gattServerRegisterAppNative", "(JJ)V",
2182      (void*)gattServerRegisterAppNative},
2183     {"gattServerUnregisterAppNative", "(I)V",
2184      (void*)gattServerUnregisterAppNative},
2185     {"gattServerConnectNative", "(ILjava/lang/String;ZI)V",
2186      (void*)gattServerConnectNative},
2187     {"gattServerDisconnectNative", "(ILjava/lang/String;I)V",
2188      (void*)gattServerDisconnectNative},
2189     {"gattServerSetPreferredPhyNative", "(ILjava/lang/String;III)V",
2190      (void*)gattServerSetPreferredPhyNative},
2191     {"gattServerReadPhyNative", "(ILjava/lang/String;)V",
2192      (void*)gattServerReadPhyNative},
2193     {"gattServerAddServiceNative", "(ILjava/util/List;)V",
2194      (void*)gattServerAddServiceNative},
2195     {"gattServerStopServiceNative", "(II)V",
2196      (void*)gattServerStopServiceNative},
2197     {"gattServerDeleteServiceNative", "(II)V",
2198      (void*)gattServerDeleteServiceNative},
2199     {"gattServerSendIndicationNative", "(III[B)V",
2200      (void*)gattServerSendIndicationNative},
2201     {"gattServerSendNotificationNative", "(III[B)V",
2202      (void*)gattServerSendNotificationNative},
2203     {"gattServerSendResponseNative", "(IIIIII[BI)V",
2204      (void*)gattServerSendResponseNative},
2205 
2206     {"gattTestNative", "(IJJLjava/lang/String;IIIII)V", (void*)gattTestNative},
2207 };
2208 
register_com_android_bluetooth_gatt(JNIEnv * env)2209 int register_com_android_bluetooth_gatt(JNIEnv* env) {
2210   int register_success = jniRegisterNativeMethods(
2211       env, "com/android/bluetooth/gatt/ScanManager$ScanNative", sScanMethods,
2212       NELEM(sScanMethods));
2213   register_success &= jniRegisterNativeMethods(
2214       env, "com/android/bluetooth/gatt/AdvertiseManager", sAdvertiseMethods,
2215       NELEM(sAdvertiseMethods));
2216   register_success &= jniRegisterNativeMethods(
2217       env, "com/android/bluetooth/gatt/PeriodicScanManager",
2218       sPeriodicScanMethods, NELEM(sPeriodicScanMethods));
2219   return register_success &
2220          jniRegisterNativeMethods(env, "com/android/bluetooth/gatt/GattService",
2221                                   sMethods, NELEM(sMethods));
2222 }
2223 }  // namespace android
2224