Example #1
0
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;
}