static unpacker* get_unpacker(JNIEnv *env, jobject pObj, bool noCreate=false) { unpacker* uPtr; uPtr = (unpacker*)jlong2ptr(env->GetLongField(pObj, unpackerPtrFID)); //fprintf(stderr, "get_unpacker(%p) uPtr=%p\n", pObj, uPtr); if (uPtr == null) { if (noCreate) return null; uPtr = new unpacker(); if (uPtr == null) { THROW_IOE(ERROR_ENOMEM); return null; } //fprintf(stderr, "get_unpacker(%p) uPtr=%p initializing\n", pObj, uPtr); uPtr->init(read_input_via_jni); uPtr->jniobj = (void*) env->NewGlobalRef(pObj); env->SetLongField(pObj, unpackerPtrFID, ptr2jlong(uPtr)); } uPtr->jnienv = env; // keep refreshing this in case of MT access return uPtr; }
JNIEXPORT jint JNICALL Java_com_intel_bluetooth_BluetoothStackBlueZ_runSearchServicesImpl (JNIEnv *env, jobject peer, jobject searchServicesThread, jlong localDeviceBTAddress, jobjectArray uuidValues, jlong remoteDeviceAddressLong) { // Prepare serviceDiscoveredCallback jclass peerClass = (*env)->GetObjectClass(env, peer); if (peerClass == NULL) { throwRuntimeException(env, "Fail to get Object Class"); return SERVICE_SEARCH_ERROR; } jmethodID serviceDiscoveredCallback = getGetMethodID(env, peerClass, "serviceDiscoveredCallback", "(Lcom/intel/bluetooth/SearchServicesThread;JJ)Z"); if (serviceDiscoveredCallback == NULL) { return SERVICE_SEARCH_ERROR; } sdp_list_t *uuidList = NULL; sdp_list_t *rsp_list = NULL; sdp_session_t *session = NULL; jint rc = SERVICE_SEARCH_ERROR; const uint16_t max_rec_num = 256; int serviceCount = 0; int error; // convert uuid set from java array to bluez sdp_list_t jsize uuidSetSize = (*env)->GetArrayLength(env, uuidValues); jsize i; debug("runSearchServicesImpl uuidSetSize %i", uuidSetSize); for(i = 0; i < uuidSetSize; i++) { jbyteArray byteArray = (jbyteArray)(*env)->GetObjectArrayElement(env, uuidValues, i); uuid_t* uuid = (uuid_t*)malloc(sizeof(uuid_t)); convertUUIDByteArrayToUUID(env, byteArray, uuid); uuidList = sdp_list_append(uuidList, uuid); } // convert remote device address from jlong to bluez bdaddr_t bdaddr_t remoteAddress; longToDeviceAddr(remoteDeviceAddressLong, &remoteAddress); bdaddr_t localAddr; longToDeviceAddr(localDeviceBTAddress, &localAddr); // connect to the device to retrieve services session = sdp_connect(&localAddr, &remoteAddress, SDP_RETRY_IF_BUSY); // if connection is not established throw an exception if (session == NULL) { rc = SERVICE_SEARCH_DEVICE_NOT_REACHABLE; goto searchServicesImplEnd; } // then ask the device for service record handles error = sdp_service_search_req(session, uuidList, max_rec_num, &(rsp_list)); if (error) { debug("sdp_service_search_req error %i", error); rc = SERVICE_SEARCH_ERROR; goto searchServicesImplEnd; } Edebug("runSearchServicesImpl session %p %li", session, ptr2jlong(session)); // Notify java about found services sdp_list_t* handle; for(handle = rsp_list; handle; handle = handle->next) { uint32_t record = *(uint32_t*)handle->data; jlong recordHandle = record; Edebug("runSearchServicesImpl serviceRecordHandle %li", recordHandle); jboolean isTerminated = (*env)->CallBooleanMethod(env, peer, serviceDiscoveredCallback, searchServicesThread, ptr2jlong(session), recordHandle); if ((*env)->ExceptionCheck(env)) { rc = SERVICE_SEARCH_ERROR; goto searchServicesImplEnd; } else if (isTerminated) { rc = SERVICE_SEARCH_TERMINATED; goto searchServicesImplEnd; } serviceCount ++; } debug("runSearchServicesImpl found %i", serviceCount); rc = SERVICE_SEARCH_COMPLETED; searchServicesImplEnd: sdp_list_free(uuidList, free); sdp_list_free(rsp_list, free); if (session != NULL) { sdp_close(session); } return rc; }