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