android.bluetooth.BluetoothGattServer Java Examples

The following examples show how to use android.bluetooth.BluetoothGattServer. 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 File: GattConnectionTests.java    From bitgatt with 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 #2
Source File: P_NativeServerWrapper.java    From SweetBlue with 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 #3
Source File: P_NativeServerWrapper.java    From AsteroidOSSync with 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 #4
Source File: BleManagerHandler.java    From Android-BLE-Library with 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 #5
Source File: FitbitGattTest.java    From bitgatt with 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 #6
Source File: GattServerTests.java    From bitgatt with 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 #7
Source File: GattServerConnection.java    From bitgatt with 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 #8
Source File: Peripheral.java    From ble-test-peripheral-android with 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 #9
Source File: GattPlugin.java    From bitgatt with 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 #10
Source File: BleManagerHandler.java    From Android-BLE-Library with 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 #11
Source File: BleManagerHandler.java    From Android-BLE-Library with 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 #12
Source File: BluetoothOffClearGattServerStrategy.java    From bitgatt with 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 #13
Source File: BleManagerHandler.java    From Android-BLE-Library with 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 #14
Source File: ProximityManager.java    From Android-nRF-Toolbox with 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 #15
Source File: Peripheral.java    From ble-test-peripheral-android with 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 #16
Source File: PA_Task_RequiresServerConnection.java    From AsteroidOSSync with 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 #17
Source File: P_NativeServerWrapper.java    From AsteroidOSSync with 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 File: P_NativeServerWrapper.java    From SweetBlue with 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 #19
Source File: GattServer.java    From Bluefruit_LE_Connect_Android_V2 with 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 #20
Source File: FitbitGattTest.java    From bitgatt with 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 #21
Source File: GattServerCallback.java    From bitgatt with 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 #22
Source File: GattServerConnection.java    From bitgatt with 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 #23
Source File: PA_Task_RequiresServerConnection.java    From SweetBlue with 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 File: P_AndroidBleServer.java    From AsteroidOSSync with GNU General Public License v3.0 4 votes vote down vote up
@Override
public final BluetoothGattServer getNativeServer()
{
    return m_server;
}
 
Example #25
Source File: UnitTestServerLayer.java    From SweetBlue with GNU General Public License v3.0 4 votes vote down vote up
@Override
public BluetoothGattServer getNativeServer()
{
    return null;
}
 
Example #26
Source File: EddystoneGattService.java    From beacons-android with Apache License 2.0 4 votes vote down vote up
public void readCharacteristic(BluetoothGattServer gattServer, BluetoothDevice device,
                                   int requestId, int offset,
                                   BluetoothGattCharacteristic characteristic) {
//        UUID uuid = characteristic.getUuid();
        int status =  BluetoothGatt.GATT_SUCCESS;

        if (isLocked()) {
            if (characteristic == mUnlockCharacteristic) {
                log("Generating secure unlock challenge");
                characteristic.setValue(new byte[16]);
                new SecureRandom().nextBytes(characteristic.getValue());
            } else {
                if (characteristic != mLockStateCharacteristic) {
                    status = BluetoothGatt.GATT_READ_NOT_PERMITTED;
                }
            }
        }
        else if (characteristic == mUnlockCharacteristic) {
            status = BluetoothGatt.GATT_READ_NOT_PERMITTED;
        } else if (characteristic == mPublicEcdhKeyCharacteristic) {
            log("ECDH Public Key was requested");
            if (0 == offset) {
                characteristic.setValue(null == mEidKeyPair ? new byte[0] : mEidKeyPair.getPublicKey());
            }
        } else if (characteristic == mAdvSlotDataCharacteristic) {
            log("Advertisement slot data requested");
            characteristic.setValue(mConfigCallback.getAdvertisedData());
        } else if (characteristic  == mEidIdentityKeyCharacteristic) {
            log("Identity Key was requested");
            byte[] identityKey = mConfigCallback.getEidIdentityKey();
            if (null == identityKey) {
                status = BluetoothGatt.GATT_FAILURE;
            }
            else {
                characteristic.setValue(aes_transform(true, identityKey, 0, 16));
            }
        }

        gattServer.sendResponse(device, requestId, status, offset,
                status == BluetoothGatt.GATT_SUCCESS ? Arrays.copyOfRange(characteristic.getValue(), offset, characteristic.getValue().length) : null);
    }
 
Example #27
Source File: P_NativeServerWrapper.java    From AsteroidOSSync with GNU General Public License v3.0 4 votes vote down vote up
public final boolean isConnected(final String macAddress)
{
	return getNativeState(macAddress) == BluetoothGattServer.STATE_CONNECTED;
}
 
Example #28
Source File: P_NativeServerWrapper.java    From SweetBlue with GNU General Public License v3.0 4 votes vote down vote up
public final boolean isDisconnecting(final String macAddress)
{
	return getNativeState(macAddress) == BluetoothGattServer.STATE_DISCONNECTING;
}
 
Example #29
Source File: P_NativeServerWrapper.java    From SweetBlue with GNU General Public License v3.0 4 votes vote down vote up
public final boolean isDisconnected(final String macAddress)
{
	return getNativeState(macAddress) == BluetoothGattServer.STATE_DISCONNECTED;
}
 
Example #30
Source File: P_NativeServerWrapper.java    From SweetBlue with GNU General Public License v3.0 4 votes vote down vote up
public final boolean isConnected(final String macAddress)
{
	return getNativeState(macAddress) == BluetoothGattServer.STATE_CONNECTED;
}