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