Direct-BT v3.3.0-1-gc2d430c
Direct-BT - Direct Bluetooth Programming.
DBGattServer.cxx
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2021 Gothel Software e.K.
4 * Copyright (c) 2021 ZAFENA AB
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#include "org_direct_bt_DBGattDesc.h"
27#include "org_direct_bt_DBGattChar.h"
28#include "org_direct_bt_DBGattService.h"
29#include "org_direct_bt_DBGattServer.h"
30#include "org_direct_bt_DBGattServer_Listener.h"
31
32// #define VERBOSE_ON 1
33#include <jau/debug.hpp>
34
35#include "helper_base.hpp"
36#include "helper_dbt.hpp"
37
40
41using namespace direct_bt;
42using namespace jau::jni;
43
44/**
45 *
46 * DBGattValue
47 *
48 */
49
50// package org.direct_bt;
51// public DBGattValue(final byte[] value, final int capacity, final boolean variable_length)
52static const std::string _dbGattValueClazzName("org/direct_bt/DBGattValue");
53static const std::string _dbGattValueClazzCtorArgs("([BIZ)V");
54
55static jobject _createDBGattValueFromDesc(JNIEnv *env_, jclass clazz, jmethodID clazz_ctor, const DBGattDescRef& valueHolder) {
56 const jau::POctets& value = valueHolder->getValue();
57 jbyteArray jval = env_->NewByteArray( (jsize) value.size() );
58 env_->SetByteArrayRegion(jval, 0, (jsize) value.size(), (const jbyte*)(value.get_ptr()));
60
61 jobject jDBGattValue = env_->NewObject(clazz, clazz_ctor, jval, (jint)value.capacity(), valueHolder->hasVariableLength());
63
64 env_->DeleteLocalRef(jval);
65
66 return jDBGattValue;
67};
68
69static jobject _createDBGattValueFromChar(JNIEnv *env_, jclass clazz, jmethodID clazz_ctor, const DBGattCharRef& valueHolder) {
70 const jau::POctets& value = valueHolder->getValue();
71 jbyteArray jval = env_->NewByteArray( (jsize) value.size() );
72 env_->SetByteArrayRegion(jval, 0, (jsize) value.size(), (const jbyte*)(value.get_ptr()));
74
75 jobject jDBGattValue = env_->NewObject(clazz, clazz_ctor, jval, (jint)value.capacity(), valueHolder->hasVariableLength());
77
78 env_->DeleteLocalRef(jval);
79
80 return jDBGattValue;
81};
82
83/**
84 *
85 * DBGattDesc
86 *
87 */
88
89jobject Java_org_direct_1bt_DBGattDesc_getValue(JNIEnv *env, jobject obj) {
90 try {
91 shared_ptr_ref<DBGattDesc> ref(env, obj); // hold until done
92 jclass clazz = search_class(env, _dbGattValueClazzName.c_str());
93 return convert_instance_to_jobject<DBGattDesc>(env, clazz, _dbGattValueClazzCtorArgs.c_str(), _createDBGattValueFromDesc, ref.shared_ptr());
94 } catch(...) {
96 }
97 return nullptr;
98}
99
100jboolean Java_org_direct_1bt_DBGattDesc_setValue(JNIEnv *env, jobject obj, jbyteArray jsource, jint jsource_pos, jint jsource_len, jint jdest_pos) {
101 try {
102 shared_ptr_ref<DBGattDesc> ref(env, obj); // hold until done
103
104 if( nullptr == jsource ) {
105 return JNI_FALSE;
106 }
107
108 const jau::nsize_t source_len0 = env->GetArrayLength(jsource);
109 const jau::nsize_t source_len1 = jsource_len;
110 const jau::nsize_t source_pos1 = jsource_pos;
111 const jau::nsize_t dest_pos = jdest_pos;
112
113 if( 0 < source_len0 && 0 < source_len1 && source_pos1 + source_len1 <= source_len0 ) {
114 JNICriticalArray<uint8_t, jbyteArray> criticalArray(env); // RAII - release
115 const uint8_t * source = criticalArray.get(jsource, criticalArray.Mode::NO_UPDATE_AND_RELEASE);
116 if( nullptr == source ) {
117 throw jau::InternalError("GetPrimitiveArrayCritical(byte array) is null", E_FILE_LINE);
118 }
119 return ref->setValue(source+source_pos1, source_len1, dest_pos) ? JNI_TRUE : JNI_FALSE;
120 } else {
121 return JNI_FALSE;
122 }
123 } catch(...) {
125 }
126 return JNI_FALSE;
127}
128
129/**
130 * private native long ctorImpl(final String type,
131 * final byte[] value, final int capacity, boolean variable_length);
132 */
133jlong Java_org_direct_1bt_DBGattDesc_ctorImpl(JNIEnv *env, jobject obj,
134 jstring jtype_,
135 jbyteArray jvalue_, jint jcapacity_, jboolean jvariable_length_) {
136 try {
137 if( nullptr == jvalue_ ) {
138 throw jau::IllegalArgumentException("byte array null", E_FILE_LINE);
139 }
140 JNIGlobalRef global_obj(obj); // lock instance first (global reference), inserted below
141
142 // POctets value
143 jau::POctets value(jcapacity_, env->GetArrayLength(jvalue_), jau::lb_endian_t::little);
144 if( 0 < value.size() ) {
145 JNICriticalArray<uint8_t, jbyteArray> criticalArray(env); // RAII - release
146 const uint8_t * value_ptr = criticalArray.get(jvalue_, criticalArray.Mode::NO_UPDATE_AND_RELEASE);
147 if( nullptr == value_ptr ) {
148 throw jau::InternalError("GetPrimitiveArrayCritical(byte array) is null", E_FILE_LINE);
149 }
150 value.put_bytes_nc(0, value_ptr, value.size());
151 }
152
153 // uuid_t type
154 std::string stype = from_jstring_to_string(env, jtype_);
155 std::shared_ptr<const jau::uuid_t> type( jau::uuid_t::create(stype) );
156
157 // new instance
158 shared_ptr_ref<DBGattDesc> ref( new DBGattDesc(type, std::move(value), JNI_TRUE == jvariable_length_) );
159
160 ref->setJavaObject( std::make_shared<JavaGlobalObj>( std::move(global_obj), nullptr ) );
161 JavaGlobalObj::check(ref->getJavaObject(), E_FILE_LINE);
162
163 return ref.release_to_jlong();
164 } catch(...) {
166 }
167 return (jlong) (intptr_t)nullptr;
168}
169
170void Java_org_direct_1bt_DBGattDesc_dtorImpl(JNIEnv *env, jclass clazz, jlong nativeInstance) {
171 (void)clazz;
172 try {
173 shared_ptr_ref<DBGattDesc> sref(nativeInstance, false /* throw_on_nullptr */); // hold copy until done
174 if( nullptr != sref.pointer() ) {
175 if( !sref.is_null() ) {
176 JavaAnonRef sref_java = sref->getJavaObject(); // hold until done!
177 JavaGlobalObj::check(sref_java, E_FILE_LINE);
178 sref->setJavaObject();
179 }
180 std::shared_ptr<DBGattDesc>* sref_ptr = castInstance<DBGattDesc>(nativeInstance);
181 delete sref_ptr;
182 }
183 } catch(...) {
185 }
186}
187
188jshort Java_org_direct_1bt_DBGattDesc_getHandle(JNIEnv *env, jobject obj)
189{
190 try {
191 shared_ptr_ref<DBGattDesc> ref(env, obj); // hold until done
192 return (jshort)( ref->getHandle() );
193 } catch(...) {
195 }
196 return 0;
197}
198
199
200void Java_org_direct_1bt_DBGattDesc_bzero(JNIEnv *env, jobject obj)
201{
202 try {
203 shared_ptr_ref<DBGattDesc> ref(env, obj); // hold until done
204 ref->bzero();
205 } catch(...) {
207 }
208}
209
210jstring Java_org_direct_1bt_DBGattDesc_toString(JNIEnv *env, jobject obj) {
211 try {
212 shared_ptr_ref<DBGattDesc> ref(env, obj); // hold until done
213 return from_string_to_jstring(env, ref->toString());
214 } catch(...) {
216 }
217 return nullptr;
218}
219
220
221/**
222 *
223 * DBGattChar
224 *
225 */
226
227jobject Java_org_direct_1bt_DBGattChar_getValue(JNIEnv *env, jobject obj) {
228 try {
229 shared_ptr_ref<DBGattChar> ref(env, obj); // hold until done
230 jclass clazz = search_class(env, _dbGattValueClazzName.c_str());
231 return convert_instance_to_jobject<DBGattChar>(env, clazz, _dbGattValueClazzCtorArgs.c_str(), _createDBGattValueFromChar, ref.shared_ptr());
232 } catch(...) {
234 }
235 return nullptr;
236}
237
238jboolean Java_org_direct_1bt_DBGattChar_setValue(JNIEnv *env, jobject obj, jbyteArray jsource, jint jsource_pos, jint jsource_len, jint jdest_pos) {
239 try {
240 shared_ptr_ref<DBGattChar> ref(env, obj); // hold until done
241
242 if( nullptr == jsource ) {
243 return JNI_FALSE;
244 }
245
246 const jau::nsize_t source_len0 = env->GetArrayLength(jsource);
247 const jau::nsize_t source_len1 = jsource_len;
248 const jau::nsize_t source_pos1 = jsource_pos;
249 const jau::nsize_t dest_pos = jdest_pos;
250
251 if( 0 < source_len0 && 0 < source_len1 && source_pos1 + source_len1 <= source_len0 ) {
252 JNICriticalArray<uint8_t, jbyteArray> criticalArray(env); // RAII - release
253 const uint8_t * source = criticalArray.get(jsource, criticalArray.Mode::NO_UPDATE_AND_RELEASE);
254 if( nullptr == source ) {
255 throw jau::InternalError("GetPrimitiveArrayCritical(byte array) is null", E_FILE_LINE);
256 }
257 return ref->setValue(source+source_pos1, source_len1, dest_pos) ? JNI_TRUE : JNI_FALSE;
258 } else {
259 return JNI_FALSE;
260 }
261 } catch(...) {
263 }
264 return JNI_FALSE;
265}
266
267/**
268 * private native long ctorImpl(final String type,
269 * final byte properties, final long[] descriptors,
270 * final byte[] value, final int capacity, boolean variable_length);
271 */
272jlong Java_org_direct_1bt_DBGattChar_ctorImpl(JNIEnv *env, jobject obj,
273 jstring jtype_,
274 jbyte jproperties, jlongArray jDescriptors,
275 jbyteArray jvalue_, jint jcapacity_, jboolean jvariable_length_) {
276 try {
277 if( nullptr == jvalue_ ) {
278 throw jau::IllegalArgumentException("byte array null", E_FILE_LINE);
279 }
280 if( nullptr == jDescriptors ) {
281 throw jau::IllegalArgumentException("descriptor array null", E_FILE_LINE);
282 }
283 JNIGlobalRef global_obj(obj); // lock instance first (global reference), inserted below
284
285 // POctets value
286 jau::POctets value(jcapacity_, env->GetArrayLength(jvalue_), jau::lb_endian_t::little);
287 if( 0 < value.size() ) {
288 JNICriticalArray<uint8_t, jbyteArray> criticalArray(env); // RAII - release
289 const uint8_t * value_ptr = criticalArray.get(jvalue_, criticalArray.Mode::NO_UPDATE_AND_RELEASE);
290 if( nullptr == value_ptr ) {
291 throw jau::InternalError("GetPrimitiveArrayCritical(byte array) is null", E_FILE_LINE);
292 }
293 value.put_bytes_nc(0, value_ptr, value.size());
294 }
295
296 // DBGattDescRef List
297 jau::darray<DBGattDescRef> descriptors( env->GetArrayLength(jDescriptors) /* capacity */ );
298 const jau::nsize_t count = descriptors.capacity();
299 if( 0 < count ) {
300 JNICriticalArray<jlong, jlongArray> criticalArray(env); // RAII - release
301 jlong * jlong_desc_ref_array = criticalArray.get(jDescriptors, criticalArray.Mode::NO_UPDATE_AND_RELEASE);
302 if( nullptr == jlong_desc_ref_array ) {
303 throw jau::InternalError("GetPrimitiveArrayCritical(DBGattDesc* array) is null", E_FILE_LINE);
304 }
305 for(jau::nsize_t i=0; i < count; ++i) {
306 std::shared_ptr<DBGattDesc> desc_ref = *( (std::shared_ptr<DBGattDesc> *) (intptr_t) jlong_desc_ref_array[i] ); // NOLINT(performance-no-int-to-ptr)
307 descriptors.push_back( desc_ref );
308 }
309 }
310
311 // PropertyBitVal
312 const BTGattChar::PropertyBitVal properties = static_cast<BTGattChar::PropertyBitVal>(jproperties);
313
314 // uuid_t type
315 std::string stype = from_jstring_to_string(env, jtype_);
316 std::shared_ptr<const jau::uuid_t> type( jau::uuid_t::create(stype) );
317
318 // new instance
319 shared_ptr_ref<DBGattChar> ref( new DBGattChar(type, properties,
320 std::move(descriptors),
321 std::move(value), JNI_TRUE == jvariable_length_) );
322
323 ref->setJavaObject( std::make_shared<JavaGlobalObj>( std::move(global_obj), nullptr ) );
324 JavaGlobalObj::check(ref->getJavaObject(), E_FILE_LINE);
325
326 return ref.release_to_jlong();
327 } catch(...) {
329 }
330 return (jlong) (intptr_t) nullptr;
331}
332
333void Java_org_direct_1bt_DBGattChar_dtorImpl(JNIEnv *env, jclass clazz, jlong nativeInstance) {
334 (void)clazz;
335 try {
336 shared_ptr_ref<BTGattChar> sref(nativeInstance, false /* throw_on_nullptr */); // hold copy until done
337 if( nullptr != sref.pointer() ) {
338 if( !sref.is_null() ) {
339 JavaAnonRef sref_java = sref->getJavaObject(); // hold until done!
340 JavaGlobalObj::check(sref_java, E_FILE_LINE);
341 sref->setJavaObject();
342 }
343 std::shared_ptr<BTGattChar>* sref_ptr = castInstance<BTGattChar>(nativeInstance);
344 delete sref_ptr;
345 }
346 } catch(...) {
348 }
349}
350
351jshort Java_org_direct_1bt_DBGattChar_getHandle(JNIEnv *env, jobject obj)
352{
353 try {
354 shared_ptr_ref<DBGattChar> ref(env, obj); // hold until done
355 return (jshort)( ref->getHandle() );
356 } catch(...) {
358 }
359 return 0;
360}
361
362jshort Java_org_direct_1bt_DBGattChar_getEndHandle(JNIEnv *env, jobject obj)
363{
364 try {
365 shared_ptr_ref<DBGattChar> ref(env, obj); // hold until done
366 return (jshort)( ref->getEndHandle() );
367 } catch(...) {
369 }
370 return 0;
371}
372
373jshort Java_org_direct_1bt_DBGattChar_getValueHandle(JNIEnv *env, jobject obj)
374{
375 try {
376 shared_ptr_ref<DBGattChar> ref(env, obj); // hold until done
377 return (jshort)( ref->getValueHandle() );
378 } catch(...) {
380 }
381 return 0;
382}
383
384
385void Java_org_direct_1bt_DBGattChar_bzero(JNIEnv *env, jobject obj)
386{
387 try {
388 shared_ptr_ref<DBGattChar> ref(env, obj); // hold until done
389 ref->bzero();
390 } catch(...) {
392 }
393}
394
395jstring Java_org_direct_1bt_DBGattChar_toString(JNIEnv *env, jobject obj) {
396 try {
397 shared_ptr_ref<DBGattChar> ref(env, obj); // hold until done
398 return from_string_to_jstring(env, ref->toString());
399 } catch(...) {
401 }
402 return nullptr;
403}
404
405/**
406 *
407 * DBGattService
408 *
409 */
410
411/**
412 * private native long ctorImpl(final boolean primary, final String type,
413 * final long[] characteristics);
414 */
415jlong Java_org_direct_1bt_DBGattService_ctorImpl(JNIEnv *env, jobject obj,
416 jboolean jprimary, jstring jtype_,
417 jlongArray jCharacteristics) {
418 try {
419 if( nullptr == jCharacteristics ) {
420 throw jau::IllegalArgumentException("characteristics array null", E_FILE_LINE);
421 }
422 JNIGlobalRef global_obj(obj); // lock instance first (global reference), inserted below
423
424 // DBGattCharRef List
425 jau::darray<DBGattCharRef> characteristics( env->GetArrayLength(jCharacteristics) /* capacity */ );
426 const jau::nsize_t count = characteristics.capacity();
427 if( 0 < count ) {
428 JNICriticalArray<jlong, jlongArray> criticalArray(env); // RAII - release
429 jlong * jlong_char_ref_array = criticalArray.get(jCharacteristics, criticalArray.Mode::NO_UPDATE_AND_RELEASE);
430 if( nullptr == jlong_char_ref_array ) {
431 throw jau::InternalError("GetPrimitiveArrayCritical(DBGattChar* array) is null", E_FILE_LINE);
432 }
433 for(jau::nsize_t i=0; i < count; ++i) {
434 std::shared_ptr<DBGattChar> char_ref = *( (std::shared_ptr<DBGattChar> *) (intptr_t) jlong_char_ref_array[i] ); // NOLINT(performance-no-int-to-ptr)
435 characteristics.push_back( char_ref );
436 }
437 }
438
439 // uuid_t type
440 std::string stype = from_jstring_to_string(env, jtype_);
441 std::shared_ptr<const jau::uuid_t> type( jau::uuid_t::create(stype) );
442
443 // new instance
444 shared_ptr_ref<DBGattService> ref( new DBGattService( JNI_TRUE == jprimary, type, std::move(characteristics) ) );
445
446 ref->setJavaObject( std::make_shared<JavaGlobalObj>( std::move(global_obj), nullptr ) );
447 JavaGlobalObj::check(ref->getJavaObject(), E_FILE_LINE);
448
449 return ref.release_to_jlong();
450 } catch(...) {
452 }
453 return (jlong) (intptr_t) nullptr;
454}
455
456void Java_org_direct_1bt_DBGattService_dtorImpl(JNIEnv *env, jclass clazz, jlong nativeInstance) {
457 (void)clazz;
458 try {
459 shared_ptr_ref<DBGattService> sref(nativeInstance, false /* throw_on_nullptr */); // hold copy until done
460 if( nullptr != sref.pointer() ) {
461 if( !sref.is_null() ) {
462 JavaAnonRef sref_java = sref->getJavaObject(); // hold until done!
463 JavaGlobalObj::check(sref_java, E_FILE_LINE);
464 sref->setJavaObject();
465 }
466 std::shared_ptr<DBGattService>* sref_ptr = castInstance<DBGattService>(nativeInstance);
467 delete sref_ptr;
468 }
469 } catch(...) {
471 }
472}
473
474jshort Java_org_direct_1bt_DBGattService_getHandle(JNIEnv *env, jobject obj)
475{
476 try {
477 shared_ptr_ref<DBGattService> ref(env, obj); // hold until done
478 return (jshort)( ref->getHandle() );
479 } catch(...) {
481 }
482 return 0;
483}
484
486{
487 try {
488 shared_ptr_ref<DBGattService> ref(env, obj); // hold until done
489 return (jshort)( ref->getEndHandle() );
490 } catch(...) {
492 }
493 return 0;
494}
495
496jstring Java_org_direct_1bt_DBGattService_toString(JNIEnv *env, jobject obj) {
497 try {
498 shared_ptr_ref<DBGattService> ref(env, obj); // hold until done
499 return from_string_to_jstring(env, ref->toString());
500 } catch(...) {
502 }
503 return nullptr;
504}
505
506/**
507 *
508 * DBGattServer
509 *
510 */
511
512/**
513 * private native long ctorImpl(final int max_att_mtu, final long[] services);
514 */
515jlong Java_org_direct_1bt_DBGattServer_ctorImpl(JNIEnv *env, jobject obj,
516 jint jmax_att_mtu,
517 jlongArray jService) {
518 try {
519 if( nullptr == jService ) {
520 throw jau::IllegalArgumentException("characteristics array null", E_FILE_LINE);
521 }
522 JNIGlobalRef global_obj(obj); // lock instance first (global reference), inserted below
523
524 // DBGattServiceRef List
525 jau::darray<DBGattServiceRef> services( env->GetArrayLength(jService) /* capacity */ );
526 const jau::nsize_t count = services.capacity();
527 if( 0 < count ) {
528 JNICriticalArray<jlong, jlongArray> criticalArray(env); // RAII - release
529 jlong * jlong_service_ref_array = criticalArray.get(jService, criticalArray.Mode::NO_UPDATE_AND_RELEASE);
530 if( nullptr == jlong_service_ref_array ) {
531 throw jau::InternalError("GetPrimitiveArrayCritical(DBGattService* array) is null", E_FILE_LINE);
532 }
533 for(jau::nsize_t i=0; i < count; ++i) {
534 std::shared_ptr<DBGattService> service_ref = *( (std::shared_ptr<DBGattService> *) (intptr_t) jlong_service_ref_array[i] ); // NOLINT(performance-no-int-to-ptr)
535 services.push_back( service_ref );
536 }
537 }
538
539 // new instance
540 shared_ptr_ref<DBGattServer> ref( new DBGattServer( jmax_att_mtu, std::move(services) ) );
541
542 ref->setJavaObject( std::make_shared<JavaGlobalObj>( std::move(global_obj), nullptr ) );
543 JavaGlobalObj::check(ref->getJavaObject(), E_FILE_LINE);
544
545 return ref.release_to_jlong();
546 } catch(...) {
548 }
549 return (jlong) (intptr_t) nullptr;
550}
551
552void Java_org_direct_1bt_DBGattServer_dtorImpl(JNIEnv *env, jclass clazz, jlong nativeInstance) {
553 (void)clazz;
554 try {
555 shared_ptr_ref<DBGattServer> sref(nativeInstance, false /* throw_on_nullptr */); // hold copy until done
556 if( nullptr != sref.pointer() ) {
557 if( !sref.is_null() ) {
558 JavaAnonRef sref_java = sref->getJavaObject(); // hold until done!
559 JavaGlobalObj::check(sref_java, E_FILE_LINE);
560 sref->setJavaObject();
561 }
562 std::shared_ptr<DBGattServer>* sref_ptr = castInstance<DBGattServer>(nativeInstance);
563 delete sref_ptr;
564 }
565 } catch(...) {
567 }
568}
569
571{
572 try {
573 shared_ptr_ref<DBGattServer> ref(env, obj); // hold until done
574 return (jint)( ref->getMaxAttMTU() );
575 } catch(...) {
577 }
578 return 0;
579}
580
581void Java_org_direct_1bt_DBGattServer_setMaxAttMTU(JNIEnv *env, jobject obj, jint v)
582{
583 try {
584 shared_ptr_ref<DBGattServer> ref(env, obj); // hold until done
585 ref->setMaxAttMTU(v);
586 } catch(...) {
588 }
589}
590
591jstring Java_org_direct_1bt_DBGattServer_toString(JNIEnv *env, jobject obj) {
592 try {
593 shared_ptr_ref<DBGattServer> ref(env, obj); // hold until done
594 return from_string_to_jstring(env, ref->toString());
595 } catch(...) {
597 }
598 return nullptr;
599}
600
601/**
602 *
603 * DBGattServer.Listener and related DBGattServer methods
604 *
605 */
606
607
609 private:
610 JavaGlobalObj listenerObjRef;
611 jmethodID mConnected = nullptr;
612 jmethodID mDisconnected = nullptr;
613 jmethodID mMtuChanged = nullptr;
614 jmethodID mReadCharValue = nullptr;
615 jmethodID mReadDescValue = nullptr;
616 jmethodID mWriteCharValue = nullptr;
617 jmethodID mWriteCharValueDone = nullptr;
618 jmethodID mWriteDescValue = nullptr;
619 jmethodID mWriteDescValueDone = nullptr;
620 jmethodID mCCDChanged = nullptr;
621
622 public:
623 JNIDBGattServerListener(JNIEnv *env, jclass clazz, jobject obj)
624 : listenerObjRef(obj, nullptr)
625 {
626 mConnected = search_method(env, clazz, "connected", "(Lorg/direct_bt/BTDevice;I)V", false);
627 mDisconnected = search_method(env, clazz, "disconnected", "(Lorg/direct_bt/BTDevice;)V", false);
628 mMtuChanged = search_method(env, clazz, "mtuChanged", "(Lorg/direct_bt/BTDevice;I)V", false);
629 mReadCharValue = search_method(env, clazz, "readCharValue", "(Lorg/direct_bt/BTDevice;Lorg/direct_bt/DBGattService;Lorg/direct_bt/DBGattChar;)Z", false);
630 mReadDescValue = search_method(env, clazz, "readDescValue", "(Lorg/direct_bt/BTDevice;Lorg/direct_bt/DBGattService;Lorg/direct_bt/DBGattChar;Lorg/direct_bt/DBGattDesc;)Z", false);
631 mWriteCharValue = search_method(env, clazz, "writeCharValue", "(Lorg/direct_bt/BTDevice;Lorg/direct_bt/DBGattService;Lorg/direct_bt/DBGattChar;[BI)Z", false);
632 mWriteCharValueDone = search_method(env, clazz, "writeCharValueDone", "(Lorg/direct_bt/BTDevice;Lorg/direct_bt/DBGattService;Lorg/direct_bt/DBGattChar;)V", false);
633 mWriteDescValue = search_method(env, clazz, "writeDescValue", "(Lorg/direct_bt/BTDevice;Lorg/direct_bt/DBGattService;Lorg/direct_bt/DBGattChar;Lorg/direct_bt/DBGattDesc;[BI)Z", false);
634 mWriteDescValueDone = search_method(env, clazz, "writeDescValueDone", "(Lorg/direct_bt/BTDevice;Lorg/direct_bt/DBGattService;Lorg/direct_bt/DBGattChar;Lorg/direct_bt/DBGattDesc;)V", false);
635 mCCDChanged = search_method(env, clazz, "clientCharConfigChanged", "(Lorg/direct_bt/BTDevice;Lorg/direct_bt/DBGattService;Lorg/direct_bt/DBGattChar;Lorg/direct_bt/DBGattDesc;ZZ)V", false);
636 }
637
638 ~JNIDBGattServerListener() noexcept override = default;
639
640 void connected(const BTDeviceRef& device, const uint16_t initialMTU) override {
641 jobject j_device = JavaGlobalObj::checkAndGetObject(device->getJavaObject(), E_FILE_LINE);
642 JNIEnv *env = *jni_env;
643
644 env->CallVoidMethod(listenerObjRef.getObject(), mConnected, j_device, (jint)initialMTU);
646 }
647
648 void disconnected(const BTDeviceRef& device) override {
649 jobject j_device = JavaGlobalObj::checkAndGetObject(device->getJavaObject(), E_FILE_LINE);
650 JNIEnv *env = *jni_env;
651
652 env->CallVoidMethod(listenerObjRef.getObject(), mDisconnected, j_device);
654 }
655
656 void mtuChanged(const BTDeviceRef& device, const uint16_t mtu) override {
657 jobject j_device = JavaGlobalObj::checkAndGetObject(device->getJavaObject(), E_FILE_LINE);
658 JNIEnv *env = *jni_env;
659
660 env->CallVoidMethod(listenerObjRef.getObject(), mMtuChanged, j_device, (jint)mtu);
662 }
663
664 bool readCharValue(const BTDeviceRef& device, const DBGattServiceRef& s, const DBGattCharRef& c) override {
665 jobject j_device = JavaGlobalObj::checkAndGetObject(device->getJavaObject(), E_FILE_LINE);
666 jobject j_s = JavaGlobalObj::checkAndGetObject(s->getJavaObject(), E_FILE_LINE);
667 jobject j_c = JavaGlobalObj::checkAndGetObject(c->getJavaObject(), E_FILE_LINE);
668 JNIEnv *env = *jni_env;
669
670 jboolean res = env->CallBooleanMethod(listenerObjRef.getObject(), mReadCharValue, j_device, j_s, j_c);
672 return JNI_TRUE == res;
673 }
674
675 bool readDescValue(const BTDeviceRef& device, const DBGattServiceRef& s, const DBGattCharRef& c, const DBGattDescRef& d) override {
676 jobject j_device = JavaGlobalObj::checkAndGetObject(device->getJavaObject(), E_FILE_LINE);
677 jobject j_s = JavaGlobalObj::checkAndGetObject(s->getJavaObject(), E_FILE_LINE);
678 jobject j_c = JavaGlobalObj::checkAndGetObject(c->getJavaObject(), E_FILE_LINE);
679 jobject j_d = JavaGlobalObj::checkAndGetObject(d->getJavaObject(), E_FILE_LINE);
680 JNIEnv *env = *jni_env;
681
682 jboolean res = env->CallBooleanMethod(listenerObjRef.getObject(), mReadDescValue, j_device, j_s, j_c, j_d);
684 return JNI_TRUE == res;
685 }
686
687 bool writeCharValue(const BTDeviceRef& device, const DBGattServiceRef& s, const DBGattCharRef& c, const jau::TROOctets & value, const uint16_t value_offset) override {
688 jobject j_device = JavaGlobalObj::checkAndGetObject(device->getJavaObject(), E_FILE_LINE);
689 jobject j_s = JavaGlobalObj::checkAndGetObject(s->getJavaObject(), E_FILE_LINE);
690 jobject j_c = JavaGlobalObj::checkAndGetObject(c->getJavaObject(), E_FILE_LINE);
691 JNIEnv *env = *jni_env;
692
693 const size_t value_size = value.size();
694 jbyteArray j_value = env->NewByteArray((jsize)value_size);
695 env->SetByteArrayRegion(j_value, 0, (jsize)value_size, (const jbyte *)value.get_ptr());
697
698 jboolean res = env->CallBooleanMethod(listenerObjRef.getObject(), mWriteCharValue, j_device, j_s, j_c, j_value, (jint)value_offset);
700 env->DeleteLocalRef(j_value);
701 return JNI_TRUE == res;
702 }
703 void writeCharValueDone(const BTDeviceRef& device, const DBGattServiceRef& s, const DBGattCharRef& c) override {
704 jobject j_device = JavaGlobalObj::checkAndGetObject(device->getJavaObject(), E_FILE_LINE);
705 jobject j_s = JavaGlobalObj::checkAndGetObject(s->getJavaObject(), E_FILE_LINE);
706 jobject j_c = JavaGlobalObj::checkAndGetObject(c->getJavaObject(), E_FILE_LINE);
707 JNIEnv *env = *jni_env;
708
709 env->CallVoidMethod(listenerObjRef.getObject(), mWriteCharValueDone, j_device, j_s, j_c);
711 }
712
713 bool writeDescValue(const BTDeviceRef& device, const DBGattServiceRef& s, const DBGattCharRef& c, const DBGattDescRef& d, const jau::TROOctets & value, const uint16_t value_offset) override {
714 jobject j_device = JavaGlobalObj::checkAndGetObject(device->getJavaObject(), E_FILE_LINE);
715 jobject j_s = JavaGlobalObj::checkAndGetObject(s->getJavaObject(), E_FILE_LINE);
716 jobject j_c = JavaGlobalObj::checkAndGetObject(c->getJavaObject(), E_FILE_LINE);
717 jobject j_d = JavaGlobalObj::checkAndGetObject(d->getJavaObject(), E_FILE_LINE);
718 JNIEnv *env = *jni_env;
719
720 const size_t value_size = value.size();
721 jbyteArray j_value = env->NewByteArray((jsize)value_size);
722 env->SetByteArrayRegion(j_value, 0, (jsize)value_size, (const jbyte *)value.get_ptr());
724
725 jboolean res = env->CallBooleanMethod(listenerObjRef.getObject(), mWriteDescValue, j_device, j_s, j_c, j_d, j_value, (jint)value_offset);
727 env->DeleteLocalRef(j_value);
728 return JNI_TRUE == res;
729 }
730 void writeDescValueDone(const BTDeviceRef& device, const DBGattServiceRef& s, const DBGattCharRef& c, const DBGattDescRef& d) override {
731 jobject j_device = JavaGlobalObj::checkAndGetObject(device->getJavaObject(), E_FILE_LINE);
732 jobject j_s = JavaGlobalObj::checkAndGetObject(s->getJavaObject(), E_FILE_LINE);
733 jobject j_c = JavaGlobalObj::checkAndGetObject(c->getJavaObject(), E_FILE_LINE);
734 jobject j_d = JavaGlobalObj::checkAndGetObject(d->getJavaObject(), E_FILE_LINE);
735 JNIEnv *env = *jni_env;
736
737 env->CallVoidMethod(listenerObjRef.getObject(), mWriteDescValueDone, j_device, j_s, j_c, j_d);
739 }
740
741 void clientCharConfigChanged(const BTDeviceRef& device, const DBGattServiceRef& s, const DBGattCharRef& c, const DBGattDescRef& d, const bool notificationEnabled, const bool indicationEnabled) override {
742 jobject j_device = JavaGlobalObj::checkAndGetObject(device->getJavaObject(), E_FILE_LINE);
743 jobject j_s = JavaGlobalObj::checkAndGetObject(s->getJavaObject(), E_FILE_LINE);
744 jobject j_c = JavaGlobalObj::checkAndGetObject(c->getJavaObject(), E_FILE_LINE);
745 jobject j_d = JavaGlobalObj::checkAndGetObject(d->getJavaObject(), E_FILE_LINE);
746 JNIEnv *env = *jni_env;
747
748 env->CallVoidMethod(listenerObjRef.getObject(), mCCDChanged, j_device, j_s, j_c, j_d,
749 notificationEnabled? JNI_TRUE : JNI_FALSE, indicationEnabled? JNI_TRUE : JNI_FALSE);
751 }
752};
753
754
755/*
756 * Class: org_direct_bt_DBGattServer
757 * Method: addListenerImpl
758 * Signature: (Lorg/direct_bt/DBGattServer/Listener;)Z
759 */
760jboolean Java_org_direct_1bt_DBGattServer_addListenerImpl(JNIEnv *env, jobject obj, jobject jlistener) {
761 try {
762 shared_ptr_ref<DBGattServer> ref(env, obj); // hold until done
763 shared_ptr_ref<JNIDBGattServerListener> listener_ref(env, jlistener); // hold until done
764 bool res = ref->addListener(listener_ref.shared_ptr());
765 return res ? JNI_TRUE : JNI_FALSE;
766 } catch(...) {
768 }
769 return JNI_FALSE;
770}
771
772/*
773 * Class: org_direct_bt_DBGattServer
774 * Method: removeListenerImpl
775 * Signature: (Lorg/direct_bt/DBGattServer/Listener;)Z
776 */
777jboolean Java_org_direct_1bt_DBGattServer_removeListenerImpl(JNIEnv *env, jobject obj, jobject jlistener) {
778 try {
779 shared_ptr_ref<DBGattServer> ref(env, obj); // hold until done
780 shared_ptr_ref<JNIDBGattServerListener> listener_ref(env, jlistener); // hold until done
781 bool res = ref->removeListener(listener_ref.shared_ptr());
782 return res ? JNI_TRUE : JNI_FALSE;
783 } catch(...) {
785 }
786 return JNI_FALSE;
787}
788
789
790/*
791 * Class: org_direct_bt_DBGattServer_Listener
792 * Method: ctorImpl
793 * Signature: ()J
794 */
796 try {
797 jclass clazz = search_class(env, obj);
799 env->DeleteLocalRef(clazz);
800
801 return ref.release_to_jlong();
802 } catch(...) {
804 }
805 return (jlong) (intptr_t)nullptr;
806}
807
808/*
809 * Class: org_direct_bt_DBGattServer_Listener
810 * Method: dtorImpl
811 * Signature: (J)V
812 */
813void Java_org_direct_1bt_DBGattServer_00024Listener_dtorImpl(JNIEnv *env, jclass clazz, jlong nativeInstance) {
814 (void)clazz;
815 try {
816 shared_ptr_ref<JNIDBGattServerListener> sref(nativeInstance, false /* throw_on_nullptr */); // hold copy until done
817 if( nullptr != sref.pointer() ) {
818 std::shared_ptr<JNIDBGattServerListener>* sref_ptr = castInstance<JNIDBGattServerListener>(nativeInstance);
819 delete sref_ptr;
820 }
821 } catch(...) {
823 }
824}
jobject Java_org_direct_1bt_DBGattDesc_getValue(JNIEnv *env, jobject obj)
DBGattDesc.
jshort Java_org_direct_1bt_DBGattService_getEndHandle(JNIEnv *env, jobject obj)
jint Java_org_direct_1bt_DBGattServer_getMaxAttMTU(JNIEnv *env, jobject obj)
void Java_org_direct_1bt_DBGattServer_setMaxAttMTU(JNIEnv *env, jobject obj, jint v)
jboolean Java_org_direct_1bt_DBGattServer_addListenerImpl(JNIEnv *env, jobject obj, jobject jlistener)
jlong Java_org_direct_1bt_DBGattChar_ctorImpl(JNIEnv *env, jobject obj, jstring jtype_, jbyte jproperties, jlongArray jDescriptors, jbyteArray jvalue_, jint jcapacity_, jboolean jvariable_length_)
private native long ctorImpl(final String type, final byte properties,...
void Java_org_direct_1bt_DBGattServer_00024Listener_dtorImpl(JNIEnv *env, jclass clazz, jlong nativeInstance)
jstring Java_org_direct_1bt_DBGattServer_toString(JNIEnv *env, jobject obj)
static const std::string _dbGattValueClazzName("org/direct_bt/DBGattValue")
DBGattValue.
static const std::string _dbGattValueClazzCtorArgs("([BIZ)V")
jboolean Java_org_direct_1bt_DBGattChar_setValue(JNIEnv *env, jobject obj, jbyteArray jsource, jint jsource_pos, jint jsource_len, jint jdest_pos)
jshort Java_org_direct_1bt_DBGattDesc_getHandle(JNIEnv *env, jobject obj)
jlong Java_org_direct_1bt_DBGattServer_ctorImpl(JNIEnv *env, jobject obj, jint jmax_att_mtu, jlongArray jService)
DBGattServer.
jboolean Java_org_direct_1bt_DBGattDesc_setValue(JNIEnv *env, jobject obj, jbyteArray jsource, jint jsource_pos, jint jsource_len, jint jdest_pos)
jstring Java_org_direct_1bt_DBGattChar_toString(JNIEnv *env, jobject obj)
jshort Java_org_direct_1bt_DBGattChar_getHandle(JNIEnv *env, jobject obj)
void Java_org_direct_1bt_DBGattChar_bzero(JNIEnv *env, jobject obj)
void Java_org_direct_1bt_DBGattDesc_bzero(JNIEnv *env, jobject obj)
jstring Java_org_direct_1bt_DBGattDesc_toString(JNIEnv *env, jobject obj)
jlong Java_org_direct_1bt_DBGattDesc_ctorImpl(JNIEnv *env, jobject obj, jstring jtype_, jbyteArray jvalue_, jint jcapacity_, jboolean jvariable_length_)
private native long ctorImpl(final String type, final byte[] value,...
jobject Java_org_direct_1bt_DBGattChar_getValue(JNIEnv *env, jobject obj)
DBGattChar.
static jobject _createDBGattValueFromChar(JNIEnv *env_, jclass clazz, jmethodID clazz_ctor, const DBGattCharRef &valueHolder)
jlong Java_org_direct_1bt_DBGattService_ctorImpl(JNIEnv *env, jobject obj, jboolean jprimary, jstring jtype_, jlongArray jCharacteristics)
DBGattService.
jlong Java_org_direct_1bt_DBGattServer_00024Listener_ctorImpl(JNIEnv *env, jobject obj)
jshort Java_org_direct_1bt_DBGattChar_getEndHandle(JNIEnv *env, jobject obj)
jstring Java_org_direct_1bt_DBGattService_toString(JNIEnv *env, jobject obj)
void Java_org_direct_1bt_DBGattServer_dtorImpl(JNIEnv *env, jclass clazz, jlong nativeInstance)
jshort Java_org_direct_1bt_DBGattService_getHandle(JNIEnv *env, jobject obj)
jboolean Java_org_direct_1bt_DBGattServer_removeListenerImpl(JNIEnv *env, jobject obj, jobject jlistener)
jshort Java_org_direct_1bt_DBGattChar_getValueHandle(JNIEnv *env, jobject obj)
void Java_org_direct_1bt_DBGattService_dtorImpl(JNIEnv *env, jclass clazz, jlong nativeInstance)
void Java_org_direct_1bt_DBGattChar_dtorImpl(JNIEnv *env, jclass clazz, jlong nativeInstance)
void Java_org_direct_1bt_DBGattDesc_dtorImpl(JNIEnv *env, jclass clazz, jlong nativeInstance)
static jobject _createDBGattValueFromDesc(JNIEnv *env_, jclass clazz, jmethodID clazz_ctor, const DBGattDescRef &valueHolder)
#define E_FILE_LINE
DBGattServer.Listener and related DBGattServer methods.
void connected(const BTDeviceRef &device, const uint16_t initialMTU) override
Notification that device got connected.
JNIDBGattServerListener(JNIEnv *env, jclass clazz, jobject obj)
void mtuChanged(const BTDeviceRef &device, const uint16_t mtu) override
Notification that the MTU has changed.
void writeCharValueDone(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c) override
Notifies completion of single or bulk writeCharValue() after having accepted and performed all write ...
bool writeDescValue(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c, const DBGattDescRef &d, const jau::TROOctets &value, const uint16_t value_offset) override
Signals attempt to write a single or bulk (prepare) value.
void writeDescValueDone(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c, const DBGattDescRef &d) override
Notifies completion of single or bulk writeCharValue() after having accepted and performed all write ...
~JNIDBGattServerListener() noexcept override=default
void clientCharConfigChanged(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c, const DBGattDescRef &d, const bool notificationEnabled, const bool indicationEnabled) override
Notifies a change of the Client Characteristic Configuration Descriptor (CCCD) value.
bool writeCharValue(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c, const jau::TROOctets &value, const uint16_t value_offset) override
Signals attempt to write a single or bulk (prepare) value.
bool readCharValue(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c) override
Signals attempt to read a value.
void disconnected(const BTDeviceRef &device) override
Notification that device got disconnected.
bool readDescValue(const BTDeviceRef &device, const DBGattServiceRef &s, const DBGattCharRef &c, const DBGattDescRef &d) override
Signals attempt to read a value.
PropertyBitVal
BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.1.1 Characteristic Properties.
Definition: BTGattChar.hpp:105
Representing a Gatt Characteristic object from the GATTRole::Server perspective.
Representing a Gatt Characteristic Descriptor object from the GATTRole::Server perspective.
Listener to remote master device's operations on the local GATT-Server.
Representing a complete list of Gatt Service objects from the GATTRole::Server perspective,...
Representing a Gatt Service object from the GATTRole::Server perspective.
Persistent endian aware octet data, i.e.
Definition: octets.hpp:560
constexpr nsize_t capacity() const noexcept
Returns the memory capacity, never zero, greater or equal size().
Definition: octets.hpp:591
void put_bytes_nc(const nsize_t i, const uint8_t *source, const nsize_t byte_count) noexcept
Definition: octets.hpp:416
Transient read only and endian aware octet data, i.e.
Definition: octets.hpp:67
constexpr nsize_t size() const noexcept
Returns the used memory size for read and write operations, may be zero.
Definition: octets.hpp:162
constexpr uint8_t const * get_ptr() const noexcept
Definition: octets.hpp:272
constexpr size_type capacity() const noexcept
Return the current capacity.
Definition: darray.hpp:738
constexpr void push_back(const value_type &x)
Like std::vector::push_back(), copy.
Definition: darray.hpp:1124
T * get(U jarray_val, Mode mode_val=UPDATE_AND_RELEASE)
Acquired the primitive array.
Definition: jni_mem.hpp:193
Implementation for JavaAnon, by simply wrapping a JNIGlobalRef instance.
Definition: helper_jni.hpp:166
jobject getObject() const noexcept
Definition: helper_jni.hpp:232
A std::shared_ptr<T> storage instance to be copied from and released into a java object's long native...
Definition: helper_jni.hpp:393
bool is_null() const noexcept
Returns true if either this instances shared_ptr<T> storage or the managed object reference is nullpt...
Definition: helper_jni.hpp:614
const std::shared_ptr< T > & shared_ptr() const
Provides access to const reference of shared_ptr<T>, r-value.
Definition: helper_jni.hpp:630
std::shared_ptr< T > * pointer() noexcept
Provides access to the shared_ptr<T> pointer, l-value of storage.
Definition: helper_jni.hpp:621
std::string toString() const noexcept
Definition: helper_jni.hpp:657
jlong release_to_jlong() noexcept
Release ownership and return the jlong representation of the shared_ptr<T> storage.
Definition: helper_jni.hpp:574
static std::unique_ptr< uuid_t > create(TypeSize const t, uint8_t const *const buffer, lb_endian_t const le_or_be)
Definition: uuid.cpp:56
@ little
Identifier for little endian, equivalent to endian::little.
std::shared_ptr< BTDevice > BTDeviceRef
Definition: BTDevice.hpp:1347
std::shared_ptr< DBGattDesc > DBGattDescRef
std::shared_ptr< DBGattService > DBGattServiceRef
std::shared_ptr< DBGattChar > DBGattCharRef
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
Definition: int_types.hpp:53
void java_exception_check_and_throw(JNIEnv *env, const char *file, int line)
Throws a C++ exception if a java exception occurred, otherwise do nothing.
thread_local JNIEnvContainer jni_env
jstring from_string_to_jstring(JNIEnv *env, const std::string &str)
jmethodID search_method(JNIEnv *env, jclass clazz, const char *method_name, const char *prototype, bool is_static)
std::shared_ptr< JavaAnon > JavaAnonRef
Definition: java_uplink.hpp:55
std::string from_jstring_to_string(JNIEnv *env, jstring str)
jclass search_class(JNIEnv *env, const char *clazz_name)
#define rethrow_and_raise_java_exception(E)
Re-throw current exception and raise respective java exception using any matching function above.
Definition: helper_base.hpp:52