Swift SDK: Swift Package wrapping libquicproquo_ffi with QpqClient class (connect, login, send, receive, disconnect) for iOS 15+ / macOS 13+. Kotlin SDK: JNI bridge to libquicproquo_ffi with QpqClient class for Android (aarch64, armv7) and JVM, Gradle build configuration. Adds RegisterPushToken RPC (method ID 710) to device.proto for APNs/FCM/WebPush device push token registration.
118 lines
3.6 KiB
C
118 lines
3.6 KiB
C
/**
|
|
* JNI bridge between Kotlin/Java and libquicproquo_ffi.
|
|
*
|
|
* Compile with:
|
|
* gcc -shared -fPIC -o libquicproquo_jni.so \
|
|
* -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" \
|
|
* dev_quicproquo_NativeBridge.c \
|
|
* -L ../../../../target/release -lquicproquo_ffi
|
|
*/
|
|
|
|
#include <jni.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
/* Forward declarations for libquicproquo_ffi functions. */
|
|
typedef struct QpqHandle QpqHandle;
|
|
|
|
extern QpqHandle* qpq_connect(const char* server, const char* ca_cert, const char* server_name);
|
|
extern int qpq_login(QpqHandle* handle, const char* username, const char* password);
|
|
extern int qpq_send(QpqHandle* handle, const char* recipient,
|
|
const uint8_t* message, size_t message_len);
|
|
extern int qpq_receive(QpqHandle* handle, uint32_t timeout_ms, char** out_json);
|
|
extern void qpq_disconnect(QpqHandle* handle);
|
|
extern const char* qpq_last_error(const QpqHandle* handle);
|
|
extern void qpq_free_string(char* ptr);
|
|
|
|
/* --- JNI exports --- */
|
|
|
|
JNIEXPORT jlong JNICALL
|
|
Java_dev_quicproquo_NativeBridge_nativeConnect(
|
|
JNIEnv* env, jclass cls,
|
|
jstring server, jstring caCert, jstring serverName)
|
|
{
|
|
const char* s = (*env)->GetStringUTFChars(env, server, NULL);
|
|
const char* c = (*env)->GetStringUTFChars(env, caCert, NULL);
|
|
const char* n = (*env)->GetStringUTFChars(env, serverName, NULL);
|
|
|
|
QpqHandle* h = qpq_connect(s, c, n);
|
|
|
|
(*env)->ReleaseStringUTFChars(env, server, s);
|
|
(*env)->ReleaseStringUTFChars(env, caCert, c);
|
|
(*env)->ReleaseStringUTFChars(env, serverName, n);
|
|
|
|
return (jlong)(uintptr_t)h;
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL
|
|
Java_dev_quicproquo_NativeBridge_nativeLogin(
|
|
JNIEnv* env, jclass cls,
|
|
jlong handle, jstring username, jstring password)
|
|
{
|
|
QpqHandle* h = (QpqHandle*)(uintptr_t)handle;
|
|
const char* u = (*env)->GetStringUTFChars(env, username, NULL);
|
|
const char* p = (*env)->GetStringUTFChars(env, password, NULL);
|
|
|
|
int code = qpq_login(h, u, p);
|
|
|
|
(*env)->ReleaseStringUTFChars(env, username, u);
|
|
(*env)->ReleaseStringUTFChars(env, password, p);
|
|
return code;
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL
|
|
Java_dev_quicproquo_NativeBridge_nativeSend(
|
|
JNIEnv* env, jclass cls,
|
|
jlong handle, jstring recipient, jbyteArray message)
|
|
{
|
|
QpqHandle* h = (QpqHandle*)(uintptr_t)handle;
|
|
const char* r = (*env)->GetStringUTFChars(env, recipient, NULL);
|
|
jsize len = (*env)->GetArrayLength(env, message);
|
|
jbyte* bytes = (*env)->GetByteArrayElements(env, message, NULL);
|
|
|
|
int code = qpq_send(h, r, (const uint8_t*)bytes, (size_t)len);
|
|
|
|
(*env)->ReleaseByteArrayElements(env, message, bytes, JNI_ABORT);
|
|
(*env)->ReleaseStringUTFChars(env, recipient, r);
|
|
return code;
|
|
}
|
|
|
|
JNIEXPORT jstring JNICALL
|
|
Java_dev_quicproquo_NativeBridge_nativeReceive(
|
|
JNIEnv* env, jclass cls,
|
|
jlong handle, jint timeoutMs)
|
|
{
|
|
QpqHandle* h = (QpqHandle*)(uintptr_t)handle;
|
|
char* json = NULL;
|
|
int code = qpq_receive(h, (uint32_t)timeoutMs, &json);
|
|
|
|
if (code != 0 || json == NULL) {
|
|
if (json) qpq_free_string(json);
|
|
return NULL;
|
|
}
|
|
|
|
jstring result = (*env)->NewStringUTF(env, json);
|
|
qpq_free_string(json);
|
|
return result;
|
|
}
|
|
|
|
JNIEXPORT void JNICALL
|
|
Java_dev_quicproquo_NativeBridge_nativeDisconnect(
|
|
JNIEnv* env, jclass cls, jlong handle)
|
|
{
|
|
QpqHandle* h = (QpqHandle*)(uintptr_t)handle;
|
|
if (h) {
|
|
qpq_disconnect(h);
|
|
}
|
|
}
|
|
|
|
JNIEXPORT jstring JNICALL
|
|
Java_dev_quicproquo_NativeBridge_nativeLastError(
|
|
JNIEnv* env, jclass cls, jlong handle)
|
|
{
|
|
QpqHandle* h = (QpqHandle*)(uintptr_t)handle;
|
|
const char* err = qpq_last_error(h);
|
|
if (!err) return NULL;
|
|
return (*env)->NewStringUTF(env, err);
|
|
}
|