1 /******************************************************************
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
25 #include "caedrinterface.h"
26 #include "caedrutils.h"
27 #include "caedrserver.h"
29 #include "oic_malloc.h"
30 #include "cathreadpool.h" /* for thread pool */
32 #include "uarraylist.h"
33 #include "caadapterutils.h"
36 #define TAG PCF("CA_EDR_SERVER")
38 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
39 static const char METHODID_STRINGNONPARAM[] = "()Ljava/lang/String;";
40 static const char CLASSPATH_BT_ADPATER[] = "android/bluetooth/BluetoothAdapter";
41 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
43 static const uint32_t MAX_PDU_BUFFER = 1024;
45 static u_arraylist_t *g_deviceStateList = NULL;
46 static u_arraylist_t *g_deviceObjectList = NULL;
48 static ca_thread_pool_t g_threadPoolHandle = NULL;
52 static jbyteArray g_sendBuffer;
55 * @var g_mMutexSocketListManager
56 * @brief Mutex to synchronize socket list update
58 static ca_mutex g_mutexSocketListManager;
60 // server socket instance
61 static jobject g_serverSocketObject = NULL;
64 * @var g_mutexUnicastServer
65 * @brief Mutex to synchronize unicast server
67 static ca_mutex g_mutexUnicastServer = NULL;
71 * @brief Flag to control the Receive Unicast Data Thread
73 static bool g_stopUnicast = false;
76 * @var g_mutexMulticastServer
77 * @brief Mutex to synchronize secure multicast server
79 static ca_mutex g_mutexMulticastServer = NULL;
82 * @var g_stopMulticast
83 * @brief Flag to control the Receive Multicast Data Thread
85 static bool g_stopMulticast = false;
89 * @brief Flag to control the Accept Thread
91 static bool g_stopAccept = false;
93 typedef struct send_data {
100 @brief Thread context information for unicast, multicast and secured unicast server
105 CAAdapterServerType_t type;
106 } CAAdapterReceiveThreadContext_t;
111 } CAAdapterAcceptThreadContext_t;
116 * @var g_EDRPacketReceivedCallback
117 * @brief Maintains the callback to be notified when data received from remote Bluetooth device
119 static CAEDRDataReceivedCallback g_EDRPacketReceivedCallback = NULL;
121 static void CAReceiveHandler(void *data)
123 OIC_LOG(DEBUG, TAG, "start CAReceiveHandler..");
124 OIC_LOG(DEBUG, TAG, "IN");
126 VERIFY_NON_NULL_VOID(data, TAG, "Invalid thread context");
128 jboolean isAttached = JNI_FALSE;
130 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
133 OIC_LOG(DEBUG, TAG, "CAReceiveHandler - Could not get JNIEnv pointer");
134 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
138 OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
141 isAttached = JNI_TRUE;
144 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)data;
146 while (true != *(ctx->stopFlag))
150 // if new socket object is added in socket list after below logic is ran.
151 // new socket will be started to read after next while loop
152 uint32_t length = CAEDRServerGetSocketListLength();
155 OIC_LOG(DEBUG, TAG, "socket list is empty");
158 for (idx = 0; idx < length; idx++)
160 OIC_LOG(DEBUG, TAG, "start CAEDRNativeReadData");
161 CAEDRNativeReadData(env, idx, ctx->type);
167 (*g_jvm)->DetachCurrentThread(g_jvm);
172 OIC_LOG(DEBUG, TAG, "OUT");
175 static void CAAcceptHandler(void *data)
179 OIC_LOG(ERROR, TAG, "[EDR] CAAcceptHandler: data is null");
182 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread start");
184 jboolean isAttached = JNI_FALSE;
186 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
189 OIC_LOG(DEBUG, TAG, "CAAcceptHandler - Could not get JNIEnv pointer");
190 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
194 OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
197 isAttached = JNI_TRUE;
200 jobject jni_obj_BTSeverSocket = CAEDRNativeListen(env);
201 if (!jni_obj_BTSeverSocket)
203 OIC_LOG(ERROR, TAG, "[EDR] AcceptThread: jni_obj_BTSeverSocket is null");
206 (*g_jvm)->DetachCurrentThread(g_jvm);
211 CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *)data;
213 while (true != *(ctx->stopFlag))
215 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread running");
216 CAEDRNativeAccept(env, jni_obj_BTSeverSocket);
220 (*g_jvm)->DetachCurrentThread(g_jvm);
225 OIC_LOG(DEBUG, TAG, "[EDR] AcceptThread finish");
231 // adapter common method
233 CAResult_t CAEDRServerStart(const char *serviceUUID, int32_t *serverFD, ca_thread_pool_t handle)
235 OIC_LOG(DEBUG, TAG, "IN");
236 CAEDRServerInitialize(handle);
238 CAEDRStartUnicastServer(NULL, false);
239 OIC_LOG(DEBUG, TAG, "OUT");
243 CAResult_t CAEDRServerStop(int serverFD)
245 OIC_LOG(DEBUG, TAG, "IN");
246 CAEDRStopUnicastServer(-1);
247 CAEDRStopMulticastServer(-1);
250 g_stopMulticast = true;
251 g_stopUnicast = true;
253 OIC_LOG(DEBUG, TAG, "OUT");
257 void CAEDRSetPacketReceivedCallback(CAEDRDataReceivedCallback packetReceivedCallback)
259 g_EDRPacketReceivedCallback = packetReceivedCallback;
265 static void CAEDRServerDestroyMutex()
267 OIC_LOG(DEBUG, TAG, "IN");
269 if (g_mutexUnicastServer)
271 ca_mutex_free(g_mutexUnicastServer);
272 g_mutexUnicastServer = NULL;
275 if (g_mutexMulticastServer)
277 ca_mutex_free(g_mutexMulticastServer);
278 g_mutexMulticastServer = NULL;
281 if(g_mutexSocketListManager)
283 ca_mutex_free(g_mutexSocketListManager);
284 g_mutexSocketListManager = NULL;
287 OIC_LOG(DEBUG, TAG, "OUT");
294 static CAResult_t CAEDRServerCreateMutex()
296 OIC_LOG(DEBUG, TAG, "IN");
298 g_mutexUnicastServer = ca_mutex_new();
299 if (!g_mutexUnicastServer)
301 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
302 return CA_STATUS_FAILED;
305 g_mutexMulticastServer = ca_mutex_new();
306 if (!g_mutexMulticastServer)
308 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
310 CAEDRServerDestroyMutex();
311 return CA_STATUS_FAILED;
314 g_mutexSocketListManager = ca_mutex_new();
315 if (!g_mutexSocketListManager)
317 OIC_LOG(ERROR, TAG, "Failed to created mutex!");
319 CAEDRServerDestroyMutex();
320 return CA_STATUS_FAILED;
323 OIC_LOG(DEBUG, TAG, "OUT");
327 void CAEDRServerJniInit(JNIEnv *env, JavaVM* jvm)
329 OIC_LOG(DEBUG, TAG, "CAEDRServerJniInit");
333 void CAEDRServerInitialize(ca_thread_pool_t handle)
335 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize");
337 g_threadPoolHandle = handle;
340 CAEDRServerCreateMutex();
342 jboolean isAttached = JNI_FALSE;
344 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
347 OIC_LOG(DEBUG, TAG, "CAEDRServerInitialize - Could not get JNIEnv pointer");
348 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
352 OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
355 isAttached = JNI_TRUE;
358 jstring jni_address = CAEDRNativeGetLocalDeviceAddress(env);
361 const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
362 OIC_LOG_V(DEBUG, TAG, "My BT Address is %s", localAddress);
363 (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
366 CAEDRServerNativeCreateDeviceStateList();
367 CAEDRServerNativeCreateDeviceSocketList();
370 (*g_jvm)->DetachCurrentThread(g_jvm);
372 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
373 OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
376 OIC_LOG(ERROR, TAG, "Out of memory!");
380 ctx->stopFlag = &g_stopAccept;
381 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *)ctx))
383 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
384 OICFree((void *)ctx);
388 OIC_LOG(DEBUG, TAG, "OUT");
391 void CAEDRServerTerminate()
393 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate");
399 jboolean isAttached = JNI_FALSE;
401 jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
404 OIC_LOG(DEBUG, TAG, "CAEDRServerTerminate - Could not get JNIEnv pointer");
405 res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
409 OIC_LOG(DEBUG, TAG, "AttachCurrentThread failed");
412 isAttached = JNI_TRUE;
417 (*g_jvm)->DetachCurrentThread(g_jvm);
420 CAEDRServerNativeRemoveAllDeviceState();
421 CAEDRServerNativeRemoveAllDeviceSocket(env);
424 CAEDRServerDestroyMutex();
427 int32_t CAEDRStartUnicastServer(const char* address, bool isSecured)
429 OIC_LOG_V(DEBUG, TAG, "CAEDRStartUnicastServer(%s)", address);
431 ca_mutex_lock(g_mutexUnicastServer);
434 * The task to listen for data from unicast is added to the thread pool.
435 * This is a blocking call is made where we try to receive some data..
436 * We will keep waiting until some data is received.
437 * This task will be terminated when thread pool is freed on stopping the adapters.
438 * Thread context will be freed by thread on exit.
440 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
441 OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
444 OIC_LOG(ERROR, TAG, "Out of memory!");
445 ca_mutex_unlock(g_mutexUnicastServer);
446 return CA_MEMORY_ALLOC_FAILED;
449 ctx->stopFlag = &g_stopUnicast;
450 ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
451 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *)ctx))
453 OIC_LOG(ERROR, TAG, "Failed to create read thread!");
454 ca_mutex_unlock(g_mutexUnicastServer);
455 OICFree((void *)ctx);
456 return CA_STATUS_FAILED;
458 ca_mutex_unlock(g_mutexUnicastServer);
460 OIC_LOG(DEBUG, TAG, "OUT");
464 int32_t CAEDRStartMulticastServer(bool isSecured)
466 OIC_LOG(DEBUG, TAG, "CAEDRStartMulticastServer");
468 ca_mutex_lock(g_mutexMulticastServer);
471 * The task to listen to data from multicast socket is added to the thread pool.
472 * This is a blocking call is made where we try to receive some data.
473 * We will keep waiting until some data is received.
474 * This task will be terminated when thread pool is freed on stopping the adapters.
475 * Thread context will be freed by thread on exit.
477 CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
478 OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
481 OIC_LOG(ERROR, TAG, "Out of memory!");
482 ca_mutex_unlock(g_mutexMulticastServer);
484 return CA_MEMORY_ALLOC_FAILED;
487 ctx->stopFlag = &g_stopMulticast;
488 ctx->type = CA_MULTICAST_SERVER;
490 g_stopMulticast = false;
491 if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *)ctx))
493 OIC_LOG(ERROR, TAG, "thread_pool_add_task failed!");
495 g_stopMulticast = true;
496 ca_mutex_unlock(g_mutexMulticastServer);
497 OICFree((void *)ctx);
499 return CA_STATUS_FAILED;
501 ca_mutex_unlock(g_mutexMulticastServer);
503 OIC_LOG(DEBUG, TAG, "OUT");
507 int32_t CAEDRStopUnicastServer(int32_t serverID)
509 OIC_LOG(DEBUG, TAG, "CAEDRStopUnicastServer");
511 ca_mutex_lock(g_mutexUnicastServer);
512 g_stopUnicast = true;
513 ca_mutex_unlock(g_mutexUnicastServer);
518 int32_t CAEDRStopMulticastServer(int32_t serverID)
520 OIC_LOG(DEBUG, TAG, "CAEDRStopMulticastServer");
522 ca_mutex_lock(g_mutexMulticastServer);
523 g_stopMulticast = true;
524 ca_mutex_unlock(g_mutexMulticastServer);
526 OIC_LOG(INFO, TAG, "Multicast server stopped");
531 CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t id, CAAdapterServerType_t type)
533 if(!((*env)->ExceptionCheck(env)))
535 // check whether this socket object is connected or not.
536 jobject jni_obj_socket = CAEDRServerNativeGetDeviceSocket(id);
539 return CA_STATUS_INVALID_PARAM;
542 jstring jni_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_socket);
543 const char* address = (*env)->GetStringUTFChars(env, jni_str_address, NULL);
544 if(STATE_DISCONNECTED == CAEDRServerIsConnectedDevice(address))
546 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: it is not connected yet..");
547 return CA_STATUS_FAILED;
550 // start to read through InputStream
551 jclass jni_cid_BTsocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
552 jmethodID jni_mid_getInputStream = (*env)->GetMethodID(env,
553 jni_cid_BTsocket, "getInputStream", "()Ljava/io/InputStream;");
554 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: get InputStream..%d, %s", id, address);
558 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore..");
559 return CA_STATUS_FAILED;
562 jobject jni_obj_inputStream = (*env)->CallObjectMethod(env,
563 jni_obj_socket, jni_mid_getInputStream);
564 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: ready inputStream..");
566 jclass jni_cid_InputStream = (*env)->FindClass(env, "java/io/InputStream");
567 jmethodID jni_mid_read = (*env)->GetMethodID(env, jni_cid_InputStream, "read", "([BII)I");
569 jbyteArray jbuf = (*env)->NewByteArray(env, MAX_PDU_BUFFER);
574 OIC_LOG(ERROR, TAG, "[EDR][Native] jni_obj_socket is not available anymore...");
575 return CA_STATUS_FAILED;
578 while ((nread = (*env)->CallIntMethod(env, jni_obj_inputStream,
579 jni_mid_read, jbuf, (jint)0, MAX_PDU_BUFFER)) != -1)
581 if((*env)->ExceptionCheck(env))
583 OIC_LOG(ERROR, TAG, "[EDR][Native] btReadData: read Error!!!");
584 (*env)->ExceptionDescribe(env);
585 (*env)->ExceptionClear(env);
586 return CA_STATUS_FAILED;
588 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: reading");
589 jbyte* buf = (*env)->GetByteArrayElements(env, jbuf, NULL);
590 jint length = strlen((char*)buf);
591 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btReadData: read %s", buf);
594 return CA_STATUS_FAILED;
599 case CA_UNICAST_SERVER:
600 case CA_MULTICAST_SERVER:
601 // Notify data to upper layer
602 if (g_EDRPacketReceivedCallback)
604 uint32_t sentLength = 0;
605 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] data will be sent \
606 to callback routine: %s, %d", buf, length);
607 g_EDRPacketReceivedCallback(address, (void*)buf, length, &sentLength);
612 // Should never occur
613 OIC_LOG(DEBUG, TAG, "Invalid server type");
614 return CA_STATUS_FAILED;
616 (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
618 // close socket after data was sent
619 CAEDRNativeServerSocketClose(env, address, id);
625 (*env)->ExceptionDescribe(env);
626 (*env)->ExceptionClear(env);
627 OIC_LOG(DEBUG, TAG, "[EDR][Native] btReadData: env error!!");
628 return CA_STATUS_FAILED;
634 jobject CAEDRNativeListen(JNIEnv *env)
636 OIC_LOG(DEBUG, TAG, "[EDR][Native] btListen");
638 jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADPATER);
639 if(!jni_cid_BTAdapter)
641 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
646 jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env,
647 jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
648 if(!jni_cid_BTAdapter)
650 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_cid_BTAdapter is null");
654 jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env,
655 jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
656 if(!jni_obj_BTAdapter)
658 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTAdapter is null");
662 // get listen method ID
663 jmethodID jni_mid_listen = (*env)->GetMethodID(env, jni_cid_BTAdapter,
664 "listenUsingInsecureRfcommWithServiceRecord",
665 "(Ljava/lang/String;Ljava/util/UUID;)Landroid/bluetooth/BluetoothServerSocket;");
668 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
671 // listenUsingInsecureRfcommWithServiceRecord / listenUsingRfcommWithServiceRecord
673 jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
676 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_listen is null");
680 jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid,
681 "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
682 if(!jni_mid_fromString)
684 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_mid_fromString is null");
688 jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid,
689 jni_mid_fromString, OIC_EDR_SERVICE_ID);
692 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_uuid is null");
697 jstring jni_name = (*env)->NewStringUTF(env, "BluetoothTestSecure");
700 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_name is null");
703 jobject jni_obj_BTSeverSocket = (*env)->CallObjectMethod(env,
704 jni_obj_BTAdapter, jni_mid_listen, jni_name, jni_obj_uuid);
705 if(!jni_obj_BTSeverSocket)
707 OIC_LOG(ERROR, TAG, "[EDR][Native] btListen: jni_obj_BTSeverSocket is null");
711 g_serverSocketObject = (*env)->NewGlobalRef(env, jni_obj_BTSeverSocket);
713 return jni_obj_BTSeverSocket;
716 void CAEDRNativeAccept(JNIEnv *env, jobject severSocketObject)
718 if(severSocketObject != NULL)
720 jclass jni_cid_BTServerSocket = (*env)->FindClass(env,
721 "android/bluetooth/BluetoothServerSocket");
722 if(!jni_cid_BTServerSocket)
724 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_cid_BTServerSocket is null");
728 jmethodID jni_mid_accept = (*env)->GetMethodID(env,
729 jni_cid_BTServerSocket, "accept",
730 "(I)Landroid/bluetooth/BluetoothSocket;");
733 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_mid_accept is null");
737 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: initiating accept...");
739 jobject jni_obj_BTSocket = NULL;
740 jni_obj_BTSocket = (*env)->CallObjectMethod(env, severSocketObject, jni_mid_accept, 1000);
741 if(!jni_obj_BTSocket)
743 OIC_LOG(ERROR, TAG, "[EDR][Native] btAccept: jni_obj_BTSocket is null");
747 // get remote address
748 jstring j_str_address = CAEDRNativeGetAddressFromDeviceSocket(env, jni_obj_BTSocket);
750 const char* address = (*env)->GetStringUTFChars(env, j_str_address, NULL);
751 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] btAccept: address is %s", address);
753 // set socket to list
754 jobject jni_socket = (*env)->NewGlobalRef(env, jni_obj_BTSocket);
755 CAEDRServerNativeAddDeviceSocketToList(env, jni_socket);
757 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: Accepted!!");
760 CAEDRServerUpdateDeviceState(STATE_CONNECTED, address);
761 (*env)->ReleaseStringUTFChars(env, j_str_address, address);
765 OIC_LOG(DEBUG, TAG, "[EDR][Native] btAccept: severSocket is close previously");
769 void CAEDRNativeServerSocketClose(JNIEnv *env, const char *address, uint32_t id)
772 jclass jni_cid_BTSocket = (*env)->FindClass(env, "android/bluetooth/BluetoothSocket");
773 if(!jni_cid_BTSocket)
775 OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_cid_BTSocket is null");
779 jmethodID jni_mid_close = (*env)->GetMethodID(env, jni_cid_BTSocket, "close", "()V");
782 OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_mid_close is null");
786 jobject jni_obj_socket = CAEDRServerNativeGetDeviceSocket(id);
789 OIC_LOG(ERROR, TAG, "[EDR][Native] close: jni_obj_socket is not available");
793 (*env)->CallVoidMethod(env, jni_obj_socket, jni_mid_close);
795 if((*env)->ExceptionCheck(env))
797 OIC_LOG(DEBUG, TAG, "[EDR][Native] close: close is Failed!!!");
798 (*env)->ExceptionDescribe(env);
799 (*env)->ExceptionClear(env);
803 // remove socket to list
804 CAEDRServerNativeRemoveDeviceSocket(env, jni_obj_socket);
807 CAEDRServerUpdateDeviceState(STATE_DISCONNECTED, address);
809 OIC_LOG(DEBUG, TAG, "[EDR][Native] close: disconnected");
815 void CAEDRServerNativeCreateDeviceStateList()
817 OIC_LOG(DEBUG, TAG, "[EDR][Native] CAEDRNativeCreateDeviceStateList");
819 // create new object array
820 if (g_deviceStateList == NULL)
822 OIC_LOG(DEBUG, TAG, "Create device list");
824 g_deviceStateList = u_arraylist_create();
825 if (g_deviceStateList == NULL)
827 OIC_LOG(DEBUG, TAG, "Create device list is null");
832 void CAEDRServerUpdateDeviceState(uint32_t state, const char *address)
834 state_t *newstate = (state_t*) OICCalloc(1, sizeof(state_t));
836 OIC_LOG(ERROR, TAG, "[BLE][Native] newstate is null");
839 strcpy(newstate->address, address);
840 newstate->state = state;
842 CAEDRServerNativeAddDeviceStateToList(newstate);
845 void CAEDRServerNativeAddDeviceStateToList(state_t *state)
849 OIC_LOG(ERROR, TAG, "[EDR][Native] device is null");
853 if(!g_deviceStateList)
855 OIC_LOG(ERROR, TAG, "[EDR][Native] gdevice_list is null");
859 if(!CAEDRServerNativeIsDeviceInList(state->address)) {
860 CAEDRServerNativeRemoveDevice(state->address); // delete previous state for update new state
861 u_arraylist_add(g_deviceStateList, state); // update new state
862 OIC_LOG(DEBUG, TAG, "Set State to Connected State List");
866 jboolean CAEDRServerNativeIsDeviceInList(const char* remoteAddress){
868 if (!remoteAddress) {
869 OIC_LOG(ERROR, TAG, "[BLE][Native] remoteAddress is null");
873 for (index = 0; index < u_arraylist_length(g_deviceStateList); index++)
875 state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index);
878 OIC_LOG(ERROR, TAG, "[EDR][Native] state_t object is null");
882 if(!strcmp(remoteAddress, state->address))
884 OIC_LOG(DEBUG, TAG, "the device is already set");
893 OIC_LOG(DEBUG, TAG, "there are no the device in list.");
897 void CAEDRServerNativeRemoveAllDeviceState()
899 OIC_LOG(DEBUG, TAG, "CAEDRNativeRemoveAllDevices");
901 if(!g_deviceStateList)
903 OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null");
908 for (index = 0; index < u_arraylist_length(g_deviceStateList); index++)
910 state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index);
913 OIC_LOG(DEBUG, TAG, "[EDR][Native] jarrayObj is null");
919 OICFree(g_deviceStateList);
920 g_deviceStateList = NULL;
924 void CAEDRServerNativeRemoveDevice(const char *remoteAddress)
926 OIC_LOG(DEBUG, TAG, "CAEDRNativeRemoveDevice");
928 if(!g_deviceStateList)
930 OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null");
933 if (!remoteAddress) {
934 OIC_LOG(ERROR, TAG, "[BLE][Native] remoteAddress is null");
939 for (index = 0; index < u_arraylist_length(g_deviceStateList); index++)
941 state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index);
944 OIC_LOG(DEBUG, TAG, "[EDR][Native] state_t object is null");
948 if(!strcmp(state->address, remoteAddress))
950 OIC_LOG_V(DEBUG, TAG, "[EDR][Native] remove object : %s", remoteAddress);
953 CAEDRServerReorderingDeviceList(index);
957 OIC_LOG(DEBUG, TAG, "[EDR][Native] there are no target object");
961 jboolean CAEDRServerIsConnectedDevice(const char *remoteAddress)
963 OIC_LOG(DEBUG, TAG, "CAEDRServerIsConnectedDevice");
965 if(!g_deviceStateList)
967 OIC_LOG(ERROR, TAG, "[EDR][Native] gdeviceStateList is null");
970 if (!remoteAddress) {
971 OIC_LOG(ERROR, TAG, "[BLE][Native] remoteAddress is null");
976 for (index = 0; index < u_arraylist_length(g_deviceStateList); index++)
978 state_t* state = (state_t*) u_arraylist_get(g_deviceStateList, index);
981 OIC_LOG(DEBUG, TAG, "[EDR][Native] state_t object is null");
985 if(!strcmp(state->address, remoteAddress))
987 OIC_LOG(DEBUG, TAG, "[EDR][Native] check whether it is connected or not");
992 OIC_LOG(DEBUG, TAG, "[EDR][Native] there are no target object");
996 void CAEDRServerReorderingDeviceList(uint32_t index)
998 if (index >= g_deviceStateList->length)
1003 if (index < g_deviceStateList->length - 1)
1005 memmove(&g_deviceStateList->data[index], &g_deviceStateList->data[index + 1],
1006 (g_deviceStateList->length - index - 1) * sizeof(void *));
1009 g_deviceStateList->size--;
1010 g_deviceStateList->length--;
1014 * Device Socket Object List
1016 void CAEDRServerNativeCreateDeviceSocketList()
1018 OIC_LOG(DEBUG, TAG, "[BLE][Native] CAEDRServerNativeCreateDeviceSocketList");
1020 // create new object array
1021 if (g_deviceObjectList == NULL)
1023 OIC_LOG(DEBUG, TAG, "Create Device object list");
1025 g_deviceObjectList = u_arraylist_create();
1026 if (g_deviceObjectList == NULL)
1028 OIC_LOG(DEBUG, TAG, "Create Device object list is null");
1033 void CAEDRServerNativeAddDeviceSocketToList(JNIEnv *env, jobject deviceSocket)
1035 OIC_LOG(DEBUG, TAG, "[BLE][Native] CAEDRServerNativeAddDeviceSocketToList");
1039 OIC_LOG(ERROR, TAG, "[BLE][Native] Device is null");
1043 if(!g_deviceObjectList)
1045 OIC_LOG(ERROR, TAG, "[BLE][Native] gdeviceObjectList is null");
1049 jstring jni_remoteAddress = CAEDRNativeGetAddressFromDeviceSocket(env, deviceSocket);
1050 if(!jni_remoteAddress)
1052 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_remoteAddress is null");
1056 ca_mutex_lock(g_mutexSocketListManager);
1058 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1060 if(!CAEDRServerNativeIsDeviceSocketInList(env, remoteAddress))
1062 jobject gDeviceSocket = (*env)->NewGlobalRef(env, deviceSocket);
1063 u_arraylist_add(g_deviceObjectList, gDeviceSocket);
1064 OIC_LOG(DEBUG, TAG, "Set Object to Array as Element");
1067 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
1068 ca_mutex_unlock(g_mutexSocketListManager);
1071 jboolean CAEDRServerNativeIsDeviceSocketInList(JNIEnv *env, const char* remoteAddress)
1073 OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeIsDeviceObjInList");
1076 for (index = 0; index < u_arraylist_length(g_deviceObjectList); index++)
1079 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index);
1082 OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
1086 jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj);
1089 OIC_LOG(ERROR, TAG, "[BLE][Native] jni_setAddress is null");
1093 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1094 if (!setAddress || !remoteAddress) {
1095 OIC_LOG(ERROR, TAG, "[BLE][Native] setAddress or remoteAddress is null");
1098 if(!strcmp(remoteAddress, setAddress))
1100 OIC_LOG(DEBUG, TAG, "the device is already set");
1109 OIC_LOG(DEBUG, TAG, "there are no the Device obejct in list. we can add");
1113 void CAEDRServerNativeRemoveAllDeviceSocket(JNIEnv *env)
1115 OIC_LOG(DEBUG, TAG, "CANativeRemoveAllDeviceObjsList");
1117 if(!g_deviceObjectList)
1119 OIC_LOG(ERROR, TAG, "[BLE][Native] gdeviceObjectList is null");
1124 for (index = 0; index < u_arraylist_length(g_deviceObjectList); index++)
1126 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index);
1129 OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is null");
1132 (*env)->DeleteGlobalRef(env, jarrayObj);
1135 OICFree(g_deviceObjectList);
1136 g_deviceObjectList = NULL;
1140 void CAEDRServerNativeRemoveDeviceSocket(JNIEnv *env, jobject deviceSocket)
1142 OIC_LOG(DEBUG, TAG, "CAEDRServerNativeRemoveDeviceSocket");
1144 if(!g_deviceObjectList)
1146 OIC_LOG(ERROR, TAG, "[BLE][Native] gdeviceObjectList is null");
1150 ca_mutex_lock(g_mutexSocketListManager);
1153 for (index = 0; index < u_arraylist_length(g_deviceObjectList); index++)
1155 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, index);
1158 OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
1162 jstring jni_setAddress = CAEDRNativeGetAddressFromDeviceSocket(env, jarrayObj);
1165 OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
1168 const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
1169 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
1171 jstring jni_remoteAddress = CAEDRNativeGetAddressFromDeviceSocket(env, deviceSocket);
1172 if(!jni_remoteAddress)
1174 OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_remoteAddress is null");
1177 const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
1178 (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
1180 if (!setAddress || !remoteAddress) {
1181 OIC_LOG(DEBUG, TAG, "[BLE][Native] setAddress or remoteAddress is null");
1184 if(!strcmp(setAddress, remoteAddress))
1186 OIC_LOG_V(DEBUG, TAG, "[BLE][Native] remove object : %s", remoteAddress);
1187 (*env)->DeleteGlobalRef(env, jarrayObj);
1189 CAEDRServerReorderingDeviceSocketList(index);
1193 ca_mutex_unlock(g_mutexSocketListManager);
1195 OIC_LOG(DEBUG, TAG, "[BLE][Native] there are no target object");
1199 jobject CAEDRServerNativeGetDeviceSocket(uint32_t idx)
1201 OIC_LOG(DEBUG, TAG, "CAEDRServerNativeGetDeviceSocket");
1205 OIC_LOG(DEBUG, TAG, "[BLE][Native] index is not available");
1209 if(!g_deviceObjectList)
1211 OIC_LOG(ERROR, TAG, "[BLE][Native] gdeviceObjectList is null");
1215 jobject jarrayObj = (jobject) u_arraylist_get(g_deviceObjectList, idx);
1218 OIC_LOG(ERROR, TAG, "[BLE][Native] jarrayObj is not available");
1224 uint32_t CAEDRServerGetSocketListLength()
1226 if(!g_deviceObjectList)
1228 OIC_LOG(ERROR, TAG, "[BLE][Native] gdeviceObjectList is null");
1232 uint32_t length = u_arraylist_length(g_deviceObjectList);
1237 void CAEDRServerReorderingDeviceSocketList(uint32_t index)
1239 if (index >= g_deviceObjectList->length)
1244 if (index < g_deviceObjectList->length - 1)
1246 memmove(&g_deviceObjectList->data[index], &g_deviceObjectList->data[index + 1],
1247 (g_deviceObjectList->length - index - 1) * sizeof(void *));
1250 g_deviceObjectList->size--;
1251 g_deviceObjectList->length--;
1254 void CAEDRServerSetPacketReceivedCallback
1255 (CAEDRDataReceivedCallback packetReceivedCallback)
1257 g_EDRPacketReceivedCallback = packetReceivedCallback;