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