Java Code Examples for android.bluetooth.BluetoothGattServer

The following examples show how to use android.bluetooth.BluetoothGattServer. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: bitgatt   Source File: GattServerConnection.java    License: Mozilla Public License 2.0 6 votes vote down vote up
@SuppressWarnings("unused") // API method and warning
protected void closeGattServer(){
    Timber.v("Unregistering gatt server listeners");
    asynchronousEventListeners.clear();
    BluetoothGattServer server = getServer();
    if(server != null) {
        setState(GattState.CLOSING_GATT_SERVER);
        Timber.v("Clearing gatt server services");
        server.clearServices();
        Timber.v("Closing gatt server");
        // it seems to me that close should not be used unless the process is dying
        // it always prevents adding services on the GS9+ ( Exynos ) and on the Pixel 2 ( Q )
        server.close();
        setState(GattState.CLOSE_GATT_SERVER_SUCCESS);
        if(serverQueue != null) {
            serverQueue.stop();
        }
    }
}
 
Example 2
Source Project: bitgatt   Source File: GattServerTests.java    License: Mozilla Public License 2.0 6 votes vote down vote up
@Test
public void ensureNpeHandlingServerNoListenersSendResponse() {
    Looper mockLooper = mock(Looper.class);
    Context mockContext = mock(Context.class);
    when(mockContext.getMainLooper()).thenReturn(mockLooper);
    BluetoothDevice mockDevice = mock(BluetoothDevice.class);
    BluetoothGattServer mockServer = mock(BluetoothGattServer.class);
    GattServerConnection mockServerConnection = mock(GattServerConnection.class);
    when(mockServer.sendResponse(any(BluetoothDevice.class), any(Integer.class), any(Integer.class), any(Integer.class), any(byte[].class))).thenThrow(new NullPointerException("Parcel read exception"));
    when(mockServerConnection.getServer()).thenReturn(mockServer);
    GattServerCallback serverCallback = new GattServerCallback();
    NullPointerException exception = null;
    try {
        serverCallback.returnErrorToRemoteClient(mockServerConnection, mockDevice, 0, 1);
    }catch(NullPointerException e) {
        exception = e;
    }
    Assert.assertNull(exception);
}
 
Example 3
Source Project: bitgatt   Source File: FitbitGattTest.java    License: Mozilla Public License 2.0 6 votes vote down vote up
@Test
public void startingTheGattServerWithoutIssues() {
    BluetoothGattServer serverMock = mock(BluetoothGattServer.class);
    doReturn(serverMock).when(managerMock).openGattServer(eq(contextMock), any());
    FitbitGatt.OpenGattServerCallback openServerCB = mock(FitbitGatt.OpenGattServerCallback.class);
    FitbitGatt.FitbitGattCallback cb = mock(FitbitGatt.FitbitGattCallback.class);

    fitbitGatt.registerGattEventListener(cb);
    Runnable startGattServer = fitbitGatt.tryAndStartGattServer(contextMock, openServerCB, managerMock);
    startGattServer.run();

    verify(cb, times(1)).onGattServerStarted(any());
    verify(serverMock).clearServices();
    verify(openServerCB, times(1)).onGattServerStatus(true);
    verifyNoMoreInteractions(cb);
    verifyNoMoreInteractions(openServerCB);
    assertSame(GattState.IDLE, fitbitGatt.getServer().getGattState());
}
 
