bool isCurrentThreadInterrupted(JNIEnv *env, jobject peer) { jclass peerClass = (*env)->GetObjectClass(env, peer); jmethodID aMethod = getGetMethodID(env, peerClass, "isCurrentThreadInterruptedCallback", "()Z"); if (aMethod == NULL) { return true; } if ((*env)->CallBooleanMethod(env, peer, aMethod)) { throwInterruptedIOException(env, "thread interrupted"); return true; } return (*env)->ExceptionCheck(env); }
JNIEXPORT jlong JNICALL Java_com_intel_bluetooth_BluetoothStackWIDCOMM_l2ServerAcceptAndOpenServerConnection (JNIEnv *env, jobject peer, jlong handle) { WIDCOMMStackL2CapServer* srv = validL2CapServerHandle(env, handle); if (srv == NULL) { return 0; } if (srv->sdpService == NULL) { throwIOException(env, cCONNECTION_CLOSED); return 0; } if (!srv->finalizeSDPRecord(env)) { return 0; } #ifdef BWT_SINCE_SDK_6_0_1 srv->sdpService->CommitRecord(); #endif EnterCriticalSection(&stack->csCommIf); if (stack == NULL) { throwInterruptedIOException(env, cSTACK_CLOSED); } WIDCOMMStackL2CapConn* l2c = stack->createL2CapConn(); if (l2c == NULL) { throwBluetoothConnectionException(env, BT_CONNECTION_ERROR_NO_RESOURCES, "No free connections Objects in Pool"); LeaveCriticalSection(&stack->csCommIf); return 0; } srv->addClient(l2c); l2c->receiveMTU = srv->receiveMTU; l2c->transmitMTU = srv->transmitMTU; BOOL rc = l2c->Listen(&(srv->l2CapIf)); if (stack != NULL) { LeaveCriticalSection(&stack->csCommIf); } if (!rc) { throwBluetoothConnectionException(env, BT_CONNECTION_ERROR_FAILED_NOINFO, "Failed to Listen"); accept_l2_server_return 0; } HANDLE hEvents[2]; hEvents[0] = l2c->hConnectionEvent; hEvents[1] = srv->hConnectionEvent; debug(("l2s(%i) l2(%i) L2CAP server waits for connection", srv->internalHandle, l2c->internalHandle)); long incomingConnectionCountWas = incomingL2CAPConnectionCount; while ((stack != NULL) && (!srv->isClosing) && (!l2c->isConnected) && (!l2c->isDisconnected) && (srv->sdpService != NULL)) { DWORD rc = WaitForMultipleObjects(2, hEvents, FALSE, 500); if (rc == WAIT_FAILED) { throwRuntimeException(env, "WaitForSingleObject"); accept_l2_server_return 0; } if ((stack != NULL) && (incomingConnectionCountWas != incomingL2CAPConnectionCount)) { debug(("L2CAP server incomingConnectionCount %i", incomingL2CAPConnectionCount)); incomingConnectionCountWas = incomingL2CAPConnectionCount; } if (isCurrentThreadInterrupted(env, peer, "accept")) { accept_l2_server_return 0; } } if (stack == NULL) { throwInterruptedIOException(env, cSTACK_CLOSED); return 0; } if (!l2c->isConnected) { if (srv->isClosing || (srv->sdpService == NULL)) { throwInterruptedIOException(env, cCONNECTION_CLOSED); } else if (l2c->isDisconnected) { throwIOException(env, "Connection error"); } else { throwIOException(env, "Failed to connect"); } accept_l2_server_return 0; } debug(("l2s(%i) l2(%i) L2CAP server connection made", srv->internalHandle, l2c->internalHandle)); l2c->selectConnectionTransmitMTU(env); return l2c->internalHandle; }