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   Author: Fitbit   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   Author: Fitbit   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   Author: Fitbit   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   Author: Fitbit   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
Source Project: Android-BLE-Library   Author: NordicSemiconductor   File: BleManagerHandler.java    License: BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
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
Source Project: AsteroidOSSync   Author: AsteroidOS   File: P_NativeServerWrapper.java    License: GNU General Public License v3.0 6 votes vote down vote up
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
Source Project: SweetBlue   Author: iDevicesInc   File: P_NativeServerWrapper.java    License: GNU General Public License v3.0 6 votes vote down vote up
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   Author: Fitbit   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
Source Project: bitgatt   Author: Fitbit   File: BluetoothOffClearGattServerStrategy.java    License: Mozilla Public License 2.0 5 votes vote down vote up
@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   Author: Fitbit   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   Author: Fitbit   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   Author: Fitbit   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   Author: adafruit   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
Source Project: Android-BLE-Library   Author: NordicSemiconductor   File: BleManagerHandler.java    License: BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
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
Source Project: Android-BLE-Library   Author: NordicSemiconductor   File: BleManagerHandler.java    License: BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
@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
Source Project: Android-BLE-Library   Author: NordicSemiconductor   File: BleManagerHandler.java    License: BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
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
Source Project: AsteroidOSSync   Author: AsteroidOS   File: P_NativeServerWrapper.java    License: GNU General Public License v3.0 5 votes vote down vote up
public final int getNativeState(final String macAddress)
{
	if( m_nativeConnectionStates.containsKey(macAddress) )
	{
		return m_nativeConnectionStates.get(macAddress);
	}
	else
	{
		return BluetoothGattServer.STATE_DISCONNECTED;
	}
}
 
Example #18
Source Project: AsteroidOSSync   Author: AsteroidOS   File: PA_Task_RequiresServerConnection.java    License: GNU General Public License v3.0 5 votes vote down vote up
@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   Author: WebBluetoothCG   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   Author: WebBluetoothCG   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
Source Project: Android-nRF-Toolbox   Author: NordicSemiconductor   File: ProximityManager.java    License: BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
@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
Source Project: SweetBlue   Author: iDevicesInc   File: P_NativeServerWrapper.java    License: GNU General Public License v3.0 5 votes vote down vote up
public final int getNativeState(final String macAddress)
{
	if( m_nativeConnectionStates.containsKey(macAddress) )
	{
		return m_nativeConnectionStates.get(macAddress);
	}
	else
	{
		return BluetoothGattServer.STATE_DISCONNECTED;
	}
}
 
Example #23
Source Project: SweetBlue   Author: iDevicesInc   File: PA_Task_RequiresServerConnection.java    License: GNU General Public License v3.0 5 votes vote down vote up
@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   Author: Fitbit   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
Source Project: bitgatt   Author: Fitbit   File: CloseGattServerTransaction.java    License: Mozilla Public License 2.0 4 votes vote down vote up
@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   Author: Fitbit   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   Author: Fitbit   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   Author: Fitbit   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
Source Project: Android-BLE-Library   Author: NordicSemiconductor   File: BleServerManager.java    License: BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * Returns the {@link BluetoothGattServer} instance.
 */
@Nullable
final BluetoothGattServer getServer() {
	return server;
}
 
Example #30
Source Project: Android-BLE-Library   Author: NordicSemiconductor   File: BleManagerHandler.java    License: BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
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);
	}
}