Example 4
Source Project: bitgatt   Source File: GattConnectionTests.java    License: Mozilla Public License 2.0 6 votes vote down vote up
@BeforeClass
public static void beforeClass() {
    Context appContext = mock(Context.class);
    when(appContext.getSystemService(any(String.class))).thenReturn(null);
    when(appContext.getApplicationContext()).thenReturn(appContext);
    FitbitGatt.getInstance().setAsyncOperationThreadWatchdog(mock(LooperWatchdog.class));
    FitbitGatt.getInstance().start(appContext);
    Looper mockLooper = mock(Looper.class);
    BluetoothDevice mockBluetoothDevice = mock(BluetoothDevice.class);
    when(mockBluetoothDevice.getAddress()).thenReturn(MOCK_ADDRESS);
    when(mockBluetoothDevice.getName()).thenReturn(MOCK_NAME);
    mockGatt = mock(BluetoothGatt.class);
    when(mockGatt.getDevice()).thenReturn(mockBluetoothDevice);
    connection = new GattConnection(new FitbitBluetoothDevice(mockBluetoothDevice), mockLooper);
    connection.setMockMode(true);
    BluetoothGattServer server = mock(BluetoothGattServer.class);
    serverConnection = new GattServerConnection(server, mockLooper);
    serverConnection.setMockMode(true);
}
 
Example 5
final void onNotificationSent(@NonNull final BluetoothGattServer server,
							  @NonNull final BluetoothDevice device, final int status) {
	log(Log.DEBUG, "[Server callback] Notification sent (status=" + status + ")");
	if (status == BluetoothGatt.GATT_SUCCESS) {
		notifyNotificationSent(device);
	} else {
		Log.e(TAG, "onNotificationSent error " + status);
		if (request instanceof WriteRequest) {
			request.notifyFail(device, status);
		}
		awaitingRequest = null;
		onError(device, ERROR_NOTIFY, status);
	}
	checkCondition();
	nextRequest(true);
}
 
Example 6
private void assertThatAllClientsAreDisconnected()
{
	if( m_nativeConnectionStates.size() == 0 )  return;

	for( String macAddress : m_nativeConnectionStates.keySet() )
	{
		final Integer state = m_nativeConnectionStates.get(macAddress);

		if( state != null && state != BluetoothGattServer.STATE_DISCONNECTED )
		{
			m_mngr.ASSERT(false, "Found a server connection state that is not disconnected when it should be.");

			return;
		}
	}
}
 
Example 7
private void assertThatAllClientsAreDisconnected()
{
	if( m_nativeConnectionStates.size() == 0 )  return;

	for( String macAddress : m_nativeConnectionStates.keySet() )
	{
		final Integer state = m_nativeConnectionStates.get(macAddress);

		if( state != null && state != BluetoothGattServer.STATE_DISCONNECTED )
		{
			m_mngr.ASSERT(false, "Found a server connection state that is not disconnected when it should be.");

			return;
		}
	}
}
 
Example 8
Source Project: bitgatt   Source File: GattPlugin.java    License: Mozilla Public License 2.0 5 votes vote down vote up
private void addLocalGattServerService(DumperContext dumpContext, Iterator<String> args) throws InterruptedException {
    if (args.hasNext()) {
        String serviceUuid = args.next();
        BluetoothGattServer server = fitbitGatt.getServer().getServer();
        boolean isDuplicate = false;
        for (BluetoothGattService service : server.getServices()) {
            String currentUuid = service.getUuid().toString();
            if (currentUuid.equals(serviceUuid)) {
                isDuplicate = true;
                break;
            }
        }

        if (!isDuplicate) {
            BluetoothGattService gattService = new BluetoothGattService(UUID.fromString(serviceUuid), BluetoothGattService.SERVICE_TYPE_PRIMARY);
            AddGattServerServiceTransaction tx = new AddGattServerServiceTransaction(fitbitGatt.getServer(), GattState.ADD_SERVICE_SUCCESS, gattService);
            CountDownLatch cdl = new CountDownLatch(1);
            fitbitGatt.getServer().runTx(tx, result -> {
                logSuccessOrFailure(result, dumpContext, "Successfully Added Gatt Server Service", "Failed Adding Gatt Server Service");
                cdl.countDown();
            });
            cdl.await();
        } else {
            logSuccess(dumpContext, "Duplicate service by UUID ");
        }

    } else {
        logError(dumpContext, new IllegalArgumentException("No viable service UUID provided"));
    }
}
 
