Directly include BLE lib as java files
This commit is contained in:
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -29,5 +29,4 @@ dependencies {
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||
implementation 'no.nordicsemi.android:ble:2.1.1'
|
||||
}
|
||||
|
||||
@@ -9,11 +9,11 @@ import android.bluetooth.le.ScanResult;
|
||||
import android.bluetooth.le.ScanSettings;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
3650
app/src/main/java/no/nordicsemi/android/ble/BleManager.java
Normal file
3650
app/src/main/java/no/nordicsemi/android/ble/BleManager.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCallback;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
// DO NOT EDIT THIS FILE UNLESS NECESSARY!
|
||||
/**
|
||||
* The BleManagerCallbacks should be overridden in your app and all the 'high level' callbacks
|
||||
* should be added there. See examples in Android nRF Blinky or Android nRF Toolbox.
|
||||
* <p>
|
||||
* Keeping this file as is (and {@link BleManager} as well) will allow to quickly update it when
|
||||
* an update is posted here.
|
||||
*/
|
||||
@SuppressWarnings({"DeprecatedIsStillUsed", "unused"})
|
||||
public interface BleManagerCallbacks {
|
||||
|
||||
/**
|
||||
* Called when the Android device started connecting to given device.
|
||||
* The {@link #onDeviceConnected(BluetoothDevice)} will be called when the device is connected,
|
||||
* or {@link #onError(BluetoothDevice, String, int)} in case of error.
|
||||
*
|
||||
* @param device the device that got connected.
|
||||
*/
|
||||
void onDeviceConnecting(@NonNull final BluetoothDevice device);
|
||||
|
||||
/**
|
||||
* Called when the device has been connected. This does not mean that the application may start
|
||||
* communication.
|
||||
* A service discovery will be handled automatically after this call. Service discovery
|
||||
* may ends up with calling {@link #onServicesDiscovered(BluetoothDevice, boolean)} or
|
||||
* {@link #onDeviceNotSupported(BluetoothDevice)} if required services have not been found.
|
||||
*
|
||||
* @param device the device that got connected.
|
||||
*/
|
||||
void onDeviceConnected(@NonNull final BluetoothDevice device);
|
||||
|
||||
/**
|
||||
* Called when user initialized disconnection.
|
||||
*
|
||||
* @param device the device that gets disconnecting.
|
||||
*/
|
||||
void onDeviceDisconnecting(@NonNull final BluetoothDevice device);
|
||||
|
||||
/**
|
||||
* Called when the device has disconnected (when the callback returned
|
||||
* {@link BluetoothGattCallback#onConnectionStateChange(BluetoothGatt, int, int)} with state
|
||||
* DISCONNECTED), but ONLY if the {@link BleManager#shouldAutoConnect()} method returned false
|
||||
* for this device when it was connecting.
|
||||
* Otherwise the {@link #onLinkLossOccurred(BluetoothDevice)} method will be called instead.
|
||||
*
|
||||
* @param device the device that got disconnected.
|
||||
*/
|
||||
void onDeviceDisconnected(@NonNull final BluetoothDevice device);
|
||||
|
||||
/**
|
||||
* This callback is invoked when the Ble Manager lost connection to a device that has been
|
||||
* connected with autoConnect option (see {@link BleManager#shouldAutoConnect()}.
|
||||
* Otherwise a {@link #onDeviceDisconnected(BluetoothDevice)} method will be called on such
|
||||
* event.
|
||||
*
|
||||
* @param device the device that got disconnected due to a link loss.
|
||||
*/
|
||||
void onLinkLossOccurred(@NonNull final BluetoothDevice device);
|
||||
|
||||
/**
|
||||
* Called when service discovery has finished and primary services has been found.
|
||||
* This method is not called if the primary, mandatory services were not found during service
|
||||
* discovery. For example in the Blood Pressure Monitor, a Blood Pressure service is a
|
||||
* primary service and Intermediate Cuff Pressure service is a optional secondary service.
|
||||
* Existence of battery service is not notified by this call.
|
||||
* <p>
|
||||
* After successful service discovery the service will initialize all services.
|
||||
* The {@link #onDeviceReady(BluetoothDevice)} method will be called when the initialization
|
||||
* is complete.
|
||||
*
|
||||
* @param device the device which services got disconnected.
|
||||
* @param optionalServicesFound if <code>true</code> the secondary services were also found
|
||||
* on the device.
|
||||
*/
|
||||
void onServicesDiscovered(@NonNull final BluetoothDevice device, final boolean optionalServicesFound);
|
||||
|
||||
/**
|
||||
* Method called when all initialization requests has been completed.
|
||||
*
|
||||
* @param device the device that get ready.
|
||||
*/
|
||||
void onDeviceReady(@NonNull final BluetoothDevice device);
|
||||
|
||||
/**
|
||||
* This method should return true if Battery Level notifications should be enabled on the
|
||||
* target device. If there is no Battery Service, or the Battery Level characteristic does
|
||||
* not have NOTIFY property, this method will not be called for this device.
|
||||
* <p>
|
||||
* This method may return true only if an activity is bound to the service (to display the
|
||||
* information to the user), always (e.g. if critical battery level is reported using
|
||||
* notifications) or never, if such information is not important or the manager wants to
|
||||
* control Battery Level notifications on its own.
|
||||
*
|
||||
* @param device the target device.
|
||||
* @return True to enabled battery level notifications after connecting to the device,
|
||||
* false otherwise.
|
||||
* @deprecated Use
|
||||
* <pre>{@code
|
||||
* setNotificationCallback(batteryLevelCharacteristic)
|
||||
* .with(new BatteryLevelDataCallback() {
|
||||
* onBatteryLevelChanged(int batteryLevel) {
|
||||
* ...
|
||||
* }
|
||||
* });
|
||||
* }</pre>
|
||||
* in the {@link BleManager.BleManagerGattCallback#initialize() initialize(BluetoothDevice)}
|
||||
* instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default boolean shouldEnableBatteryLevelNotifications(@NonNull final BluetoothDevice device) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when battery value has been received from the device.
|
||||
*
|
||||
* @param device the device from which the battery value has changed.
|
||||
* @param value the battery value in percent.
|
||||
* @deprecated Use
|
||||
* <pre>{@code
|
||||
* setNotificationCallback(batteryLevelCharacteristic)
|
||||
* .with(new BatteryLevelDataCallback() {
|
||||
* onBatteryLevelChanged(int batteryLevel) {
|
||||
* ...
|
||||
* }
|
||||
* });
|
||||
* }</pre>
|
||||
* in the {@link BleManager.BleManagerGattCallback#initialize() initialize(BluetoothDevice)}
|
||||
* instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default void onBatteryValueReceived(@NonNull final BluetoothDevice device,
|
||||
@IntRange(from = 0, to = 100) final int value) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an {@link BluetoothGatt#GATT_INSUFFICIENT_AUTHENTICATION} error occurred and the
|
||||
* device bond state is {@link BluetoothDevice#BOND_NONE}.
|
||||
*
|
||||
* @param device the device that requires bonding.
|
||||
*/
|
||||
void onBondingRequired(@NonNull final BluetoothDevice device);
|
||||
|
||||
/**
|
||||
* Called when the device has been successfully bonded.
|
||||
*
|
||||
* @param device the device that got bonded.
|
||||
*/
|
||||
void onBonded(@NonNull final BluetoothDevice device);
|
||||
|
||||
/**
|
||||
* Called when the bond state has changed from {@link BluetoothDevice#BOND_BONDING} to
|
||||
* {@link BluetoothDevice#BOND_NONE}.
|
||||
*
|
||||
* @param device the device that failed to bond.
|
||||
*/
|
||||
void onBondingFailed(@NonNull final BluetoothDevice device);
|
||||
|
||||
/**
|
||||
* Called when a BLE error has occurred
|
||||
*
|
||||
* @param message the error message.
|
||||
* @param errorCode the error code.
|
||||
* @param device the device that caused an error.
|
||||
*/
|
||||
void onError(@NonNull final BluetoothDevice device,
|
||||
@NonNull final String message, final int errorCode);
|
||||
|
||||
/**
|
||||
* Called when service discovery has finished but the main services were not found on the device.
|
||||
*
|
||||
* @param device the device that failed to connect due to lack of required services.
|
||||
*/
|
||||
void onDeviceNotSupported(@NonNull final BluetoothDevice device);
|
||||
}
|
||||
246
app/src/main/java/no/nordicsemi/android/ble/ConnectRequest.java
Normal file
246
app/src/main/java/no/nordicsemi/android/ble/ConnectRequest.java
Normal file
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCallback;
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import no.nordicsemi.android.ble.annotation.PhyMask;
|
||||
import no.nordicsemi.android.ble.callback.BeforeCallback;
|
||||
import no.nordicsemi.android.ble.callback.FailCallback;
|
||||
import no.nordicsemi.android.ble.callback.InvalidRequestCallback;
|
||||
import no.nordicsemi.android.ble.callback.SuccessCallback;
|
||||
|
||||
/**
|
||||
* The connect request is used to connect to a Bluetooth LE device. The request will end when
|
||||
* the device gets connected, the connection timeouts, or an error occurs.
|
||||
* <p>
|
||||
* The {@link #done(SuccessCallback)} callback will be called after the device is ready, that is
|
||||
* when it is connected, the services were discovered, the required services were found and the
|
||||
* initialization queue set in {@link BleManager.BleManagerGattCallback#initialize()} is complete
|
||||
* (without or with errors).
|
||||
*/
|
||||
@SuppressWarnings({"WeakerAccess", "unused", "deprecation"})
|
||||
public class ConnectRequest extends TimeoutableRequest {
|
||||
@NonNull
|
||||
private BluetoothDevice device;
|
||||
@PhyMask
|
||||
private int preferredPhy;
|
||||
@IntRange(from = 0)
|
||||
private int attempt = 0, retries = 0;
|
||||
@IntRange(from = 0)
|
||||
private int delay = 0;
|
||||
private boolean autoConnect = false;
|
||||
|
||||
ConnectRequest(@NonNull final Type type, @NonNull final BluetoothDevice device) {
|
||||
super(type);
|
||||
this.device = device;
|
||||
this.preferredPhy = PhyRequest.PHY_LE_1M_MASK;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
ConnectRequest setManager(@NonNull final BleManager manager) {
|
||||
super.setManager(manager);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ConnectRequest timeout(@IntRange(from = 0) final long timeout) {
|
||||
super.timeout(timeout);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use to set a completion callback. The callback will be invoked when the operation has
|
||||
* finished successfully unless {@link #await()} or its variant was used, in which case this
|
||||
* callback will be ignored.
|
||||
* <p>
|
||||
* The done callback will also be called when one or more of initialization requests has
|
||||
* failed due to a reason other than disconnect event. This is because
|
||||
* {@link BleManagerCallbacks#onDeviceReady(BluetoothDevice)} is called no matter
|
||||
* if the requests succeeded, or not. Set failure callbacks to initialization requests
|
||||
* to get information about failures.
|
||||
*
|
||||
* @param callback the callback.
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public ConnectRequest done(@NonNull final SuccessCallback callback) {
|
||||
super.done(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ConnectRequest fail(@NonNull final FailCallback callback) {
|
||||
super.fail(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ConnectRequest invalid(@NonNull final InvalidRequestCallback callback) {
|
||||
super.invalid(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ConnectRequest before(@NonNull final BeforeCallback callback) {
|
||||
super.before(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an optional retry count. The BleManager will do that many attempts to connect to the
|
||||
* device in case of an error. The library will NOT retry if the device is not reachable,
|
||||
* that is when the 30 sec. timeout occurs. In that case the app should scan before
|
||||
* connecting, to make sure the target is in range.
|
||||
*
|
||||
* @param count how many times should the BleManager retry to connect.
|
||||
* @return The request.
|
||||
* @see #retry(int, int)
|
||||
*/
|
||||
public ConnectRequest retry(@IntRange(from = 0) final int count) {
|
||||
this.retries = count;
|
||||
this.delay = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an optional retry count and a delay that the process will wait before each connection
|
||||
* attempt. The library will NOT retry if the device is not reachable, that is when the 30 sec.
|
||||
* timeout occurs. In that case the app should scan before connecting, to make sure the
|
||||
* target is in range.
|
||||
*
|
||||
* @param count how many times should the BleManager retry to connect.
|
||||
* @param delay the delay between each connection attempt, in milliseconds.
|
||||
* The real delay will be 200 ms longer than specified, as
|
||||
* {@link BluetoothGatt#clone()} is estimated to last
|
||||
* {@link BleManager#internalConnect(BluetoothDevice, ConnectRequest) 200 ms}.
|
||||
* @return The request.
|
||||
* @see #retry(int)
|
||||
*/
|
||||
public ConnectRequest retry(@IntRange(from = 0) final int count,
|
||||
@IntRange(from = 0) final int delay) {
|
||||
this.retries = count;
|
||||
this.delay = delay;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method replaces the {@link BleManager#shouldAutoConnect()} method.
|
||||
* <p>
|
||||
* Sets whether to connect to the remote device just once (false) or to add the address to
|
||||
* white list of devices that will be automatically connect as soon as they become available
|
||||
* (true). In the latter case, if Bluetooth adapter is enabled, Android scans periodically
|
||||
* for devices from the white list and, if an advertising packet is received from such, it tries
|
||||
* to connect to it. When the connection is lost, the system will keep trying to reconnect to
|
||||
* it. If method is called with parameter set to true, and the connection to the device is
|
||||
* lost, the {@link BleManagerCallbacks#onLinkLossOccurred(BluetoothDevice)} callback is
|
||||
* called instead of {@link BleManagerCallbacks#onDeviceDisconnected(BluetoothDevice)}.
|
||||
* <p>
|
||||
* This feature works much better on newer Android phone models and may have issues on older
|
||||
* phones.
|
||||
* <p>
|
||||
* This method should only be used with bonded devices, as otherwise the device may change
|
||||
* it's address. It will however work also with non-bonded devices with private static address.
|
||||
* A connection attempt to a non-bonded device with private resolvable address will fail.
|
||||
* <p>
|
||||
* The first connection to a device will always be created with autoConnect flag to false
|
||||
* (see {@link BluetoothDevice#connectGatt(Context, boolean, BluetoothGattCallback)}). This is
|
||||
* to make it quick as the user most probably waits for a quick response. If autoConnect is
|
||||
* used (true), the following connections will be done using {@link BluetoothGatt#connect()},
|
||||
* which forces the autoConnect parameter to true.
|
||||
*
|
||||
* @param autoConnect true to use autoConnect feature on the second and following connections.
|
||||
* The first connection is always done with autoConnect parameter equal to
|
||||
* false, to make it faster and allow to timeout it the device is unreachable.
|
||||
* Default value is false.
|
||||
* @return The request.
|
||||
*/
|
||||
public ConnectRequest useAutoConnect(final boolean autoConnect) {
|
||||
this.autoConnect = autoConnect;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the preferred PHY used for connection. Th value should be a bitmask composed of
|
||||
* {@link PhyRequest#PHY_LE_1M_MASK}, {@link PhyRequest#PHY_LE_2M_MASK} or
|
||||
* {@link PhyRequest#PHY_LE_CODED_MASK}.
|
||||
* <p>
|
||||
* Different PHYs are available only on more recent devices with Android 8+.
|
||||
* Check {@link BluetoothAdapter#isLe2MPhySupported()} and
|
||||
* {@link BluetoothAdapter#isLeCodedPhySupported()} if required PHYs are supported by this
|
||||
* Android device. The default PHY is {@link PhyRequest#PHY_LE_1M_MASK}.
|
||||
*
|
||||
* @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of
|
||||
* {@link PhyRequest#PHY_LE_1M_MASK}, {@link PhyRequest#PHY_LE_2M_MASK},
|
||||
* and {@link PhyRequest#PHY_LE_CODED_MASK}. This option does not take effect
|
||||
* if {@code autoConnect} is set to true.
|
||||
* @return The request.
|
||||
*/
|
||||
public ConnectRequest usePreferredPhy(@PhyMask final int phy) {
|
||||
this.preferredPhy = phy;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public BluetoothDevice getDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
@PhyMask
|
||||
int getPreferredPhy() {
|
||||
return preferredPhy;
|
||||
}
|
||||
|
||||
boolean canRetry() {
|
||||
if (retries > 0) {
|
||||
retries -= 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isFirstAttempt() {
|
||||
return attempt++ == 0;
|
||||
}
|
||||
|
||||
@IntRange(from = 0)
|
||||
int getRetryDelay() {
|
||||
return delay;
|
||||
}
|
||||
|
||||
boolean shouldAutoConnect() {
|
||||
return autoConnect;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import no.nordicsemi.android.ble.annotation.ConnectionPriority;
|
||||
import no.nordicsemi.android.ble.callback.BeforeCallback;
|
||||
import no.nordicsemi.android.ble.callback.ConnectionPriorityCallback;
|
||||
import no.nordicsemi.android.ble.callback.FailCallback;
|
||||
import no.nordicsemi.android.ble.callback.InvalidRequestCallback;
|
||||
import no.nordicsemi.android.ble.callback.SuccessCallback;
|
||||
import no.nordicsemi.android.ble.exception.BluetoothDisabledException;
|
||||
import no.nordicsemi.android.ble.exception.DeviceDisconnectedException;
|
||||
import no.nordicsemi.android.ble.exception.InvalidRequestException;
|
||||
import no.nordicsemi.android.ble.exception.RequestFailedException;
|
||||
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public final class ConnectionPriorityRequest extends SimpleValueRequest<ConnectionPriorityCallback>
|
||||
implements Operation {
|
||||
|
||||
/**
|
||||
* Connection parameter update - Use the connection parameters recommended by the
|
||||
* Bluetooth SIG. This is the default value if no connection parameter update
|
||||
* is requested.
|
||||
* <p>
|
||||
* Interval: 30 - 50 ms, latency: 0, supervision timeout: 20 sec.
|
||||
*/
|
||||
public static final int CONNECTION_PRIORITY_BALANCED = 0;
|
||||
|
||||
/**
|
||||
* Connection parameter update - Request a high priority, low latency connection.
|
||||
* An application should only request high priority connection parameters to transfer
|
||||
* large amounts of data over LE quickly. Once the transfer is complete, the application
|
||||
* should request {@link #CONNECTION_PRIORITY_BALANCED} connection parameters
|
||||
* to reduce energy use.
|
||||
* <p>
|
||||
* Interval: 11.25 - 15 ms (Android 6+) or 7.5 - 10 ms (Android 4.3 - 5.1),
|
||||
* latency: 0, supervision timeout: 20 sec.
|
||||
*/
|
||||
public static final int CONNECTION_PRIORITY_HIGH = 1;
|
||||
|
||||
/**
|
||||
* Connection parameter update - Request low power, reduced data rate connection parameters.
|
||||
* <p>
|
||||
* Interval: 100 - 125 ms, latency: 2, supervision timeout: 20 sec.
|
||||
*/
|
||||
public static final int CONNECTION_PRIORITY_LOW_POWER = 2;
|
||||
|
||||
private final int value;
|
||||
|
||||
ConnectionPriorityRequest(@NonNull final Type type, @ConnectionPriority int priority) {
|
||||
super(type);
|
||||
if (priority < 0 || priority > 2)
|
||||
priority = CONNECTION_PRIORITY_BALANCED;
|
||||
this.value = priority;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
ConnectionPriorityRequest setManager(@NonNull final BleManager manager) {
|
||||
super.setManager(manager);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ConnectionPriorityRequest done(@NonNull final SuccessCallback callback) {
|
||||
super.done(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ConnectionPriorityRequest fail(@NonNull final FailCallback callback) {
|
||||
super.fail(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ConnectionPriorityRequest invalid(@NonNull final InvalidRequestCallback callback) {
|
||||
super.invalid(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ConnectionPriorityRequest before(@NonNull final BeforeCallback callback) {
|
||||
super.before(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@RequiresApi(value = Build.VERSION_CODES.O)
|
||||
@Override
|
||||
@NonNull
|
||||
public ConnectionPriorityRequest with(@NonNull final ConnectionPriorityCallback callback) {
|
||||
// The BluetoothGattCallback#onConnectionUpdated callback was introduced in Android Oreo.
|
||||
super.with(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@RequiresApi(value = Build.VERSION_CODES.O)
|
||||
@NonNull
|
||||
@Override
|
||||
public <E extends ConnectionPriorityCallback> E await(@NonNull final Class<E> responseClass)
|
||||
throws RequestFailedException, DeviceDisconnectedException, BluetoothDisabledException,
|
||||
InvalidRequestException {
|
||||
// The BluetoothGattCallback#onConnectionUpdated callback was introduced in Android Oreo.
|
||||
return super.await(responseClass);
|
||||
}
|
||||
|
||||
@RequiresApi(value = Build.VERSION_CODES.O)
|
||||
@NonNull
|
||||
@Override
|
||||
public <E extends ConnectionPriorityCallback> E await(@NonNull final E response)
|
||||
throws RequestFailedException, DeviceDisconnectedException, BluetoothDisabledException,
|
||||
InvalidRequestException {
|
||||
// The BluetoothGattCallback#onConnectionUpdated callback was introduced in Android Oreo.
|
||||
return super.await(response);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
void notifyConnectionPriorityChanged(@NonNull final BluetoothDevice device,
|
||||
@IntRange(from = 6, to = 3200) final int interval,
|
||||
@IntRange(from = 0, to = 499) final int latency,
|
||||
@IntRange(from = 10, to = 3200) final int timeout) {
|
||||
if (valueCallback != null)
|
||||
valueCallback.onConnectionUpdated(device, interval, latency, timeout);
|
||||
}
|
||||
|
||||
@ConnectionPriority
|
||||
int getRequiredPriority() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import no.nordicsemi.android.ble.callback.BeforeCallback;
|
||||
import no.nordicsemi.android.ble.callback.FailCallback;
|
||||
import no.nordicsemi.android.ble.callback.InvalidRequestCallback;
|
||||
import no.nordicsemi.android.ble.callback.SuccessCallback;
|
||||
|
||||
@SuppressWarnings({"WeakerAccess", "unused", "deprecation"})
|
||||
public class DisconnectRequest extends TimeoutableRequest {
|
||||
|
||||
DisconnectRequest(@NonNull final Type type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
DisconnectRequest setManager(@NonNull final BleManager manager) {
|
||||
super.setManager(manager);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public DisconnectRequest timeout(@IntRange(from = 0) final long timeout) {
|
||||
super.timeout(timeout);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public DisconnectRequest done(@NonNull final SuccessCallback callback) {
|
||||
super.done(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public DisconnectRequest fail(@NonNull final FailCallback callback) {
|
||||
super.fail(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public DisconnectRequest invalid(@NonNull final InvalidRequestCallback callback) {
|
||||
super.invalid(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public DisconnectRequest before(@NonNull final BeforeCallback callback) {
|
||||
super.before(callback);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCallback;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattDescriptor;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import no.nordicsemi.android.ble.annotation.ConnectionState;
|
||||
import no.nordicsemi.android.ble.annotation.PhyValue;
|
||||
|
||||
/**
|
||||
* This class ensures that the BLE callbacks will be called on the main (UI) thread.
|
||||
* Handler parameter was added to {@link android.bluetooth.BluetoothDevice
|
||||
* #connectGatt(Context, boolean, BluetoothGattCallback, int, int, Handler)}
|
||||
* in Android Oreo, before that the behavior was undefined.
|
||||
*/
|
||||
abstract class MainThreadBluetoothGattCallback extends BluetoothGattCallback {
|
||||
private Handler mHandler;
|
||||
|
||||
void setHandler(@NonNull final Handler handler) {
|
||||
mHandler = handler;
|
||||
}
|
||||
|
||||
private void runOnUiThread(@NonNull final Runnable runnable) {
|
||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
mHandler.post(runnable);
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
abstract void onConnectionStateChangeSafe(@NonNull final BluetoothGatt gatt, final int status,
|
||||
final int newState);
|
||||
abstract void onServicesDiscoveredSafe(@NonNull final BluetoothGatt gatt, final int status);
|
||||
abstract void onCharacteristicReadSafe(@NonNull final BluetoothGatt gatt,
|
||||
@NonNull final BluetoothGattCharacteristic characteristic,
|
||||
@Nullable final byte[] data,
|
||||
final int status);
|
||||
abstract void onCharacteristicWriteSafe(@NonNull final BluetoothGatt gatt,
|
||||
@NonNull final BluetoothGattCharacteristic characteristic,
|
||||
@Nullable final byte[] data,
|
||||
final int status);
|
||||
abstract void onCharacteristicChangedSafe(@NonNull final BluetoothGatt gatt,
|
||||
@NonNull final BluetoothGattCharacteristic characteristic,
|
||||
@Nullable final byte[] data);
|
||||
abstract void onDescriptorReadSafe(@NonNull final BluetoothGatt gatt,
|
||||
@NonNull final BluetoothGattDescriptor descriptor,
|
||||
@Nullable final byte[] data,
|
||||
final int status);
|
||||
abstract void onDescriptorWriteSafe(@NonNull final BluetoothGatt gatt,
|
||||
@NonNull final BluetoothGattDescriptor descriptor,
|
||||
@Nullable final byte[] data,
|
||||
final int status);
|
||||
abstract void onReadRemoteRssiSafe(@NonNull final BluetoothGatt gatt,
|
||||
@IntRange(from = -128, to = 20) final int rssi,
|
||||
final int status);
|
||||
abstract void onReliableWriteCompletedSafe(@NonNull final BluetoothGatt gatt, final int status);
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
abstract void onMtuChangedSafe(@NonNull final BluetoothGatt gatt,
|
||||
@IntRange(from = 23, to = 517) final int mtu, final int status);
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
abstract void onPhyReadSafe(@NonNull final BluetoothGatt gatt,
|
||||
@PhyValue final int txPhy, @PhyValue final int rxPhy, final int status);
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
abstract void onPhyUpdateSafe(@NonNull final BluetoothGatt gatt,
|
||||
@PhyValue final int txPhy, @PhyValue final int rxPhy, final int status);
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
abstract void onConnectionUpdatedSafe(@NonNull final BluetoothGatt gatt,
|
||||
@IntRange(from = 6, to = 3200) final int interval,
|
||||
@IntRange(from = 0, to = 499) final int latency,
|
||||
@IntRange(from = 10, to = 3200) final int timeout,
|
||||
final int status);
|
||||
|
||||
@Override
|
||||
public final void onConnectionStateChange(@NonNull final BluetoothGatt gatt, final int status,
|
||||
@ConnectionState final int newState) {
|
||||
runOnUiThread(() -> onConnectionStateChangeSafe(gatt, status, newState));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onServicesDiscovered(@NonNull final BluetoothGatt gatt, final int status) {
|
||||
runOnUiThread(() -> onServicesDiscoveredSafe(gatt, status));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onCharacteristicRead(@NonNull final BluetoothGatt gatt,
|
||||
@NonNull final BluetoothGattCharacteristic characteristic,
|
||||
final int status) {
|
||||
final byte[] data = characteristic.getValue();
|
||||
runOnUiThread(() -> onCharacteristicReadSafe(gatt, characteristic, data, status));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onCharacteristicWrite(@NonNull final BluetoothGatt gatt,
|
||||
@NonNull final BluetoothGattCharacteristic characteristic,
|
||||
final int status) {
|
||||
final byte[] data = characteristic.getValue();
|
||||
runOnUiThread(() -> onCharacteristicWriteSafe(gatt, characteristic, data, status));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onCharacteristicChanged(@NonNull final BluetoothGatt gatt,
|
||||
@NonNull final BluetoothGattCharacteristic characteristic) {
|
||||
final byte[] data = characteristic.getValue();
|
||||
runOnUiThread(() -> onCharacteristicChangedSafe(gatt, characteristic, data));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onDescriptorRead(@NonNull final BluetoothGatt gatt,
|
||||
@NonNull final BluetoothGattDescriptor descriptor,
|
||||
final int status) {
|
||||
final byte[] data = descriptor.getValue();
|
||||
runOnUiThread(() -> onDescriptorReadSafe(gatt, descriptor, data, status));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onDescriptorWrite(@NonNull final BluetoothGatt gatt,
|
||||
@NonNull final BluetoothGattDescriptor descriptor,
|
||||
final int status) {
|
||||
final byte[] data = descriptor.getValue();
|
||||
runOnUiThread(() -> onDescriptorWriteSafe(gatt, descriptor, data, status));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onReadRemoteRssi(@NonNull final BluetoothGatt gatt,
|
||||
@IntRange(from = -128, to = 20) final int rssi,
|
||||
final int status) {
|
||||
runOnUiThread(() -> onReadRemoteRssiSafe(gatt, rssi, status));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onReliableWriteCompleted(@NonNull final BluetoothGatt gatt, final int status) {
|
||||
runOnUiThread(() -> onReliableWriteCompletedSafe(gatt, status));
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public final void onMtuChanged(@NonNull final BluetoothGatt gatt,
|
||||
@IntRange(from = 23, to = 517) final int mtu, final int status) {
|
||||
runOnUiThread(() -> onMtuChangedSafe(gatt, mtu, status));
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
@Override
|
||||
public final void onPhyRead(@NonNull final BluetoothGatt gatt,
|
||||
@PhyValue final int txPhy, @PhyValue final int rxPhy,
|
||||
final int status) {
|
||||
runOnUiThread(() -> onPhyReadSafe(gatt, txPhy, rxPhy, status));
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
@Override
|
||||
public final void onPhyUpdate(@NonNull final BluetoothGatt gatt,
|
||||
@PhyValue final int txPhy, @PhyValue final int rxPhy,
|
||||
final int status) {
|
||||
runOnUiThread(() -> onPhyUpdateSafe(gatt, txPhy, rxPhy, status));
|
||||
}
|
||||
|
||||
// This method is hidden in Android Oreo and Pie
|
||||
// @Override
|
||||
@SuppressWarnings("unused")
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
@Keep
|
||||
public final void onConnectionUpdated(@NonNull final BluetoothGatt gatt,
|
||||
@IntRange(from = 6, to = 3200) final int interval,
|
||||
@IntRange(from = 0, to = 499) final int latency,
|
||||
@IntRange(from = 10, to = 3200) final int timeout,
|
||||
final int status) {
|
||||
runOnUiThread(() -> onConnectionUpdatedSafe(gatt, interval, latency, timeout, status));
|
||||
}
|
||||
}
|
||||
98
app/src/main/java/no/nordicsemi/android/ble/MtuRequest.java
Normal file
98
app/src/main/java/no/nordicsemi/android/ble/MtuRequest.java
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import no.nordicsemi.android.ble.callback.BeforeCallback;
|
||||
import no.nordicsemi.android.ble.callback.FailCallback;
|
||||
import no.nordicsemi.android.ble.callback.InvalidRequestCallback;
|
||||
import no.nordicsemi.android.ble.callback.MtuCallback;
|
||||
import no.nordicsemi.android.ble.callback.SuccessCallback;
|
||||
|
||||
public final class MtuRequest extends SimpleValueRequest<MtuCallback>implements Operation {
|
||||
private final int value;
|
||||
|
||||
MtuRequest(@NonNull final Type type, @IntRange(from = 23, to = 517) int mtu) {
|
||||
super(type);
|
||||
if (mtu < 23)
|
||||
mtu = 23;
|
||||
if (mtu > 517)
|
||||
mtu = 517;
|
||||
this.value = mtu;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
MtuRequest setManager(@NonNull final BleManager manager) {
|
||||
super.setManager(manager);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public MtuRequest done(@NonNull final SuccessCallback callback) {
|
||||
super.done(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public MtuRequest fail(@NonNull final FailCallback callback) {
|
||||
super.fail(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MtuRequest invalid(@NonNull final InvalidRequestCallback callback) {
|
||||
super.invalid(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public MtuRequest before(@NonNull final BeforeCallback callback) {
|
||||
super.before(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public MtuRequest with(@NonNull final MtuCallback callback) {
|
||||
super.with(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
void notifyMtuChanged(@NonNull final BluetoothDevice device,
|
||||
@IntRange(from = 23, to = 517) final int mtu) {
|
||||
if (valueCallback != null)
|
||||
valueCallback.onMtuChanged(device, mtu);
|
||||
}
|
||||
|
||||
int getRequiredMtu() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
32
app/src/main/java/no/nordicsemi/android/ble/Operation.java
Normal file
32
app/src/main/java/no/nordicsemi/android/ble/Operation.java
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
/**
|
||||
* An operation is a request that can be executed during a pending connection without
|
||||
* changing connection state. Such requests may be added to {@link RequestQueue}.
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public interface Operation {
|
||||
// empty
|
||||
}
|
||||
165
app/src/main/java/no/nordicsemi/android/ble/PhyRequest.java
Normal file
165
app/src/main/java/no/nordicsemi/android/ble/PhyRequest.java
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import no.nordicsemi.android.ble.annotation.PhyMask;
|
||||
import no.nordicsemi.android.ble.annotation.PhyOption;
|
||||
import no.nordicsemi.android.ble.annotation.PhyValue;
|
||||
import no.nordicsemi.android.ble.callback.BeforeCallback;
|
||||
import no.nordicsemi.android.ble.callback.FailCallback;
|
||||
import no.nordicsemi.android.ble.callback.InvalidRequestCallback;
|
||||
import no.nordicsemi.android.ble.callback.PhyCallback;
|
||||
import no.nordicsemi.android.ble.callback.SuccessCallback;
|
||||
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public final class PhyRequest extends SimpleValueRequest<PhyCallback> implements Operation {
|
||||
|
||||
/**
|
||||
* Bluetooth LE 1M PHY mask. Used to specify LE 1M Physical Channel as one of many available
|
||||
* options in a bitmask.
|
||||
*/
|
||||
public static final int PHY_LE_1M_MASK = 1;
|
||||
|
||||
/**
|
||||
* Bluetooth LE 2M PHY mask. Used to specify LE 2M Physical Channel as one of many available
|
||||
* options in a bitmask.
|
||||
*/
|
||||
public static final int PHY_LE_2M_MASK = 2;
|
||||
|
||||
/**
|
||||
* Bluetooth LE Coded PHY mask. Used to specify LE Coded Physical Channel as one of many
|
||||
* available options in a bitmask.
|
||||
*/
|
||||
public static final int PHY_LE_CODED_MASK = 4;
|
||||
|
||||
/**
|
||||
* No preferred coding when transmitting on the LE Coded PHY.
|
||||
*/
|
||||
public static final int PHY_OPTION_NO_PREFERRED = 0;
|
||||
|
||||
/**
|
||||
* Prefer the S=2 coding to be used when transmitting on the LE Coded PHY.
|
||||
*/
|
||||
public static final int PHY_OPTION_S2 = 1;
|
||||
|
||||
/**
|
||||
* Prefer the S=8 coding to be used when transmitting on the LE Coded PHY.
|
||||
*/
|
||||
public static final int PHY_OPTION_S8 = 2;
|
||||
|
||||
private final int txPhy;
|
||||
private final int rxPhy;
|
||||
private final int phyOptions;
|
||||
|
||||
PhyRequest(@NonNull final Type type) {
|
||||
super(type);
|
||||
this.txPhy = 0;
|
||||
this.rxPhy = 0;
|
||||
this.phyOptions = 0;
|
||||
}
|
||||
|
||||
PhyRequest(@NonNull final Type type,
|
||||
@PhyMask int txPhy, @PhyMask int rxPhy, @PhyOption int phyOptions) {
|
||||
super(type);
|
||||
if ((txPhy & ~(PHY_LE_1M_MASK | PHY_LE_2M_MASK | PHY_LE_CODED_MASK)) > 0)
|
||||
txPhy = PHY_LE_1M_MASK;
|
||||
if ((rxPhy & ~(PHY_LE_1M_MASK | PHY_LE_2M_MASK | PHY_LE_CODED_MASK)) > 0)
|
||||
rxPhy = PHY_LE_1M_MASK;
|
||||
if (phyOptions < PHY_OPTION_NO_PREFERRED || phyOptions > PHY_OPTION_S8)
|
||||
phyOptions = PHY_OPTION_NO_PREFERRED;
|
||||
this.txPhy = txPhy;
|
||||
this.rxPhy = rxPhy;
|
||||
this.phyOptions = phyOptions;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
PhyRequest setManager(@NonNull final BleManager manager) {
|
||||
super.setManager(manager);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public PhyRequest done(@NonNull final SuccessCallback callback) {
|
||||
super.done(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public PhyRequest fail(@NonNull final FailCallback callback) {
|
||||
super.fail(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public PhyRequest invalid(@NonNull final InvalidRequestCallback callback) {
|
||||
super.invalid(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public PhyRequest before(@NonNull final BeforeCallback callback) {
|
||||
super.before(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public PhyRequest with(@NonNull final PhyCallback callback) {
|
||||
super.with(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
void notifyPhyChanged(@NonNull final BluetoothDevice device,
|
||||
@PhyValue final int txPhy, @PhyValue final int rxPhy) {
|
||||
if (valueCallback != null)
|
||||
valueCallback.onPhyChanged(device, txPhy, rxPhy);
|
||||
}
|
||||
|
||||
void notifyLegacyPhy(@NonNull final BluetoothDevice device) {
|
||||
if (valueCallback != null)
|
||||
valueCallback.onPhyChanged(device, PhyCallback.PHY_LE_1M, PhyCallback.PHY_LE_1M);
|
||||
}
|
||||
|
||||
@PhyMask
|
||||
int getPreferredTxPhy() {
|
||||
return txPhy;
|
||||
}
|
||||
|
||||
@PhyMask
|
||||
int getPreferredRxPhy() {
|
||||
return rxPhy;
|
||||
}
|
||||
|
||||
@PhyOption
|
||||
int getPreferredPhyOptions() {
|
||||
return phyOptions;
|
||||
}
|
||||
}
|
||||
249
app/src/main/java/no/nordicsemi/android/ble/ReadRequest.java
Normal file
249
app/src/main/java/no/nordicsemi/android/ble/ReadRequest.java
Normal file
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattDescriptor;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.callback.BeforeCallback;
|
||||
import no.nordicsemi.android.ble.callback.DataReceivedCallback;
|
||||
import no.nordicsemi.android.ble.callback.FailCallback;
|
||||
import no.nordicsemi.android.ble.callback.InvalidRequestCallback;
|
||||
import no.nordicsemi.android.ble.callback.ReadProgressCallback;
|
||||
import no.nordicsemi.android.ble.callback.SuccessCallback;
|
||||
import no.nordicsemi.android.ble.callback.profile.ProfileReadResponse;
|
||||
import no.nordicsemi.android.ble.data.Data;
|
||||
import no.nordicsemi.android.ble.data.DataFilter;
|
||||
import no.nordicsemi.android.ble.data.DataMerger;
|
||||
import no.nordicsemi.android.ble.data.DataStream;
|
||||
import no.nordicsemi.android.ble.exception.BluetoothDisabledException;
|
||||
import no.nordicsemi.android.ble.exception.DeviceDisconnectedException;
|
||||
import no.nordicsemi.android.ble.exception.InvalidDataException;
|
||||
import no.nordicsemi.android.ble.exception.InvalidRequestException;
|
||||
import no.nordicsemi.android.ble.exception.RequestFailedException;
|
||||
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public final class ReadRequest extends SimpleValueRequest<DataReceivedCallback> implements Operation {
|
||||
private ReadProgressCallback progressCallback;
|
||||
private DataMerger dataMerger;
|
||||
private DataStream buffer;
|
||||
private DataFilter filter;
|
||||
private int count = 0;
|
||||
|
||||
ReadRequest(@NonNull final Type type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
ReadRequest(@NonNull final Type type, @Nullable final BluetoothGattCharacteristic characteristic) {
|
||||
super(type, characteristic);
|
||||
}
|
||||
|
||||
ReadRequest(@NonNull final Type type, @Nullable final BluetoothGattDescriptor descriptor) {
|
||||
super(type, descriptor);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
ReadRequest setManager(@NonNull final BleManager manager) {
|
||||
super.setManager(manager);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ReadRequest done(@NonNull final SuccessCallback callback) {
|
||||
super.done(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ReadRequest fail(@NonNull final FailCallback callback) {
|
||||
super.fail(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ReadRequest invalid(@NonNull final InvalidRequestCallback callback) {
|
||||
super.invalid(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ReadRequest before(@NonNull final BeforeCallback callback) {
|
||||
super.before(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ReadRequest with(@NonNull final DataReceivedCallback callback) {
|
||||
super.with(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a filter which allows to skip some incoming data.
|
||||
*
|
||||
* @param filter the data filter.
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public ReadRequest filter(@NonNull final DataFilter filter) {
|
||||
this.filter = filter;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a merger that will be used to merge multiple packets into a single Data.
|
||||
* The merger may modify each packet if necessary.
|
||||
*
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public ReadRequest merge(@NonNull final DataMerger merger) {
|
||||
this.dataMerger = merger;
|
||||
this.progressCallback = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a merger that will be used to merge multiple packets into a single Data.
|
||||
* The merger may modify each packet if necessary.
|
||||
*
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public ReadRequest merge(@NonNull final DataMerger merger,
|
||||
@NonNull final ReadProgressCallback callback) {
|
||||
this.dataMerger = merger;
|
||||
this.progressCallback = callback;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #await(Class)}, but if the response class extends
|
||||
* {@link ProfileReadResponse} and the received response is not valid
|
||||
* ({@link ProfileReadResponse#isValid()} returns false), this method will
|
||||
* throw an exception.
|
||||
*
|
||||
* @param responseClass the response class. This class will be instantiate, therefore it
|
||||
* has to have a default constructor.
|
||||
* @return The object with the response.
|
||||
* @throws RequestFailedException thrown when the BLE request finished with status other
|
||||
* than {@link BluetoothGatt#GATT_SUCCESS}.
|
||||
* @throws IllegalStateException thrown when you try to call this method from the main
|
||||
* (UI) thread.
|
||||
* @throws IllegalArgumentException thrown when the response class could not be instantiated.
|
||||
* @throws DeviceDisconnectedException thrown when the device disconnected before the request
|
||||
* was completed.
|
||||
* @throws BluetoothDisabledException thrown when the Bluetooth adapter has been disabled.
|
||||
* @throws InvalidDataException thrown when the received data were not valid (that is when
|
||||
* {@link ProfileReadResponse#onDataReceived(BluetoothDevice, Data)}
|
||||
* failed to parse the data correctly and called
|
||||
* {@link ProfileReadResponse#onInvalidDataReceived(BluetoothDevice, Data)}).
|
||||
* @throws InvalidRequestException thrown when the request was called before the device was
|
||||
* connected at least once (unknown device).
|
||||
*/
|
||||
@NonNull
|
||||
public <E extends ProfileReadResponse> E awaitValid(@NonNull final Class<E> responseClass)
|
||||
throws RequestFailedException, InvalidDataException, DeviceDisconnectedException,
|
||||
BluetoothDisabledException, InvalidRequestException {
|
||||
final E response = await(responseClass);
|
||||
if (!response.isValid()) {
|
||||
throw new InvalidDataException(response);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #await(Object)}, but if the response class extends
|
||||
* {@link ProfileReadResponse} and the received response is not valid
|
||||
* ({@link ProfileReadResponse#isValid()} returns false), this method will
|
||||
* throw an exception.
|
||||
*
|
||||
* @param response the response object.
|
||||
* @return The object with the response.
|
||||
* @throws RequestFailedException thrown when the BLE request finished with status other
|
||||
* than {@link BluetoothGatt#GATT_SUCCESS}.
|
||||
* @throws IllegalStateException thrown when you try to call this method from the main
|
||||
* (UI) thread.
|
||||
* @throws DeviceDisconnectedException thrown when the device disconnected before the request
|
||||
* was completed.
|
||||
* @throws BluetoothDisabledException thrown when the Bluetooth adapter has been disabled.
|
||||
* @throws InvalidDataException thrown when the received data were not valid (that is when
|
||||
* {@link ProfileReadResponse#onDataReceived(BluetoothDevice, Data)}
|
||||
* failed to parse the data correctly and called
|
||||
* {@link ProfileReadResponse#onInvalidDataReceived(BluetoothDevice, Data)}).
|
||||
* @throws InvalidRequestException thrown when the request was called before the device was
|
||||
* connected at least once (unknown device).
|
||||
*/
|
||||
@NonNull
|
||||
public <E extends ProfileReadResponse> E awaitValid(@NonNull final E response)
|
||||
throws RequestFailedException, InvalidDataException, DeviceDisconnectedException,
|
||||
BluetoothDisabledException, InvalidRequestException {
|
||||
await(response);
|
||||
if (!response.isValid()) {
|
||||
throw new InvalidDataException(response);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
boolean matches(final byte[] packet) {
|
||||
return filter == null || filter.filter(packet);
|
||||
}
|
||||
|
||||
void notifyValueChanged(@NonNull final BluetoothDevice device, @Nullable final byte[] value) {
|
||||
// Keep a reference to the value callback, as it may change during execution
|
||||
final DataReceivedCallback valueCallback = this.valueCallback;
|
||||
|
||||
// With no value callback there is no need for any merging
|
||||
if (valueCallback == null)
|
||||
return;
|
||||
|
||||
if (dataMerger == null) {
|
||||
valueCallback.onDataReceived(device, new Data(value));
|
||||
} else {
|
||||
if (progressCallback != null)
|
||||
progressCallback.onPacketReceived(device, value, count);
|
||||
if (buffer == null)
|
||||
buffer = new DataStream();
|
||||
if (dataMerger.merge(buffer, value, count++)) {
|
||||
valueCallback.onDataReceived(device, buffer.toData());
|
||||
buffer = null;
|
||||
count = 0;
|
||||
} // else
|
||||
// wait for more packets to be merged
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasMore() {
|
||||
return count > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import no.nordicsemi.android.ble.callback.BeforeCallback;
|
||||
import no.nordicsemi.android.ble.callback.FailCallback;
|
||||
import no.nordicsemi.android.ble.callback.InvalidRequestCallback;
|
||||
import no.nordicsemi.android.ble.callback.RssiCallback;
|
||||
import no.nordicsemi.android.ble.callback.SuccessCallback;
|
||||
|
||||
public final class ReadRssiRequest extends SimpleValueRequest<RssiCallback> implements Operation {
|
||||
|
||||
ReadRssiRequest(@NonNull final Type type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
ReadRssiRequest setManager(@NonNull final BleManager manager) {
|
||||
super.setManager(manager);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ReadRssiRequest done(@NonNull final SuccessCallback callback) {
|
||||
super.done(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ReadRssiRequest fail(@NonNull final FailCallback callback) {
|
||||
super.fail(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ReadRssiRequest invalid(@NonNull final InvalidRequestCallback callback) {
|
||||
super.invalid(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ReadRssiRequest before(@NonNull final BeforeCallback callback) {
|
||||
super.before(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ReadRssiRequest with(@NonNull final RssiCallback callback) {
|
||||
super.with(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
void notifyRssiRead(@NonNull final BluetoothDevice device,
|
||||
@IntRange(from = -128, to = 20) final int rssi) {
|
||||
if (valueCallback != null)
|
||||
valueCallback.onRssiRead(device, rssi);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import no.nordicsemi.android.ble.callback.BeforeCallback;
|
||||
import no.nordicsemi.android.ble.callback.FailCallback;
|
||||
import no.nordicsemi.android.ble.callback.InvalidRequestCallback;
|
||||
import no.nordicsemi.android.ble.callback.SuccessCallback;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class ReliableWriteRequest extends RequestQueue {
|
||||
private boolean initialized;
|
||||
private boolean closed;
|
||||
private boolean cancelled;
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
ReliableWriteRequest setManager(@NonNull final BleManager manager) {
|
||||
super.setManager(manager);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ReliableWriteRequest done(@NonNull final SuccessCallback callback) {
|
||||
super.done(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ReliableWriteRequest fail(@NonNull final FailCallback callback) {
|
||||
super.fail(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ReliableWriteRequest invalid(@NonNull final InvalidRequestCallback callback) {
|
||||
super.invalid(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public ReliableWriteRequest before(@NonNull final BeforeCallback callback) {
|
||||
super.before(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ReliableWriteRequest add(@NonNull final Operation operation) {
|
||||
super.add(operation);
|
||||
// Make sure the write request uses splitting, as Long Write is not supported
|
||||
// in Reliable Write sub-procedure.
|
||||
if (operation instanceof WriteRequest) {
|
||||
((WriteRequest) operation).forceSplit();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelQueue() {
|
||||
cancelled = true;
|
||||
super.cancelQueue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for {@link #cancelQueue()}.
|
||||
*/
|
||||
public void abort() {
|
||||
cancelQueue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
int size = super.size();
|
||||
|
||||
// Add Begin Reliable Write
|
||||
if (!initialized)
|
||||
size += 1;
|
||||
|
||||
// Add Execute or Abort Reliable Write
|
||||
if (!closed)
|
||||
size += 1;
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
Request getNext() {
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
return newBeginReliableWriteRequest();
|
||||
}
|
||||
if (super.isEmpty()) {
|
||||
closed = true;
|
||||
|
||||
if (cancelled)
|
||||
return newAbortReliableWriteRequest();
|
||||
return newExecuteReliableWriteRequest();
|
||||
}
|
||||
return super.getNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean hasMore() {
|
||||
// If no operations were added, consider the RW request empty, no requests will be executed.
|
||||
if (!initialized)
|
||||
return super.hasMore();
|
||||
return !closed;
|
||||
}
|
||||
}
|
||||
896
app/src/main/java/no/nordicsemi/android/ble/Request.java
Normal file
896
app/src/main/java/no/nordicsemi/android/ble/Request.java
Normal file
@@ -0,0 +1,896 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCallback;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattDescriptor;
|
||||
import android.os.ConditionVariable;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.annotation.ConnectionPriority;
|
||||
import no.nordicsemi.android.ble.annotation.PhyMask;
|
||||
import no.nordicsemi.android.ble.annotation.PhyOption;
|
||||
import no.nordicsemi.android.ble.annotation.WriteType;
|
||||
import no.nordicsemi.android.ble.callback.BeforeCallback;
|
||||
import no.nordicsemi.android.ble.callback.FailCallback;
|
||||
import no.nordicsemi.android.ble.callback.InvalidRequestCallback;
|
||||
import no.nordicsemi.android.ble.callback.SuccessCallback;
|
||||
import no.nordicsemi.android.ble.data.Data;
|
||||
|
||||
/**
|
||||
* On Android, when multiple BLE operations needs to be done, it is required to wait for a proper
|
||||
* {@link BluetoothGattCallback} callback before calling another operation.
|
||||
* In order to make BLE operations easier the BleManager allows to enqueue a request containing all
|
||||
* data necessary for a given operation. Requests are performed one after another until the queue
|
||||
* is empty.
|
||||
*/
|
||||
@SuppressWarnings({"unused", "WeakerAccess", "deprecation", "DeprecatedIsStillUsed"})
|
||||
public abstract class Request {
|
||||
|
||||
enum Type {
|
||||
SET,
|
||||
CONNECT,
|
||||
DISCONNECT,
|
||||
CREATE_BOND,
|
||||
REMOVE_BOND,
|
||||
WRITE,
|
||||
READ,
|
||||
WRITE_DESCRIPTOR,
|
||||
READ_DESCRIPTOR,
|
||||
BEGIN_RELIABLE_WRITE,
|
||||
EXECUTE_RELIABLE_WRITE,
|
||||
ABORT_RELIABLE_WRITE,
|
||||
ENABLE_NOTIFICATIONS,
|
||||
ENABLE_INDICATIONS,
|
||||
DISABLE_NOTIFICATIONS,
|
||||
DISABLE_INDICATIONS,
|
||||
WAIT_FOR_NOTIFICATION,
|
||||
WAIT_FOR_INDICATION,
|
||||
@Deprecated
|
||||
READ_BATTERY_LEVEL,
|
||||
@Deprecated
|
||||
ENABLE_BATTERY_LEVEL_NOTIFICATIONS,
|
||||
@Deprecated
|
||||
DISABLE_BATTERY_LEVEL_NOTIFICATIONS,
|
||||
ENABLE_SERVICE_CHANGED_INDICATIONS,
|
||||
REQUEST_MTU,
|
||||
REQUEST_CONNECTION_PRIORITY,
|
||||
SET_PREFERRED_PHY,
|
||||
READ_PHY,
|
||||
READ_RSSI,
|
||||
REFRESH_CACHE,
|
||||
SLEEP,
|
||||
}
|
||||
|
||||
private BleManager manager;
|
||||
|
||||
final ConditionVariable syncLock;
|
||||
final Type type;
|
||||
final BluetoothGattCharacteristic characteristic;
|
||||
final BluetoothGattDescriptor descriptor;
|
||||
BeforeCallback beforeCallback;
|
||||
SuccessCallback successCallback;
|
||||
FailCallback failCallback;
|
||||
InvalidRequestCallback invalidRequestCallback;
|
||||
BeforeCallback internalBeforeCallback;
|
||||
SuccessCallback internalSuccessCallback;
|
||||
FailCallback internalFailCallback;
|
||||
boolean enqueued;
|
||||
boolean finished;
|
||||
|
||||
Request(@NonNull final Type type) {
|
||||
this.type = type;
|
||||
this.characteristic = null;
|
||||
this.descriptor = null;
|
||||
this.syncLock = new ConditionVariable(true);
|
||||
}
|
||||
|
||||
Request(@NonNull final Type type, @Nullable final BluetoothGattCharacteristic characteristic) {
|
||||
this.type = type;
|
||||
this.characteristic = characteristic;
|
||||
this.descriptor = null;
|
||||
this.syncLock = new ConditionVariable(true);
|
||||
}
|
||||
|
||||
Request(@NonNull final Type type, @Nullable final BluetoothGattDescriptor descriptor) {
|
||||
this.type = type;
|
||||
this.characteristic = null;
|
||||
this.descriptor = descriptor;
|
||||
this.syncLock = new ConditionVariable(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link BleManager} instance.
|
||||
*
|
||||
* @param manager the manager in which the request will be executed.
|
||||
*/
|
||||
@NonNull
|
||||
Request setManager(@NonNull final BleManager manager) {
|
||||
this.manager = manager;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new connect request. This allows to set a callback to the connect event,
|
||||
* just like any other request.
|
||||
*
|
||||
* @param device the device to connect to.
|
||||
* @return The new connect request.
|
||||
*/
|
||||
@NonNull
|
||||
static ConnectRequest connect(@NonNull final BluetoothDevice device) {
|
||||
return new ConnectRequest(Type.CONNECT, device);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new disconnect request. This allows to set a callback to a disconnect event,
|
||||
* just like any other request.
|
||||
*
|
||||
* @return The new disconnect request.
|
||||
*/
|
||||
@NonNull
|
||||
static DisconnectRequest disconnect() {
|
||||
return new DisconnectRequest(Type.DISCONNECT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new request that will start pairing with the device.
|
||||
*
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#createBond()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static SimpleRequest createBond() {
|
||||
return new SimpleRequest(Type.CREATE_BOND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new request that will remove the bonding information from the Android device.
|
||||
* This is done using reflections and may not work on all devices.
|
||||
* <p>
|
||||
* The device will disconnect after calling this method. The success callback will be called
|
||||
* after the device got disconnected, when the {@link BluetoothDevice#getBondState()} changes
|
||||
* to {@link BluetoothDevice#BOND_NONE}.
|
||||
*
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#removeBond()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static SimpleRequest removeBond() {
|
||||
return new SimpleRequest(Type.REMOVE_BOND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Read Characteristic request. The request will not be executed if given
|
||||
* characteristic is null or does not have READ property.
|
||||
* After the operation is complete a proper callback will be invoked.
|
||||
*
|
||||
* @param characteristic characteristic to be read.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#readCharacteristic(BluetoothGattCharacteristic)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static ReadRequest newReadRequest(
|
||||
@Nullable final BluetoothGattCharacteristic characteristic) {
|
||||
return new ReadRequest(Type.READ, characteristic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Write Characteristic request. The request will not be executed if given
|
||||
* characteristic is null or does not have WRITE property.
|
||||
* After the operation is complete a proper callback will be invoked.
|
||||
*
|
||||
* @param characteristic characteristic to be written.
|
||||
* @param value value to be written. The array is copied into another buffer so it's
|
||||
* safe to reuse the array again.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#writeCharacteristic(BluetoothGattCharacteristic, byte[])} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static WriteRequest newWriteRequest(
|
||||
@Nullable final BluetoothGattCharacteristic characteristic,
|
||||
@Nullable final byte[] value) {
|
||||
return new WriteRequest(Type.WRITE, characteristic, value, 0,
|
||||
value != null ? value.length : 0,
|
||||
characteristic != null ?
|
||||
characteristic.getWriteType() :
|
||||
BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Write Characteristic request. The request will not be executed if given
|
||||
* characteristic is null or does not have WRITE property.
|
||||
* After the operation is complete a proper callback will be invoked.
|
||||
*
|
||||
* @param characteristic characteristic to be written.
|
||||
* @param value value to be written. The array is copied into another buffer so it's
|
||||
* safe to reuse the array again.
|
||||
* @param writeType write type to be used, one of
|
||||
* {@link BluetoothGattCharacteristic#WRITE_TYPE_DEFAULT},
|
||||
* {@link BluetoothGattCharacteristic#WRITE_TYPE_NO_RESPONSE}.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#writeCharacteristic(BluetoothGattCharacteristic, Data)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static WriteRequest newWriteRequest(
|
||||
@Nullable final BluetoothGattCharacteristic characteristic,
|
||||
@Nullable final byte[] value, @WriteType final int writeType) {
|
||||
return new WriteRequest(Type.WRITE, characteristic, value, 0,
|
||||
value != null ? value.length : 0, writeType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Write Characteristic request. The request will not be executed if given
|
||||
* characteristic is null or does not have WRITE property.
|
||||
* After the operation is complete a proper callback will be invoked.
|
||||
*
|
||||
* @param characteristic characteristic to be written.
|
||||
* @param value value to be written. The array is copied into another buffer so it's
|
||||
* safe to reuse the array again.
|
||||
* @param offset the offset from which value has to be copied.
|
||||
* @param length number of bytes to be copied from the value buffer.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#writeCharacteristic(BluetoothGattCharacteristic, byte[], int, int)}
|
||||
* instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static WriteRequest newWriteRequest(
|
||||
@Nullable final BluetoothGattCharacteristic characteristic,
|
||||
@Nullable final byte[] value,
|
||||
@IntRange(from = 0) final int offset, @IntRange(from = 0) final int length) {
|
||||
return new WriteRequest(Type.WRITE, characteristic, value, offset, length,
|
||||
characteristic != null ?
|
||||
characteristic.getWriteType() :
|
||||
BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Write Characteristic request. The request will not be executed if given
|
||||
* characteristic is null or does not have WRITE property.
|
||||
* After the operation is complete a proper callback will be invoked.
|
||||
*
|
||||
* @param characteristic characteristic to be written.
|
||||
* @param value value to be written. The array is copied into another buffer so it's
|
||||
* safe to reuse the array again.
|
||||
* @param offset the offset from which value has to be copied.
|
||||
* @param length number of bytes to be copied from the value buffer.
|
||||
* @param writeType write type to be used, one of
|
||||
* {@link BluetoothGattCharacteristic#WRITE_TYPE_DEFAULT},
|
||||
* {@link BluetoothGattCharacteristic#WRITE_TYPE_NO_RESPONSE} or
|
||||
* {@link BluetoothGattCharacteristic#WRITE_TYPE_SIGNED}.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#writeCharacteristic(BluetoothGattCharacteristic, byte[], int, int)}
|
||||
* instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static WriteRequest newWriteRequest(
|
||||
@Nullable final BluetoothGattCharacteristic characteristic,
|
||||
@Nullable final byte[] value,
|
||||
@IntRange(from = 0) final int offset, @IntRange(from = 0) final int length,
|
||||
@WriteType final int writeType) {
|
||||
return new WriteRequest(Type.WRITE, characteristic, value, offset, length, writeType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Read Descriptor request. The request will not be executed if given descriptor
|
||||
* is null. After the operation is complete a proper callback will be invoked.
|
||||
*
|
||||
* @param descriptor descriptor to be read.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#readDescriptor(BluetoothGattDescriptor)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static ReadRequest newReadRequest(@Nullable final BluetoothGattDescriptor descriptor) {
|
||||
return new ReadRequest(Type.READ_DESCRIPTOR, descriptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Write Descriptor request. The request will not be executed if given descriptor
|
||||
* is null. After the operation is complete a proper callback will be invoked.
|
||||
*
|
||||
* @param descriptor descriptor to be written.
|
||||
* @param value value to be written. The array is copied into another buffer so it's safe
|
||||
* to reuse the array again.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#writeDescriptor(BluetoothGattDescriptor, byte[])} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static WriteRequest newWriteRequest(@Nullable final BluetoothGattDescriptor descriptor,
|
||||
@Nullable final byte[] value) {
|
||||
return new WriteRequest(Type.WRITE_DESCRIPTOR, descriptor, value, 0,
|
||||
value != null ? value.length : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Write Descriptor request. The request will not be executed if given descriptor
|
||||
* is null. After the operation is complete a proper callback will be invoked.
|
||||
*
|
||||
* @param descriptor descriptor to be written.
|
||||
* @param value value to be written. The array is copied into another buffer so it's safe
|
||||
* to reuse the array again.
|
||||
* @param offset the offset from which value has to be copied.
|
||||
* @param length number of bytes to be copied from the value buffer.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#writeDescriptor(BluetoothGattDescriptor, byte[], int, int)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static WriteRequest newWriteRequest(
|
||||
@Nullable final BluetoothGattDescriptor descriptor,
|
||||
@Nullable final byte[] value,
|
||||
@IntRange(from = 0) final int offset, @IntRange(from = 0) final int length) {
|
||||
return new WriteRequest(Type.WRITE_DESCRIPTOR, descriptor, value, offset, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Reliable Write request. All operations that need to be executed
|
||||
* reliably should be enqueued inside the returned request before enqueuing it in the
|
||||
* BleManager. The library will automatically verify the data sent
|
||||
*
|
||||
* @return The new request.
|
||||
*/
|
||||
@NonNull
|
||||
static ReliableWriteRequest newReliableWriteRequest() {
|
||||
return new ReliableWriteRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Begin Reliable Write request.
|
||||
*
|
||||
* @return The new request.
|
||||
*/
|
||||
@NonNull
|
||||
static SimpleRequest newBeginReliableWriteRequest() {
|
||||
return new SimpleRequest(Type.BEGIN_RELIABLE_WRITE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes Reliable Write sub-procedure. At lease one Write Request must be performed
|
||||
* before the Reliable Write is to be executed, otherwise error
|
||||
* {@link no.nordicsemi.android.ble.error.GattError#GATT_INVALID_OFFSET} will be returned.
|
||||
*
|
||||
* @return The new request.
|
||||
*/
|
||||
@NonNull
|
||||
static SimpleRequest newExecuteReliableWriteRequest() {
|
||||
return new SimpleRequest(Type.EXECUTE_RELIABLE_WRITE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Aborts Reliable Write sub-procedure. All write requests performed during Reliable Write will
|
||||
* be cancelled. At lease one Write Request must be performed before the Reliable Write
|
||||
* is to be executed, otherwise error
|
||||
* {@link no.nordicsemi.android.ble.error.GattError#GATT_INVALID_OFFSET} will be returned.
|
||||
*
|
||||
* @return The new request.
|
||||
*/
|
||||
@NonNull
|
||||
static SimpleRequest newAbortReliableWriteRequest() {
|
||||
return new SimpleRequest(Type.ABORT_RELIABLE_WRITE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Enable Notification request. The request will not be executed if given
|
||||
* characteristic is null, does not have NOTIFY property or the CCCD.
|
||||
* After the operation is complete a proper callback will be invoked.
|
||||
*
|
||||
* @param characteristic characteristic to have notifications enabled.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#enableNotifications(BluetoothGattCharacteristic)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static WriteRequest newEnableNotificationsRequest(
|
||||
@Nullable final BluetoothGattCharacteristic characteristic) {
|
||||
return new WriteRequest(Type.ENABLE_NOTIFICATIONS, characteristic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Disable Notification request. The request will not be executed if given
|
||||
* characteristic is null, does not have NOTIFY property or the CCCD.
|
||||
* After the operation is complete a proper callback will be invoked.
|
||||
*
|
||||
* @param characteristic characteristic to have notifications disabled.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#disableNotifications(BluetoothGattCharacteristic)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static WriteRequest newDisableNotificationsRequest(
|
||||
@Nullable final BluetoothGattCharacteristic characteristic) {
|
||||
return new WriteRequest(Type.DISABLE_NOTIFICATIONS, characteristic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Enable Indications request. The request will not be executed if given
|
||||
* characteristic is null, does not have INDICATE property or the CCCD.
|
||||
* After the operation is complete a proper callback will be invoked.
|
||||
*
|
||||
* @param characteristic characteristic to have indications enabled.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#enableIndications(BluetoothGattCharacteristic)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static WriteRequest newEnableIndicationsRequest(
|
||||
@Nullable final BluetoothGattCharacteristic characteristic) {
|
||||
return new WriteRequest(Type.ENABLE_INDICATIONS, characteristic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Disable Indications request. The request will not be executed if given
|
||||
* characteristic is null, does not have INDICATE property or the CCCD.
|
||||
* After the operation is complete a proper callback will be invoked.
|
||||
*
|
||||
* @param characteristic characteristic to have indications disabled.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#disableNotifications(BluetoothGattCharacteristic)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static WriteRequest newDisableIndicationsRequest(
|
||||
@Nullable final BluetoothGattCharacteristic characteristic) {
|
||||
return new WriteRequest(Type.DISABLE_INDICATIONS, characteristic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Wait For Notification request. The request will not be executed if given
|
||||
* characteristic is null, does not have NOTIFY property or the CCCD.
|
||||
* After the operation is complete a proper callback will be invoked.
|
||||
* <p>
|
||||
* If the notification should be triggered by another operation (for example writing an
|
||||
* op code), set it with {@link WaitForValueChangedRequest#trigger(Operation)}.
|
||||
*
|
||||
* @param characteristic characteristic from which a notification should be received.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#waitForNotification(BluetoothGattCharacteristic)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static WaitForValueChangedRequest newWaitForNotificationRequest(
|
||||
@Nullable final BluetoothGattCharacteristic characteristic) {
|
||||
return new WaitForValueChangedRequest(Type.WAIT_FOR_NOTIFICATION, characteristic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Wait For Indication request. The request will not be executed if given
|
||||
* characteristic is null, does not have INDICATE property or the CCCD.
|
||||
* After the operation is complete a proper callback will be invoked.
|
||||
* <p>
|
||||
* If the indication should be triggered by another operation (for example writing an
|
||||
* op code), set it with {@link WaitForValueChangedRequest#trigger(Operation)}.
|
||||
*
|
||||
* @param characteristic characteristic from which a notification should be received.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#waitForIndication(BluetoothGattCharacteristic)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static WaitForValueChangedRequest newWaitForIndicationRequest(
|
||||
@Nullable final BluetoothGattCharacteristic characteristic) {
|
||||
return new WaitForValueChangedRequest(Type.WAIT_FOR_INDICATION, characteristic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Read Battery Level request. The first found Battery Level characteristic value
|
||||
* from the first found Battery Service. If any of them is not found, or the characteristic
|
||||
* does not have the READ property this operation will not execute.
|
||||
*
|
||||
* @return The new request.
|
||||
* @deprecated Use {@link #newReadRequest(BluetoothGattCharacteristic)} with
|
||||
* BatteryLevelDataCallback from Android BLE Common Library instead.
|
||||
*/
|
||||
@NonNull
|
||||
@Deprecated
|
||||
public static ReadRequest newReadBatteryLevelRequest() {
|
||||
return new ReadRequest(Type.READ_BATTERY_LEVEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Enable Notifications on the first found Battery Level characteristic from the
|
||||
* first found Battery Service. If any of them is not found, or the characteristic does not
|
||||
* have the NOTIFY property this operation will not execute.
|
||||
*
|
||||
* @return The new request.
|
||||
* @deprecated Use {@link #newEnableNotificationsRequest(BluetoothGattCharacteristic)} with
|
||||
* BatteryLevelDataCallback from Android BLE Common Library instead.
|
||||
*/
|
||||
@NonNull
|
||||
@Deprecated
|
||||
public static WriteRequest newEnableBatteryLevelNotificationsRequest() {
|
||||
return new WriteRequest(Type.ENABLE_BATTERY_LEVEL_NOTIFICATIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Disable Notifications on the first found Battery Level characteristic from the
|
||||
* first found Battery Service. If any of them is not found, or the characteristic does not
|
||||
* have the NOTIFY property this operation will not execute.
|
||||
*
|
||||
* @return The new request.
|
||||
* @deprecated Use {@link #newDisableNotificationsRequest(BluetoothGattCharacteristic)} instead.
|
||||
*/
|
||||
@NonNull
|
||||
@Deprecated
|
||||
public static WriteRequest newDisableBatteryLevelNotificationsRequest() {
|
||||
return new WriteRequest(Type.DISABLE_BATTERY_LEVEL_NOTIFICATIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Enable Indications on Service Changed characteristic. It is a NOOP if such
|
||||
* characteristic does not exist in the Generic Attribute service.
|
||||
* It is required to enable those notifications on bonded devices on older Android versions to
|
||||
* be informed about attributes changes.
|
||||
* Android 7+ (or 6+) handles this automatically and no action is required.
|
||||
*
|
||||
* @return The new request.
|
||||
*/
|
||||
@NonNull
|
||||
static WriteRequest newEnableServiceChangedIndicationsRequest() {
|
||||
return new WriteRequest(Type.ENABLE_SERVICE_CHANGED_INDICATIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests new MTU (Maximum Transfer Unit). This is only supported on Android Lollipop or newer.
|
||||
* On older platforms the request will enqueue, but will fail to execute and
|
||||
* {@link #fail(FailCallback)} callback will be called.
|
||||
* The target device may reject requested value and set a smaller MTU.
|
||||
*
|
||||
* @param mtu the new MTU. Acceptable values are <23, 517>.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#requestMtu(int)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static MtuRequest newMtuRequest(@IntRange(from = 23, to = 517) final int mtu) {
|
||||
return new MtuRequest(Type.REQUEST_MTU, mtu);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests the new connection priority. Acceptable values are:
|
||||
* <ol>
|
||||
* <li>{@link ConnectionPriorityRequest#CONNECTION_PRIORITY_HIGH}
|
||||
* - Interval: 11.25 -15 ms (Android 6+) and 7.5 - 10 ms (older), latency: 0,
|
||||
* supervision timeout: 20 sec,</li>
|
||||
* <li>{@link ConnectionPriorityRequest#CONNECTION_PRIORITY_BALANCED}
|
||||
* - Interval: 30 - 50 ms, latency: 0, supervision timeout: 20 sec,</li>
|
||||
* <li>{@link ConnectionPriorityRequest#CONNECTION_PRIORITY_LOW_POWER}
|
||||
* - Interval: 100 - 125 ms, latency: 2, supervision timeout: 20 sec.</li>
|
||||
* </ol>
|
||||
* Requesting connection priority is available on Android Lollipop or newer. On older
|
||||
* platforms the request will enqueue, but will fail to execute and {@link #fail(FailCallback)}
|
||||
* callback will be called.
|
||||
*
|
||||
* @param priority one of: {@link ConnectionPriorityRequest#CONNECTION_PRIORITY_HIGH},
|
||||
* {@link ConnectionPriorityRequest#CONNECTION_PRIORITY_BALANCED},
|
||||
* {@link ConnectionPriorityRequest#CONNECTION_PRIORITY_LOW_POWER}.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#requestConnectionPriority(int)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static ConnectionPriorityRequest newConnectionPriorityRequest(
|
||||
@ConnectionPriority final int priority) {
|
||||
return new ConnectionPriorityRequest(Type.REQUEST_CONNECTION_PRIORITY, priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests the change of preferred PHY for this connections.
|
||||
* <p>
|
||||
* PHY LE 2M and PHY LE Coded are supported only on Android Oreo or newer.
|
||||
* You may safely request other PHYs on older platforms, but the request will not be executed
|
||||
* and you will get PHY LE 1M as TX and RX PHY in the callback.
|
||||
*
|
||||
* @param txPhy preferred transmitter PHY. Bitwise OR of any of
|
||||
* {@link PhyRequest#PHY_LE_1M_MASK}, {@link PhyRequest#PHY_LE_2M_MASK},
|
||||
* and {@link PhyRequest#PHY_LE_CODED_MASK}.
|
||||
* @param rxPhy preferred receiver PHY. Bitwise OR of any of
|
||||
* {@link PhyRequest#PHY_LE_1M_MASK}, {@link PhyRequest#PHY_LE_2M_MASK},
|
||||
* and {@link PhyRequest#PHY_LE_CODED_MASK}.
|
||||
* @param phyOptions preferred coding to use when transmitting on the LE Coded PHY. Can be one
|
||||
* of {@link PhyRequest#PHY_OPTION_NO_PREFERRED},
|
||||
* {@link PhyRequest#PHY_OPTION_S2} or {@link PhyRequest#PHY_OPTION_S8}.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#setPreferredPhy(int, int, int)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static PhyRequest newSetPreferredPhyRequest(@PhyMask final int txPhy,
|
||||
@PhyMask final int rxPhy,
|
||||
@PhyOption final int phyOptions) {
|
||||
return new PhyRequest(Type.SET_PREFERRED_PHY, txPhy, rxPhy, phyOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the current PHY for this connections.
|
||||
* <p>
|
||||
* PHY LE 2M and PHY LE Coded are supported only on Android Oreo or newer.
|
||||
* You may safely read PHY on older platforms, but the request will not be executed
|
||||
* and you will get PHY LE 1M as TX and RX PHY in the callback.
|
||||
*
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#readPhy()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static PhyRequest newReadPhyRequest() {
|
||||
return new PhyRequest(Type.READ_PHY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the current RSSI (Received Signal Strength Indication).
|
||||
*
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#readRssi()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static ReadRssiRequest newReadRssiRequest() {
|
||||
return new ReadRssiRequest(Type.READ_RSSI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the device cache. As the {@link BluetoothGatt#refresh()} method is not in the
|
||||
* public API (it's hidden, and on Android P it is on a light gray list) it is called
|
||||
* using reflections and may be removed in some future Android release or on some devices.
|
||||
* <p>
|
||||
* There is no callback indicating when the cache has been cleared. This library assumes
|
||||
* some time and waits. After the delay, it will start service discovery and clear the
|
||||
* task queue. When the service discovery finishes, the
|
||||
* {@link BleManager.BleManagerGattCallback#isRequiredServiceSupported(BluetoothGatt)} and
|
||||
* {@link BleManager.BleManagerGattCallback#isOptionalServiceSupported(BluetoothGatt)} will
|
||||
* be called and the initialization will be performed as if the device has just connected.
|
||||
*
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#refreshDeviceCache()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings("JavadocReference")
|
||||
@NonNull
|
||||
public static SimpleRequest newRefreshCacheRequest() {
|
||||
return new SimpleRequest(Type.REFRESH_CACHE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new Sleep request that will postpone next request for given number of milliseconds.
|
||||
*
|
||||
* @param delay the delay in milliseconds.
|
||||
* @return The new request.
|
||||
* @deprecated Access to this method will change to package-only.
|
||||
* Use {@link BleManager#sleep(long)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public static SleepRequest newSleepRequest(@IntRange(from = 0) final long delay) {
|
||||
return new SleepRequest(Type.SLEEP, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use to set a completion callback. The callback will be invoked when the operation has
|
||||
* finished successfully unless the request was executed synchronously, in which case this
|
||||
* callback will be ignored.
|
||||
*
|
||||
* @param callback the callback.
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public Request done(@NonNull final SuccessCallback callback) {
|
||||
this.successCallback = callback;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use to set a callback that will be called in case the request has failed.
|
||||
* If the target device wasn't set before executing this request
|
||||
* ({@link BleManager#connect(BluetoothDevice)} was never called), the
|
||||
* {@link #invalid(InvalidRequestCallback)} will be used instead, as the
|
||||
* {@link BluetoothDevice} is not known.
|
||||
* <p>
|
||||
* This callback will be ignored if request was executed synchronously, in which case
|
||||
* the error will be returned as an exception.
|
||||
*
|
||||
* @param callback the callback.
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public Request fail(@NonNull final FailCallback callback) {
|
||||
this.failCallback = callback;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to set internal callback what will be executed before the request is executed.
|
||||
*
|
||||
* @param callback the callback.
|
||||
*/
|
||||
void internalBefore(@NonNull final BeforeCallback callback) {
|
||||
this.internalBeforeCallback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to set internal success callback. The callback will be notified in case the request
|
||||
* has completed.
|
||||
*
|
||||
* @param callback the callback.
|
||||
*/
|
||||
void internalSuccess(@NonNull final SuccessCallback callback) {
|
||||
this.internalSuccessCallback = callback;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to set internal fail callback. The callback will be notified in case the request
|
||||
* has failed.
|
||||
*
|
||||
* @param callback the callback.
|
||||
*/
|
||||
void internalFail(@NonNull final FailCallback callback) {
|
||||
this.internalFailCallback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use to set a callback that will be called in case the request was invalid, for example
|
||||
* called before the device was connected.
|
||||
* This callback will be ignored if request was executed synchronously, in which case
|
||||
* the error will be returned as an exception.
|
||||
*
|
||||
* @param callback the callback.
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public Request invalid(@NonNull final InvalidRequestCallback callback) {
|
||||
this.invalidRequestCallback = callback;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a callback that will be executed before the execution of this operation starts.
|
||||
*
|
||||
* @param callback the callback.
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public Request before(@NonNull final BeforeCallback callback) {
|
||||
this.beforeCallback = callback;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues the request for asynchronous execution.
|
||||
*/
|
||||
public void enqueue() {
|
||||
manager.enqueue(this);
|
||||
}
|
||||
|
||||
void notifyStarted(@NonNull final BluetoothDevice device) {
|
||||
if (beforeCallback != null)
|
||||
beforeCallback.onRequestStarted(device);
|
||||
if (internalBeforeCallback != null)
|
||||
internalBeforeCallback.onRequestStarted(device);
|
||||
}
|
||||
|
||||
void notifySuccess(@NonNull final BluetoothDevice device) {
|
||||
if (!finished) {
|
||||
finished = true;
|
||||
|
||||
if (successCallback != null)
|
||||
successCallback.onRequestCompleted(device);
|
||||
if (internalSuccessCallback != null)
|
||||
internalSuccessCallback.onRequestCompleted(device);
|
||||
}
|
||||
}
|
||||
|
||||
void notifyFail(@NonNull final BluetoothDevice device, final int status) {
|
||||
if (!finished) {
|
||||
finished = true;
|
||||
|
||||
if (failCallback != null)
|
||||
failCallback.onRequestFailed(device, status);
|
||||
if (internalFailCallback != null)
|
||||
internalFailCallback.onRequestFailed(device, status);
|
||||
}
|
||||
}
|
||||
|
||||
void notifyInvalidRequest() {
|
||||
if (!finished) {
|
||||
finished = true;
|
||||
|
||||
if (invalidRequestCallback != null)
|
||||
invalidRequestCallback.onInvalidRequest();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the synchronous method was not called from the UI thread.
|
||||
*
|
||||
* @throws IllegalStateException when called from a UI thread.
|
||||
*/
|
||||
static void assertNotMainThread() throws IllegalStateException {
|
||||
if (Looper.myLooper() == Looper.getMainLooper()) {
|
||||
throw new IllegalStateException("Cannot execute synchronous operation from the UI thread.");
|
||||
}
|
||||
}
|
||||
|
||||
final class RequestCallback implements SuccessCallback, FailCallback, InvalidRequestCallback {
|
||||
final static int REASON_REQUEST_INVALID = -1000000;
|
||||
int status = BluetoothGatt.GATT_SUCCESS;
|
||||
|
||||
@Override
|
||||
public void onRequestCompleted(@NonNull final BluetoothDevice device) {
|
||||
syncLock.open();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestFailed(@NonNull final BluetoothDevice device, final int status) {
|
||||
this.status = status;
|
||||
syncLock.open();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInvalidRequest() {
|
||||
this.status = REASON_REQUEST_INVALID;
|
||||
syncLock.open();
|
||||
}
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
boolean isSuccess() {
|
||||
return this.status == BluetoothGatt.GATT_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
164
app/src/main/java/no/nordicsemi/android/ble/RequestQueue.java
Normal file
164
app/src/main/java/no/nordicsemi/android/ble/RequestQueue.java
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.callback.BeforeCallback;
|
||||
import no.nordicsemi.android.ble.callback.FailCallback;
|
||||
import no.nordicsemi.android.ble.callback.InvalidRequestCallback;
|
||||
import no.nordicsemi.android.ble.callback.SuccessCallback;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public class RequestQueue extends SimpleRequest {
|
||||
/**
|
||||
* A list of operations that will be executed together.
|
||||
*/
|
||||
@NonNull
|
||||
private final Queue<Request> requests;
|
||||
|
||||
RequestQueue() {
|
||||
super(Type.SET);
|
||||
requests = new LinkedList<>();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
RequestQueue setManager(@NonNull final BleManager manager) {
|
||||
super.setManager(manager);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public RequestQueue done(@NonNull final SuccessCallback callback) {
|
||||
super.done(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public RequestQueue fail(@NonNull final FailCallback callback) {
|
||||
super.fail(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RequestQueue invalid(@NonNull final InvalidRequestCallback callback) {
|
||||
super.invalid(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public RequestQueue before(@NonNull final BeforeCallback callback) {
|
||||
super.before(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues a new operation. All operations will be executed sequentially in order they were
|
||||
* added.
|
||||
*
|
||||
* @param operation the new operation to be enqueued.
|
||||
* @throws IllegalStateException if the operation was enqueued before.
|
||||
* @throws IllegalArgumentException if the operation is not a {@link Request}.
|
||||
*/
|
||||
@NonNull
|
||||
public RequestQueue add(@NonNull final Operation operation) {
|
||||
if (operation instanceof Request) {
|
||||
final Request request = (Request) operation;
|
||||
// Validate
|
||||
if (request.enqueued)
|
||||
throw new IllegalStateException("Request already enqueued");
|
||||
// Add
|
||||
requests.add(request);
|
||||
// Mark
|
||||
request.enqueued = true;
|
||||
return this;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Operation does not extend Request");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns number of enqueued operations.
|
||||
*
|
||||
* @return the size of the internal operations list.
|
||||
*/
|
||||
@IntRange(from = 0)
|
||||
public int size() {
|
||||
return requests.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the set is empty, or not.
|
||||
*
|
||||
* @return true if the set is empty. Set gets emptied while it all enqueued operations
|
||||
* are being executed.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return requests.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels all the enqueued operations that were not executed yet.
|
||||
* The one currently executed will be finished.
|
||||
* <p>
|
||||
* It is safe to call this method in {@link Request#done(SuccessCallback)} or
|
||||
* {@link Request#fail(FailCallback)} callback;
|
||||
*/
|
||||
public void cancelQueue() {
|
||||
requests.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next {@link Request} to be enqueued.
|
||||
*
|
||||
* @return the next request.
|
||||
*/
|
||||
@Nullable
|
||||
Request getNext() {
|
||||
try {
|
||||
return requests.remove();
|
||||
// poll() may also throw an exception
|
||||
// See: https://github.com/NordicSemiconductor/Android-BLE-Library/issues/37
|
||||
} catch (final Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether there are more operations to be executed.
|
||||
*
|
||||
* @return true, if not all operations were completed.
|
||||
*/
|
||||
boolean hasMore() {
|
||||
return !requests.isEmpty();
|
||||
}
|
||||
}
|
||||
106
app/src/main/java/no/nordicsemi/android/ble/SimpleRequest.java
Normal file
106
app/src/main/java/no/nordicsemi/android/ble/SimpleRequest.java
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattDescriptor;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.callback.FailCallback;
|
||||
import no.nordicsemi.android.ble.callback.SuccessCallback;
|
||||
import no.nordicsemi.android.ble.exception.BluetoothDisabledException;
|
||||
import no.nordicsemi.android.ble.exception.DeviceDisconnectedException;
|
||||
import no.nordicsemi.android.ble.exception.InvalidRequestException;
|
||||
import no.nordicsemi.android.ble.exception.RequestFailedException;
|
||||
|
||||
/**
|
||||
* A request that requires a {@link android.bluetooth.BluetoothGattCallback callback} or can't
|
||||
* have timeout for any other reason. This class defines the {@link #await()} method.
|
||||
*/
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public class SimpleRequest extends Request {
|
||||
|
||||
SimpleRequest(@NonNull final Type type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
SimpleRequest(@NonNull final Type type,
|
||||
@Nullable final BluetoothGattCharacteristic characteristic) {
|
||||
super(type, characteristic);
|
||||
}
|
||||
|
||||
SimpleRequest(@NonNull final Type type,
|
||||
@Nullable final BluetoothGattDescriptor descriptor) {
|
||||
super(type, descriptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously waits until the request is done.
|
||||
* <p>
|
||||
* Callbacks set using {@link #done(SuccessCallback)} and {@link #fail(FailCallback)}
|
||||
* will be ignored.
|
||||
* <p>
|
||||
* This method may not be called from the main (UI) thread.
|
||||
*
|
||||
* @throws RequestFailedException thrown when the BLE request finished with status other
|
||||
* than {@link BluetoothGatt#GATT_SUCCESS}.
|
||||
* @throws IllegalStateException thrown when you try to call this method from the main
|
||||
* (UI) thread.
|
||||
* @throws DeviceDisconnectedException thrown when the device disconnected before the request
|
||||
* was completed.
|
||||
* @throws BluetoothDisabledException thrown when the Bluetooth adapter has been disabled.
|
||||
* @throws InvalidRequestException thrown when the request was called before the device was
|
||||
* connected at least once (unknown device).
|
||||
*/
|
||||
public final void await() throws RequestFailedException, DeviceDisconnectedException,
|
||||
BluetoothDisabledException, InvalidRequestException {
|
||||
assertNotMainThread();
|
||||
|
||||
final SuccessCallback sc = successCallback;
|
||||
final FailCallback fc = failCallback;
|
||||
try {
|
||||
syncLock.close();
|
||||
final RequestCallback callback = new RequestCallback();
|
||||
done(callback).fail(callback).invalid(callback).enqueue();
|
||||
|
||||
syncLock.block();
|
||||
if (!callback.isSuccess()) {
|
||||
if (callback.status == FailCallback.REASON_DEVICE_DISCONNECTED) {
|
||||
throw new DeviceDisconnectedException();
|
||||
}
|
||||
if (callback.status == FailCallback.REASON_BLUETOOTH_DISABLED) {
|
||||
throw new BluetoothDisabledException();
|
||||
}
|
||||
if (callback.status == RequestCallback.REASON_REQUEST_INVALID) {
|
||||
throw new InvalidRequestException(this);
|
||||
}
|
||||
throw new RequestFailedException(this, callback.status);
|
||||
}
|
||||
} finally {
|
||||
successCallback = sc;
|
||||
failCallback = fc;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattDescriptor;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.callback.FailCallback;
|
||||
import no.nordicsemi.android.ble.callback.SuccessCallback;
|
||||
import no.nordicsemi.android.ble.exception.BluetoothDisabledException;
|
||||
import no.nordicsemi.android.ble.exception.DeviceDisconnectedException;
|
||||
import no.nordicsemi.android.ble.exception.InvalidRequestException;
|
||||
import no.nordicsemi.android.ble.exception.RequestFailedException;
|
||||
|
||||
/**
|
||||
* A value request that requires a {@link android.bluetooth.BluetoothGattCallback callback} or
|
||||
* can't have timeout for any other reason. This class defines the {@link #await()} methods.
|
||||
*/
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public abstract class SimpleValueRequest<T> extends SimpleRequest {
|
||||
T valueCallback;
|
||||
|
||||
SimpleValueRequest(@NonNull final Type type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
SimpleValueRequest(@NonNull final Type type,
|
||||
@Nullable final BluetoothGattCharacteristic characteristic) {
|
||||
super(type, characteristic);
|
||||
}
|
||||
|
||||
SimpleValueRequest(@NonNull final Type type,
|
||||
@Nullable final BluetoothGattDescriptor descriptor) {
|
||||
super(type, descriptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value callback. When the request is invoked synchronously, this callback will
|
||||
* be ignored and the received value will be returned by the <code>await(...)</code> method;
|
||||
*
|
||||
* @param callback the callback.
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public SimpleValueRequest<T> with(@NonNull final T callback) {
|
||||
this.valueCallback = callback;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously waits until the request is done. The given response object will be filled
|
||||
* with the request response.
|
||||
* <p>
|
||||
* Callbacks set using {@link #done(SuccessCallback)} and {@link #fail(FailCallback)} and
|
||||
* {@link #with(T)} will be ignored.
|
||||
* <p>
|
||||
* This method may not be called from the main (UI) thread.
|
||||
*
|
||||
* @param response the response object.
|
||||
* @param <E> a response class.
|
||||
* @return The response with a response.
|
||||
* @throws RequestFailedException thrown when the BLE request finished with status other
|
||||
* than {@link android.bluetooth.BluetoothGatt#GATT_SUCCESS}.
|
||||
* @throws IllegalStateException thrown when you try to call this method from the main
|
||||
* (UI) thread.
|
||||
* @throws DeviceDisconnectedException thrown when the device disconnected before the request
|
||||
* was completed.
|
||||
* @throws BluetoothDisabledException thrown when the Bluetooth adapter is disabled.
|
||||
* @throws InvalidRequestException thrown when the request was called before the device was
|
||||
* connected at least once (unknown device).
|
||||
* @see #await(Class)
|
||||
*/
|
||||
@NonNull
|
||||
public <E extends T> E await(@NonNull final E response)
|
||||
throws RequestFailedException, DeviceDisconnectedException, BluetoothDisabledException,
|
||||
InvalidRequestException {
|
||||
assertNotMainThread();
|
||||
|
||||
final T vc = valueCallback;
|
||||
try {
|
||||
with(response).await();
|
||||
return response;
|
||||
} finally {
|
||||
valueCallback = vc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously waits until the request is done.
|
||||
* <p>
|
||||
* Callbacks set using {@link #done(SuccessCallback)} and {@link #fail(FailCallback)} and
|
||||
* {@link #with(T)} will be ignored.
|
||||
* <p>
|
||||
* This method may not be called from the main (UI) thread.
|
||||
*
|
||||
* @param responseClass the response class. This class will be instantiate, therefore it has
|
||||
* to have a default constructor.
|
||||
* @return The response with a response.
|
||||
* @throws RequestFailedException thrown when the BLE request finished with status other
|
||||
* than {@link android.bluetooth.BluetoothGatt#GATT_SUCCESS}.
|
||||
* @throws IllegalStateException thrown when you try to call this method from the main
|
||||
* (UI) thread.
|
||||
* @throws IllegalArgumentException thrown when the response class could not be instantiated.
|
||||
* @throws DeviceDisconnectedException thrown when the device disconnected before the request
|
||||
* was completed.
|
||||
* @throws BluetoothDisabledException thrown when the Bluetooth adapter is disabled.
|
||||
* @throws InvalidRequestException thrown when the request was called before the device was
|
||||
* connected at least once (unknown device).
|
||||
* @see #await(Object)
|
||||
*/
|
||||
@NonNull
|
||||
public <E extends T> E await(@NonNull final Class<E> responseClass)
|
||||
throws RequestFailedException, DeviceDisconnectedException, BluetoothDisabledException,
|
||||
InvalidRequestException {
|
||||
assertNotMainThread();
|
||||
|
||||
try {
|
||||
final E response = responseClass.newInstance();
|
||||
return await(response);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalArgumentException("Couldn't instantiate "
|
||||
+ responseClass.getCanonicalName()
|
||||
+ " class. Is the default constructor accessible?");
|
||||
} catch (InstantiationException e) {
|
||||
throw new IllegalArgumentException("Couldn't instantiate "
|
||||
+ responseClass.getCanonicalName()
|
||||
+ " class. Does it have a default constructor with no arguments?");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import no.nordicsemi.android.ble.callback.BeforeCallback;
|
||||
import no.nordicsemi.android.ble.callback.FailCallback;
|
||||
import no.nordicsemi.android.ble.callback.InvalidRequestCallback;
|
||||
import no.nordicsemi.android.ble.callback.SuccessCallback;
|
||||
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public final class SleepRequest extends SimpleRequest implements Operation {
|
||||
private long delay;
|
||||
|
||||
SleepRequest(@NonNull final Type type, @IntRange(from = 0) final long delay) {
|
||||
super(type);
|
||||
this.delay = delay;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
SleepRequest setManager(@NonNull final BleManager manager) {
|
||||
super.setManager(manager);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public SleepRequest done(@NonNull final SuccessCallback callback) {
|
||||
super.done(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public SleepRequest fail(@NonNull final FailCallback callback) {
|
||||
super.fail(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public SleepRequest invalid(@NonNull final InvalidRequestCallback callback) {
|
||||
super.invalid(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public SleepRequest before(@NonNull final BeforeCallback callback) {
|
||||
super.before(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
long getDelay() {
|
||||
return delay;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
abstract class TimeoutHandler {
|
||||
|
||||
/**
|
||||
* Method called when the request timed out.
|
||||
*
|
||||
* @param request the request that timed out.
|
||||
*/
|
||||
abstract void onRequestTimeout(@NonNull final TimeoutableRequest request);
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattDescriptor;
|
||||
import android.os.Handler;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.callback.FailCallback;
|
||||
import no.nordicsemi.android.ble.callback.SuccessCallback;
|
||||
import no.nordicsemi.android.ble.exception.BluetoothDisabledException;
|
||||
import no.nordicsemi.android.ble.exception.DeviceDisconnectedException;
|
||||
import no.nordicsemi.android.ble.exception.InvalidRequestException;
|
||||
import no.nordicsemi.android.ble.exception.RequestFailedException;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public abstract class TimeoutableRequest extends Request {
|
||||
private TimeoutHandler timeoutHandler;
|
||||
private Runnable timeoutCallback;
|
||||
private Handler handler;
|
||||
protected long timeout;
|
||||
|
||||
TimeoutableRequest(@NonNull final Type type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
TimeoutableRequest(@NonNull final Type type, @Nullable final BluetoothGattCharacteristic characteristic) {
|
||||
super(type, characteristic);
|
||||
}
|
||||
|
||||
TimeoutableRequest(@NonNull final Type type, @Nullable final BluetoothGattDescriptor descriptor) {
|
||||
super(type, descriptor);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
TimeoutableRequest setManager(@NonNull final BleManager manager) {
|
||||
super.setManager(manager);
|
||||
this.handler = manager.mHandler;
|
||||
this.timeoutHandler = manager;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the operation timeout.
|
||||
* When the timeout occurs, the request will fail with {@link FailCallback#REASON_TIMEOUT}.
|
||||
*
|
||||
* @param timeout the request timeout in milliseconds, 0 to disable timeout.
|
||||
* @return the callback.
|
||||
* @throws IllegalStateException thrown when the request has already been started.
|
||||
* @throws UnsupportedOperationException thrown when the timeout is not allowed for this request,
|
||||
* as the callback from the system is required.
|
||||
*/
|
||||
@NonNull
|
||||
public TimeoutableRequest timeout(@IntRange(from = 0) final long timeout) {
|
||||
if (timeoutCallback != null)
|
||||
throw new IllegalStateException("Request already started");
|
||||
this.timeout = timeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues the request for asynchronous execution.
|
||||
* <p>
|
||||
* Use {@link #timeout(long)} to set the maximum time the manager should wait until the device
|
||||
* is ready. When the timeout occurs, the request will fail with
|
||||
* {@link FailCallback#REASON_TIMEOUT} and the device will get disconnected.
|
||||
*/
|
||||
@Override
|
||||
public final void enqueue() {
|
||||
super.enqueue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues the request for asynchronous execution.
|
||||
* <p>
|
||||
* When the timeout occurs, the request will fail with {@link FailCallback#REASON_TIMEOUT}
|
||||
* and the device will get disconnected.
|
||||
*
|
||||
* @param timeout the request timeout in milliseconds, 0 to disable timeout. This value will
|
||||
* override one set in {@link #timeout(long)}.
|
||||
* @deprecated Use {@link #timeout(long)} and {@link #enqueue()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public final void enqueue(@IntRange(from = 0) final long timeout) {
|
||||
timeout(timeout).enqueue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously waits until the request is done.
|
||||
* <p>
|
||||
* Use {@link #timeout(long)} to set the maximum time the manager should wait until the request
|
||||
* is ready. When the timeout occurs, the {@link InterruptedException} will be thrown.
|
||||
* <p>
|
||||
* Callbacks set using {@link #done(SuccessCallback)} and {@link #fail(FailCallback)}
|
||||
* will be ignored.
|
||||
* <p>
|
||||
* This method may not be called from the main (UI) thread.
|
||||
*
|
||||
* @throws RequestFailedException thrown when the BLE request finished with status other
|
||||
* than {@link BluetoothGatt#GATT_SUCCESS}.
|
||||
* @throws InterruptedException thrown if the timeout occurred before the request has
|
||||
* finished.
|
||||
* @throws IllegalStateException thrown when you try to call this method from the main
|
||||
* (UI) thread.
|
||||
* @throws DeviceDisconnectedException thrown when the device disconnected before the request
|
||||
* was completed.
|
||||
* @throws BluetoothDisabledException thrown when the Bluetooth adapter has been disabled.
|
||||
* @throws InvalidRequestException thrown when the request was called before the device was
|
||||
* connected at least once (unknown device).
|
||||
* @see #enqueue()
|
||||
*/
|
||||
public final void await() throws RequestFailedException, DeviceDisconnectedException,
|
||||
BluetoothDisabledException, InvalidRequestException, InterruptedException {
|
||||
assertNotMainThread();
|
||||
|
||||
final SuccessCallback sc = successCallback;
|
||||
final FailCallback fc = failCallback;
|
||||
try {
|
||||
syncLock.close();
|
||||
final RequestCallback callback = new RequestCallback();
|
||||
done(callback).fail(callback).invalid(callback).enqueue();
|
||||
|
||||
if (!syncLock.block(timeout)) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
if (!callback.isSuccess()) {
|
||||
if (callback.status == FailCallback.REASON_DEVICE_DISCONNECTED) {
|
||||
throw new DeviceDisconnectedException();
|
||||
}
|
||||
if (callback.status == FailCallback.REASON_BLUETOOTH_DISABLED) {
|
||||
throw new BluetoothDisabledException();
|
||||
}
|
||||
if (callback.status == RequestCallback.REASON_REQUEST_INVALID) {
|
||||
throw new InvalidRequestException(this);
|
||||
}
|
||||
throw new RequestFailedException(this, callback.status);
|
||||
}
|
||||
} finally {
|
||||
successCallback = sc;
|
||||
failCallback = fc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously waits, for as most as the given number of milliseconds, until the request
|
||||
* is ready.
|
||||
* <p>
|
||||
* When the timeout occurs, the {@link InterruptedException} will be thrown.
|
||||
* <p>
|
||||
* Callbacks set using {@link #done(SuccessCallback)} and {@link #fail(FailCallback)}
|
||||
* will be ignored.
|
||||
* <p>
|
||||
* This method may not be called from the main (UI) thread.
|
||||
*
|
||||
* @param timeout optional timeout in milliseconds, 0 to disable timeout. This will
|
||||
* override the timeout set using {@link #timeout(long)}.
|
||||
* @throws RequestFailedException thrown when the BLE request finished with status other
|
||||
* than {@link BluetoothGatt#GATT_SUCCESS}.
|
||||
* @throws InterruptedException thrown if the timeout occurred before the request has
|
||||
* finished.
|
||||
* @throws IllegalStateException thrown when you try to call this method from the main
|
||||
* (UI) thread.
|
||||
* @throws DeviceDisconnectedException thrown when the device disconnected before the request
|
||||
* was completed.
|
||||
* @throws BluetoothDisabledException thrown when the Bluetooth adapter has been disabled.
|
||||
* @throws InvalidRequestException thrown when the request was called before the device was
|
||||
* connected at least once (unknown device).
|
||||
* @deprecated Use {@link #timeout(long)} and {@link #await()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public final void await(@IntRange(from = 0) final long timeout) throws RequestFailedException,
|
||||
InterruptedException, DeviceDisconnectedException, BluetoothDisabledException,
|
||||
InvalidRequestException {
|
||||
timeout(timeout).await();
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyStarted(@NonNull final BluetoothDevice device) {
|
||||
if (timeout > 0L) {
|
||||
timeoutCallback = () -> {
|
||||
timeoutCallback = null;
|
||||
if (!finished) {
|
||||
notifyFail(device, FailCallback.REASON_TIMEOUT);
|
||||
timeoutHandler.onRequestTimeout(this);
|
||||
}
|
||||
};
|
||||
handler.postDelayed(timeoutCallback, timeout);
|
||||
}
|
||||
super.notifyStarted(device);
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifySuccess(@NonNull final BluetoothDevice device) {
|
||||
if (!finished) {
|
||||
handler.removeCallbacks(timeoutCallback);
|
||||
timeoutCallback = null;
|
||||
}
|
||||
super.notifySuccess(device);
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyFail(@NonNull final BluetoothDevice device, final int status) {
|
||||
if (!finished) {
|
||||
handler.removeCallbacks(timeoutCallback);
|
||||
timeoutCallback = null;
|
||||
}
|
||||
super.notifyFail(device, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyInvalidRequest() {
|
||||
if (!finished) {
|
||||
handler.removeCallbacks(timeoutCallback);
|
||||
timeoutCallback = null;
|
||||
}
|
||||
super.notifyInvalidRequest();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattDescriptor;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.callback.FailCallback;
|
||||
import no.nordicsemi.android.ble.callback.SuccessCallback;
|
||||
import no.nordicsemi.android.ble.exception.BluetoothDisabledException;
|
||||
import no.nordicsemi.android.ble.exception.DeviceDisconnectedException;
|
||||
import no.nordicsemi.android.ble.exception.InvalidRequestException;
|
||||
import no.nordicsemi.android.ble.exception.RequestFailedException;
|
||||
|
||||
/**
|
||||
* A value request that requires a {@link android.bluetooth.BluetoothGattCallback callback} or
|
||||
* can't have timeout for any other reason. This class defines the {@link #await()} methods.
|
||||
*/
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public abstract class TimeoutableValueRequest<T> extends TimeoutableRequest {
|
||||
T valueCallback;
|
||||
|
||||
TimeoutableValueRequest(@NonNull final Type type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
TimeoutableValueRequest(@NonNull final Type type,
|
||||
@Nullable final BluetoothGattCharacteristic characteristic) {
|
||||
super(type, characteristic);
|
||||
}
|
||||
|
||||
TimeoutableValueRequest(@NonNull final Type type,
|
||||
@Nullable final BluetoothGattDescriptor descriptor) {
|
||||
super(type, descriptor);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public TimeoutableValueRequest<T> timeout(@IntRange(from = 0) final long timeout) {
|
||||
super.timeout(timeout);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value callback. When the request is invoked synchronously, this callback will
|
||||
* be ignored and the received value will be returned by the <code>await(...)</code> method;
|
||||
*
|
||||
* @param callback the callback.
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public TimeoutableValueRequest<T> with(@NonNull final T callback) {
|
||||
this.valueCallback = callback;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously waits until the request is done.
|
||||
* <p>
|
||||
* When the timeout, set with {@link #timeout(long)} occurs, the {@link InterruptedException}
|
||||
* will be thrown.
|
||||
* <p>
|
||||
* Callbacks set using {@link #done(SuccessCallback)} and {@link #fail(FailCallback)} and
|
||||
* {@link #with(E)} will be ignored.
|
||||
* <p>
|
||||
* This method may not be called from the main (UI) thread.
|
||||
*
|
||||
* @param response the response object.
|
||||
* @param <E> a response class.
|
||||
* @return The response with a response.
|
||||
* @throws RequestFailedException thrown when the BLE request finished with status other
|
||||
* than {@link android.bluetooth.BluetoothGatt#GATT_SUCCESS}.
|
||||
* @throws InterruptedException thrown if the timeout occurred before the request has
|
||||
* finished.
|
||||
* @throws IllegalStateException thrown when you try to call this method from the main
|
||||
* (UI) thread, or when the trigger was already enqueued.
|
||||
* @throws DeviceDisconnectedException thrown when the device disconnected before the request
|
||||
* was completed.
|
||||
* @throws BluetoothDisabledException thrown when the Bluetooth adapter is disabled.
|
||||
* @throws InvalidRequestException thrown when the request was called before the device was
|
||||
* connected at least once (unknown device).
|
||||
*/
|
||||
@NonNull
|
||||
public <E extends T> E await(@NonNull final E response)
|
||||
throws RequestFailedException, DeviceDisconnectedException, BluetoothDisabledException,
|
||||
InvalidRequestException, InterruptedException {
|
||||
assertNotMainThread();
|
||||
|
||||
final T vc = valueCallback;
|
||||
try {
|
||||
with(response).await();
|
||||
return response;
|
||||
} finally {
|
||||
valueCallback = vc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously waits until the request is done.
|
||||
* <p>
|
||||
* Callbacks set using {@link #done(SuccessCallback)} and {@link #fail(FailCallback)} and
|
||||
* {@link #with(T)} will be ignored.
|
||||
* <p>
|
||||
* This method may not be called from the main (UI) thread.
|
||||
*
|
||||
* @param responseClass the response class. This class will be instantiate, therefore it has
|
||||
* to have a default constructor.
|
||||
* @return The response with a response.
|
||||
* @throws RequestFailedException thrown when the BLE request finished with status other
|
||||
* than {@link android.bluetooth.BluetoothGatt#GATT_SUCCESS}.
|
||||
* @throws InterruptedException thrown if the timeout occurred before the request has
|
||||
* finished.
|
||||
* @throws IllegalStateException thrown when you try to call this method from the main
|
||||
* (UI) thread.
|
||||
* @throws IllegalArgumentException thrown when the response class could not be instantiated.
|
||||
* @throws DeviceDisconnectedException thrown when the device disconnected before the request
|
||||
* was completed.
|
||||
* @throws BluetoothDisabledException thrown when the Bluetooth adapter is disabled.
|
||||
* @throws InvalidRequestException thrown when the request was called before the device was
|
||||
* connected at least once (unknown device).
|
||||
* @see #await(Object)
|
||||
*/
|
||||
@NonNull
|
||||
public <E extends T> E await(@NonNull final Class<E> responseClass)
|
||||
throws RequestFailedException, DeviceDisconnectedException, BluetoothDisabledException,
|
||||
InvalidRequestException, InterruptedException {
|
||||
assertNotMainThread();
|
||||
|
||||
try {
|
||||
final E response = responseClass.newInstance();
|
||||
return await(response);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalArgumentException("Couldn't instantiate "
|
||||
+ responseClass.getCanonicalName()
|
||||
+ " class. Is the default constructor accessible?");
|
||||
} catch (InstantiationException e) {
|
||||
throw new IllegalArgumentException("Couldn't instantiate "
|
||||
+ responseClass.getCanonicalName()
|
||||
+ " class. Does it have a default constructor with no arguments?");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously waits until the request is done, for at most given number of milliseconds
|
||||
* after which the {@link InterruptedException} will be thrown.
|
||||
* <p>
|
||||
* Callbacks set using {@link #done(SuccessCallback)}, {@link #fail(FailCallback)} and
|
||||
* {@link #with(E)} will be ignored.
|
||||
* <p>
|
||||
* This method may not be called from the main (UI) thread.
|
||||
*
|
||||
* @param responseClass the response class. This class will be instantiate, therefore it has
|
||||
* to have a default constructor.
|
||||
* @param timeout optional timeout in milliseconds. This value will override one set
|
||||
* in {@link #timeout(long)}.
|
||||
* @param <E> a response class that extends {@link T}.
|
||||
* @return The object with a response.
|
||||
* @throws RequestFailedException thrown when the BLE request finished with status other
|
||||
* than {@link android.bluetooth.BluetoothGatt#GATT_SUCCESS}.
|
||||
* @throws InterruptedException thrown if the timeout occurred before the request has
|
||||
* finished.
|
||||
* @throws IllegalStateException thrown when you try to call this method from the main
|
||||
* (UI) thread.
|
||||
* @throws IllegalArgumentException thrown when the response class could not be instantiated.
|
||||
* @throws DeviceDisconnectedException thrown when the device disconnected before the request
|
||||
* was completed.
|
||||
* @throws BluetoothDisabledException thrown when the Bluetooth adapter is disabled.
|
||||
* @throws InvalidRequestException thrown when the request was called before the device was
|
||||
* connected at least once (unknown device).
|
||||
* @deprecated Use {@link #timeout(long)} and {@link #await(Class)} instead.
|
||||
*/
|
||||
@NonNull
|
||||
@Deprecated
|
||||
public <E extends T> E await(@NonNull final Class<E> responseClass,
|
||||
@IntRange(from = 0) final long timeout)
|
||||
throws RequestFailedException, InterruptedException, DeviceDisconnectedException,
|
||||
BluetoothDisabledException, InvalidRequestException {
|
||||
return timeout(timeout).await(responseClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronously waits until the request is done, for at most given number of milliseconds
|
||||
* after which the {@link InterruptedException} will be thrown.
|
||||
* <p>
|
||||
* Callbacks set using {@link #done(SuccessCallback)}, {@link #fail(FailCallback)} and
|
||||
* {@link #with(E)} will be ignored.
|
||||
* <p>
|
||||
* This method may not be called from the main (UI) thread.
|
||||
*
|
||||
* @param response the response object.
|
||||
* @param timeout optional timeout in milliseconds.
|
||||
* @param <E> a response class that extends {@link T}.
|
||||
* @return The object with a response.
|
||||
* @throws RequestFailedException thrown when the BLE request finished with status other
|
||||
* than {@link android.bluetooth.BluetoothGatt#GATT_SUCCESS}.
|
||||
* @throws InterruptedException thrown if the timeout occurred before the request has
|
||||
* finished.
|
||||
* @throws IllegalStateException thrown when you try to call this method from the main
|
||||
* (UI) thread.
|
||||
* @throws DeviceDisconnectedException thrown when the device disconnected before the request
|
||||
* was completed.
|
||||
* @throws BluetoothDisabledException thrown when the Bluetooth adapter is disabled.
|
||||
* @throws InvalidRequestException thrown when the request was called before the device was
|
||||
* connected at least once (unknown device).
|
||||
* @deprecated Use {@link #timeout(long)} and {@link #await(E)} instead.
|
||||
*/
|
||||
@NonNull
|
||||
@Deprecated
|
||||
public <E extends T> E await(@NonNull final E response,
|
||||
@IntRange(from = 0) final long timeout)
|
||||
throws RequestFailedException, InterruptedException, DeviceDisconnectedException,
|
||||
BluetoothDisabledException, InvalidRequestException {
|
||||
return timeout(timeout).await(response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.callback.DataReceivedCallback;
|
||||
import no.nordicsemi.android.ble.callback.ReadProgressCallback;
|
||||
import no.nordicsemi.android.ble.data.Data;
|
||||
import no.nordicsemi.android.ble.data.DataFilter;
|
||||
import no.nordicsemi.android.ble.data.DataMerger;
|
||||
import no.nordicsemi.android.ble.data.DataStream;
|
||||
|
||||
@SuppressWarnings({"unused", "WeakerAccess", "UnusedReturnValue"})
|
||||
public class ValueChangedCallback {
|
||||
private ReadProgressCallback progressCallback;
|
||||
private DataReceivedCallback valueCallback;
|
||||
private DataMerger dataMerger;
|
||||
private DataStream buffer;
|
||||
private DataFilter filter;
|
||||
private int count = 0;
|
||||
|
||||
ValueChangedCallback() {
|
||||
// empty
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the asynchronous data callback that will be called whenever a notification or
|
||||
* an indication is received on given characteristic.
|
||||
*
|
||||
* @param callback the data callback.
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public ValueChangedCallback with(@NonNull final DataReceivedCallback callback) {
|
||||
this.valueCallback = callback;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a filter which allows to skip some incoming data.
|
||||
*
|
||||
* @param filter the data filter.
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public ValueChangedCallback filter(@NonNull final DataFilter filter) {
|
||||
this.filter = filter;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a merger that will be used to merge multiple packets into a single Data.
|
||||
* The merger may modify each packet if necessary.
|
||||
*
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public ValueChangedCallback merge(@NonNull final DataMerger merger) {
|
||||
this.dataMerger = merger;
|
||||
this.progressCallback = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a merger that will be used to merge multiple packets into a single Data.
|
||||
* The merger may modify each packet if necessary.
|
||||
*
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public ValueChangedCallback merge(@NonNull final DataMerger merger,
|
||||
@NonNull final ReadProgressCallback callback) {
|
||||
this.dataMerger = merger;
|
||||
this.progressCallback = callback;
|
||||
return this;
|
||||
}
|
||||
|
||||
ValueChangedCallback free() {
|
||||
valueCallback = null;
|
||||
dataMerger = null;
|
||||
progressCallback = null;
|
||||
buffer = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
boolean matches(final byte[] packet) {
|
||||
return filter == null || filter.filter(packet);
|
||||
}
|
||||
|
||||
void notifyValueChanged(@NonNull final BluetoothDevice device, @Nullable final byte[] value) {
|
||||
// Keep a reference to the value callback, as it may change during execution
|
||||
final DataReceivedCallback valueCallback = this.valueCallback;
|
||||
|
||||
// With no value callback there is no need for any merging
|
||||
if (valueCallback == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dataMerger == null) {
|
||||
valueCallback.onDataReceived(device, new Data(value));
|
||||
} else {
|
||||
if (progressCallback != null)
|
||||
progressCallback.onPacketReceived(device, value, count);
|
||||
if (buffer == null)
|
||||
buffer = new DataStream();
|
||||
if (dataMerger.merge(buffer, value, count++)) {
|
||||
valueCallback.onDataReceived(device, buffer.toData());
|
||||
buffer = null;
|
||||
count = 0;
|
||||
} // else
|
||||
// wait for more packets to be merged
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,400 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.callback.BeforeCallback;
|
||||
import no.nordicsemi.android.ble.callback.DataReceivedCallback;
|
||||
import no.nordicsemi.android.ble.callback.FailCallback;
|
||||
import no.nordicsemi.android.ble.callback.InvalidRequestCallback;
|
||||
import no.nordicsemi.android.ble.callback.ReadProgressCallback;
|
||||
import no.nordicsemi.android.ble.callback.SuccessCallback;
|
||||
import no.nordicsemi.android.ble.callback.profile.ProfileReadResponse;
|
||||
import no.nordicsemi.android.ble.data.Data;
|
||||
import no.nordicsemi.android.ble.data.DataFilter;
|
||||
import no.nordicsemi.android.ble.data.DataMerger;
|
||||
import no.nordicsemi.android.ble.data.DataStream;
|
||||
import no.nordicsemi.android.ble.exception.BluetoothDisabledException;
|
||||
import no.nordicsemi.android.ble.exception.DeviceDisconnectedException;
|
||||
import no.nordicsemi.android.ble.exception.InvalidDataException;
|
||||
import no.nordicsemi.android.ble.exception.InvalidRequestException;
|
||||
import no.nordicsemi.android.ble.exception.RequestFailedException;
|
||||
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public final class WaitForValueChangedRequest extends TimeoutableValueRequest<DataReceivedCallback>
|
||||
implements Operation {
|
||||
static final int NOT_STARTED = -123456;
|
||||
static final int STARTED = NOT_STARTED + 1;
|
||||
|
||||
private ReadProgressCallback progressCallback;
|
||||
private DataMerger dataMerger;
|
||||
private DataStream buffer;
|
||||
private DataFilter filter;
|
||||
private Request trigger;
|
||||
private boolean deviceDisconnected;
|
||||
private boolean bluetoothDisabled;
|
||||
private int triggerStatus = BluetoothGatt.GATT_SUCCESS;
|
||||
private int count = 0;
|
||||
|
||||
WaitForValueChangedRequest(@NonNull final Type type,
|
||||
@Nullable final BluetoothGattCharacteristic characteristic) {
|
||||
super(type, characteristic);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
WaitForValueChangedRequest setManager(@NonNull final BleManager manager) {
|
||||
super.setManager(manager);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public WaitForValueChangedRequest timeout(@IntRange(from = 0) final long timeout) {
|
||||
super.timeout(timeout);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public WaitForValueChangedRequest done(@NonNull final SuccessCallback callback) {
|
||||
super.done(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public WaitForValueChangedRequest fail(@NonNull final FailCallback callback) {
|
||||
super.fail(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public WaitForValueChangedRequest invalid(@NonNull final InvalidRequestCallback callback) {
|
||||
super.invalid(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public WaitForValueChangedRequest before(@NonNull final BeforeCallback callback) {
|
||||
super.before(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public WaitForValueChangedRequest with(@NonNull final DataReceivedCallback callback) {
|
||||
super.with(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a filter which allows to skip some incoming data.
|
||||
*
|
||||
* @param filter the data filter.
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public WaitForValueChangedRequest filter(@NonNull final DataFilter filter) {
|
||||
this.filter = filter;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a merger that will be used to merge multiple packets into a single Data.
|
||||
* The merger may modify each packet if necessary.
|
||||
*
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public WaitForValueChangedRequest merge(@NonNull final DataMerger merger) {
|
||||
this.dataMerger = merger;
|
||||
this.progressCallback = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a merger that will be used to merge multiple packets into a single Data.
|
||||
* The merger may modify each packet if necessary.
|
||||
*
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public WaitForValueChangedRequest merge(@NonNull final DataMerger merger,
|
||||
@NonNull final ReadProgressCallback callback) {
|
||||
this.dataMerger = merger;
|
||||
this.progressCallback = callback;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an optional request that is suppose to trigger the notification or indication.
|
||||
* This is to ensure that the characteristic value won't change before the callback was set.
|
||||
*
|
||||
* @param trigger the operation that triggers the notification, usually a write characteristic
|
||||
* request that write some OP CODE.
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public WaitForValueChangedRequest trigger(@NonNull final Operation trigger) {
|
||||
if (trigger instanceof Request) {
|
||||
this.trigger = (Request) trigger;
|
||||
this.triggerStatus = NOT_STARTED;
|
||||
// The trigger will never receive invalid request event.
|
||||
// If the BluetoothDevice wasn't set, the whole WaitForValueChangedRequest would be invalid.
|
||||
/*this.trigger.invalid(() -> {
|
||||
// never called
|
||||
});*/
|
||||
this.trigger.internalBefore(device -> triggerStatus = STARTED);
|
||||
this.trigger.internalSuccess(device -> triggerStatus = BluetoothGatt.GATT_SUCCESS);
|
||||
this.trigger.internalFail((device, status) -> {
|
||||
triggerStatus = status;
|
||||
syncLock.open();
|
||||
notifyFail(device, status);
|
||||
});
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public <E extends DataReceivedCallback> E await(@NonNull final E response)
|
||||
throws RequestFailedException, DeviceDisconnectedException, BluetoothDisabledException,
|
||||
InvalidRequestException, InterruptedException {
|
||||
assertNotMainThread();
|
||||
|
||||
try {
|
||||
// Ensure the trigger request it enqueued after the callback has been set.
|
||||
if (trigger != null && trigger.enqueued) {
|
||||
throw new IllegalStateException("Trigger request already enqueued");
|
||||
}
|
||||
super.await(response);
|
||||
return response;
|
||||
} catch (final RequestFailedException e) {
|
||||
if (triggerStatus != BluetoothGatt.GATT_SUCCESS) {
|
||||
// Trigger will never have invalid request status. The outer request will.
|
||||
/*if (triggerStatus == RequestCallback.REASON_REQUEST_INVALID) {
|
||||
throw new InvalidRequestException(trigger);
|
||||
}*/
|
||||
throw new RequestFailedException(trigger, triggerStatus);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to {@link #await(Class)}, but if the response class extends
|
||||
* {@link ProfileReadResponse} and the received response is invalid, an exception is thrown.
|
||||
* This allows to keep all error handling in one place.
|
||||
*
|
||||
* @param response the result object.
|
||||
* @param <E> a response class that extends {@link ProfileReadResponse}.
|
||||
* @return Object with a valid response.
|
||||
* @throws IllegalStateException thrown when you try to call this method from
|
||||
* the main (UI) thread.
|
||||
* @throws InterruptedException thrown when the timeout occurred before the
|
||||
* characteristic value has changed.
|
||||
* @throws RequestFailedException thrown when the trigger request has failed.
|
||||
* @throws DeviceDisconnectedException thrown when the device disconnected before the
|
||||
* notification or indication was received.
|
||||
* @throws BluetoothDisabledException thrown when the Bluetooth adapter has been disabled.
|
||||
* @throws InvalidRequestException thrown when the request was called before the device was
|
||||
* connected at least once (unknown device).
|
||||
* @throws InvalidDataException thrown when the received data were not valid (that is when
|
||||
* {@link ProfileReadResponse#onDataReceived(BluetoothDevice, Data)}
|
||||
* failed to parse the data correctly and called
|
||||
* {@link ProfileReadResponse#onInvalidDataReceived(BluetoothDevice, Data)}).
|
||||
*/
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@NonNull
|
||||
public <E extends ProfileReadResponse> E awaitValid(@NonNull final E response)
|
||||
throws RequestFailedException, InvalidDataException, DeviceDisconnectedException,
|
||||
BluetoothDisabledException, InvalidRequestException, InterruptedException {
|
||||
final E result = await(response);
|
||||
if (result != null && !result.isValid()) {
|
||||
throw new InvalidDataException(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to {@link #await(DataReceivedCallback)}, but if the response class extends
|
||||
* {@link ProfileReadResponse} and the received response is invalid, an exception is thrown.
|
||||
* This allows to keep all error handling in one place.
|
||||
*
|
||||
* @param responseClass the result class. This class will be instantiate, therefore it
|
||||
* has to have a default constructor.
|
||||
* @param <E> a response class that extends {@link ProfileReadResponse}.
|
||||
* @return Object with a valid response.
|
||||
* @throws IllegalStateException thrown when you try to call this method from
|
||||
* the main (UI) thread.
|
||||
* @throws InterruptedException thrown when the timeout occurred before the
|
||||
* characteristic value has changed.
|
||||
* @throws IllegalArgumentException thrown when the response class could not be instantiated.
|
||||
* @throws RequestFailedException thrown when the trigger request has failed.
|
||||
* @throws DeviceDisconnectedException thrown when the device disconnected before the
|
||||
* notification or indication was received.
|
||||
* @throws BluetoothDisabledException thrown when the Bluetooth adapter has been disabled.
|
||||
* @throws InvalidRequestException thrown when the request was called before the device was
|
||||
* connected at least once (unknown device).
|
||||
* @throws InvalidDataException thrown when the received data were not valid (that is when
|
||||
* {@link ProfileReadResponse#onDataReceived(BluetoothDevice, Data)}
|
||||
* failed to parse the data correctly and called
|
||||
* {@link ProfileReadResponse#onInvalidDataReceived(BluetoothDevice, Data)}).
|
||||
*/
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@NonNull
|
||||
public <E extends ProfileReadResponse> E awaitValid(@NonNull final Class<E> responseClass)
|
||||
throws RequestFailedException, InvalidDataException, DeviceDisconnectedException,
|
||||
BluetoothDisabledException, InvalidRequestException, InterruptedException {
|
||||
final E response = await(responseClass);
|
||||
if (response != null && !response.isValid()) {
|
||||
throw new InvalidDataException(response);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #await(Class, long)}, but if received response is not valid, this method will
|
||||
* thrown an exception.
|
||||
*
|
||||
* @param responseClass the result class. This class will be instantiate, therefore it
|
||||
* has to have a default constructor.
|
||||
* @param timeout optional timeout in milliseconds.
|
||||
* @param <E> a response class that extends {@link ProfileReadResponse}.
|
||||
* @return Object with a valid response.
|
||||
* @throws IllegalStateException thrown when you try to call this method from
|
||||
* the main (UI) thread.
|
||||
* @throws InterruptedException thrown when the timeout occurred before the
|
||||
* characteristic value has changed.
|
||||
* @throws IllegalArgumentException thrown when the response class could not be instantiated.
|
||||
* @throws RequestFailedException thrown when the trigger request has failed.
|
||||
* @throws DeviceDisconnectedException thrown when the device disconnected before the
|
||||
* notification or indication was received.
|
||||
* @throws BluetoothDisabledException thrown when the Bluetooth adapter has been disabled.
|
||||
* @throws InvalidRequestException thrown when the request was called before the device was
|
||||
* connected at least once (unknown device).
|
||||
* @throws InvalidDataException thrown when the received data were not valid (that is when
|
||||
* {@link ProfileReadResponse#onDataReceived(BluetoothDevice, Data)}
|
||||
* failed to parse the data correctly and called
|
||||
* {@link ProfileReadResponse#onInvalidDataReceived(BluetoothDevice, Data)}).
|
||||
* @deprecated Use {@link #timeout(long)} and {@link #awaitValid(Class)} instead.
|
||||
*/
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@NonNull
|
||||
@Deprecated
|
||||
public <E extends ProfileReadResponse> E awaitValid(@NonNull final Class<E> responseClass,
|
||||
@IntRange(from = 0) final long timeout)
|
||||
throws InterruptedException, InvalidDataException, RequestFailedException,
|
||||
DeviceDisconnectedException, BluetoothDisabledException, InvalidRequestException {
|
||||
return timeout(timeout).awaitValid(responseClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #await(Object, long)}, but if received response is not valid,
|
||||
* this method will thrown an exception.
|
||||
*
|
||||
* @param response the result object.
|
||||
* @param timeout optional timeout in milliseconds.
|
||||
* @param <E> a response class that extends {@link ProfileReadResponse}.
|
||||
* @return Object with a valid response.
|
||||
* @throws IllegalStateException thrown when you try to call this method from
|
||||
* the main (UI) thread.
|
||||
* @throws InterruptedException thrown when the timeout occurred before the
|
||||
* characteristic value has changed.
|
||||
* @throws RequestFailedException thrown when the trigger request has failed.
|
||||
* @throws DeviceDisconnectedException thrown when the device disconnected before the
|
||||
* notification or indication was received.
|
||||
* @throws BluetoothDisabledException thrown when the Bluetooth adapter has been disabled.
|
||||
* @throws InvalidRequestException thrown when the request was called before the device was
|
||||
* connected at least once (unknown device).
|
||||
* @throws InvalidDataException thrown when the received data were not valid (that is when
|
||||
* {@link ProfileReadResponse#onDataReceived(BluetoothDevice, Data)}
|
||||
* failed to parse the data correctly and called
|
||||
* {@link ProfileReadResponse#onInvalidDataReceived(BluetoothDevice, Data)}).
|
||||
* @deprecated Use {@link #timeout(long)} and {@link #awaitValid(E)} instead.
|
||||
*/
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@NonNull
|
||||
@Deprecated
|
||||
public <E extends ProfileReadResponse> E awaitValid(@NonNull final E response,
|
||||
@IntRange(from = 0) final long timeout)
|
||||
throws InterruptedException, InvalidDataException, DeviceDisconnectedException,
|
||||
RequestFailedException, BluetoothDisabledException, InvalidRequestException {
|
||||
return timeout(timeout).awaitValid(response);
|
||||
}
|
||||
|
||||
boolean matches(final byte[] packet) {
|
||||
return filter == null || filter.filter(packet);
|
||||
}
|
||||
|
||||
void notifyValueChanged(final BluetoothDevice device, final byte[] value) {
|
||||
// Keep a reference to the value callback, as it may change during execution
|
||||
final DataReceivedCallback valueCallback = this.valueCallback;
|
||||
|
||||
// With no value callback there is no need for any merging
|
||||
if (valueCallback == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dataMerger == null) {
|
||||
valueCallback.onDataReceived(device, new Data(value));
|
||||
} else {
|
||||
if (progressCallback != null)
|
||||
progressCallback.onPacketReceived(device, value, count);
|
||||
if (buffer == null)
|
||||
buffer = new DataStream();
|
||||
if (dataMerger.merge(buffer, value, count++)) {
|
||||
valueCallback.onDataReceived(device, buffer.toData());
|
||||
buffer = null;
|
||||
count = 0;
|
||||
} // else
|
||||
// wait for more packets to be merged
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasMore() {
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Request getTrigger() {
|
||||
return trigger;
|
||||
}
|
||||
|
||||
boolean isTriggerPending() {
|
||||
return triggerStatus == NOT_STARTED;
|
||||
}
|
||||
|
||||
boolean isTriggerCompleteOrNull() {
|
||||
return triggerStatus != STARTED;
|
||||
}
|
||||
}
|
||||
282
app/src/main/java/no/nordicsemi/android/ble/WriteRequest.java
Normal file
282
app/src/main/java/no/nordicsemi/android/ble/WriteRequest.java
Normal file
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattDescriptor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.annotation.WriteType;
|
||||
import no.nordicsemi.android.ble.callback.BeforeCallback;
|
||||
import no.nordicsemi.android.ble.callback.DataSentCallback;
|
||||
import no.nordicsemi.android.ble.callback.FailCallback;
|
||||
import no.nordicsemi.android.ble.callback.InvalidRequestCallback;
|
||||
import no.nordicsemi.android.ble.callback.SuccessCallback;
|
||||
import no.nordicsemi.android.ble.callback.WriteProgressCallback;
|
||||
import no.nordicsemi.android.ble.data.Data;
|
||||
import no.nordicsemi.android.ble.data.DataSplitter;
|
||||
import no.nordicsemi.android.ble.data.DefaultMtuSplitter;
|
||||
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public final class WriteRequest extends SimpleValueRequest<DataSentCallback> implements Operation {
|
||||
private final static DataSplitter MTU_SPLITTER = new DefaultMtuSplitter();
|
||||
|
||||
private WriteProgressCallback progressCallback;
|
||||
private DataSplitter dataSplitter;
|
||||
private final byte[] data;
|
||||
private final int writeType;
|
||||
private byte[] currentChunk;
|
||||
private byte[] nextChunk;
|
||||
private int count = 0;
|
||||
private boolean complete = false;
|
||||
|
||||
WriteRequest(@NonNull final Type type) {
|
||||
this(type, null);
|
||||
}
|
||||
|
||||
WriteRequest(@NonNull final Type type, @Nullable final BluetoothGattCharacteristic characteristic) {
|
||||
super(type, characteristic);
|
||||
// not used:
|
||||
this.data = null;
|
||||
this.writeType = 0;
|
||||
// getData(int) isn't called on enabling and disabling notifications/indications.
|
||||
this.complete = true;
|
||||
}
|
||||
|
||||
WriteRequest(@NonNull final Type type, @Nullable final BluetoothGattCharacteristic characteristic,
|
||||
@Nullable final byte[] data,
|
||||
@IntRange(from = 0) final int offset, @IntRange(from = 0) final int length,
|
||||
@WriteType final int writeType) {
|
||||
super(type, characteristic);
|
||||
this.data = copy(data, offset, length);
|
||||
this.writeType = writeType;
|
||||
}
|
||||
|
||||
WriteRequest(@NonNull final Type type, @Nullable final BluetoothGattDescriptor descriptor,
|
||||
@Nullable final byte[] data,
|
||||
@IntRange(from = 0) final int offset, @IntRange(from = 0) final int length) {
|
||||
super(type, descriptor);
|
||||
this.data = copy(data, offset, length);
|
||||
this.writeType = BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
WriteRequest setManager(@NonNull final BleManager manager) {
|
||||
super.setManager(manager);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public WriteRequest done(@NonNull final SuccessCallback callback) {
|
||||
super.done(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public WriteRequest fail(@NonNull final FailCallback callback) {
|
||||
super.fail(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public WriteRequest invalid(@NonNull final InvalidRequestCallback callback) {
|
||||
super.invalid(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public WriteRequest before(@NonNull final BeforeCallback callback) {
|
||||
super.before(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public WriteRequest with(@NonNull final DataSentCallback callback) {
|
||||
super.with(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a splitter that will be used to cut given data into multiple packets.
|
||||
* The splitter may modify each packet if necessary, i.e. add a flag indicating first packet,
|
||||
* continuation or the last packet.
|
||||
*
|
||||
* @param splitter an implementation of a splitter.
|
||||
* @return The request.
|
||||
* @see #split()
|
||||
*/
|
||||
@NonNull
|
||||
public WriteRequest split(@NonNull final DataSplitter splitter) {
|
||||
this.dataSplitter = splitter;
|
||||
this.progressCallback = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a splitter that will be used to cut given data into multiple packets.
|
||||
* The splitter may modify each packet if necessary, i.e. add a flag indicating first packet,
|
||||
* continuation or the last packet.
|
||||
*
|
||||
* @param splitter an implementation of a splitter.
|
||||
* @param callback the progress callback that will be notified each time a packet was sent.
|
||||
* @return The request.
|
||||
* @see #split()
|
||||
*/
|
||||
@NonNull
|
||||
public WriteRequest split(@NonNull final DataSplitter splitter,
|
||||
@NonNull final WriteProgressCallback callback) {
|
||||
this.dataSplitter = splitter;
|
||||
this.progressCallback = callback;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a default MTU splitter that will be used to cut given data into at-most MTU-3
|
||||
* bytes long packets.
|
||||
*
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public WriteRequest split() {
|
||||
this.dataSplitter = MTU_SPLITTER;
|
||||
this.progressCallback = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a default MTU splitter that will be used to cut given data into at-most MTU-3
|
||||
* bytes long packets.
|
||||
*
|
||||
* @param callback the progress callback that will be notified each time a packet was sent.
|
||||
* @return The request.
|
||||
*/
|
||||
@NonNull
|
||||
public WriteRequest split(@NonNull final WriteProgressCallback callback) {
|
||||
this.dataSplitter = MTU_SPLITTER;
|
||||
this.progressCallback = callback;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method makes sure the data sent will be split to at-most MTU-3 bytes long packets.
|
||||
* This is because Long Write does not work with Reliable Write.
|
||||
*/
|
||||
void forceSplit() {
|
||||
if (dataSplitter == null)
|
||||
split();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next chunk to be sent. If data splitter was not set the date returned may
|
||||
* be longer than MTU. Android will try to send them using Long Write sub-procedure if
|
||||
* write type is {@link BluetoothGattCharacteristic#WRITE_TYPE_DEFAULT}. Other write types
|
||||
* will cause the data to be truncated.
|
||||
*
|
||||
* @param mtu the current MTU.
|
||||
* @return The next bytes to be sent.
|
||||
*/
|
||||
byte[] getData(@IntRange(from = 23, to = 517) final int mtu) {
|
||||
if (dataSplitter == null || data == null) {
|
||||
complete = true;
|
||||
return currentChunk = data;
|
||||
}
|
||||
|
||||
// Write Request and Write Command require 3 bytes for handler and op code.
|
||||
// Write Signed requires 12 bytes, as the signature is sent.
|
||||
final int maxLength = writeType != BluetoothGattCharacteristic.WRITE_TYPE_SIGNED ?
|
||||
mtu - 3 : mtu - 12;
|
||||
|
||||
byte[] chunk = nextChunk;
|
||||
// Get the first chunk.
|
||||
if (chunk == null) {
|
||||
chunk = dataSplitter.chunk(data, count, maxLength);
|
||||
}
|
||||
// If there's something to send, check if there are any more packets to be sent later.
|
||||
if (chunk != null) {
|
||||
nextChunk = dataSplitter.chunk(data, count + 1, maxLength);
|
||||
}
|
||||
// If there's no next packet left, we are done.
|
||||
if (nextChunk == null) {
|
||||
complete = true;
|
||||
}
|
||||
return currentChunk = chunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method called when packet has been sent and confirmed (when Write With Response was used),
|
||||
* or added to local outgoing buffer (when Write Without Response was used).
|
||||
*
|
||||
* @param device the target device.
|
||||
* @param data the data received in the
|
||||
* {@link android.bluetooth.BluetoothGattCallback#onCharacteristicWrite(BluetoothGatt, BluetoothGattCharacteristic, int)}.
|
||||
* @return True, if the data received are equal to data sent.
|
||||
*/
|
||||
boolean notifyPacketSent(@NonNull final BluetoothDevice device, @Nullable final byte[] data) {
|
||||
if (progressCallback != null)
|
||||
progressCallback.onPacketSent(device, data, count);
|
||||
count++;
|
||||
if (complete && valueCallback != null)
|
||||
valueCallback.onDataSent(device, new Data(WriteRequest.this.data));
|
||||
return Arrays.equals(data, currentChunk);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether there are more bytes to be sent from this Write Request.
|
||||
* @return True if not all data were sent, false if the request is complete.
|
||||
*/
|
||||
boolean hasMore() {
|
||||
return !complete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the write type that should be used to send the data.
|
||||
* @return The write type.
|
||||
*/
|
||||
@WriteType
|
||||
int getWriteType() {
|
||||
return writeType;
|
||||
}
|
||||
|
||||
private static byte[] copy(@Nullable final byte[] value,
|
||||
@IntRange(from = 0) final int offset,
|
||||
@IntRange(from = 0) final int length) {
|
||||
if (value == null || offset > value.length)
|
||||
return null;
|
||||
final int maxLength = Math.min(value.length - offset, length);
|
||||
final byte[] copy = new byte[maxLength];
|
||||
System.arraycopy(value, offset, copy, 0, maxLength);
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.annotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import no.nordicsemi.android.ble.ConnectionPriorityRequest;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
ConnectionPriorityRequest.CONNECTION_PRIORITY_BALANCED,
|
||||
ConnectionPriorityRequest.CONNECTION_PRIORITY_HIGH,
|
||||
ConnectionPriorityRequest.CONNECTION_PRIORITY_LOW_POWER
|
||||
})
|
||||
public @interface ConnectionPriority {}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.annotation;
|
||||
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
BluetoothProfile.STATE_DISCONNECTED,
|
||||
BluetoothProfile.STATE_CONNECTING,
|
||||
BluetoothProfile.STATE_CONNECTED,
|
||||
BluetoothProfile.STATE_DISCONNECTING,
|
||||
})
|
||||
public @interface ConnectionState {}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.annotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import no.nordicsemi.android.ble.PhyRequest;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(flag = true, value = {
|
||||
PhyRequest.PHY_LE_1M_MASK,
|
||||
PhyRequest.PHY_LE_2M_MASK,
|
||||
PhyRequest.PHY_LE_CODED_MASK
|
||||
})
|
||||
public @interface PhyMask {}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.annotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import no.nordicsemi.android.ble.PhyRequest;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
PhyRequest.PHY_OPTION_NO_PREFERRED,
|
||||
PhyRequest.PHY_OPTION_S2,
|
||||
PhyRequest.PHY_OPTION_S8
|
||||
})
|
||||
public @interface PhyOption {}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.annotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import no.nordicsemi.android.ble.callback.PhyCallback;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
PhyCallback.PHY_LE_1M,
|
||||
PhyCallback.PHY_LE_2M,
|
||||
PhyCallback.PHY_LE_CODED
|
||||
})
|
||||
public @interface PhyValue {}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.annotation;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT,
|
||||
BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE,
|
||||
BluetoothGattCharacteristic.WRITE_TYPE_SIGNED,
|
||||
})
|
||||
public @interface WriteType {}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.callback;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public interface BeforeCallback {
|
||||
|
||||
/**
|
||||
* A callback invoked when the request is about to start.
|
||||
*
|
||||
* @param device the target device.
|
||||
*/
|
||||
void onRequestStarted(@NonNull final BluetoothDevice device);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.callback;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* The connection parameters for a Bluetooth LE connection is a set of parameters that determine
|
||||
* when and how the Central and a Peripheral in a link transmits data.
|
||||
* It is always the Central that actually sets the connection parameters used, but the Peripheral
|
||||
* can send a so-called Connection Parameter Update Request, that the Central can then accept or reject.
|
||||
* <p>
|
||||
* On Android, requesting connection parameters is available since Android Lollipop using
|
||||
* {@link android.bluetooth.BluetoothGatt#requestConnectionPriority(int)}. There are 3 options
|
||||
* available: {@link android.bluetooth.BluetoothGatt#CONNECTION_PRIORITY_LOW_POWER},
|
||||
* {@link android.bluetooth.BluetoothGatt#CONNECTION_PRIORITY_BALANCED} and
|
||||
* {@link android.bluetooth.BluetoothGatt#CONNECTION_PRIORITY_HIGH}. See
|
||||
* {@link no.nordicsemi.android.ble.Request#newConnectionPriorityRequest(int)} for details.
|
||||
* <p>
|
||||
* Until Android 8.0 Oreo, there was no callback indicating whether the change has succeeded,
|
||||
* or not. Also, when a Central or Peripheral requested connection parameters change without
|
||||
* explicit calling of this method, the application was not aware of it.
|
||||
* Android Oreo added a hidden callback to {@link android.bluetooth.BluetoothGattCallback}
|
||||
* notifying about connection parameters change. Those values will be reported with this callback.
|
||||
*/
|
||||
public interface ConnectionPriorityCallback {
|
||||
|
||||
/**
|
||||
* Callback indicating the connection parameters were updated. Works on Android 8.0 Oreo or newer.
|
||||
*
|
||||
* @param device the target device.
|
||||
* @param interval Connection interval used on this connection, 1.25ms unit. Valid range is from
|
||||
* 6 (7.5ms) to 3200 (4000ms).
|
||||
* @param latency Slave latency for the connection in number of connection events. Valid range
|
||||
* is from 0 to 499.
|
||||
* @param timeout Supervision timeout for this connection, in 10ms unit. Valid range is from 10
|
||||
* (100 ms = 0.1s) to 3200 (32s).
|
||||
*/
|
||||
void onConnectionUpdated(@NonNull final BluetoothDevice device,
|
||||
@IntRange(from = 6, to = 3200) final int interval,
|
||||
@IntRange(from = 0, to = 499) final int latency,
|
||||
@IntRange(from = 10, to = 3200) final int timeout);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.callback;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import no.nordicsemi.android.ble.data.Data;
|
||||
import no.nordicsemi.android.ble.data.DataMerger;
|
||||
|
||||
public interface DataReceivedCallback {
|
||||
|
||||
/**
|
||||
* Callback received each time the value was read or has changed using
|
||||
* notifications or indications.
|
||||
*
|
||||
* @param device the target device.
|
||||
* @param data the data received. If the {@link DataMerger} was used,
|
||||
* this contains the merged result.
|
||||
*/
|
||||
void onDataReceived(@NonNull final BluetoothDevice device, @NonNull final Data data);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.callback;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import no.nordicsemi.android.ble.data.Data;
|
||||
import no.nordicsemi.android.ble.data.DataSplitter;
|
||||
|
||||
public interface DataSentCallback {
|
||||
|
||||
/**
|
||||
* Callback received each time the value was written to a characteristic or descriptor.
|
||||
*
|
||||
* @param device the target device.
|
||||
* @param data the data sent. If the {@link DataSplitter} was used, this contains the full data.
|
||||
*/
|
||||
void onDataSent(@NonNull final BluetoothDevice device, @NonNull final Data data);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.callback;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public interface FailCallback {
|
||||
int REASON_DEVICE_DISCONNECTED = -1;
|
||||
int REASON_DEVICE_NOT_SUPPORTED = -2;
|
||||
int REASON_NULL_ATTRIBUTE = -3;
|
||||
int REASON_REQUEST_FAILED = -4;
|
||||
int REASON_TIMEOUT = -5;
|
||||
int REASON_VALIDATION = -6;
|
||||
int REASON_BLUETOOTH_DISABLED = -100;
|
||||
|
||||
/**
|
||||
* A callback invoked when the request has failed with status other than
|
||||
* {@link android.bluetooth.BluetoothGatt#GATT_SUCCESS}.
|
||||
*
|
||||
* @param device target device.
|
||||
* @param status error status code, one of BluetoothGatt#GATT_* constants or
|
||||
* {@link #REASON_DEVICE_DISCONNECTED}, {@link #REASON_TIMEOUT},
|
||||
* {@link #REASON_DEVICE_NOT_SUPPORTED} (only for Connect request),
|
||||
* {@link #REASON_BLUETOOTH_DISABLED}, {@link #REASON_NULL_ATTRIBUTE},
|
||||
* {@link #REASON_VALIDATION} or {@link #REASON_REQUEST_FAILED} (for other reason).
|
||||
*/
|
||||
void onRequestFailed(@NonNull final BluetoothDevice device, final int status);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.callback;
|
||||
|
||||
public interface InvalidRequestCallback {
|
||||
|
||||
/**
|
||||
* A callback invoked when the request was invalid, for example when was called before the
|
||||
* device was connected.
|
||||
*/
|
||||
void onInvalidRequest();
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.callback;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public interface MtuCallback {
|
||||
|
||||
/**
|
||||
* Method called when the MTU request has finished with success. The MTU value may
|
||||
* be different than requested one. The maximum packet size is 3 bytes less then MTU.
|
||||
*
|
||||
* @param device the target device.
|
||||
* @param mtu the new MTU (Maximum Transfer Unit).
|
||||
*/
|
||||
void onMtuChanged(@NonNull final BluetoothDevice device,
|
||||
@IntRange(from = 23, to = 517) final int mtu);
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.callback;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import no.nordicsemi.android.ble.annotation.PhyValue;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public interface PhyCallback {
|
||||
/**
|
||||
* Bluetooth LE 1M PHY. Used to refer to LE 1M Physical Channel for advertising, scanning or
|
||||
* connection.
|
||||
*/
|
||||
int PHY_LE_1M = 1;
|
||||
|
||||
/**
|
||||
* Bluetooth LE 2M PHY. Used to refer to LE 2M Physical Channel for advertising, scanning or
|
||||
* connection.
|
||||
*/
|
||||
int PHY_LE_2M = 2;
|
||||
|
||||
/**
|
||||
* Bluetooth LE Coded PHY. Used to refer to LE Coded Physical Channel for advertising, scanning
|
||||
* or connection.
|
||||
*/
|
||||
int PHY_LE_CODED = 3;
|
||||
|
||||
/**
|
||||
* Method called when the PHY value has changed or was read.
|
||||
*
|
||||
* @param device the target device.
|
||||
* @param txPhy the transmitter PHY in use. One of {@link #PHY_LE_1M},
|
||||
* {@link #PHY_LE_2M}, and {@link #PHY_LE_CODED}.
|
||||
* @param rxPhy the receiver PHY in use. One of {@link #PHY_LE_1M},
|
||||
* {@link #PHY_LE_2M}, and {@link #PHY_LE_CODED}.
|
||||
*/
|
||||
void onPhyChanged(@NonNull final BluetoothDevice device,
|
||||
@PhyValue final int txPhy, @PhyValue final int rxPhy);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.callback;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.data.DataMerger;
|
||||
|
||||
public interface ReadProgressCallback {
|
||||
|
||||
/**
|
||||
* Callback received each time the value was read or has changed using notifications or
|
||||
* indications when {@link DataMerger} was used.
|
||||
*
|
||||
* @param device the target device.
|
||||
* @param data the last packet received.
|
||||
* @param index the index of a packet that will be merged into a single Data.
|
||||
*/
|
||||
void onPacketReceived(@NonNull final BluetoothDevice device,
|
||||
@Nullable final byte[] data, @IntRange(from = 0) final int index);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.callback;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public interface RssiCallback {
|
||||
|
||||
/**
|
||||
* Method called when the RSSI value has been read.
|
||||
*
|
||||
* @param device the target device.
|
||||
* @param rssi the current RSSI value, in dBm.
|
||||
*/
|
||||
void onRssiRead(@NonNull final BluetoothDevice device,
|
||||
@IntRange(from = -128, to = 20) final int rssi);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.callback;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public interface SuccessCallback {
|
||||
|
||||
/**
|
||||
* A callback invoked when the request completed successfully.
|
||||
*
|
||||
* @param device the target device.
|
||||
*/
|
||||
void onRequestCompleted(@NonNull final BluetoothDevice device);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.callback;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.data.DataSplitter;
|
||||
|
||||
public interface WriteProgressCallback {
|
||||
|
||||
/**
|
||||
* Callback called each time a packet has been sent when {@link DataSplitter} was used.
|
||||
*
|
||||
* @param device the target device.
|
||||
* @param data the last packet sent.
|
||||
* @param index the index of a packet that the initial Data was cut into.
|
||||
*/
|
||||
void onPacketSent(@NonNull final BluetoothDevice device,
|
||||
@Nullable final byte[] data, @IntRange(from = 0) final int index);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.callback.profile;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import no.nordicsemi.android.ble.callback.DataReceivedCallback;
|
||||
import no.nordicsemi.android.ble.data.Data;
|
||||
import no.nordicsemi.android.ble.data.DataMerger;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public interface ProfileDataCallback extends DataReceivedCallback {
|
||||
|
||||
/**
|
||||
* Callback called when the data received do not conform to required scheme.
|
||||
* @param device the target device.
|
||||
* @param data the data received. If the {@link DataMerger} was used, this contains the
|
||||
* merged result.
|
||||
*/
|
||||
default void onInvalidDataReceived(@NonNull final BluetoothDevice device,
|
||||
@NonNull final Data data) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.callback.profile;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import no.nordicsemi.android.ble.data.Data;
|
||||
import no.nordicsemi.android.ble.response.ReadResponse;
|
||||
|
||||
/**
|
||||
* A response type for read requests with basic validation check.
|
||||
* When read was requested as a synchronous call the {@link #isValid()} can be used to
|
||||
* check if data were parsed successfully. Parsing method must call super methods on
|
||||
* both {@link #onDataReceived(BluetoothDevice, Data)} and
|
||||
* {@link #onInvalidDataReceived(BluetoothDevice, Data)} in order to make getters working properly.
|
||||
* <p>
|
||||
* Check out profile data callbacks in the Android BLE Common Library for example of usage.
|
||||
*/
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public class ProfileReadResponse extends ReadResponse implements ProfileDataCallback, Parcelable {
|
||||
private boolean valid = true;
|
||||
|
||||
public ProfileReadResponse() {
|
||||
// empty
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInvalidDataReceived(@NonNull final BluetoothDevice device,
|
||||
@NonNull final Data data) {
|
||||
this.valid = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if {@link #onInvalidDataReceived(BluetoothDevice, Data)} wasn't called.
|
||||
*
|
||||
* @return True, if profile data were valid, false if parsing error occurred.
|
||||
*/
|
||||
public boolean isValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
// Parcelable
|
||||
protected ProfileReadResponse(final Parcel in) {
|
||||
super(in);
|
||||
valid = in.readByte() != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel dest, final int flags) {
|
||||
super.writeToParcel(dest, flags);
|
||||
dest.writeByte((byte) (valid ? 1 : 0));
|
||||
}
|
||||
|
||||
public static final Creator<ProfileReadResponse> CREATOR = new Creator<ProfileReadResponse>() {
|
||||
@Override
|
||||
public ProfileReadResponse createFromParcel(final Parcel in) {
|
||||
return new ProfileReadResponse(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProfileReadResponse[] newArray(final int size) {
|
||||
return new ProfileReadResponse[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
470
app/src/main/java/no/nordicsemi/android/ble/data/Data.java
Normal file
470
app/src/main/java/no/nordicsemi/android/ble/data/Data.java
Normal file
@@ -0,0 +1,470 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.data;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattDescriptor;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@SuppressWarnings({"WeakerAccess", "unused", "UnusedReturnValue"})
|
||||
public class Data implements Parcelable {
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
FORMAT_UINT8,
|
||||
FORMAT_UINT16,
|
||||
FORMAT_UINT24,
|
||||
FORMAT_UINT32,
|
||||
FORMAT_SINT8,
|
||||
FORMAT_SINT16,
|
||||
FORMAT_SINT24,
|
||||
FORMAT_SINT32,
|
||||
FORMAT_FLOAT,
|
||||
FORMAT_SFLOAT
|
||||
})
|
||||
public @interface ValueFormat {}
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
FORMAT_UINT8,
|
||||
FORMAT_UINT16,
|
||||
FORMAT_UINT24,
|
||||
FORMAT_UINT32,
|
||||
FORMAT_SINT8,
|
||||
FORMAT_SINT16,
|
||||
FORMAT_SINT24,
|
||||
FORMAT_SINT32
|
||||
})
|
||||
public @interface IntFormat {}
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
FORMAT_UINT32,
|
||||
FORMAT_SINT32
|
||||
})
|
||||
public @interface LongFormat {}
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(value = {
|
||||
FORMAT_FLOAT,
|
||||
FORMAT_SFLOAT
|
||||
})
|
||||
public @interface FloatFormat {}
|
||||
|
||||
private static char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
|
||||
|
||||
/**
|
||||
* Data value format type uint8
|
||||
*/
|
||||
public final static int FORMAT_UINT8 = 0x11;
|
||||
|
||||
/**
|
||||
* Data value format type uint16
|
||||
*/
|
||||
public final static int FORMAT_UINT16 = 0x12;
|
||||
|
||||
/**
|
||||
* Data value format type uint24
|
||||
*/
|
||||
public final static int FORMAT_UINT24 = 0x13;
|
||||
|
||||
/**
|
||||
* Data value format type uint32
|
||||
*/
|
||||
public final static int FORMAT_UINT32 = 0x14;
|
||||
|
||||
/**
|
||||
* Data value format type sint8
|
||||
*/
|
||||
public final static int FORMAT_SINT8 = 0x21;
|
||||
|
||||
/**
|
||||
* Data value format type sint16
|
||||
*/
|
||||
public final static int FORMAT_SINT16 = 0x22;
|
||||
|
||||
/**
|
||||
* Data value format type sint24
|
||||
*/
|
||||
public final static int FORMAT_SINT24 = 0x23;
|
||||
|
||||
/**
|
||||
* Data value format type sint32
|
||||
*/
|
||||
public final static int FORMAT_SINT32 = 0x24;
|
||||
|
||||
/**
|
||||
* Data value format type sfloat (16-bit float, IEEE-11073)
|
||||
*/
|
||||
public final static int FORMAT_SFLOAT = 0x32;
|
||||
|
||||
/**
|
||||
* Data value format type float (32-bit float, IEEE-11073)
|
||||
*/
|
||||
public final static int FORMAT_FLOAT = 0x34;
|
||||
|
||||
protected byte[] mValue;
|
||||
|
||||
public Data() {
|
||||
this.mValue = null;
|
||||
}
|
||||
|
||||
public Data(@Nullable final byte[] value) {
|
||||
this.mValue = value;
|
||||
}
|
||||
|
||||
public static Data from(@NonNull final String value) {
|
||||
return new Data(value.getBytes()); // UTF-8
|
||||
}
|
||||
|
||||
public static Data from(@NonNull final BluetoothGattCharacteristic characteristic) {
|
||||
return new Data(characteristic.getValue());
|
||||
}
|
||||
|
||||
public static Data from(@NonNull final BluetoothGattDescriptor descriptor) {
|
||||
return new Data(descriptor.getValue());
|
||||
}
|
||||
|
||||
public static Data opCode(final byte opCode) {
|
||||
return new Data(new byte[] { opCode });
|
||||
}
|
||||
|
||||
public static Data opCode(final byte opCode, final byte parameter) {
|
||||
return new Data(new byte[] { opCode, parameter });
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying byte array.
|
||||
*
|
||||
* @return Data received.
|
||||
*/
|
||||
@Nullable
|
||||
public byte[] getValue() {
|
||||
return mValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the stored value of this characteristic.
|
||||
* <p>See {@link #getValue} for details.
|
||||
*
|
||||
* @param offset Offset at which the string value can be found.
|
||||
* @return Cached value of the characteristic
|
||||
*/
|
||||
@Nullable
|
||||
public String getStringValue(@IntRange(from = 0) final int offset) {
|
||||
if (mValue == null || offset > mValue.length)
|
||||
return null;
|
||||
final byte[] strBytes = new byte[mValue.length - offset];
|
||||
for (int i = 0; i != (mValue.length - offset); ++i)
|
||||
strBytes[i] = mValue[offset+i];
|
||||
return new String(strBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of underlying byte array.
|
||||
*
|
||||
* @return Length of the data.
|
||||
*/
|
||||
public int size() {
|
||||
return mValue != null ? mValue.length : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (size() == 0)
|
||||
return "";
|
||||
|
||||
final char[] out = new char[mValue.length * 3 - 1];
|
||||
for (int j = 0; j < mValue.length; j++) {
|
||||
int v = mValue[j] & 0xFF;
|
||||
out[j * 3] = HEX_ARRAY[v >>> 4];
|
||||
out[j * 3 + 1] = HEX_ARRAY[v & 0x0F];
|
||||
if (j != mValue.length - 1)
|
||||
out[j * 3 + 2] = '-';
|
||||
}
|
||||
return "(0x) " + new String(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a byte at the given offset from the byte array.
|
||||
*
|
||||
* @param offset Offset at which the byte value can be found.
|
||||
* @return Cached value or null of offset exceeds value size.
|
||||
*/
|
||||
@Nullable
|
||||
public Byte getByte(@IntRange(from = 0) final int offset) {
|
||||
if (offset + 1 > size()) return null;
|
||||
|
||||
return mValue[offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an integer value from the byte array.
|
||||
* <p>
|
||||
* <p>The formatType parameter determines how the value
|
||||
* is to be interpreted. For example, setting formatType to
|
||||
* {@link #FORMAT_UINT16} specifies that the first two bytes of the
|
||||
* value at the given offset are interpreted to generate the
|
||||
* return value.
|
||||
*
|
||||
* @param formatType The format type used to interpret the value.
|
||||
* @param offset Offset at which the integer value can be found.
|
||||
* @return Cached value or null of offset exceeds value size.
|
||||
*/
|
||||
@Nullable
|
||||
public Integer getIntValue(@IntFormat final int formatType,
|
||||
@IntRange(from = 0) final int offset) {
|
||||
if ((offset + getTypeLen(formatType)) > size()) return null;
|
||||
|
||||
switch (formatType) {
|
||||
case FORMAT_UINT8:
|
||||
return unsignedByteToInt(mValue[offset]);
|
||||
|
||||
case FORMAT_UINT16:
|
||||
return unsignedBytesToInt(mValue[offset], mValue[offset + 1]);
|
||||
|
||||
case FORMAT_UINT24:
|
||||
return unsignedBytesToInt(mValue[offset], mValue[offset + 1],
|
||||
mValue[offset + 2], (byte) 0);
|
||||
|
||||
case FORMAT_UINT32:
|
||||
return unsignedBytesToInt(mValue[offset], mValue[offset + 1],
|
||||
mValue[offset + 2], mValue[offset + 3]);
|
||||
|
||||
case FORMAT_SINT8:
|
||||
return unsignedToSigned(unsignedByteToInt(mValue[offset]), 8);
|
||||
|
||||
case FORMAT_SINT16:
|
||||
return unsignedToSigned(unsignedBytesToInt(mValue[offset],
|
||||
mValue[offset + 1]), 16);
|
||||
|
||||
case FORMAT_SINT24:
|
||||
return unsignedToSigned(unsignedBytesToInt(mValue[offset],
|
||||
mValue[offset + 1], mValue[offset + 2], (byte) 0), 24);
|
||||
|
||||
case FORMAT_SINT32:
|
||||
return unsignedToSigned(unsignedBytesToInt(mValue[offset],
|
||||
mValue[offset + 1], mValue[offset + 2], mValue[offset + 3]), 32);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a long value from the byte array.
|
||||
* <p>Only {@link #FORMAT_UINT32} and {@link #FORMAT_SINT32} are supported.
|
||||
* <p>The formatType parameter determines how the value
|
||||
* is to be interpreted. For example, setting formatType to
|
||||
* {@link #FORMAT_UINT32} specifies that the first four bytes of the
|
||||
* value at the given offset are interpreted to generate the
|
||||
* return value.
|
||||
*
|
||||
* @param formatType The format type used to interpret the value.
|
||||
* @param offset Offset at which the integer value can be found.
|
||||
* @return Cached value or null of offset exceeds value size.
|
||||
*/
|
||||
@Nullable
|
||||
public Long getLongValue(@LongFormat final int formatType,
|
||||
@IntRange(from = 0) final int offset) {
|
||||
if ((offset + getTypeLen(formatType)) > size()) return null;
|
||||
|
||||
switch (formatType) {
|
||||
case FORMAT_SINT32:
|
||||
return unsignedToSigned(unsignedBytesToLong(mValue[offset],
|
||||
mValue[offset + 1], mValue[offset + 2], mValue[offset + 3]), 32);
|
||||
|
||||
case FORMAT_UINT32:
|
||||
return unsignedBytesToLong(mValue[offset], mValue[offset + 1],
|
||||
mValue[offset + 2], mValue[offset + 3]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an float value from the given byte array.
|
||||
*
|
||||
* @param formatType The format type used to interpret the value.
|
||||
* @param offset Offset at which the float value can be found.
|
||||
* @return Cached value at a given offset or null if the requested offset exceeds the value size.
|
||||
*/
|
||||
@Nullable
|
||||
public Float getFloatValue(@FloatFormat final int formatType,
|
||||
@IntRange(from = 0) final int offset) {
|
||||
if ((offset + getTypeLen(formatType)) > size()) return null;
|
||||
|
||||
switch (formatType) {
|
||||
case FORMAT_SFLOAT:
|
||||
if (mValue[offset + 1] == 0x07 && mValue[offset] == (byte) 0xFE)
|
||||
return Float.POSITIVE_INFINITY;
|
||||
if ((mValue[offset + 1] == 0x07 && mValue[offset] == (byte) 0xFF) ||
|
||||
(mValue[offset + 1] == 0x08 && mValue[offset] == 0x00) ||
|
||||
(mValue[offset + 1] == 0x08 && mValue[offset] == 0x01))
|
||||
return Float.NaN;
|
||||
if (mValue[offset + 1] == 0x08 && mValue[offset] == 0x02)
|
||||
return Float.NEGATIVE_INFINITY;
|
||||
|
||||
return bytesToFloat(mValue[offset], mValue[offset + 1]);
|
||||
|
||||
case FORMAT_FLOAT:
|
||||
if (mValue[offset + 3] == 0x00) {
|
||||
if (mValue[offset + 2] == 0x7F && mValue[offset + 1] == (byte) 0xFF) {
|
||||
if (mValue[offset] == (byte) 0xFE)
|
||||
return Float.POSITIVE_INFINITY;
|
||||
if (mValue[offset] == (byte) 0xFF)
|
||||
return Float.NaN;
|
||||
} else if (mValue[offset + 2] == (byte) 0x80 && mValue[offset + 1] == 0x00) {
|
||||
if (mValue[offset] == 0x00 || mValue[offset] == 0x01)
|
||||
return Float.NaN;
|
||||
if (mValue[offset] == 0x02)
|
||||
return Float.NEGATIVE_INFINITY;
|
||||
}
|
||||
}
|
||||
|
||||
return bytesToFloat(mValue[offset], mValue[offset + 1],
|
||||
mValue[offset + 2], mValue[offset + 3]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of a give value type.
|
||||
*/
|
||||
public static int getTypeLen(@ValueFormat final int formatType) {
|
||||
return formatType & 0xF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a signed byte to an unsigned int.
|
||||
*/
|
||||
private static int unsignedByteToInt(final byte b) {
|
||||
return b & 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a signed byte to an unsigned int.
|
||||
*/
|
||||
private static long unsignedByteToLong(final byte b) {
|
||||
return b & 0xFFL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert signed bytes to a 16-bit unsigned int.
|
||||
*/
|
||||
private static int unsignedBytesToInt(final byte b0, final byte b1) {
|
||||
return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert signed bytes to a 32-bit unsigned int.
|
||||
*/
|
||||
private static int unsignedBytesToInt(final byte b0, final byte b1, final byte b2, final byte b3) {
|
||||
return (unsignedByteToInt(b0) + (unsignedByteToInt(b1) << 8))
|
||||
+ (unsignedByteToInt(b2) << 16) + (unsignedByteToInt(b3) << 24);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert signed bytes to a 32-bit unsigned long.
|
||||
*/
|
||||
private static long unsignedBytesToLong(final byte b0, final byte b1, final byte b2, final byte b3) {
|
||||
return (unsignedByteToLong(b0) + (unsignedByteToLong(b1) << 8))
|
||||
+ (unsignedByteToLong(b2) << 16) + (unsignedByteToLong(b3) << 24);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert signed bytes to a 16-bit short float value.
|
||||
*/
|
||||
private static float bytesToFloat(final byte b0, final byte b1) {
|
||||
int mantissa = unsignedToSigned(unsignedByteToInt(b0)
|
||||
+ ((unsignedByteToInt(b1) & 0x0F) << 8), 12);
|
||||
int exponent = unsignedToSigned(unsignedByteToInt(b1) >> 4, 4);
|
||||
return (float) (mantissa * Math.pow(10, exponent));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert signed bytes to a 32-bit short float value.
|
||||
*/
|
||||
private static float bytesToFloat(final byte b0, final byte b1, final byte b2, final byte b3) {
|
||||
int mantissa = unsignedToSigned(unsignedByteToInt(b0)
|
||||
+ (unsignedByteToInt(b1) << 8)
|
||||
+ (unsignedByteToInt(b2) << 16), 24);
|
||||
return (float) (mantissa * Math.pow(10, b3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an unsigned integer value to a two's-complement encoded
|
||||
* signed value.
|
||||
*/
|
||||
private static int unsignedToSigned(int unsigned, final int size) {
|
||||
if ((unsigned & (1 << size - 1)) != 0) {
|
||||
unsigned = -1 * ((1 << size - 1) - (unsigned & ((1 << size - 1) - 1)));
|
||||
}
|
||||
return unsigned;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an unsigned long value to a two's-complement encoded
|
||||
* signed value.
|
||||
*/
|
||||
private static long unsignedToSigned(long unsigned, final int size) {
|
||||
if ((unsigned & (1 << size - 1)) != 0) {
|
||||
unsigned = -1 * ((1 << size - 1) - (unsigned & ((1 << size - 1) - 1)));
|
||||
}
|
||||
return unsigned;
|
||||
}
|
||||
|
||||
// Parcelable
|
||||
protected Data(final Parcel in) {
|
||||
mValue = in.createByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel dest, final int flags) {
|
||||
dest.writeByteArray(mValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Creator<Data> CREATOR = new Creator<Data>() {
|
||||
@Override
|
||||
public Data createFromParcel(final Parcel in) {
|
||||
return new Data(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Data[] newArray(final int size) {
|
||||
return new Data[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.data;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public interface DataFilter {
|
||||
|
||||
/**
|
||||
* This method should return true if the packet matches the filter and should be processed
|
||||
* by the request.
|
||||
*
|
||||
* @param lastPacket the packet received.
|
||||
* @return True, if packet should be processed, false if it should be ignored.
|
||||
*/
|
||||
boolean filter(@Nullable final byte[] lastPacket);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.data;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public interface DataMerger {
|
||||
|
||||
/**
|
||||
* This method should merge the last packet into the output message.
|
||||
*
|
||||
* @param output the stream for the output message, initially empty.
|
||||
* @param lastPacket the data received in the last read/notify/indicate operation.
|
||||
* @param index an index of the packet, 0-based (if you expect 3 packets, they will be
|
||||
* called with indexes 0, 1, 2).
|
||||
* @return True, if the message is complete, false if more data are expected.
|
||||
*/
|
||||
boolean merge(@NonNull final DataStream output,
|
||||
@Nullable final byte[] lastPacket, @IntRange(from = 0) final int index);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.data;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public interface DataSplitter {
|
||||
|
||||
/**
|
||||
* The implementation should return a index'th byte array from given message,
|
||||
* with at most maxLength size, or null if no bytes are left to be sent.
|
||||
*
|
||||
* @param message the full message to be chunk.
|
||||
* @param index index of a packet, 0-based.
|
||||
* @param maxLength maximum length of the returned packet. Equals to MTU-3.
|
||||
* Use {@link no.nordicsemi.android.ble.BleManager#requestMtu(int)} to request
|
||||
* higher MTU, or {@link no.nordicsemi.android.ble.BleManager#overrideMtu(int)}
|
||||
* If the MTU change was initiated by the target device.
|
||||
* @return The packet to be sent, or null, if the whole message was already split.
|
||||
*/
|
||||
@Nullable
|
||||
byte[] chunk(@NonNull final byte[] message,
|
||||
@IntRange(from = 0) final int index, @IntRange(from = 20) final int maxLength);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.data;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public class DataStream {
|
||||
private final ByteArrayOutputStream buffer;
|
||||
|
||||
public DataStream() {
|
||||
buffer = new ByteArrayOutputStream();
|
||||
}
|
||||
|
||||
@SuppressWarnings("SimplifiableIfStatement")
|
||||
public boolean write(@Nullable final byte[] data) {
|
||||
if (data == null)
|
||||
return false;
|
||||
|
||||
return write(data, 0, data.length);
|
||||
}
|
||||
|
||||
public boolean write(@Nullable final byte[] data,
|
||||
@IntRange(from = 0) final int offset, @IntRange(from = 0) final int length) {
|
||||
if (data == null || data.length < offset)
|
||||
return false;
|
||||
|
||||
final int len = Math.min(data.length - offset, length);
|
||||
buffer.write(data, offset, len);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean write(@Nullable final Data data) {
|
||||
return data != null && write(data.getValue());
|
||||
}
|
||||
|
||||
@IntRange(from = 0)
|
||||
public int size() {
|
||||
return buffer.size();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public byte[] toByteArray() {
|
||||
return buffer.toByteArray();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Data toData() {
|
||||
return new Data(buffer.toByteArray());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.data;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Splits the message into at-most MTU-3 size packets.
|
||||
*/
|
||||
public final class DefaultMtuSplitter implements DataSplitter {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public byte[] chunk(@NonNull final byte[] message,
|
||||
@IntRange(from = 0) final int index,
|
||||
@IntRange(from = 20) final int maxLength) {
|
||||
final int offset = index * maxLength;
|
||||
final int length = Math.min(maxLength, message.length - offset);
|
||||
|
||||
if (length <= 0)
|
||||
return null;
|
||||
|
||||
final byte[] data = new byte[length];
|
||||
System.arraycopy(message, offset, data, 0, length);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.data;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattDescriptor;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@SuppressWarnings({"unused", "SameParameterValue", "WeakerAccess", "UnusedReturnValue"})
|
||||
public class MutableData extends Data {
|
||||
// Values required to convert float to IEEE-11073 SFLOAT
|
||||
private final static int SFLOAT_POSITIVE_INFINITY = 0x07FE;
|
||||
private final static int SFLOAT_NAN = 0x07FF;
|
||||
// private final static int SFLOAT_NOT_AT_THIS_RESOLUTION = 0x0800;
|
||||
// private final static int SFLOAT_RESERVED_VALUE = 0x0801;
|
||||
private final static int SFLOAT_NEGATIVE_INFINITY = 0x0802;
|
||||
private final static int SFLOAT_MANTISSA_MAX = 0x07FD;
|
||||
private final static int SFLOAT_EXPONENT_MAX = 7;
|
||||
private final static int SFLOAT_EXPONENT_MIN = -8;
|
||||
private final static float SFLOAT_MAX = 20450000000.0f;
|
||||
private final static float SFLOAT_MIN = -SFLOAT_MAX;
|
||||
private final static int SFLOAT_PRECISION = 10000;
|
||||
// private final static float SFLOAT_EPSILON = 1e-8f;
|
||||
|
||||
// Values required to convert float to IEEE-11073 FLOAT
|
||||
private final static int FLOAT_POSITIVE_INFINITY = 0x007FFFFE;
|
||||
private final static int FLOAT_NAN = 0x007FFFFF;
|
||||
// private final static int FLOAT_NOT_AT_THIS_RESOLUTION = 0x00800000;
|
||||
// private final static int FLOAT_RESERVED_VALUE = 0x00800001;
|
||||
private final static int FLOAT_NEGATIVE_INFINITY = 0x00800002;
|
||||
private final static int FLOAT_MANTISSA_MAX = 0x007FFFFD;
|
||||
private final static int FLOAT_EXPONENT_MAX = 127;
|
||||
private final static int FLOAT_EXPONENT_MIN = -128;
|
||||
private final static int FLOAT_PRECISION = 10000000;
|
||||
// private final static float FLOAT_EPSILON = 1e-128f;
|
||||
|
||||
public MutableData() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MutableData(@Nullable final byte[] data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
public static MutableData from(@NonNull final BluetoothGattCharacteristic characteristic) {
|
||||
return new MutableData(characteristic.getValue());
|
||||
}
|
||||
|
||||
public static MutableData from(@NonNull final BluetoothGattDescriptor descriptor) {
|
||||
return new MutableData(descriptor.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the locally stored value of this data.
|
||||
*
|
||||
* @param value New value
|
||||
* @return true if the locally stored value has been set, false if the
|
||||
* requested value could not be stored locally.
|
||||
*/
|
||||
public boolean setValue(@Nullable final byte[] value) {
|
||||
mValue = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the byte at offset position.
|
||||
*
|
||||
* @param value Byte to set
|
||||
* @param offset The offset
|
||||
* @return true if the locally stored value has been set, false if the
|
||||
* requested value could not be stored locally.
|
||||
*/
|
||||
public boolean setByte(final int value, @IntRange(from = 0) final int offset) {
|
||||
final int len = offset + 1;
|
||||
if (mValue == null) mValue = new byte[len];
|
||||
if (len > mValue.length) return false;
|
||||
mValue[offset] = (byte) value;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the locally stored value of this data.
|
||||
* <p>See {@link #setValue(byte[])} for details.
|
||||
*
|
||||
* @param value New value for this data
|
||||
* @param formatType Integer format type used to transform the value parameter
|
||||
* @param offset Offset at which the value should be placed
|
||||
* @return true if the locally stored value has been set
|
||||
*/
|
||||
public boolean setValue(int value, @IntFormat int formatType, @IntRange(from = 0) int offset) {
|
||||
final int len = offset + getTypeLen(formatType);
|
||||
if (mValue == null) mValue = new byte[len];
|
||||
if (len > mValue.length) return false;
|
||||
|
||||
switch (formatType) {
|
||||
case FORMAT_SINT8:
|
||||
value = intToSignedBits(value, 8);
|
||||
// Fall-through intended
|
||||
case FORMAT_UINT8:
|
||||
mValue[offset] = (byte) (value & 0xFF);
|
||||
break;
|
||||
|
||||
case FORMAT_SINT16:
|
||||
value = intToSignedBits(value, 16);
|
||||
// Fall-through intended
|
||||
case FORMAT_UINT16:
|
||||
mValue[offset++] = (byte) (value & 0xFF);
|
||||
mValue[offset] = (byte) ((value >> 8) & 0xFF);
|
||||
break;
|
||||
|
||||
case FORMAT_SINT24:
|
||||
value = intToSignedBits(value, 24);
|
||||
// Fall-through intended
|
||||
case FORMAT_UINT24:
|
||||
mValue[offset++] = (byte) (value & 0xFF);
|
||||
mValue[offset++] = (byte) ((value >> 8) & 0xFF);
|
||||
mValue[offset] = (byte) ((value >> 16) & 0xFF);
|
||||
break;
|
||||
|
||||
case FORMAT_SINT32:
|
||||
value = intToSignedBits(value, 32);
|
||||
// Fall-through intended
|
||||
case FORMAT_UINT32:
|
||||
mValue[offset++] = (byte) (value & 0xFF);
|
||||
mValue[offset++] = (byte) ((value >> 8) & 0xFF);
|
||||
mValue[offset++] = (byte) ((value >> 16) & 0xFF);
|
||||
mValue[offset] = (byte) ((value >> 24) & 0xFF);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the locally stored value of this data.
|
||||
* <p>See {@link #setValue(byte[])} for details.
|
||||
*
|
||||
* @param mantissa Mantissa for this data
|
||||
* @param exponent Exponent value for this data
|
||||
* @param formatType Float format type used to transform the value parameter
|
||||
* @param offset Offset at which the value should be placed
|
||||
* @return true if the locally stored value has been set
|
||||
*/
|
||||
public boolean setValue(int mantissa, int exponent,
|
||||
@FloatFormat int formatType, @IntRange(from = 0) int offset) {
|
||||
final int len = offset + getTypeLen(formatType);
|
||||
if (mValue == null) mValue = new byte[len];
|
||||
if (len > mValue.length) return false;
|
||||
|
||||
switch (formatType) {
|
||||
case FORMAT_SFLOAT:
|
||||
mantissa = intToSignedBits(mantissa, 12);
|
||||
exponent = intToSignedBits(exponent, 4);
|
||||
mValue[offset++] = (byte) (mantissa & 0xFF);
|
||||
mValue[offset] = (byte) ((mantissa >> 8) & 0x0F);
|
||||
mValue[offset] += (byte) ((exponent & 0x0F) << 4);
|
||||
break;
|
||||
|
||||
case FORMAT_FLOAT:
|
||||
mantissa = intToSignedBits(mantissa, 24);
|
||||
exponent = intToSignedBits(exponent, 8);
|
||||
mValue[offset++] = (byte) (mantissa & 0xFF);
|
||||
mValue[offset++] = (byte) ((mantissa >> 8) & 0xFF);
|
||||
mValue[offset++] = (byte) ((mantissa >> 16) & 0xFF);
|
||||
mValue[offset] += (byte) (exponent & 0xFF);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the locally stored value of this data.
|
||||
* <p>See {@link #setValue(byte[])} for details.
|
||||
*
|
||||
* @param value New value for this data. This allows to send {@link #FORMAT_UINT32}.
|
||||
* @param formatType Integer format type used to transform the value parameter
|
||||
* @param offset Offset at which the value should be placed
|
||||
* @return true if the locally stored value has been set
|
||||
*/
|
||||
public boolean setValue(long value, @LongFormat int formatType, @IntRange(from = 0) int offset) {
|
||||
final int len = offset + getTypeLen(formatType);
|
||||
if (mValue == null) mValue = new byte[len];
|
||||
if (len > mValue.length) return false;
|
||||
|
||||
switch (formatType) {
|
||||
case FORMAT_SINT32:
|
||||
value = longToSignedBits(value, 32);
|
||||
// Fall-through intended
|
||||
case FORMAT_UINT32:
|
||||
mValue[offset++] = (byte) (value & 0xFF);
|
||||
mValue[offset++] = (byte) ((value >> 8) & 0xFF);
|
||||
mValue[offset++] = (byte) ((value >> 16) & 0xFF);
|
||||
mValue[offset] = (byte) ((value >> 24) & 0xFF);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the locally stored value of this data.
|
||||
* <p>See {@link #setValue(byte[])} for details.
|
||||
*
|
||||
* @param value Float value to be written
|
||||
* @param formatType Float format type used to transform the value parameter
|
||||
* @param offset Offset at which the value should be placed
|
||||
* @return true if the locally stored value has been set
|
||||
*/
|
||||
public boolean setValue(float value,
|
||||
@FloatFormat int formatType, @IntRange(from = 0) int offset) {
|
||||
final int len = offset + getTypeLen(formatType);
|
||||
if (mValue == null) mValue = new byte[len];
|
||||
if (len > mValue.length) return false;
|
||||
|
||||
switch (formatType) {
|
||||
case FORMAT_SFLOAT:
|
||||
final int sfloatAsInt = sfloatToInt(value);
|
||||
mValue[offset++] = (byte) (sfloatAsInt & 0xFF);
|
||||
mValue[offset] = (byte) ((sfloatAsInt >> 8) & 0xFF);
|
||||
break;
|
||||
|
||||
case FORMAT_FLOAT:
|
||||
final int floatAsInt = floatToInt(value);
|
||||
mValue[offset++] = (byte) (floatAsInt & 0xFF);
|
||||
mValue[offset++] = (byte) ((floatAsInt >> 8) & 0xFF);
|
||||
mValue[offset++] = (byte) ((floatAsInt >> 16) & 0xFF);
|
||||
mValue[offset] += (byte) ((floatAsInt >> 24) & 0xFF);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts float to SFLOAT IEEE 11073 format as UINT16, rounding up or down.
|
||||
* See: https://github.com/signove/antidote/blob/master/src/util/bytelib.c
|
||||
*
|
||||
* @param value the value to be converted.
|
||||
* @return given float as UINT16 in IEEE 11073 format.
|
||||
*/
|
||||
private static int sfloatToInt(final float value) {
|
||||
if (Float.isNaN(value)) {
|
||||
return SFLOAT_NAN;
|
||||
} else if (value > SFLOAT_MAX) {
|
||||
return SFLOAT_POSITIVE_INFINITY;
|
||||
} else if (value < SFLOAT_MIN) {
|
||||
return SFLOAT_NEGATIVE_INFINITY;
|
||||
}
|
||||
|
||||
int sign = value >= 0 ? +1 : -1;
|
||||
float mantissa = Math.abs(value);
|
||||
int exponent = 0; // Note: 10**x exponent, not 2**x
|
||||
|
||||
// scale up if number is too big
|
||||
while (mantissa > SFLOAT_MANTISSA_MAX) {
|
||||
mantissa /= 10.0f;
|
||||
++exponent;
|
||||
if (exponent > SFLOAT_EXPONENT_MAX) {
|
||||
// argh, should not happen
|
||||
if (sign > 0) {
|
||||
return SFLOAT_POSITIVE_INFINITY;
|
||||
} else {
|
||||
return SFLOAT_NEGATIVE_INFINITY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// scale down if number is too small
|
||||
while (mantissa < 1) {
|
||||
mantissa *= 10;
|
||||
--exponent;
|
||||
if (exponent < SFLOAT_EXPONENT_MIN) {
|
||||
// argh, should not happen
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// scale down if number needs more precision
|
||||
double smantissa = Math.round(mantissa * SFLOAT_PRECISION);
|
||||
double rmantissa = Math.round(mantissa) * SFLOAT_PRECISION;
|
||||
double mdiff = Math.abs(smantissa - rmantissa);
|
||||
while (mdiff > 0.5 && exponent > SFLOAT_EXPONENT_MIN &&
|
||||
(mantissa * 10) <= SFLOAT_MANTISSA_MAX) {
|
||||
mantissa *= 10;
|
||||
--exponent;
|
||||
smantissa = Math.round(mantissa * SFLOAT_PRECISION);
|
||||
rmantissa = Math.round(mantissa) * SFLOAT_PRECISION;
|
||||
mdiff = Math.abs(smantissa - rmantissa);
|
||||
}
|
||||
|
||||
int int_mantissa = Math.round(sign * mantissa);
|
||||
return ((exponent & 0xF) << 12) | (int_mantissa & 0xFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts float to FLOAT IEEE 11073 format as UINT32, rounding up or down.
|
||||
* See: https://github.com/signove/antidote/blob/master/src/util/bytelib.c
|
||||
*
|
||||
* @param value the value to be converted.
|
||||
* @return given float as UINT32 in IEEE 11073 format.
|
||||
*/
|
||||
private static int floatToInt(final float value) {
|
||||
if (Float.isNaN(value)) {
|
||||
return FLOAT_NAN;
|
||||
} else if (value == Float.POSITIVE_INFINITY) {
|
||||
return FLOAT_POSITIVE_INFINITY;
|
||||
} else if (value == Float.NEGATIVE_INFINITY) {
|
||||
return FLOAT_NEGATIVE_INFINITY;
|
||||
}
|
||||
|
||||
int sign = value >= 0 ? +1 : -1;
|
||||
float mantissa = Math.abs(value);
|
||||
int exponent = 0; // Note: 10**x exponent, not 2**x
|
||||
|
||||
// scale up if number is too big
|
||||
while (mantissa > FLOAT_MANTISSA_MAX) {
|
||||
mantissa /= 10.0f;
|
||||
++exponent;
|
||||
if (exponent > FLOAT_EXPONENT_MAX) {
|
||||
// argh, should not happen
|
||||
if (sign > 0) {
|
||||
return FLOAT_POSITIVE_INFINITY;
|
||||
} else {
|
||||
return FLOAT_NEGATIVE_INFINITY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// scale down if number is too small
|
||||
while (mantissa < 1) {
|
||||
mantissa *= 10;
|
||||
--exponent;
|
||||
if (exponent < FLOAT_EXPONENT_MIN) {
|
||||
// argh, should not happen
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// scale down if number needs more precision
|
||||
double smantissa = Math.round(mantissa * FLOAT_PRECISION);
|
||||
double rmantissa = Math.round(mantissa) * FLOAT_PRECISION;
|
||||
double mdiff = Math.abs(smantissa - rmantissa);
|
||||
while (mdiff > 0.5 && exponent > FLOAT_EXPONENT_MIN &&
|
||||
(mantissa * 10) <= FLOAT_MANTISSA_MAX) {
|
||||
mantissa *= 10;
|
||||
--exponent;
|
||||
smantissa = Math.round(mantissa * FLOAT_PRECISION);
|
||||
rmantissa = Math.round(mantissa) * FLOAT_PRECISION;
|
||||
mdiff = Math.abs(smantissa - rmantissa);
|
||||
}
|
||||
|
||||
int int_mantissa = Math.round(sign * mantissa);
|
||||
return (exponent << 24) | (int_mantissa & 0xFFFFFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an integer into the signed bits of a given length.
|
||||
*/
|
||||
private static int intToSignedBits(int i, int size) {
|
||||
if (i < 0) {
|
||||
i = (1 << size - 1) + (i & ((1 << size - 1) - 1));
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a long into the signed bits of a given length.
|
||||
*/
|
||||
private static long longToSignedBits(long i, int size) {
|
||||
if (i < 0) {
|
||||
i = (1L << size - 1) + (i & ((1L << size - 1) - 1));
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
209
app/src/main/java/no/nordicsemi/android/ble/error/GattError.java
Normal file
209
app/src/main/java/no/nordicsemi/android/ble/error/GattError.java
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package no.nordicsemi.android.ble.error;
|
||||
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
|
||||
/**
|
||||
* Parses the GATT and HCI errors to human readable strings.
|
||||
* <p>
|
||||
* See: <a href="https://android.googlesource.com/platform/external/bluetooth/bluedroid/+/master/stack/include/gatt_api.h">gatt_api.h</a> for details.<br>
|
||||
* See also: <a href="https://android.googlesource.com/platform/external/libnfc-nci/+/master/src/include/hcidefs.h#447">hcidefs.h</a> for other possible HCI errors.
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public class GattError {
|
||||
public static final int GATT_SUCCESS = BluetoothGatt.GATT_SUCCESS;
|
||||
public static final int GATT_CONN_L2C_FAILURE = 0x01;
|
||||
public static final int GATT_CONN_TIMEOUT = 0x08;
|
||||
public static final int GATT_CONN_TERMINATE_PEER_USER = 0x13;
|
||||
public static final int GATT_CONN_TERMINATE_LOCAL_HOST = 0x16;
|
||||
public static final int GATT_CONN_FAIL_ESTABLISH = 0x3E;
|
||||
public static final int GATT_CONN_LMP_TIMEOUT = 0x22;
|
||||
public static final int GATT_CONN_CANCEL = 0x0100;
|
||||
public static final int GATT_ERROR = 0x0085; // Device not reachable
|
||||
|
||||
public static final int GATT_INVALID_HANDLE = 0x0001;
|
||||
public static final int GATT_READ_NOT_PERMIT = 0x0002;
|
||||
public static final int GATT_WRITE_NOT_PERMIT = 0x0003;
|
||||
public static final int GATT_INVALID_PDU = 0x0004;
|
||||
public static final int GATT_INSUF_AUTHENTICATION = 0x0005;
|
||||
public static final int GATT_REQ_NOT_SUPPORTED = 0x0006;
|
||||
public static final int GATT_INVALID_OFFSET = 0x0007;
|
||||
public static final int GATT_INSUF_AUTHORIZATION = 0x0008;
|
||||
public static final int GATT_PREPARE_Q_FULL = 0x0009;
|
||||
public static final int GATT_NOT_FOUND = 0x000a;
|
||||
public static final int GATT_NOT_LONG = 0x000b;
|
||||
public static final int GATT_INSUF_KEY_SIZE = 0x000c;
|
||||
public static final int GATT_INVALID_ATTR_LEN = 0x000d;
|
||||
public static final int GATT_ERR_UNLIKELY = 0x000e;
|
||||
public static final int GATT_INSUF_ENCRYPTION = 0x000f;
|
||||
public static final int GATT_UNSUPPORT_GRP_TYPE = 0x0010;
|
||||
public static final int GATT_INSUF_RESOURCE = 0x0011;
|
||||
public static final int GATT_CONTROLLER_BUSY = 0x003A;
|
||||
public static final int GATT_UNACCEPT_CONN_INTERVAL = 0x003B;
|
||||
public static final int GATT_ILLEGAL_PARAMETER = 0x0087;
|
||||
public static final int GATT_NO_RESOURCES = 0x0080;
|
||||
public static final int GATT_INTERNAL_ERROR = 0x0081;
|
||||
public static final int GATT_WRONG_STATE = 0x0082;
|
||||
public static final int GATT_DB_FULL = 0x0083;
|
||||
public static final int GATT_BUSY = 0x0084;
|
||||
public static final int GATT_CMD_STARTED = 0x0086;
|
||||
public static final int GATT_PENDING = 0x0088;
|
||||
public static final int GATT_AUTH_FAIL = 0x0089;
|
||||
public static final int GATT_MORE = 0x008a;
|
||||
public static final int GATT_INVALID_CFG = 0x008b;
|
||||
public static final int GATT_SERVICE_STARTED = 0x008c;
|
||||
public static final int GATT_ENCRYPTED_NO_MITM = 0x008d;
|
||||
public static final int GATT_NOT_ENCRYPTED = 0x008e;
|
||||
public static final int GATT_CONGESTED = 0x008f;
|
||||
public static final int GATT_CCCD_CFG_ERROR = 0x00FD;
|
||||
public static final int GATT_PROCEDURE_IN_PROGRESS = 0x00FE;
|
||||
public static final int GATT_VALUE_OUT_OF_RANGE = 0x00FF;
|
||||
public static final int TOO_MANY_OPEN_CONNECTIONS = 0x0101;
|
||||
|
||||
/**
|
||||
* Converts the connection status given by the
|
||||
* {@link android.bluetooth.BluetoothGattCallback#onConnectionStateChange(BluetoothGatt, int, int)}
|
||||
* to error name.
|
||||
*
|
||||
* @param error the status number.
|
||||
* @return The error name as stated in the links in {@link GattError} documentation.
|
||||
*/
|
||||
public static String parseConnectionError(final int error) {
|
||||
switch (error) {
|
||||
case GATT_SUCCESS:
|
||||
return "SUCCESS";
|
||||
case GATT_CONN_L2C_FAILURE:
|
||||
return "GATT CONN L2C FAILURE";
|
||||
case GATT_CONN_TIMEOUT:
|
||||
return "GATT CONN TIMEOUT";
|
||||
case GATT_CONN_TERMINATE_PEER_USER:
|
||||
return "GATT CONN TERMINATE PEER USER";
|
||||
case GATT_CONN_TERMINATE_LOCAL_HOST:
|
||||
return "GATT CONN TERMINATE LOCAL HOST";
|
||||
case GATT_CONN_FAIL_ESTABLISH:
|
||||
return "GATT CONN FAIL ESTABLISH";
|
||||
case GATT_CONN_LMP_TIMEOUT:
|
||||
return "GATT CONN LMP TIMEOUT";
|
||||
case GATT_CONN_CANCEL:
|
||||
return "GATT CONN CANCEL ";
|
||||
case GATT_ERROR:
|
||||
return "GATT ERROR"; // Device not reachable
|
||||
default:
|
||||
return "UNKNOWN (" + error + ")";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the Bluetooth communication status given by other BluetoothGattCallbacks to error
|
||||
* name. It also parses the DFU errors.
|
||||
*
|
||||
* @param error the status number.
|
||||
* @return The error name as stated in the links in {@link GattError} documentation.
|
||||
*/
|
||||
public static String parse(final int error) {
|
||||
switch (error) {
|
||||
case GATT_INVALID_HANDLE:
|
||||
return "GATT INVALID HANDLE";
|
||||
case GATT_READ_NOT_PERMIT:
|
||||
return "GATT READ NOT PERMIT";
|
||||
case GATT_WRITE_NOT_PERMIT:
|
||||
return "GATT WRITE NOT PERMIT";
|
||||
case GATT_INVALID_PDU:
|
||||
return "GATT INVALID PDU";
|
||||
case GATT_INSUF_AUTHENTICATION:
|
||||
return "GATT INSUF AUTHENTICATION";
|
||||
case GATT_REQ_NOT_SUPPORTED:
|
||||
return "GATT REQ NOT SUPPORTED";
|
||||
case GATT_INVALID_OFFSET:
|
||||
return "GATT INVALID OFFSET";
|
||||
case GATT_INSUF_AUTHORIZATION:
|
||||
return "GATT INSUF AUTHORIZATION";
|
||||
case GATT_PREPARE_Q_FULL:
|
||||
return "GATT PREPARE Q FULL";
|
||||
case GATT_NOT_FOUND:
|
||||
return "GATT NOT FOUND";
|
||||
case GATT_NOT_LONG:
|
||||
return "GATT NOT LONG";
|
||||
case GATT_INSUF_KEY_SIZE:
|
||||
return "GATT INSUF KEY SIZE";
|
||||
case GATT_INVALID_ATTR_LEN:
|
||||
return "GATT INVALID ATTR LEN";
|
||||
case GATT_ERR_UNLIKELY:
|
||||
return "GATT ERR UNLIKELY";
|
||||
case GATT_INSUF_ENCRYPTION:
|
||||
return "GATT INSUF ENCRYPTION";
|
||||
case GATT_UNSUPPORT_GRP_TYPE:
|
||||
return "GATT UNSUPPORT GRP TYPE";
|
||||
case GATT_INSUF_RESOURCE:
|
||||
return "GATT INSUF RESOURCE";
|
||||
case GATT_CONN_LMP_TIMEOUT:
|
||||
return "GATT CONN LMP TIMEOUT";
|
||||
case GATT_CONTROLLER_BUSY:
|
||||
return "GATT CONTROLLER BUSY";
|
||||
case GATT_UNACCEPT_CONN_INTERVAL:
|
||||
return "GATT UNACCEPT CONN INTERVAL";
|
||||
case GATT_ILLEGAL_PARAMETER:
|
||||
return "GATT ILLEGAL PARAMETER";
|
||||
case GATT_NO_RESOURCES:
|
||||
return "GATT NO RESOURCES";
|
||||
case GATT_INTERNAL_ERROR:
|
||||
return "GATT INTERNAL ERROR";
|
||||
case GATT_WRONG_STATE:
|
||||
return "GATT WRONG STATE";
|
||||
case GATT_DB_FULL:
|
||||
return "GATT DB FULL";
|
||||
case GATT_BUSY:
|
||||
return "GATT BUSY";
|
||||
case GATT_ERROR:
|
||||
return "GATT ERROR";
|
||||
case GATT_CMD_STARTED:
|
||||
return "GATT CMD STARTED";
|
||||
case GATT_PENDING:
|
||||
return "GATT PENDING";
|
||||
case GATT_AUTH_FAIL:
|
||||
return "GATT AUTH FAIL";
|
||||
case GATT_MORE:
|
||||
return "GATT MORE";
|
||||
case GATT_INVALID_CFG:
|
||||
return "GATT INVALID CFG";
|
||||
case GATT_SERVICE_STARTED:
|
||||
return "GATT SERVICE STARTED";
|
||||
case GATT_ENCRYPTED_NO_MITM:
|
||||
return "GATT ENCRYPTED NO MITM";
|
||||
case GATT_NOT_ENCRYPTED:
|
||||
return "GATT NOT ENCRYPTED";
|
||||
case GATT_CONGESTED:
|
||||
return "GATT CONGESTED";
|
||||
case GATT_CCCD_CFG_ERROR:
|
||||
return "GATT CCCD CFG ERROR";
|
||||
case GATT_PROCEDURE_IN_PROGRESS:
|
||||
return "GATT PROCEDURE IN PROGRESS";
|
||||
case GATT_VALUE_OUT_OF_RANGE:
|
||||
return "GATT VALUE OUT OF RANGE";
|
||||
case TOO_MANY_OPEN_CONNECTIONS:
|
||||
return "TOO MANY OPEN CONNECTIONS";
|
||||
default:
|
||||
return "UNKNOWN (" + error + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.exception;
|
||||
|
||||
public class BluetoothDisabledException extends ConnectionException {
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.exception;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public class ConnectionException extends Exception {
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.exception;
|
||||
|
||||
public class DeviceDisconnectedException extends ConnectionException {
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.exception;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import no.nordicsemi.android.ble.callback.profile.ProfileReadResponse;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class InvalidDataException extends Exception {
|
||||
private final ProfileReadResponse response;
|
||||
|
||||
public InvalidDataException(@NonNull final ProfileReadResponse response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
public ProfileReadResponse getResponse() {
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.exception;
|
||||
|
||||
import no.nordicsemi.android.ble.Request;
|
||||
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public final class InvalidRequestException extends Exception {
|
||||
private final Request request;
|
||||
|
||||
public InvalidRequestException(final Request request) {
|
||||
super("Invalid request");
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the invalid request.
|
||||
* @return The invalid request.
|
||||
*/
|
||||
public Request getRequest() {
|
||||
return request;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.exception;
|
||||
|
||||
import no.nordicsemi.android.ble.Request;
|
||||
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public final class RequestFailedException extends Exception {
|
||||
private final Request request;
|
||||
private final int status;
|
||||
|
||||
public RequestFailedException(final Request request, final int status) {
|
||||
super("Request failed with status " + status);
|
||||
this.request = request;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request status. One of {{@link android.bluetooth.BluetoothGatt}} GATT_*
|
||||
* or {@link no.nordicsemi.android.ble.callback.FailCallback} REASON_* codes.
|
||||
*
|
||||
* @return Error code.
|
||||
*/
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request that failed.
|
||||
* @return The request that failed.
|
||||
*/
|
||||
public Request getRequest() {
|
||||
return request;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.response;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.callback.ConnectionPriorityCallback;
|
||||
|
||||
/**
|
||||
* The synchronous response type for connection priority requests.
|
||||
*
|
||||
* @see ConnectionPriorityCallback
|
||||
*/
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public class ConnectionPriorityResponse implements ConnectionPriorityCallback, Parcelable {
|
||||
private BluetoothDevice device;
|
||||
|
||||
@IntRange(from = 6, to = 3200)
|
||||
private int interval;
|
||||
|
||||
@IntRange(from = 0, to = 499)
|
||||
private int latency;
|
||||
|
||||
@IntRange(from = 10, to = 3200)
|
||||
private int supervisionTimeout;
|
||||
|
||||
@Override
|
||||
public void onConnectionUpdated(@NonNull final BluetoothDevice device,
|
||||
@IntRange(from = 6, to = 3200) final int interval,
|
||||
@IntRange(from = 0, to = 499) final int latency,
|
||||
@IntRange(from = 10, to = 3200) final int timeout) {
|
||||
this.device = device;
|
||||
this.interval = interval;
|
||||
this.latency = latency;
|
||||
this.supervisionTimeout = timeout;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BluetoothDevice getBluetoothDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
/**
|
||||
* The connection interval determines how often the Central will ask for data from the Peripheral.
|
||||
* When the Peripheral requests an update, it supplies a maximum and a minimum wanted interval.
|
||||
* The connection interval must be between 7.5 ms and 4 s.
|
||||
*
|
||||
* @return Connection interval used on this connection, 1.25ms unit.
|
||||
* Valid range is from 6 (7.5ms) to 3200 (4000ms).
|
||||
*/
|
||||
@IntRange(from = 6, to = 3200)
|
||||
public int getConnectionInterval() {
|
||||
return interval;
|
||||
}
|
||||
|
||||
/**
|
||||
* By setting a non-zero slave latency, the Peripheral can choose to not answer when
|
||||
* the Central asks for data up to the slave latency number of times.
|
||||
* However, if the Peripheral has data to send, it can choose to send data at any time.
|
||||
* This enables a peripheral to stay sleeping for a longer time, if it doesn't have data to send,
|
||||
* but still send data fast if needed. The text book example of such device is for example
|
||||
* keyboard and mice, which want to be sleeping for as long as possible when there is
|
||||
* no data to send, but still have low latency (and for the mouse: low connection interval)
|
||||
* when needed.
|
||||
*
|
||||
* @return Slave latency for the connection in number of connection events.
|
||||
* Valid range is from 0 to 499.
|
||||
*/
|
||||
@IntRange(from = 0, to = 499)
|
||||
public int getSlaveLatency() {
|
||||
return latency;
|
||||
}
|
||||
|
||||
/**
|
||||
* This timeout determines the timeout from the last data exchange till a link is considered lost.
|
||||
* A Central will not start trying to reconnect before the timeout has passed,
|
||||
* so if you have a device which goes in and out of range often, and you need to notice when
|
||||
* that happens, it might make sense to have a short timeout.
|
||||
*
|
||||
* @return Supervision timeout for this connection, in 10ms unit.
|
||||
* Valid range is from 10 (100 ms = 0.1s) to 3200 (32s).
|
||||
*/
|
||||
@IntRange(from = 10, to = 3200)
|
||||
public int getSupervisionTimeout() {
|
||||
return supervisionTimeout;
|
||||
}
|
||||
|
||||
// Parcelable
|
||||
protected ConnectionPriorityResponse(final Parcel in) {
|
||||
device = in.readParcelable(BluetoothDevice.class.getClassLoader());
|
||||
interval = in.readInt();
|
||||
latency = in.readInt();
|
||||
supervisionTimeout = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel dest, final int flags) {
|
||||
dest.writeParcelable(device, flags);
|
||||
dest.writeInt(interval);
|
||||
dest.writeInt(latency);
|
||||
dest.writeInt(supervisionTimeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Creator<ConnectionPriorityResponse> CREATOR = new Creator<ConnectionPriorityResponse>() {
|
||||
@Override
|
||||
public ConnectionPriorityResponse createFromParcel(final Parcel in) {
|
||||
return new ConnectionPriorityResponse(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionPriorityResponse[] newArray(final int size) {
|
||||
return new ConnectionPriorityResponse[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.response;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.callback.MtuCallback;
|
||||
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public class MtuResult implements MtuCallback, Parcelable {
|
||||
private BluetoothDevice device;
|
||||
|
||||
@IntRange(from = 23, to = 517)
|
||||
private int mtu;
|
||||
|
||||
@Override
|
||||
public void onMtuChanged(@NonNull final BluetoothDevice device,
|
||||
@IntRange(from = 23, to = 517) final int mtu) {
|
||||
this.device = device;
|
||||
this.mtu = mtu;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BluetoothDevice getBluetoothDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the agreed MTU. The maximum packet size is 3 bytes less then MTU.
|
||||
*
|
||||
* @return The MTU.
|
||||
*/
|
||||
@IntRange(from = 23, to = 517)
|
||||
public int getMtu() {
|
||||
return mtu;
|
||||
}
|
||||
|
||||
// Parcelable
|
||||
protected MtuResult(final Parcel in) {
|
||||
device = in.readParcelable(BluetoothDevice.class.getClassLoader());
|
||||
mtu = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel dest, final int flags) {
|
||||
dest.writeParcelable(device, flags);
|
||||
dest.writeInt(mtu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Creator<MtuResult> CREATOR = new Creator<MtuResult>() {
|
||||
@Override
|
||||
public MtuResult createFromParcel(final Parcel in) {
|
||||
return new MtuResult(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MtuResult[] newArray(final int size) {
|
||||
return new MtuResult[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.response;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.annotation.PhyValue;
|
||||
import no.nordicsemi.android.ble.callback.PhyCallback;
|
||||
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public class PhyResult implements PhyCallback, Parcelable {
|
||||
private BluetoothDevice device;
|
||||
|
||||
@PhyValue
|
||||
private int txPhy;
|
||||
|
||||
@PhyValue
|
||||
private int rxPhy;
|
||||
|
||||
@Override
|
||||
public void onPhyChanged(@NonNull final BluetoothDevice device,
|
||||
@PhyValue final int txPhy, @PhyValue final int rxPhy) {
|
||||
this.device = device;
|
||||
this.txPhy = txPhy;
|
||||
this.rxPhy = rxPhy;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BluetoothDevice getBluetoothDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
@PhyValue
|
||||
public int getTxPhy() {
|
||||
return txPhy;
|
||||
}
|
||||
|
||||
@PhyValue
|
||||
public int getRxPhy() {
|
||||
return rxPhy;
|
||||
}
|
||||
|
||||
// Parcelable
|
||||
protected PhyResult(final Parcel in) {
|
||||
device = in.readParcelable(BluetoothDevice.class.getClassLoader());
|
||||
txPhy = in.readInt();
|
||||
rxPhy = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel dest, final int flags) {
|
||||
dest.writeParcelable(device, flags);
|
||||
dest.writeInt(txPhy);
|
||||
dest.writeInt(rxPhy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Creator<PhyResult> CREATOR = new Creator<PhyResult>() {
|
||||
@Override
|
||||
public PhyResult createFromParcel(final Parcel in) {
|
||||
return new PhyResult(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhyResult[] newArray(final int size) {
|
||||
return new PhyResult[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.response;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.callback.DataReceivedCallback;
|
||||
import no.nordicsemi.android.ble.data.Data;
|
||||
|
||||
/**
|
||||
* Generic read response class that returns the data received and the device from which data
|
||||
* were read.
|
||||
* Overriding class must call super on {@link #onDataReceived(BluetoothDevice, Data)} in
|
||||
* order to make getters work properly.
|
||||
*/
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public class ReadResponse implements DataReceivedCallback, Parcelable {
|
||||
private BluetoothDevice device;
|
||||
private Data data;
|
||||
|
||||
public ReadResponse() {
|
||||
// empty
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataReceived(@NonNull final BluetoothDevice device, @NonNull final Data data) {
|
||||
this.device = device;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BluetoothDevice getBluetoothDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Data getRawData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
// Parcelable
|
||||
protected ReadResponse(final Parcel in) {
|
||||
device = in.readParcelable(BluetoothDevice.class.getClassLoader());
|
||||
data = in.readParcelable(Data.class.getClassLoader());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel dest, final int flags) {
|
||||
dest.writeParcelable(device, flags);
|
||||
dest.writeParcelable(data, flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Creator<ReadResponse> CREATOR = new Creator<ReadResponse>() {
|
||||
@Override
|
||||
public ReadResponse createFromParcel(final Parcel in) {
|
||||
return new ReadResponse(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadResponse[] newArray(final int size) {
|
||||
return new ReadResponse[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.response;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.callback.RssiCallback;
|
||||
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public class RssiResult implements RssiCallback, Parcelable {
|
||||
private BluetoothDevice device;
|
||||
|
||||
@IntRange(from = -128, to = 20)
|
||||
private int rssi;
|
||||
|
||||
@Override
|
||||
public void onRssiRead(@NonNull final BluetoothDevice device,
|
||||
@IntRange(from = -128, to = 20) final int rssi) {
|
||||
this.device = device;
|
||||
this.rssi = rssi;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BluetoothDevice getBluetoothDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
@IntRange(from = -128, to = 20)
|
||||
public int getRssi() {
|
||||
return rssi;
|
||||
}
|
||||
|
||||
// Parcelable
|
||||
protected RssiResult(final Parcel in) {
|
||||
device = in.readParcelable(BluetoothDevice.class.getClassLoader());
|
||||
rssi = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel dest, final int flags) {
|
||||
dest.writeParcelable(device, flags);
|
||||
dest.writeInt(rssi);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Creator<RssiResult> CREATOR = new Creator<RssiResult>() {
|
||||
@Override
|
||||
public RssiResult createFromParcel(final Parcel in) {
|
||||
return new RssiResult(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RssiResult[] newArray(final int size) {
|
||||
return new RssiResult[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package no.nordicsemi.android.ble.response;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import no.nordicsemi.android.ble.callback.DataSentCallback;
|
||||
import no.nordicsemi.android.ble.data.Data;
|
||||
|
||||
/**
|
||||
* Generic write response class that returns the target device and the data that were sent.
|
||||
* Overriding class must call super on {@link #onDataSent(BluetoothDevice, Data)} in
|
||||
* order to make getters work properly.
|
||||
*/
|
||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||
public class WriteResponse implements DataSentCallback, Parcelable {
|
||||
private BluetoothDevice device;
|
||||
private Data data;
|
||||
|
||||
@Override
|
||||
public void onDataSent(@NonNull final BluetoothDevice device, @NonNull final Data data) {
|
||||
this.device = device;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BluetoothDevice getBluetoothDevice() {
|
||||
return device;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Data getRawData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
// Parcelable
|
||||
protected WriteResponse(final Parcel in) {
|
||||
device = in.readParcelable(BluetoothDevice.class.getClassLoader());
|
||||
data = in.readParcelable(Data.class.getClassLoader());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel dest, final int flags) {
|
||||
dest.writeParcelable(device, flags);
|
||||
dest.writeParcelable(data, flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Creator<WriteResponse> CREATOR = new Creator<WriteResponse>() {
|
||||
@Override
|
||||
public WriteResponse createFromParcel(final Parcel in) {
|
||||
return new WriteResponse(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WriteResponse[] newArray(final int size) {
|
||||
return new WriteResponse[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package no.nordicsemi.android.ble.utils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public interface ILogger {
|
||||
|
||||
/**
|
||||
* Logs the given message with given log priority into the all managed devices' log session.
|
||||
*
|
||||
* @param priority the log priority.
|
||||
* @param message the message to be logged.
|
||||
*/
|
||||
void log(final int priority, @NonNull final String message);
|
||||
|
||||
/**
|
||||
* Logs the given message with given log priority into the all managed devices' log session.
|
||||
*
|
||||
* @param priority the log priority.
|
||||
* @param messageRes string resource id.
|
||||
* @param params additional (optional) parameters used to fill the message.
|
||||
*/
|
||||
void log(final int priority, @StringRes final int messageRes, @Nullable final Object... params);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Nordic Semiconductor
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package no.nordicsemi.android.ble.utils;
|
||||
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattDescriptor;
|
||||
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public class ParserUtils {
|
||||
protected final static char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
|
||||
|
||||
public static String parse(final BluetoothGattCharacteristic characteristic) {
|
||||
return parse(characteristic.getValue());
|
||||
}
|
||||
|
||||
public static String parse(final BluetoothGattDescriptor descriptor) {
|
||||
return parse(descriptor.getValue());
|
||||
}
|
||||
|
||||
public static String parse(final byte[] data) {
|
||||
if (data == null || data.length == 0)
|
||||
return "";
|
||||
|
||||
final char[] out = new char[data.length * 3 - 1];
|
||||
for (int j = 0; j < data.length; j++) {
|
||||
int v = data[j] & 0xFF;
|
||||
out[j * 3] = HEX_ARRAY[v >>> 4];
|
||||
out[j * 3 + 1] = HEX_ARRAY[v & 0x0F];
|
||||
if (j != data.length - 1)
|
||||
out[j * 3 + 2] = '-';
|
||||
}
|
||||
return "(0x) " + new String(out);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
@@ -15,4 +15,4 @@
|
||||
android:text="Button"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -13,3 +13,6 @@ org.gradle.jvmargs=-Xmx1536m
|
||||
# org.gradle.parallel=true
|
||||
|
||||
|
||||
|
||||
android.enableJetifier=true
|
||||
android.useAndroidX=true
|
||||
Reference in New Issue
Block a user