Direct-BT  2.3.1
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 
33 #include "direct_bt/BTDevice.hpp"
34 #include "direct_bt/BTAdapter.hpp"
35 
36 using namespace direct_bt;
37 using namespace jau;
38 
39 jstring Java_jau_direct_1bt_DBTGattChar_toStringImpl(JNIEnv *env, jobject obj) {
40  try {
41  BTGattChar *nativePtr = getJavaUplinkObject<BTGattChar>(env, obj);
42  JavaGlobalObj::check(nativePtr->getJavaObject(), E_FILE_LINE);
43  return from_string_to_jstring(env, nativePtr->toString());
44  } catch(...) {
46  }
47  return nullptr;
48 }
49 
50 void Java_jau_direct_1bt_DBTGattChar_deleteImpl(JNIEnv *env, jobject obj, jlong nativeInstance) {
51  (void)obj;
52  try {
53  BTGattChar *characteristic = castInstance<BTGattChar>(nativeInstance);
54  (void)characteristic;
55  // No delete: Service instance owned by BTGattService -> BTDevice
56  } catch(...) {
58  }
59 }
60 
61 static const std::string _descriptorClazzCtorArgs("(JLjau/direct_bt/DBTGattChar;Ljava/lang/String;S[B)V");
62 
63 jobject Java_jau_direct_1bt_DBTGattChar_getDescriptorsImpl(JNIEnv *env, jobject obj) {
64  try {
65  BTGattChar *characteristic = getJavaUplinkObject<BTGattChar>(env, obj);
66  JavaGlobalObj::check(characteristic->getJavaObject(), E_FILE_LINE);
67 
68  jau::darray<BTGattDescRef> & descriptorList = characteristic->descriptorList;
69 
70  // BTGattDesc(final long nativeInstance, final BTGattChar characteristic,
71  // final String type_uuid, final short handle, final byte[] value)
72 
73  // BTGattDesc(final long nativeInstance, final BTGattChar characteristic,
74  // final String type_uuid, final short handle, final byte[] value)
75 
76  std::function<jobject(JNIEnv*, jclass, jmethodID, BTGattDesc *)> ctor_desc =
77  [](JNIEnv *env_, jclass clazz, jmethodID clazz_ctor, BTGattDesc *descriptor)->jobject {
78  // prepare adapter ctor
79  std::shared_ptr<BTGattChar> _characteristic = descriptor->getGattCharChecked();
80  JavaGlobalObj::check(_characteristic->getJavaObject(), E_FILE_LINE);
81  jobject jcharacteristic = JavaGlobalObj::GetObject(_characteristic->getJavaObject());
82 
83  const jstring juuid = from_string_to_jstring(env_,
84  directBTJNISettings.getUnifyUUID128Bit() ? descriptor->type->toUUID128String() :
85  descriptor->type->toString());
87 
88  const size_t value_size = descriptor->value.getSize();
89  jbyteArray jval = env_->NewByteArray((jsize)value_size);
90  env_->SetByteArrayRegion(jval, 0, (jsize)value_size, (const jbyte *)descriptor->value.get_ptr());
92 
93  jobject jdesc = env_->NewObject(clazz, clazz_ctor, (jlong)descriptor, jcharacteristic,
94  juuid, (jshort)descriptor->handle, jval);
97  std::shared_ptr<JavaAnon> jDescRef = descriptor->getJavaObject(); // GlobalRef
98  JavaGlobalObj::check(jDescRef, E_FILE_LINE);
99  env_->DeleteLocalRef(juuid);
100  env_->DeleteLocalRef(jval);
101  env_->DeleteLocalRef(jdesc);
102  return JavaGlobalObj::GetObject(jDescRef);
103  };
104  return convert_vector_sharedptr_to_jarraylist<jau::darray<BTGattDescRef>, BTGattDesc>(
105  env, descriptorList, _descriptorClazzCtorArgs.c_str(), ctor_desc);
106  } catch(...) {
108  }
109  return nullptr;
110 }
111 
112 jbyteArray Java_jau_direct_1bt_DBTGattChar_readValueImpl(JNIEnv *env, jobject obj) {
113  try {
114  BTGattChar *characteristic = getJavaUplinkObject<BTGattChar>(env, obj);
115  JavaGlobalObj::check(characteristic->getJavaObject(), E_FILE_LINE);
116 
118  if( !characteristic->readValue(res) ) {
119  ERR_PRINT("Characteristic readValue failed: %s", characteristic->toString().c_str());
120  return env->NewByteArray((jsize)0);
121  }
122 
123  const size_t value_size = res.getSize();
124  jbyteArray jres = env->NewByteArray((jsize)value_size);
125  env->SetByteArrayRegion(jres, 0, (jsize)value_size, (const jbyte *)res.get_ptr());
127  return jres;
128 
129  } catch(...) {
131  }
132  return nullptr;
133 }
134 
135 jboolean Java_jau_direct_1bt_DBTGattChar_writeValueImpl(JNIEnv *env, jobject obj, jbyteArray jval, jboolean withResponse) {
136  try {
137  if( nullptr == jval ) {
138  throw IllegalArgumentException("byte array null", E_FILE_LINE);
139  }
140  const int value_size = env->GetArrayLength(jval);
141  if( 0 == value_size ) {
142  return JNI_TRUE;
143  }
144  BTGattChar *characteristic = getJavaUplinkObject<BTGattChar>(env, obj);
145  JavaGlobalObj::check(characteristic->getJavaObject(), E_FILE_LINE);
146 
147  JNICriticalArray<uint8_t, jbyteArray> criticalArray(env); // RAII - release
148  uint8_t * value_ptr = criticalArray.get(jval, criticalArray.Mode::NO_UPDATE_AND_RELEASE);
149  if( NULL == value_ptr ) {
150  throw InternalError("GetPrimitiveArrayCritical(byte array) is null", E_FILE_LINE);
151  }
152  TROOctets value(value_ptr, value_size);
153  bool res;
154  if( withResponse ) {
155  res = characteristic->writeValue(value);
156  } else {
157  res = characteristic->writeValueNoResp(value);
158  }
159  if( !res ) {
160  ERR_PRINT("Characteristic writeValue(withResponse %d) failed: %s",
161  withResponse, characteristic->toString().c_str());
162  return JNI_FALSE;
163  }
164  return JNI_TRUE;
165  } catch(...) {
167  }
168  return JNI_FALSE;
169 }
170 
172  jboolean enableNotification, jboolean enableIndication, jbooleanArray jEnabledState) {
173  try {
174  BTGattChar *characteristic = getJavaUplinkObjectUnchecked<BTGattChar>(env, obj);
175  if( nullptr == characteristic ) {
176  if( !enableNotification && !enableIndication ) {
177  // OK to have native characteristic being shutdown @ disable
178  DBG_PRINT("Characteristic's native instance has been deleted");
179  return false;
180  }
181  throw IllegalStateException("Characteristic's native instance deleted", E_FILE_LINE);
182  }
183  JavaGlobalObj::check(characteristic->getJavaObject(), E_FILE_LINE);
184 
185  if( nullptr == jEnabledState ) {
186  throw IllegalArgumentException("boolean array null", E_FILE_LINE);
187  }
188  const int state_size = env->GetArrayLength(jEnabledState);
189  if( 2 > state_size ) {
190  throw IllegalArgumentException("boolean array smaller than 2, length "+std::to_string(state_size), E_FILE_LINE);
191  }
192  JNICriticalArray<jboolean, jbooleanArray> criticalArray(env); // RAII - release
193  jboolean * state_ptr = criticalArray.get(jEnabledState, criticalArray.Mode::UPDATE_AND_RELEASE);
194  if( NULL == state_ptr ) {
195  throw InternalError("GetPrimitiveArrayCritical(boolean array) is null", E_FILE_LINE);
196  }
197 
198  bool cccdEnableResult[2];
199  bool res = characteristic->configNotificationIndication(enableNotification, enableIndication, cccdEnableResult);
200  DBG_PRINT("BTGattChar::configNotificationIndication Config Notification(%d), Indication(%d): Result %d",
201  cccdEnableResult[0], cccdEnableResult[1], res);
202  state_ptr[0] = cccdEnableResult[0];
203  state_ptr[1] = cccdEnableResult[1];
204  return res;
205  } catch(...) {
207  }
208  return JNI_FALSE;
209 }
210 
direct_bt::TROOctets::getSize
constexpr jau::nsize_t getSize() const noexcept
Returns the used memory size for read and write operations, may be zero.
Definition: OctetTypes.hpp:118
Java_jau_direct_1bt_DBTGattChar_readValueImpl
jbyteArray Java_jau_direct_1bt_DBTGattChar_readValueImpl(JNIEnv *env, jobject obj)
Definition: DBTGattChar.cxx:112
Java_jau_direct_1bt_DBTGattChar_toStringImpl
jstring Java_jau_direct_1bt_DBTGattChar_toStringImpl(JNIEnv *env, jobject obj)
Definition: DBTGattChar.cxx:39
direct_bt::BTGattChar::readValue
bool readValue(POctets &res, int expectedLength=-1)
BT Core Spec v5.2: Vol 3, Part G GATT: 4.8.1 Read Characteristic Value.
Definition: BTGattChar.cpp:304
jau::IllegalArgumentException
Definition: basic_types.hpp:111
jau::from_string_to_jstring
jstring from_string_to_jstring(JNIEnv *env, const std::string &str)
helper_dbt.hpp
helper_base.hpp
direct_bt
Definition: ATTPDUTypes.hpp:171
direct_bt::BTGattChar
Definition: BTGattChar.hpp:75
jau::InternalError
Definition: basic_types.hpp:93
direct_bt::DirectBTJNISettings::getUnifyUUID128Bit
bool getUnifyUUID128Bit()
Enables or disables uuid128_t consolidation for native uuid16_t and uuid32_t values before string con...
Definition: helper_dbt.hpp:47
direct_bt::TROOctets::get_ptr
constexpr uint8_t const * get_ptr() const noexcept
Definition: OctetTypes.hpp:228
jau
Definition: basic_algos.hpp:34
jau::java_exception_check_and_throw
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.
jau::to_string
PRAGMA_DISABLE_WARNING_POP constexpr_cxx20 std::string to_string(const endian &v) noexcept
Return std::string representation of the given jau::endian.
Definition: byte_util.hpp:198
E_FILE_LINE
#define E_FILE_LINE
Definition: basic_types.hpp:64
direct_bt::directBTJNISettings
DirectBTJNISettings directBTJNISettings
Definition: helper_dbt.cxx:35
jau::darray< BTGattDescRef >
BTAdapter.hpp
direct_bt::BTGattHandler::Defaults::MAX_ATT_MTU
@ MAX_ATT_MTU
JNIGlobalRef::check
static void check(jobject object, const char *file, int line)
Definition: jni_mem.hpp:80
JNICriticalArray::get
T * get(U jarray_val, Mode mode_val=UPDATE_AND_RELEASE)
Acquired the primitive array.
Definition: jni_mem.hpp:177
direct_bt::BTGattChar::toString
std::string toString() const noexcept override
Definition: BTGattChar.cpp:106
JNICriticalArray
Definition: jni_mem.hpp:126
debug.hpp
direct_bt::TROOctets
Transient read only octet data, i.e.
Definition: OctetTypes.hpp:59
rethrow_and_raise_java_exception
#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:55
jau::IllegalStateException
Definition: basic_types.hpp:117
Java_jau_direct_1bt_DBTGattChar_writeValueImpl
jboolean Java_jau_direct_1bt_DBTGattChar_writeValueImpl(JNIEnv *env, jobject obj, jbyteArray jval, jboolean withResponse)
Definition: DBTGattChar.cxx:135
ERR_PRINT
#define ERR_PRINT(...)
Use for unconditional error messages, prefix '[elapsed_time] Error @ FILE:LINE: '.
Definition: debug.hpp:132
direct_bt::BTGattChar::writeValue
bool writeValue(const TROOctets &value)
BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.3 Write Characteristic Value.
Definition: BTGattChar.cpp:315
direct_bt::BTGattChar::configNotificationIndication
bool configNotificationIndication(const bool enableNotification, const bool enableIndication, bool enabledState[2])
BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3.3 Client Characteristic Configuration.
Definition: BTGattChar.cpp:186
direct_bt::BTGattChar::writeValueNoResp
bool writeValueNoResp(const TROOctets &value)
BT Core Spec v5.2: Vol 3, Part G GATT: 4.9.1 Write Characteristic Value Without Response.
Definition: BTGattChar.cpp:327
direct_bt::BTGattChar::descriptorList
jau::darray< BTGattDescRef > descriptorList
List of Characteristic Descriptions as shared reference.
Definition: BTGattChar.hpp:192
direct_bt::POctets
Persistent octet data, i.e.
Definition: OctetTypes.hpp:451
direct_bt::BTGattHandler::number
static constexpr int number(const Defaults d)
Definition: BTGattHandler.hpp:149
BTDevice.hpp
direct_bt::BTGattDesc
BT Core Spec v5.2: Vol 3, Part G GATT: 3.3.3 Characteristic Descriptor.
Definition: BTGattDesc.hpp:62
DBG_PRINT
#define DBG_PRINT(...)
Use for environment-variable environment::DEBUG conditional debug messages, prefix '[elapsed_time] De...
Definition: debug.hpp:78
Java_jau_direct_1bt_DBTGattChar_getDescriptorsImpl
jobject Java_jau_direct_1bt_DBTGattChar_getDescriptorsImpl(JNIEnv *env, jobject obj)
Definition: DBTGattChar.cxx:63
Java_jau_direct_1bt_DBTGattChar_deleteImpl
void Java_jau_direct_1bt_DBTGattChar_deleteImpl(JNIEnv *env, jobject obj, jlong nativeInstance)
Definition: DBTGattChar.cxx:50
Java_jau_direct_1bt_DBTGattChar_configNotificationIndicationImpl
jboolean Java_jau_direct_1bt_DBTGattChar_configNotificationIndicationImpl(JNIEnv *env, jobject obj, jboolean enableNotification, jboolean enableIndication, jbooleanArray jEnabledState)
Definition: DBTGattChar.cxx:171
_descriptorClazzCtorArgs
static const std::string _descriptorClazzCtorArgs("(JLjau/direct_bt/DBTGattChar;Ljava/lang/String;S[B)V")