Example 9
@Override
public void applyStrategy() {
    // we want to clear the services on the server, however we must make sure that we do not
    // crash in a stack NPE if the bluetooth service has crashed or is shut down, and we want
    // to make sure that this does not occur on the main thread since this probably transits
    // the JNI and could lead to a ANR
    Handler strategyHandler = new Handler(FitbitGatt.getInstance().getFitbitGattAsyncOperationThread().getLooper());
    strategyHandler.post(() -> {
        GattServerConnection serverConn = FitbitGatt.getInstance().getServer();
        if(serverConn == null) {
            Timber.i("Server connection was null when trying to execute strategy");
            return;
        }
        // make it disconnected so that no one can use it
        serverConn.setState(GattState.DISCONNECTED);
        BluetoothGattServer gattServer = serverConn.getServer();
        if(gattServer == null) {
            Timber.i("Android BluetoothGattServer instance was null when trying to execute strategy");
            return;
        }
        try {
            /* this may not execute instantly, so considering some sort of delay between
             * clear, close and release ... in the downside of a delay is that the BT service
             * may go away while we are waiting, so opting for now to just go for it and hope
             * that the queue system does the right thing.
             */
            gattServer.clearServices();
        } catch (NullPointerException e) {
            Timber.w(e, "There was an internal stack NPE, the Android BluetoothService probably crashed or already shut down");
        }
        serverConn.setState(GattState.IDLE);
    });
}
 
Example 10
Source Project: bitgatt   Source File: GattServerCallback.java    License: Mozilla Public License 2.0 5 votes vote down vote up
private boolean checkCharacteristicAndCharacteristicService(GattServerConnection conn, BluetoothDevice device, @Nullable BluetoothGattCharacteristic characteristic, int requestId, int offset) {
    BluetoothGattServer server = conn.getServer();
    if (characteristic == null) {
        Timber.w("[%s] The characteristic wasn't attached to the descriptor! Returning error", device);
        returnErrorToRemoteClient(conn, device, requestId, offset);
        return true;
    }
    UUID charUuid = characteristic.getUuid();
    BluetoothGattService referencedService = characteristic.getService();
    if (referencedService == null) {
        Timber.w("[%s] The expected service wasn't attached to the characteristic! Returning error", device);
        returnErrorToRemoteClient(conn, device, requestId, offset);
        return true;
    }
    if (server.getService(referencedService.getUuid()) == null) {
        Timber.w("[%s] The expected service wasn't hosted! Returning error", device);
        returnErrorToRemoteClient(conn, device, requestId, offset);
        return true;
    }
    BluetoothGattService hostedService = server.getService(referencedService.getUuid());
    if (hostedService.getCharacteristic(charUuid) == null) {
        Timber.w("[%s] The expected characteristic wasn't hosted! Returning error", device);
        returnErrorToRemoteClient(conn, device, requestId, offset);
        return true;
    }
    return false;
}
 
Example 11
Source Project: bitgatt   Source File: GattServerConnection.java    License: Mozilla Public License 2.0 5 votes vote down vote up
protected GattServerConnection(@Nullable BluetoothGattServer server, Looper looper) {
    this.server = server;
    this.serverQueue = new TransactionQueueController();
    this.guard = new GattStateTransitionValidator();
    this.state = GattState.IDLE;
    this.mainHandler = new Handler(looper);
}
 
