Merge branch 'master' into release
This commit is contained in:
commit
1205a04c17
|
@ -6,6 +6,7 @@
|
|||
<option name="distributionType" value="LOCAL" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleHome" value="C:\Program Files\Android\Android Studio\gradle\gradle-2.2.1" />
|
||||
<option name="gradleJvm" value="1.7" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
|
@ -15,5 +16,4 @@
|
|||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
|
||||
</project>
|
|
@ -1,9 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<module external.linked.project.id="DFULibrary" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="java-gradle" name="Java-Gradle">
|
||||
<configuration>
|
||||
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
|
||||
<option name="BUILDABLE" value="false" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
|
@ -15,5 +16,4 @@
|
|||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
</module>
|
|
@ -8,7 +8,7 @@ ext {
|
|||
|
||||
android {
|
||||
compileSdkVersion 22
|
||||
buildToolsVersion '22.0.0'
|
||||
buildToolsVersion '22.0.1'
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 18
|
||||
|
@ -26,7 +26,7 @@ android {
|
|||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile 'com.android.support:support-v4:22.0.0'
|
||||
compile 'com.android.support:support-v4:22.1.1'
|
||||
compile 'com.google.code.gson:gson:2.3.1'
|
||||
}
|
||||
|
||||
|
|
12
dfu/dfu.iml
12
dfu/dfu.iml
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="DFULibrary" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<module external.linked.project.id=":dfu" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="DFULibrary" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
|
@ -12,8 +12,9 @@
|
|||
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
|
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
|
||||
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
|
||||
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
|
||||
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
|
||||
<option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
|
||||
<option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugAndroidTestSources" />
|
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||
|
@ -87,8 +88,7 @@
|
|||
<orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" exported="" name="gson-2.3.1" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-v4-22.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-annotations-22.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-v4-22.1.1" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-annotations-22.1.1" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
</module>
|
|
@ -66,6 +66,7 @@ import no.nordicsemi.android.dfu.exception.HexFileValidationException;
|
|||
import no.nordicsemi.android.dfu.exception.RemoteDfuException;
|
||||
import no.nordicsemi.android.dfu.exception.UnknownResponseException;
|
||||
import no.nordicsemi.android.dfu.exception.UploadAbortedException;
|
||||
import no.nordicsemi.android.dfu.scanner.BootloaderScannerFactory;
|
||||
import no.nordicsemi.android.error.GattError;
|
||||
|
||||
/**
|
||||
|
@ -1727,14 +1728,32 @@ public abstract class DfuBaseService extends IntentService {
|
|||
updateProgressNotification(PROGRESS_COMPLETED);
|
||||
} else {
|
||||
/*
|
||||
* The current service handle will try to upload Soft Device and/or Bootloader.
|
||||
* We need to enqueue another Intent that will try to send application only.
|
||||
* In case when the Soft Device has been upgraded, and the application should be send in the following connection, we have to
|
||||
* make sure that we know the address the device is advertising with. Depending on the method used to start the DFU bootloader the first time
|
||||
* the new Bootloader may advertise with the same address or one incremented by 1.
|
||||
* When the buttonless update was used, the bootloader will use the same address as the application. The cached list of services on the Android device
|
||||
* should be cleared thanks to the Service Changed characteristic (the fact that it exists if not bonded, or the Service Changed indication on bonded one).
|
||||
* In case of forced DFU mode (using a button), the Bootloader does not know whether there was the Service Changed characteristic present in the list of
|
||||
* application's services so it must advertise with a different address. The same situation applies when the new Soft Device was uploaded and the old
|
||||
* application has been removed in this process.
|
||||
*
|
||||
* We could have save the fact of jumping as a parameter of the service but it ma be that some Android devices must first scan a device before connecting to it.
|
||||
* It a device with the address+1 has never been detected before the service could have failed on connection.
|
||||
*/
|
||||
sendLogBroadcast(LOG_LEVEL_VERBOSE, "Scanning for the DFU bootloader...");
|
||||
final String newAddress = BootloaderScannerFactory.getScanner().searchFor(mDeviceAddress);
|
||||
sendLogBroadcast(LOG_LEVEL_INFO, "The Bootloader found (" + newAddress + ")");
|
||||
|
||||
/*
|
||||
* The current service instance has uploaded the Soft Device and/or Bootloader.
|
||||
* We need to start another instance that will try to send application only.
|
||||
*/
|
||||
logi("Starting service that will upload application");
|
||||
final Intent newIntent = new Intent();
|
||||
newIntent.fillIn(intent, Intent.FILL_IN_COMPONENT | Intent.FILL_IN_PACKAGE);
|
||||
newIntent.putExtra(EXTRA_FILE_MIME_TYPE, MIME_TYPE_ZIP); // ensure this is set (f.e. for scripts)
|
||||
newIntent.putExtra(EXTRA_FILE_MIME_TYPE, MIME_TYPE_ZIP); // ensure this is set (e.g. for scripts)
|
||||
newIntent.putExtra(EXTRA_FILE_TYPE, TYPE_APPLICATION); // set the type to application only
|
||||
newIntent.putExtra(EXTRA_DEVICE_ADDRESS, newAddress);
|
||||
newIntent.putExtra(EXTRA_PART_CURRENT, mPartCurrent + 1);
|
||||
newIntent.putExtra(EXTRA_PARTS_TOTAL, mPartsTotal);
|
||||
startService(newIntent);
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*************************************************************************************************************************************************
|
||||
* Copyright (c) 2015, 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.dfu.scanner;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The DFU Bootloader may advertise with the same address as an application (in case of the buttonless update) or one incremented by 1 (in case of jumping to the DFU mode with a button,
|
||||
* or after flashing the new Soft Device (flashing new SD removes the old application)).
|
||||
* </p>
|
||||
* <p>
|
||||
* The DFU service always connects to the address given as a parameter. However, when flashing SD+BL+App it will first send the SD+BL as part one followed by the App in the second connection.
|
||||
* As the service does not know which address was used in the first connection (normal, when buttonless update, or +1 when with-button update) we have to scan for the advertising device
|
||||
* after SD+BL part is completed.
|
||||
* </p>
|
||||
*/
|
||||
public interface BootloaderScanner {
|
||||
/**
|
||||
* After the buttonless jump from the application mode to the bootloader mode the service will wait this long for the advertising bootloader (in milliseconds).
|
||||
*/
|
||||
public final static long TIMEOUT = 2000l; // ms
|
||||
/** The bootloader may advertise with the same address or one with the last byte incremented by this value. F.e. 00:11:22:33:44:55 -> 00:11:22:33:44:56. FF changes to 00. */
|
||||
public final static int ADDRESS_DIFF = 1;
|
||||
|
||||
/**
|
||||
* Searches for the advertising bootloader. The bootloader may advertise with the same device address or one with the last byte incremented by 1.
|
||||
* This method is a blocking one and ends when such device is found. There are two implementations of this interface - one for Androids 4.3 and 4.4.x and one for
|
||||
* the Android 5+ devices.
|
||||
*
|
||||
* @param deviceAddress
|
||||
* the application device address
|
||||
* @return the address of the advertising DFU bootloader. If may be the same as the application address or one with the last byte incremented by 1 (AA:BB:CC:DD:EE:45/FF -> AA:BB:CC:DD:EE:46/00).
|
||||
*/
|
||||
public String searchFor(final String deviceAddress);
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*************************************************************************************************************************************************
|
||||
* Copyright (c) 2015, 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.dfu.scanner;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
/**
|
||||
* The factory should be used to create the {@link BootloaderScanner} instance appropriate for the Android version.
|
||||
*/
|
||||
public class BootloaderScannerFactory {
|
||||
|
||||
/**
|
||||
* Returns the scanner implementation.
|
||||
*
|
||||
* @return the bootloader scanner
|
||||
*/
|
||||
public static BootloaderScanner getScanner() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
return new BootloaderScannerLollipop();
|
||||
return new BootloaderScannerJB();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
/*************************************************************************************************************************************************
|
||||
* Copyright (c) 2015, 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.dfu.scanner;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
/**
|
||||
* @see BootloaderScanner
|
||||
*/
|
||||
public class BootloaderScannerJB implements BootloaderScanner, BluetoothAdapter.LeScanCallback {
|
||||
private final Object mLock = new Object();
|
||||
private String mDeviceAddress;
|
||||
private String mDeviceAddressIncremented;
|
||||
private String mBootloaderAddress;
|
||||
private boolean mFound;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public String searchFor(final String deviceAddress) {
|
||||
final String fistBytes = deviceAddress.substring(0, 15);
|
||||
final String lastByte = deviceAddress.substring(15); // assuming that the device address is correct
|
||||
final String lastByteIncremented = String.format("%02X", (Integer.valueOf(lastByte, 16) + ADDRESS_DIFF) & 0xFF);
|
||||
|
||||
mDeviceAddress = deviceAddress;
|
||||
mDeviceAddressIncremented = fistBytes + lastByteIncremented;
|
||||
mBootloaderAddress = null;
|
||||
mFound = false;
|
||||
|
||||
// Add timeout
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(BootloaderScanner.TIMEOUT);
|
||||
} catch (final InterruptedException e) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
if (mFound)
|
||||
return;
|
||||
|
||||
mBootloaderAddress = null;
|
||||
mFound = true;
|
||||
|
||||
// Notify the waiting thread
|
||||
synchronized (mLock) {
|
||||
mLock.notifyAll();
|
||||
}
|
||||
}
|
||||
}, "Scanner timer").start();
|
||||
|
||||
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
adapter.startLeScan(this);
|
||||
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
while (!mFound)
|
||||
mLock.wait();
|
||||
}
|
||||
} catch (final InterruptedException e) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
adapter.stopLeScan(this);
|
||||
return mBootloaderAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {
|
||||
final String address = device.getAddress();
|
||||
|
||||
if (mDeviceAddress.equals(address) || mDeviceAddressIncremented.equals(address)) {
|
||||
mBootloaderAddress = address;
|
||||
mFound = true;
|
||||
|
||||
// Notify the waiting thread
|
||||
synchronized (mLock) {
|
||||
mLock.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/*************************************************************************************************************************************************
|
||||
* Copyright (c) 2015, 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.dfu.scanner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.le.BluetoothLeScanner;
|
||||
import android.bluetooth.le.ScanCallback;
|
||||
import android.bluetooth.le.ScanFilter;
|
||||
import android.bluetooth.le.ScanResult;
|
||||
import android.bluetooth.le.ScanSettings;
|
||||
import android.os.Build;
|
||||
|
||||
/**
|
||||
* @see BootloaderScanner
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public class BootloaderScannerLollipop extends ScanCallback implements BootloaderScanner {
|
||||
private final Object mLock = new Object();
|
||||
private String mDeviceAddress;
|
||||
private String mDeviceAddressIncremented;
|
||||
private String mBootloaderAddress;
|
||||
private boolean mFound;
|
||||
|
||||
@Override
|
||||
public String searchFor(final String deviceAddress) {
|
||||
final String fistBytes = deviceAddress.substring(0, 15);
|
||||
final String lastByte = deviceAddress.substring(15); // assuming that the device address is correct
|
||||
final String lastByteIncremented = String.format("%02X", (Integer.valueOf(lastByte, 16) + ADDRESS_DIFF) & 0xFF);
|
||||
|
||||
mDeviceAddress = deviceAddress;
|
||||
mDeviceAddressIncremented = fistBytes + lastByteIncremented;
|
||||
mBootloaderAddress = null;
|
||||
mFound = false;
|
||||
|
||||
// Add timeout
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(BootloaderScanner.TIMEOUT);
|
||||
} catch (final InterruptedException e) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
if (mFound)
|
||||
return;
|
||||
|
||||
mBootloaderAddress = null;
|
||||
mFound = true;
|
||||
|
||||
// Notify the waiting thread
|
||||
synchronized (mLock) {
|
||||
mLock.notifyAll();
|
||||
}
|
||||
}
|
||||
}, "Scanner timer").start();
|
||||
|
||||
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
final BluetoothLeScanner scanner = adapter.getBluetoothLeScanner();
|
||||
final List<ScanFilter> filters = new ArrayList<>();
|
||||
filters.add(new ScanFilter.Builder().setDeviceAddress(mDeviceAddress).build());
|
||||
filters.add(new ScanFilter.Builder().setDeviceAddress(mDeviceAddressIncremented).build());
|
||||
final ScanSettings settings = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
|
||||
scanner.startScan(filters, settings, this);
|
||||
|
||||
try {
|
||||
synchronized (mLock) {
|
||||
while (!mFound)
|
||||
mLock.wait();
|
||||
}
|
||||
} catch (final InterruptedException e) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
scanner.stopScan(this);
|
||||
return mBootloaderAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanResult(final int callbackType, final ScanResult result) {
|
||||
final String address = result.getDevice().getAddress();
|
||||
|
||||
if (mDeviceAddress.equals(address) || mDeviceAddressIncremented.equals(address)) {
|
||||
mBootloaderAddress = address;
|
||||
mFound = true;
|
||||
|
||||
// Notify the waiting thread
|
||||
synchronized (mLock) {
|
||||
mLock.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -135,12 +135,16 @@ public class GattError {
|
|||
return "GATT ENCRYPTED NO MITM";
|
||||
case 0x008e:
|
||||
return "GATT NOT ENCRYPTED";
|
||||
case 0x01FF:
|
||||
case 0x008f:
|
||||
return "GATT CONGESTED";
|
||||
case 0x00FD:
|
||||
return "GATT CCCD CFG ERROR";
|
||||
case 0x00FE:
|
||||
return "GATT PROCEDURE IN PROGRESS";
|
||||
case 0x00FF:
|
||||
return "GATT VALUE OUT OF RANGE";
|
||||
case 0x0101:
|
||||
return "TOO MANY OPEN CONNECTIONS";
|
||||
case 0x00FF:
|
||||
return "DFU SERVICE DISCOVERY NOT STARTED";
|
||||
case DfuBaseService.ERROR_DEVICE_DISCONNECTED:
|
||||
return "DFU DEVICE DISCONNECTED";
|
||||
case DfuBaseService.ERROR_FILE_ERROR:
|
||||
|
@ -152,7 +156,7 @@ public class GattError {
|
|||
case DfuBaseService.ERROR_FILE_NOT_FOUND:
|
||||
return "DFU FILE NOT FOUND";
|
||||
case DfuBaseService.ERROR_SERVICE_DISCOVERY_NOT_STARTED:
|
||||
return "DFU ERROR WHILE SERVICE DISCOVERY";
|
||||
return "DFU SERVICE DISCOVERY NOT STARTED";
|
||||
case DfuBaseService.ERROR_SERVICE_NOT_FOUND:
|
||||
return "DFU SERVICE NOT FOUND";
|
||||
case DfuBaseService.ERROR_CHARACTERISTICS_NOT_FOUND:
|
||||
|
|
Loading…
Reference in New Issue