-
Notifications
You must be signed in to change notification settings - Fork 6
BT Socket Factory creation and connecting with java code #457
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Aniket392
wants to merge
19
commits into
master
Choose a base branch
from
wip/socket_factory
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
c029675
BT changes for common
Aniket392 76792ba
Update cmakelist and bluetoothpeer enterprise check
Aniket392 25bd509
Updated as build failure due to wrong checks and static declaration
Aniket392 193881a
Updating multipeer replicator argument to take protocol
Aniket392 ccfcd40
Added release for BT peer and removed onIncommingConnection
Aniket392 ed78477
Added public transport APIs and removed UUID sync
Aniket392 1c16c31
Updated the BluetoothPeer object creation in Java instead of native side
Aniket392 6e5c4f6
Updating addpeer and C4Peer creation and protocol usage
Aniket392 fa3eb2a
Conversion of MultipeerTransport and Enumset in java rather than in J…
Aniket392 f2d2aa6
Adding replicatorTansport API
Aniket392 0d1afb9
BT Socket Factory creation and connecting with java code
Aniket392 4c1a7dd
Socketfactory register and fromnative removal and location update
Aniket392 c5c9b8f
Updated Socketfactory's classes from java to android path
Aniket392 85d2f87
Hashmap update and initating the C4BtSocketFactory
Aniket392 bb4b679
Changes needed to make it possible for me to build
borrrden 5240212
Delete dangling local ref
borrrden d20415b
Use byte array slice in its own scope
borrrden 10e64ad
Fix JNI linkage in NativeBluetoothPeer
pasin 43562e5
Use the proper context and directly use string_view
borrrden File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,7 +6,7 @@ | |
| #include <jni.h> | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C++" { | ||
| extern "C" { | ||
| #endif | ||
|
|
||
| /* | ||
|
|
||
21 changes: 21 additions & 0 deletions
21
common/main/cpp/com_couchbase_lite_internal_core_impl_NativeC4BTSocketFactory.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| #ifndef ANDROID_COM_COUCHBASE_LITE_INTERNAL_CORE_IMPL_NATIVEC4BTSOCKETFACTORY_H | ||
| #define ANDROID_COM_COUCHBASE_LITE_INTERNAL_CORE_IMPL_NATIVEC4BTSOCKETFACTORY_H | ||
| #include <jni.h> | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C++" { | ||
| #endif | ||
|
|
||
| JNIEXPORT jlong JNICALL | ||
| Java_com_couchbase_lite_internal_core_impl_NativeC4BTSocketFactory_registerBTSocketFactory( | ||
| JNIEnv*, jclass); | ||
|
|
||
| JNIEXPORT jlong JNICALL | ||
| Java_com_couchbase_lite_internal_core_impl_NativeC4BTSocketFactory_fromNative( | ||
| JNIEnv*, jclass, jlong, jstring, jstring, jlong, jstring, jint); | ||
|
|
||
| #ifdef __cplusplus | ||
| } | ||
| #endif | ||
|
|
||
| #endif //ANDROID_COM_COUCHBASE_LITE_INTERNAL_CORE_IMPL_NATIVEC4BTSOCKETFACTORY_H |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,211 @@ | ||
| #if defined(COUCHBASE_ENTERPRISE) && defined(__ANDROID__) | ||
|
|
||
| #include "c4Socket.h" | ||
| #include "c4Socket.hh" | ||
| #include "c4SocketTypes.h" | ||
| #include "native_glue.hh" | ||
| #include "native_bluetoothpeer_internal.h" | ||
| #include "com_couchbase_lite_internal_core_impl_NativeC4BTSocketFactory.h" | ||
|
|
||
| #include <string> | ||
|
|
||
| using namespace litecore; | ||
| using namespace litecore::jni; | ||
|
|
||
| // ───────────────────────────────────────────────────────────────────────────── | ||
| // Java class / method cache | ||
| // ───────────────────────────────────────────────────────────────────────────── | ||
|
|
||
| static jclass cls_C4BTSocketFactory; | ||
| static jmethodID m_open; | ||
| static jmethodID m_write; | ||
| static jmethodID m_completedReceive; | ||
| static jmethodID m_close; | ||
| static jmethodID m_dispose; | ||
| static jmethodID m_attached; | ||
|
|
||
| bool litecore::jni::initC4BTSocketFactory(JNIEnv* env) { | ||
| jclass localCls = env->FindClass( | ||
| "com/couchbase/lite/internal/p2p/ble/BluetoothSocketFactory"); | ||
| if (!localCls) return false; | ||
|
|
||
| cls_C4BTSocketFactory = reinterpret_cast<jclass>(env->NewGlobalRef(localCls)); | ||
| env->DeleteLocalRef(localCls); | ||
| if (!cls_C4BTSocketFactory) return false; | ||
|
|
||
| // static void open(long c4socketPeer, long factoryToken, String peerID) | ||
| m_open = env->GetStaticMethodID(cls_C4BTSocketFactory, | ||
| "open", "(JJLjava/lang/String;)V"); | ||
| if (!m_open) return false; | ||
|
|
||
| // static void write(long c4socketPeer, byte[] data) | ||
| m_write = env->GetStaticMethodID(cls_C4BTSocketFactory, | ||
| "write", "(J[B)V"); | ||
| if (!m_write) return false; | ||
|
|
||
| // static void completedReceive(long c4socketPeer, long byteCount) | ||
| m_completedReceive = env->GetStaticMethodID(cls_C4BTSocketFactory, | ||
| "completedReceive", "(JJ)V"); | ||
| if (!m_completedReceive) return false; | ||
|
|
||
| // static void close(long c4socketPeer) | ||
| m_close = env->GetStaticMethodID(cls_C4BTSocketFactory, | ||
| "close", "(J)V"); | ||
| if (!m_close) return false; | ||
|
|
||
| // static void dispose(long c4socketPeer) | ||
| m_dispose = env->GetStaticMethodID(cls_C4BTSocketFactory, | ||
| "dispose", "(J)V"); | ||
| if (!m_dispose) return false; | ||
|
|
||
| // static void attached(long c4socketPeer, long btSocketHandle, String peerID) | ||
| m_attached = env->GetStaticMethodID(cls_C4BTSocketFactory, | ||
| "attached", "(JJLjava/lang/String;)V"); | ||
| if (!m_attached) return false; | ||
|
|
||
| jniLog("C4BTSocketFactory: callbacks initialized"); | ||
| return true; | ||
| } | ||
|
|
||
| // ───────────────────────────────────────────────────────────────────────────── | ||
| // C4SocketFactory callback implementations | ||
| // ───────────────────────────────────────────────────────────────────────────── | ||
|
|
||
| static void btOpen(C4Socket* socket, | ||
| const C4Address* addr, | ||
| C4Slice options, | ||
| void* context) { | ||
| JNIEnv* env = nullptr; | ||
| jint envState = attachJVM(&env, "btOpen"); | ||
| if (envState != JNI_OK && envState != JNI_EDETACHED) return; | ||
|
|
||
| c4socket_retain(socket); | ||
|
|
||
| // addr->hostname carries the CBL peer-ID / BT MAC address as a C4Slice. | ||
| // toJString(env, C4Slice) is the correct helper (same as native_c4socket.cc). | ||
| jstring jPeerID = toJString(env, addr->hostname); | ||
|
|
||
| env->CallStaticVoidMethod( | ||
| cls_C4BTSocketFactory, m_open, | ||
| (jlong) socket, | ||
| (jlong) context, // factoryToken = context set at registration | ||
| jPeerID); | ||
|
|
||
| if (envState == JNI_EDETACHED) { | ||
| detachJVM("btOpen"); | ||
| } else { | ||
| if (jPeerID) env->DeleteLocalRef(jPeerID); | ||
| } | ||
| } | ||
|
|
||
| static void btWrite(C4Socket* socket, C4SliceResult allocatedData) { | ||
| JNIEnv* env = nullptr; | ||
| jint envState = attachJVM(&env, "btWrite"); | ||
| if (envState != JNI_OK && envState != JNI_EDETACHED) { | ||
| c4slice_free(allocatedData); | ||
| return; | ||
| } | ||
|
|
||
| jbyteArray jData = toJByteArray(env, allocatedData); | ||
| c4slice_free(allocatedData); | ||
|
|
||
| env->CallStaticVoidMethod(cls_C4BTSocketFactory, m_write, (jlong) socket, jData); | ||
|
|
||
| if (envState == JNI_EDETACHED) { | ||
| detachJVM("btWrite"); | ||
| } else { | ||
| if (jData) env->DeleteLocalRef(jData); | ||
| } | ||
| } | ||
|
|
||
| static void btCompletedReceive(C4Socket* socket, size_t byteCount) { | ||
| JNIEnv* env = nullptr; | ||
| jint envState = attachJVM(&env, "btCompletedReceive"); | ||
| if (envState != JNI_OK && envState != JNI_EDETACHED) return; | ||
|
|
||
| env->CallStaticVoidMethod(cls_C4BTSocketFactory, m_completedReceive, | ||
| (jlong) socket, (jlong) byteCount); | ||
|
|
||
| if (envState == JNI_EDETACHED) detachJVM("btCompletedReceive"); | ||
| } | ||
|
|
||
| static void btClose(C4Socket* socket) { | ||
| JNIEnv* env = nullptr; | ||
| jint envState = attachJVM(&env, "btClose"); | ||
| if (envState != JNI_OK && envState != JNI_EDETACHED) return; | ||
|
|
||
| env->CallStaticVoidMethod(cls_C4BTSocketFactory, m_close, (jlong) socket); | ||
|
|
||
| if (envState == JNI_EDETACHED) detachJVM("btClose"); | ||
| } | ||
|
|
||
| static void btDispose(C4Socket* socket) { | ||
| auto* ctx = static_cast<BTNativeHandle*>(socket->getNativeHandle()); | ||
| if (ctx) { | ||
| socket->setNativeHandle(nullptr); | ||
| delete ctx; | ||
| } | ||
|
|
||
| JNIEnv* env = nullptr; | ||
| jint envState = attachJVM(&env, "btDispose"); | ||
| if (envState != JNI_OK && envState != JNI_EDETACHED) return; | ||
|
|
||
| env->CallStaticVoidMethod(cls_C4BTSocketFactory, m_dispose, (jlong) socket); | ||
|
|
||
| if (envState == JNI_EDETACHED) detachJVM("btDispose"); | ||
| } | ||
|
|
||
| /** | ||
| * btAttached – called by LiteCore after c4socket_fromNative creates the | ||
| * peripheral (incoming) C4Socket. | ||
| * | ||
| * Retrieves the BTNativeHandle stored by fromNative via setNativeHandle(), | ||
| * forwards {btSocketHandle, peerID} to Java, then frees the handle. | ||
| */ | ||
| static void btAttached(C4Socket* socket) { | ||
| auto* ctx = static_cast<BTNativeHandle*>(socket->getNativeHandle()); | ||
| if (!ctx) return; | ||
|
|
||
| // Clear immediately so btDispose won't double-free. | ||
| socket->setNativeHandle(nullptr); | ||
|
|
||
| JNIEnv* env = nullptr; | ||
| jint envState = attachJVM(&env, "btAttached"); | ||
| if (envState != JNI_OK && envState != JNI_EDETACHED) { | ||
| delete ctx; | ||
| return; | ||
| } | ||
|
|
||
| jstring jPeerID = env->NewStringUTF((ctx->peerID).c_str()); | ||
|
|
||
| env->CallStaticVoidMethod( | ||
| cls_C4BTSocketFactory, m_attached, | ||
| (jlong) socket, | ||
| ctx->btSocketHandle, | ||
| jPeerID); | ||
|
|
||
| delete ctx; | ||
|
|
||
| if (envState == JNI_EDETACHED) { | ||
| detachJVM("btAttached"); | ||
| } else { | ||
| if (jPeerID) env->DeleteLocalRef(jPeerID); | ||
| } | ||
| } | ||
|
|
||
| // ───────────────────────────────────────────────────────────────────────────── | ||
| // The factory struct | ||
| // ───────────────────────────────────────────────────────────────────────────── | ||
| namespace litecore::jni { | ||
| const C4SocketFactory kBTSocketFactory{ | ||
| .framing = kC4WebSocketClientFraming, | ||
| .context = nullptr, // filled in at registration time | ||
| .open = btOpen, | ||
| .write = btWrite, | ||
| .completedReceive = btCompletedReceive, | ||
| .close = btClose, | ||
| .dispose = btDispose, | ||
| .attached = btAttached, | ||
| }; | ||
| } | ||
| #endif // COUCHBASE_ENTERPRISE && __ANDROID__ | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on https://developer.android.com/ndk/guides/jni-tips, it's a good practice to call ExceptionCheck() and ExceptionClear() to handle both caught and runtime exception when calling Java code such as
You may check if we have don't this anywhere else or have any helper function for this. If not, I suggest to create a helper function to do this or create a ticket to take care this later if the method doesn't declare throws.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently in code base i can't see similar checks
I will create ticket for same