Example 12
Source Project: bitgatt   Source File: FitbitGattTest.java    License: Mozilla Public License 2.0 5 votes vote down vote up
@Test
public void startingTheGattServerWithAPreviousConnectionExisting() {
    BluetoothGattServer serverMock = mock(BluetoothGattServer.class);
    doReturn(serverMock).when(managerMock).openGattServer(eq(contextMock), any());
    FitbitGatt.OpenGattServerCallback openServerCB = mock(FitbitGatt.OpenGattServerCallback.class);
    FitbitGatt.FitbitGattCallback cb = mock(FitbitGatt.FitbitGattCallback.class);
    GattServerConnection prevConnection = mock(GattServerConnection.class);
    doAnswer(invocation -> {
        TransactionResult tr = new TransactionResult.Builder()
            .resultStatus(TransactionResult.TransactionResultStatus.SUCCESS).build();
        GattTransactionCallback gattServerCallback = invocation.getArgument(1);
        gattServerCallback.onTransactionComplete(tr);
        return tr;
    }).when(prevConnection).runTx(any(ClearServerServicesTransaction.class), any());

    fitbitGatt.setGattServerConnection(prevConnection);
    fitbitGatt.setAppContext(contextMock);
    fitbitGatt.registerGattEventListener(cb);

    Runnable startGattServer = fitbitGatt.tryAndStartGattServer(contextMock, openServerCB, managerMock);
    startGattServer.run();

    verify(prevConnection).runTx(any(ClearServerServicesTransaction.class), any());
    verify(cb, times(1)).onGattServerStarted(any());
    verify(openServerCB, times(1)).onGattServerStatus(true);
    verifyNoMoreInteractions(cb);
    verifyNoMoreInteractions(openServerCB);
    assertSame(GattState.IDLE, fitbitGatt.getServer().getGattState());
}
 
Example 13
Source Project: Bluefruit_LE_Connect_Android_V2   Source File: GattServer.java    License: MIT License 5 votes vote down vote up
private synchronized void stopAdvertising(/*@NonNull Context context, */boolean notifyListener) {
    mShouldStartAdvertising = false;

    if (mAdvertiser != null && mIsAdvertising) {
        try {
            mAdvertiser.stopAdvertising(mAdvertisingCallback);
        } catch (IllegalStateException e) {         // Discard IllegalStateException reported in Android vitals crashes
            Log.w(TAG, "stopAdvertising illegalstate: " + e);
        }
        mIsAdvertising = false;
        Log.d(TAG, "Advertising stopAdvertising");
    }

    if (mGattServer != null) {
        List<BluetoothDevice> devices = mBluetoothManager.getConnectedDevices(BluetoothGattServer.GATT_SERVER);
        for (int i = 0; i < devices.size(); i++) {
            mGattServer.cancelConnection(devices.get(i));
        }
        mGattServer.clearServices();

        /*
        if (kAddDelayAfterBeforeClosing) {      // Hack to avoid Android internal bugs. Exists on Android v6 and v7... maybe more...
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }*/
        mGattServer.close();
        mGattServer = null;
    }

    if (notifyListener && mListener != null) {
        mListener.onDidStopAdvertising();
    }
}
 
Example 14
final void onExecuteWrite(@NonNull final BluetoothGattServer server,
						  @NonNull final BluetoothDevice device, final int requestId,
						  final boolean execute) {
	log(Log.DEBUG, "[Server callback] Execute write request (requestId=" + requestId + ", execute=" + execute + ")");
	if (execute) {
		final Deque<Pair<Object, byte[]>> values = preparedValues;
		log(Log.INFO, "[Server] Execute write request received");
		preparedValues = null;
		if (prepareError != 0) {
			sendResponse(server, device, prepareError, requestId, 0, null);
			prepareError = 0;
			return;
		}
		sendResponse(server, device, BluetoothGatt.GATT_SUCCESS, requestId, 0, null);

		if (values == null || values.isEmpty()) {
			return;
		}
		boolean startNextRequest = false;
		for (final Pair<Object, byte[]> value: values) {
			if (value.first instanceof BluetoothGattCharacteristic) {
				final BluetoothGattCharacteristic characteristic = (BluetoothGattCharacteristic) value.first;
				startNextRequest = assignAndNotify(device, characteristic, value.second) || startNextRequest;
			} else if (value.first instanceof BluetoothGattDescriptor){
				final BluetoothGattDescriptor descriptor = (BluetoothGattDescriptor) value.first;
				startNextRequest = assignAndNotify(device, descriptor, value.second) || startNextRequest;
			}
		}
		if (checkCondition() || startNextRequest) {
			nextRequest(true);
		}
	} else {
		log(Log.INFO, "[Server] Cancel write request received");
		preparedValues = null;
		sendResponse(server, device, BluetoothGatt.GATT_SUCCESS, requestId, 0, null);
	}
}
 
