static void CAReceiveHandler(void *data) { OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler.."); // Input validation VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context"); bool isAttached = false; JNIEnv* env = NULL; jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); if (JNI_OK != res) { OIC_LOG(DEBUG, TAG, "CAReceiveHandler - Could not get JNIEnv pointer"); res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); if (JNI_OK != res) { OIC_LOG(ERROR, TAG, "AttachCurrentThread failed"); return; } isAttached = true; } CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *) data; while (true != *(ctx->stopFlag)) { if (!CAEDRNativeIsEnableBTAdapter(env)) { OIC_LOG(INFO, TAG, "BT adapter is not enabled"); break; } // if new socket object is added in socket list after below logic is ran. // new socket will be started to read after next while loop uint32_t length = CAEDRGetSocketListLength(); if (0 != length) { for (uint32_t idx = 0; idx < length; idx++) { CAEDRNativeReadData(env, idx); } } } if (isAttached) { (*g_jvm)->DetachCurrentThread(g_jvm); } OICFree(ctx); OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler"); }
CAResult_t CAEDRGetAdapterEnableState(bool *state) { OIC_LOG(DEBUG, TAG, "IN"); if (!g_jvm) { OIC_LOG(ERROR, TAG, "g_jvm is null"); return CA_STATUS_INVALID_PARAM; } bool isAttached = false; JNIEnv* env; jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); if (JNI_OK != res) { OIC_LOG(DEBUG, TAG, "CAEDRGetAdapterEnableState - Could not get JNIEnv pointer"); res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); if (JNI_OK != res) { OIC_LOG(ERROR, TAG, "AttachCurrentThread failed"); return CA_STATUS_INVALID_PARAM; } isAttached = true; } jboolean ret = CAEDRNativeIsEnableBTAdapter(env); if (ret) { *state = true; } else { *state = false; } if (isAttached) { (*g_jvm)->DetachCurrentThread(g_jvm); } OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; }
static void CAAcceptHandler(void *data) { OIC_LOG(DEBUG, TAG, "AcceptThread start"); VERIFY_NON_NULL_VOID(data, TAG, "data is null"); bool isAttached = false; JNIEnv* env = NULL; jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6); if (JNI_OK != res) { OIC_LOG(DEBUG, TAG, "Could not get JNIEnv pointer"); res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL); if (JNI_OK != res) { OIC_LOG(ERROR, TAG, "AttachCurrentThread failed"); return; } isAttached = true; } jobject jni_obj_BTServerSocket = CAEDRNativeListen(env); if (!jni_obj_BTServerSocket) { OIC_LOG(ERROR, TAG, "jni_obj_BTServerSocket is null"); if (isAttached) { (*g_jvm)->DetachCurrentThread(g_jvm); } return; } oc_mutex_lock(g_mutexServerSocket); g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket); oc_mutex_unlock(g_mutexServerSocket); CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data; // it should be initialized for restart accept thread oc_mutex_lock(g_mutexAcceptServer); g_stopAccept = false; oc_mutex_unlock(g_mutexAcceptServer); while (true != *(ctx->stopFlag)) { // when BT state is changed with Off. its thread will be stopped if (!CAEDRNativeIsEnableBTAdapter(env)) { OIC_LOG(INFO, TAG, "BT adapter is not enabled"); oc_mutex_lock(g_mutexAcceptServer); g_stopAccept = true; oc_mutex_unlock(g_mutexAcceptServer); oc_mutex_lock(g_mutexServerSocket); g_serverSocket = NULL; oc_mutex_unlock(g_mutexServerSocket); } else { CAEDRNativeAccept(env, g_serverSocket); } } if (isAttached) { (*g_jvm)->DetachCurrentThread(g_jvm); } OICFree(ctx); OIC_LOG(DEBUG, TAG, "AcceptThread finish"); return; }
CAResult_t CAEDRNativeConnect(JNIEnv *env, const char *address) { VERIFY_NON_NULL(address, TAG, "address is null"); if (!CAEDRNativeIsEnableBTAdapter(env)) { OIC_LOG(INFO, TAG, "BT adapter is not enabled"); return CA_ADAPTER_NOT_ENABLED; } jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER); if (!jni_cid_BTAdapter) { OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null"); return CA_STATUS_FAILED; } // get BTadpater jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM); if (!jni_mid_getDefaultAdapter) { OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null"); (*env)->DeleteLocalRef(env, jni_cid_BTAdapter); return CA_STATUS_FAILED; } jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter); if (!jni_obj_BTAdapter) { OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null"); (*env)->DeleteLocalRef(env, jni_cid_BTAdapter); return CA_STATUS_FAILED; } // get remote bluetooth device jmethodID jni_mid_getRemoteDevice = (*env)->GetMethodID(env, jni_cid_BTAdapter, "getRemoteDevice", METHODID_BT_DEVICEPARAM); (*env)->DeleteLocalRef(env, jni_cid_BTAdapter); if (!jni_mid_getRemoteDevice) { OIC_LOG(ERROR, TAG, "jni_mid_getRemoteDevice is null"); (*env)->DeleteLocalRef(env, jni_obj_BTAdapter); return CA_STATUS_FAILED; } jstring jni_address = (*env)->NewStringUTF(env, address); jobject jni_obj_remoteBTDevice = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_getRemoteDevice, jni_address); (*env)->DeleteLocalRef(env, jni_address); (*env)->DeleteLocalRef(env, jni_obj_BTAdapter); if (!jni_obj_remoteBTDevice) { OIC_LOG(ERROR, TAG, "jni_obj_remoteBTDevice is null"); return CA_STATUS_FAILED; } // get create Rfcomm Socket method ID jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE); if (!jni_cid_BluetoothDevice) { OIC_LOG(ERROR, TAG, "jni_cid_BluetoothDevice is null"); (*env)->DeleteLocalRef(env, jni_obj_remoteBTDevice); return CA_STATUS_FAILED; } jmethodID jni_mid_createSocket = (*env)->GetMethodID( env, jni_cid_BluetoothDevice, "createInsecureRfcommSocketToServiceRecord", "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothSocket;"); (*env)->DeleteLocalRef(env, jni_cid_BluetoothDevice); if (!jni_mid_createSocket) { OIC_LOG(ERROR, TAG, "jni_mid_createSocket is null"); (*env)->DeleteLocalRef(env, jni_obj_remoteBTDevice); return CA_STATUS_FAILED; } // setting UUID jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID); if (!jni_cid_uuid) { OIC_LOG(ERROR, TAG, "jni_cid_uuid is null"); (*env)->DeleteLocalRef(env, jni_obj_remoteBTDevice); return CA_STATUS_FAILED; } jmethodID jni_mid_fromString = (*env)->GetStaticMethodID( env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;"); if (!jni_mid_fromString) { OIC_LOG(ERROR, TAG, "jni_mid_fromString is null"); (*env)->DeleteLocalRef(env, jni_cid_uuid); (*env)->DeleteLocalRef(env, jni_obj_remoteBTDevice); return CA_STATUS_FAILED; } jstring jni_uuid = (*env)->NewStringUTF(env, OIC_EDR_SERVICE_ID); if (!jni_uuid) { OIC_LOG(ERROR, TAG, "jni_uuid is null"); (*env)->DeleteLocalRef(env, jni_cid_uuid); (*env)->DeleteLocalRef(env, jni_obj_remoteBTDevice); return CA_STATUS_FAILED; } jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString, jni_uuid); (*env)->DeleteLocalRef(env, jni_cid_uuid); (*env)->DeleteLocalRef(env, jni_uuid); if (!jni_obj_uuid) { OIC_LOG(ERROR, TAG, "jni_obj_uuid is null"); (*env)->DeleteLocalRef(env, jni_obj_remoteBTDevice); return CA_STATUS_FAILED; } // create socket jobject jni_obj_BTSocket = (*env)->CallObjectMethod(env, jni_obj_remoteBTDevice, jni_mid_createSocket, jni_obj_uuid); (*env)->DeleteLocalRef(env, jni_obj_uuid); (*env)->DeleteLocalRef(env, jni_obj_remoteBTDevice); if (!jni_obj_BTSocket) { OIC_LOG(ERROR, TAG, "jni_obj_BTSocket is null"); return CA_STATUS_FAILED; } // connect jclass jni_cid_BTSocket = (*env)->FindClass(env, CLASSPATH_BT_SOCKET); if (!jni_cid_BTSocket) { OIC_LOG(ERROR, TAG, "jni_cid_BTSocket is null"); (*env)->DeleteLocalRef(env, jni_obj_BTSocket); return CA_STATUS_FAILED; } jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_BTSocket, "connect", "()V"); (*env)->DeleteLocalRef(env, jni_cid_BTSocket); if (!jni_mid_connect) { OIC_LOG(ERROR, TAG, "jni_mid_connect is null"); (*env)->DeleteLocalRef(env, jni_obj_BTSocket); return CA_STATUS_FAILED; } OIC_LOG(DEBUG, TAG, "initiating connection..."); (*env)->CallVoidMethod(env, jni_obj_BTSocket, jni_mid_connect); if ((*env)->ExceptionCheck(env)) { OIC_LOG(ERROR, TAG, "Connect is Failed!!!"); (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); return CA_STATUS_FAILED; } // set socket to list jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket); if (!jni_socket) { OIC_LOG(ERROR, TAG, "jni_socket is null"); (*env)->DeleteLocalRef(env, jni_obj_BTSocket); return CA_STATUS_FAILED; } ca_mutex_lock(g_mutexObjectList); CAEDRNativeAddDeviceSocketToList(env, jni_socket); (*env)->DeleteGlobalRef(env, jni_socket); (*env)->DeleteLocalRef(env, jni_obj_BTSocket); ca_mutex_unlock(g_mutexObjectList); // update state ca_mutex_lock(g_mutexStateList); CAEDRUpdateDeviceState(STATE_CONNECTED, address); ca_mutex_unlock(g_mutexStateList); OIC_LOG(DEBUG, TAG, "successfully connected"); return CA_STATUS_OK; }
CAResult_t CAEDRNativeSendData(JNIEnv *env, const char *address, const uint8_t *data, uint32_t dataLength) { VERIFY_NON_NULL(env, TAG, "env is null"); VERIFY_NON_NULL(address, TAG, "address is null"); VERIFY_NON_NULL(data, TAG, "data is null"); if (!CAEDRNativeIsEnableBTAdapter(env)) { OIC_LOG(INFO, TAG, "BT adapter is not enabled"); return CA_ADAPTER_NOT_ENABLED; } if (STATE_DISCONNECTED == CAEDRIsConnectedDevice(address)) { // connect before send data OIC_LOG_V(DEBUG, TAG, "try to connect with [%s] before sending data", address); CAResult_t res = CAEDRNativeConnect(env, address); if (CA_STATUS_OK != res) { return res; } } if (STATE_CONNECTED == CAEDRIsConnectedDevice(address)) { if (!((*env)->ExceptionCheck(env))) { jclass jni_cid_BTsocket = (*env)->FindClass(env, CLASSPATH_BT_SOCKET); if (!jni_cid_BTsocket) { OIC_LOG(ERROR, TAG, "jni_cid_BTsocket is null"); return CA_STATUS_FAILED; } jmethodID jni_mid_getOutputStream = (*env)->GetMethodID(env, jni_cid_BTsocket, "getOutputStream", METHODID_OUTPUTNONPARAM); if (!jni_mid_getOutputStream) { OIC_LOG(ERROR, TAG, "jni_mid_getOutputStream is null"); (*env)->DeleteLocalRef(env, jni_cid_BTsocket); return CA_STATUS_FAILED; } OIC_LOG(DEBUG, TAG, "Get MethodID for i/o stream"); jobject jni_obj_socket = CAEDRNativeGetDeviceSocketBaseAddr(env, address); if (!jni_obj_socket) { OIC_LOG(ERROR, TAG, "jni_socket is not available"); (*env)->DeleteLocalRef(env, jni_cid_BTsocket); return CA_STATUS_FAILED; } jobject jni_obj_outputStream = (*env)->CallObjectMethod(env, jni_obj_socket, jni_mid_getOutputStream); if (!jni_obj_outputStream) { OIC_LOG(ERROR, TAG, "jni_obj_outputStream is null"); (*env)->DeleteLocalRef(env, jni_cid_BTsocket); return CA_STATUS_FAILED; } OIC_LOG(DEBUG, TAG, "ready outputStream.."); jclass jni_cid_OutputStream = (*env)->FindClass(env, CLASSPATH_OUTPUT); if (!jni_cid_OutputStream) { OIC_LOG(ERROR, TAG, "jni_cid_OutputStream is null"); (*env)->DeleteLocalRef(env, jni_cid_BTsocket); (*env)->DeleteLocalRef(env, jni_obj_outputStream); return CA_STATUS_FAILED; } jmethodID jni_mid_write = (*env)->GetMethodID(env, jni_cid_OutputStream, "write", "([BII)V"); if (!jni_mid_write) { OIC_LOG(ERROR, TAG, "jni_mid_write is null"); (*env)->DeleteLocalRef(env, jni_cid_BTsocket); (*env)->DeleteLocalRef(env, jni_obj_outputStream); (*env)->DeleteLocalRef(env, jni_cid_OutputStream); return CA_STATUS_FAILED; } jbyteArray jbuf = (*env)->NewByteArray(env, dataLength); (*env)->SetByteArrayRegion(env, jbuf, 0, dataLength, (jbyte*) data); (*env)->CallVoidMethod(env, jni_obj_outputStream, jni_mid_write, jbuf, (jint) 0, (jint) dataLength); (*env)->DeleteLocalRef(env, jni_cid_BTsocket); (*env)->DeleteLocalRef(env, jni_obj_outputStream); (*env)->DeleteLocalRef(env, jni_cid_OutputStream); (*env)->DeleteLocalRef(env, jbuf); if ((*env)->ExceptionCheck(env)) { OIC_LOG(ERROR, TAG, "Failed to write data in outputStram"); (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); return CA_STATUS_FAILED; } OIC_LOG_V(INFO, TAG, "EDR sendTo is successful: %u bytes, to %s", dataLength, address); } else { (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); OIC_LOG(ERROR, TAG, "error!!"); return CA_STATUS_FAILED; } } else { OIC_LOG(DEBUG, TAG, "BT connection is not completed!!"); } return CA_STATUS_OK; }
/** * EDR Method */ CAResult_t CAEDRNativeSendData(JNIEnv *env, const char *address, const char *data, uint32_t dataLength, uint32_t id) { OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btSendData logic start : %s, %d", data, dataLength); if (!CAEDRNativeIsEnableBTAdapter(env)) { OIC_LOG(ERROR, TAG, "BT adpater is not enable"); return CA_STATUS_INVALID_PARAM; } if (STATE_DISCONNECTED == CAEDRIsConnectedDevice(address)) { // connect before send data OIC_LOG(DEBUG, TAG, "[EDR][Native] connect before send data"); if (NULL == address) { OIC_LOG(ERROR, TAG, "[EDR][Native] remote address is empty"); return CA_STATUS_INVALID_PARAM; } else { CAResult_t res = CAEDRNativeConnect(env, address, id); if (CA_STATUS_OK != res) { return res; } } } if (STATE_CONNECTED == CAEDRIsConnectedDevice(address)) { if (!((*env)->ExceptionCheck(env))) { jclass jni_cid_BTsocket = (*env)->FindClass(env, CLASSPATH_BT_SOCKET); if (!jni_cid_BTsocket) { OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_cid_BTsocket is null"); return CA_STATUS_FAILED; } jmethodID jni_mid_getOutputStream = (*env)->GetMethodID(env, jni_cid_BTsocket, "getOutputStream", METHODID_OUTPUTNONPARAM); if (!jni_mid_getOutputStream) { OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_mid_getOutputStream is null"); return CA_STATUS_FAILED; } OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: Get MethodID for i/o stream"); jobject jni_obj_socket = CAEDRNativeGetDeviceSocketBaseAddr(env, address); if (!jni_obj_socket) { OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_socket is not available"); return CA_STATUS_FAILED; } jobject jni_obj_outputStream = (*env)->CallObjectMethod(env, jni_obj_socket, jni_mid_getOutputStream); if (!jni_obj_outputStream) { OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_obj_outputStream is null"); return CA_STATUS_FAILED; } OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: ready outputStream.."); jclass jni_cid_OutputStream = (*env)->FindClass(env, CLASSPATH_OUTPUT); if (!jni_cid_OutputStream) { OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_cid_OutputStream is null"); return CA_STATUS_FAILED; } jmethodID jni_mid_write = (*env)->GetMethodID(env, jni_cid_OutputStream, "write", "([BII)V"); if (!jni_mid_write) { OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: jni_mid_write is null"); return CA_STATUS_FAILED; } jbyteArray jbuf; jbuf = (*env)->NewByteArray(env, dataLength); (*env)->SetByteArrayRegion(env, jbuf, 0, dataLength, (jbyte*) data); (*env)->CallVoidMethod(env, jni_obj_outputStream, jni_mid_write, jbuf, (jint) 0, (jint) dataLength); if ((*env)->ExceptionCheck(env)) { OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: Write Error!!!"); (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); return CA_STATUS_FAILED; } OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: Write Success"); } else { (*env)->ExceptionDescribe(env); (*env)->ExceptionClear(env); OIC_LOG(ERROR, TAG, "[EDR][Native] btSendData: error!!"); return CA_STATUS_FAILED; } } else { OIC_LOG(DEBUG, TAG, "[EDR][Native] btSendData: BT connection is not completed!!"); } return CA_STATUS_OK; }