Direct-BT v3.3.0-1-gc2d430c
Direct-BT - Direct Bluetooth Programming.
DBTGattChar.cxx
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2020 Gothel Software e.K.
4 * Copyright (c) 2020 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 "jau_direct_bt_DBTGattChar.h"
27
28#include <jau/debug.hpp>
29
30#include "helper_base.hpp"
31#include "helper_dbt.hpp"
32
35
36using namespace direct_bt;
37using namespace jau::jni;
38
39void Java_jau_direct_1bt_DBTGattChar_deleteImpl(JNIEnv *env, jobject obj, jlong nativeInstance) {
40 (void)obj;
41 try {
42 shared_ptr_ref<BTGattChar> sref(nativeInstance, false /* throw_on_nullptr */); // hold copy until done
43 if( nullptr != sref.pointer() ) {
44 std::shared_ptr<BTGattChar>* sref_ptr = castInstance<BTGattChar>(nativeInstance);
45 delete sref_ptr;
46 }
47 } catch(...) {
49 }
50}
51
52jstring Java_jau_direct_1bt_DBTGattChar_toStringImpl(JNIEnv *env, jobject obj) {
53 try {
54 shared_ptr_ref<BTGattChar> characteristic(env, obj); // hold until done
55 JavaAnonRef characteristic_java = characteristic->getJavaObject(); // hold until done!
56 JavaGlobalObj::check(characteristic_java, E_FILE_LINE);
57 return from_string_to_jstring(env, characteristic->toString());
58 } catch(...) {
60 }
61 return nullptr;
62}
63
64static const std::string _descriptorClazzCtorArgs("(JLjau/direct_bt/DBTGattChar;Ljava/lang/String;S[B)V");
65
66jobject Java_jau_direct_1bt_DBTGattChar_getDescriptorsImpl(JNIEnv *env, jobject obj) {
67 try {
68 shared_ptr_ref<BTGattChar> characteristic(env, obj); // hold until done
69 JavaAnonRef characteristic_java = characteristic->getJavaObject(); // hold until done!
70 JavaGlobalObj::check(characteristic_java, E_FILE_LINE);
71
72 jau::darray<BTGattDescRef> & descriptorList = characteristic->descriptorList;
73
74 // BTGattDesc(final long nativeInstance, final BTGattChar characteristic,
75 // final String type_uuid, final short handle, final byte[] value)
76
77 // BTGattDesc(final long nativeInstance, final BTGattChar characteristic,
78 // final String type_uuid, final short handle, final byte[] value)
79
80 jau::function<jobject(JNIEnv*, jclass, jmethodID, const BTGattDescRef&)> ctor_desc =
81 [](JNIEnv *env_, jclass clazz, jmethodID clazz_ctor, const BTGattDescRef& descriptor)->jobject {
82 // prepare adapter ctor
83 std::shared_ptr<BTGattChar> _characteristic = descriptor->getGattCharUnchecked();
84 if( nullptr == _characteristic ) {
85 throw jau::RuntimeException("Descriptor's characteristic null: "+descriptor->toString(), E_FILE_LINE);
86 }
87 JavaAnonRef _characteristic_java = _characteristic->getJavaObject(); // hold until done!
88 JavaGlobalObj::check(_characteristic_java, E_FILE_LINE);
89 jobject jcharacteristic = JavaGlobalObj::GetObject(_characteristic_java);
90
91 const jstring juuid = from_string_to_jstring(env_, descriptor->type->toUUID128String());
93
94 const size_t value_size = descriptor->value.size();
95 jbyteArray jval = env_->NewByteArray((jsize)value_size);
96 env_->SetByteArrayRegion(jval, 0, (jsize)value_size, (const jbyte *)descriptor->value.get_ptr());
98
99 shared_ptr_ref<BTGattDesc> descriptor_sref(descriptor); // new instance to be released into new jobject
100 jobject jdesc = env_->NewObject(clazz, clazz_ctor, descriptor_sref.release_to_jlong(), jcharacteristic,
101 juuid, (jshort)descriptor->handle, jval);
103 JNIGlobalRef::check(jdesc, E_FILE_LINE);
104 JavaAnonRef jDescRef = descriptor->getJavaObject(); // GlobalRef
105 JavaGlobalObj::check(jDescRef, E_FILE_LINE);
106 env_->DeleteLocalRef(juuid);
107 env_->DeleteLocalRef(jval);
108 env_->DeleteLocalRef(jdesc);
109 return JavaGlobalObj::GetObject(jDescRef);
110 };
111 return convert_vector_sharedptr_to_jarraylist<jau::darray<BTGattDescRef>, BTGattDesc>(
112 env, descriptorList, _descriptorClazzCtorArgs.c_str(), ctor_desc);
113 } catch(...) {
115 }
116 return nullptr;
117}
118
119jbyteArray Java_jau_direct_1bt_DBTGattChar_readValueImpl(JNIEnv *env, jobject obj) {
120 try {
121 shared_ptr_ref<BTGattChar> characteristic(env, obj); // hold until done
122 JavaAnonRef characteristic_java = characteristic->getJavaObject(); // hold until done!
123 JavaGlobalObj::check(characteristic_java, E_FILE_LINE);
124
125 jau::POctets res(BTGattHandler::number(BTGattHandler::Defaults::MAX_ATT_MTU), 0, jau::lb_endian_t::little);
126 if( !characteristic->readValue(res) ) {
127 ERR_PRINT("Characteristic readValue failed: %s", characteristic->toString().c_str());
128 return env->NewByteArray((jsize)0);
129 }
130
131 const size_t value_size = res.size();
132 jbyteArray jres = env->NewByteArray((jsize)value_size);
133 env->SetByteArrayRegion(jres, 0, (jsize)value_size, (const jbyte *)res.get_ptr());
135 return jres;
136
137 } catch(...) {
139 }
140 return nullptr;
141}
142
143jboolean Java_jau_direct_1bt_DBTGattChar_writeValueImpl(JNIEnv *env, jobject obj, jbyteArray jval, jboolean withResponse) {
144 try {
145 shared_ptr_ref<BTGattChar> characteristic(env, obj); // hold until done
146 JavaAnonRef characteristic_java = characteristic->getJavaObject(); // hold until done!
147 JavaGlobalObj::check(characteristic_java, E_FILE_LINE);
148
149 if( nullptr == jval ) {
150 throw jau::IllegalArgumentException("byte array null", E_FILE_LINE);
151 }
152 const int value_size = env->GetArrayLength(jval);
153 if( 0 == value_size ) {
154 return JNI_TRUE;
155 }
156
157 JNICriticalArray<uint8_t, jbyteArray> criticalArray(env); // RAII - release
158 uint8_t * value_ptr = criticalArray.get(jval, criticalArray.Mode::NO_UPDATE_AND_RELEASE);
159 if( nullptr == value_ptr ) {
160 throw jau::InternalError("GetPrimitiveArrayCritical(byte array) is null", E_FILE_LINE);
161 }
162 jau::TROOctets value(value_ptr, value_size, jau::lb_endian_t::little);
163 bool res;
164 if( withResponse ) {
165 res = characteristic->writeValue(value);
166 } else {
167 res = characteristic->writeValueNoResp(value);
168 }
169 if( !res ) {
170 ERR_PRINT("Characteristic writeValue(withResponse %d) failed: %s",
171 withResponse, characteristic->toString().c_str());
172 return JNI_FALSE;
173 }
174 return JNI_TRUE;
175 } catch(...) {
177 }
178 return JNI_FALSE;
179}
180
182 jboolean enableNotification, jboolean enableIndication, jbooleanArray jEnabledState) {
183 try {
184 shared_ptr_ref<BTGattChar> characteristic(env, obj, false /* throw_on_nullptr */); // hold until done
185 if( characteristic.is_null() ) {
186 if( !enableNotification && !enableIndication ) {
187 // OK to have native characteristic being shutdown @ disable
188 DBG_PRINT("Characteristic's native instance has been deleted");
189 return false;
190 }
191 throw jau::IllegalStateException("Characteristic's native instance deleted", E_FILE_LINE);
192 }
193 JavaAnonRef characteristic_java = characteristic->getJavaObject(); // hold until done!
194 JavaGlobalObj::check(characteristic_java, E_FILE_LINE);
195
196 if( nullptr == jEnabledState ) {
197 throw jau::IllegalArgumentException("boolean array null", E_FILE_LINE);
198 }
199 const int state_size = env->GetArrayLength(jEnabledState);
200 if( 2 > state_size ) {
201 throw jau::IllegalArgumentException("boolean array smaller than 2, length "+std::to_string(state_size), E_FILE_LINE);
202 }
203 JNICriticalArray<jboolean, jbooleanArray> criticalArray(env); // RAII - release
204 jboolean * state_ptr = criticalArray.get(jEnabledState, criticalArray.Mode::UPDATE_AND_RELEASE);
205 if( nullptr == state_ptr ) {
206 throw jau::InternalError("GetPrimitiveArrayCritical(boolean array) is null", E_FILE_LINE);
207 }
208
209 bool cccdEnableResult[2];
210 bool res = characteristic->configNotificationIndication(enableNotification, enableIndication, cccdEnableResult);
211 DBG_PRINT("BTGattChar::configNotificationIndication Config Notification(%d), Indication(%d): Result %d",
212 cccdEnableResult[0], cccdEnableResult[1], res);
213 state_ptr[0] = cccdEnableResult[0];
214 state_ptr[1] = cccdEnableResult[1];
215 return res;
216 } catch(...) {
218 }
219 return JNI_FALSE;
220}
221
void Java_jau_direct_1bt_DBTGattChar_deleteImpl(JNIEnv *env, jobject obj, jlong nativeInstance)
Definition: DBTGattChar.cxx:39
jboolean Java_jau_direct_1bt_DBTGattChar_writeValueImpl(JNIEnv *env, jobject obj, jbyteArray jval, jboolean withResponse)
jboolean Java_jau_direct_1bt_DBTGattChar_configNotificationIndicationImpl(JNIEnv *env, jobject obj, jboolean enableNotification, jboolean enableIndication, jbooleanArray jEnabledState)
jbyteArray Java_jau_direct_1bt_DBTGattChar_readValueImpl(JNIEnv *env, jobject obj)
jstring Java_jau_direct_1bt_DBTGattChar_toStringImpl(JNIEnv *env, jobject obj)
Definition: DBTGattChar.cxx:52
static const std::string _descriptorClazzCtorArgs("(JLjau/direct_bt/DBTGattChar;Ljava/lang/String;S[B)V")
jobject Java_jau_direct_1bt_DBTGattChar_getDescriptorsImpl(JNIEnv *env, jobject obj)
Definition: DBTGattChar.cxx:66
#define E_FILE_LINE
Representing a Gatt Characteristic Descriptor object from the GATTRole::Client perspective.
Definition: BTGattDesc.hpp:74
Persistent endian aware octet data, i.e.
Definition: octets.hpp:560
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
Class template jau::function is a general-purpose static-polymorphic function wrapper.
T * get(U jarray_val, Mode mode_val=UPDATE_AND_RELEASE)
Acquired the primitive array.
Definition: jni_mem.hpp:193
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
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
#define ERR_PRINT(...)
Use for unconditional error messages, prefix '[elapsed_time] Error @ FILE:LINE FUNC: '.
Definition: debug.hpp:109
#define DBG_PRINT(...)
Use for environment-variable environment::DEBUG conditional debug messages, prefix '[elapsed_time] De...
Definition: debug.hpp:52
@ little
Identifier for little endian, equivalent to endian::little.
std::string to_string(const alphabet &v) noexcept
Definition: base_codec.hpp:97
std::shared_ptr< BTGattDesc > BTGattDescRef
Definition: BTGattDesc.hpp:190
constexpr uint32_t number(const iostate rhs) noexcept
Definition: byte_stream.hpp:72
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.
jstring from_string_to_jstring(JNIEnv *env, const std::string &str)
std::shared_ptr< JavaAnon > JavaAnonRef
Definition: java_uplink.hpp:55
#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