Example 15
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
final void onMtuChanged(@NonNull final BluetoothGattServer server,
						@NonNull final BluetoothDevice device,
						final int mtu) {
	log(Log.INFO, "[Server] MTU changed to: " + mtu);
	BleManagerHandler.this.mtu = mtu;
	checkCondition();
	nextRequest(false);
}
 
Example 16
private void sendResponse(@NonNull final BluetoothGattServer server,
						  @NonNull final BluetoothDevice device, final int status,
						  final int requestId, final int offset,
						  @Nullable final byte[] response) {
	String msg;
	switch (status) {
		case BluetoothGatt.GATT_SUCCESS: 				msg = "GATT_SUCCESS"; break;
		case BluetoothGatt.GATT_REQUEST_NOT_SUPPORTED: 	msg = "GATT_REQUEST_NOT_SUPPORTED"; break;
		case BluetoothGatt.GATT_INVALID_OFFSET: 		msg = "GATT_INVALID_OFFSET"; break;
		default: throw new InvalidParameterException();
	}
	log(Log.DEBUG, "server.sendResponse(" + msg + ", offset=" + offset + ", value=" + ParserUtils.parseDebug(response) + ")");
	server.sendResponse(device, requestId, status, offset, response);
	log(Log.VERBOSE, "[Server] Response sent");
}
 
Example 17
public final int getNativeState(final String macAddress)
{
	if( m_nativeConnectionStates.containsKey(macAddress) )
	{
		return m_nativeConnectionStates.get(macAddress);
	}
	else
	{
		return BluetoothGattServer.STATE_DISCONNECTED;
	}
}
 
Example 18
@Override protected boolean isExecutable()
{
	boolean shouldBeExecutable = super.isExecutable() && getServer().m_nativeWrapper.getNativeState(m_macAddress) == BluetoothGattServer.STATE_CONNECTED;
	
	if( shouldBeExecutable )
	{
		return true;
	}
	
	return false;
}
 
Example 19
Source Project: ble-test-peripheral-android   Source File: Peripheral.java    License: Apache License 2.0 5 votes vote down vote up
private void updateConnectedDevicesStatus() {
  final String message = getString(R.string.status_devicesConnected) + " "
      + mBluetoothManager.getConnectedDevices(BluetoothGattServer.GATT).size();
  runOnUiThread(new Runnable() {
    @Override
    public void run() {
      mConnectionStatus.setText(message);
    }
  });
}
 
Example 20
Source Project: ble-test-peripheral-android   Source File: Peripheral.java    License: Apache License 2.0 5 votes vote down vote up
private void disconnectFromDevices() {
  Log.d(TAG, "Disconnecting devices...");
  for (BluetoothDevice device : mBluetoothManager.getConnectedDevices(
      BluetoothGattServer.GATT)) {
    Log.d(TAG, "Devices: " + device.getAddress() + " " + device.getName());
    mGattServer.cancelConnection(device);
  }
}
 
Example 21
@Override
protected void onServerReady(@NonNull final BluetoothGattServer server) {
	final BluetoothGattService immediateAlertService = server.getService(IMMEDIATE_ALERT_SERVICE_UUID);
	if (immediateAlertService != null) {
		localAlertLevelCharacteristic = immediateAlertService.getCharacteristic(ALERT_LEVEL_CHARACTERISTIC_UUID);
	}
}
 
Example 22
public final int getNativeState(final String macAddress)
{
	if( m_nativeConnectionStates.containsKey(macAddress) )
	{
		return m_nativeConnectionStates.get(macAddress);
	}
	else
	{
		return BluetoothGattServer.STATE_DISCONNECTED;
	}
}
 
Example 23
@Override protected boolean isExecutable()
{
	boolean shouldBeExecutable = super.isExecutable() && getServer().m_nativeWrapper.getNativeState(m_macAddress) == BluetoothGattServer.STATE_CONNECTED;
	
	if( shouldBeExecutable )
	{
		return true;
	}
	
	return false;
}
 
Example 24
Source Project: bitgatt   Source File: GattPlugin.java    License: Mozilla Public License 2.0 4 votes vote down vote up
private void showGattServerServices(DumperContext dumpContext) {
    int n = 106;
    StringBuilder builder = new StringBuilder();
    String status = PASS_STATUS;
    String error = "";
    if (!isJsonFormat) {
        for (int i = 0; i < n; i++) {
            builder.append("=");
        }
        log(dumpContext, builder.toString());
        format(dumpContext, "| %1$32s | %2$32s |\n",
            "Service UUID",
            "Type");
    }
    String serviceUuid;
    String type;
    BluetoothGattServer server = fitbitGatt.getServer().getServer();
    List<BluetoothGattService> services = server.getServices();
    JSONArray jsonArray = new JSONArray();
    try {
        for (BluetoothGattService service : services) {
            serviceUuid = service.getUuid().toString();
            switch (service.getType()) {
                case BluetoothGattService.SERVICE_TYPE_PRIMARY:
                    type = "primary";
                    break;
                case BluetoothGattService.SERVICE_TYPE_SECONDARY:
                    type = "secondary";
                    break;
                default:
                    type = "unknown";
            }
            if (!isJsonFormat) {
                format(dumpContext, "| %1$32s | %2$32s |\n", serviceUuid, type);
            } else {
                Map<String, Object> map = new LinkedHashMap<String, Object>();
                map.put(RESULT_SERVICE_UUID_KEY, serviceUuid);
                map.put(RESULT_SERVICE_TYPE_KEY, type);
                JSONObject jsonObject = makeJsonObject(map);
                jsonArray.put(jsonObject);
            }
        }
    } catch (Exception e) {
        status = FAIL_STATUS;
        error = Arrays.toString(e.getStackTrace());
    }

    builder = new StringBuilder();
    if (!isJsonFormat) {
        for (int i = 0; i < n; i++) {
            builder.append("=");
        }
        log(dumpContext, builder.toString());
    } else {
        logJsonResult(dumpContext, status, error, jsonArray);
    }
}
 
Example 25
@Override
protected void transaction(GattTransactionCallback callback) {
    super.transaction(callback);
    getGattServer().setState(GattState.CLOSING_GATT_SERVER);
    TransactionResult.Builder builder = new TransactionResult.Builder().transactionName(getName());
    BluetoothGattServer server = getGattServer().getServer();
    if(server == null) {
        Timber.w("The gatt server was null");
        getGattServer().setState(GattState.CLOSE_GATT_SERVER_FAILURE);
        builder.gattState(getGattServer().getGattState())
            .resultStatus(TransactionResult.TransactionResultStatus.FAILURE);
        mainThreadHandler.post(() -> {
            callCallbackWithTransactionResultAndRelease(callback, builder.build());
            getGattServer().setState(GattState.IDLE);
        });
    } else {
        BluetoothAdapter adapter = new GattUtils().getBluetoothAdapter(FitbitGatt.getInstance().getAppContext());
        if(adapter != null && adapter.isEnabled()) {
            Timber.e("I hope you know what you are doing, you will not be able to operate on the gatt server again until BT is toggled.");
        }
        try {
            server.close();
            getGattServer().setState(GattState.CLOSE_GATT_SERVER_SUCCESS);
            builder.gattState(getGattServer().getGattState())
                .resultStatus(TransactionResult.TransactionResultStatus.SUCCESS);
            mainThreadHandler.post(() -> {
                callCallbackWithTransactionResultAndRelease(callback, builder.build());
                getGattServer().setState(GattState.IDLE);
            });
        } catch (NullPointerException ex) {
            Timber.w("As the client close can sometimes NPE internally, it is reasonable to assume that a similar thing occurred for the server");
            getGattServer().setState(GattState.CLOSE_GATT_SERVER_FAILURE);
            builder.gattState(getGattServer().getGattState())
                .resultStatus(TransactionResult.TransactionResultStatus.FAILURE);
            mainThreadHandler.post(() -> {
                callCallbackWithTransactionResultAndRelease(callback, builder.build());
                getGattServer().setState(GattState.IDLE);
            });
        }
    }
}
 
Example 26
Source Project: bitgatt   Source File: GattServerConnection.java    License: Mozilla Public License 2.0 4 votes vote down vote up
public BluetoothGattServer getServer(){
    return server;
}
 
Example 27
Source Project: bitgatt   Source File: GattServerTests.java    License: Mozilla Public License 2.0 4 votes vote down vote up
@Test
public void btOffOnWillClearServicesAndThatGattServerIfStartedWillRetunrAfterToggle() throws InterruptedException {
    // should do nothing if already started
    final CountDownLatch cdl = new CountDownLatch(2);
    BluetoothAdapter adapter = new GattUtils().getBluetoothAdapter(mockContext);
    assertNotNull("adapter is null", adapter);
    AtomicBoolean isFirst = new AtomicBoolean(true);
    FitbitGatt.FitbitGattCallback cb = new NoOpGattCallback() {
        @Override
        public void onGattServerStarted(GattServerConnection serverConnection) {
            super.onGattServerStarted(serverConnection);
            if (isFirst.get()) {
                AddGattServerServiceTransaction transaction = new AddGattServerServiceTransaction(serverConnection, GattState.ADD_SERVICE_SUCCESS, liveData);
                serverConnection.runTx(transaction, result -> {
                    assertEquals(result.resultStatus, TransactionResult.TransactionResultStatus.SUCCESS);
                    adapter.disable();
                    isFirst.set(false);
                    cdl.countDown();
                });
            } else {
                BluetoothGattServer server = FitbitGatt.getInstance().getServer().getServer();
                List<BluetoothGattService> services = server.getServices();
                Assert.assertTrue(services.isEmpty());
                cdl.countDown();
            }
        }

        @Override
        public void onBluetoothOff() {
            super.onBluetoothOff();
            adapter.enable();
        }

    };
    FitbitGatt.getInstance().registerGattEventListener(cb);
    FitbitGatt.getInstance().startGattServer(mockContext);
    cdl.await(10, TimeUnit.SECONDS);
    if (cdl.getCount() != 0) {
        fail(String.format("Not all countdowns have been executed.Not Executed %d", cdl.getCount()));
    }
}
 
Example 28
Source Project: bitgatt   Source File: GattServerTests.java    License: Mozilla Public License 2.0 4 votes vote down vote up
@Test
public void btOffOnWillClearServicesAndThatGattServerIfStartedWillRetunrAfterToggleMultipleTimesInQuickSuccession() throws InterruptedException {
    // should do nothing if already started
    final CountDownLatch cdl = new CountDownLatch(2);
    BluetoothAdapter adapter = new GattUtils().getBluetoothAdapter(mockContext);
    assertNotNull("adapter is null", adapter);
    AtomicBoolean isFirst = new AtomicBoolean(true);
    AtomicInteger countTest = new AtomicInteger(1);
    FitbitGatt.FitbitGattCallback cb = new NoOpGattCallback() {
        @Override
        public void onGattServerStarted(GattServerConnection serverConnection) {
            super.onGattServerStarted(serverConnection);
            if (isFirst.get()) {
                AddGattServerServiceTransaction transaction = new AddGattServerServiceTransaction(serverConnection, GattState.ADD_SERVICE_SUCCESS, liveData);
                serverConnection.runTx(transaction, result -> {
                    assertEquals(result.resultStatus, TransactionResult.TransactionResultStatus.SUCCESS);
                    countTest.incrementAndGet();
                    adapter.disable();
                    cdl.countDown();
                    isFirst.set(false);
                });
            } else if (countTest.get() >= 20) {
                BluetoothGattServer server = FitbitGatt.getInstance().getServer().getServer();
                List<BluetoothGattService> services = server.getServices();
                Assert.assertTrue(services.isEmpty());
                cdl.countDown();
            }
        }

        @Override
        public void onBluetoothOn() {
            super.onBluetoothOn();
            if (countTest.getAndIncrement() > 0 && countTest.getAndIncrement() <= 20) {
                adapter.disable();
            }
        }

        @Override
        public void onBluetoothOff() {
            super.onBluetoothOff();
            adapter.enable();
        }

    };

    FitbitGatt.getInstance().registerGattEventListener(cb);
    FitbitGatt.getInstance().startGattServer(mockContext);
    cdl.await(60, TimeUnit.SECONDS);
    Thread.sleep(2000);
    adapter.enable();
    if (cdl.getCount() != 0) {
        fail(String.format("Not all countdowns have been executed.Not Executed %d", cdl.getCount()));
    }
}
 
Example 29
/**
 * Returns the {@link BluetoothGattServer} instance.
 */
@Nullable
final BluetoothGattServer getServer() {
	return server;
}
 
Example 30
final void onCharacteristicReadRequest(@NonNull final BluetoothGattServer server,
									   @NonNull final BluetoothDevice device,
									   final int requestId, final int offset,
									   @NonNull final BluetoothGattCharacteristic characteristic) {
	log(Log.DEBUG, "[Server callback] Read request for characteristic " + characteristic.getUuid()
			+ " (requestId=" + requestId + ", offset: " + offset + ")");
	if (offset == 0)
		log(Log.INFO, "[Server] READ request for characteristic " + characteristic.getUuid() + " received");

	byte[] data = characteristicValues == null || !characteristicValues.containsKey(characteristic)
			? characteristic.getValue() : characteristicValues.get(characteristic);

	WaitForReadRequest waitForReadRequest = null;
	// First, try to get the data from the WaitForReadRequest if the request awaits,
	if (awaitingRequest instanceof WaitForReadRequest
			// is registered for this characteristic
			&& awaitingRequest.characteristic == characteristic
			// and didn't have a trigger, or the trigger was started
			// (not necessarily completed)
			&& !awaitingRequest.isTriggerPending()) {
		waitForReadRequest = (WaitForReadRequest) awaitingRequest;
		waitForReadRequest.setDataIfNull(data);
		data = waitForReadRequest.getData(mtu);
	}
	// If data are longer than MTU - 1, cut the array. Only ATT_MTU - 1 bytes can be sent in Long Read.
	if (data != null && data.length > mtu - 1) {
		data = Bytes.copy(data, offset, mtu - 1);
	}

	sendResponse(server, device, BluetoothGatt.GATT_SUCCESS, requestId, offset, data);

	if (waitForReadRequest != null) {
		waitForReadRequest.notifyPacketRead(device, data);

		// If the request is complete, start next one.
		if (!waitForReadRequest.hasMore() && (data == null || data.length < mtu - 1)) {
			waitForReadRequest.notifySuccess(device);
			awaitingRequest = null;
			nextRequest(true);
		}
	} else if (checkCondition()) {
		nextRequest(true);
	}
}